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