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

4.115
Last change on this file since 544615d was 544615d, checked in by Sebastian Huber <sebastian.huber@…>, on 05/02/13 at 15:41:11

bsps/arm: Add arm_cp15_mmu_disable()

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