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

4.115
Last change on this file since eba0626 was eba0626, checked in by Sebastian Huber <sebastian.huber@…>, on 12/18/13 at 10:47:07

bsps/arm: Use Normal memory for code and data

  • Property mode set to 100644
File size: 22.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreCPUARMCP15
5 *
6 * @brief ARM co-processor 15 (CP15) API.
7 */
8
9/*
10 * Copyright (c) 2013 Hesham AL-Matary
11 * Copyright (c) 2009-2013 embedded brains GmbH.  All rights reserved.
12 *
13 *  embedded brains GmbH
14 *  Dornierstr. 4
15 *  82178 Puchheim
16 *  Germany
17 *  <info@embedded-brains.de>
18 *
19 * The license and distribution terms for this file may be
20 * found in the file LICENSE in this distribution or at
21 * http://www.rtems.com/license/LICENSE.
22 */
23
24#ifndef LIBCPU_SHARED_ARM_CP15_H
25#define LIBCPU_SHARED_ARM_CP15_H
26
27#include <rtems.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif /* __cplusplus */
32
33#define ARM_CP15_CACHE_PREPARE_MVA(mva) \
34  ((const void *) (((uint32_t) (mva)) & ~0x1fU))
35
36#define ARM_CP15_TLB_PREPARE_MVA(mva) \
37  ((const void *) (((uint32_t) (mva)) & ~0x3fU))
38
39/**
40 * @defgroup ScoreCPUARMCP15 ARM Co-Processor 15 Support
41 *
42 * @ingroup ScoreCPUARM
43 *
44 * @brief ARM co-processor 15 (CP15) support.
45 *
46 * @{
47 */
48
49/**
50 * @name MMU Defines
51 *
52 * See section B3.8.2, "Short-descriptor format memory region attributes,
53 * without TEX remap" in the "ARM Architecture Reference Manual ARMv7-A and
54 * ARMv7-R edition".
55 *
56 * @{
57 */
58
59#define ARM_MMU_SECT_BASE_SHIFT 20
60#define ARM_MMU_SECT_BASE_MASK (0xfffU << ARM_MMU_SECT_BASE_SHIFT)
61#define ARM_MMU_SECT_NS (1U << 19)
62#define ARM_MMU_SECT_NG (1U << 17)
63#define ARM_MMU_SECT_S (1U << 16)
64#define ARM_MMU_SECT_AP_2 (1U << 15)
65#define ARM_MMU_SECT_TEX_2 (1U << 14)
66#define ARM_MMU_SECT_TEX_1 (1U << 13)
67#define ARM_MMU_SECT_TEX_0 (1U << 12)
68#define ARM_MMU_SECT_TEX_SHIFT 12
69#define ARM_MMU_SECT_TEX_MASK (0x3U << ARM_MMU_SECT_TEX_SHIFT)
70#define ARM_MMU_SECT_AP_1 (1U << 11)
71#define ARM_MMU_SECT_AP_0 (1U << 10)
72#define ARM_MMU_SECT_AP_SHIFT 10
73#define ARM_MMU_SECT_AP_MASK (0x23U << ARM_MMU_SECT_AP_SHIFT)
74#define ARM_MMU_SECT_DOMAIN_SHIFT 5
75#define ARM_MMU_SECT_DOMAIN_MASK (0xfU << ARM_MMU_SECT_DOMAIN_SHIFT)
76#define ARM_MMU_SECT_XN (1U << 4)
77#define ARM_MMU_SECT_C (1U << 3)
78#define ARM_MMU_SECT_B (1U << 2)
79#define ARM_MMU_SECT_PXN (1U << 0)
80#define ARM_MMU_SECT_DEFAULT 0x2U
81#define ARM_MMU_SECT_GET_INDEX(mva) \
82  (((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT)
83#define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \
84  ((1U << ARM_MMU_SECT_BASE_SHIFT) \
85    + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U)))
86
87#define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U
88#define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U
89
90#define ARM_MMU_DEFAULT_CLIENT_DOMAIN 15U
91
92#define ARMV7_MMU_READ_ONLY \
93  ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
94    | ARM_MMU_SECT_AP_0 \
95    | ARM_MMU_SECT_AP_2 \
96    | ARM_MMU_SECT_DEFAULT)
97
98#define ARMV7_MMU_READ_ONLY_CACHED \
99  (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
100
101#define ARMV7_MMU_READ_WRITE \
102  ((ARM_MMU_DEFAULT_CLIENT_DOMAIN << ARM_MMU_SECT_DOMAIN_SHIFT) \
103    | ARM_MMU_SECT_AP_0 \
104    | ARM_MMU_SECT_DEFAULT)
105
106#ifdef RTEMS_SMP
107  #define ARMV7_MMU_READ_WRITE_CACHED \
108    (ARMV7_MMU_READ_WRITE \
109      | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B | ARM_MMU_SECT_S)
110#else
111  #define ARMV7_MMU_READ_WRITE_CACHED \
112    (ARMV7_MMU_READ_WRITE \
113      | ARM_MMU_SECT_TEX_0 | ARM_MMU_SECT_C | ARM_MMU_SECT_B)
114#endif
115
116#define ARMV7_MMU_DATA_READ_ONLY \
117  (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
118
119#define ARMV7_MMU_DATA_READ_ONLY_CACHED \
120  ARMV7_MMU_READ_ONLY_CACHED
121
122#define ARMV7_MMU_DATA_READ_WRITE \
123  (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_TEX_0)
124
125#define ARMV7_MMU_DATA_READ_WRITE_CACHED \
126  ARMV7_MMU_READ_WRITE_CACHED
127
128#define ARMV7_MMU_CODE \
129  (ARMV7_MMU_READ_ONLY | ARM_MMU_SECT_TEX_0)
130
131#define ARMV7_MMU_CODE_CACHED \
132  ARMV7_MMU_READ_ONLY_CACHED
133
134#define ARMV7_MMU_DEVICE \
135  (ARMV7_MMU_READ_WRITE | ARM_MMU_SECT_B)
136
137/** @} */
138
139/**
140 * @name Control Register Defines
141 *
142 * @{
143 */
144
145#define ARM_CP15_CTRL_TE (1U << 30)
146#define ARM_CP15_CTRL_AFE (1U << 29)
147#define ARM_CP15_CTRL_TRE (1U << 28)
148#define ARM_CP15_CTRL_NMFI (1U << 27)
149#define ARM_CP15_CTRL_EE (1U << 25)
150#define ARM_CP15_CTRL_VE (1U << 24)
151#define ARM_CP15_CTRL_XP (1U << 23)
152#define ARM_CP15_CTRL_U (1U << 22)
153#define ARM_CP15_CTRL_FI (1U << 21)
154#define ARM_CP15_CTRL_UWXN (1U << 20)
155#define ARM_CP15_CTRL_WXN (1U << 19)
156#define ARM_CP15_CTRL_HA (1U << 17)
157#define ARM_CP15_CTRL_L4 (1U << 15)
158#define ARM_CP15_CTRL_RR (1U << 14)
159#define ARM_CP15_CTRL_V (1U << 13)
160#define ARM_CP15_CTRL_I (1U << 12)
161#define ARM_CP15_CTRL_Z (1U << 11)
162#define ARM_CP15_CTRL_SW (1U << 10)
163#define ARM_CP15_CTRL_R (1U << 9)
164#define ARM_CP15_CTRL_S (1U << 8)
165#define ARM_CP15_CTRL_B (1U << 7)
166#define ARM_CP15_CTRL_CP15BEN (1U << 5)
167#define ARM_CP15_CTRL_C (1U << 2)
168#define ARM_CP15_CTRL_A (1U << 1)
169#define ARM_CP15_CTRL_M (1U << 0)
170
171/** @} */
172
173/**
174 * @name Domain Access Control Defines
175 *
176 * @{
177 */
178
179#define ARM_CP15_DAC_NO_ACCESS 0x0U
180#define ARM_CP15_DAC_CLIENT 0x1U
181#define ARM_CP15_DAC_MANAGER 0x3U
182#define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index))
183
184/** @} */
185
186/**
187 * @name Fault Status Register Defines
188 *
189 * @{
190 */
191
192#define ARM_CP15_FAULT_STATUS_MASK 0x040F
193
194#define ARM_CP15_FSR_ALIGNMENT_FAULT   0x00000001
195#define ARM_CP15_FSR_BACKGROUND_FAULT  0x0000
196#define ARM_CP15_FSR_ACCESS_PERMISSION_FAULT 0x000D
197#define ARM_CP15_FSR_PRECISE_EXTERNAL_ABORT_FAULT 0x0008
198#define ARM_CP15_FSR_IMPRECISE_EXTERNAL_ABORT_FAULT 0x0406
199#define ARM_CP15_FSR_PRECISE_PARITY_ERROR_EXCEPTION 0x0006
200#define ARM_CP15_FSR_IMPRECISE_PARITY_ERROR_EXCEPTION 0x0408
201#define ARM_CP15_FSR_DEBUG_EVENT 0x0002
202
203/** @} */
204
205static inline uint32_t arm_cp15_get_id_code(void)
206{
207  ARM_SWITCH_REGISTERS;
208  uint32_t val;
209
210  __asm__ volatile (
211    ARM_SWITCH_TO_ARM
212    "mrc p15, 0, %[val], c0, c0, 0\n"
213    ARM_SWITCH_BACK
214    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
215  );
216
217  return val;
218}
219
220static inline uint32_t arm_cp15_get_tcm_status(void)
221{
222  ARM_SWITCH_REGISTERS;
223  uint32_t val;
224
225  __asm__ volatile (
226    ARM_SWITCH_TO_ARM
227    "mrc p15, 0, %[val], c0, c0, 2\n"
228    ARM_SWITCH_BACK
229    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
230  );
231
232  return val;
233}
234
235static inline uint32_t arm_cp15_get_control(void)
236{
237  ARM_SWITCH_REGISTERS;
238  uint32_t val;
239
240  __asm__ volatile (
241    ARM_SWITCH_TO_ARM
242    "mrc p15, 0, %[val], c1, c0, 0\n"
243    ARM_SWITCH_BACK
244    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
245  );
246
247  return val;
248}
249
250static inline void arm_cp15_set_control(uint32_t val)
251{
252  ARM_SWITCH_REGISTERS;
253
254  __asm__ volatile (
255    ARM_SWITCH_TO_ARM
256    "mcr p15, 0, %[val], c1, c0, 0\n"
257    "nop\n"
258    "nop\n"
259    ARM_SWITCH_BACK
260    : ARM_SWITCH_OUTPUT
261    : [val] "r" (val)
262    : "memory"
263  );
264}
265
266/**
267 * @name MMU Functions
268 *
269 * @{
270 */
271
272/**
273 * @brief Disable the MMU.
274 *
275 * This function will clean and invalidate eight cache lines before and after
276 * the current stack pointer.
277 *
278 * @param[in] cls The data cache line size.
279 *
280 * @return The current control register value.
281 */
282static inline uint32_t arm_cp15_mmu_disable(uint32_t cls)
283{
284  ARM_SWITCH_REGISTERS;
285  uint32_t ctrl;
286  uint32_t tmp_0;
287  uint32_t tmp_1;
288
289  __asm__ volatile (
290    ARM_SWITCH_TO_ARM
291    "mrc p15, 0, %[ctrl], c1, c0, 0\n"
292    "bic %[tmp_0], %[ctrl], #1\n"
293    "mcr p15, 0, %[tmp_0], c1, c0, 0\n"
294    "nop\n"
295    "nop\n"
296    "mov %[tmp_1], sp\n"
297    "rsb %[tmp_0], %[cls], #0\n"
298    "and %[tmp_0], %[tmp_0], %[tmp_1]\n"
299    "sub %[tmp_0], %[tmp_0], %[cls], asl #3\n"
300    "add %[tmp_1], %[tmp_0], %[cls], asl #4\n"
301    "1:\n"
302    "mcr p15, 0, %[tmp_0], c7, c14, 1\n"
303    "add %[tmp_0], %[tmp_0], %[cls]\n"
304    "cmp %[tmp_1], %[tmp_0]\n"
305    "bne 1b\n"
306    ARM_SWITCH_BACK
307    : [ctrl] "=&r" (ctrl),
308      [tmp_0] "=&r" (tmp_0),
309      [tmp_1] "=&r" (tmp_1)
310      ARM_SWITCH_ADDITIONAL_OUTPUT
311    : [cls] "r" (cls)
312    : "memory", "cc"
313  );
314
315  return ctrl;
316}
317
318static inline uint32_t *arm_cp15_get_translation_table_base(void)
319{
320  ARM_SWITCH_REGISTERS;
321  uint32_t *base;
322
323  __asm__ volatile (
324    ARM_SWITCH_TO_ARM
325    "mrc p15, 0, %[base], c2, c0, 0\n"
326    ARM_SWITCH_BACK
327    : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
328  );
329
330  return base;
331}
332
333static inline void arm_cp15_set_translation_table_base(uint32_t *base)
334{
335  ARM_SWITCH_REGISTERS;
336
337  __asm__ volatile (
338    ARM_SWITCH_TO_ARM
339    "mcr p15, 0, %[base], c2, c0, 0\n"
340    ARM_SWITCH_BACK
341    : ARM_SWITCH_OUTPUT
342    : [base] "r" (base)
343  );
344}
345
346static inline uint32_t arm_cp15_get_domain_access_control(void)
347{
348  ARM_SWITCH_REGISTERS;
349  uint32_t val;
350
351  __asm__ volatile (
352    ARM_SWITCH_TO_ARM
353    "mrc p15, 0, %[val], c3, c0, 0\n"
354    ARM_SWITCH_BACK
355    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
356  );
357
358  return val;
359}
360
361static inline void arm_cp15_set_domain_access_control(uint32_t val)
362{
363  ARM_SWITCH_REGISTERS;
364
365  __asm__ volatile (
366    ARM_SWITCH_TO_ARM
367    "mcr p15, 0, %[val], c3, c0, 0\n"
368    ARM_SWITCH_BACK
369    : ARM_SWITCH_OUTPUT
370    : [val] "r" (val)
371  );
372}
373
374static inline uint32_t arm_cp15_get_data_fault_status(void)
375{
376  ARM_SWITCH_REGISTERS;
377  uint32_t val;
378
379  __asm__ volatile (
380    ARM_SWITCH_TO_ARM
381    "mrc p15, 0, %[val], c5, c0, 0\n"
382    ARM_SWITCH_BACK
383    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
384  );
385
386  return val;
387}
388
389static inline void arm_cp15_set_data_fault_status(uint32_t val)
390{
391  ARM_SWITCH_REGISTERS;
392
393  __asm__ volatile (
394    ARM_SWITCH_TO_ARM
395    "mcr p15, 0, %[val], c5, c0, 0\n"
396    ARM_SWITCH_BACK
397    : ARM_SWITCH_OUTPUT
398    : [val] "r" (val)
399  );
400}
401
402static inline uint32_t arm_cp15_get_instruction_fault_status(void)
403{
404  ARM_SWITCH_REGISTERS;
405  uint32_t val;
406
407  __asm__ volatile (
408    ARM_SWITCH_TO_ARM
409    "mrc p15, 0, %[val], c5, c0, 1\n"
410    ARM_SWITCH_BACK
411    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
412  );
413
414  return val;
415}
416
417static inline void arm_cp15_set_instruction_fault_status(uint32_t val)
418{
419  ARM_SWITCH_REGISTERS;
420
421  __asm__ volatile (
422    ARM_SWITCH_TO_ARM
423    "mcr p15, 0, %[val], c5, c0, 1\n"
424    ARM_SWITCH_BACK
425    : ARM_SWITCH_OUTPUT
426    : [val] "r" (val)
427  );
428}
429
430static inline void *arm_cp15_get_fault_address(void)
431{
432  ARM_SWITCH_REGISTERS;
433  void *mva;
434
435  __asm__ volatile (
436    ARM_SWITCH_TO_ARM
437    "mrc p15, 0, %[mva], c6, c0, 0\n"
438    ARM_SWITCH_BACK
439    : [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT
440  );
441
442  return mva;
443}
444
445static inline void arm_cp15_set_fault_address(const void *mva)
446{
447  ARM_SWITCH_REGISTERS;
448
449  __asm__ volatile (
450    ARM_SWITCH_TO_ARM
451    "mcr p15, 0, %[mva], c6, c0, 0\n"
452    ARM_SWITCH_BACK
453    : ARM_SWITCH_OUTPUT
454    : [mva] "r" (mva)
455  );
456}
457
458static inline void arm_cp15_tlb_invalidate(void)
459{
460  ARM_SWITCH_REGISTERS;
461  uint32_t sbz = 0;
462
463  __asm__ volatile (
464    ARM_SWITCH_TO_ARM
465    "mcr p15, 0, %[sbz], c8, c7, 0\n"
466    ARM_SWITCH_BACK
467    : ARM_SWITCH_OUTPUT
468    : [sbz] "r" (sbz)
469  );
470}
471
472static inline void arm_cp15_tlb_invalidate_entry(const void *mva)
473{
474  ARM_SWITCH_REGISTERS;
475
476  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
477
478  __asm__ volatile (
479    ARM_SWITCH_TO_ARM
480    "mcr p15, 0, %[mva], c8, c7, 1\n"
481    ARM_SWITCH_BACK
482    : ARM_SWITCH_OUTPUT
483    : [mva] "r" (mva)
484  );
485}
486
487static inline void arm_cp15_tlb_instruction_invalidate(void)
488{
489  ARM_SWITCH_REGISTERS;
490  uint32_t sbz = 0;
491
492  __asm__ volatile (
493    ARM_SWITCH_TO_ARM
494    "mcr p15, 0, %[sbz], c8, c5, 0\n"
495    ARM_SWITCH_BACK
496    : ARM_SWITCH_OUTPUT
497    : [sbz] "r" (sbz)
498  );
499}
500
501static inline void arm_cp15_tlb_instruction_invalidate_entry(const void *mva)
502{
503  ARM_SWITCH_REGISTERS;
504
505  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
506
507  __asm__ volatile (
508    ARM_SWITCH_TO_ARM
509    "mcr p15, 0, %[mva], c8, c5, 1\n"
510    ARM_SWITCH_BACK
511    : ARM_SWITCH_OUTPUT
512    : [mva] "r" (mva)
513  );
514}
515
516static inline void arm_cp15_tlb_data_invalidate(void)
517{
518  ARM_SWITCH_REGISTERS;
519  uint32_t sbz = 0;
520
521  __asm__ volatile (
522    ARM_SWITCH_TO_ARM
523    "mcr p15, 0, %[sbz], c8, c6, 0\n"
524    ARM_SWITCH_BACK
525    : ARM_SWITCH_OUTPUT
526    : [sbz] "r" (sbz)
527  );
528}
529
530static inline void arm_cp15_tlb_data_invalidate_entry(const void *mva)
531{
532  ARM_SWITCH_REGISTERS;
533
534  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
535
536  __asm__ volatile (
537    ARM_SWITCH_TO_ARM
538    "mcr p15, 0, %[mva], c8, c6, 1\n"
539    ARM_SWITCH_BACK
540    : ARM_SWITCH_OUTPUT
541    : [mva] "r" (mva)
542  );
543}
544
545static inline void arm_cp15_tlb_lockdown_entry(const void *mva)
546{
547  uint32_t arm_switch_reg;
548
549  __asm__ volatile (
550    ARM_SWITCH_TO_ARM
551    "add %[arm_switch_reg], pc, #16\n"
552    "mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n"
553    "mcr p15, 0, %[mva], c8, c7, 1\n"
554    "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
555    "orr %[arm_switch_reg], #0x1\n"
556    "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
557    "ldr %[mva], [%[mva]]\n"
558    "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
559    "bic %[arm_switch_reg], #0x1\n"
560    "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
561    ARM_SWITCH_BACK
562    : [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg)
563    : "[mva]" (mva)
564  );
565}
566
567/** @} */
568
569/**
570 * @name Cache Functions
571 *
572 * @{
573 */
574
575static inline uint32_t arm_cp15_get_cache_type(void)
576{
577  ARM_SWITCH_REGISTERS;
578  uint32_t val;
579
580  __asm__ volatile (
581    ARM_SWITCH_TO_ARM
582    "mrc p15, 0, %[val], c0, c0, 1\n"
583    ARM_SWITCH_BACK
584    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
585  );
586
587  return val;
588}
589
590static inline uint32_t arm_cp15_get_min_cache_line_size(void)
591{
592  uint32_t mcls = 0;
593  uint32_t ct = arm_cp15_get_cache_type();
594  uint32_t format = (ct >> 29) & 0x7U;
595
596  if (format == 0x4) {
597    mcls = (1U << (ct & 0xf)) * 4;
598  } else if (format == 0x0) {
599    uint32_t mask = (1U << 12) - 1;
600    uint32_t dcls = (ct >> 12) & mask;
601    uint32_t icls = ct & mask;
602
603    mcls = dcls <= icls ? dcls : icls;
604  }
605
606  return mcls;
607}
608
609/* CCSIDR, Cache Size ID Register */
610
611static inline uint32_t arm_cp15_get_cache_size_id(void)
612{
613  ARM_SWITCH_REGISTERS;
614  uint32_t val;
615
616  __asm__ volatile (
617    ARM_SWITCH_TO_ARM
618    "mrc p15, 1, %[val], c0, c0, 0\n"
619     ARM_SWITCH_BACK
620    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
621  );
622
623  return val;
624}
625
626/* CLIDR, Cache Level ID Register */
627
628static inline uint32_t arm_cp15_get_cache_level_id(void)
629{
630  ARM_SWITCH_REGISTERS;
631  uint32_t val;
632
633  __asm__ volatile (
634    ARM_SWITCH_TO_ARM
635    "mrc p15, 1, %[val], c0, c0, 1\n"
636     ARM_SWITCH_BACK
637    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
638  );
639
640  return val;
641}
642
643/* CSSELR, Cache Size Selection Register */
644
645static inline uint32_t arm_cp15_get_cache_size_selection(void)
646{
647  ARM_SWITCH_REGISTERS;
648  uint32_t val;
649
650  __asm__ volatile (
651    ARM_SWITCH_TO_ARM
652    "mrc p15, 2, %[val], c0, c0, 0\n"
653     ARM_SWITCH_BACK
654    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
655  );
656
657  return val;
658}
659
660static inline void arm_cp15_set_cache_size_selection(uint32_t val)
661{
662  ARM_SWITCH_REGISTERS;
663
664  __asm__ volatile (
665    ARM_SWITCH_TO_ARM
666    "mcr p15, 2, %[val], c0, c0, 0\n"
667     ARM_SWITCH_BACK
668    : ARM_SWITCH_OUTPUT
669    : [val] "r" (val)
670    : "memory"
671  );
672}
673
674static inline void arm_cp15_cache_invalidate(void)
675{
676  ARM_SWITCH_REGISTERS;
677  uint32_t sbz = 0;
678
679  __asm__ volatile (
680    ARM_SWITCH_TO_ARM
681    "mcr p15, 0, %[sbz], c7, c7, 0\n"
682    ARM_SWITCH_BACK
683    : ARM_SWITCH_OUTPUT
684    : [sbz] "r" (sbz)
685    : "memory"
686  );
687}
688
689static inline void arm_cp15_instruction_cache_invalidate(void)
690{
691  ARM_SWITCH_REGISTERS;
692  uint32_t sbz = 0;
693
694  __asm__ volatile (
695    ARM_SWITCH_TO_ARM
696    "mcr p15, 0, %[sbz], c7, c5, 0\n"
697    ARM_SWITCH_BACK
698    : ARM_SWITCH_OUTPUT
699    : [sbz] "r" (sbz)
700    : "memory"
701  );
702}
703
704static inline void arm_cp15_instruction_cache_invalidate_line(const void *mva)
705{
706  ARM_SWITCH_REGISTERS;
707
708  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
709
710  __asm__ volatile (
711    ARM_SWITCH_TO_ARM
712    "mcr p15, 0, %[mva], c7, c5, 1\n"
713    ARM_SWITCH_BACK
714    : ARM_SWITCH_OUTPUT
715    : [mva] "r" (mva)
716    : "memory"
717  );
718}
719
720static inline void arm_cp15_instruction_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
721{
722  ARM_SWITCH_REGISTERS;
723
724  __asm__ volatile (
725    ARM_SWITCH_TO_ARM
726    "mcr p15, 0, %[set_and_way], c7, c5, 2\n"
727    ARM_SWITCH_BACK
728    : ARM_SWITCH_OUTPUT
729    : [set_and_way] "r" (set_and_way)
730    : "memory"
731  );
732}
733
734static inline void arm_cp15_instruction_cache_prefetch_line(const void *mva)
735{
736  ARM_SWITCH_REGISTERS;
737
738  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
739
740  __asm__ volatile (
741    ARM_SWITCH_TO_ARM
742    "mcr p15, 0, %[mva], c7, c13, 1\n"
743    ARM_SWITCH_BACK
744    : ARM_SWITCH_OUTPUT
745    : [mva] "r" (mva)
746  );
747}
748
749static inline void arm_cp15_data_cache_invalidate(void)
750{
751  ARM_SWITCH_REGISTERS;
752  uint32_t sbz = 0;
753
754  __asm__ volatile (
755    ARM_SWITCH_TO_ARM
756    "mcr p15, 0, %[sbz], c7, c6, 0\n"
757    ARM_SWITCH_BACK
758    : ARM_SWITCH_OUTPUT
759    : [sbz] "r" (sbz)
760    : "memory"
761  );
762}
763
764static inline void arm_cp15_data_cache_invalidate_line(const void *mva)
765{
766  ARM_SWITCH_REGISTERS;
767
768  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
769
770  __asm__ volatile (
771    ARM_SWITCH_TO_ARM
772    "mcr p15, 0, %[mva], c7, c6, 1\n"
773    ARM_SWITCH_BACK
774    : ARM_SWITCH_OUTPUT
775    : [mva] "r" (mva)
776    : "memory"
777  );
778}
779
780static inline void arm_cp15_data_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
781{
782  ARM_SWITCH_REGISTERS;
783
784  __asm__ volatile (
785    ARM_SWITCH_TO_ARM
786    "mcr p15, 0, %[set_and_way], c7, c6, 2\n"
787    ARM_SWITCH_BACK
788    : ARM_SWITCH_OUTPUT
789    : [set_and_way] "r" (set_and_way)
790    : "memory"
791  );
792}
793
794static inline void arm_cp15_data_cache_clean_line(const void *mva)
795{
796  ARM_SWITCH_REGISTERS;
797
798  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
799
800  __asm__ volatile (
801    ARM_SWITCH_TO_ARM
802    "mcr p15, 0, %[mva], c7, c10, 1\n"
803    ARM_SWITCH_BACK
804    : ARM_SWITCH_OUTPUT
805    : [mva] "r" (mva)
806    : "memory"
807  );
808}
809
810static inline void arm_cp15_data_cache_clean_line_by_set_and_way(uint32_t set_and_way)
811{
812  ARM_SWITCH_REGISTERS;
813
814  __asm__ volatile (
815    ARM_SWITCH_TO_ARM
816    "mcr p15, 0, %[set_and_way], c7, c10, 2\n"
817    ARM_SWITCH_BACK
818    : ARM_SWITCH_OUTPUT
819    : [set_and_way] "r" (set_and_way)
820    : "memory"
821  );
822}
823
824static inline void arm_cp15_data_cache_test_and_clean(void)
825{
826  ARM_SWITCH_REGISTERS;
827
828  __asm__ volatile (
829    ARM_SWITCH_TO_ARM
830    "1:\n"
831    "mrc p15, 0, r15, c7, c10, 3\n"
832    "bne 1b\n"
833    ARM_SWITCH_BACK
834    : ARM_SWITCH_OUTPUT
835    :
836    : "memory"
837  );
838}
839
840/*      In DDI0301H_arm1176jzfs_r0p7_trm
841 *      'MCR p15, 0, <Rd>, c7, c14, 0' means
842 *      Clean and Invalidate Entire Data Cache
843 */
844static inline void arm_cp15_data_cache_clean_and_invalidate(void)
845{
846  ARM_SWITCH_REGISTERS;
847
848  uint32_t sbz = 0;
849
850  __asm__ volatile (
851    ARM_SWITCH_TO_ARM
852    "mcr p15, 0, %[sbz], c7, c14, 0\n"
853    ARM_SWITCH_BACK
854    : ARM_SWITCH_OUTPUT
855    : [sbz] "r" (sbz)
856    : "memory"
857  );
858
859}
860
861static inline void arm_cp15_data_cache_clean_and_invalidate_line(const void *mva)
862{
863  ARM_SWITCH_REGISTERS;
864
865  mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
866
867  __asm__ volatile (
868    ARM_SWITCH_TO_ARM
869    "mcr p15, 0, %[mva], c7, c14, 1\n"
870    ARM_SWITCH_BACK
871    : ARM_SWITCH_OUTPUT
872    : [mva] "r" (mva)
873    : "memory"
874  );
875}
876
877static inline void arm_cp15_data_cache_clean_and_invalidate_line_by_set_and_way(uint32_t set_and_way)
878{
879  ARM_SWITCH_REGISTERS;
880
881  __asm__ volatile (
882    ARM_SWITCH_TO_ARM
883    "mcr p15, 0, %[set_and_way], c7, c14, 2\n"
884    ARM_SWITCH_BACK
885    : ARM_SWITCH_OUTPUT
886    : [set_and_way] "r" (set_and_way)
887    : "memory"
888  );
889}
890
891static inline void arm_cp15_data_cache_test_and_clean_and_invalidate(void)
892{
893  ARM_SWITCH_REGISTERS;
894
895  __asm__ volatile (
896    ARM_SWITCH_TO_ARM
897    "1:\n"
898    "mrc p15, 0, r15, c7, c14, 3\n"
899    "bne 1b\n"
900    ARM_SWITCH_BACK
901    : ARM_SWITCH_OUTPUT
902    :
903    : "memory"
904  );
905}
906
907/** @} */
908
909static inline void arm_cp15_drain_write_buffer(void)
910{
911  ARM_SWITCH_REGISTERS;
912  uint32_t sbz = 0;
913
914  __asm__ volatile (
915    ARM_SWITCH_TO_ARM
916    "mcr p15, 0, %[sbz], c7, c10, 4\n"
917    ARM_SWITCH_BACK
918    : ARM_SWITCH_OUTPUT
919    : [sbz] "r" (sbz)
920    : "memory"
921  );
922}
923
924static inline void arm_cp15_wait_for_interrupt(void)
925{
926  ARM_SWITCH_REGISTERS;
927  uint32_t sbz = 0;
928
929  __asm__ volatile (
930    ARM_SWITCH_TO_ARM
931    "mcr p15, 0, %[sbz], c7, c0, 4\n"
932    ARM_SWITCH_BACK
933    : ARM_SWITCH_OUTPUT
934    : [sbz] "r" (sbz)
935    : "memory"
936  );
937}
938
939static inline uint32_t arm_cp15_get_multiprocessor_affinity(void)
940{
941  ARM_SWITCH_REGISTERS;
942  uint32_t mpidr;
943
944  __asm__ volatile (
945    ARM_SWITCH_TO_ARM
946          "mrc p15, 0, %[mpidr], c0, c0, 5\n"
947    ARM_SWITCH_BACK
948    : [mpidr] "=&r" (mpidr) ARM_SWITCH_ADDITIONAL_OUTPUT
949  );
950
951  return mpidr & 0xff;
952}
953
954static inline uint32_t arm_cortex_a9_get_multiprocessor_cpu_id(void)
955{
956  return arm_cp15_get_multiprocessor_affinity() & 0xff;
957}
958
959#define ARM_CORTEX_A9_ACTL_FW (1U << 0)
960#define ARM_CORTEX_A9_ACTL_L2_PREFETCH_HINT_ENABLE (1U << 1)
961#define ARM_CORTEX_A9_ACTL_L1_PREFETCH_ENABLE (1U << 2)
962#define ARM_CORTEX_A9_ACTL_WRITE_FULL_LINE_OF_ZEROS_MODE (1U << 3)
963#define ARM_CORTEX_A9_ACTL_SMP (1U << 6)
964#define ARM_CORTEX_A9_ACTL_EXCL (1U << 7)
965#define ARM_CORTEX_A9_ACTL_ALLOC_IN_ONE_WAY (1U << 8)
966#define ARM_CORTEX_A9_ACTL_PARITY_ON (1U << 9)
967
968static inline uint32_t arm_cp15_get_auxiliary_control(void)
969{
970  ARM_SWITCH_REGISTERS;
971  uint32_t val;
972
973  __asm__ volatile (
974    ARM_SWITCH_TO_ARM
975    "mrc p15, 0, %[val], c1, c0, 1\n"
976    ARM_SWITCH_BACK
977    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
978  );
979
980  return val;
981}
982
983static inline void arm_cp15_set_auxiliary_control(uint32_t val)
984{
985  ARM_SWITCH_REGISTERS;
986
987  __asm__ volatile (
988    ARM_SWITCH_TO_ARM
989    "mcr p15, 0, %[val], c1, c0, 1\n"
990    ARM_SWITCH_BACK
991    : ARM_SWITCH_OUTPUT
992    : [val] "r" (val)
993  );
994}
995
996/* ID_PFR1, Processor Feature Register 1 */
997
998static inline uint32_t arm_cp15_get_processor_feature_1(void)
999{
1000  ARM_SWITCH_REGISTERS;
1001  uint32_t val;
1002
1003  __asm__ volatile (
1004    ARM_SWITCH_TO_ARM
1005    "mrc p15, 0, %[val], c0, c1, 1\n"
1006    ARM_SWITCH_BACK
1007    : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
1008  );
1009
1010  return val;
1011}
1012
1013/* VBAR, Vector Base Address Register, Security Extensions */
1014
1015static inline void *arm_cp15_get_vector_base_address(void)
1016{
1017  ARM_SWITCH_REGISTERS;
1018  void *base;
1019
1020  __asm__ volatile (
1021    ARM_SWITCH_TO_ARM
1022    "mrc p15, 0, %[base], c12, c0, 0\n"
1023    ARM_SWITCH_BACK
1024    : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
1025  );
1026
1027  return base;
1028}
1029
1030static inline void arm_cp15_set_vector_base_address(void *base)
1031{
1032  ARM_SWITCH_REGISTERS;
1033
1034  __asm__ volatile (
1035    ARM_SWITCH_TO_ARM
1036    "mcr p15, 0, %[base], c12, c0, 0\n"
1037    ARM_SWITCH_BACK
1038    : ARM_SWITCH_OUTPUT
1039    : [base] "r" (base)
1040  );
1041}
1042
1043/**
1044 * @brief Sets the @a section_flags for the address range [@a begin, @a end).
1045 *
1046 * @return Previous section flags of the first modified entry.
1047 */
1048uint32_t arm_cp15_set_translation_table_entries(
1049  const void *begin,
1050  const void *end,
1051  uint32_t section_flags
1052);
1053
1054void arm_cp15_set_exception_handler(
1055  Arm_symbolic_exception_name exception,
1056  void (*handler)(void)
1057);
1058
1059/** @} */
1060
1061#ifdef __cplusplus
1062}
1063#endif /* __cplusplus */
1064
1065#endif /* LIBCPU_SHARED_ARM_CP15_H */
Note: See TracBrowser for help on using the repository browser.