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

4.115
Last change on this file since 03e097b7 was c9b66f5, checked in by Ric Claus <claus@…>, on 08/22/13 at 12:00:51

bsps/arm: Add more CP15 cache functions

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