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

4.104.115
Last change on this file since 39c8fdb was 39c8fdb, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 01/12/10 at 15:03:22

add support for lpc32xx

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