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

4.11
Last change on this file since f074a4d was f074a4d, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 27, 2013 at 6:27:44 PM

bsps/arm: ARMV7_MMU_DATA_READ_WRITE_SHAREABLE

Delete ARMV7_MMU_DATA_READ_WRITE_SHAREABLE and move RTEMS_SMP
specific MMU attribute settings to arm-cp15.h.

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