RTEMS 5.2
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
30extern "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
296ARM_CP15_TEXT_SECTION static inline uint32_t
297arm_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
312ARM_CP15_TEXT_SECTION static inline uint32_t
313arm_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
328ARM_CP15_TEXT_SECTION static inline uint32_t
329arm_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
344ARM_CP15_TEXT_SECTION static inline void
345arm_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
377ARM_CP15_TEXT_SECTION static inline uint32_t
378arm_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
414ARM_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
430ARM_CP15_TEXT_SECTION static inline void
431arm_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 */
445ARM_CP15_TEXT_SECTION static inline uint32_t
446arm_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
461ARM_CP15_TEXT_SECTION static inline void
462arm_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
475ARM_CP15_TEXT_SECTION static inline uint32_t
476arm_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
491ARM_CP15_TEXT_SECTION static inline void
492arm_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
505ARM_CP15_TEXT_SECTION static inline uint32_t
506arm_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
521ARM_CP15_TEXT_SECTION static inline void
522arm_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
535ARM_CP15_TEXT_SECTION static inline uint32_t
536arm_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
551ARM_CP15_TEXT_SECTION static inline void
552arm_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
565ARM_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
581ARM_CP15_TEXT_SECTION static inline void
582arm_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
595ARM_CP15_TEXT_SECTION static inline void
596arm_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
617ARM_CP15_TEXT_SECTION static inline void
618arm_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
633ARM_CP15_TEXT_SECTION static inline void
634arm_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
649ARM_CP15_TEXT_SECTION static inline void
650arm_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
664ARM_CP15_TEXT_SECTION static inline void
665arm_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
680ARM_CP15_TEXT_SECTION static inline void
681arm_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
695ARM_CP15_TEXT_SECTION static inline void
696arm_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
711ARM_CP15_TEXT_SECTION static inline void
712arm_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 */
743ARM_CP15_TEXT_SECTION static inline uint32_t
744arm_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 */
760ARM_CP15_TEXT_SECTION static inline int
761arm_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 */
767ARM_CP15_TEXT_SECTION static inline uint32_t
768arm_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 */
790ARM_CP15_TEXT_SECTION static inline uint32_t
791arm_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 */
810ARM_CP15_TEXT_SECTION static inline uint32_t
811arm_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
831ARM_CP15_TEXT_SECTION static inline uint32_t
832arm_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
847ARM_CP15_TEXT_SECTION static inline uint32_t
848arm_ccsidr_get_line_power(uint32_t ccsidr)
849{
850 return (ccsidr & 0x7) + 4;
851}
852
853ARM_CP15_TEXT_SECTION static inline uint32_t
854arm_ccsidr_get_associativity(uint32_t ccsidr)
855{
856 return ((ccsidr >> 3) & 0x3ff) + 1;
857}
858
859ARM_CP15_TEXT_SECTION static inline uint32_t
860arm_ccsidr_get_num_sets(uint32_t ccsidr)
861{
862 return ((ccsidr >> 13) & 0x7fff) + 1;
863}
864
865/* CLIDR, Cache Level ID Register */
866
867ARM_CP15_TEXT_SECTION static inline uint32_t
868arm_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
883ARM_CP15_TEXT_SECTION static inline uint32_t
884arm_clidr_get_level_of_coherency(uint32_t clidr)
885{
886 return (clidr >> 24) & 0x7;
887}
888
889ARM_CP15_TEXT_SECTION static inline uint32_t
890arm_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
897ARM_CP15_TEXT_SECTION static inline uint32_t
898arm_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
913ARM_CP15_TEXT_SECTION static inline void
914arm_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
928ARM_CP15_TEXT_SECTION static inline uint32_t
929arm_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();
939
940 return ccsidr;
941}
942
943ARM_CP15_TEXT_SECTION static inline void
944arm_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
961ARM_CP15_TEXT_SECTION static inline void
962arm_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
979ARM_CP15_TEXT_SECTION static inline void
980arm_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
997ARM_CP15_TEXT_SECTION static inline void
998arm_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 */
1014ARM_CP15_TEXT_SECTION static inline void
1015arm_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
1030ARM_CP15_TEXT_SECTION static inline void
1031arm_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
1046ARM_CP15_TEXT_SECTION static inline void
1047arm_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
1063ARM_CP15_TEXT_SECTION static inline void
1064arm_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
1078ARM_CP15_TEXT_SECTION static inline void
1079arm_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
1094ARM_CP15_TEXT_SECTION static inline void
1095arm_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
1110ARM_CP15_TEXT_SECTION static inline void
1111arm_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
1127ARM_CP15_TEXT_SECTION static inline void
1128arm_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
1142ARM_CP15_TEXT_SECTION static inline void
1143arm_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
1171ARM_CP15_TEXT_SECTION static inline void
1172arm_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
1188ARM_CP15_TEXT_SECTION static inline void
1189arm_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
1205ARM_CP15_TEXT_SECTION static inline void
1206arm_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
1220ARM_CP15_TEXT_SECTION static inline void
1221arm_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
1249ARM_CP15_TEXT_SECTION static inline void
1250arm_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
1266ARM_CP15_TEXT_SECTION static inline void
1267arm_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 */
1287ARM_CP15_TEXT_SECTION static inline void
1288arm_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
1304ARM_CP15_TEXT_SECTION static inline void
1305arm_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
1321ARM_CP15_TEXT_SECTION static inline void
1322arm_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
1336ARM_CP15_TEXT_SECTION static inline void
1337arm_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
1355ARM_CP15_TEXT_SECTION static inline void
1356arm_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
1371ARM_CP15_TEXT_SECTION static inline void
1372arm_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
1387ARM_CP15_TEXT_SECTION static inline uint32_t
1388arm_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
1403ARM_CP15_TEXT_SECTION static inline uint32_t
1404arm_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
1418ARM_CP15_TEXT_SECTION static inline uint32_t
1419arm_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
1434ARM_CP15_TEXT_SECTION static inline void
1435arm_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
1450ARM_CP15_TEXT_SECTION static inline uint32_t
1451arm_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
1468ARM_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
1484ARM_CP15_TEXT_SECTION static inline void
1485arm_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
1498ARM_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
1514ARM_CP15_TEXT_SECTION static inline void
1515arm_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 */
1529ARM_CP15_TEXT_SECTION static inline uint32_t
1530arm_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 */
1546ARM_CP15_TEXT_SECTION static inline void
1547arm_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 */
1561ARM_CP15_TEXT_SECTION static inline uint32_t
1562arm_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 */
1578ARM_CP15_TEXT_SECTION static inline uint32_t
1579arm_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 */
1597ARM_CP15_TEXT_SECTION static inline uint32_t
1598arm_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 */
1614ARM_CP15_TEXT_SECTION static inline void
1615arm_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 */
1629ARM_CP15_TEXT_SECTION static inline uint32_t
1630arm_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 */
1646ARM_CP15_TEXT_SECTION static inline void
1647arm_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 */
1671ARM_CP15_TEXT_SECTION static inline uint32_t
1672arm_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 */
1688ARM_CP15_TEXT_SECTION static inline void
1689arm_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 */
1703ARM_CP15_TEXT_SECTION static inline uint32_t
1704arm_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 */
1720ARM_CP15_TEXT_SECTION static inline void
1721arm_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 */
1735ARM_CP15_TEXT_SECTION static inline uint32_t
1736arm_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 */
1752ARM_CP15_TEXT_SECTION static inline void
1753arm_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 */
1767ARM_CP15_TEXT_SECTION static inline uint32_t
1768arm_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 */
1784ARM_CP15_TEXT_SECTION static inline void
1785arm_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 */
1799ARM_CP15_TEXT_SECTION static inline uint32_t
1800arm_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 */
1816ARM_CP15_TEXT_SECTION static inline void
1817arm_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 */
1831ARM_CP15_TEXT_SECTION static inline uint32_t
1832arm_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 */
1848ARM_CP15_TEXT_SECTION static inline void
1849arm_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 */
1863ARM_CP15_TEXT_SECTION static inline void
1864arm_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 */
1878ARM_CP15_TEXT_SECTION static inline uint32_t
1879arm_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 */
1895ARM_CP15_TEXT_SECTION static inline void
1896arm_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 */
1910ARM_CP15_TEXT_SECTION static inline uint32_t
1911arm_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 */
1927ARM_CP15_TEXT_SECTION static inline void
1928arm_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 */
1942ARM_CP15_TEXT_SECTION static inline uint32_t
1943arm_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 */
1959ARM_CP15_TEXT_SECTION static inline void
1960arm_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 */
1974ARM_CP15_TEXT_SECTION static inline uint32_t
1975arm_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 */
1991ARM_CP15_TEXT_SECTION static inline void
1992arm_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 */
2006ARM_CP15_TEXT_SECTION static inline uint64_t
2007arm_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 */
2023ARM_CP15_TEXT_SECTION static inline uint32_t
2024arm_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 */
2040ARM_CP15_TEXT_SECTION static inline void
2041arm_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 */
2055ARM_CP15_TEXT_SECTION static inline uint32_t
2056arm_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 */
2072ARM_CP15_TEXT_SECTION static inline void
2073arm_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 */
2087ARM_CP15_TEXT_SECTION static inline uint32_t
2088arm_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 */
2104ARM_CP15_TEXT_SECTION static inline void
2105arm_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 */
2119ARM_CP15_TEXT_SECTION static inline uint32_t
2120arm_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 */
2136ARM_CP15_TEXT_SECTION static inline void
2137arm_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 */
2151ARM_CP15_TEXT_SECTION static inline uint32_t
2152arm_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 */
2168ARM_CP15_TEXT_SECTION static inline void
2169arm_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 */
2183ARM_CP15_TEXT_SECTION static inline uint64_t
2184arm_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 */
2200ARM_CP15_TEXT_SECTION static inline uint64_t
2201arm_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 */
2217ARM_CP15_TEXT_SECTION static inline void
2218arm_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 */
2232ARM_CP15_TEXT_SECTION static inline uint64_t
2233arm_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 */
2249ARM_CP15_TEXT_SECTION static inline void
2250arm_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 */
2264ARM_CP15_TEXT_SECTION static inline uint64_t
2265arm_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 */
2281ARM_CP15_TEXT_SECTION static inline void
2282arm_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
2295/* Diagnostic Control Register */
2296ARM_CP15_TEXT_SECTION static inline uint32_t
2297arm_cp15_get_diagnostic_control(void)
2298{
2299 ARM_SWITCH_REGISTERS;
2300 uint32_t val;
2301
2302 __asm__ volatile (
2303 ARM_SWITCH_TO_ARM
2304 "mrc p15, 0, %[val], c15, c0, 1\n"
2305 ARM_SWITCH_BACK
2306 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
2307 );
2308
2309 return val;
2310}
2311
2312/* Diagnostic Control Register */
2313ARM_CP15_TEXT_SECTION static inline void
2314arm_cp15_set_diagnostic_control(uint32_t val)
2315{
2316 ARM_SWITCH_REGISTERS;
2317
2318 __asm__ volatile (
2319 ARM_SWITCH_TO_ARM
2320 "mcr p15, 0, %[val], c15, c0, 1\n"
2321 ARM_SWITCH_BACK
2322 : ARM_SWITCH_OUTPUT
2323 : [val] "r" (val)
2324 );
2325}
2326
2333 const void *begin,
2334 const void *end,
2335 uint32_t section_flags
2336);
2337
2344 Arm_symbolic_exception_name exception,
2345 void (*handler)(void)
2346);
2347
2350#ifdef __cplusplus
2351}
2352#endif /* __cplusplus */
2353
2354#endif /* LIBCPU_SHARED_ARM_CP15_H */
#define rtems_interrupt_local_disable(_isr_cookie)
This macro disables the interrupts on the current processor.
Definition: intr.h:138
ISR_Level rtems_interrupt_level
Interrupt level type.
Definition: intr.h:42
#define rtems_interrupt_local_enable(_isr_cookie)
This macro restores the previous interrupt level on the current processor.
Definition: intr.h:148
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
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.
Definition: mknod-pack_dev.c:254
unsigned ct
Definition: tlb.h:14