RTEMS  5.0.0
arm-cp15.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2013 Hesham AL-Matary
11  * Copyright (c) 2009-2017 embedded brains GmbH. All rights reserved.
12  *
13  * embedded brains GmbH
14  * Dornierstr. 4
15  * 82178 Puchheim
16  * Germany
17  * <info@embedded-brains.de>
18  *
19  * The license and distribution terms for this file may be
20  * found in the file LICENSE in this distribution or at
21  * http://www.rtems.org/license/LICENSE.
22  */
23 
24 #ifndef LIBCPU_SHARED_ARM_CP15_H
25 #define LIBCPU_SHARED_ARM_CP15_H
26 
27 #include <rtems.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif /* __cplusplus */
32 
33 /*
34  * Allow users of this header file to optionally place the inline functions
35  * into a non-standard section.
36  */
37 #ifndef ARM_CP15_TEXT_SECTION
38  #define ARM_CP15_TEXT_SECTION
39 #endif
40 
41 #define ARM_CP15_CACHE_PREPARE_MVA(mva) \
42  ((const void *) (((uint32_t) (mva)) & ~0x1fU))
43 
44 #define ARM_CP15_TLB_PREPARE_MVA(mva) \
45  ((const void *) (((uint32_t) (mva)) & ~0x3fU))
46 
67 #define ARM_MMU_SECT_BASE_SHIFT 20
68 #define ARM_MMU_SECT_BASE_MASK (0xfffU << ARM_MMU_SECT_BASE_SHIFT)
69 #define ARM_MMU_SECT_NS (1U << 19)
70 #define ARM_MMU_SECT_NG (1U << 17)
71 #define ARM_MMU_SECT_S (1U << 16)
72 #define ARM_MMU_SECT_AP_2 (1U << 15)
73 #define ARM_MMU_SECT_TEX_2 (1U << 14)
74 #define ARM_MMU_SECT_TEX_1 (1U << 13)
75 #define ARM_MMU_SECT_TEX_0 (1U << 12)
76 #define ARM_MMU_SECT_TEX_SHIFT 12
77 #define ARM_MMU_SECT_TEX_MASK (0x3U << ARM_MMU_SECT_TEX_SHIFT)
78 #define ARM_MMU_SECT_AP_1 (1U << 11)
79 #define ARM_MMU_SECT_AP_0 (1U << 10)
80 #define ARM_MMU_SECT_AP_SHIFT 10
81 #define ARM_MMU_SECT_AP_MASK (0x23U << ARM_MMU_SECT_AP_SHIFT)
82 #define ARM_MMU_SECT_DOMAIN_SHIFT 5
83 #define ARM_MMU_SECT_DOMAIN_MASK (0xfU << ARM_MMU_SECT_DOMAIN_SHIFT)
84 #define ARM_MMU_SECT_XN (1U << 4)
85 #define ARM_MMU_SECT_C (1U << 3)
86 #define ARM_MMU_SECT_B (1U << 2)
87 #define ARM_MMU_SECT_PXN (1U << 0)
88 #define ARM_MMU_SECT_DEFAULT 0x2U
89 #define ARM_MMU_SECT_GET_INDEX(mva) \
90  (((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT)
91 #define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \
92  ((1U << ARM_MMU_SECT_BASE_SHIFT) \
93  + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U)))
94 
95 #define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U
96 #define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U
97 
98 #define ARM_MMU_DEFAULT_CLIENT_DOMAIN 15U
99 
100 #define ARMV7_MMU_READ_ONLY \
101  ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
102  | ARM_MMU_SECT_AP_0 \
103  | ARM_MMU_SECT_AP_2 \
104  | ARM_MMU_SECT_DEFAULT)
105 
106 #define ARMV7_MMU_READ_ONLY_CACHED \
107  (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
108 
109 #define ARMV7_MMU_READ_WRITE \
110  ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
111  | ARM_MMU_SECT_AP_0 \
112  | ARM_MMU_SECT_DEFAULT)
113 
114 #ifdef RTEMS_SMP
115  #define ARMV7_MMU_READ_WRITE_CACHED \
116  (ARMV7_MMU_READ_WRITE \
117  | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B | ARM_MMU_SECT_S)
118 #else
119  #define ARMV7_MMU_READ_WRITE_CACHED \
120  (ARMV7_MMU_READ_WRITE \
121  | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
122 #endif
123 
124 #define ARMV7_MMU_DATA_READ_ONLY \
125  (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
126 
127 #define ARMV7_MMU_DATA_READ_ONLY_CACHED \
128  ARMV7_MMU_READ_ONLY_CACHED
129 
130 #define ARMV7_MMU_DATA_READ_WRITE \
131  (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_TEX_0)
132 
133 #define ARMV7_MMU_DATA_READ_WRITE_CACHED \
134  ARMV7_MMU_READ_WRITE_CACHED
135 
136 #define ARMV7_MMU_CODE \
137  (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
138 
139 #define ARMV7_MMU_CODE_CACHED \
140  ARMV7_MMU_READ_ONLY_CACHED
141 
142 #define ARMV7_MMU_DEVICE \
143  (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_B)
144 
153 #define ARM_CP15_CTRL_TE (1U << 30)
154 #define ARM_CP15_CTRL_AFE (1U << 29)
155 #define ARM_CP15_CTRL_TRE (1U << 28)
156 #define ARM_CP15_CTRL_NMFI (1U << 27)
157 #define ARM_CP15_CTRL_EE (1U << 25)
158 #define ARM_CP15_CTRL_VE (1U << 24)
159 #define ARM_CP15_CTRL_XP (1U << 23)
160 #define ARM_CP15_CTRL_U (1U << 22)
161 #define ARM_CP15_CTRL_FI (1U << 21)
162 #define ARM_CP15_CTRL_UWXN (1U << 20)
163 #define ARM_CP15_CTRL_WXN (1U << 19)
164 #define ARM_CP15_CTRL_HA (1U << 17)
165 #define ARM_CP15_CTRL_L4 (1U << 15)
166 #define ARM_CP15_CTRL_RR (1U << 14)
167 #define ARM_CP15_CTRL_V (1U << 13)
168 #define ARM_CP15_CTRL_I (1U << 12)
169 #define ARM_CP15_CTRL_Z (1U << 11)
170 #define ARM_CP15_CTRL_SW (1U << 10)
171 #define ARM_CP15_CTRL_R (1U << 9)
172 #define ARM_CP15_CTRL_S (1U << 8)
173 #define ARM_CP15_CTRL_B (1U << 7)
174 #define ARM_CP15_CTRL_CP15BEN (1U << 5)
175 #define ARM_CP15_CTRL_C (1U << 2)
176 #define ARM_CP15_CTRL_A (1U << 1)
177 #define ARM_CP15_CTRL_M (1U << 0)
178 
187 #define ARM_CP15_DAC_NO_ACCESS 0x0U
188 #define ARM_CP15_DAC_CLIENT 0x1U
189 #define ARM_CP15_DAC_MANAGER 0x3U
190 #define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index))
191 
200 #define ARM_CP15_FAULT_STATUS_MASK 0x040F
201 
202 #define ARM_CP15_FSR_ALIGNMENT_FAULT 0x00000001
203 #define ARM_CP15_FSR_BACKGROUND_FAULT 0x0000
204 #define ARM_CP15_FSR_ACCESS_PERMISSION_FAULT 0x000D
205 #define ARM_CP15_FSR_PRECISE_EXTERNAL_ABORT_FAULT 0x0008
206 #define ARM_CP15_FSR_IMPRECISE_EXTERNAL_ABORT_FAULT 0x0406
207 #define ARM_CP15_FSR_PRECISE_PARITY_ERROR_EXCEPTION 0x0006
208 #define ARM_CP15_FSR_IMPRECISE_PARITY_ERROR_EXCEPTION 0x0408
209 #define ARM_CP15_FSR_DEBUG_EVENT 0x0002
210 
222 #define ARM_CP15_CACHE_TYPE_FORMAT_ARMV6 0
223 #define ARM_CP15_CACHE_TYPE_FORMAT_ARMV7 4
224 
233 #define ARM_CP15_CACHE_CSS_ID_DATA 0
234 #define ARM_CP15_CACHE_CSS_ID_INSTRUCTION 1
235 #define ARM_CP15_CACHE_CSS_LEVEL(level) ((level) << 1)
236 
239 ARM_CP15_TEXT_SECTION static inline uint32_t
240 arm_cp15_get_id_code(void)
241 {
242  ARM_SWITCH_REGISTERS;
243  uint32_t val;
244 
245  __asm__ volatile (
246  ARM_SWITCH_TO_ARM
247  "mrc p15, 0, %[val], c0, c0, 0\n"
248  ARM_SWITCH_BACK
249  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
250  );
251 
252  return val;
253 }
254 
255 ARM_CP15_TEXT_SECTION static inline uint32_t
256 arm_cp15_get_tcm_status(void)
257 {
258  ARM_SWITCH_REGISTERS;
259  uint32_t val;
260 
261  __asm__ volatile (
262  ARM_SWITCH_TO_ARM
263  "mrc p15, 0, %[val], c0, c0, 2\n"
264  ARM_SWITCH_BACK
265  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
266  );
267 
268  return val;
269 }
270 
271 ARM_CP15_TEXT_SECTION static inline uint32_t
272 arm_cp15_get_control(void)
273 {
274  ARM_SWITCH_REGISTERS;
275  uint32_t val;
276 
277  __asm__ volatile (
278  ARM_SWITCH_TO_ARM
279  "mrc p15, 0, %[val], c1, c0, 0\n"
280  ARM_SWITCH_BACK
281  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
282  );
283 
284  return val;
285 }
286 
287 ARM_CP15_TEXT_SECTION static inline void
288 arm_cp15_set_control(uint32_t val)
289 {
290  ARM_SWITCH_REGISTERS;
291 
292  __asm__ volatile (
293  ARM_SWITCH_TO_ARM
294  "mcr p15, 0, %[val], c1, c0, 0\n"
295  "nop\n"
296  "nop\n"
297  ARM_SWITCH_BACK
298  : ARM_SWITCH_OUTPUT
299  : [val] "r" (val)
300  : "memory"
301  );
302 }
303 
320 ARM_CP15_TEXT_SECTION static inline uint32_t
321 arm_cp15_mmu_disable(uint32_t cls)
322 {
323  ARM_SWITCH_REGISTERS;
324  uint32_t ctrl;
325  uint32_t tmp_0;
326  uint32_t tmp_1;
327 
328  __asm__ volatile (
329  ARM_SWITCH_TO_ARM
330  "mrc p15, 0, %[ctrl], c1, c0, 0\n"
331  "bic %[tmp_0], %[ctrl], #1\n"
332  "mcr p15, 0, %[tmp_0], c1, c0, 0\n"
333  "nop\n"
334  "nop\n"
335  "mov %[tmp_1], sp\n"
336  "rsb %[tmp_0], %[cls], #0\n"
337  "and %[tmp_0], %[tmp_0], %[tmp_1]\n"
338  "sub %[tmp_0], %[tmp_0], %[cls], asl #3\n"
339  "add %[tmp_1], %[tmp_0], %[cls], asl #4\n"
340  "1:\n"
341  "mcr p15, 0, %[tmp_0], c7, c14, 1\n"
342  "add %[tmp_0], %[tmp_0], %[cls]\n"
343  "cmp %[tmp_1], %[tmp_0]\n"
344  "bne 1b\n"
345  ARM_SWITCH_BACK
346  : [ctrl] "=&r" (ctrl),
347  [tmp_0] "=&r" (tmp_0),
348  [tmp_1] "=&r" (tmp_1)
349  ARM_SWITCH_ADDITIONAL_OUTPUT
350  : [cls] "r" (cls)
351  : "memory", "cc"
352  );
353 
354  return ctrl;
355 }
356 
357 ARM_CP15_TEXT_SECTION static inline uint32_t
358 *arm_cp15_get_translation_table_base(void)
359 {
360  ARM_SWITCH_REGISTERS;
361  uint32_t *base;
362 
363  __asm__ volatile (
364  ARM_SWITCH_TO_ARM
365  "mrc p15, 0, %[base], c2, c0, 0\n"
366  ARM_SWITCH_BACK
367  : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
368  );
369 
370  return base;
371 }
372 
373 ARM_CP15_TEXT_SECTION static inline void
374 arm_cp15_set_translation_table_base(uint32_t *base)
375 {
376  ARM_SWITCH_REGISTERS;
377 
378  __asm__ volatile (
379  ARM_SWITCH_TO_ARM
380  "mcr p15, 0, %[base], c2, c0, 0\n"
381  ARM_SWITCH_BACK
382  : ARM_SWITCH_OUTPUT
383  : [base] "r" (base)
384  );
385 }
386 
387 /* Translation Table Base Control Register - DDI0301H arm1176jzfs TRM 3.2.15 */
388 ARM_CP15_TEXT_SECTION static inline uint32_t
389 arm_cp15_get_translation_table_base_control_register(void)
390 {
391  ARM_SWITCH_REGISTERS;
392  uint32_t ttb_cr;
393 
394  __asm__ volatile (
395  ARM_SWITCH_TO_ARM
396  "mrc p15, 0, %[ttb_cr], c2, c0, 2\n"
397  ARM_SWITCH_BACK
398  : [ttb_cr] "=&r" (ttb_cr) ARM_SWITCH_ADDITIONAL_OUTPUT
399  );
400 
401  return ttb_cr;
402 }
403 
404 ARM_CP15_TEXT_SECTION static inline void
405 arm_cp15_set_translation_table_base_control_register(uint32_t ttb_cr)
406 {
407  ARM_SWITCH_REGISTERS;
408 
409  __asm__ volatile (
410  ARM_SWITCH_TO_ARM
411  "mcr p15, 0, %[ttb_cr], c2, c0, 2\n"
412  ARM_SWITCH_BACK
413  : ARM_SWITCH_OUTPUT
414  : [ttb_cr] "r" (ttb_cr)
415  );
416 }
417 
418 ARM_CP15_TEXT_SECTION static inline uint32_t
419 arm_cp15_get_domain_access_control(void)
420 {
421  ARM_SWITCH_REGISTERS;
422  uint32_t val;
423 
424  __asm__ volatile (
425  ARM_SWITCH_TO_ARM
426  "mrc p15, 0, %[val], c3, c0, 0\n"
427  ARM_SWITCH_BACK
428  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
429  );
430 
431  return val;
432 }
433 
434 ARM_CP15_TEXT_SECTION static inline void
435 arm_cp15_set_domain_access_control(uint32_t val)
436 {
437  ARM_SWITCH_REGISTERS;
438 
439  __asm__ volatile (
440  ARM_SWITCH_TO_ARM
441  "mcr p15, 0, %[val], c3, c0, 0\n"
442  ARM_SWITCH_BACK
443  : ARM_SWITCH_OUTPUT
444  : [val] "r" (val)
445  );
446 }
447 
448 ARM_CP15_TEXT_SECTION static inline uint32_t
449 arm_cp15_get_data_fault_status(void)
450 {
451  ARM_SWITCH_REGISTERS;
452  uint32_t val;
453 
454  __asm__ volatile (
455  ARM_SWITCH_TO_ARM
456  "mrc p15, 0, %[val], c5, c0, 0\n"
457  ARM_SWITCH_BACK
458  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
459  );
460 
461  return val;
462 }
463 
464 ARM_CP15_TEXT_SECTION static inline void
465 arm_cp15_set_data_fault_status(uint32_t val)
466 {
467  ARM_SWITCH_REGISTERS;
468 
469  __asm__ volatile (
470  ARM_SWITCH_TO_ARM
471  "mcr p15, 0, %[val], c5, c0, 0\n"
472  ARM_SWITCH_BACK
473  : ARM_SWITCH_OUTPUT
474  : [val] "r" (val)
475  );
476 }
477 
478 ARM_CP15_TEXT_SECTION static inline uint32_t
479 arm_cp15_get_instruction_fault_status(void)
480 {
481  ARM_SWITCH_REGISTERS;
482  uint32_t val;
483 
484  __asm__ volatile (
485  ARM_SWITCH_TO_ARM
486  "mrc p15, 0, %[val], c5, c0, 1\n"
487  ARM_SWITCH_BACK
488  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
489  );
490 
491  return val;
492 }
493 
494 ARM_CP15_TEXT_SECTION static inline void
495 arm_cp15_set_instruction_fault_status(uint32_t val)
496 {
497  ARM_SWITCH_REGISTERS;
498 
499  __asm__ volatile (
500  ARM_SWITCH_TO_ARM
501  "mcr p15, 0, %[val], c5, c0, 1\n"
502  ARM_SWITCH_BACK
503  : ARM_SWITCH_OUTPUT
504  : [val] "r" (val)
505  );
506 }
507 
508 ARM_CP15_TEXT_SECTION static inline void
509 *arm_cp15_get_fault_address(void)
510 {
511  ARM_SWITCH_REGISTERS;
512  void *mva;
513 
514  __asm__ volatile (
515  ARM_SWITCH_TO_ARM
516  "mrc p15, 0, %[mva], c6, c0, 0\n"
517  ARM_SWITCH_BACK
518  : [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT
519  );
520 
521  return mva;
522 }
523 
524 ARM_CP15_TEXT_SECTION static inline void
525 arm_cp15_set_fault_address(const void *mva)
526 {
527  ARM_SWITCH_REGISTERS;
528 
529  __asm__ volatile (
530  ARM_SWITCH_TO_ARM
531  "mcr p15, 0, %[mva], c6, c0, 0\n"
532  ARM_SWITCH_BACK
533  : ARM_SWITCH_OUTPUT
534  : [mva] "r" (mva)
535  );
536 }
537 
538 ARM_CP15_TEXT_SECTION static inline void
539 arm_cp15_tlb_invalidate(void)
540 {
541  ARM_SWITCH_REGISTERS;
542  uint32_t sbz = 0;
543 
544  __asm__ volatile (
545  ARM_SWITCH_TO_ARM
546  "mcr p15, 0, %[sbz], c8, c7, 0\n"
547  ARM_SWITCH_BACK
548  : ARM_SWITCH_OUTPUT
549  : [sbz] "r" (sbz)
550  );
551 
552  /*
553  * ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, Issue C,
554  * B3.10.1 General TLB maintenance requirements.
555  */
556  _ARM_Data_synchronization_barrier();
557  _ARM_Instruction_synchronization_barrier();
558 }
559 
560 ARM_CP15_TEXT_SECTION static inline void
561 arm_cp15_tlb_invalidate_entry(const void *mva)
562 {
563  ARM_SWITCH_REGISTERS;
564 
565  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
566 
567  __asm__ volatile (
568  ARM_SWITCH_TO_ARM
569  "mcr p15, 0, %[mva], c8, c7, 1\n"
570  ARM_SWITCH_BACK
571  : ARM_SWITCH_OUTPUT
572  : [mva] "r" (mva)
573  );
574 }
575 
576 ARM_CP15_TEXT_SECTION static inline void
577 arm_cp15_tlb_invalidate_entry_all_asids(const void *mva)
578 {
579  ARM_SWITCH_REGISTERS;
580 
581  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
582 
583  __asm__ volatile (
584  ARM_SWITCH_TO_ARM
585  "mcr p15, 0, %[mva], c8, c7, 3\n"
586  ARM_SWITCH_BACK
587  : ARM_SWITCH_OUTPUT
588  : [mva] "r" (mva)
589  );
590 }
591 
592 ARM_CP15_TEXT_SECTION static inline void
593 arm_cp15_tlb_instruction_invalidate(void)
594 {
595  ARM_SWITCH_REGISTERS;
596  uint32_t sbz = 0;
597 
598  __asm__ volatile (
599  ARM_SWITCH_TO_ARM
600  "mcr p15, 0, %[sbz], c8, c5, 0\n"
601  ARM_SWITCH_BACK
602  : ARM_SWITCH_OUTPUT
603  : [sbz] "r" (sbz)
604  );
605 }
606 
607 ARM_CP15_TEXT_SECTION static inline void
608 arm_cp15_tlb_instruction_invalidate_entry(const void *mva)
609 {
610  ARM_SWITCH_REGISTERS;
611 
612  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
613 
614  __asm__ volatile (
615  ARM_SWITCH_TO_ARM
616  "mcr p15, 0, %[mva], c8, c5, 1\n"
617  ARM_SWITCH_BACK
618  : ARM_SWITCH_OUTPUT
619  : [mva] "r" (mva)
620  );
621 }
622 
623 ARM_CP15_TEXT_SECTION static inline void
624 arm_cp15_tlb_data_invalidate(void)
625 {
626  ARM_SWITCH_REGISTERS;
627  uint32_t sbz = 0;
628 
629  __asm__ volatile (
630  ARM_SWITCH_TO_ARM
631  "mcr p15, 0, %[sbz], c8, c6, 0\n"
632  ARM_SWITCH_BACK
633  : ARM_SWITCH_OUTPUT
634  : [sbz] "r" (sbz)
635  );
636 }
637 
638 ARM_CP15_TEXT_SECTION static inline void
639 arm_cp15_tlb_data_invalidate_entry(const void *mva)
640 {
641  ARM_SWITCH_REGISTERS;
642 
643  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
644 
645  __asm__ volatile (
646  ARM_SWITCH_TO_ARM
647  "mcr p15, 0, %[mva], c8, c6, 1\n"
648  ARM_SWITCH_BACK
649  : ARM_SWITCH_OUTPUT
650  : [mva] "r" (mva)
651  );
652 }
653 
654 ARM_CP15_TEXT_SECTION static inline void
655 arm_cp15_tlb_lockdown_entry(const void *mva)
656 {
657  uint32_t arm_switch_reg;
658 
659  __asm__ volatile (
660  ARM_SWITCH_TO_ARM
661  "add %[arm_switch_reg], pc, #16\n"
662  "mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n"
663  "mcr p15, 0, %[mva], c8, c7, 1\n"
664  "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
665  "orr %[arm_switch_reg], #0x1\n"
666  "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
667  "ldr %[mva], [%[mva]]\n"
668  "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
669  "bic %[arm_switch_reg], #0x1\n"
670  "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
671  ARM_SWITCH_BACK
672  : [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg)
673  : "[mva]" (mva)
674  );
675 }
676 
685 /* Read cache type register CTR */
686 ARM_CP15_TEXT_SECTION static inline uint32_t
687 arm_cp15_get_cache_type(void)
688 {
689  ARM_SWITCH_REGISTERS;
690  uint32_t val;
691 
692  __asm__ volatile (
693  ARM_SWITCH_TO_ARM
694  "mrc p15, 0, %[val], c0, c0, 1\n"
695  ARM_SWITCH_BACK
696  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
697  );
698 
699  return val;
700 }
701 
702 /* Extract format version from cache type CTR */
703 ARM_CP15_TEXT_SECTION static inline int
704 arm_cp15_cache_type_get_format(uint32_t ct)
705 {
706  return (ct >> 29) & 0x7U;
707 }
708 
709 /* Read size of smallest cache line of all instruction/data caches controlled by the processor */
710 ARM_CP15_TEXT_SECTION static inline uint32_t
711 arm_cp15_get_min_cache_line_size(void)
712 {
713  uint32_t mcls = 0;
714  uint32_t ct = arm_cp15_get_cache_type();
715  uint32_t format = arm_cp15_cache_type_get_format(ct);
716 
717  if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
718  /* ARMv7 format */
719  mcls = (1U << (ct & 0xf)) * 4;
720  } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
721  /* ARMv6 format */
722  uint32_t mask = (1U << 12) - 1;
723  uint32_t dcls = (ct >> 12) & mask;
724  uint32_t icls = ct & mask;
725 
726  mcls = dcls <= icls ? dcls : icls;
727  }
728 
729  return mcls;
730 }
731 
732 /* Read size of smallest data cache lines */
733 ARM_CP15_TEXT_SECTION static inline uint32_t
734 arm_cp15_get_data_cache_line_size(void)
735 {
736  uint32_t mcls = 0;
737  uint32_t ct = arm_cp15_get_cache_type();
738  uint32_t format = arm_cp15_cache_type_get_format(ct);
739 
740  if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
741  /* ARMv7 format */
742  mcls = (1U << ((ct & 0xf0000) >> 16)) * 4;
743  } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
744  /* ARMv6 format */
745  uint32_t mask = (1U << 12) - 1;
746  mcls = (ct >> 12) & mask;
747  }
748 
749  return mcls;
750 }
751 
752 /* Read size of smallest instruction cache lines */
753 ARM_CP15_TEXT_SECTION static inline uint32_t
754 arm_cp15_get_instruction_cache_line_size(void)
755 {
756  uint32_t mcls = 0;
757  uint32_t ct = arm_cp15_get_cache_type();
758  uint32_t format = arm_cp15_cache_type_get_format(ct);
759 
760  if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
761  /* ARMv7 format */
762  mcls = (1U << (ct & 0x0000f)) * 4;
763  } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
764  /* ARMv6 format */
765  uint32_t mask = (1U << 12) - 1;
766  mcls = ct & mask;;
767  }
768 
769  return mcls;
770 }
771 
772 /* CCSIDR, Cache Size ID Register */
773 
774 ARM_CP15_TEXT_SECTION static inline uint32_t
775 arm_cp15_get_cache_size_id(void)
776 {
777  ARM_SWITCH_REGISTERS;
778  uint32_t val;
779 
780  __asm__ volatile (
781  ARM_SWITCH_TO_ARM
782  "mrc p15, 1, %[val], c0, c0, 0\n"
783  ARM_SWITCH_BACK
784  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
785  );
786 
787  return val;
788 }
789 
790 ARM_CP15_TEXT_SECTION static inline uint32_t
791 arm_ccsidr_get_line_power(uint32_t ccsidr)
792 {
793  return (ccsidr & 0x7) + 4;
794 }
795 
796 ARM_CP15_TEXT_SECTION static inline uint32_t
797 arm_ccsidr_get_associativity(uint32_t ccsidr)
798 {
799  return ((ccsidr >> 3) & 0x3ff) + 1;
800 }
801 
802 ARM_CP15_TEXT_SECTION static inline uint32_t
803 arm_ccsidr_get_num_sets(uint32_t ccsidr)
804 {
805  return ((ccsidr >> 13) & 0x7fff) + 1;
806 }
807 
808 /* CLIDR, Cache Level ID Register */
809 
810 ARM_CP15_TEXT_SECTION static inline uint32_t
811 arm_cp15_get_cache_level_id(void)
812 {
813  ARM_SWITCH_REGISTERS;
814  uint32_t val;
815 
816  __asm__ volatile (
817  ARM_SWITCH_TO_ARM
818  "mrc p15, 1, %[val], c0, c0, 1\n"
819  ARM_SWITCH_BACK
820  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
821  );
822 
823  return val;
824 }
825 
826 ARM_CP15_TEXT_SECTION static inline uint32_t
827 arm_clidr_get_level_of_coherency(uint32_t clidr)
828 {
829  return (clidr >> 24) & 0x7;
830 }
831 
832 ARM_CP15_TEXT_SECTION static inline uint32_t
833 arm_clidr_get_cache_type(uint32_t clidr, uint32_t level)
834 {
835  return (clidr >> (3 * level)) & 0x7;
836 }
837 
838 /* CSSELR, Cache Size Selection Register */
839 
840 ARM_CP15_TEXT_SECTION static inline uint32_t
841 arm_cp15_get_cache_size_selection(void)
842 {
843  ARM_SWITCH_REGISTERS;
844  uint32_t val;
845 
846  __asm__ volatile (
847  ARM_SWITCH_TO_ARM
848  "mrc p15, 2, %[val], c0, c0, 0\n"
849  ARM_SWITCH_BACK
850  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
851  );
852 
853  return val;
854 }
855 
856 ARM_CP15_TEXT_SECTION static inline void
857 arm_cp15_set_cache_size_selection(uint32_t val)
858 {
859  ARM_SWITCH_REGISTERS;
860 
861  __asm__ volatile (
862  ARM_SWITCH_TO_ARM
863  "mcr p15, 2, %[val], c0, c0, 0\n"
864  ARM_SWITCH_BACK
865  : ARM_SWITCH_OUTPUT
866  : [val] "r" (val)
867  : "memory"
868  );
869 }
870 
871 ARM_CP15_TEXT_SECTION static inline uint32_t
872 arm_cp15_get_cache_size_id_for_level(uint32_t level_and_inst_dat)
873 {
874  rtems_interrupt_level irq_level;
875  uint32_t ccsidr;
876 
878  arm_cp15_set_cache_size_selection(level_and_inst_dat);
879  _ARM_Instruction_synchronization_barrier();
880  ccsidr = arm_cp15_get_cache_size_id();
881  rtems_interrupt_local_enable(irq_level);
882 
883  return ccsidr;
884 }
885 
886 ARM_CP15_TEXT_SECTION static inline void
887 arm_cp15_cache_invalidate(void)
888 {
889  ARM_SWITCH_REGISTERS;
890  uint32_t sbz = 0;
891 
892  __asm__ volatile (
893  ARM_SWITCH_TO_ARM
894  "mcr p15, 0, %[sbz], c7, c7, 0\n"
895  ARM_SWITCH_BACK
896  : ARM_SWITCH_OUTPUT
897  : [sbz] "r" (sbz)
898  : "memory"
899  );
900 }
901 
902 /* ICIALLUIS, Instruction Cache Invalidate All to PoU, Inner Shareable */
903 
904 ARM_CP15_TEXT_SECTION static inline void
905 arm_cp15_instruction_cache_inner_shareable_invalidate_all(void)
906 {
907  ARM_SWITCH_REGISTERS;
908  uint32_t sbz = 0;
909 
910  __asm__ volatile (
911  ARM_SWITCH_TO_ARM
912  "mcr p15, 0, %[sbz], c7, c1, 0\n"
913  ARM_SWITCH_BACK
914  : ARM_SWITCH_OUTPUT
915  : [sbz] "r" (sbz)
916  : "memory"
917  );
918 }
919 
920 /* BPIALLIS, Branch Predictor Invalidate All, Inner Shareable */
921 
922 ARM_CP15_TEXT_SECTION static inline void
923 arm_cp15_branch_predictor_inner_shareable_invalidate_all(void)
924 {
925  ARM_SWITCH_REGISTERS;
926  uint32_t sbz = 0;
927 
928  __asm__ volatile (
929  ARM_SWITCH_TO_ARM
930  "mcr p15, 0, %[sbz], c7, c1, 6\n"
931  ARM_SWITCH_BACK
932  : ARM_SWITCH_OUTPUT
933  : [sbz] "r" (sbz)
934  : "memory"
935  );
936 }
937 
938 /* BPIALL, Branch Predictor Invalidate All */
939 
940 ARM_CP15_TEXT_SECTION static inline void
941 arm_cp15_branch_predictor_invalidate_all(void)
942 {
943  ARM_SWITCH_REGISTERS;
944  uint32_t sbz = 0;
945 
946  __asm__ volatile (
947  ARM_SWITCH_TO_ARM
948  "mcr p15, 0, %[sbz], c7, c5, 6\n"
949  ARM_SWITCH_BACK
950  : ARM_SWITCH_OUTPUT
951  : [sbz] "r" (sbz)
952  : "memory"
953  );
954 }
955 
956 /* Flush Prefetch Buffer - DDI0301H arm1176jzfs TRM 3.2.22 */
957 ARM_CP15_TEXT_SECTION static inline void
958 arm_cp15_flush_prefetch_buffer(void)
959 {
960  ARM_SWITCH_REGISTERS;
961  uint32_t sbz = 0;
962 
963  __asm__ volatile (
964  ARM_SWITCH_TO_ARM
965  "mcr p15, 0, %[sbz], c7, c5, 4\n"
966  ARM_SWITCH_BACK
967  : ARM_SWITCH_OUTPUT
968  : [sbz] "r" (sbz)
969  : "memory"
970  );
971 }
972 
973 ARM_CP15_TEXT_SECTION static inline void
974 arm_cp15_instruction_cache_invalidate(void)
975 {
976  ARM_SWITCH_REGISTERS;
977  uint32_t sbz = 0;
978 
979  __asm__ volatile (
980  ARM_SWITCH_TO_ARM
981  "mcr p15, 0, %[sbz], c7, c5, 0\n"
982  ARM_SWITCH_BACK
983  : ARM_SWITCH_OUTPUT
984  : [sbz] "r" (sbz)
985  : "memory"
986  );
987 }
988 
989 ARM_CP15_TEXT_SECTION static inline void
990 arm_cp15_instruction_cache_invalidate_line(const void *mva)
991 {
992  ARM_SWITCH_REGISTERS;
993 
994  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
995 
996  __asm__ volatile (
997  ARM_SWITCH_TO_ARM
998  "mcr p15, 0, %[mva], c7, c5, 1\n"
999  ARM_SWITCH_BACK
1000  : ARM_SWITCH_OUTPUT
1001  : [mva] "r" (mva)
1002  : "memory"
1003  );
1004 }
1005 
1006 ARM_CP15_TEXT_SECTION static inline void
1007 arm_cp15_instruction_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
1008 {
1009  ARM_SWITCH_REGISTERS;
1010 
1011  __asm__ volatile (
1012  ARM_SWITCH_TO_ARM
1013  "mcr p15, 0, %[set_and_way], c7, c5, 2\n"
1014  ARM_SWITCH_BACK
1015  : ARM_SWITCH_OUTPUT
1016  : [set_and_way] "r" (set_and_way)
1017  : "memory"
1018  );
1019 }
1020 
1021 ARM_CP15_TEXT_SECTION static inline void
1022 arm_cp15_instruction_cache_prefetch_line(const void *mva)
1023 {
1024  ARM_SWITCH_REGISTERS;
1025 
1026  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1027 
1028  __asm__ volatile (
1029  ARM_SWITCH_TO_ARM
1030  "mcr p15, 0, %[mva], c7, c13, 1\n"
1031  ARM_SWITCH_BACK
1032  : ARM_SWITCH_OUTPUT
1033  : [mva] "r" (mva)
1034  );
1035 }
1036 
1037 ARM_CP15_TEXT_SECTION static inline void
1038 arm_cp15_data_cache_invalidate(void)
1039 {
1040  ARM_SWITCH_REGISTERS;
1041  uint32_t sbz = 0;
1042 
1043  __asm__ volatile (
1044  ARM_SWITCH_TO_ARM
1045  "mcr p15, 0, %[sbz], c7, c6, 0\n"
1046  ARM_SWITCH_BACK
1047  : ARM_SWITCH_OUTPUT
1048  : [sbz] "r" (sbz)
1049  : "memory"
1050  );
1051 }
1052 
1053 ARM_CP15_TEXT_SECTION static inline void
1054 arm_cp15_data_cache_invalidate_line(const void *mva)
1055 {
1056  ARM_SWITCH_REGISTERS;
1057 
1058  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1059 
1060  __asm__ volatile (
1061  ARM_SWITCH_TO_ARM
1062  "mcr p15, 0, %[mva], c7, c6, 1\n"
1063  ARM_SWITCH_BACK
1064  : ARM_SWITCH_OUTPUT
1065  : [mva] "r" (mva)
1066  : "memory"
1067  );
1068 }
1069 
1070 ARM_CP15_TEXT_SECTION static inline void
1071 arm_cp15_data_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
1072 {
1073  ARM_SWITCH_REGISTERS;
1074 
1075  __asm__ volatile (
1076  ARM_SWITCH_TO_ARM
1077  "mcr p15, 0, %[set_and_way], c7, c6, 2\n"
1078  ARM_SWITCH_BACK
1079  : ARM_SWITCH_OUTPUT
1080  : [set_and_way] "r" (set_and_way)
1081  : "memory"
1082  );
1083 }
1084 
1085 ARM_CP15_TEXT_SECTION static inline void
1086 arm_cp15_cache_invalidate_level(uint32_t level, uint32_t inst_data_fl)
1087 {
1088  uint32_t ccsidr;
1089  uint32_t line_power;
1090  uint32_t associativity;
1091  uint32_t way;
1092  uint32_t way_shift;
1093 
1094  ccsidr = arm_cp15_get_cache_size_id_for_level((level << 1) | inst_data_fl);
1095 
1096  line_power = arm_ccsidr_get_line_power(ccsidr);
1097  associativity = arm_ccsidr_get_associativity(ccsidr);
1098  way_shift = __builtin_clz(associativity - 1);
1099 
1100  for (way = 0; way < associativity; ++way) {
1101  uint32_t num_sets = arm_ccsidr_get_num_sets(ccsidr);
1102  uint32_t set;
1103 
1104  for (set = 0; set < num_sets; ++set) {
1105  uint32_t set_way = (way << way_shift)
1106  | (set << line_power)
1107  | (level << 1);
1108 
1109  arm_cp15_data_cache_invalidate_line_by_set_and_way(set_way);
1110  }
1111  }
1112 }
1113 
1114 ARM_CP15_TEXT_SECTION static inline void
1115 arm_cp15_data_cache_invalidate_all_levels(void)
1116 {
1117  uint32_t clidr = arm_cp15_get_cache_level_id();
1118  uint32_t loc = arm_clidr_get_level_of_coherency(clidr);
1119  uint32_t level = 0;
1120 
1121  for (level = 0; level < loc; ++level) {
1122  uint32_t ctype = arm_clidr_get_cache_type(clidr, level);
1123 
1124  /* Check if this level has a data cache or unified cache */
1125  if (((ctype & (0x6)) == 2) || (ctype == 4)) {
1126  arm_cp15_cache_invalidate_level(level, 0);
1127  }
1128  }
1129 }
1130 
1131 ARM_CP15_TEXT_SECTION static inline void
1132 arm_cp15_data_cache_clean_line(const void *mva)
1133 {
1134  ARM_SWITCH_REGISTERS;
1135 
1136  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1137 
1138  __asm__ volatile (
1139  ARM_SWITCH_TO_ARM
1140  "mcr p15, 0, %[mva], c7, c10, 1\n"
1141  ARM_SWITCH_BACK
1142  : ARM_SWITCH_OUTPUT
1143  : [mva] "r" (mva)
1144  : "memory"
1145  );
1146 }
1147 
1148 ARM_CP15_TEXT_SECTION static inline void
1149 arm_cp15_data_cache_clean_line_by_set_and_way(uint32_t set_and_way)
1150 {
1151  ARM_SWITCH_REGISTERS;
1152 
1153  __asm__ volatile (
1154  ARM_SWITCH_TO_ARM
1155  "mcr p15, 0, %[set_and_way], c7, c10, 2\n"
1156  ARM_SWITCH_BACK
1157  : ARM_SWITCH_OUTPUT
1158  : [set_and_way] "r" (set_and_way)
1159  : "memory"
1160  );
1161 }
1162 
1163 ARM_CP15_TEXT_SECTION static inline void
1164 arm_cp15_data_cache_clean_level(uint32_t level)
1165 {
1166  uint32_t ccsidr;
1167  uint32_t line_power;
1168  uint32_t associativity;
1169  uint32_t way;
1170  uint32_t way_shift;
1171 
1172  ccsidr = arm_cp15_get_cache_size_id_for_level(level << 1);
1173 
1174  line_power = arm_ccsidr_get_line_power(ccsidr);
1175  associativity = arm_ccsidr_get_associativity(ccsidr);
1176  way_shift = __builtin_clz(associativity - 1);
1177 
1178  for (way = 0; way < associativity; ++way) {
1179  uint32_t num_sets = arm_ccsidr_get_num_sets(ccsidr);
1180  uint32_t set;
1181 
1182  for (set = 0; set < num_sets; ++set) {
1183  uint32_t set_way = (way << way_shift)
1184  | (set << line_power)
1185  | (level << 1);
1186 
1187  arm_cp15_data_cache_clean_line_by_set_and_way(set_way);
1188  }
1189  }
1190 }
1191 
1192 ARM_CP15_TEXT_SECTION static inline void
1193 arm_cp15_data_cache_clean_all_levels(void)
1194 {
1195  uint32_t clidr = arm_cp15_get_cache_level_id();
1196  uint32_t loc = arm_clidr_get_level_of_coherency(clidr);
1197  uint32_t level = 0;
1198 
1199  for (level = 0; level < loc; ++level) {
1200  uint32_t ctype = arm_clidr_get_cache_type(clidr, level);
1201 
1202  /* Check if this level has a data cache or unified cache */
1203  if (((ctype & (0x6)) == 2) || (ctype == 4)) {
1204  arm_cp15_data_cache_clean_level(level);
1205  }
1206  }
1207 }
1208 
1209 ARM_CP15_TEXT_SECTION static inline void
1210 arm_cp15_data_cache_test_and_clean(void)
1211 {
1212  ARM_SWITCH_REGISTERS;
1213 
1214  __asm__ volatile (
1215  ARM_SWITCH_TO_ARM
1216  "1:\n"
1217  "mrc p15, 0, r15, c7, c10, 3\n"
1218  "bne 1b\n"
1219  ARM_SWITCH_BACK
1220  : ARM_SWITCH_OUTPUT
1221  :
1222  : "memory"
1223  );
1224 }
1225 
1226 /* In DDI0301H_arm1176jzfs_r0p7_trm
1227  * 'MCR p15, 0, <Rd>, c7, c14, 0' means
1228  * Clean and Invalidate Entire Data Cache
1229  */
1230 ARM_CP15_TEXT_SECTION static inline void
1231 arm_cp15_data_cache_clean_and_invalidate(void)
1232 {
1233  ARM_SWITCH_REGISTERS;
1234 
1235  uint32_t sbz = 0;
1236 
1237  __asm__ volatile (
1238  ARM_SWITCH_TO_ARM
1239  "mcr p15, 0, %[sbz], c7, c14, 0\n"
1240  ARM_SWITCH_BACK
1241  : ARM_SWITCH_OUTPUT
1242  : [sbz] "r" (sbz)
1243  : "memory"
1244  );
1245 }
1246 
1247 ARM_CP15_TEXT_SECTION static inline void
1248 arm_cp15_data_cache_clean_and_invalidate_line(const void *mva)
1249 {
1250  ARM_SWITCH_REGISTERS;
1251 
1252  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1253 
1254  __asm__ volatile (
1255  ARM_SWITCH_TO_ARM
1256  "mcr p15, 0, %[mva], c7, c14, 1\n"
1257  ARM_SWITCH_BACK
1258  : ARM_SWITCH_OUTPUT
1259  : [mva] "r" (mva)
1260  : "memory"
1261  );
1262 }
1263 
1264 ARM_CP15_TEXT_SECTION static inline void
1265 arm_cp15_data_cache_clean_and_invalidate_line_by_set_and_way(uint32_t set_and_way)
1266 {
1267  ARM_SWITCH_REGISTERS;
1268 
1269  __asm__ volatile (
1270  ARM_SWITCH_TO_ARM
1271  "mcr p15, 0, %[set_and_way], c7, c14, 2\n"
1272  ARM_SWITCH_BACK
1273  : ARM_SWITCH_OUTPUT
1274  : [set_and_way] "r" (set_and_way)
1275  : "memory"
1276  );
1277 }
1278 
1279 ARM_CP15_TEXT_SECTION static inline void
1280 arm_cp15_data_cache_test_and_clean_and_invalidate(void)
1281 {
1282  ARM_SWITCH_REGISTERS;
1283 
1284  __asm__ volatile (
1285  ARM_SWITCH_TO_ARM
1286  "1:\n"
1287  "mrc p15, 0, r15, c7, c14, 3\n"
1288  "bne 1b\n"
1289  ARM_SWITCH_BACK
1290  : ARM_SWITCH_OUTPUT
1291  :
1292  : "memory"
1293  );
1294 }
1295 
1298 ARM_CP15_TEXT_SECTION static inline void
1299 arm_cp15_drain_write_buffer(void)
1300 {
1301  ARM_SWITCH_REGISTERS;
1302  uint32_t sbz = 0;
1303 
1304  __asm__ volatile (
1305  ARM_SWITCH_TO_ARM
1306  "mcr p15, 0, %[sbz], c7, c10, 4\n"
1307  ARM_SWITCH_BACK
1308  : ARM_SWITCH_OUTPUT
1309  : [sbz] "r" (sbz)
1310  : "memory"
1311  );
1312 }
1313 
1314 ARM_CP15_TEXT_SECTION static inline void
1315 arm_cp15_wait_for_interrupt(void)
1316 {
1317  ARM_SWITCH_REGISTERS;
1318  uint32_t sbz = 0;
1319 
1320  __asm__ volatile (
1321  ARM_SWITCH_TO_ARM
1322  "mcr p15, 0, %[sbz], c7, c0, 4\n"
1323  ARM_SWITCH_BACK
1324  : ARM_SWITCH_OUTPUT
1325  : [sbz] "r" (sbz)
1326  : "memory"
1327  );
1328 }
1329 
1330 ARM_CP15_TEXT_SECTION static inline uint32_t
1331 arm_cp15_get_multiprocessor_affinity(void)
1332 {
1333  ARM_SWITCH_REGISTERS;
1334  uint32_t mpidr;
1335 
1336  __asm__ volatile (
1337  ARM_SWITCH_TO_ARM
1338  "mrc p15, 0, %[mpidr], c0, c0, 5\n"
1339  ARM_SWITCH_BACK
1340  : [mpidr] "=&r" (mpidr) ARM_SWITCH_ADDITIONAL_OUTPUT
1341  );
1342 
1343  return mpidr & 0xff;
1344 }
1345 
1346 ARM_CP15_TEXT_SECTION static inline uint32_t
1347 arm_cortex_a9_get_multiprocessor_cpu_id(void)
1348 {
1349  return arm_cp15_get_multiprocessor_affinity() & 0xff;
1350 }
1351 
1352 #define ARM_CORTEX_A9_ACTL_FW (1U << 0)
1353 #define ARM_CORTEX_A9_ACTL_L2_PREFETCH_HINT_ENABLE (1U << 1)
1354 #define ARM_CORTEX_A9_ACTL_L1_PREFETCH_ENABLE (1U << 2)
1355 #define ARM_CORTEX_A9_ACTL_WRITE_FULL_LINE_OF_ZEROS_MODE (1U << 3)
1356 #define ARM_CORTEX_A9_ACTL_SMP (1U << 6)
1357 #define ARM_CORTEX_A9_ACTL_EXCL (1U << 7)
1358 #define ARM_CORTEX_A9_ACTL_ALLOC_IN_ONE_WAY (1U << 8)
1359 #define ARM_CORTEX_A9_ACTL_PARITY_ON (1U << 9)
1360 
1361 ARM_CP15_TEXT_SECTION static inline uint32_t
1362 arm_cp15_get_auxiliary_control(void)
1363 {
1364  ARM_SWITCH_REGISTERS;
1365  uint32_t val;
1366 
1367  __asm__ volatile (
1368  ARM_SWITCH_TO_ARM
1369  "mrc p15, 0, %[val], c1, c0, 1\n"
1370  ARM_SWITCH_BACK
1371  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1372  );
1373 
1374  return val;
1375 }
1376 
1377 ARM_CP15_TEXT_SECTION static inline void
1378 arm_cp15_set_auxiliary_control(uint32_t val)
1379 {
1380  ARM_SWITCH_REGISTERS;
1381 
1382  __asm__ volatile (
1383  ARM_SWITCH_TO_ARM
1384  "mcr p15, 0, %[val], c1, c0, 1\n"
1385  ARM_SWITCH_BACK
1386  : ARM_SWITCH_OUTPUT
1387  : [val] "r" (val)
1388  );
1389 }
1390 
1391 /* ID_PFR1, Processor Feature Register 1 */
1392 
1393 ARM_CP15_TEXT_SECTION static inline uint32_t
1394 arm_cp15_get_processor_feature_1(void)
1395 {
1396  ARM_SWITCH_REGISTERS;
1397  uint32_t val;
1398 
1399  __asm__ volatile (
1400  ARM_SWITCH_TO_ARM
1401  "mrc p15, 0, %[val], c0, c1, 1\n"
1402  ARM_SWITCH_BACK
1403  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1404  );
1405 
1406  return val;
1407 }
1408 
1409 /* VBAR, Vector Base Address Register, Security Extensions */
1410 
1411 ARM_CP15_TEXT_SECTION static inline void
1412 *arm_cp15_get_vector_base_address(void)
1413 {
1414  ARM_SWITCH_REGISTERS;
1415  void *base;
1416 
1417  __asm__ volatile (
1418  ARM_SWITCH_TO_ARM
1419  "mrc p15, 0, %[base], c12, c0, 0\n"
1420  ARM_SWITCH_BACK
1421  : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
1422  );
1423 
1424  return base;
1425 }
1426 
1427 ARM_CP15_TEXT_SECTION static inline void
1428 arm_cp15_set_vector_base_address(void *base)
1429 {
1430  ARM_SWITCH_REGISTERS;
1431 
1432  __asm__ volatile (
1433  ARM_SWITCH_TO_ARM
1434  "mcr p15, 0, %[base], c12, c0, 0\n"
1435  ARM_SWITCH_BACK
1436  : ARM_SWITCH_OUTPUT
1437  : [base] "r" (base)
1438  );
1439 }
1440 
1441 ARM_CP15_TEXT_SECTION static inline void
1442 *arm_cp15_get_hyp_vector_base_address(void)
1443 {
1444  ARM_SWITCH_REGISTERS;
1445  void *base;
1446 
1447  __asm__ volatile (
1448  ARM_SWITCH_TO_ARM
1449  "mrc p15, 4, %[base], c12, c0, 0\n"
1450  ARM_SWITCH_BACK
1451  : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
1452  );
1453 
1454  return base;
1455 }
1456 
1457 ARM_CP15_TEXT_SECTION static inline void
1458 arm_cp15_set_hyp_vector_base_address(void *base)
1459 {
1460  ARM_SWITCH_REGISTERS;
1461 
1462  __asm__ volatile (
1463  ARM_SWITCH_TO_ARM
1464  "mcr p15, 4, %[base], c12, c0, 0\n"
1465  ARM_SWITCH_BACK
1466  : ARM_SWITCH_OUTPUT
1467  : [base] "r" (base)
1468  );
1469 }
1470 
1471 /* PMCCNTR */
1472 ARM_CP15_TEXT_SECTION static inline uint32_t
1473 arm_cp15_get_performance_monitors_cycle_count(void)
1474 {
1475  ARM_SWITCH_REGISTERS;
1476  uint32_t val;
1477 
1478  __asm__ volatile (
1479  ARM_SWITCH_TO_ARM
1480  "mrc p15, 0, %[val], c9, c13, 0\n"
1481  ARM_SWITCH_BACK
1482  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1483  );
1484 
1485  return val;
1486 }
1487 
1488 /* PMCCNTR */
1489 ARM_CP15_TEXT_SECTION static inline void
1490 arm_cp15_set_performance_monitors_cycle_count(uint32_t val)
1491 {
1492  ARM_SWITCH_REGISTERS;
1493 
1494  __asm__ volatile (
1495  ARM_SWITCH_TO_ARM
1496  "mcr p15, 0, %[val], c9, c13, 0\n"
1497  ARM_SWITCH_BACK
1498  : ARM_SWITCH_OUTPUT
1499  : [val] "r" (val)
1500  );
1501 }
1502 
1503 /* PMCEID0 */
1504 ARM_CP15_TEXT_SECTION static inline uint32_t
1505 arm_cp15_get_performance_monitors_common_event_id_0(void)
1506 {
1507  ARM_SWITCH_REGISTERS;
1508  uint32_t val;
1509 
1510  __asm__ volatile (
1511  ARM_SWITCH_TO_ARM
1512  "mrc p15, 0, %[val], c9, c12, 6\n"
1513  ARM_SWITCH_BACK
1514  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1515  );
1516 
1517  return val;
1518 }
1519 
1520 /* PMCEID1 */
1521 ARM_CP15_TEXT_SECTION static inline uint32_t
1522 arm_cp15_get_performance_monitors_common_event_id_1(void)
1523 {
1524  ARM_SWITCH_REGISTERS;
1525  uint32_t val;
1526 
1527  __asm__ volatile (
1528  ARM_SWITCH_TO_ARM
1529  "mrc p15, 0, %[val], c9, c12, 7\n"
1530  ARM_SWITCH_BACK
1531  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1532  );
1533 
1534  return val;
1535 }
1536 
1537 #define ARM_CP15_PMCLRSET_CYCLE_COUNTER 0x80000000
1538 
1539 /* PMCCNTENCLR */
1540 ARM_CP15_TEXT_SECTION static inline uint32_t
1541 arm_cp15_get_performance_monitors_count_enable_clear(void)
1542 {
1543  ARM_SWITCH_REGISTERS;
1544  uint32_t val;
1545 
1546  __asm__ volatile (
1547  ARM_SWITCH_TO_ARM
1548  "mrc p15, 0, %[val], c9, c12, 2\n"
1549  ARM_SWITCH_BACK
1550  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1551  );
1552 
1553  return val;
1554 }
1555 
1556 /* PMCCNTENCLR */
1557 ARM_CP15_TEXT_SECTION static inline void
1558 arm_cp15_set_performance_monitors_count_enable_clear(uint32_t val)
1559 {
1560  ARM_SWITCH_REGISTERS;
1561 
1562  __asm__ volatile (
1563  ARM_SWITCH_TO_ARM
1564  "mcr p15, 0, %[val], c9, c12, 2\n"
1565  ARM_SWITCH_BACK
1566  : ARM_SWITCH_OUTPUT
1567  : [val] "r" (val)
1568  );
1569 }
1570 
1571 /* PMCCNTENSET */
1572 ARM_CP15_TEXT_SECTION static inline uint32_t
1573 arm_cp15_get_performance_monitors_count_enable_set(void)
1574 {
1575  ARM_SWITCH_REGISTERS;
1576  uint32_t val;
1577 
1578  __asm__ volatile (
1579  ARM_SWITCH_TO_ARM
1580  "mrc p15, 0, %[val], c9, c12, 1\n"
1581  ARM_SWITCH_BACK
1582  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1583  );
1584 
1585  return val;
1586 }
1587 
1588 /* PMCCNTENSET */
1589 ARM_CP15_TEXT_SECTION static inline void
1590 arm_cp15_set_performance_monitors_count_enable_set(uint32_t val)
1591 {
1592  ARM_SWITCH_REGISTERS;
1593 
1594  __asm__ volatile (
1595  ARM_SWITCH_TO_ARM
1596  "mcr p15, 0, %[val], c9, c12, 1\n"
1597  ARM_SWITCH_BACK
1598  : ARM_SWITCH_OUTPUT
1599  : [val] "r" (val)
1600  );
1601 }
1602 
1603 #define ARM_CP15_PMCR_IMP(x) ((x) << 24)
1604 #define ARM_CP15_PMCR_IDCODE(x) ((x) << 16)
1605 #define ARM_CP15_PMCR_N(x) ((x) << 11)
1606 #define ARM_CP15_PMCR_DP (1U << 5)
1607 #define ARM_CP15_PMCR_X (1U << 4)
1608 #define ARM_CP15_PMCR_D (1U << 3)
1609 #define ARM_CP15_PMCR_C (1U << 2)
1610 #define ARM_CP15_PMCR_P (1U << 1)
1611 #define ARM_CP15_PMCR_E (1U << 0)
1612 
1613 /* PMCR */
1614 ARM_CP15_TEXT_SECTION static inline uint32_t
1615 arm_cp15_get_performance_monitors_control(void)
1616 {
1617  ARM_SWITCH_REGISTERS;
1618  uint32_t val;
1619 
1620  __asm__ volatile (
1621  ARM_SWITCH_TO_ARM
1622  "mrc p15, 0, %[val], c9, c12, 0\n"
1623  ARM_SWITCH_BACK
1624  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1625  );
1626 
1627  return val;
1628 }
1629 
1630 /* PMCR */
1631 ARM_CP15_TEXT_SECTION static inline void
1632 arm_cp15_set_performance_monitors_control(uint32_t val)
1633 {
1634  ARM_SWITCH_REGISTERS;
1635 
1636  __asm__ volatile (
1637  ARM_SWITCH_TO_ARM
1638  "mcr p15, 0, %[val], c9, c12, 0\n"
1639  ARM_SWITCH_BACK
1640  : ARM_SWITCH_OUTPUT
1641  : [val] "r" (val)
1642  );
1643 }
1644 
1645 /* PMINTENCLR */
1646 ARM_CP15_TEXT_SECTION static inline uint32_t
1647 arm_cp15_get_performance_monitors_interrupt_enable_clear(void)
1648 {
1649  ARM_SWITCH_REGISTERS;
1650  uint32_t val;
1651 
1652  __asm__ volatile (
1653  ARM_SWITCH_TO_ARM
1654  "mrc p15, 0, %[val], c9, c14, 2\n"
1655  ARM_SWITCH_BACK
1656  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1657  );
1658 
1659  return val;
1660 }
1661 
1662 /* PMINTENCLR */
1663 ARM_CP15_TEXT_SECTION static inline void
1664 arm_cp15_set_performance_monitors_interrupt_enable_clear(uint32_t val)
1665 {
1666  ARM_SWITCH_REGISTERS;
1667 
1668  __asm__ volatile (
1669  ARM_SWITCH_TO_ARM
1670  "mcr p15, 0, %[val], c9, c14, 2\n"
1671  ARM_SWITCH_BACK
1672  : ARM_SWITCH_OUTPUT
1673  : [val] "r" (val)
1674  );
1675 }
1676 
1677 /* PMINTENSET */
1678 ARM_CP15_TEXT_SECTION static inline uint32_t
1679 arm_cp15_get_performance_monitors_interrupt_enable_set(void)
1680 {
1681  ARM_SWITCH_REGISTERS;
1682  uint32_t val;
1683 
1684  __asm__ volatile (
1685  ARM_SWITCH_TO_ARM
1686  "mrc p15, 0, %[val], c9, c14, 1\n"
1687  ARM_SWITCH_BACK
1688  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1689  );
1690 
1691  return val;
1692 }
1693 
1694 /* PMINTENSET */
1695 ARM_CP15_TEXT_SECTION static inline void
1696 arm_cp15_set_performance_monitors_interrupt_enable_set(uint32_t val)
1697 {
1698  ARM_SWITCH_REGISTERS;
1699 
1700  __asm__ volatile (
1701  ARM_SWITCH_TO_ARM
1702  "mcr p15, 0, %[val], c9, c14, 1\n"
1703  ARM_SWITCH_BACK
1704  : ARM_SWITCH_OUTPUT
1705  : [val] "r" (val)
1706  );
1707 }
1708 
1709 /* PMOVSR */
1710 ARM_CP15_TEXT_SECTION static inline uint32_t
1711 arm_cp15_get_performance_monitors_overflow_flag_status(void)
1712 {
1713  ARM_SWITCH_REGISTERS;
1714  uint32_t val;
1715 
1716  __asm__ volatile (
1717  ARM_SWITCH_TO_ARM
1718  "mrc p15, 0, %[val], c9, c12, 3\n"
1719  ARM_SWITCH_BACK
1720  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1721  );
1722 
1723  return val;
1724 }
1725 
1726 /* PMOVSR */
1727 ARM_CP15_TEXT_SECTION static inline void
1728 arm_cp15_set_performance_monitors_overflow_flag_status(uint32_t val)
1729 {
1730  ARM_SWITCH_REGISTERS;
1731 
1732  __asm__ volatile (
1733  ARM_SWITCH_TO_ARM
1734  "mcr p15, 0, %[val], c9, c12, 3\n"
1735  ARM_SWITCH_BACK
1736  : ARM_SWITCH_OUTPUT
1737  : [val] "r" (val)
1738  );
1739 }
1740 
1741 /* PMOVSSET */
1742 ARM_CP15_TEXT_SECTION static inline uint32_t
1743 arm_cp15_get_performance_monitors_overflow_flag_status_set(void)
1744 {
1745  ARM_SWITCH_REGISTERS;
1746  uint32_t val;
1747 
1748  __asm__ volatile (
1749  ARM_SWITCH_TO_ARM
1750  "mrc p15, 0, %[val], c9, c14, 3\n"
1751  ARM_SWITCH_BACK
1752  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1753  );
1754 
1755  return val;
1756 }
1757 
1758 /* PMOVSSET */
1759 ARM_CP15_TEXT_SECTION static inline void
1760 arm_cp15_set_performance_monitors_overflow_flag_status_set(uint32_t val)
1761 {
1762  ARM_SWITCH_REGISTERS;
1763 
1764  __asm__ volatile (
1765  ARM_SWITCH_TO_ARM
1766  "mcr p15, 0, %[val], c9, c14, 3\n"
1767  ARM_SWITCH_BACK
1768  : ARM_SWITCH_OUTPUT
1769  : [val] "r" (val)
1770  );
1771 }
1772 
1773 /* PMSELR */
1774 ARM_CP15_TEXT_SECTION static inline uint32_t
1775 arm_cp15_get_performance_monitors_event_counter_selection(void)
1776 {
1777  ARM_SWITCH_REGISTERS;
1778  uint32_t val;
1779 
1780  __asm__ volatile (
1781  ARM_SWITCH_TO_ARM
1782  "mrc p15, 0, %[val], c9, c12, 5\n"
1783  ARM_SWITCH_BACK
1784  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1785  );
1786 
1787  return val;
1788 }
1789 
1790 /* PMSELR */
1791 ARM_CP15_TEXT_SECTION static inline void
1792 arm_cp15_set_performance_monitors_event_counter_selection(uint32_t val)
1793 {
1794  ARM_SWITCH_REGISTERS;
1795 
1796  __asm__ volatile (
1797  ARM_SWITCH_TO_ARM
1798  "mcr p15, 0, %[val], c9, c12, 5\n"
1799  ARM_SWITCH_BACK
1800  : ARM_SWITCH_OUTPUT
1801  : [val] "r" (val)
1802  );
1803 }
1804 
1805 /* PMSWINC */
1806 ARM_CP15_TEXT_SECTION static inline void
1807 arm_cp15_set_performance_monitors_software_increment(uint32_t val)
1808 {
1809  ARM_SWITCH_REGISTERS;
1810 
1811  __asm__ volatile (
1812  ARM_SWITCH_TO_ARM
1813  "mcr p15, 0, %[val], c9, c12, 4\n"
1814  ARM_SWITCH_BACK
1815  : ARM_SWITCH_OUTPUT
1816  : [val] "r" (val)
1817  );
1818 }
1819 
1820 /* PMUSERENR */
1821 ARM_CP15_TEXT_SECTION static inline uint32_t
1822 arm_cp15_get_performance_monitors_user_enable(void)
1823 {
1824  ARM_SWITCH_REGISTERS;
1825  uint32_t val;
1826 
1827  __asm__ volatile (
1828  ARM_SWITCH_TO_ARM
1829  "mrc p15, 0, %[val], c9, c14, 0\n"
1830  ARM_SWITCH_BACK
1831  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1832  );
1833 
1834  return val;
1835 }
1836 
1837 /* PMUSERENR */
1838 ARM_CP15_TEXT_SECTION static inline void
1839 arm_cp15_set_performance_monitors_user_enable(uint32_t val)
1840 {
1841  ARM_SWITCH_REGISTERS;
1842 
1843  __asm__ volatile (
1844  ARM_SWITCH_TO_ARM
1845  "mcr p15, 0, %[val], c9, c14, 0\n"
1846  ARM_SWITCH_BACK
1847  : ARM_SWITCH_OUTPUT
1848  : [val] "r" (val)
1849  );
1850 }
1851 
1852 /* PMXEVCNTR */
1853 ARM_CP15_TEXT_SECTION static inline uint32_t
1854 arm_cp15_get_performance_monitors_event_count(void)
1855 {
1856  ARM_SWITCH_REGISTERS;
1857  uint32_t val;
1858 
1859  __asm__ volatile (
1860  ARM_SWITCH_TO_ARM
1861  "mrc p15, 0, %[val], c9, c13, 2\n"
1862  ARM_SWITCH_BACK
1863  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1864  );
1865 
1866  return val;
1867 }
1868 
1869 /* PMXEVCNTR */
1870 ARM_CP15_TEXT_SECTION static inline void
1871 arm_cp15_set_performance_monitors_event_count(uint32_t val)
1872 {
1873  ARM_SWITCH_REGISTERS;
1874 
1875  __asm__ volatile (
1876  ARM_SWITCH_TO_ARM
1877  "mcr p15, 0, %[val], c9, c13, 2\n"
1878  ARM_SWITCH_BACK
1879  : ARM_SWITCH_OUTPUT
1880  : [val] "r" (val)
1881  );
1882 }
1883 
1884 /* PMXEVTYPER */
1885 ARM_CP15_TEXT_SECTION static inline uint32_t
1886 arm_cp15_get_performance_monitors_event_type_select(void)
1887 {
1888  ARM_SWITCH_REGISTERS;
1889  uint32_t val;
1890 
1891  __asm__ volatile (
1892  ARM_SWITCH_TO_ARM
1893  "mrc p15, 0, %[val], c9, c13, 1\n"
1894  ARM_SWITCH_BACK
1895  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1896  );
1897 
1898  return val;
1899 }
1900 
1901 /* PMXEVTYPER */
1902 ARM_CP15_TEXT_SECTION static inline void
1903 arm_cp15_set_performance_monitors_event_type_select(uint32_t val)
1904 {
1905  ARM_SWITCH_REGISTERS;
1906 
1907  __asm__ volatile (
1908  ARM_SWITCH_TO_ARM
1909  "mcr p15, 0, %[val], c9, c13, 1\n"
1910  ARM_SWITCH_BACK
1911  : ARM_SWITCH_OUTPUT
1912  : [val] "r" (val)
1913  );
1914 }
1915 
1916 /* CNTFRQ */
1917 ARM_CP15_TEXT_SECTION static inline uint32_t
1918 arm_cp15_get_counter_frequency(void)
1919 {
1920  ARM_SWITCH_REGISTERS;
1921  uint32_t val;
1922 
1923  __asm__ volatile (
1924  ARM_SWITCH_TO_ARM
1925  "mrc p15, 0, %[val], c14, c0, 0\n"
1926  ARM_SWITCH_BACK
1927  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1928  );
1929 
1930  return val;
1931 }
1932 
1933 /* CNTFRQ */
1934 ARM_CP15_TEXT_SECTION static inline void
1935 arm_cp15_set_counter_frequency(uint32_t val)
1936 {
1937  ARM_SWITCH_REGISTERS;
1938 
1939  __asm__ volatile (
1940  ARM_SWITCH_TO_ARM
1941  "mcr p15, 0, %[val], c14, c0, 0\n"
1942  ARM_SWITCH_BACK
1943  : ARM_SWITCH_OUTPUT
1944  : [val] "r" (val)
1945  );
1946 }
1947 
1948 /* CNTPCT */
1949 ARM_CP15_TEXT_SECTION static inline uint64_t
1950 arm_cp15_get_counter_physical_count(void)
1951 {
1952  ARM_SWITCH_REGISTERS;
1953  uint64_t val;
1954 
1955  __asm__ volatile (
1956  ARM_SWITCH_TO_ARM
1957  "mrrc p15, 0, %Q[val], %R[val], c14\n"
1958  ARM_SWITCH_BACK
1959  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1960  );
1961 
1962  return val;
1963 }
1964 
1965 /* CNTKCTL */
1966 ARM_CP15_TEXT_SECTION static inline uint32_t
1967 arm_cp15_get_counter_non_secure_pl1_control(void)
1968 {
1969  ARM_SWITCH_REGISTERS;
1970  uint32_t val;
1971 
1972  __asm__ volatile (
1973  ARM_SWITCH_TO_ARM
1974  "mrc p15, 0, %[val], c14, c1, 0\n"
1975  ARM_SWITCH_BACK
1976  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1977  );
1978 
1979  return val;
1980 }
1981 
1982 /* CNTKCTL */
1983 ARM_CP15_TEXT_SECTION static inline void
1984 arm_cp15_set_counter_non_secure_pl1_control(uint32_t val)
1985 {
1986  ARM_SWITCH_REGISTERS;
1987 
1988  __asm__ volatile (
1989  ARM_SWITCH_TO_ARM
1990  "mcr p15, 0, %[val], c14, c1, 0\n"
1991  ARM_SWITCH_BACK
1992  : ARM_SWITCH_OUTPUT
1993  : [val] "r" (val)
1994  );
1995 }
1996 
1997 /* CNTP_TVAL */
1998 ARM_CP15_TEXT_SECTION static inline uint32_t
1999 arm_cp15_get_counter_pl1_physical_timer_value(void)
2000 {
2001  ARM_SWITCH_REGISTERS;
2002  uint32_t val;
2003 
2004  __asm__ volatile (
2005  ARM_SWITCH_TO_ARM
2006  "mrc p15, 0, %[val], c14, c2, 0\n"
2007  ARM_SWITCH_BACK
2008  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2009  );
2010 
2011  return val;
2012 }
2013 
2014 /* CNTP_TVAL */
2015 ARM_CP15_TEXT_SECTION static inline void
2016 arm_cp15_set_counter_pl1_physical_timer_value(uint32_t val)
2017 {
2018  ARM_SWITCH_REGISTERS;
2019 
2020  __asm__ volatile (
2021  ARM_SWITCH_TO_ARM
2022  "mcr p15, 0, %[val], c14, c2, 0\n"
2023  ARM_SWITCH_BACK
2024  : ARM_SWITCH_OUTPUT
2025  : [val] "r" (val)
2026  );
2027 }
2028 
2029 /* CNTP_CTL */
2030 ARM_CP15_TEXT_SECTION static inline uint32_t
2031 arm_cp15_get_counter_pl1_physical_timer_control(void)
2032 {
2033  ARM_SWITCH_REGISTERS;
2034  uint32_t val;
2035 
2036  __asm__ volatile (
2037  ARM_SWITCH_TO_ARM
2038  "mrc p15, 0, %[val], c14, c2, 1\n"
2039  ARM_SWITCH_BACK
2040  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2041  );
2042 
2043  return val;
2044 }
2045 
2046 /* CNTP_CTL */
2047 ARM_CP15_TEXT_SECTION static inline void
2048 arm_cp15_set_counter_pl1_physical_timer_control(uint32_t val)
2049 {
2050  ARM_SWITCH_REGISTERS;
2051 
2052  __asm__ volatile (
2053  ARM_SWITCH_TO_ARM
2054  "mcr p15, 0, %[val], c14, c2, 1\n"
2055  ARM_SWITCH_BACK
2056  : ARM_SWITCH_OUTPUT
2057  : [val] "r" (val)
2058  );
2059 }
2060 
2061 /* CNTV_TVAL */
2062 ARM_CP15_TEXT_SECTION static inline uint32_t
2063 arm_cp15_get_counter_pl1_virtual_timer_value(void)
2064 {
2065  ARM_SWITCH_REGISTERS;
2066  uint32_t val;
2067 
2068  __asm__ volatile (
2069  ARM_SWITCH_TO_ARM
2070  "mrc p15, 0, %[val], c14, c3, 0\n"
2071  ARM_SWITCH_BACK
2072  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2073  );
2074 
2075  return val;
2076 }
2077 
2078 /* CNTV_TVAL */
2079 ARM_CP15_TEXT_SECTION static inline void
2080 arm_cp15_set_counter_pl1_virtual_timer_value(uint32_t val)
2081 {
2082  ARM_SWITCH_REGISTERS;
2083 
2084  __asm__ volatile (
2085  ARM_SWITCH_TO_ARM
2086  "mcr p15, 0, %[val], c14, c3, 0\n"
2087  ARM_SWITCH_BACK
2088  : ARM_SWITCH_OUTPUT
2089  : [val] "r" (val)
2090  );
2091 }
2092 
2093 /* CNTV_CTL */
2094 ARM_CP15_TEXT_SECTION static inline uint32_t
2095 arm_cp15_get_counter_pl1_virtual_timer_control(void)
2096 {
2097  ARM_SWITCH_REGISTERS;
2098  uint32_t val;
2099 
2100  __asm__ volatile (
2101  ARM_SWITCH_TO_ARM
2102  "mrc p15, 0, %[val], c14, c3, 1\n"
2103  ARM_SWITCH_BACK
2104  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2105  );
2106 
2107  return val;
2108 }
2109 
2110 /* CNTV_CTL */
2111 ARM_CP15_TEXT_SECTION static inline void
2112 arm_cp15_set_counter_pl1_virtual_timer_control(uint32_t val)
2113 {
2114  ARM_SWITCH_REGISTERS;
2115 
2116  __asm__ volatile (
2117  ARM_SWITCH_TO_ARM
2118  "mcr p15, 0, %[val], c14, c3, 1\n"
2119  ARM_SWITCH_BACK
2120  : ARM_SWITCH_OUTPUT
2121  : [val] "r" (val)
2122  );
2123 }
2124 
2125 /* CNTVCT */
2126 ARM_CP15_TEXT_SECTION static inline uint64_t
2127 arm_cp15_get_counter_virtual_count(void)
2128 {
2129  ARM_SWITCH_REGISTERS;
2130  uint64_t val;
2131 
2132  __asm__ volatile (
2133  ARM_SWITCH_TO_ARM
2134  "mrrc p15, 1, %Q[val], %R[val], c14\n"
2135  ARM_SWITCH_BACK
2136  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2137  );
2138 
2139  return val;
2140 }
2141 
2142 /* CNTP_CVAL */
2143 ARM_CP15_TEXT_SECTION static inline uint64_t
2144 arm_cp15_get_counter_pl1_physical_compare_value(void)
2145 {
2146  ARM_SWITCH_REGISTERS;
2147  uint64_t val;
2148 
2149  __asm__ volatile (
2150  ARM_SWITCH_TO_ARM
2151  "mrrc p15, 2, %Q[val], %R[val], c14\n"
2152  ARM_SWITCH_BACK
2153  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2154  );
2155 
2156  return val;
2157 }
2158 
2159 /* CNTP_CVAL */
2160 ARM_CP15_TEXT_SECTION static inline void
2161 arm_cp15_set_counter_pl1_physical_compare_value(uint64_t val)
2162 {
2163  ARM_SWITCH_REGISTERS;
2164 
2165  __asm__ volatile (
2166  ARM_SWITCH_TO_ARM
2167  "mcrr p15, 2, %Q[val], %R[val], c14\n"
2168  ARM_SWITCH_BACK
2169  : ARM_SWITCH_OUTPUT
2170  : [val] "r" (val)
2171  );
2172 }
2173 
2174 /* CNTV_CVAL */
2175 ARM_CP15_TEXT_SECTION static inline uint64_t
2176 arm_cp15_get_counter_pl1_virtual_compare_value(void)
2177 {
2178  ARM_SWITCH_REGISTERS;
2179  uint64_t val;
2180 
2181  __asm__ volatile (
2182  ARM_SWITCH_TO_ARM
2183  "mrrc p15, 3, %Q[val], %R[val], c14\n"
2184  ARM_SWITCH_BACK
2185  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2186  );
2187 
2188  return val;
2189 }
2190 
2191 /* CNTV_CVAL */
2192 ARM_CP15_TEXT_SECTION static inline void
2193 arm_cp15_set_counter_pl1_virtual_compare_value(uint64_t val)
2194 {
2195  ARM_SWITCH_REGISTERS;
2196 
2197  __asm__ volatile (
2198  ARM_SWITCH_TO_ARM
2199  "mcrr p15, 3, %Q[val], %R[val], c14\n"
2200  ARM_SWITCH_BACK
2201  : ARM_SWITCH_OUTPUT
2202  : [val] "r" (val)
2203  );
2204 }
2205 
2206 /* CNTVOFF */
2207 ARM_CP15_TEXT_SECTION static inline uint64_t
2208 arm_cp15_get_counter_virtual_offset(void)
2209 {
2210  ARM_SWITCH_REGISTERS;
2211  uint64_t val;
2212 
2213  __asm__ volatile (
2214  ARM_SWITCH_TO_ARM
2215  "mrrc p15, 4, %Q[val], %R[val], c14\n"
2216  ARM_SWITCH_BACK
2217  : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2218  );
2219 
2220  return val;
2221 }
2222 
2223 /* CNTVOFF */
2224 ARM_CP15_TEXT_SECTION static inline void
2225 arm_cp15_set_counter_virtual_offset(uint64_t val)
2226 {
2227  ARM_SWITCH_REGISTERS;
2228 
2229  __asm__ volatile (
2230  ARM_SWITCH_TO_ARM
2231  "mcrr p15, 4, %Q[val], %R[val], c14\n"
2232  ARM_SWITCH_BACK
2233  : ARM_SWITCH_OUTPUT
2234  : [val] "r" (val)
2235  );
2236 }
2237 
2244  const void *begin,
2245  const void *end,
2246  uint32_t section_flags
2247 );
2248 
2249 void arm_cp15_set_exception_handler(
2250  Arm_symbolic_exception_name exception,
2251  void (*handler)(void)
2252 );
2253 
2256 #ifdef __cplusplus
2257 }
2258 #endif /* __cplusplus */
2259 
2260 #endif /* LIBCPU_SHARED_ARM_CP15_H */
Definition: mknod-pack_dev.c:254
#define rtems_interrupt_local_enable(_isr_cookie)
This macro restores the previous interrupt level on the current processor.
Definition: intr.h:148
uint32_t arm_cp15_set_translation_table_entries(const void *begin, const void *end, uint32_t section_flags)
Sets the section_flags for the address range [begin, end).
Definition: arm-cp15-set-ttb-entries.c:82
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
unsigned ct
Definition: tlb.h:224
ISR_Level rtems_interrupt_level
Interrupt level type.
Definition: intr.h:42
#define rtems_interrupt_local_disable(_isr_cookie)
This macro disables the interrupts on the current processor.
Definition: intr.h:138