File indexing completed on 2025-05-11 08:24:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef LIBCPU_SHARED_ARM_CP15_H
0038 #define LIBCPU_SHARED_ARM_CP15_H
0039
0040 #include <rtems.h>
0041
0042 #ifdef __cplusplus
0043 extern "C" {
0044 #endif
0045
0046
0047
0048
0049
0050 #ifndef ARM_CP15_TEXT_SECTION
0051 #define ARM_CP15_TEXT_SECTION
0052 #endif
0053
0054 #define ARM_CP15_CACHE_PREPARE_MVA(mva) \
0055 ((const void *) (((uint32_t) (mva)) & ~0x1fU))
0056
0057 #define ARM_CP15_TLB_PREPARE_MVA(mva) \
0058 ((const void *) (((uint32_t) (mva)) & ~0x3fU))
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 #define ARM_MMU_SECT_BASE_SHIFT 20
0081 #define ARM_MMU_SECT_BASE_MASK (0xfffU << ARM_MMU_SECT_BASE_SHIFT)
0082 #define ARM_MMU_SECT_NS (1U << 19)
0083 #define ARM_MMU_SECT_NG (1U << 17)
0084 #define ARM_MMU_SECT_S (1U << 16)
0085 #define ARM_MMU_SECT_AP_2 (1U << 15)
0086 #define ARM_MMU_SECT_TEX_2 (1U << 14)
0087 #define ARM_MMU_SECT_TEX_1 (1U << 13)
0088 #define ARM_MMU_SECT_TEX_0 (1U << 12)
0089 #define ARM_MMU_SECT_TEX_SHIFT 12
0090 #define ARM_MMU_SECT_TEX_MASK (0x3U << ARM_MMU_SECT_TEX_SHIFT)
0091 #define ARM_MMU_SECT_AP_1 (1U << 11)
0092 #define ARM_MMU_SECT_AP_0 (1U << 10)
0093 #define ARM_MMU_SECT_AP_SHIFT 10
0094 #define ARM_MMU_SECT_AP_MASK (0x23U << ARM_MMU_SECT_AP_SHIFT)
0095 #define ARM_MMU_SECT_DOMAIN_SHIFT 5
0096 #define ARM_MMU_SECT_DOMAIN_MASK (0xfU << ARM_MMU_SECT_DOMAIN_SHIFT)
0097 #define ARM_MMU_SECT_XN (1U << 4)
0098 #define ARM_MMU_SECT_C (1U << 3)
0099 #define ARM_MMU_SECT_B (1U << 2)
0100 #define ARM_MMU_SECT_PXN (1U << 0)
0101 #define ARM_MMU_SECT_DEFAULT 0x2U
0102 #define ARM_MMU_SECT_GET_INDEX(mva) \
0103 (((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT)
0104 #define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \
0105 ((1U << ARM_MMU_SECT_BASE_SHIFT) \
0106 + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U)))
0107
0108 #define ARM_MMU_PAGE_TABLE_BASE_SHIFT 10
0109 #define ARM_MMU_PAGE_TABLE_BASE_MASK (0x3fffffU << ARM_MMU_PAGE_TABLE_BASE_SHIFT)
0110 #define ARM_MMU_PAGE_TABLE_DOMAIN_SHIFT 5
0111 #define ARM_MMU_PAGE_TABLE_DOMAIN_MASK (0xfU << ARM_MMU_PAGE_TABLE_DOMAIN_SHIFT)
0112 #define ARM_MMU_PAGE_TABLE_NS (1U << 3)
0113 #define ARM_MMU_PAGE_TABLE_PXN (1U << 2)
0114 #define ARM_MMU_PAGE_TABLE_DEFAULT 0x1U
0115
0116 #define ARM_MMU_SMALL_PAGE_BASE_SHIFT 12
0117 #define ARM_MMU_SMALL_PAGE_BASE_MASK (0xfffffU << ARM_MMU_SMALL_PAGE_BASE_SHIFT)
0118 #define ARM_MMU_SMALL_PAGE_NG (1U << 11)
0119 #define ARM_MMU_SMALL_PAGE_S (1U << 10)
0120 #define ARM_MMU_SMALL_PAGE_AP_2 (1U << 9)
0121 #define ARM_MMU_SMALL_PAGE_TEX_2 (1U << 8)
0122 #define ARM_MMU_SMALL_PAGE_TEX_1 (1U << 7)
0123 #define ARM_MMU_SMALL_PAGE_TEX_0 (1U << 6)
0124 #define ARM_MMU_SMALL_PAGE_TEX_SHIFT 6
0125 #define ARM_MMU_SMALL_PAGE_TEX_MASK (0x3U << ARM_MMU_SMALL_PAGE_TEX_SHIFT)
0126 #define ARM_MMU_SMALL_PAGE_AP_1 (1U << 5)
0127 #define ARM_MMU_SMALL_PAGE_AP_0 (1U << 4)
0128 #define ARM_MMU_SMALL_PAGE_AP_SHIFT 4
0129 #define ARM_MMU_SMALL_PAGE_AP_MASK (0x23U << ARM_MMU_SMALL_PAGE_AP_SHIFT)
0130 #define ARM_MMU_SMALL_PAGE_C (1U << 3)
0131 #define ARM_MMU_SMALL_PAGE_B (1U << 2)
0132 #define ARM_MMU_SMALL_PAGE_XN (1U << 0)
0133 #define ARM_MMU_SMALL_PAGE_DEFAULT 0x2U
0134 #define ARM_MMU_SMALL_PAGE_GET_INDEX(mva) \
0135 (((uint32_t) (mva)) >> ARM_MMU_SMALL_PAGE_BASE_SHIFT)
0136 #define ARM_MMU_SMALL_PAGE_MVA_ALIGN_UP(mva) \
0137 ((1U << ARM_MMU_SMALL_PAGE_BASE_SHIFT) \
0138 + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SMALL_PAGE_BASE_SHIFT) - 1U)))
0139
0140 #define ARM_MMU_SECT_FLAGS_TO_PAGE_TABLE(flags) \
0141 (ARM_MMU_PAGE_TABLE_DEFAULT \
0142 | ((flags) & ARM_MMU_SECT_DOMAIN_MASK) \
0143 | (((flags) & ARM_MMU_SECT_NS) >> 16) \
0144 | (((flags) & ARM_MMU_SECT_PXN) << 2))
0145
0146 #define ARM_MMU_PAGE_TABLE_FLAGS_TO_SECT(flags) \
0147 (ARM_MMU_SECT_DEFAULT \
0148 | ((flags) & ARM_MMU_PAGE_TABLE_DOMAIN_MASK) \
0149 | (((flags) & ARM_MMU_PAGE_TABLE_NS) << 16) \
0150 | (((flags) & ARM_MMU_PAGE_TABLE_PXN) >> 2))
0151
0152 #define ARM_MMU_SECT_FLAGS_TO_SMALL_PAGE(flags) \
0153 ((((flags) & 0x3fc00) >> 6) \
0154 | ((flags) & (ARM_MMU_SECT_C | ARM_MMU_SECT_B | 0x2)) \
0155 | (((flags) & ARM_MMU_SECT_XN) >> 4))
0156
0157 #define ARM_MMU_SMALL_PAGE_FLAGS_TO_SECT(flags) \
0158 ((((flags) & 0xff0) << 6) \
0159 | ((flags) & (ARM_MMU_SMALL_PAGE_C | ARM_MMU_SMALL_PAGE_B | 0x2)) \
0160 | (((flags) & ARM_MMU_SMALL_PAGE_XN) << 4))
0161
0162 #define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U
0163 #define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U
0164
0165 #define ARM_MMU_SMALL_PAGE_TABLE_ENTRY_SIZE 4U
0166 #define ARM_MMU_SMALL_PAGE_TABLE_ENTRY_COUNT 256U
0167
0168 #define ARM_MMU_DEFAULT_CLIENT_DOMAIN 15U
0169
0170 #define ARMV7_MMU_READ_ONLY \
0171 ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
0172 | ARM_MMU_SECT_AP_0 \
0173 | ARM_MMU_SECT_AP_2 \
0174 | ARM_MMU_SECT_DEFAULT)
0175
0176 #define ARMV7_MMU_READ_ONLY_CACHED \
0177 (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
0178
0179 #define ARMV7_MMU_READ_WRITE \
0180 ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
0181 | ARM_MMU_SECT_AP_0 \
0182 | ARM_MMU_SECT_DEFAULT)
0183
0184 #ifdef RTEMS_SMP
0185 #define ARMV7_MMU_READ_WRITE_CACHED \
0186 (ARMV7_MMU_READ_WRITE \
0187 | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B | ARM_MMU_SECT_S)
0188 #else
0189 #define ARMV7_MMU_READ_WRITE_CACHED \
0190 (ARMV7_MMU_READ_WRITE \
0191 | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
0192 #endif
0193
0194 #define ARMV7_MMU_DATA_READ_ONLY \
0195 (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
0196
0197 #define ARMV7_MMU_DATA_READ_ONLY_CACHED \
0198 ARMV7_MMU_READ_ONLY_CACHED
0199
0200 #define ARMV7_MMU_DATA_READ_WRITE \
0201 (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_TEX_0)
0202
0203 #define ARMV7_MMU_DATA_READ_WRITE_CACHED \
0204 ARMV7_MMU_READ_WRITE_CACHED
0205
0206 #define ARMV7_MMU_CODE \
0207 (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
0208
0209 #define ARMV7_MMU_CODE_CACHED \
0210 ARMV7_MMU_READ_ONLY_CACHED
0211
0212 #define ARMV7_MMU_DEVICE \
0213 (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_B)
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 #define ARM_CP15_CTRL_TE (1U << 30)
0224 #define ARM_CP15_CTRL_AFE (1U << 29)
0225 #define ARM_CP15_CTRL_TRE (1U << 28)
0226 #define ARM_CP15_CTRL_NMFI (1U << 27)
0227 #define ARM_CP15_CTRL_EE (1U << 25)
0228 #define ARM_CP15_CTRL_VE (1U << 24)
0229 #define ARM_CP15_CTRL_XP (1U << 23)
0230 #define ARM_CP15_CTRL_U (1U << 22)
0231 #define ARM_CP15_CTRL_FI (1U << 21)
0232 #define ARM_CP15_CTRL_UWXN (1U << 20)
0233 #define ARM_CP15_CTRL_WXN (1U << 19)
0234 #define ARM_CP15_CTRL_HA (1U << 17)
0235 #define ARM_CP15_CTRL_L4 (1U << 15)
0236 #define ARM_CP15_CTRL_RR (1U << 14)
0237 #define ARM_CP15_CTRL_V (1U << 13)
0238 #define ARM_CP15_CTRL_I (1U << 12)
0239 #define ARM_CP15_CTRL_Z (1U << 11)
0240 #define ARM_CP15_CTRL_SW (1U << 10)
0241 #define ARM_CP15_CTRL_R (1U << 9)
0242 #define ARM_CP15_CTRL_S (1U << 8)
0243 #define ARM_CP15_CTRL_B (1U << 7)
0244 #define ARM_CP15_CTRL_CP15BEN (1U << 5)
0245 #define ARM_CP15_CTRL_C (1U << 2)
0246 #define ARM_CP15_CTRL_A (1U << 1)
0247 #define ARM_CP15_CTRL_M (1U << 0)
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 #define ARM_CP15_DAC_NO_ACCESS 0x0U
0258 #define ARM_CP15_DAC_CLIENT 0x1U
0259 #define ARM_CP15_DAC_MANAGER 0x3U
0260 #define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index))
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 #define ARM_CP15_FAULT_STATUS_MASK 0x040F
0271
0272 #define ARM_CP15_FSR_ALIGNMENT_FAULT 0x00000001
0273 #define ARM_CP15_FSR_BACKGROUND_FAULT 0x0000
0274 #define ARM_CP15_FSR_ACCESS_PERMISSION_FAULT 0x000D
0275 #define ARM_CP15_FSR_PRECISE_EXTERNAL_ABORT_FAULT 0x0008
0276 #define ARM_CP15_FSR_IMPRECISE_EXTERNAL_ABORT_FAULT 0x0406
0277 #define ARM_CP15_FSR_PRECISE_PARITY_ERROR_EXCEPTION 0x0006
0278 #define ARM_CP15_FSR_IMPRECISE_PARITY_ERROR_EXCEPTION 0x0408
0279 #define ARM_CP15_FSR_DEBUG_EVENT 0x0002
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 #define ARM_CP15_CACHE_TYPE_FORMAT_ARMV6 0
0293 #define ARM_CP15_CACHE_TYPE_FORMAT_ARMV7 4
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 #define ARM_CP15_CACHE_CSS_ID_DATA 0
0304 #define ARM_CP15_CACHE_CSS_ID_INSTRUCTION 1
0305 #define ARM_CP15_CACHE_CSS_LEVEL(level) ((level) << 1)
0306
0307
0308
0309 ARM_CP15_TEXT_SECTION static inline uint32_t
0310 arm_cp15_get_id_code(void)
0311 {
0312 ARM_SWITCH_REGISTERS;
0313 uint32_t val;
0314
0315 __asm__ volatile (
0316 ARM_SWITCH_TO_ARM
0317 "mrc p15, 0, %[val], c0, c0, 0\n"
0318 ARM_SWITCH_BACK
0319 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0320 );
0321
0322 return val;
0323 }
0324
0325 ARM_CP15_TEXT_SECTION static inline uint32_t
0326 arm_cp15_get_tcm_status(void)
0327 {
0328 ARM_SWITCH_REGISTERS;
0329 uint32_t val;
0330
0331 __asm__ volatile (
0332 ARM_SWITCH_TO_ARM
0333 "mrc p15, 0, %[val], c0, c0, 2\n"
0334 ARM_SWITCH_BACK
0335 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0336 );
0337
0338 return val;
0339 }
0340
0341 ARM_CP15_TEXT_SECTION static inline uint32_t
0342 arm_cp15_get_control(void)
0343 {
0344 ARM_SWITCH_REGISTERS;
0345 uint32_t val;
0346
0347 __asm__ volatile (
0348 ARM_SWITCH_TO_ARM
0349 "mrc p15, 0, %[val], c1, c0, 0\n"
0350 ARM_SWITCH_BACK
0351 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0352 );
0353
0354 return val;
0355 }
0356
0357 ARM_CP15_TEXT_SECTION static inline void
0358 arm_cp15_set_control(uint32_t val)
0359 {
0360 ARM_SWITCH_REGISTERS;
0361
0362 __asm__ volatile (
0363 ARM_SWITCH_TO_ARM
0364 "mcr p15, 0, %[val], c1, c0, 0\n"
0365 "nop\n"
0366 "nop\n"
0367 ARM_SWITCH_BACK
0368 : ARM_SWITCH_OUTPUT
0369 : [val] "r" (val)
0370 : "memory"
0371 );
0372 }
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390 ARM_CP15_TEXT_SECTION static inline uint32_t
0391 arm_cp15_mmu_disable(uint32_t cls)
0392 {
0393 ARM_SWITCH_REGISTERS;
0394 uint32_t ctrl;
0395 uint32_t tmp_0;
0396 uint32_t tmp_1;
0397
0398 __asm__ volatile (
0399 ARM_SWITCH_TO_ARM
0400 "mrc p15, 0, %[ctrl], c1, c0, 0\n"
0401 "bic %[tmp_0], %[ctrl], #1\n"
0402 "mcr p15, 0, %[tmp_0], c1, c0, 0\n"
0403 "nop\n"
0404 "nop\n"
0405 "mov %[tmp_1], sp\n"
0406 "rsb %[tmp_0], %[cls], #0\n"
0407 "and %[tmp_0], %[tmp_0], %[tmp_1]\n"
0408 "sub %[tmp_0], %[tmp_0], %[cls], asl #3\n"
0409 "add %[tmp_1], %[tmp_0], %[cls], asl #4\n"
0410 "1:\n"
0411 "mcr p15, 0, %[tmp_0], c7, c14, 1\n"
0412 "add %[tmp_0], %[tmp_0], %[cls]\n"
0413 "cmp %[tmp_1], %[tmp_0]\n"
0414 "bne 1b\n"
0415 ARM_SWITCH_BACK
0416 : [ctrl] "=&r" (ctrl),
0417 [tmp_0] "=&r" (tmp_0),
0418 [tmp_1] "=&r" (tmp_1)
0419 ARM_SWITCH_ADDITIONAL_OUTPUT
0420 : [cls] "r" (cls)
0421 : "memory", "cc"
0422 );
0423
0424 return ctrl;
0425 }
0426
0427 ARM_CP15_TEXT_SECTION static inline uint32_t
0428 *arm_cp15_get_translation_table_base(void)
0429 {
0430 ARM_SWITCH_REGISTERS;
0431 uint32_t *base;
0432
0433 __asm__ volatile (
0434 ARM_SWITCH_TO_ARM
0435 "mrc p15, 0, %[base], c2, c0, 0\n"
0436 ARM_SWITCH_BACK
0437 : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
0438 );
0439
0440 return base;
0441 }
0442
0443 ARM_CP15_TEXT_SECTION static inline void
0444 arm_cp15_set_translation_table_base(uint32_t *base)
0445 {
0446 ARM_SWITCH_REGISTERS;
0447
0448 __asm__ volatile (
0449 ARM_SWITCH_TO_ARM
0450 "mcr p15, 0, %[base], c2, c0, 0\n"
0451 ARM_SWITCH_BACK
0452 : ARM_SWITCH_OUTPUT
0453 : [base] "r" (base)
0454 );
0455 }
0456
0457
0458 ARM_CP15_TEXT_SECTION static inline uint32_t
0459 arm_cp15_get_translation_table_base_control_register(void)
0460 {
0461 ARM_SWITCH_REGISTERS;
0462 uint32_t ttb_cr;
0463
0464 __asm__ volatile (
0465 ARM_SWITCH_TO_ARM
0466 "mrc p15, 0, %[ttb_cr], c2, c0, 2\n"
0467 ARM_SWITCH_BACK
0468 : [ttb_cr] "=&r" (ttb_cr) ARM_SWITCH_ADDITIONAL_OUTPUT
0469 );
0470
0471 return ttb_cr;
0472 }
0473
0474 ARM_CP15_TEXT_SECTION static inline void
0475 arm_cp15_set_translation_table_base_control_register(uint32_t ttb_cr)
0476 {
0477 ARM_SWITCH_REGISTERS;
0478
0479 __asm__ volatile (
0480 ARM_SWITCH_TO_ARM
0481 "mcr p15, 0, %[ttb_cr], c2, c0, 2\n"
0482 ARM_SWITCH_BACK
0483 : ARM_SWITCH_OUTPUT
0484 : [ttb_cr] "r" (ttb_cr)
0485 );
0486 }
0487
0488 ARM_CP15_TEXT_SECTION static inline uint32_t
0489 arm_cp15_get_domain_access_control(void)
0490 {
0491 ARM_SWITCH_REGISTERS;
0492 uint32_t val;
0493
0494 __asm__ volatile (
0495 ARM_SWITCH_TO_ARM
0496 "mrc p15, 0, %[val], c3, c0, 0\n"
0497 ARM_SWITCH_BACK
0498 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0499 );
0500
0501 return val;
0502 }
0503
0504 ARM_CP15_TEXT_SECTION static inline void
0505 arm_cp15_set_domain_access_control(uint32_t val)
0506 {
0507 ARM_SWITCH_REGISTERS;
0508
0509 __asm__ volatile (
0510 ARM_SWITCH_TO_ARM
0511 "mcr p15, 0, %[val], c3, c0, 0\n"
0512 ARM_SWITCH_BACK
0513 : ARM_SWITCH_OUTPUT
0514 : [val] "r" (val)
0515 );
0516 }
0517
0518 ARM_CP15_TEXT_SECTION static inline uint32_t
0519 arm_cp15_get_data_fault_status(void)
0520 {
0521 ARM_SWITCH_REGISTERS;
0522 uint32_t val;
0523
0524 __asm__ volatile (
0525 ARM_SWITCH_TO_ARM
0526 "mrc p15, 0, %[val], c5, c0, 0\n"
0527 ARM_SWITCH_BACK
0528 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0529 );
0530
0531 return val;
0532 }
0533
0534 ARM_CP15_TEXT_SECTION static inline void
0535 arm_cp15_set_data_fault_status(uint32_t val)
0536 {
0537 ARM_SWITCH_REGISTERS;
0538
0539 __asm__ volatile (
0540 ARM_SWITCH_TO_ARM
0541 "mcr p15, 0, %[val], c5, c0, 0\n"
0542 ARM_SWITCH_BACK
0543 : ARM_SWITCH_OUTPUT
0544 : [val] "r" (val)
0545 );
0546 }
0547
0548 ARM_CP15_TEXT_SECTION static inline uint32_t
0549 arm_cp15_get_instruction_fault_status(void)
0550 {
0551 ARM_SWITCH_REGISTERS;
0552 uint32_t val;
0553
0554 __asm__ volatile (
0555 ARM_SWITCH_TO_ARM
0556 "mrc p15, 0, %[val], c5, c0, 1\n"
0557 ARM_SWITCH_BACK
0558 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0559 );
0560
0561 return val;
0562 }
0563
0564 ARM_CP15_TEXT_SECTION static inline void
0565 arm_cp15_set_instruction_fault_status(uint32_t val)
0566 {
0567 ARM_SWITCH_REGISTERS;
0568
0569 __asm__ volatile (
0570 ARM_SWITCH_TO_ARM
0571 "mcr p15, 0, %[val], c5, c0, 1\n"
0572 ARM_SWITCH_BACK
0573 : ARM_SWITCH_OUTPUT
0574 : [val] "r" (val)
0575 );
0576 }
0577
0578 ARM_CP15_TEXT_SECTION static inline void
0579 *arm_cp15_get_fault_address(void)
0580 {
0581 ARM_SWITCH_REGISTERS;
0582 void *mva;
0583
0584 __asm__ volatile (
0585 ARM_SWITCH_TO_ARM
0586 "mrc p15, 0, %[mva], c6, c0, 0\n"
0587 ARM_SWITCH_BACK
0588 : [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT
0589 );
0590
0591 return mva;
0592 }
0593
0594 ARM_CP15_TEXT_SECTION static inline void
0595 arm_cp15_set_fault_address(const void *mva)
0596 {
0597 ARM_SWITCH_REGISTERS;
0598
0599 __asm__ volatile (
0600 ARM_SWITCH_TO_ARM
0601 "mcr p15, 0, %[mva], c6, c0, 0\n"
0602 ARM_SWITCH_BACK
0603 : ARM_SWITCH_OUTPUT
0604 : [mva] "r" (mva)
0605 );
0606 }
0607
0608 ARM_CP15_TEXT_SECTION static inline void
0609 arm_cp15_tlb_invalidate(void)
0610 {
0611 ARM_SWITCH_REGISTERS;
0612 uint32_t sbz = 0;
0613
0614 __asm__ volatile (
0615 ARM_SWITCH_TO_ARM
0616 "mcr p15, 0, %[sbz], c8, c7, 0\n"
0617 ARM_SWITCH_BACK
0618 : ARM_SWITCH_OUTPUT
0619 : [sbz] "r" (sbz)
0620 );
0621
0622
0623
0624
0625
0626 _ARM_Data_synchronization_barrier();
0627 _ARM_Instruction_synchronization_barrier();
0628 }
0629
0630 ARM_CP15_TEXT_SECTION static inline void
0631 arm_cp15_tlb_invalidate_entry(const void *mva)
0632 {
0633 ARM_SWITCH_REGISTERS;
0634
0635 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
0636
0637 __asm__ volatile (
0638 ARM_SWITCH_TO_ARM
0639 "mcr p15, 0, %[mva], c8, c7, 1\n"
0640 ARM_SWITCH_BACK
0641 : ARM_SWITCH_OUTPUT
0642 : [mva] "r" (mva)
0643 );
0644 }
0645
0646 ARM_CP15_TEXT_SECTION static inline void
0647 arm_cp15_tlb_invalidate_entry_all_asids(const void *mva)
0648 {
0649 ARM_SWITCH_REGISTERS;
0650
0651 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
0652
0653 __asm__ volatile (
0654 ARM_SWITCH_TO_ARM
0655 "mcr p15, 0, %[mva], c8, c7, 3\n"
0656 ARM_SWITCH_BACK
0657 : ARM_SWITCH_OUTPUT
0658 : [mva] "r" (mva)
0659 );
0660 }
0661
0662 ARM_CP15_TEXT_SECTION static inline void
0663 arm_cp15_tlb_invalidate_entry_all_asids_inner_shareable(const void *mva)
0664 {
0665 ARM_SWITCH_REGISTERS;
0666
0667 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
0668
0669 __asm__ volatile (
0670 ARM_SWITCH_TO_ARM
0671 "mcr p15, 0, %[mva], c8, c3, 3\n"
0672 ARM_SWITCH_BACK
0673 : ARM_SWITCH_OUTPUT
0674 : [mva] "r" (mva)
0675 );
0676 }
0677
0678 ARM_CP15_TEXT_SECTION static inline void
0679 arm_cp15_tlb_instruction_invalidate(void)
0680 {
0681 ARM_SWITCH_REGISTERS;
0682 uint32_t sbz = 0;
0683
0684 __asm__ volatile (
0685 ARM_SWITCH_TO_ARM
0686 "mcr p15, 0, %[sbz], c8, c5, 0\n"
0687 ARM_SWITCH_BACK
0688 : ARM_SWITCH_OUTPUT
0689 : [sbz] "r" (sbz)
0690 );
0691 }
0692
0693 ARM_CP15_TEXT_SECTION static inline void
0694 arm_cp15_tlb_instruction_invalidate_entry(const void *mva)
0695 {
0696 ARM_SWITCH_REGISTERS;
0697
0698 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
0699
0700 __asm__ volatile (
0701 ARM_SWITCH_TO_ARM
0702 "mcr p15, 0, %[mva], c8, c5, 1\n"
0703 ARM_SWITCH_BACK
0704 : ARM_SWITCH_OUTPUT
0705 : [mva] "r" (mva)
0706 );
0707 }
0708
0709 ARM_CP15_TEXT_SECTION static inline void
0710 arm_cp15_tlb_data_invalidate(void)
0711 {
0712 ARM_SWITCH_REGISTERS;
0713 uint32_t sbz = 0;
0714
0715 __asm__ volatile (
0716 ARM_SWITCH_TO_ARM
0717 "mcr p15, 0, %[sbz], c8, c6, 0\n"
0718 ARM_SWITCH_BACK
0719 : ARM_SWITCH_OUTPUT
0720 : [sbz] "r" (sbz)
0721 );
0722 }
0723
0724 ARM_CP15_TEXT_SECTION static inline void
0725 arm_cp15_tlb_data_invalidate_entry(const void *mva)
0726 {
0727 ARM_SWITCH_REGISTERS;
0728
0729 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
0730
0731 __asm__ volatile (
0732 ARM_SWITCH_TO_ARM
0733 "mcr p15, 0, %[mva], c8, c6, 1\n"
0734 ARM_SWITCH_BACK
0735 : ARM_SWITCH_OUTPUT
0736 : [mva] "r" (mva)
0737 );
0738 }
0739
0740 ARM_CP15_TEXT_SECTION static inline void
0741 arm_cp15_tlb_lockdown_entry(const void *mva)
0742 {
0743 uint32_t arm_switch_reg;
0744
0745 __asm__ volatile (
0746 ARM_SWITCH_TO_ARM
0747 "add %[arm_switch_reg], pc, #16\n"
0748 "mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n"
0749 "mcr p15, 0, %[mva], c8, c7, 1\n"
0750 "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
0751 "orr %[arm_switch_reg], #0x1\n"
0752 "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
0753 "ldr %[mva], [%[mva]]\n"
0754 "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
0755 "bic %[arm_switch_reg], #0x1\n"
0756 "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
0757 ARM_SWITCH_BACK
0758 : [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg)
0759 : "[mva]" (mva)
0760 );
0761 }
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772 ARM_CP15_TEXT_SECTION static inline uint32_t
0773 arm_cp15_get_cache_type(void)
0774 {
0775 ARM_SWITCH_REGISTERS;
0776 uint32_t val;
0777
0778 __asm__ volatile (
0779 ARM_SWITCH_TO_ARM
0780 "mrc p15, 0, %[val], c0, c0, 1\n"
0781 ARM_SWITCH_BACK
0782 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0783 );
0784
0785 return val;
0786 }
0787
0788
0789 ARM_CP15_TEXT_SECTION static inline int
0790 arm_cp15_cache_type_get_format(uint32_t ct)
0791 {
0792 return (ct >> 29) & 0x7U;
0793 }
0794
0795
0796 ARM_CP15_TEXT_SECTION static inline uint32_t
0797 arm_cp15_get_min_cache_line_size(void)
0798 {
0799 uint32_t mcls = 0;
0800 uint32_t ct = arm_cp15_get_cache_type();
0801 uint32_t format = arm_cp15_cache_type_get_format(ct);
0802
0803 if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
0804
0805 mcls = (1U << (ct & 0xf)) * 4;
0806 } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
0807
0808 uint32_t mask = (1U << 12) - 1;
0809 uint32_t dcls = (ct >> 12) & mask;
0810 uint32_t icls = ct & mask;
0811
0812 mcls = dcls <= icls ? dcls : icls;
0813 }
0814
0815 return mcls;
0816 }
0817
0818
0819 ARM_CP15_TEXT_SECTION static inline uint32_t
0820 arm_cp15_get_data_cache_line_size(void)
0821 {
0822 uint32_t mcls = 0;
0823 uint32_t ct = arm_cp15_get_cache_type();
0824 uint32_t format = arm_cp15_cache_type_get_format(ct);
0825
0826 if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
0827
0828 mcls = (1U << ((ct & 0xf0000) >> 16)) * 4;
0829 } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
0830
0831 uint32_t mask = (1U << 12) - 1;
0832 mcls = (ct >> 12) & mask;
0833 }
0834
0835 return mcls;
0836 }
0837
0838
0839 ARM_CP15_TEXT_SECTION static inline uint32_t
0840 arm_cp15_get_instruction_cache_line_size(void)
0841 {
0842 uint32_t mcls = 0;
0843 uint32_t ct = arm_cp15_get_cache_type();
0844 uint32_t format = arm_cp15_cache_type_get_format(ct);
0845
0846 if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
0847
0848 mcls = (1U << (ct & 0x0000f)) * 4;
0849 } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
0850
0851 uint32_t mask = (1U << 12) - 1;
0852 mcls = ct & mask;;
0853 }
0854
0855 return mcls;
0856 }
0857
0858
0859
0860 ARM_CP15_TEXT_SECTION static inline uint32_t
0861 arm_cp15_get_cache_size_id(void)
0862 {
0863 ARM_SWITCH_REGISTERS;
0864 uint32_t val;
0865
0866 __asm__ volatile (
0867 ARM_SWITCH_TO_ARM
0868 "mrc p15, 1, %[val], c0, c0, 0\n"
0869 ARM_SWITCH_BACK
0870 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0871 );
0872
0873 return val;
0874 }
0875
0876 ARM_CP15_TEXT_SECTION static inline uint32_t
0877 arm_ccsidr_get_line_power(uint32_t ccsidr)
0878 {
0879 return (ccsidr & 0x7) + 4;
0880 }
0881
0882 ARM_CP15_TEXT_SECTION static inline uint32_t
0883 arm_ccsidr_get_associativity(uint32_t ccsidr)
0884 {
0885 return ((ccsidr >> 3) & 0x3ff) + 1;
0886 }
0887
0888 ARM_CP15_TEXT_SECTION static inline uint32_t
0889 arm_ccsidr_get_num_sets(uint32_t ccsidr)
0890 {
0891 return ((ccsidr >> 13) & 0x7fff) + 1;
0892 }
0893
0894
0895
0896 ARM_CP15_TEXT_SECTION static inline uint32_t
0897 arm_cp15_get_cache_level_id(void)
0898 {
0899 ARM_SWITCH_REGISTERS;
0900 uint32_t val;
0901
0902 __asm__ volatile (
0903 ARM_SWITCH_TO_ARM
0904 "mrc p15, 1, %[val], c0, c0, 1\n"
0905 ARM_SWITCH_BACK
0906 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0907 );
0908
0909 return val;
0910 }
0911
0912 ARM_CP15_TEXT_SECTION static inline uint32_t
0913 arm_clidr_get_level_of_coherency(uint32_t clidr)
0914 {
0915 return (clidr >> 24) & 0x7;
0916 }
0917
0918 ARM_CP15_TEXT_SECTION static inline uint32_t
0919 arm_clidr_get_cache_type(uint32_t clidr, uint32_t level)
0920 {
0921 return (clidr >> (3 * level)) & 0x7;
0922 }
0923
0924
0925
0926 ARM_CP15_TEXT_SECTION static inline uint32_t
0927 arm_cp15_get_cache_size_selection(void)
0928 {
0929 ARM_SWITCH_REGISTERS;
0930 uint32_t val;
0931
0932 __asm__ volatile (
0933 ARM_SWITCH_TO_ARM
0934 "mrc p15, 2, %[val], c0, c0, 0\n"
0935 ARM_SWITCH_BACK
0936 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
0937 );
0938
0939 return val;
0940 }
0941
0942 ARM_CP15_TEXT_SECTION static inline void
0943 arm_cp15_set_cache_size_selection(uint32_t val)
0944 {
0945 ARM_SWITCH_REGISTERS;
0946
0947 __asm__ volatile (
0948 ARM_SWITCH_TO_ARM
0949 "mcr p15, 2, %[val], c0, c0, 0\n"
0950 ARM_SWITCH_BACK
0951 : ARM_SWITCH_OUTPUT
0952 : [val] "r" (val)
0953 : "memory"
0954 );
0955 }
0956
0957 ARM_CP15_TEXT_SECTION static inline uint32_t
0958 arm_cp15_get_cache_size_id_for_level(uint32_t level_and_inst_dat)
0959 {
0960 rtems_interrupt_level irq_level;
0961 uint32_t ccsidr;
0962
0963 rtems_interrupt_local_disable(irq_level);
0964 arm_cp15_set_cache_size_selection(level_and_inst_dat);
0965 _ARM_Instruction_synchronization_barrier();
0966 ccsidr = arm_cp15_get_cache_size_id();
0967 rtems_interrupt_local_enable(irq_level);
0968
0969 return ccsidr;
0970 }
0971
0972 ARM_CP15_TEXT_SECTION static inline void
0973 arm_cp15_cache_invalidate(void)
0974 {
0975 ARM_SWITCH_REGISTERS;
0976 uint32_t sbz = 0;
0977
0978 __asm__ volatile (
0979 ARM_SWITCH_TO_ARM
0980 "mcr p15, 0, %[sbz], c7, c7, 0\n"
0981 ARM_SWITCH_BACK
0982 : ARM_SWITCH_OUTPUT
0983 : [sbz] "r" (sbz)
0984 : "memory"
0985 );
0986 }
0987
0988
0989
0990 ARM_CP15_TEXT_SECTION static inline void
0991 arm_cp15_instruction_cache_inner_shareable_invalidate_all(void)
0992 {
0993 ARM_SWITCH_REGISTERS;
0994 uint32_t sbz = 0;
0995
0996 __asm__ volatile (
0997 ARM_SWITCH_TO_ARM
0998 "mcr p15, 0, %[sbz], c7, c1, 0\n"
0999 ARM_SWITCH_BACK
1000 : ARM_SWITCH_OUTPUT
1001 : [sbz] "r" (sbz)
1002 : "memory"
1003 );
1004 }
1005
1006
1007
1008 ARM_CP15_TEXT_SECTION static inline void
1009 arm_cp15_branch_predictor_inner_shareable_invalidate_all(void)
1010 {
1011 ARM_SWITCH_REGISTERS;
1012 uint32_t sbz = 0;
1013
1014 __asm__ volatile (
1015 ARM_SWITCH_TO_ARM
1016 "mcr p15, 0, %[sbz], c7, c1, 6\n"
1017 ARM_SWITCH_BACK
1018 : ARM_SWITCH_OUTPUT
1019 : [sbz] "r" (sbz)
1020 : "memory"
1021 );
1022 }
1023
1024
1025
1026 ARM_CP15_TEXT_SECTION static inline void
1027 arm_cp15_branch_predictor_invalidate_all(void)
1028 {
1029 ARM_SWITCH_REGISTERS;
1030 uint32_t sbz = 0;
1031
1032 __asm__ volatile (
1033 ARM_SWITCH_TO_ARM
1034 "mcr p15, 0, %[sbz], c7, c5, 6\n"
1035 ARM_SWITCH_BACK
1036 : ARM_SWITCH_OUTPUT
1037 : [sbz] "r" (sbz)
1038 : "memory"
1039 );
1040 }
1041
1042
1043 ARM_CP15_TEXT_SECTION static inline void
1044 arm_cp15_flush_prefetch_buffer(void)
1045 {
1046 ARM_SWITCH_REGISTERS;
1047 uint32_t sbz = 0;
1048
1049 __asm__ volatile (
1050 ARM_SWITCH_TO_ARM
1051 "mcr p15, 0, %[sbz], c7, c5, 4\n"
1052 ARM_SWITCH_BACK
1053 : ARM_SWITCH_OUTPUT
1054 : [sbz] "r" (sbz)
1055 : "memory"
1056 );
1057 }
1058
1059 ARM_CP15_TEXT_SECTION static inline void
1060 arm_cp15_instruction_cache_invalidate(void)
1061 {
1062 ARM_SWITCH_REGISTERS;
1063 uint32_t sbz = 0;
1064
1065 __asm__ volatile (
1066 ARM_SWITCH_TO_ARM
1067 "mcr p15, 0, %[sbz], c7, c5, 0\n"
1068 ARM_SWITCH_BACK
1069 : ARM_SWITCH_OUTPUT
1070 : [sbz] "r" (sbz)
1071 : "memory"
1072 );
1073 }
1074
1075 ARM_CP15_TEXT_SECTION static inline void
1076 arm_cp15_instruction_cache_invalidate_line(const void *mva)
1077 {
1078 ARM_SWITCH_REGISTERS;
1079
1080 mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1081
1082 __asm__ volatile (
1083 ARM_SWITCH_TO_ARM
1084 "mcr p15, 0, %[mva], c7, c5, 1\n"
1085 ARM_SWITCH_BACK
1086 : ARM_SWITCH_OUTPUT
1087 : [mva] "r" (mva)
1088 : "memory"
1089 );
1090 }
1091
1092 ARM_CP15_TEXT_SECTION static inline void
1093 arm_cp15_instruction_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
1094 {
1095 ARM_SWITCH_REGISTERS;
1096
1097 __asm__ volatile (
1098 ARM_SWITCH_TO_ARM
1099 "mcr p15, 0, %[set_and_way], c7, c5, 2\n"
1100 ARM_SWITCH_BACK
1101 : ARM_SWITCH_OUTPUT
1102 : [set_and_way] "r" (set_and_way)
1103 : "memory"
1104 );
1105 }
1106
1107 ARM_CP15_TEXT_SECTION static inline void
1108 arm_cp15_instruction_cache_prefetch_line(const void *mva)
1109 {
1110 ARM_SWITCH_REGISTERS;
1111
1112 mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1113
1114 __asm__ volatile (
1115 ARM_SWITCH_TO_ARM
1116 "mcr p15, 0, %[mva], c7, c13, 1\n"
1117 ARM_SWITCH_BACK
1118 : ARM_SWITCH_OUTPUT
1119 : [mva] "r" (mva)
1120 );
1121 }
1122
1123 ARM_CP15_TEXT_SECTION static inline void
1124 arm_cp15_data_cache_invalidate(void)
1125 {
1126 ARM_SWITCH_REGISTERS;
1127 uint32_t sbz = 0;
1128
1129 __asm__ volatile (
1130 ARM_SWITCH_TO_ARM
1131 "mcr p15, 0, %[sbz], c7, c6, 0\n"
1132 ARM_SWITCH_BACK
1133 : ARM_SWITCH_OUTPUT
1134 : [sbz] "r" (sbz)
1135 : "memory"
1136 );
1137 }
1138
1139 ARM_CP15_TEXT_SECTION static inline void
1140 arm_cp15_data_cache_invalidate_line(const void *mva)
1141 {
1142 ARM_SWITCH_REGISTERS;
1143
1144 mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1145
1146 __asm__ volatile (
1147 ARM_SWITCH_TO_ARM
1148 "mcr p15, 0, %[mva], c7, c6, 1\n"
1149 ARM_SWITCH_BACK
1150 : ARM_SWITCH_OUTPUT
1151 : [mva] "r" (mva)
1152 : "memory"
1153 );
1154 }
1155
1156 ARM_CP15_TEXT_SECTION static inline void
1157 arm_cp15_data_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
1158 {
1159 ARM_SWITCH_REGISTERS;
1160
1161 __asm__ volatile (
1162 ARM_SWITCH_TO_ARM
1163 "mcr p15, 0, %[set_and_way], c7, c6, 2\n"
1164 ARM_SWITCH_BACK
1165 : ARM_SWITCH_OUTPUT
1166 : [set_and_way] "r" (set_and_way)
1167 : "memory"
1168 );
1169 }
1170
1171 ARM_CP15_TEXT_SECTION static inline void
1172 arm_cp15_cache_invalidate_level(uint32_t level, uint32_t inst_data_fl)
1173 {
1174 uint32_t ccsidr;
1175 uint32_t line_power;
1176 uint32_t associativity;
1177 uint32_t way;
1178 uint32_t way_shift;
1179
1180 ccsidr = arm_cp15_get_cache_size_id_for_level((level << 1) | inst_data_fl);
1181
1182 line_power = arm_ccsidr_get_line_power(ccsidr);
1183 associativity = arm_ccsidr_get_associativity(ccsidr);
1184 way_shift = __builtin_clz(associativity - 1);
1185
1186 for (way = 0; way < associativity; ++way) {
1187 uint32_t num_sets = arm_ccsidr_get_num_sets(ccsidr);
1188 uint32_t set;
1189
1190 for (set = 0; set < num_sets; ++set) {
1191 uint32_t set_way = (way << way_shift)
1192 | (set << line_power)
1193 | (level << 1);
1194
1195 arm_cp15_data_cache_invalidate_line_by_set_and_way(set_way);
1196 }
1197 }
1198 }
1199
1200 ARM_CP15_TEXT_SECTION static inline void
1201 arm_cp15_data_cache_invalidate_all_levels(void)
1202 {
1203 uint32_t clidr = arm_cp15_get_cache_level_id();
1204 uint32_t loc = arm_clidr_get_level_of_coherency(clidr);
1205 uint32_t level = 0;
1206
1207 for (level = 0; level < loc; ++level) {
1208 uint32_t ctype = arm_clidr_get_cache_type(clidr, level);
1209
1210
1211 if (((ctype & (0x6)) == 2) || (ctype == 4)) {
1212 arm_cp15_cache_invalidate_level(level, 0);
1213 }
1214 }
1215 }
1216
1217 ARM_CP15_TEXT_SECTION static inline void
1218 arm_cp15_data_cache_clean_line(const void *mva)
1219 {
1220 ARM_SWITCH_REGISTERS;
1221
1222 mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1223
1224 __asm__ volatile (
1225 ARM_SWITCH_TO_ARM
1226 "mcr p15, 0, %[mva], c7, c10, 1\n"
1227 ARM_SWITCH_BACK
1228 : ARM_SWITCH_OUTPUT
1229 : [mva] "r" (mva)
1230 : "memory"
1231 );
1232 }
1233
1234 ARM_CP15_TEXT_SECTION static inline void
1235 arm_cp15_data_cache_clean_line_by_set_and_way(uint32_t set_and_way)
1236 {
1237 ARM_SWITCH_REGISTERS;
1238
1239 __asm__ volatile (
1240 ARM_SWITCH_TO_ARM
1241 "mcr p15, 0, %[set_and_way], c7, c10, 2\n"
1242 ARM_SWITCH_BACK
1243 : ARM_SWITCH_OUTPUT
1244 : [set_and_way] "r" (set_and_way)
1245 : "memory"
1246 );
1247 }
1248
1249 ARM_CP15_TEXT_SECTION static inline void
1250 arm_cp15_data_cache_clean_level(uint32_t level)
1251 {
1252 uint32_t ccsidr;
1253 uint32_t line_power;
1254 uint32_t associativity;
1255 uint32_t way;
1256 uint32_t way_shift;
1257
1258 ccsidr = arm_cp15_get_cache_size_id_for_level(level << 1);
1259
1260 line_power = arm_ccsidr_get_line_power(ccsidr);
1261 associativity = arm_ccsidr_get_associativity(ccsidr);
1262 way_shift = __builtin_clz(associativity - 1);
1263
1264 for (way = 0; way < associativity; ++way) {
1265 uint32_t num_sets = arm_ccsidr_get_num_sets(ccsidr);
1266 uint32_t set;
1267
1268 for (set = 0; set < num_sets; ++set) {
1269 uint32_t set_way = (way << way_shift)
1270 | (set << line_power)
1271 | (level << 1);
1272
1273 arm_cp15_data_cache_clean_line_by_set_and_way(set_way);
1274 }
1275 }
1276 }
1277
1278 ARM_CP15_TEXT_SECTION static inline void
1279 arm_cp15_data_cache_clean_all_levels(void)
1280 {
1281 uint32_t clidr = arm_cp15_get_cache_level_id();
1282 uint32_t loc = arm_clidr_get_level_of_coherency(clidr);
1283 uint32_t level = 0;
1284
1285 for (level = 0; level < loc; ++level) {
1286 uint32_t ctype = arm_clidr_get_cache_type(clidr, level);
1287
1288
1289 if (((ctype & (0x6)) == 2) || (ctype == 4)) {
1290 arm_cp15_data_cache_clean_level(level);
1291 }
1292 }
1293 }
1294
1295 ARM_CP15_TEXT_SECTION static inline void
1296 arm_cp15_data_cache_test_and_clean(void)
1297 {
1298 ARM_SWITCH_REGISTERS;
1299
1300 __asm__ volatile (
1301 ARM_SWITCH_TO_ARM
1302 "1:\n"
1303 "mrc p15, 0, r15, c7, c10, 3\n"
1304 "bne 1b\n"
1305 ARM_SWITCH_BACK
1306 : ARM_SWITCH_OUTPUT
1307 :
1308 : "memory"
1309 );
1310 }
1311
1312 ARM_CP15_TEXT_SECTION static inline void
1313 arm_cp15_data_cache_clean_and_invalidate(void)
1314 {
1315 ARM_SWITCH_REGISTERS;
1316
1317 #if __ARM_ARCH >= 6
1318
1319
1320
1321
1322
1323 uint32_t sbz = 0;
1324
1325 __asm__ volatile (
1326 ARM_SWITCH_TO_ARM
1327 "mcr p15, 0, %[sbz], c7, c14, 0\n"
1328 ARM_SWITCH_BACK
1329 : ARM_SWITCH_OUTPUT
1330 : [sbz] "r" (sbz)
1331 : "memory"
1332 );
1333 #else
1334
1335
1336
1337
1338 __asm__ volatile (
1339 ARM_SWITCH_TO_ARM
1340 "1:\n"
1341 "mrc p15, 0, r15, c7, c14, 3\n"
1342 "bne 1b\n"
1343 ARM_SWITCH_BACK
1344 : ARM_SWITCH_OUTPUT
1345 :
1346 : "memory"
1347 );
1348 #endif
1349 }
1350
1351 ARM_CP15_TEXT_SECTION static inline void
1352 arm_cp15_data_cache_clean_and_invalidate_line(const void *mva)
1353 {
1354 ARM_SWITCH_REGISTERS;
1355
1356 mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
1357
1358 __asm__ volatile (
1359 ARM_SWITCH_TO_ARM
1360 "mcr p15, 0, %[mva], c7, c14, 1\n"
1361 ARM_SWITCH_BACK
1362 : ARM_SWITCH_OUTPUT
1363 : [mva] "r" (mva)
1364 : "memory"
1365 );
1366 }
1367
1368 ARM_CP15_TEXT_SECTION static inline void
1369 arm_cp15_data_cache_clean_and_invalidate_line_by_set_and_way(uint32_t set_and_way)
1370 {
1371 ARM_SWITCH_REGISTERS;
1372
1373 __asm__ volatile (
1374 ARM_SWITCH_TO_ARM
1375 "mcr p15, 0, %[set_and_way], c7, c14, 2\n"
1376 ARM_SWITCH_BACK
1377 : ARM_SWITCH_OUTPUT
1378 : [set_and_way] "r" (set_and_way)
1379 : "memory"
1380 );
1381 }
1382
1383 ARM_CP15_TEXT_SECTION static inline void
1384 arm_cp15_data_cache_test_and_clean_and_invalidate(void)
1385 {
1386 ARM_SWITCH_REGISTERS;
1387
1388 __asm__ volatile (
1389 ARM_SWITCH_TO_ARM
1390 "1:\n"
1391 "mrc p15, 0, r15, c7, c14, 3\n"
1392 "bne 1b\n"
1393 ARM_SWITCH_BACK
1394 : ARM_SWITCH_OUTPUT
1395 :
1396 : "memory"
1397 );
1398 }
1399
1400
1401
1402 ARM_CP15_TEXT_SECTION static inline void
1403 arm_cp15_drain_write_buffer(void)
1404 {
1405 ARM_SWITCH_REGISTERS;
1406 uint32_t sbz = 0;
1407
1408 __asm__ volatile (
1409 ARM_SWITCH_TO_ARM
1410 "mcr p15, 0, %[sbz], c7, c10, 4\n"
1411 ARM_SWITCH_BACK
1412 : ARM_SWITCH_OUTPUT
1413 : [sbz] "r" (sbz)
1414 : "memory"
1415 );
1416 }
1417
1418 ARM_CP15_TEXT_SECTION static inline void
1419 arm_cp15_wait_for_interrupt(void)
1420 {
1421 ARM_SWITCH_REGISTERS;
1422 uint32_t sbz = 0;
1423
1424 __asm__ volatile (
1425 ARM_SWITCH_TO_ARM
1426 "mcr p15, 0, %[sbz], c7, c0, 4\n"
1427 ARM_SWITCH_BACK
1428 : ARM_SWITCH_OUTPUT
1429 : [sbz] "r" (sbz)
1430 : "memory"
1431 );
1432 }
1433
1434 ARM_CP15_TEXT_SECTION static inline uint32_t
1435 arm_cp15_get_multiprocessor_affinity(void)
1436 {
1437 ARM_SWITCH_REGISTERS;
1438 uint32_t mpidr;
1439
1440 __asm__ volatile (
1441 ARM_SWITCH_TO_ARM
1442 "mrc p15, 0, %[mpidr], c0, c0, 5\n"
1443 ARM_SWITCH_BACK
1444 : [mpidr] "=&r" (mpidr) ARM_SWITCH_ADDITIONAL_OUTPUT
1445 );
1446
1447 return mpidr & 0xff;
1448 }
1449
1450 ARM_CP15_TEXT_SECTION static inline uint32_t
1451 arm_cortex_a9_get_multiprocessor_cpu_id(void)
1452 {
1453 return arm_cp15_get_multiprocessor_affinity() & 0xff;
1454 }
1455
1456 #define ARM_CORTEX_A9_ACTL_FW (1U << 0)
1457 #define ARM_CORTEX_A9_ACTL_L2_PREFETCH_HINT_ENABLE (1U << 1)
1458 #define ARM_CORTEX_A9_ACTL_L1_PREFETCH_ENABLE (1U << 2)
1459 #define ARM_CORTEX_A9_ACTL_WRITE_FULL_LINE_OF_ZEROS_MODE (1U << 3)
1460 #define ARM_CORTEX_A9_ACTL_SMP (1U << 6)
1461 #define ARM_CORTEX_A9_ACTL_EXCL (1U << 7)
1462 #define ARM_CORTEX_A9_ACTL_ALLOC_IN_ONE_WAY (1U << 8)
1463 #define ARM_CORTEX_A9_ACTL_PARITY_ON (1U << 9)
1464
1465 ARM_CP15_TEXT_SECTION static inline uint32_t
1466 arm_cp15_get_auxiliary_control(void)
1467 {
1468 ARM_SWITCH_REGISTERS;
1469 uint32_t val;
1470
1471 __asm__ volatile (
1472 ARM_SWITCH_TO_ARM
1473 "mrc p15, 0, %[val], c1, c0, 1\n"
1474 ARM_SWITCH_BACK
1475 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1476 );
1477
1478 return val;
1479 }
1480
1481 ARM_CP15_TEXT_SECTION static inline void
1482 arm_cp15_set_auxiliary_control(uint32_t val)
1483 {
1484 ARM_SWITCH_REGISTERS;
1485
1486 __asm__ volatile (
1487 ARM_SWITCH_TO_ARM
1488 "mcr p15, 0, %[val], c1, c0, 1\n"
1489 ARM_SWITCH_BACK
1490 : ARM_SWITCH_OUTPUT
1491 : [val] "r" (val)
1492 );
1493 }
1494
1495
1496
1497 ARM_CP15_TEXT_SECTION static inline uint32_t
1498 arm_cp15_get_processor_feature_1(void)
1499 {
1500 ARM_SWITCH_REGISTERS;
1501 uint32_t val;
1502
1503 __asm__ volatile (
1504 ARM_SWITCH_TO_ARM
1505 "mrc p15, 0, %[val], c0, c1, 1\n"
1506 ARM_SWITCH_BACK
1507 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1508 );
1509
1510 return val;
1511 }
1512
1513
1514
1515 ARM_CP15_TEXT_SECTION static inline void
1516 *arm_cp15_get_vector_base_address(void)
1517 {
1518 ARM_SWITCH_REGISTERS;
1519 void *base;
1520
1521 __asm__ volatile (
1522 ARM_SWITCH_TO_ARM
1523 "mrc p15, 0, %[base], c12, c0, 0\n"
1524 ARM_SWITCH_BACK
1525 : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
1526 );
1527
1528 return base;
1529 }
1530
1531 ARM_CP15_TEXT_SECTION static inline void
1532 arm_cp15_set_vector_base_address(void *base)
1533 {
1534 ARM_SWITCH_REGISTERS;
1535
1536 __asm__ volatile (
1537 ARM_SWITCH_TO_ARM
1538 "mcr p15, 0, %[base], c12, c0, 0\n"
1539 ARM_SWITCH_BACK
1540 : ARM_SWITCH_OUTPUT
1541 : [base] "r" (base)
1542 );
1543 }
1544
1545 ARM_CP15_TEXT_SECTION static inline void
1546 *arm_cp15_get_hyp_vector_base_address(void)
1547 {
1548 ARM_SWITCH_REGISTERS;
1549 void *base;
1550
1551 __asm__ volatile (
1552 ARM_SWITCH_TO_ARM
1553 "mrc p15, 4, %[base], c12, c0, 0\n"
1554 ARM_SWITCH_BACK
1555 : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
1556 );
1557
1558 return base;
1559 }
1560
1561 ARM_CP15_TEXT_SECTION static inline void
1562 arm_cp15_set_hyp_vector_base_address(void *base)
1563 {
1564 ARM_SWITCH_REGISTERS;
1565
1566 __asm__ volatile (
1567 ARM_SWITCH_TO_ARM
1568 "mcr p15, 4, %[base], c12, c0, 0\n"
1569 ARM_SWITCH_BACK
1570 : ARM_SWITCH_OUTPUT
1571 : [base] "r" (base)
1572 );
1573 }
1574
1575
1576 ARM_CP15_TEXT_SECTION static inline uint32_t
1577 arm_cp15_get_performance_monitors_cycle_count(void)
1578 {
1579 ARM_SWITCH_REGISTERS;
1580 uint32_t val;
1581
1582 __asm__ volatile (
1583 ARM_SWITCH_TO_ARM
1584 "mrc p15, 0, %[val], c9, c13, 0\n"
1585 ARM_SWITCH_BACK
1586 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1587 );
1588
1589 return val;
1590 }
1591
1592
1593 ARM_CP15_TEXT_SECTION static inline void
1594 arm_cp15_set_performance_monitors_cycle_count(uint32_t val)
1595 {
1596 ARM_SWITCH_REGISTERS;
1597
1598 __asm__ volatile (
1599 ARM_SWITCH_TO_ARM
1600 "mcr p15, 0, %[val], c9, c13, 0\n"
1601 ARM_SWITCH_BACK
1602 : ARM_SWITCH_OUTPUT
1603 : [val] "r" (val)
1604 );
1605 }
1606
1607
1608 ARM_CP15_TEXT_SECTION static inline uint32_t
1609 arm_cp15_get_performance_monitors_common_event_id_0(void)
1610 {
1611 ARM_SWITCH_REGISTERS;
1612 uint32_t val;
1613
1614 __asm__ volatile (
1615 ARM_SWITCH_TO_ARM
1616 "mrc p15, 0, %[val], c9, c12, 6\n"
1617 ARM_SWITCH_BACK
1618 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1619 );
1620
1621 return val;
1622 }
1623
1624
1625 ARM_CP15_TEXT_SECTION static inline uint32_t
1626 arm_cp15_get_performance_monitors_common_event_id_1(void)
1627 {
1628 ARM_SWITCH_REGISTERS;
1629 uint32_t val;
1630
1631 __asm__ volatile (
1632 ARM_SWITCH_TO_ARM
1633 "mrc p15, 0, %[val], c9, c12, 7\n"
1634 ARM_SWITCH_BACK
1635 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1636 );
1637
1638 return val;
1639 }
1640
1641 #define ARM_CP15_PMCLRSET_CYCLE_COUNTER 0x80000000
1642
1643
1644 ARM_CP15_TEXT_SECTION static inline uint32_t
1645 arm_cp15_get_performance_monitors_count_enable_clear(void)
1646 {
1647 ARM_SWITCH_REGISTERS;
1648 uint32_t val;
1649
1650 __asm__ volatile (
1651 ARM_SWITCH_TO_ARM
1652 "mrc p15, 0, %[val], c9, c12, 2\n"
1653 ARM_SWITCH_BACK
1654 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1655 );
1656
1657 return val;
1658 }
1659
1660
1661 ARM_CP15_TEXT_SECTION static inline void
1662 arm_cp15_set_performance_monitors_count_enable_clear(uint32_t val)
1663 {
1664 ARM_SWITCH_REGISTERS;
1665
1666 __asm__ volatile (
1667 ARM_SWITCH_TO_ARM
1668 "mcr p15, 0, %[val], c9, c12, 2\n"
1669 ARM_SWITCH_BACK
1670 : ARM_SWITCH_OUTPUT
1671 : [val] "r" (val)
1672 );
1673 }
1674
1675
1676 ARM_CP15_TEXT_SECTION static inline uint32_t
1677 arm_cp15_get_performance_monitors_count_enable_set(void)
1678 {
1679 ARM_SWITCH_REGISTERS;
1680 uint32_t val;
1681
1682 __asm__ volatile (
1683 ARM_SWITCH_TO_ARM
1684 "mrc p15, 0, %[val], c9, c12, 1\n"
1685 ARM_SWITCH_BACK
1686 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1687 );
1688
1689 return val;
1690 }
1691
1692
1693 ARM_CP15_TEXT_SECTION static inline void
1694 arm_cp15_set_performance_monitors_count_enable_set(uint32_t val)
1695 {
1696 ARM_SWITCH_REGISTERS;
1697
1698 __asm__ volatile (
1699 ARM_SWITCH_TO_ARM
1700 "mcr p15, 0, %[val], c9, c12, 1\n"
1701 ARM_SWITCH_BACK
1702 : ARM_SWITCH_OUTPUT
1703 : [val] "r" (val)
1704 );
1705 }
1706
1707 #define ARM_CP15_PMCR_IMP(x) ((x) << 24)
1708 #define ARM_CP15_PMCR_IDCODE(x) ((x) << 16)
1709 #define ARM_CP15_PMCR_N(x) ((x) << 11)
1710 #define ARM_CP15_PMCR_DP (1U << 5)
1711 #define ARM_CP15_PMCR_X (1U << 4)
1712 #define ARM_CP15_PMCR_D (1U << 3)
1713 #define ARM_CP15_PMCR_C (1U << 2)
1714 #define ARM_CP15_PMCR_P (1U << 1)
1715 #define ARM_CP15_PMCR_E (1U << 0)
1716
1717
1718 ARM_CP15_TEXT_SECTION static inline uint32_t
1719 arm_cp15_get_performance_monitors_control(void)
1720 {
1721 ARM_SWITCH_REGISTERS;
1722 uint32_t val;
1723
1724 __asm__ volatile (
1725 ARM_SWITCH_TO_ARM
1726 "mrc p15, 0, %[val], c9, c12, 0\n"
1727 ARM_SWITCH_BACK
1728 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1729 );
1730
1731 return val;
1732 }
1733
1734
1735 ARM_CP15_TEXT_SECTION static inline void
1736 arm_cp15_set_performance_monitors_control(uint32_t val)
1737 {
1738 ARM_SWITCH_REGISTERS;
1739
1740 __asm__ volatile (
1741 ARM_SWITCH_TO_ARM
1742 "mcr p15, 0, %[val], c9, c12, 0\n"
1743 ARM_SWITCH_BACK
1744 : ARM_SWITCH_OUTPUT
1745 : [val] "r" (val)
1746 );
1747 }
1748
1749
1750 ARM_CP15_TEXT_SECTION static inline uint32_t
1751 arm_cp15_get_performance_monitors_interrupt_enable_clear(void)
1752 {
1753 ARM_SWITCH_REGISTERS;
1754 uint32_t val;
1755
1756 __asm__ volatile (
1757 ARM_SWITCH_TO_ARM
1758 "mrc p15, 0, %[val], c9, c14, 2\n"
1759 ARM_SWITCH_BACK
1760 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1761 );
1762
1763 return val;
1764 }
1765
1766
1767 ARM_CP15_TEXT_SECTION static inline void
1768 arm_cp15_set_performance_monitors_interrupt_enable_clear(uint32_t val)
1769 {
1770 ARM_SWITCH_REGISTERS;
1771
1772 __asm__ volatile (
1773 ARM_SWITCH_TO_ARM
1774 "mcr p15, 0, %[val], c9, c14, 2\n"
1775 ARM_SWITCH_BACK
1776 : ARM_SWITCH_OUTPUT
1777 : [val] "r" (val)
1778 );
1779 }
1780
1781
1782 ARM_CP15_TEXT_SECTION static inline uint32_t
1783 arm_cp15_get_performance_monitors_interrupt_enable_set(void)
1784 {
1785 ARM_SWITCH_REGISTERS;
1786 uint32_t val;
1787
1788 __asm__ volatile (
1789 ARM_SWITCH_TO_ARM
1790 "mrc p15, 0, %[val], c9, c14, 1\n"
1791 ARM_SWITCH_BACK
1792 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1793 );
1794
1795 return val;
1796 }
1797
1798
1799 ARM_CP15_TEXT_SECTION static inline void
1800 arm_cp15_set_performance_monitors_interrupt_enable_set(uint32_t val)
1801 {
1802 ARM_SWITCH_REGISTERS;
1803
1804 __asm__ volatile (
1805 ARM_SWITCH_TO_ARM
1806 "mcr p15, 0, %[val], c9, c14, 1\n"
1807 ARM_SWITCH_BACK
1808 : ARM_SWITCH_OUTPUT
1809 : [val] "r" (val)
1810 );
1811 }
1812
1813
1814 ARM_CP15_TEXT_SECTION static inline uint32_t
1815 arm_cp15_get_performance_monitors_overflow_flag_status(void)
1816 {
1817 ARM_SWITCH_REGISTERS;
1818 uint32_t val;
1819
1820 __asm__ volatile (
1821 ARM_SWITCH_TO_ARM
1822 "mrc p15, 0, %[val], c9, c12, 3\n"
1823 ARM_SWITCH_BACK
1824 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1825 );
1826
1827 return val;
1828 }
1829
1830
1831 ARM_CP15_TEXT_SECTION static inline void
1832 arm_cp15_set_performance_monitors_overflow_flag_status(uint32_t val)
1833 {
1834 ARM_SWITCH_REGISTERS;
1835
1836 __asm__ volatile (
1837 ARM_SWITCH_TO_ARM
1838 "mcr p15, 0, %[val], c9, c12, 3\n"
1839 ARM_SWITCH_BACK
1840 : ARM_SWITCH_OUTPUT
1841 : [val] "r" (val)
1842 );
1843 }
1844
1845
1846 ARM_CP15_TEXT_SECTION static inline uint32_t
1847 arm_cp15_get_performance_monitors_overflow_flag_status_set(void)
1848 {
1849 ARM_SWITCH_REGISTERS;
1850 uint32_t val;
1851
1852 __asm__ volatile (
1853 ARM_SWITCH_TO_ARM
1854 "mrc p15, 0, %[val], c9, c14, 3\n"
1855 ARM_SWITCH_BACK
1856 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1857 );
1858
1859 return val;
1860 }
1861
1862
1863 ARM_CP15_TEXT_SECTION static inline void
1864 arm_cp15_set_performance_monitors_overflow_flag_status_set(uint32_t val)
1865 {
1866 ARM_SWITCH_REGISTERS;
1867
1868 __asm__ volatile (
1869 ARM_SWITCH_TO_ARM
1870 "mcr p15, 0, %[val], c9, c14, 3\n"
1871 ARM_SWITCH_BACK
1872 : ARM_SWITCH_OUTPUT
1873 : [val] "r" (val)
1874 );
1875 }
1876
1877
1878 ARM_CP15_TEXT_SECTION static inline uint32_t
1879 arm_cp15_get_performance_monitors_event_counter_selection(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, c12, 5\n"
1887 ARM_SWITCH_BACK
1888 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1889 );
1890
1891 return val;
1892 }
1893
1894
1895 ARM_CP15_TEXT_SECTION static inline void
1896 arm_cp15_set_performance_monitors_event_counter_selection(uint32_t val)
1897 {
1898 ARM_SWITCH_REGISTERS;
1899
1900 __asm__ volatile (
1901 ARM_SWITCH_TO_ARM
1902 "mcr p15, 0, %[val], c9, c12, 5\n"
1903 ARM_SWITCH_BACK
1904 : ARM_SWITCH_OUTPUT
1905 : [val] "r" (val)
1906 );
1907 }
1908
1909
1910 ARM_CP15_TEXT_SECTION static inline void
1911 arm_cp15_set_performance_monitors_software_increment(uint32_t val)
1912 {
1913 ARM_SWITCH_REGISTERS;
1914
1915 __asm__ volatile (
1916 ARM_SWITCH_TO_ARM
1917 "mcr p15, 0, %[val], c9, c12, 4\n"
1918 ARM_SWITCH_BACK
1919 : ARM_SWITCH_OUTPUT
1920 : [val] "r" (val)
1921 );
1922 }
1923
1924
1925 ARM_CP15_TEXT_SECTION static inline uint32_t
1926 arm_cp15_get_performance_monitors_user_enable(void)
1927 {
1928 ARM_SWITCH_REGISTERS;
1929 uint32_t val;
1930
1931 __asm__ volatile (
1932 ARM_SWITCH_TO_ARM
1933 "mrc p15, 0, %[val], c9, c14, 0\n"
1934 ARM_SWITCH_BACK
1935 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1936 );
1937
1938 return val;
1939 }
1940
1941
1942 ARM_CP15_TEXT_SECTION static inline void
1943 arm_cp15_set_performance_monitors_user_enable(uint32_t val)
1944 {
1945 ARM_SWITCH_REGISTERS;
1946
1947 __asm__ volatile (
1948 ARM_SWITCH_TO_ARM
1949 "mcr p15, 0, %[val], c9, c14, 0\n"
1950 ARM_SWITCH_BACK
1951 : ARM_SWITCH_OUTPUT
1952 : [val] "r" (val)
1953 );
1954 }
1955
1956
1957 ARM_CP15_TEXT_SECTION static inline uint32_t
1958 arm_cp15_get_performance_monitors_event_count(void)
1959 {
1960 ARM_SWITCH_REGISTERS;
1961 uint32_t val;
1962
1963 __asm__ volatile (
1964 ARM_SWITCH_TO_ARM
1965 "mrc p15, 0, %[val], c9, c13, 2\n"
1966 ARM_SWITCH_BACK
1967 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1968 );
1969
1970 return val;
1971 }
1972
1973
1974 ARM_CP15_TEXT_SECTION static inline void
1975 arm_cp15_set_performance_monitors_event_count(uint32_t val)
1976 {
1977 ARM_SWITCH_REGISTERS;
1978
1979 __asm__ volatile (
1980 ARM_SWITCH_TO_ARM
1981 "mcr p15, 0, %[val], c9, c13, 2\n"
1982 ARM_SWITCH_BACK
1983 : ARM_SWITCH_OUTPUT
1984 : [val] "r" (val)
1985 );
1986 }
1987
1988
1989 ARM_CP15_TEXT_SECTION static inline uint32_t
1990 arm_cp15_get_performance_monitors_event_type_select(void)
1991 {
1992 ARM_SWITCH_REGISTERS;
1993 uint32_t val;
1994
1995 __asm__ volatile (
1996 ARM_SWITCH_TO_ARM
1997 "mrc p15, 0, %[val], c9, c13, 1\n"
1998 ARM_SWITCH_BACK
1999 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2000 );
2001
2002 return val;
2003 }
2004
2005
2006 ARM_CP15_TEXT_SECTION static inline void
2007 arm_cp15_set_performance_monitors_event_type_select(uint32_t val)
2008 {
2009 ARM_SWITCH_REGISTERS;
2010
2011 __asm__ volatile (
2012 ARM_SWITCH_TO_ARM
2013 "mcr p15, 0, %[val], c9, c13, 1\n"
2014 ARM_SWITCH_BACK
2015 : ARM_SWITCH_OUTPUT
2016 : [val] "r" (val)
2017 );
2018 }
2019
2020
2021 ARM_CP15_TEXT_SECTION static inline uint32_t
2022 arm_cp15_get_counter_frequency(void)
2023 {
2024 ARM_SWITCH_REGISTERS;
2025 uint32_t val;
2026
2027 __asm__ volatile (
2028 ARM_SWITCH_TO_ARM
2029 "mrc p15, 0, %[val], c14, c0, 0\n"
2030 ARM_SWITCH_BACK
2031 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2032 );
2033
2034 return val;
2035 }
2036
2037
2038 ARM_CP15_TEXT_SECTION static inline void
2039 arm_cp15_set_counter_frequency(uint32_t val)
2040 {
2041 ARM_SWITCH_REGISTERS;
2042
2043 __asm__ volatile (
2044 ARM_SWITCH_TO_ARM
2045 "mcr p15, 0, %[val], c14, c0, 0\n"
2046 ARM_SWITCH_BACK
2047 : ARM_SWITCH_OUTPUT
2048 : [val] "r" (val)
2049 );
2050 }
2051
2052
2053 ARM_CP15_TEXT_SECTION static inline uint64_t
2054 arm_cp15_get_counter_physical_count(void)
2055 {
2056 ARM_SWITCH_REGISTERS;
2057 uint64_t val;
2058
2059 __asm__ volatile (
2060 ARM_SWITCH_TO_ARM
2061 "mrrc p15, 0, %Q[val], %R[val], c14\n"
2062 ARM_SWITCH_BACK
2063 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2064 );
2065
2066 return val;
2067 }
2068
2069
2070 ARM_CP15_TEXT_SECTION static inline uint32_t
2071 arm_cp15_get_counter_non_secure_pl1_control(void)
2072 {
2073 ARM_SWITCH_REGISTERS;
2074 uint32_t val;
2075
2076 __asm__ volatile (
2077 ARM_SWITCH_TO_ARM
2078 "mrc p15, 0, %[val], c14, c1, 0\n"
2079 ARM_SWITCH_BACK
2080 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2081 );
2082
2083 return val;
2084 }
2085
2086
2087 ARM_CP15_TEXT_SECTION static inline void
2088 arm_cp15_set_counter_non_secure_pl1_control(uint32_t val)
2089 {
2090 ARM_SWITCH_REGISTERS;
2091
2092 __asm__ volatile (
2093 ARM_SWITCH_TO_ARM
2094 "mcr p15, 0, %[val], c14, c1, 0\n"
2095 ARM_SWITCH_BACK
2096 : ARM_SWITCH_OUTPUT
2097 : [val] "r" (val)
2098 );
2099 }
2100
2101
2102 ARM_CP15_TEXT_SECTION static inline uint32_t
2103 arm_cp15_get_counter_pl1_physical_timer_value(void)
2104 {
2105 ARM_SWITCH_REGISTERS;
2106 uint32_t val;
2107
2108 __asm__ volatile (
2109 ARM_SWITCH_TO_ARM
2110 "mrc p15, 0, %[val], c14, c2, 0\n"
2111 ARM_SWITCH_BACK
2112 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2113 );
2114
2115 return val;
2116 }
2117
2118
2119 ARM_CP15_TEXT_SECTION static inline void
2120 arm_cp15_set_counter_pl1_physical_timer_value(uint32_t val)
2121 {
2122 ARM_SWITCH_REGISTERS;
2123
2124 __asm__ volatile (
2125 ARM_SWITCH_TO_ARM
2126 "mcr p15, 0, %[val], c14, c2, 0\n"
2127 ARM_SWITCH_BACK
2128 : ARM_SWITCH_OUTPUT
2129 : [val] "r" (val)
2130 );
2131 }
2132
2133
2134 ARM_CP15_TEXT_SECTION static inline uint32_t
2135 arm_cp15_get_counter_pl1_physical_timer_control(void)
2136 {
2137 ARM_SWITCH_REGISTERS;
2138 uint32_t val;
2139
2140 __asm__ volatile (
2141 ARM_SWITCH_TO_ARM
2142 "mrc p15, 0, %[val], c14, c2, 1\n"
2143 ARM_SWITCH_BACK
2144 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2145 );
2146
2147 return val;
2148 }
2149
2150
2151 ARM_CP15_TEXT_SECTION static inline void
2152 arm_cp15_set_counter_pl1_physical_timer_control(uint32_t val)
2153 {
2154 ARM_SWITCH_REGISTERS;
2155
2156 __asm__ volatile (
2157 ARM_SWITCH_TO_ARM
2158 "mcr p15, 0, %[val], c14, c2, 1\n"
2159 ARM_SWITCH_BACK
2160 : ARM_SWITCH_OUTPUT
2161 : [val] "r" (val)
2162 );
2163 }
2164
2165
2166 ARM_CP15_TEXT_SECTION static inline uint32_t
2167 arm_cp15_get_counter_pl1_virtual_timer_value(void)
2168 {
2169 ARM_SWITCH_REGISTERS;
2170 uint32_t val;
2171
2172 __asm__ volatile (
2173 ARM_SWITCH_TO_ARM
2174 "mrc p15, 0, %[val], c14, c3, 0\n"
2175 ARM_SWITCH_BACK
2176 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2177 );
2178
2179 return val;
2180 }
2181
2182
2183 ARM_CP15_TEXT_SECTION static inline void
2184 arm_cp15_set_counter_pl1_virtual_timer_value(uint32_t val)
2185 {
2186 ARM_SWITCH_REGISTERS;
2187
2188 __asm__ volatile (
2189 ARM_SWITCH_TO_ARM
2190 "mcr p15, 0, %[val], c14, c3, 0\n"
2191 ARM_SWITCH_BACK
2192 : ARM_SWITCH_OUTPUT
2193 : [val] "r" (val)
2194 );
2195 }
2196
2197
2198 ARM_CP15_TEXT_SECTION static inline uint32_t
2199 arm_cp15_get_counter_pl1_virtual_timer_control(void)
2200 {
2201 ARM_SWITCH_REGISTERS;
2202 uint32_t val;
2203
2204 __asm__ volatile (
2205 ARM_SWITCH_TO_ARM
2206 "mrc p15, 0, %[val], c14, c3, 1\n"
2207 ARM_SWITCH_BACK
2208 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2209 );
2210
2211 return val;
2212 }
2213
2214
2215 ARM_CP15_TEXT_SECTION static inline void
2216 arm_cp15_set_counter_pl1_virtual_timer_control(uint32_t val)
2217 {
2218 ARM_SWITCH_REGISTERS;
2219
2220 __asm__ volatile (
2221 ARM_SWITCH_TO_ARM
2222 "mcr p15, 0, %[val], c14, c3, 1\n"
2223 ARM_SWITCH_BACK
2224 : ARM_SWITCH_OUTPUT
2225 : [val] "r" (val)
2226 );
2227 }
2228
2229
2230 ARM_CP15_TEXT_SECTION static inline uint64_t
2231 arm_cp15_get_counter_virtual_count(void)
2232 {
2233 ARM_SWITCH_REGISTERS;
2234 uint64_t val;
2235
2236 __asm__ volatile (
2237 ARM_SWITCH_TO_ARM
2238 "mrrc p15, 1, %Q[val], %R[val], c14\n"
2239 ARM_SWITCH_BACK
2240 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2241 );
2242
2243 return val;
2244 }
2245
2246
2247 ARM_CP15_TEXT_SECTION static inline uint64_t
2248 arm_cp15_get_counter_pl1_physical_compare_value(void)
2249 {
2250 ARM_SWITCH_REGISTERS;
2251 uint64_t val;
2252
2253 __asm__ volatile (
2254 ARM_SWITCH_TO_ARM
2255 "mrrc p15, 2, %Q[val], %R[val], c14\n"
2256 ARM_SWITCH_BACK
2257 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2258 );
2259
2260 return val;
2261 }
2262
2263
2264 ARM_CP15_TEXT_SECTION static inline void
2265 arm_cp15_set_counter_pl1_physical_compare_value(uint64_t val)
2266 {
2267 ARM_SWITCH_REGISTERS;
2268
2269 __asm__ volatile (
2270 ARM_SWITCH_TO_ARM
2271 "mcrr p15, 2, %Q[val], %R[val], c14\n"
2272 ARM_SWITCH_BACK
2273 : ARM_SWITCH_OUTPUT
2274 : [val] "r" (val)
2275 );
2276 }
2277
2278
2279 ARM_CP15_TEXT_SECTION static inline uint64_t
2280 arm_cp15_get_counter_pl1_virtual_compare_value(void)
2281 {
2282 ARM_SWITCH_REGISTERS;
2283 uint64_t val;
2284
2285 __asm__ volatile (
2286 ARM_SWITCH_TO_ARM
2287 "mrrc p15, 3, %Q[val], %R[val], c14\n"
2288 ARM_SWITCH_BACK
2289 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2290 );
2291
2292 return val;
2293 }
2294
2295
2296 ARM_CP15_TEXT_SECTION static inline void
2297 arm_cp15_set_counter_pl1_virtual_compare_value(uint64_t val)
2298 {
2299 ARM_SWITCH_REGISTERS;
2300
2301 __asm__ volatile (
2302 ARM_SWITCH_TO_ARM
2303 "mcrr p15, 3, %Q[val], %R[val], c14\n"
2304 ARM_SWITCH_BACK
2305 : ARM_SWITCH_OUTPUT
2306 : [val] "r" (val)
2307 );
2308 }
2309
2310
2311 ARM_CP15_TEXT_SECTION static inline uint64_t
2312 arm_cp15_get_counter_virtual_offset(void)
2313 {
2314 ARM_SWITCH_REGISTERS;
2315 uint64_t val;
2316
2317 __asm__ volatile (
2318 ARM_SWITCH_TO_ARM
2319 "mrrc p15, 4, %Q[val], %R[val], c14\n"
2320 ARM_SWITCH_BACK
2321 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2322 );
2323
2324 return val;
2325 }
2326
2327
2328 ARM_CP15_TEXT_SECTION static inline void
2329 arm_cp15_set_counter_virtual_offset(uint64_t val)
2330 {
2331 ARM_SWITCH_REGISTERS;
2332
2333 __asm__ volatile (
2334 ARM_SWITCH_TO_ARM
2335 "mcrr p15, 4, %Q[val], %R[val], c14\n"
2336 ARM_SWITCH_BACK
2337 : ARM_SWITCH_OUTPUT
2338 : [val] "r" (val)
2339 );
2340 }
2341
2342
2343 ARM_CP15_TEXT_SECTION static inline uint32_t
2344 arm_cp15_get_diagnostic_control(void)
2345 {
2346 ARM_SWITCH_REGISTERS;
2347 uint32_t val;
2348
2349 __asm__ volatile (
2350 ARM_SWITCH_TO_ARM
2351 "mrc p15, 0, %[val], c15, c0, 1\n"
2352 ARM_SWITCH_BACK
2353 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2354 );
2355
2356 return val;
2357 }
2358
2359
2360 ARM_CP15_TEXT_SECTION static inline void
2361 arm_cp15_set_diagnostic_control(uint32_t val)
2362 {
2363 ARM_SWITCH_REGISTERS;
2364
2365 __asm__ volatile (
2366 ARM_SWITCH_TO_ARM
2367 "mcr p15, 0, %[val], c15, c0, 1\n"
2368 ARM_SWITCH_BACK
2369 : ARM_SWITCH_OUTPUT
2370 : [val] "r" (val)
2371 );
2372 }
2373
2374
2375 ARM_CP15_TEXT_SECTION static inline void
2376 arm_cp15_data_cache_all_invalidate(void)
2377 {
2378 ARM_SWITCH_REGISTERS;
2379 uint32_t sbz = 0;
2380
2381 __asm__ volatile (
2382 ARM_SWITCH_TO_ARM
2383 "mcr p15, 0, %[sbz], c15, c5, 0\n"
2384 ARM_SWITCH_BACK
2385 : ARM_SWITCH_OUTPUT
2386 : [sbz] "r" (sbz)
2387 : "memory"
2388 );
2389 }
2390
2391
2392
2393
2394
2395
2396 uint32_t arm_cp15_set_translation_table_entries(
2397 const void *begin,
2398 const void *end,
2399 uint32_t section_flags
2400 );
2401
2402
2403
2404
2405
2406
2407 void* arm_cp15_set_exception_handler(
2408 Arm_symbolic_exception_name exception,
2409 void (*handler)(void)
2410 );
2411
2412
2413
2414 #ifdef __cplusplus
2415 }
2416 #endif
2417
2418 #endif