RTEMS 6.1-rc5
Loading...
Searching...
No Matches
arm-cp15.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
11/*
12 * Copyright (c) 2013 Hesham AL-Matary
13 * Copyright (C) 2009, 2017 embedded brains GmbH & Co. KG
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef LIBCPU_SHARED_ARM_CP15_H
38#define LIBCPU_SHARED_ARM_CP15_H
39
40#include <rtems.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif /* __cplusplus */
45
46/*
47 * Allow users of this header file to optionally place the inline functions
48 * into a non-standard section.
49 */
50#ifndef ARM_CP15_TEXT_SECTION
51 #define ARM_CP15_TEXT_SECTION
52#endif
53
54#define ARM_CP15_CACHE_PREPARE_MVA(mva) \
55 ((const void *) (((uint32_t) (mva)) & ~0x1fU))
56
57#define ARM_CP15_TLB_PREPARE_MVA(mva) \
58 ((const void *) (((uint32_t) (mva)) & ~0x3fU))
59
80#define ARM_MMU_SECT_BASE_SHIFT 20
81#define ARM_MMU_SECT_BASE_MASK (0xfffU << ARM_MMU_SECT_BASE_SHIFT)
82#define ARM_MMU_SECT_NS (1U << 19)
83#define ARM_MMU_SECT_NG (1U << 17)
84#define ARM_MMU_SECT_S (1U << 16)
85#define ARM_MMU_SECT_AP_2 (1U << 15)
86#define ARM_MMU_SECT_TEX_2 (1U << 14)
87#define ARM_MMU_SECT_TEX_1 (1U << 13)
88#define ARM_MMU_SECT_TEX_0 (1U << 12)
89#define ARM_MMU_SECT_TEX_SHIFT 12
90#define ARM_MMU_SECT_TEX_MASK (0x3U << ARM_MMU_SECT_TEX_SHIFT)
91#define ARM_MMU_SECT_AP_1 (1U << 11)
92#define ARM_MMU_SECT_AP_0 (1U << 10)
93#define ARM_MMU_SECT_AP_SHIFT 10
94#define ARM_MMU_SECT_AP_MASK (0x23U << ARM_MMU_SECT_AP_SHIFT)
95#define ARM_MMU_SECT_DOMAIN_SHIFT 5
96#define ARM_MMU_SECT_DOMAIN_MASK (0xfU << ARM_MMU_SECT_DOMAIN_SHIFT)
97#define ARM_MMU_SECT_XN (1U << 4)
98#define ARM_MMU_SECT_C (1U << 3)
99#define ARM_MMU_SECT_B (1U << 2)
100#define ARM_MMU_SECT_PXN (1U << 0)
101#define ARM_MMU_SECT_DEFAULT 0x2U
102#define ARM_MMU_SECT_GET_INDEX(mva) \
103 (((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT)
104#define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \
105 ((1U << ARM_MMU_SECT_BASE_SHIFT) \
106 + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U)))
107
108#define ARM_MMU_PAGE_TABLE_BASE_SHIFT 10
109#define ARM_MMU_PAGE_TABLE_BASE_MASK (0x3fffffU << ARM_MMU_PAGE_TABLE_BASE_SHIFT)
110#define ARM_MMU_PAGE_TABLE_DOMAIN_SHIFT 5
111#define ARM_MMU_PAGE_TABLE_DOMAIN_MASK (0xfU << ARM_MMU_PAGE_TABLE_DOMAIN_SHIFT)
112#define ARM_MMU_PAGE_TABLE_NS (1U << 3)
113#define ARM_MMU_PAGE_TABLE_PXN (1U << 2)
114#define ARM_MMU_PAGE_TABLE_DEFAULT 0x1U
115
116#define ARM_MMU_SMALL_PAGE_BASE_SHIFT 12
117#define ARM_MMU_SMALL_PAGE_BASE_MASK (0xfffffU << ARM_MMU_SMALL_PAGE_BASE_SHIFT)
118#define ARM_MMU_SMALL_PAGE_NG (1U << 11)
119#define ARM_MMU_SMALL_PAGE_S (1U << 10)
120#define ARM_MMU_SMALL_PAGE_AP_2 (1U << 9)
121#define ARM_MMU_SMALL_PAGE_TEX_2 (1U << 8)
122#define ARM_MMU_SMALL_PAGE_TEX_1 (1U << 7)
123#define ARM_MMU_SMALL_PAGE_TEX_0 (1U << 6)
124#define ARM_MMU_SMALL_PAGE_TEX_SHIFT 6
125#define ARM_MMU_SMALL_PAGE_TEX_MASK (0x3U << ARM_MMU_SMALL_PAGE_TEX_SHIFT)
126#define ARM_MMU_SMALL_PAGE_AP_1 (1U << 5)
127#define ARM_MMU_SMALL_PAGE_AP_0 (1U << 4)
128#define ARM_MMU_SMALL_PAGE_AP_SHIFT 4
129#define ARM_MMU_SMALL_PAGE_AP_MASK (0x23U << ARM_MMU_SMALL_PAGE_AP_SHIFT)
130#define ARM_MMU_SMALL_PAGE_C (1U << 3)
131#define ARM_MMU_SMALL_PAGE_B (1U << 2)
132#define ARM_MMU_SMALL_PAGE_XN (1U << 0)
133#define ARM_MMU_SMALL_PAGE_DEFAULT 0x2U
134#define ARM_MMU_SMALL_PAGE_GET_INDEX(mva) \
135 (((uint32_t) (mva)) >> ARM_MMU_SMALL_PAGE_BASE_SHIFT)
136#define ARM_MMU_SMALL_PAGE_MVA_ALIGN_UP(mva) \
137 ((1U << ARM_MMU_SMALL_PAGE_BASE_SHIFT) \
138 + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SMALL_PAGE_BASE_SHIFT) - 1U)))
139
140#define ARM_MMU_SECT_FLAGS_TO_PAGE_TABLE(flags) \
141 (ARM_MMU_PAGE_TABLE_DEFAULT \
142 | ((flags) & ARM_MMU_SECT_DOMAIN_MASK) \
143 | (((flags) & ARM_MMU_SECT_NS) >> 16) \
144 | (((flags) & ARM_MMU_SECT_PXN) << 2))
145
146#define ARM_MMU_PAGE_TABLE_FLAGS_TO_SECT(flags) \
147 (ARM_MMU_SECT_DEFAULT \
148 | ((flags) & ARM_MMU_PAGE_TABLE_DOMAIN_MASK) \
149 | (((flags) & ARM_MMU_PAGE_TABLE_NS) << 16) \
150 | (((flags) & ARM_MMU_PAGE_TABLE_PXN) >> 2))
151
152#define ARM_MMU_SECT_FLAGS_TO_SMALL_PAGE(flags) \
153 ((((flags) & 0x3fc00) >> 6) \
154 | ((flags) & (ARM_MMU_SECT_C | ARM_MMU_SECT_B | 0x2)) \
155 | (((flags) & ARM_MMU_SECT_XN) >> 4))
156
157#define ARM_MMU_SMALL_PAGE_FLAGS_TO_SECT(flags) \
158 ((((flags) & 0xff0) << 6) \
159 | ((flags) & (ARM_MMU_SMALL_PAGE_C | ARM_MMU_SMALL_PAGE_B | 0x2)) \
160 | (((flags) & ARM_MMU_SMALL_PAGE_XN) << 4))
161
162#define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U
163#define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U
164
165#define ARM_MMU_SMALL_PAGE_TABLE_ENTRY_SIZE 4U
166#define ARM_MMU_SMALL_PAGE_TABLE_ENTRY_COUNT 256U
167
168#define ARM_MMU_DEFAULT_CLIENT_DOMAIN 15U
169
170#define ARMV7_MMU_READ_ONLY \
171 ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
172 | ARM_MMU_SECT_AP_0 \
173 | ARM_MMU_SECT_AP_2 \
174 | ARM_MMU_SECT_DEFAULT)
175
176#define ARMV7_MMU_READ_ONLY_CACHED \
177 (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
178
179#define ARMV7_MMU_READ_WRITE \
180 ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
181 | ARM_MMU_SECT_AP_0 \
182 | ARM_MMU_SECT_DEFAULT)
183
184#ifdef RTEMS_SMP
185 #define ARMV7_MMU_READ_WRITE_CACHED \
186 (ARMV7_MMU_READ_WRITE \
187 | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B | ARM_MMU_SECT_S)
188#else
189 #define ARMV7_MMU_READ_WRITE_CACHED \
190 (ARMV7_MMU_READ_WRITE \
191 | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
192#endif
193
194#define ARMV7_MMU_DATA_READ_ONLY \
195 (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
196
197#define ARMV7_MMU_DATA_READ_ONLY_CACHED \
198 ARMV7_MMU_READ_ONLY_CACHED
199
200#define ARMV7_MMU_DATA_READ_WRITE \
201 (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_TEX_0)
202
203#define ARMV7_MMU_DATA_READ_WRITE_CACHED \
204 ARMV7_MMU_READ_WRITE_CACHED
205
206#define ARMV7_MMU_CODE \
207 (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
208
209#define ARMV7_MMU_CODE_CACHED \
210 ARMV7_MMU_READ_ONLY_CACHED
211
212#define ARMV7_MMU_DEVICE \
213 (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_B)
214
223#define ARM_CP15_CTRL_TE (1U << 30)
224#define ARM_CP15_CTRL_AFE (1U << 29)
225#define ARM_CP15_CTRL_TRE (1U << 28)
226#define ARM_CP15_CTRL_NMFI (1U << 27)
227#define ARM_CP15_CTRL_EE (1U << 25)
228#define ARM_CP15_CTRL_VE (1U << 24)
229#define ARM_CP15_CTRL_XP (1U << 23)
230#define ARM_CP15_CTRL_U (1U << 22)
231#define ARM_CP15_CTRL_FI (1U << 21)
232#define ARM_CP15_CTRL_UWXN (1U << 20)
233#define ARM_CP15_CTRL_WXN (1U << 19)
234#define ARM_CP15_CTRL_HA (1U << 17)
235#define ARM_CP15_CTRL_L4 (1U << 15)
236#define ARM_CP15_CTRL_RR (1U << 14)
237#define ARM_CP15_CTRL_V (1U << 13)
238#define ARM_CP15_CTRL_I (1U << 12)
239#define ARM_CP15_CTRL_Z (1U << 11)
240#define ARM_CP15_CTRL_SW (1U << 10)
241#define ARM_CP15_CTRL_R (1U << 9)
242#define ARM_CP15_CTRL_S (1U << 8)
243#define ARM_CP15_CTRL_B (1U << 7)
244#define ARM_CP15_CTRL_CP15BEN (1U << 5)
245#define ARM_CP15_CTRL_C (1U << 2)
246#define ARM_CP15_CTRL_A (1U << 1)
247#define ARM_CP15_CTRL_M (1U << 0)
248
257#define ARM_CP15_DAC_NO_ACCESS 0x0U
258#define ARM_CP15_DAC_CLIENT 0x1U
259#define ARM_CP15_DAC_MANAGER 0x3U
260#define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index))
261
270#define ARM_CP15_FAULT_STATUS_MASK 0x040F
271
272#define ARM_CP15_FSR_ALIGNMENT_FAULT 0x00000001
273#define ARM_CP15_FSR_BACKGROUND_FAULT 0x0000
274#define ARM_CP15_FSR_ACCESS_PERMISSION_FAULT 0x000D
275#define ARM_CP15_FSR_PRECISE_EXTERNAL_ABORT_FAULT 0x0008
276#define ARM_CP15_FSR_IMPRECISE_EXTERNAL_ABORT_FAULT 0x0406
277#define ARM_CP15_FSR_PRECISE_PARITY_ERROR_EXCEPTION 0x0006
278#define ARM_CP15_FSR_IMPRECISE_PARITY_ERROR_EXCEPTION 0x0408
279#define ARM_CP15_FSR_DEBUG_EVENT 0x0002
280
292#define ARM_CP15_CACHE_TYPE_FORMAT_ARMV6 0
293#define ARM_CP15_CACHE_TYPE_FORMAT_ARMV7 4
294
303#define ARM_CP15_CACHE_CSS_ID_DATA 0
304#define ARM_CP15_CACHE_CSS_ID_INSTRUCTION 1
305#define ARM_CP15_CACHE_CSS_LEVEL(level) ((level) << 1)
306
309ARM_CP15_TEXT_SECTION static inline uint32_t
310arm_cp15_get_id_code(void)
311{
312 ARM_SWITCH_REGISTERS;
313 uint32_t val;
314
315 __asm__ volatile (
316 ARM_SWITCH_TO_ARM
317 "mrc p15, 0, %[val], c0, c0, 0\n"
318 ARM_SWITCH_BACK
319 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
320 );
321
322 return val;
323}
324
325ARM_CP15_TEXT_SECTION static inline uint32_t
326arm_cp15_get_tcm_status(void)
327{
328 ARM_SWITCH_REGISTERS;
329 uint32_t val;
330
331 __asm__ volatile (
332 ARM_SWITCH_TO_ARM
333 "mrc p15, 0, %[val], c0, c0, 2\n"
334 ARM_SWITCH_BACK
335 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
336 );
337
338 return val;
339}
340
341ARM_CP15_TEXT_SECTION static inline uint32_t
342arm_cp15_get_control(void)
343{
344 ARM_SWITCH_REGISTERS;
345 uint32_t val;
346
347 __asm__ volatile (
348 ARM_SWITCH_TO_ARM
349 "mrc p15, 0, %[val], c1, c0, 0\n"
350 ARM_SWITCH_BACK
351 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
352 );
353
354 return val;
355}
356
357ARM_CP15_TEXT_SECTION static inline void
358arm_cp15_set_control(uint32_t val)
359{
360 ARM_SWITCH_REGISTERS;
361
362 __asm__ volatile (
363 ARM_SWITCH_TO_ARM
364 "mcr p15, 0, %[val], c1, c0, 0\n"
365 "nop\n"
366 "nop\n"
367 ARM_SWITCH_BACK
368 : ARM_SWITCH_OUTPUT
369 : [val] "r" (val)
370 : "memory"
371 );
372}
373
390ARM_CP15_TEXT_SECTION static inline uint32_t
391arm_cp15_mmu_disable(uint32_t cls)
392{
393 ARM_SWITCH_REGISTERS;
394 uint32_t ctrl;
395 uint32_t tmp_0;
396 uint32_t tmp_1;
397
398 __asm__ volatile (
399 ARM_SWITCH_TO_ARM
400 "mrc p15, 0, %[ctrl], c1, c0, 0\n"
401 "bic %[tmp_0], %[ctrl], #1\n"
402 "mcr p15, 0, %[tmp_0], c1, c0, 0\n"
403 "nop\n"
404 "nop\n"
405 "mov %[tmp_1], sp\n"
406 "rsb %[tmp_0], %[cls], #0\n"
407 "and %[tmp_0], %[tmp_0], %[tmp_1]\n"
408 "sub %[tmp_0], %[tmp_0], %[cls], asl #3\n"
409 "add %[tmp_1], %[tmp_0], %[cls], asl #4\n"
410 "1:\n"
411 "mcr p15, 0, %[tmp_0], c7, c14, 1\n"
412 "add %[tmp_0], %[tmp_0], %[cls]\n"
413 "cmp %[tmp_1], %[tmp_0]\n"
414 "bne 1b\n"
415 ARM_SWITCH_BACK
416 : [ctrl] "=&r" (ctrl),
417 [tmp_0] "=&r" (tmp_0),
418 [tmp_1] "=&r" (tmp_1)
419 ARM_SWITCH_ADDITIONAL_OUTPUT
420 : [cls] "r" (cls)
421 : "memory", "cc"
422 );
423
424 return ctrl;
425}
426
427ARM_CP15_TEXT_SECTION static inline uint32_t
428*arm_cp15_get_translation_table_base(void)
429{
430 ARM_SWITCH_REGISTERS;
431 uint32_t *base;
432
433 __asm__ volatile (
434 ARM_SWITCH_TO_ARM
435 "mrc p15, 0, %[base], c2, c0, 0\n"
436 ARM_SWITCH_BACK
437 : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
438 );
439
440 return base;
441}
442
443ARM_CP15_TEXT_SECTION static inline void
444arm_cp15_set_translation_table_base(uint32_t *base)
445{
446 ARM_SWITCH_REGISTERS;
447
448 __asm__ volatile (
449 ARM_SWITCH_TO_ARM
450 "mcr p15, 0, %[base], c2, c0, 0\n"
451 ARM_SWITCH_BACK
452 : ARM_SWITCH_OUTPUT
453 : [base] "r" (base)
454 );
455}
456
457/* Translation Table Base Control Register - DDI0301H arm1176jzfs TRM 3.2.15 */
458ARM_CP15_TEXT_SECTION static inline uint32_t
459arm_cp15_get_translation_table_base_control_register(void)
460{
461 ARM_SWITCH_REGISTERS;
462 uint32_t ttb_cr;
463
464 __asm__ volatile (
465 ARM_SWITCH_TO_ARM
466 "mrc p15, 0, %[ttb_cr], c2, c0, 2\n"
467 ARM_SWITCH_BACK
468 : [ttb_cr] "=&r" (ttb_cr) ARM_SWITCH_ADDITIONAL_OUTPUT
469 );
470
471 return ttb_cr;
472}
473
474ARM_CP15_TEXT_SECTION static inline void
475arm_cp15_set_translation_table_base_control_register(uint32_t ttb_cr)
476{
477 ARM_SWITCH_REGISTERS;
478
479 __asm__ volatile (
480 ARM_SWITCH_TO_ARM
481 "mcr p15, 0, %[ttb_cr], c2, c0, 2\n"
482 ARM_SWITCH_BACK
483 : ARM_SWITCH_OUTPUT
484 : [ttb_cr] "r" (ttb_cr)
485 );
486}
487
488ARM_CP15_TEXT_SECTION static inline uint32_t
489arm_cp15_get_domain_access_control(void)
490{
491 ARM_SWITCH_REGISTERS;
492 uint32_t val;
493
494 __asm__ volatile (
495 ARM_SWITCH_TO_ARM
496 "mrc p15, 0, %[val], c3, c0, 0\n"
497 ARM_SWITCH_BACK
498 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
499 );
500
501 return val;
502}
503
504ARM_CP15_TEXT_SECTION static inline void
505arm_cp15_set_domain_access_control(uint32_t val)
506{
507 ARM_SWITCH_REGISTERS;
508
509 __asm__ volatile (
510 ARM_SWITCH_TO_ARM
511 "mcr p15, 0, %[val], c3, c0, 0\n"
512 ARM_SWITCH_BACK
513 : ARM_SWITCH_OUTPUT
514 : [val] "r" (val)
515 );
516}
517
518ARM_CP15_TEXT_SECTION static inline uint32_t
519arm_cp15_get_data_fault_status(void)
520{
521 ARM_SWITCH_REGISTERS;
522 uint32_t val;
523
524 __asm__ volatile (
525 ARM_SWITCH_TO_ARM
526 "mrc p15, 0, %[val], c5, c0, 0\n"
527 ARM_SWITCH_BACK
528 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
529 );
530
531 return val;
532}
533
534ARM_CP15_TEXT_SECTION static inline void
535arm_cp15_set_data_fault_status(uint32_t val)
536{
537 ARM_SWITCH_REGISTERS;
538
539 __asm__ volatile (
540 ARM_SWITCH_TO_ARM
541 "mcr p15, 0, %[val], c5, c0, 0\n"
542 ARM_SWITCH_BACK
543 : ARM_SWITCH_OUTPUT
544 : [val] "r" (val)
545 );
546}
547
548ARM_CP15_TEXT_SECTION static inline uint32_t
549arm_cp15_get_instruction_fault_status(void)
550{
551 ARM_SWITCH_REGISTERS;
552 uint32_t val;
553
554 __asm__ volatile (
555 ARM_SWITCH_TO_ARM
556 "mrc p15, 0, %[val], c5, c0, 1\n"
557 ARM_SWITCH_BACK
558 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
559 );
560
561 return val;
562}
563
564ARM_CP15_TEXT_SECTION static inline void
565arm_cp15_set_instruction_fault_status(uint32_t val)
566{
567 ARM_SWITCH_REGISTERS;
568
569 __asm__ volatile (
570 ARM_SWITCH_TO_ARM
571 "mcr p15, 0, %[val], c5, c0, 1\n"
572 ARM_SWITCH_BACK
573 : ARM_SWITCH_OUTPUT
574 : [val] "r" (val)
575 );
576}
577
578ARM_CP15_TEXT_SECTION static inline void
579*arm_cp15_get_fault_address(void)
580{
581 ARM_SWITCH_REGISTERS;
582 void *mva;
583
584 __asm__ volatile (
585 ARM_SWITCH_TO_ARM
586 "mrc p15, 0, %[mva], c6, c0, 0\n"
587 ARM_SWITCH_BACK
588 : [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT
589 );
590
591 return mva;
592}
593
594ARM_CP15_TEXT_SECTION static inline void
595arm_cp15_set_fault_address(const void *mva)
596{
597 ARM_SWITCH_REGISTERS;
598
599 __asm__ volatile (
600 ARM_SWITCH_TO_ARM
601 "mcr p15, 0, %[mva], c6, c0, 0\n"
602 ARM_SWITCH_BACK
603 : ARM_SWITCH_OUTPUT
604 : [mva] "r" (mva)
605 );
606}
607
608ARM_CP15_TEXT_SECTION static inline void
609arm_cp15_tlb_invalidate(void)
610{
611 ARM_SWITCH_REGISTERS;
612 uint32_t sbz = 0;
613
614 __asm__ volatile (
615 ARM_SWITCH_TO_ARM
616 "mcr p15, 0, %[sbz], c8, c7, 0\n"
617 ARM_SWITCH_BACK
618 : ARM_SWITCH_OUTPUT
619 : [sbz] "r" (sbz)
620 );
621
622 /*
623 * ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, Issue C,
624 * B3.10.1 General TLB maintenance requirements.
625 */
626 _ARM_Data_synchronization_barrier();
627 _ARM_Instruction_synchronization_barrier();
628}
629
630ARM_CP15_TEXT_SECTION static inline void
631arm_cp15_tlb_invalidate_entry(const void *mva)
632{
633 ARM_SWITCH_REGISTERS;
634
635 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
636
637 __asm__ volatile (
638 ARM_SWITCH_TO_ARM
639 "mcr p15, 0, %[mva], c8, c7, 1\n"
640 ARM_SWITCH_BACK
641 : ARM_SWITCH_OUTPUT
642 : [mva] "r" (mva)
643 );
644}
645
646ARM_CP15_TEXT_SECTION static inline void
647arm_cp15_tlb_invalidate_entry_all_asids(const void *mva)
648{
649 ARM_SWITCH_REGISTERS;
650
651 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
652
653 __asm__ volatile (
654 ARM_SWITCH_TO_ARM
655 "mcr p15, 0, %[mva], c8, c7, 3\n"
656 ARM_SWITCH_BACK
657 : ARM_SWITCH_OUTPUT
658 : [mva] "r" (mva)
659 );
660}
661
662ARM_CP15_TEXT_SECTION static inline void
663arm_cp15_tlb_invalidate_entry_all_asids_inner_shareable(const void *mva)
664{
665 ARM_SWITCH_REGISTERS;
666
667 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
668
669 __asm__ volatile (
670 ARM_SWITCH_TO_ARM
671 "mcr p15, 0, %[mva], c8, c3, 3\n"
672 ARM_SWITCH_BACK
673 : ARM_SWITCH_OUTPUT
674 : [mva] "r" (mva)
675 );
676}
677
678ARM_CP15_TEXT_SECTION static inline void
679arm_cp15_tlb_instruction_invalidate(void)
680{
681 ARM_SWITCH_REGISTERS;
682 uint32_t sbz = 0;
683
684 __asm__ volatile (
685 ARM_SWITCH_TO_ARM
686 "mcr p15, 0, %[sbz], c8, c5, 0\n"
687 ARM_SWITCH_BACK
688 : ARM_SWITCH_OUTPUT
689 : [sbz] "r" (sbz)
690 );
691}
692
693ARM_CP15_TEXT_SECTION static inline void
694arm_cp15_tlb_instruction_invalidate_entry(const void *mva)
695{
696 ARM_SWITCH_REGISTERS;
697
698 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
699
700 __asm__ volatile (
701 ARM_SWITCH_TO_ARM
702 "mcr p15, 0, %[mva], c8, c5, 1\n"
703 ARM_SWITCH_BACK
704 : ARM_SWITCH_OUTPUT
705 : [mva] "r" (mva)
706 );
707}
708
709ARM_CP15_TEXT_SECTION static inline void
710arm_cp15_tlb_data_invalidate(void)
711{
712 ARM_SWITCH_REGISTERS;
713 uint32_t sbz = 0;
714
715 __asm__ volatile (
716 ARM_SWITCH_TO_ARM
717 "mcr p15, 0, %[sbz], c8, c6, 0\n"
718 ARM_SWITCH_BACK
719 : ARM_SWITCH_OUTPUT
720 : [sbz] "r" (sbz)
721 );
722}
723
724ARM_CP15_TEXT_SECTION static inline void
725arm_cp15_tlb_data_invalidate_entry(const void *mva)
726{
727 ARM_SWITCH_REGISTERS;
728
729 mva = ARM_CP15_TLB_PREPARE_MVA(mva);
730
731 __asm__ volatile (
732 ARM_SWITCH_TO_ARM
733 "mcr p15, 0, %[mva], c8, c6, 1\n"
734 ARM_SWITCH_BACK
735 : ARM_SWITCH_OUTPUT
736 : [mva] "r" (mva)
737 );
738}
739
740ARM_CP15_TEXT_SECTION static inline void
741arm_cp15_tlb_lockdown_entry(const void *mva)
742{
743 uint32_t arm_switch_reg;
744
745 __asm__ volatile (
746 ARM_SWITCH_TO_ARM
747 "add %[arm_switch_reg], pc, #16\n"
748 "mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n"
749 "mcr p15, 0, %[mva], c8, c7, 1\n"
750 "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
751 "orr %[arm_switch_reg], #0x1\n"
752 "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
753 "ldr %[mva], [%[mva]]\n"
754 "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
755 "bic %[arm_switch_reg], #0x1\n"
756 "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
757 ARM_SWITCH_BACK
758 : [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg)
759 : "[mva]" (mva)
760 );
761}
762
771/* Read cache type register CTR */
772ARM_CP15_TEXT_SECTION static inline uint32_t
773arm_cp15_get_cache_type(void)
774{
775 ARM_SWITCH_REGISTERS;
776 uint32_t val;
777
778 __asm__ volatile (
779 ARM_SWITCH_TO_ARM
780 "mrc p15, 0, %[val], c0, c0, 1\n"
781 ARM_SWITCH_BACK
782 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
783 );
784
785 return val;
786}
787
788/* Extract format version from cache type CTR */
789ARM_CP15_TEXT_SECTION static inline int
790arm_cp15_cache_type_get_format(uint32_t ct)
791{
792 return (ct >> 29) & 0x7U;
793}
794
795/* Read size of smallest cache line of all instruction/data caches controlled by the processor */
796ARM_CP15_TEXT_SECTION static inline uint32_t
797arm_cp15_get_min_cache_line_size(void)
798{
799 uint32_t mcls = 0;
800 uint32_t ct = arm_cp15_get_cache_type();
801 uint32_t format = arm_cp15_cache_type_get_format(ct);
802
803 if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
804 /* ARMv7 format */
805 mcls = (1U << (ct & 0xf)) * 4;
806 } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
807 /* ARMv6 format */
808 uint32_t mask = (1U << 12) - 1;
809 uint32_t dcls = (ct >> 12) & mask;
810 uint32_t icls = ct & mask;
811
812 mcls = dcls <= icls ? dcls : icls;
813 }
814
815 return mcls;
816}
817
818/* Read size of smallest data cache lines */
819ARM_CP15_TEXT_SECTION static inline uint32_t
820arm_cp15_get_data_cache_line_size(void)
821{
822 uint32_t mcls = 0;
823 uint32_t ct = arm_cp15_get_cache_type();
824 uint32_t format = arm_cp15_cache_type_get_format(ct);
825
826 if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
827 /* ARMv7 format */
828 mcls = (1U << ((ct & 0xf0000) >> 16)) * 4;
829 } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
830 /* ARMv6 format */
831 uint32_t mask = (1U << 12) - 1;
832 mcls = (ct >> 12) & mask;
833 }
834
835 return mcls;
836}
837
838/* Read size of smallest instruction cache lines */
839ARM_CP15_TEXT_SECTION static inline uint32_t
840arm_cp15_get_instruction_cache_line_size(void)
841{
842 uint32_t mcls = 0;
843 uint32_t ct = arm_cp15_get_cache_type();
844 uint32_t format = arm_cp15_cache_type_get_format(ct);
845
846 if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV7) {
847 /* ARMv7 format */
848 mcls = (1U << (ct & 0x0000f)) * 4;
849 } else if (format == ARM_CP15_CACHE_TYPE_FORMAT_ARMV6) {
850 /* ARMv6 format */
851 uint32_t mask = (1U << 12) - 1;
852 mcls = ct & mask;;
853 }
854
855 return mcls;
856}
857
858/* CCSIDR, Cache Size ID Register */
859
860ARM_CP15_TEXT_SECTION static inline uint32_t
861arm_cp15_get_cache_size_id(void)
862{
863 ARM_SWITCH_REGISTERS;
864 uint32_t val;
865
866 __asm__ volatile (
867 ARM_SWITCH_TO_ARM
868 "mrc p15, 1, %[val], c0, c0, 0\n"
869 ARM_SWITCH_BACK
870 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
871 );
872
873 return val;
874}
875
876ARM_CP15_TEXT_SECTION static inline uint32_t
877arm_ccsidr_get_line_power(uint32_t ccsidr)
878{
879 return (ccsidr & 0x7) + 4;
880}
881
882ARM_CP15_TEXT_SECTION static inline uint32_t
883arm_ccsidr_get_associativity(uint32_t ccsidr)
884{
885 return ((ccsidr >> 3) & 0x3ff) + 1;
886}
887
888ARM_CP15_TEXT_SECTION static inline uint32_t
889arm_ccsidr_get_num_sets(uint32_t ccsidr)
890{
891 return ((ccsidr >> 13) & 0x7fff) + 1;
892}
893
894/* CLIDR, Cache Level ID Register */
895
896ARM_CP15_TEXT_SECTION static inline uint32_t
897arm_cp15_get_cache_level_id(void)
898{
899 ARM_SWITCH_REGISTERS;
900 uint32_t val;
901
902 __asm__ volatile (
903 ARM_SWITCH_TO_ARM
904 "mrc p15, 1, %[val], c0, c0, 1\n"
905 ARM_SWITCH_BACK
906 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
907 );
908
909 return val;
910}
911
912ARM_CP15_TEXT_SECTION static inline uint32_t
913arm_clidr_get_level_of_coherency(uint32_t clidr)
914{
915 return (clidr >> 24) & 0x7;
916}
917
918ARM_CP15_TEXT_SECTION static inline uint32_t
919arm_clidr_get_cache_type(uint32_t clidr, uint32_t level)
920{
921 return (clidr >> (3 * level)) & 0x7;
922}
923
924/* CSSELR, Cache Size Selection Register */
925
926ARM_CP15_TEXT_SECTION static inline uint32_t
927arm_cp15_get_cache_size_selection(void)
928{
929 ARM_SWITCH_REGISTERS;
930 uint32_t val;
931
932 __asm__ volatile (
933 ARM_SWITCH_TO_ARM
934 "mrc p15, 2, %[val], c0, c0, 0\n"
935 ARM_SWITCH_BACK
936 : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
937 );
938
939 return val;
940}
941
942ARM_CP15_TEXT_SECTION static inline void
943arm_cp15_set_cache_size_selection(uint32_t val)
944{
945 ARM_SWITCH_REGISTERS;
946
947 __asm__ volatile (
948 ARM_SWITCH_TO_ARM
949 "mcr p15, 2, %[val], c0, c0, 0\n"
950 ARM_SWITCH_BACK
951 : ARM_SWITCH_OUTPUT
952 : [val] "r" (val)
953 : "memory"
954 );
955}
956
957ARM_CP15_TEXT_SECTION static inline uint32_t
958arm_cp15_get_cache_size_id_for_level(uint32_t level_and_inst_dat)
959{
960 rtems_interrupt_level irq_level;
961 uint32_t ccsidr;
962
964 arm_cp15_set_cache_size_selection(level_and_inst_dat);
965 _ARM_Instruction_synchronization_barrier();
966 ccsidr = arm_cp15_get_cache_size_id();
968
969 return ccsidr;
970}
971
972ARM_CP15_TEXT_SECTION static inline void
973arm_cp15_cache_invalidate(void)
974{
975 ARM_SWITCH_REGISTERS;
976 uint32_t sbz = 0;
977
978 __asm__ volatile (
979 ARM_SWITCH_TO_ARM
980 "mcr p15, 0, %[sbz], c7, c7, 0\n"
981 ARM_SWITCH_BACK
982 : ARM_SWITCH_OUTPUT
983 : [sbz] "r" (sbz)
984 : "memory"
985 );
986}
987
988/* ICIALLUIS, Instruction Cache Invalidate All to PoU, Inner Shareable */
989
990ARM_CP15_TEXT_SECTION static inline void
991arm_cp15_instruction_cache_inner_shareable_invalidate_all(void)
992{
993 ARM_SWITCH_REGISTERS;
994 uint32_t sbz = 0;
995
996 __asm__ volatile (
997 ARM_SWITCH_TO_ARM
998 "mcr p15, 0, %[sbz], c7, c1, 0\n"
999 ARM_SWITCH_BACK
1000 : ARM_SWITCH_OUTPUT
1001 : [sbz] "r" (sbz)
1002 : "memory"
1003 );
1004}
1005
1006/* BPIALLIS, Branch Predictor Invalidate All, Inner Shareable */
1007
1008ARM_CP15_TEXT_SECTION static inline void
1009arm_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/* BPIALL, Branch Predictor Invalidate All */
1025
1026ARM_CP15_TEXT_SECTION static inline void
1027arm_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/* Flush Prefetch Buffer - DDI0301H arm1176jzfs TRM 3.2.22 */
1043ARM_CP15_TEXT_SECTION static inline void
1044arm_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
1059ARM_CP15_TEXT_SECTION static inline void
1060arm_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
1075ARM_CP15_TEXT_SECTION static inline void
1076arm_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
1092ARM_CP15_TEXT_SECTION static inline void
1093arm_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
1107ARM_CP15_TEXT_SECTION static inline void
1108arm_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
1123ARM_CP15_TEXT_SECTION static inline void
1124arm_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
1139ARM_CP15_TEXT_SECTION static inline void
1140arm_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
1156ARM_CP15_TEXT_SECTION static inline void
1157arm_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
1171ARM_CP15_TEXT_SECTION static inline void
1172arm_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
1200ARM_CP15_TEXT_SECTION static inline void
1201arm_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 /* Check if this level has a data cache or unified cache */
1211 if (((ctype & (0x6)) == 2) || (ctype == 4)) {
1212 arm_cp15_cache_invalidate_level(level, 0);
1213 }
1214 }
1215}
1216
1217ARM_CP15_TEXT_SECTION static inline void
1218arm_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
1234ARM_CP15_TEXT_SECTION static inline void
1235arm_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
1249ARM_CP15_TEXT_SECTION static inline void
1250arm_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
1278ARM_CP15_TEXT_SECTION static inline void
1279arm_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 /* Check if this level has a data cache or unified cache */
1289 if (((ctype & (0x6)) == 2) || (ctype == 4)) {
1290 arm_cp15_data_cache_clean_level(level);
1291 }
1292 }
1293}
1294
1295ARM_CP15_TEXT_SECTION static inline void
1296arm_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
1312ARM_CP15_TEXT_SECTION static inline void
1313arm_cp15_data_cache_clean_and_invalidate(void)
1314{
1315 ARM_SWITCH_REGISTERS;
1316
1317#if __ARM_ARCH >= 6
1318 /*
1319 * In DDI0301H_arm1176jzfs_r0p7_trm
1320 * 'MCR p15, 0, <Rd>, c7, c14, 0' means
1321 * Clean and Invalidate Entire Data Cache
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 * Assume this is an ARM926EJ-S. Use the test, clean, and invalidate DCache
1336 * operation.
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
1351ARM_CP15_TEXT_SECTION static inline void
1352arm_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
1368ARM_CP15_TEXT_SECTION static inline void
1369arm_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
1383ARM_CP15_TEXT_SECTION static inline void
1384arm_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
1402ARM_CP15_TEXT_SECTION static inline void
1403arm_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
1418ARM_CP15_TEXT_SECTION static inline void
1419arm_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
1434ARM_CP15_TEXT_SECTION static inline uint32_t
1435arm_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
1450ARM_CP15_TEXT_SECTION static inline uint32_t
1451arm_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
1465ARM_CP15_TEXT_SECTION static inline uint32_t
1466arm_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
1481ARM_CP15_TEXT_SECTION static inline void
1482arm_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/* ID_PFR1, Processor Feature Register 1 */
1496
1497ARM_CP15_TEXT_SECTION static inline uint32_t
1498arm_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/* VBAR, Vector Base Address Register, Security Extensions */
1514
1515ARM_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
1531ARM_CP15_TEXT_SECTION static inline void
1532arm_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
1545ARM_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
1561ARM_CP15_TEXT_SECTION static inline void
1562arm_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/* PMCCNTR */
1576ARM_CP15_TEXT_SECTION static inline uint32_t
1577arm_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/* PMCCNTR */
1593ARM_CP15_TEXT_SECTION static inline void
1594arm_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/* PMCEID0 */
1608ARM_CP15_TEXT_SECTION static inline uint32_t
1609arm_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/* PMCEID1 */
1625ARM_CP15_TEXT_SECTION static inline uint32_t
1626arm_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/* PMCCNTENCLR */
1644ARM_CP15_TEXT_SECTION static inline uint32_t
1645arm_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/* PMCCNTENCLR */
1661ARM_CP15_TEXT_SECTION static inline void
1662arm_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/* PMCCNTENSET */
1676ARM_CP15_TEXT_SECTION static inline uint32_t
1677arm_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/* PMCCNTENSET */
1693ARM_CP15_TEXT_SECTION static inline void
1694arm_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/* PMCR */
1718ARM_CP15_TEXT_SECTION static inline uint32_t
1719arm_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/* PMCR */
1735ARM_CP15_TEXT_SECTION static inline void
1736arm_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/* PMINTENCLR */
1750ARM_CP15_TEXT_SECTION static inline uint32_t
1751arm_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/* PMINTENCLR */
1767ARM_CP15_TEXT_SECTION static inline void
1768arm_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/* PMINTENSET */
1782ARM_CP15_TEXT_SECTION static inline uint32_t
1783arm_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/* PMINTENSET */
1799ARM_CP15_TEXT_SECTION static inline void
1800arm_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/* PMOVSR */
1814ARM_CP15_TEXT_SECTION static inline uint32_t
1815arm_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/* PMOVSR */
1831ARM_CP15_TEXT_SECTION static inline void
1832arm_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/* PMOVSSET */
1846ARM_CP15_TEXT_SECTION static inline uint32_t
1847arm_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/* PMOVSSET */
1863ARM_CP15_TEXT_SECTION static inline void
1864arm_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/* PMSELR */
1878ARM_CP15_TEXT_SECTION static inline uint32_t
1879arm_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/* PMSELR */
1895ARM_CP15_TEXT_SECTION static inline void
1896arm_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/* PMSWINC */
1910ARM_CP15_TEXT_SECTION static inline void
1911arm_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/* PMUSERENR */
1925ARM_CP15_TEXT_SECTION static inline uint32_t
1926arm_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/* PMUSERENR */
1942ARM_CP15_TEXT_SECTION static inline void
1943arm_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/* PMXEVCNTR */
1957ARM_CP15_TEXT_SECTION static inline uint32_t
1958arm_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/* PMXEVCNTR */
1974ARM_CP15_TEXT_SECTION static inline void
1975arm_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/* PMXEVTYPER */
1989ARM_CP15_TEXT_SECTION static inline uint32_t
1990arm_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/* PMXEVTYPER */
2006ARM_CP15_TEXT_SECTION static inline void
2007arm_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/* CNTFRQ */
2021ARM_CP15_TEXT_SECTION static inline uint32_t
2022arm_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/* CNTFRQ */
2038ARM_CP15_TEXT_SECTION static inline void
2039arm_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/* CNTPCT */
2053ARM_CP15_TEXT_SECTION static inline uint64_t
2054arm_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/* CNTKCTL */
2070ARM_CP15_TEXT_SECTION static inline uint32_t
2071arm_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/* CNTKCTL */
2087ARM_CP15_TEXT_SECTION static inline void
2088arm_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/* CNTP_TVAL */
2102ARM_CP15_TEXT_SECTION static inline uint32_t
2103arm_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/* CNTP_TVAL */
2119ARM_CP15_TEXT_SECTION static inline void
2120arm_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/* CNTP_CTL */
2134ARM_CP15_TEXT_SECTION static inline uint32_t
2135arm_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/* CNTP_CTL */
2151ARM_CP15_TEXT_SECTION static inline void
2152arm_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/* CNTV_TVAL */
2166ARM_CP15_TEXT_SECTION static inline uint32_t
2167arm_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/* CNTV_TVAL */
2183ARM_CP15_TEXT_SECTION static inline void
2184arm_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/* CNTV_CTL */
2198ARM_CP15_TEXT_SECTION static inline uint32_t
2199arm_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/* CNTV_CTL */
2215ARM_CP15_TEXT_SECTION static inline void
2216arm_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/* CNTVCT */
2230ARM_CP15_TEXT_SECTION static inline uint64_t
2231arm_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/* CNTP_CVAL */
2247ARM_CP15_TEXT_SECTION static inline uint64_t
2248arm_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/* CNTP_CVAL */
2264ARM_CP15_TEXT_SECTION static inline void
2265arm_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/* CNTV_CVAL */
2279ARM_CP15_TEXT_SECTION static inline uint64_t
2280arm_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/* CNTV_CVAL */
2296ARM_CP15_TEXT_SECTION static inline void
2297arm_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/* CNTVOFF */
2311ARM_CP15_TEXT_SECTION static inline uint64_t
2312arm_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/* CNTVOFF */
2328ARM_CP15_TEXT_SECTION static inline void
2329arm_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/* Diagnostic Control Register */
2343ARM_CP15_TEXT_SECTION static inline uint32_t
2344arm_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/* Diagnostic Control Register */
2360ARM_CP15_TEXT_SECTION static inline void
2361arm_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/* This is probably a Cortex-R5 specific operation */
2375ARM_CP15_TEXT_SECTION static inline void
2376arm_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
2397 const void *begin,
2398 const void *end,
2399 uint32_t section_flags
2400);
2401
2408 Arm_symbolic_exception_name exception,
2409 void (*handler)(void)
2410);
2411
2414#ifdef __cplusplus
2415}
2416#endif /* __cplusplus */
2417
2418#endif /* LIBCPU_SHARED_ARM_CP15_H */
#define rtems_interrupt_local_disable(_isr_cookie)
Disables the maskable interrupts on the current processor.
Definition: intr.h:427
ISR_Level rtems_interrupt_level
This integer type represents interrupt levels.
Definition: intr.h:111
#define rtems_interrupt_local_enable(_isr_cookie)
Restores the previous interrupt level on the current processor.
Definition: intr.h:468
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:41
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:148
This header file defines the RTEMS Classic API.
Definition: mknod-pack_dev.c:254
unsigned ct
Definition: tlb.h:14