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

4.115
Last change on this file since fd51f7e was fd51f7e, checked in by Sebastian Huber <sebastian.huber@…>, on 05/02/13 at 09:09:24

bsps/arm: Support ARMv7 VMSA sections and control

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