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

4.104.11
Last change on this file since 5e657e2 was 5e657e2, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Apr 9, 2010 at 12:30:39 PM

Documentation. Fixed mask defines.

  • Property mode set to 100644
File size: 13.2 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, 2010
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.com/license/LICENSE.
20 */
21
22#ifndef LIBCPU_SHARED_ARM_CP15_H
23#define LIBCPU_SHARED_ARM_CP15_H
24
25#include <rtems.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif /* __cplusplus */
30
31#define ARM_CP15_CACHE_PREPARE_MVA(mva) \
32  ((const void *) (((uint32_t) (mva)) & ~0x1fU))
33
34#define ARM_CP15_TLB_PREPARE_MVA(mva) \
35  ((const void *) (((uint32_t) (mva)) & ~0x3fU))
36
37/**
38 * @defgroup ScoreCPUARMCP15 ARM Co-Processor 15 Support
39 *
40 * @ingroup ScoreCPUARM
41 *
42 * @brief ARM co-processor 15 (CP15) support.
43 *
44 * @{
45 */
46
47/**
48 * @name MMU Defines
49 *
50 * @{
51 */
52
53#define ARM_MMU_SECT_BASE_SHIFT 20
54#define ARM_MMU_SECT_BASE_MASK (0xfffU << ARM_MMU_SECT_BASE_SHIFT)
55#define ARM_MMU_SECT_DOMAIN_SHIFT 5
56#define ARM_MMU_SECT_DOMAIN_MASK (0xfU << ARM_MMU_SECT_DOMAIN_SHIFT)
57#define ARM_MMU_SECT_AP_1 (1U << 11)
58#define ARM_MMU_SECT_AP_0 (1U << 10)
59#define ARM_MMU_SECT_AP_SHIFT 10
60#define ARM_MMU_SECT_AP_MASK (0x3U << ARM_MMU_SECT_AP_SHIFT)
61#define ARM_MMU_SECT_C (1U << 3)
62#define ARM_MMU_SECT_B (1U << 2)
63#define ARM_MMU_SECT_DEFAULT 0x12U
64#define ARM_MMU_SECT_GET_INDEX(mva) \
65  (((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT)
66#define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \
67  ((1U << ARM_MMU_SECT_BASE_SHIFT) \
68    + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U)))
69
70#define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U
71#define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U
72
73/** @} */
74
75/**
76 * @name Control Register Defines
77 *
78 * @{
79 */
80
81#define ARM_CP15_CTRL_L4 (1U << 15)
82#define ARM_CP15_CTRL_RR (1U << 14)
83#define ARM_CP15_CTRL_V (1U << 13)
84#define ARM_CP15_CTRL_I (1U << 12)
85#define ARM_CP15_CTRL_R (1U << 9)
86#define ARM_CP15_CTRL_S (1U << 8)
87#define ARM_CP15_CTRL_B (1U << 7)
88#define ARM_CP15_CTRL_C (1U << 2)
89#define ARM_CP15_CTRL_A (1U << 1)
90#define ARM_CP15_CTRL_M (1U << 0)
91
92/** @} */
93
94/**
95 * @name Domain Access Control Defines
96 *
97 * @{
98 */
99
100#define ARM_CP15_DAC_NO_ACCESS 0x0U
101#define ARM_CP15_DAC_CLIENT 0x1U
102#define ARM_CP15_DAC_MANAGER 0x3U
103#define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index))
104
105/** @} */
106
107static inline uint32_t arm_cp15_get_id_code(void)
108{
109  ARM_SWITCH_REGISTERS;
110  uint32_t val;
111
112  asm volatile (
113    ARM_SWITCH_TO_ARM
114    "mrc p15, 0, %[val], c0, c0, 0\n"
115    ARM_SWITCH_BACK
116    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
117  );
118
119  return val;
120}
121
122static inline uint32_t arm_cp15_get_tcm_status(void)
123{
124  ARM_SWITCH_REGISTERS;
125  uint32_t val;
126
127  asm volatile (
128    ARM_SWITCH_TO_ARM
129    "mrc p15, 0, %[val], c0, c0, 2\n"
130    ARM_SWITCH_BACK
131    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
132  );
133
134  return val;
135}
136
137static inline uint32_t arm_cp15_get_control(void)
138{
139  ARM_SWITCH_REGISTERS;
140  uint32_t val;
141
142  asm volatile (
143    ARM_SWITCH_TO_ARM
144    "mrc p15, 0, %[val], c1, c0, 0\n"
145    ARM_SWITCH_BACK
146    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
147  );
148
149  return val;
150}
151
152static inline void arm_cp15_set_control(uint32_t val)
153{
154  ARM_SWITCH_REGISTERS;
155
156  asm volatile (
157    ARM_SWITCH_TO_ARM
158    "mcr p15, 0, %[val], c1, c0, 0\n"
159    "nop\n"
160    "nop\n"
161    ARM_SWITCH_BACK
162    : ARM_SWITCH_OUTPUT
163    : [val] "r" (val)
164    : "memory"
165  );
166}
167
168/**
169 * @name MMU Functions
170 *
171 * @{
172 */
173
174static inline uint32_t *arm_cp15_get_translation_table_base(void)
175{
176  ARM_SWITCH_REGISTERS;
177  uint32_t *base;
178
179  asm volatile (
180    ARM_SWITCH_TO_ARM
181    "mrc p15, 0, %[base], c2, c0, 0\n"
182    ARM_SWITCH_BACK
183    : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
184  );
185
186  return base;
187}
188
189static inline void arm_cp15_set_translation_table_base(uint32_t *base)
190{
191  ARM_SWITCH_REGISTERS;
192
193  asm volatile (
194    ARM_SWITCH_TO_ARM
195    "mcr p15, 0, %[base], c2, c0, 0\n"
196    ARM_SWITCH_BACK
197    : ARM_SWITCH_OUTPUT
198    : [base] "r" (base)
199  );
200}
201
202static inline uint32_t arm_cp15_get_domain_access_control(void)
203{
204  ARM_SWITCH_REGISTERS;
205  uint32_t val;
206
207  asm volatile (
208    ARM_SWITCH_TO_ARM
209    "mrc p15, 0, %[val], c3, c0, 0\n"
210    ARM_SWITCH_BACK
211    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
212  );
213
214  return val;
215}
216
217static inline void arm_cp15_set_domain_access_control(uint32_t val)
218{
219  ARM_SWITCH_REGISTERS;
220
221  asm volatile (
222    ARM_SWITCH_TO_ARM
223    "mcr p15, 0, %[val], c3, c0, 0\n"
224    ARM_SWITCH_BACK
225    : ARM_SWITCH_OUTPUT
226    : [val] "r" (val)
227  );
228}
229
230static inline uint32_t arm_cp15_get_data_fault_status(void)
231{
232  ARM_SWITCH_REGISTERS;
233  uint32_t val;
234
235  asm volatile (
236    ARM_SWITCH_TO_ARM
237    "mrc p15, 0, %[val], c5, c0, 0\n"
238    ARM_SWITCH_BACK
239    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
240  );
241
242  return val;
243}
244
245static inline void arm_cp15_set_data_fault_status(uint32_t val)
246{
247  ARM_SWITCH_REGISTERS;
248
249  asm volatile (
250    ARM_SWITCH_TO_ARM
251    "mcr p15, 0, %[val], c5, c0, 0\n"
252    ARM_SWITCH_BACK
253    : ARM_SWITCH_OUTPUT
254    : [val] "r" (val)
255  );
256}
257
258static inline uint32_t arm_cp15_get_instruction_fault_status(void)
259{
260  ARM_SWITCH_REGISTERS;
261  uint32_t val;
262
263  asm volatile (
264    ARM_SWITCH_TO_ARM
265    "mrc p15, 0, %[val], c5, c0, 1\n"
266    ARM_SWITCH_BACK
267    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
268  );
269
270  return val;
271}
272
273static inline void arm_cp15_set_instruction_fault_status(uint32_t val)
274{
275  ARM_SWITCH_REGISTERS;
276
277  asm volatile (
278    ARM_SWITCH_TO_ARM
279    "mcr p15, 0, %[val], c5, c0, 1\n"
280    ARM_SWITCH_BACK
281    : ARM_SWITCH_OUTPUT
282    : [val] "r" (val)
283  );
284}
285
286static inline void *arm_cp15_get_fault_address(void)
287{
288  ARM_SWITCH_REGISTERS;
289  void *mva;
290
291  asm volatile (
292    ARM_SWITCH_TO_ARM
293    "mrc p15, 0, %[mva], c6, c0, 0\n"
294    ARM_SWITCH_BACK
295    : [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT
296  );
297
298  return mva;
299}
300
301static inline void arm_cp15_set_fault_address(const void *mva)
302{
303  ARM_SWITCH_REGISTERS;
304
305  asm volatile (
306    ARM_SWITCH_TO_ARM
307    "mcr p15, 0, %[mva], c6, c0, 0\n"
308    ARM_SWITCH_BACK
309    : ARM_SWITCH_OUTPUT
310    : [mva] "r" (mva)
311  );
312}
313
314static inline void arm_cp15_tlb_invalidate(void)
315{
316  ARM_SWITCH_REGISTERS;
317  uint32_t sbz = 0;
318
319  asm volatile (
320    ARM_SWITCH_TO_ARM
321    "mcr p15, 0, %[sbz], c8, c7, 0\n"
322    ARM_SWITCH_BACK
323    : ARM_SWITCH_OUTPUT
324    : [sbz] "r" (sbz)
325  );
326}
327
328static inline void arm_cp15_tlb_invalidate_entry(const void *mva)
329{
330  ARM_SWITCH_REGISTERS;
331
332  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
333
334  asm volatile (
335    ARM_SWITCH_TO_ARM
336    "mcr p15, 0, %[mva], c8, c7, 1\n"
337    ARM_SWITCH_BACK
338    : ARM_SWITCH_OUTPUT
339    : [mva] "r" (mva)
340  );
341}
342
343static inline void arm_cp15_tlb_instruction_invalidate(void)
344{
345  ARM_SWITCH_REGISTERS;
346  uint32_t sbz = 0;
347
348  asm volatile (
349    ARM_SWITCH_TO_ARM
350    "mcr p15, 0, %[sbz], c8, c5, 0\n"
351    ARM_SWITCH_BACK
352    : ARM_SWITCH_OUTPUT
353    : [sbz] "r" (sbz)
354  );
355}
356
357static inline void arm_cp15_tlb_instruction_invalidate_entry(const void *mva)
358{
359  ARM_SWITCH_REGISTERS;
360
361  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
362
363  asm volatile (
364    ARM_SWITCH_TO_ARM
365    "mcr p15, 0, %[mva], c8, c5, 1\n"
366    ARM_SWITCH_BACK
367    : ARM_SWITCH_OUTPUT
368    : [mva] "r" (mva)
369  );
370}
371
372static inline void arm_cp15_tlb_data_invalidate(void)
373{
374  ARM_SWITCH_REGISTERS;
375  uint32_t sbz = 0;
376
377  asm volatile (
378    ARM_SWITCH_TO_ARM
379    "mcr p15, 0, %[sbz], c8, c6, 0\n"
380    ARM_SWITCH_BACK
381    : ARM_SWITCH_OUTPUT
382    : [sbz] "r" (sbz)
383  );
384}
385
386static inline void arm_cp15_tlb_data_invalidate_entry(const void *mva)
387{
388  ARM_SWITCH_REGISTERS;
389
390  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
391
392  asm volatile (
393    ARM_SWITCH_TO_ARM
394    "mcr p15, 0, %[mva], c8, c6, 1\n"
395    ARM_SWITCH_BACK
396    : ARM_SWITCH_OUTPUT
397    : [mva] "r" (mva)
398  );
399}
400
401static inline void arm_cp15_tlb_lockdown_entry(const void *mva)
402{
403  uint32_t arm_switch_reg;
404
405  asm volatile (
406    ARM_SWITCH_TO_ARM
407    "add %[arm_switch_reg], pc, #16\n"
408    "mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n"
409    "mcr p15, 0, %[mva], c8, c7, 1\n"
410    "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
411    "orr %[arm_switch_reg], #0x1\n"
412    "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
413    "ldr %[mva], [%[mva]]\n"
414    "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
415    "bic %[arm_switch_reg], #0x1\n"
416    "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
417    ARM_SWITCH_BACK
418    : [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg)
419    : "[mva]" (mva)
420  );
421}
422
423/** @} */
424
425/**
426 * @name Cache Functions
427 *
428 * @{
429 */
430
431static inline uint32_t arm_cp15_get_cache_type(void)
432{
433  ARM_SWITCH_REGISTERS;
434  uint32_t val;
435
436  asm volatile (
437    ARM_SWITCH_TO_ARM
438    "mrc p15, 0, %[val], c0, c0, 1\n"
439    ARM_SWITCH_BACK
440    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
441  );
442
443  return val;
444}
445
446static inline void arm_cp15_cache_invalidate(void)
447{
448  ARM_SWITCH_REGISTERS;
449  uint32_t sbz = 0;
450
451  asm volatile (
452    ARM_SWITCH_TO_ARM
453    "mcr p15, 0, %[sbz], c7, c7, 0\n"
454    ARM_SWITCH_BACK
455    : ARM_SWITCH_OUTPUT
456    : [sbz] "r" (sbz)
457    : "memory"
458  );
459}
460
461static inline void arm_cp15_instruction_cache_invalidate(void)
462{
463  ARM_SWITCH_REGISTERS;
464  uint32_t sbz = 0;
465
466  asm volatile (
467    ARM_SWITCH_TO_ARM
468    "mcr p15, 0, %[sbz], c7, c5, 0\n"
469    ARM_SWITCH_BACK
470    : ARM_SWITCH_OUTPUT
471    : [sbz] "r" (sbz)
472    : "memory"
473  );
474}
475
476static inline void arm_cp15_instruction_cache_invalidate_line(const void *mva)
477{
478  ARM_SWITCH_REGISTERS;
479
480  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
481
482  asm volatile (
483    ARM_SWITCH_TO_ARM
484    "mcr p15, 0, %[mva], c7, c5, 1\n"
485    ARM_SWITCH_BACK
486    : ARM_SWITCH_OUTPUT
487    : [mva] "r" (mva)
488    : "memory"
489  );
490}
491
492static inline void arm_cp15_instruction_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
493{
494  ARM_SWITCH_REGISTERS;
495
496  asm volatile (
497    ARM_SWITCH_TO_ARM
498    "mcr p15, 0, %[set_and_way], c7, c5, 2\n"
499    ARM_SWITCH_BACK
500    : ARM_SWITCH_OUTPUT
501    : [set_and_way] "r" (set_and_way)
502    : "memory"
503  );
504}
505
506static inline void arm_cp15_instruction_cache_prefetch_line(const void *mva)
507{
508  ARM_SWITCH_REGISTERS;
509
510  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
511
512  asm volatile (
513    ARM_SWITCH_TO_ARM
514    "mcr p15, 0, %[mva], c7, c13, 1\n"
515    ARM_SWITCH_BACK
516    : ARM_SWITCH_OUTPUT
517    : [mva] "r" (mva)
518  );
519}
520
521static inline void arm_cp15_data_cache_invalidate(void)
522{
523  ARM_SWITCH_REGISTERS;
524  uint32_t sbz = 0;
525
526  asm volatile (
527    ARM_SWITCH_TO_ARM
528    "mcr p15, 0, %[sbz], c7, c6, 0\n"
529    ARM_SWITCH_BACK
530    : ARM_SWITCH_OUTPUT
531    : [sbz] "r" (sbz)
532    : "memory"
533  );
534}
535
536static inline void arm_cp15_data_cache_invalidate_line(const void *mva)
537{
538  ARM_SWITCH_REGISTERS;
539
540  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
541
542  asm volatile (
543    ARM_SWITCH_TO_ARM
544    "mcr p15, 0, %[mva], c7, c6, 1\n"
545    ARM_SWITCH_BACK
546    : ARM_SWITCH_OUTPUT
547    : [mva] "r" (mva)
548    : "memory"
549  );
550}
551
552static inline void arm_cp15_data_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
553{
554  ARM_SWITCH_REGISTERS;
555
556  asm volatile (
557    ARM_SWITCH_TO_ARM
558    "mcr p15, 0, %[set_and_way], c7, c6, 2\n"
559    ARM_SWITCH_BACK
560    : ARM_SWITCH_OUTPUT
561    : [set_and_way] "r" (set_and_way)
562    : "memory"
563  );
564}
565
566static inline void arm_cp15_data_cache_clean_line(const void *mva)
567{
568  ARM_SWITCH_REGISTERS;
569
570  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
571
572  asm volatile (
573    ARM_SWITCH_TO_ARM
574    "mcr p15, 0, %[mva], c7, c10, 1\n"
575    ARM_SWITCH_BACK
576    : ARM_SWITCH_OUTPUT
577    : [mva] "r" (mva)
578    : "memory"
579  );
580}
581
582static inline void arm_cp15_data_cache_clean_line_by_set_and_way(uint32_t set_and_way)
583{
584  ARM_SWITCH_REGISTERS;
585
586  asm volatile (
587    ARM_SWITCH_TO_ARM
588    "mcr p15, 0, %[set_and_way], c7, c10, 2\n"
589    ARM_SWITCH_BACK
590    : ARM_SWITCH_OUTPUT
591    : [set_and_way] "r" (set_and_way)
592    : "memory"
593  );
594}
595
596static inline void arm_cp15_data_cache_test_and_clean(void)
597{
598  ARM_SWITCH_REGISTERS;
599
600  asm volatile (
601    ARM_SWITCH_TO_ARM
602    "1:\n"
603    "mrc p15, 0, r15, c7, c10, 3\n"
604    "bne 1b\n"
605    ARM_SWITCH_BACK
606    : ARM_SWITCH_OUTPUT
607    :
608    : "memory"
609  );
610}
611
612static inline void arm_cp15_data_cache_clean_and_invalidate_line(const void *mva)
613{
614  ARM_SWITCH_REGISTERS;
615
616  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
617
618  asm volatile (
619    ARM_SWITCH_TO_ARM
620    "mcr p15, 0, %[mva], c7, c14, 1\n"
621    ARM_SWITCH_BACK
622    : ARM_SWITCH_OUTPUT
623    : [mva] "r" (mva)
624    : "memory"
625  );
626}
627
628static inline void arm_cp15_data_cache_clean_and_invalidate_line_by_set_and_way(uint32_t set_and_way)
629{
630  ARM_SWITCH_REGISTERS;
631
632  asm volatile (
633    ARM_SWITCH_TO_ARM
634    "mcr p15, 0, %[set_and_way], c7, c14, 2\n"
635    ARM_SWITCH_BACK
636    : ARM_SWITCH_OUTPUT
637    : [set_and_way] "r" (set_and_way)
638    : "memory"
639  );
640}
641
642static inline void arm_cp15_data_cache_test_and_clean_and_invalidate(void)
643{
644  ARM_SWITCH_REGISTERS;
645
646  asm volatile (
647    ARM_SWITCH_TO_ARM
648    "1:\n"
649    "mrc p15, 0, r15, c7, c14, 3\n"
650    "bne 1b\n"
651    ARM_SWITCH_BACK
652    : ARM_SWITCH_OUTPUT
653    :
654    : "memory"
655  );
656}
657
658/** @} */
659
660static inline void arm_cp15_drain_write_buffer(void)
661{
662  ARM_SWITCH_REGISTERS;
663  uint32_t sbz = 0;
664
665  asm volatile (
666    ARM_SWITCH_TO_ARM
667    "mcr p15, 0, %[sbz], c7, c10, 4\n"
668    ARM_SWITCH_BACK
669    : ARM_SWITCH_OUTPUT
670    : [sbz] "r" (sbz)
671    : "memory"
672  );
673}
674
675static inline void arm_cp15_wait_for_interrupt(void)
676{
677  ARM_SWITCH_REGISTERS;
678  uint32_t sbz = 0;
679
680  asm volatile (
681    ARM_SWITCH_TO_ARM
682    "mcr p15, 0, %[sbz], c7, c0, 4\n"
683    ARM_SWITCH_BACK
684    : ARM_SWITCH_OUTPUT
685    : [sbz] "r" (sbz)
686    : "memory"
687  );
688}
689
690/** @} */
691
692#ifdef __cplusplus
693}
694#endif /* __cplusplus */
695
696#endif /* LIBCPU_SHARED_ARM_CP15_H */
Note: See TracBrowser for help on using the repository browser.