source: rtems/c/src/lib/libcpu/arm/shared/include/arm-cp15.h @ fd51f7e

4.115
Last change on this file since fd51f7e was fd51f7e, checked in by Sebastian Huber <sebastian.huber@…>, on 05/02/13 at 09:09:24

bsps/arm: Support ARMv7 VMSA sections and control

  • Property mode set to 100644
File size: 16.6 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreCPUARMCP15
5 *
6 * @brief ARM co-processor 15 (CP15) API.
7 */
8
9/*
10 * Copyright (c) 2009-2013 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <info@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.com/license/LICENSE.
21 */
22
23#ifndef LIBCPU_SHARED_ARM_CP15_H
24#define LIBCPU_SHARED_ARM_CP15_H
25
26#include <rtems.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32#define ARM_CP15_CACHE_PREPARE_MVA(mva) \
33  ((const void *) (((uint32_t) (mva)) & ~0x1fU))
34
35#define ARM_CP15_TLB_PREPARE_MVA(mva) \
36  ((const void *) (((uint32_t) (mva)) & ~0x3fU))
37
38/**
39 * @defgroup ScoreCPUARMCP15 ARM Co-Processor 15 Support
40 *
41 * @ingroup ScoreCPUARM
42 *
43 * @brief ARM co-processor 15 (CP15) support.
44 *
45 * @{
46 */
47
48/**
49 * @name MMU Defines
50 *
51 * @{
52 */
53
54#define ARM_MMU_SECT_BASE_SHIFT 20
55#define ARM_MMU_SECT_BASE_MASK (0xfffU << ARM_MMU_SECT_BASE_SHIFT)
56#define ARM_MMU_SECT_NS (1U << 19)
57#define ARM_MMU_SECT_NG (1U << 17)
58#define ARM_MMU_SECT_S (1U << 16)
59#define ARM_MMU_SECT_AP_2 (1U << 15)
60#define ARM_MMU_SECT_TEX_2 (1U << 14)
61#define ARM_MMU_SECT_TEX_1 (1U << 13)
62#define ARM_MMU_SECT_TEX_0 (1U << 12)
63#define ARM_MMU_SECT_TEX_SHIFT 12
64#define ARM_MMU_SECT_TEX_MASK (0x3U << ARM_MMU_SECT_TEX_SHIFT)
65#define ARM_MMU_SECT_AP_1 (1U << 11)
66#define ARM_MMU_SECT_AP_0 (1U << 10)
67#define ARM_MMU_SECT_AP_SHIFT 10
68#define ARM_MMU_SECT_AP_MASK (0x23U << ARM_MMU_SECT_AP_SHIFT)
69#define ARM_MMU_SECT_DOMAIN_SHIFT 5
70#define ARM_MMU_SECT_DOMAIN_MASK (0xfU << ARM_MMU_SECT_DOMAIN_SHIFT)
71#define ARM_MMU_SECT_XN (1U << 4)
72#define ARM_MMU_SECT_C (1U << 3)
73#define ARM_MMU_SECT_B (1U << 2)
74#define ARM_MMU_SECT_PXN (1U << 0)
75#define ARM_MMU_SECT_DEFAULT 0x2U
76#define ARM_MMU_SECT_GET_INDEX(mva) \
77  (((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT)
78#define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \
79  ((1U << ARM_MMU_SECT_BASE_SHIFT) \
80    + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U)))
81
82#define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U
83#define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U
84
85/** @} */
86
87/**
88 * @name Control Register Defines
89 *
90 * @{
91 */
92
93#define ARM_CP15_CTRL_TE (1U << 30)
94#define ARM_CP15_CTRL_AFE (1U << 29)
95#define ARM_CP15_CTRL_TRE (1U << 28)
96#define ARM_CP15_CTRL_NMFI (1U << 27)
97#define ARM_CP15_CTRL_EE (1U << 25)
98#define ARM_CP15_CTRL_VE (1U << 24)
99#define ARM_CP15_CTRL_U (1U << 22)
100#define ARM_CP15_CTRL_FI (1U << 21)
101#define ARM_CP15_CTRL_UWXN (1U << 20)
102#define ARM_CP15_CTRL_WXN (1U << 19)
103#define ARM_CP15_CTRL_HA (1U << 17)
104#define ARM_CP15_CTRL_L4 (1U << 15)
105#define ARM_CP15_CTRL_RR (1U << 14)
106#define ARM_CP15_CTRL_V (1U << 13)
107#define ARM_CP15_CTRL_I (1U << 12)
108#define ARM_CP15_CTRL_Z (1U << 11)
109#define ARM_CP15_CTRL_SW (1U << 10)
110#define ARM_CP15_CTRL_R (1U << 9)
111#define ARM_CP15_CTRL_S (1U << 8)
112#define ARM_CP15_CTRL_B (1U << 7)
113#define ARM_CP15_CTRL_CP15BEN (1U << 5)
114#define ARM_CP15_CTRL_C (1U << 2)
115#define ARM_CP15_CTRL_A (1U << 1)
116#define ARM_CP15_CTRL_M (1U << 0)
117
118/** @} */
119
120/**
121 * @name Domain Access Control Defines
122 *
123 * @{
124 */
125
126#define ARM_CP15_DAC_NO_ACCESS 0x0U
127#define ARM_CP15_DAC_CLIENT 0x1U
128#define ARM_CP15_DAC_MANAGER 0x3U
129#define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index))
130
131/** @} */
132
133static inline uint32_t arm_cp15_get_id_code(void)
134{
135  ARM_SWITCH_REGISTERS;
136  uint32_t val;
137
138  __asm__ volatile (
139    ARM_SWITCH_TO_ARM
140    "mrc p15, 0, %[val], c0, c0, 0\n"
141    ARM_SWITCH_BACK
142    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
143  );
144
145  return val;
146}
147
148static inline uint32_t arm_cp15_get_tcm_status(void)
149{
150  ARM_SWITCH_REGISTERS;
151  uint32_t val;
152
153  __asm__ volatile (
154    ARM_SWITCH_TO_ARM
155    "mrc p15, 0, %[val], c0, c0, 2\n"
156    ARM_SWITCH_BACK
157    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
158  );
159
160  return val;
161}
162
163static inline uint32_t arm_cp15_get_control(void)
164{
165  ARM_SWITCH_REGISTERS;
166  uint32_t val;
167
168  __asm__ volatile (
169    ARM_SWITCH_TO_ARM
170    "mrc p15, 0, %[val], c1, c0, 0\n"
171    ARM_SWITCH_BACK
172    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
173  );
174
175  return val;
176}
177
178static inline void arm_cp15_set_control(uint32_t val)
179{
180  ARM_SWITCH_REGISTERS;
181
182  __asm__ volatile (
183    ARM_SWITCH_TO_ARM
184    "mcr p15, 0, %[val], c1, c0, 0\n"
185    "nop\n"
186    "nop\n"
187    ARM_SWITCH_BACK
188    : ARM_SWITCH_OUTPUT
189    : [val] "r" (val)
190    : "memory"
191  );
192}
193
194/**
195 * @name MMU Functions
196 *
197 * @{
198 */
199
200/**
201 * @brief Disable the MMU.
202 *
203 * This function will clean and invalidate eight cache lines before and after
204 * the current stack pointer.
205 *
206 * @param[in] cls The data cache line size.
207 *
208 * @return The current control register value.
209 */
210static inline uint32_t arm_cp15_mmu_disable(uint32_t cls)
211{
212  ARM_SWITCH_REGISTERS;
213  uint32_t ctrl;
214  uint32_t tmp_0;
215  uint32_t tmp_1;
216
217  __asm__ volatile (
218    ARM_SWITCH_TO_ARM
219    "mrc p15, 0, %[ctrl], c1, c0, 0\n"
220    "bic %[tmp_0], %[ctrl], #1\n"
221    "mcr p15, 0, %[tmp_0], c1, c0, 0\n"
222    "nop\n"
223    "nop\n"
224    "mov %[tmp_1], sp\n"
225    "rsb %[tmp_0], %[cls], #0\n"
226    "and %[tmp_0], %[tmp_0], %[tmp_1]\n"
227    "sub %[tmp_0], %[tmp_0], %[cls], asl #3\n"
228    "add %[tmp_1], %[tmp_0], %[cls], asl #4\n"
229    "1:\n"
230    "mcr p15, 0, %[tmp_0], c7, c14, 1\n"
231    "add %[tmp_0], %[tmp_0], %[cls]\n"
232    "cmp %[tmp_1], %[tmp_0]\n"
233    "bne 1b\n"
234    ARM_SWITCH_BACK
235    : [ctrl] "=&r" (ctrl),
236      [tmp_0] "=&r" (tmp_0),
237      [tmp_1] "=&r" (tmp_1)
238      ARM_SWITCH_ADDITIONAL_OUTPUT
239    : [cls] "r" (cls)
240    : "memory", "cc"
241  );
242
243  return ctrl;
244}
245
246static inline uint32_t *arm_cp15_get_translation_table_base(void)
247{
248  ARM_SWITCH_REGISTERS;
249  uint32_t *base;
250
251  __asm__ volatile (
252    ARM_SWITCH_TO_ARM
253    "mrc p15, 0, %[base], c2, c0, 0\n"
254    ARM_SWITCH_BACK
255    : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
256  );
257
258  return base;
259}
260
261static inline void arm_cp15_set_translation_table_base(uint32_t *base)
262{
263  ARM_SWITCH_REGISTERS;
264
265  __asm__ volatile (
266    ARM_SWITCH_TO_ARM
267    "mcr p15, 0, %[base], c2, c0, 0\n"
268    ARM_SWITCH_BACK
269    : ARM_SWITCH_OUTPUT
270    : [base] "r" (base)
271  );
272}
273
274static inline uint32_t arm_cp15_get_domain_access_control(void)
275{
276  ARM_SWITCH_REGISTERS;
277  uint32_t val;
278
279  __asm__ volatile (
280    ARM_SWITCH_TO_ARM
281    "mrc p15, 0, %[val], c3, c0, 0\n"
282    ARM_SWITCH_BACK
283    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
284  );
285
286  return val;
287}
288
289static inline void arm_cp15_set_domain_access_control(uint32_t val)
290{
291  ARM_SWITCH_REGISTERS;
292
293  __asm__ volatile (
294    ARM_SWITCH_TO_ARM
295    "mcr p15, 0, %[val], c3, c0, 0\n"
296    ARM_SWITCH_BACK
297    : ARM_SWITCH_OUTPUT
298    : [val] "r" (val)
299  );
300}
301
302static inline uint32_t arm_cp15_get_data_fault_status(void)
303{
304  ARM_SWITCH_REGISTERS;
305  uint32_t val;
306
307  __asm__ volatile (
308    ARM_SWITCH_TO_ARM
309    "mrc p15, 0, %[val], c5, c0, 0\n"
310    ARM_SWITCH_BACK
311    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
312  );
313
314  return val;
315}
316
317static inline void arm_cp15_set_data_fault_status(uint32_t val)
318{
319  ARM_SWITCH_REGISTERS;
320
321  __asm__ volatile (
322    ARM_SWITCH_TO_ARM
323    "mcr p15, 0, %[val], c5, c0, 0\n"
324    ARM_SWITCH_BACK
325    : ARM_SWITCH_OUTPUT
326    : [val] "r" (val)
327  );
328}
329
330static inline uint32_t arm_cp15_get_instruction_fault_status(void)
331{
332  ARM_SWITCH_REGISTERS;
333  uint32_t val;
334
335  __asm__ volatile (
336    ARM_SWITCH_TO_ARM
337    "mrc p15, 0, %[val], c5, c0, 1\n"
338    ARM_SWITCH_BACK
339    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
340  );
341
342  return val;
343}
344
345static inline void arm_cp15_set_instruction_fault_status(uint32_t val)
346{
347  ARM_SWITCH_REGISTERS;
348
349  __asm__ volatile (
350    ARM_SWITCH_TO_ARM
351    "mcr p15, 0, %[val], c5, c0, 1\n"
352    ARM_SWITCH_BACK
353    : ARM_SWITCH_OUTPUT
354    : [val] "r" (val)
355  );
356}
357
358static inline void *arm_cp15_get_fault_address(void)
359{
360  ARM_SWITCH_REGISTERS;
361  void *mva;
362
363  __asm__ volatile (
364    ARM_SWITCH_TO_ARM
365    "mrc p15, 0, %[mva], c6, c0, 0\n"
366    ARM_SWITCH_BACK
367    : [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT
368  );
369
370  return mva;
371}
372
373static inline void arm_cp15_set_fault_address(const void *mva)
374{
375  ARM_SWITCH_REGISTERS;
376
377  __asm__ volatile (
378    ARM_SWITCH_TO_ARM
379    "mcr p15, 0, %[mva], c6, c0, 0\n"
380    ARM_SWITCH_BACK
381    : ARM_SWITCH_OUTPUT
382    : [mva] "r" (mva)
383  );
384}
385
386static inline void arm_cp15_tlb_invalidate(void)
387{
388  ARM_SWITCH_REGISTERS;
389  uint32_t sbz = 0;
390
391  __asm__ volatile (
392    ARM_SWITCH_TO_ARM
393    "mcr p15, 0, %[sbz], c8, c7, 0\n"
394    ARM_SWITCH_BACK
395    : ARM_SWITCH_OUTPUT
396    : [sbz] "r" (sbz)
397  );
398}
399
400static inline void arm_cp15_tlb_invalidate_entry(const void *mva)
401{
402  ARM_SWITCH_REGISTERS;
403
404  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
405
406  __asm__ volatile (
407    ARM_SWITCH_TO_ARM
408    "mcr p15, 0, %[mva], c8, c7, 1\n"
409    ARM_SWITCH_BACK
410    : ARM_SWITCH_OUTPUT
411    : [mva] "r" (mva)
412  );
413}
414
415static inline void arm_cp15_tlb_instruction_invalidate(void)
416{
417  ARM_SWITCH_REGISTERS;
418  uint32_t sbz = 0;
419
420  __asm__ volatile (
421    ARM_SWITCH_TO_ARM
422    "mcr p15, 0, %[sbz], c8, c5, 0\n"
423    ARM_SWITCH_BACK
424    : ARM_SWITCH_OUTPUT
425    : [sbz] "r" (sbz)
426  );
427}
428
429static inline void arm_cp15_tlb_instruction_invalidate_entry(const void *mva)
430{
431  ARM_SWITCH_REGISTERS;
432
433  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
434
435  __asm__ volatile (
436    ARM_SWITCH_TO_ARM
437    "mcr p15, 0, %[mva], c8, c5, 1\n"
438    ARM_SWITCH_BACK
439    : ARM_SWITCH_OUTPUT
440    : [mva] "r" (mva)
441  );
442}
443
444static inline void arm_cp15_tlb_data_invalidate(void)
445{
446  ARM_SWITCH_REGISTERS;
447  uint32_t sbz = 0;
448
449  __asm__ volatile (
450    ARM_SWITCH_TO_ARM
451    "mcr p15, 0, %[sbz], c8, c6, 0\n"
452    ARM_SWITCH_BACK
453    : ARM_SWITCH_OUTPUT
454    : [sbz] "r" (sbz)
455  );
456}
457
458static inline void arm_cp15_tlb_data_invalidate_entry(const void *mva)
459{
460  ARM_SWITCH_REGISTERS;
461
462  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
463
464  __asm__ volatile (
465    ARM_SWITCH_TO_ARM
466    "mcr p15, 0, %[mva], c8, c6, 1\n"
467    ARM_SWITCH_BACK
468    : ARM_SWITCH_OUTPUT
469    : [mva] "r" (mva)
470  );
471}
472
473static inline void arm_cp15_tlb_lockdown_entry(const void *mva)
474{
475  uint32_t arm_switch_reg;
476
477  __asm__ volatile (
478    ARM_SWITCH_TO_ARM
479    "add %[arm_switch_reg], pc, #16\n"
480    "mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n"
481    "mcr p15, 0, %[mva], c8, c7, 1\n"
482    "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
483    "orr %[arm_switch_reg], #0x1\n"
484    "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
485    "ldr %[mva], [%[mva]]\n"
486    "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
487    "bic %[arm_switch_reg], #0x1\n"
488    "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
489    ARM_SWITCH_BACK
490    : [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg)
491    : "[mva]" (mva)
492  );
493}
494
495/** @} */
496
497/**
498 * @name Cache Functions
499 *
500 * @{
501 */
502
503static inline uint32_t arm_cp15_get_cache_type(void)
504{
505  ARM_SWITCH_REGISTERS;
506  uint32_t val;
507
508  __asm__ volatile (
509    ARM_SWITCH_TO_ARM
510    "mrc p15, 0, %[val], c0, c0, 1\n"
511    ARM_SWITCH_BACK
512    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
513  );
514
515  return val;
516}
517
518static inline uint32_t arm_cp15_get_min_cache_line_size(void)
519{
520  uint32_t mcls = 0;
521  uint32_t ct = arm_cp15_get_cache_type();
522  uint32_t format = (ct >> 29) & 0x7U;
523
524  if (format == 0x4) {
525    mcls = (1U << (ct & 0xf)) * 4;
526  } else if (format == 0x0) {
527    uint32_t mask = (1U << 12) - 1;
528    uint32_t dcls = (ct >> 12) & mask;
529    uint32_t icls = ct & mask;
530
531    mcls = dcls <= icls ? dcls : icls;
532  }
533
534  return mcls;
535}
536
537static inline void arm_cp15_cache_invalidate(void)
538{
539  ARM_SWITCH_REGISTERS;
540  uint32_t sbz = 0;
541
542  __asm__ volatile (
543    ARM_SWITCH_TO_ARM
544    "mcr p15, 0, %[sbz], c7, c7, 0\n"
545    ARM_SWITCH_BACK
546    : ARM_SWITCH_OUTPUT
547    : [sbz] "r" (sbz)
548    : "memory"
549  );
550}
551
552static inline void arm_cp15_instruction_cache_invalidate(void)
553{
554  ARM_SWITCH_REGISTERS;
555  uint32_t sbz = 0;
556
557  __asm__ volatile (
558    ARM_SWITCH_TO_ARM
559    "mcr p15, 0, %[sbz], c7, c5, 0\n"
560    ARM_SWITCH_BACK
561    : ARM_SWITCH_OUTPUT
562    : [sbz] "r" (sbz)
563    : "memory"
564  );
565}
566
567static inline void arm_cp15_instruction_cache_invalidate_line(const void *mva)
568{
569  ARM_SWITCH_REGISTERS;
570
571  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
572
573  __asm__ volatile (
574    ARM_SWITCH_TO_ARM
575    "mcr p15, 0, %[mva], c7, c5, 1\n"
576    ARM_SWITCH_BACK
577    : ARM_SWITCH_OUTPUT
578    : [mva] "r" (mva)
579    : "memory"
580  );
581}
582
583static inline void arm_cp15_instruction_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
584{
585  ARM_SWITCH_REGISTERS;
586
587  __asm__ volatile (
588    ARM_SWITCH_TO_ARM
589    "mcr p15, 0, %[set_and_way], c7, c5, 2\n"
590    ARM_SWITCH_BACK
591    : ARM_SWITCH_OUTPUT
592    : [set_and_way] "r" (set_and_way)
593    : "memory"
594  );
595}
596
597static inline void arm_cp15_instruction_cache_prefetch_line(const void *mva)
598{
599  ARM_SWITCH_REGISTERS;
600
601  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
602
603  __asm__ volatile (
604    ARM_SWITCH_TO_ARM
605    "mcr p15, 0, %[mva], c7, c13, 1\n"
606    ARM_SWITCH_BACK
607    : ARM_SWITCH_OUTPUT
608    : [mva] "r" (mva)
609  );
610}
611
612static inline void arm_cp15_data_cache_invalidate(void)
613{
614  ARM_SWITCH_REGISTERS;
615  uint32_t sbz = 0;
616
617  __asm__ volatile (
618    ARM_SWITCH_TO_ARM
619    "mcr p15, 0, %[sbz], c7, c6, 0\n"
620    ARM_SWITCH_BACK
621    : ARM_SWITCH_OUTPUT
622    : [sbz] "r" (sbz)
623    : "memory"
624  );
625}
626
627static inline void arm_cp15_data_cache_invalidate_line(const void *mva)
628{
629  ARM_SWITCH_REGISTERS;
630
631  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
632
633  __asm__ volatile (
634    ARM_SWITCH_TO_ARM
635    "mcr p15, 0, %[mva], c7, c6, 1\n"
636    ARM_SWITCH_BACK
637    : ARM_SWITCH_OUTPUT
638    : [mva] "r" (mva)
639    : "memory"
640  );
641}
642
643static inline void arm_cp15_data_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
644{
645  ARM_SWITCH_REGISTERS;
646
647  __asm__ volatile (
648    ARM_SWITCH_TO_ARM
649    "mcr p15, 0, %[set_and_way], c7, c6, 2\n"
650    ARM_SWITCH_BACK
651    : ARM_SWITCH_OUTPUT
652    : [set_and_way] "r" (set_and_way)
653    : "memory"
654  );
655}
656
657static inline void arm_cp15_data_cache_clean_line(const void *mva)
658{
659  ARM_SWITCH_REGISTERS;
660
661  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
662
663  __asm__ volatile (
664    ARM_SWITCH_TO_ARM
665    "mcr p15, 0, %[mva], c7, c10, 1\n"
666    ARM_SWITCH_BACK
667    : ARM_SWITCH_OUTPUT
668    : [mva] "r" (mva)
669    : "memory"
670  );
671}
672
673static inline void arm_cp15_data_cache_clean_line_by_set_and_way(uint32_t set_and_way)
674{
675  ARM_SWITCH_REGISTERS;
676
677  __asm__ volatile (
678    ARM_SWITCH_TO_ARM
679    "mcr p15, 0, %[set_and_way], c7, c10, 2\n"
680    ARM_SWITCH_BACK
681    : ARM_SWITCH_OUTPUT
682    : [set_and_way] "r" (set_and_way)
683    : "memory"
684  );
685}
686
687static inline void arm_cp15_data_cache_test_and_clean(void)
688{
689  ARM_SWITCH_REGISTERS;
690
691  __asm__ volatile (
692    ARM_SWITCH_TO_ARM
693    "1:\n"
694    "mrc p15, 0, r15, c7, c10, 3\n"
695    "bne 1b\n"
696    ARM_SWITCH_BACK
697    : ARM_SWITCH_OUTPUT
698    :
699    : "memory"
700  );
701}
702
703/*      In DDI0301H_arm1176jzfs_r0p7_trm
704 *      'MCR p15, 0, <Rd>, c7, c14, 0' means
705 *      Clean and Invalidate Entire Data Cache
706 */
707static inline void arm_cp15_data_cache_clean_and_invalidate(void)
708{
709  ARM_SWITCH_REGISTERS;
710
711  uint32_t sbz = 0;
712
713  __asm__ volatile (
714    ARM_SWITCH_TO_ARM
715    "mcr p15, 0, %[sbz], c7, c14, 0\n"
716    ARM_SWITCH_BACK
717    : ARM_SWITCH_OUTPUT
718    : [sbz] "r" (sbz)
719    : "memory"
720  );
721
722}
723
724static inline void arm_cp15_data_cache_clean_and_invalidate_line(const void *mva)
725{
726  ARM_SWITCH_REGISTERS;
727
728  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
729
730  __asm__ volatile (
731    ARM_SWITCH_TO_ARM
732    "mcr p15, 0, %[mva], c7, c14, 1\n"
733    ARM_SWITCH_BACK
734    : ARM_SWITCH_OUTPUT
735    : [mva] "r" (mva)
736    : "memory"
737  );
738}
739
740static inline void arm_cp15_data_cache_clean_and_invalidate_line_by_set_and_way(uint32_t set_and_way)
741{
742  ARM_SWITCH_REGISTERS;
743
744  __asm__ volatile (
745    ARM_SWITCH_TO_ARM
746    "mcr p15, 0, %[set_and_way], c7, c14, 2\n"
747    ARM_SWITCH_BACK
748    : ARM_SWITCH_OUTPUT
749    : [set_and_way] "r" (set_and_way)
750    : "memory"
751  );
752}
753
754static inline void arm_cp15_data_cache_test_and_clean_and_invalidate(void)
755{
756  ARM_SWITCH_REGISTERS;
757
758  __asm__ volatile (
759    ARM_SWITCH_TO_ARM
760    "1:\n"
761    "mrc p15, 0, r15, c7, c14, 3\n"
762    "bne 1b\n"
763    ARM_SWITCH_BACK
764    : ARM_SWITCH_OUTPUT
765    :
766    : "memory"
767  );
768}
769
770/** @} */
771
772static inline void arm_cp15_drain_write_buffer(void)
773{
774  ARM_SWITCH_REGISTERS;
775  uint32_t sbz = 0;
776
777  __asm__ volatile (
778    ARM_SWITCH_TO_ARM
779    "mcr p15, 0, %[sbz], c7, c10, 4\n"
780    ARM_SWITCH_BACK
781    : ARM_SWITCH_OUTPUT
782    : [sbz] "r" (sbz)
783    : "memory"
784  );
785}
786
787static inline void arm_cp15_wait_for_interrupt(void)
788{
789  ARM_SWITCH_REGISTERS;
790  uint32_t sbz = 0;
791
792  __asm__ volatile (
793    ARM_SWITCH_TO_ARM
794    "mcr p15, 0, %[sbz], c7, c0, 4\n"
795    ARM_SWITCH_BACK
796    : ARM_SWITCH_OUTPUT
797    : [sbz] "r" (sbz)
798    : "memory"
799  );
800}
801
802/**
803 * @brief Sets the @a section_flags for the address range [@a begin, @a end).
804 *
805 * @return Previous section flags of the first modified entry.
806 */
807uint32_t arm_cp15_set_translation_table_entries(
808  const void *begin,
809  const void *end,
810  uint32_t section_flags
811);
812
813void arm_cp15_set_exception_handler(
814  Arm_symbolic_exception_name exception,
815  void (*handler)(void),
816  uint32_t section_flags_for_mirror_table_access
817);
818
819/** @} */
820
821#ifdef __cplusplus
822}
823#endif /* __cplusplus */
824
825#endif /* LIBCPU_SHARED_ARM_CP15_H */
Note: See TracBrowser for help on using the repository browser.