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

4.115
Last change on this file since 544615d was 544615d, checked in by Sebastian Huber <sebastian.huber@…>, on 05/02/13 at 15:41:11

bsps/arm: Add arm_cp15_mmu_disable()

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