5 /* check interrupt state */
6 static inline void check_int(unsigned int state
, int line
)
10 asm volatile("mrs %0, cpsr" : "=r" (cpsr
));
12 if ((cpsr
& PSR_F
) != (state
& PSR_F
))
13 printf("%d: FIQs are unexpectedly %s\n", line
, (cpsr
& PSR_F
) ? "MASKED" : "UNMASKED");
15 if ((cpsr
& PSR_I
) != (state
& PSR_I
))
16 printf("%d: IRQs are unexpectedly %s\n", line
, (cpsr
& PSR_I
) ? "MASKED" : "UNMASKED");
21 /* Data memory barrier */
22 static inline void dmb(void)
24 asm volatile("dmb" : : : "memory");
27 /* Data synchronization barrier */
28 static inline void dsb(void)
30 asm volatile("dsb" : : : "memory");
33 /* Instruction synchronization barrier */
34 static inline void isb(void)
36 asm volatile("isb" : : : "memory");
39 static inline void barrier(void)
46 /* Read CLIDR, Cache Level ID Register */
47 static inline u32_t
read_clidr(void){
49 asm volatile("mrc p15, 1, %[clidr], c0, c0 , 1 @ READ CLIDR\n\t"
50 : [clidr
] "=r" (clidr
));
55 /* Read CSSELR, Cache Size Selection Register */
56 static inline u32_t
read_csselr(void){
58 asm volatile("mrc p15, 2, %[csselr], c0, c0 , 0 @ READ CSSELR\n\t"
59 : [csselr
] "=r" (csselr
));
63 /* Write CSSELR, Cache Size Selection Register */
64 static inline void write_csselr(u32_t csselr
){
65 asm volatile("mcr p15, 2, %[csselr], c0, c0 , 0 @ WRITE CSSELR\n\t"
66 : : [csselr
] "r" (csselr
));
69 /* Read Cache Size ID Register */
70 static inline u32_t
read_ccsidr(void)
73 asm volatile("mrc p15, 1, %[ccsidr], c0, c0, 0 @ Read CCSIDR\n\t"
74 : [ccsidr
] "=r" (ccsidr
));
78 /* Read TLBTR, TLB Type Register */
79 static inline u32_t
read_tlbtr(void)
82 asm volatile("mrc p15, 0, %[tlbtr], c0, c0, 3 @ Read TLBTR\n\t"
83 : [tlbtr
] "=r" (tlbtr
));
87 /* keesj:move these out */
88 static inline u32_t
ilog2(u32_t t
)
91 while( (t
= t
>> 1) ) counter
++;
95 /* keesj:move these out */
96 static inline u32_t
ipow2(u32_t t
)
103 * type = 2 == INVALIDATE
105 static inline void dcache_maint(int type
){
110 u32_t line_size
,line_length
;
111 u32_t number_of_sets
,number_of_ways
;
114 clidr
= read_clidr();
115 u32_t loc
= ( clidr
>> 24) & 0x7;
116 u32_t louu
= ( clidr
>> 27) & 0x7;
117 u32_t louis
= ( clidr
>> 21) & 0x7;
118 for (cache_level
=0 ; cache_level
< loc
; cache_level
++){
119 /* get current cache type */
120 ctype
= ( clidr
>> cache_level
*3) & 0x7;
121 /* select data or unified or cache level */
122 write_csselr(cache_level
<< 1);
124 ccsidr
= read_ccsidr();
125 line_size
= ccsidr
& 0x7;
126 line_length
= 2 << (line_size
+ 1) ; /* 2**(line_size + 2) */
127 number_of_sets
= ((ccsidr
>> 13) & 0x7fff) + 1;
128 number_of_ways
= ((ccsidr
>> 3) & 0x3ff) + 1;
130 u32_t way_bits
= ilog2(number_of_ways
);
131 if(ipow2(ilog2(number_of_ways
) < number_of_ways
) ) {
135 u32_t l
= ilog2(line_length
);
136 for (way
=0 ; way
< number_of_ways
; way
++) {
137 for (set
=0 ; set
< number_of_sets
; set
++) {
138 u32_t val
= ( way
<< (32 - way_bits
) ) | (set
<< l
) | (cache_level
<< 1 );
140 /* DCCISW, Data Cache Clean and Invalidate by Set/Way */
141 asm volatile("mcr p15, 0, %[set], c7, c14, 2 @ DCCISW"
142 : : [set
] "r" (val
));
143 } else if (type
==2 ){
144 /* DCISW, Data Cache Invalidate by Set/Way */
145 asm volatile("mcr p15, 0, %[set], c7, c6, 2"
146 : : [set
] "r" (val
));
155 static inline void dcache_clean(void){
158 static inline void dcache_invalidate(void){
162 static inline void refresh_tlb(void)
166 /* Invalidate entire unified TLB */
167 asm volatile("mcr p15, 0, %[zero], c8, c7, 0 @ TLBIALL\n\t" : : [zero
] "r" (0));
170 /* Invalidate entire data TLB */
171 asm volatile("mcr p15, 0, %[zero], c8, c6, 0" : : [zero
] "r" (0));
173 /* Invalidate entire instruction TLB */
174 asm volatile("mcr p15, 0, %[zero], c8, c5, 0" : : [zero
] "r" (0));
178 * Invalidate all instruction caches to PoU.
179 * Also flushes branch target cache.
181 asm volatile("mcr p15, 0, %[zero], c7, c5, 0" : : [zero
] "r" (0));
183 /* Invalidate entire branch predictor array */
184 asm volatile("mcr p15, 0, %[zero], c7, c5, 6" : : [zero
] "r" (0)); /* flush BTB */
191 /* Read System Control Register */
192 static inline u32_t
read_sctlr(void)
196 asm volatile("mrc p15, 0, %[ctl], c1, c0, 0 @ Read SCTLR\n\t"
202 /* Write System Control Register */
203 static inline void write_sctlr(u32_t ctl
)
205 asm volatile("mcr p15, 0, %[ctl], c1, c0, 0 @ Write SCTLR\n\t"
206 : : [ctl
] "r" (ctl
));
210 /* Read Translation Table Base Register 0 */
211 static inline u32_t
read_ttbr0(void)
215 asm volatile("mrc p15, 0, %[bar], c2, c0, 0 @ Read TTBR0\n\t"
218 return bar
& ARM_TTBR_ADDR_MASK
;
221 /* Write Translation Table Base Register 0 */
222 static inline void write_ttbr0(u32_t bar
)
225 /* In our setup TTBR contains the base address *and* the flags
226 but other pieces of the kernel code expect ttbr to be the
227 base address of the l1 page table. We therefore add the
228 flags here and remove them in the read_ttbr0 */
229 u32_t v
= (bar
& ARM_TTBR_ADDR_MASK
) | ARM_TTBR_FLAGS_CACHED
;
230 asm volatile("mcr p15, 0, %[bar], c2, c0, 0 @ Write TTBR0\n\t"
236 /* Reload Translation Table Base Register 0 */
237 static inline void reload_ttbr0(void)
239 reg_t ttbr
= read_ttbr0();
243 /* Read Translation Table Base Register 1 */
244 static inline u32_t
read_ttbr1(void)
248 asm volatile("mrc p15, 0, %[bar], c2, c0, 1 @ Read TTBR1\n\t"
254 /* Write Translation Table Base Register 1 */
255 static inline void write_ttbr1(u32_t bar
)
259 asm volatile("mcr p15, 0, %[bar], c2, c0, 1 @ Write TTBR1\n\t"
260 : : [bar
] "r" (bar
));
265 /* Reload Translation Table Base Register 1 */
266 static inline void reload_ttbr1(void)
268 reg_t ttbr
= read_ttbr1();
273 /* Read Translation Table Base Control Register */
274 static inline u32_t
read_ttbcr(void)
278 asm volatile("mrc p15, 0, %[bcr], c2, c0, 2 @ Read TTBCR\n\t"
284 /* Write Translation Table Base Control Register */
285 static inline void write_ttbcr(u32_t bcr
)
287 asm volatile("mcr p15, 0, %[bcr], c2, c0, 2 @ Write TTBCR\n\t"
288 : : [bcr
] "r" (bcr
));
293 /* Read Domain Access Control Register */
294 static inline u32_t
read_dacr(void)
298 asm volatile("mrc p15, 0, %[dacr], c3, c0, 0 @ Read DACR\n\t"
299 : [dacr
] "=r" (dacr
));
304 /* Write Domain Access Control Register */
305 static inline void write_dacr(u32_t dacr
)
307 asm volatile("mcr p15, 0, %[dacr], c3, c0, 0 @ Write DACR\n\t"
308 : : [dacr
] "r" (dacr
));
313 /* Read Data Fault Status Register */
314 static inline u32_t
read_dfsr(void)
318 asm volatile("mrc p15, 0, %[fsr], c5, c0, 0 @ Read DFSR\n\t"
324 /* Write Data Fault Status Register */
325 static inline void write_dfsr(u32_t fsr
)
327 asm volatile("mcr p15, 0, %[fsr], c5, c0, 0 @ Write DFSR\n\t"
328 : : [fsr
] "r" (fsr
));
333 /* Read Instruction Fault Status Register */
334 static inline u32_t
read_ifsr(void)
338 asm volatile("mrc p15, 0, %[fsr], c5, c0, 1 @ Read IFSR\n\t"
344 /* Write Instruction Fault Status Register */
345 static inline void write_ifsr(u32_t fsr
)
347 asm volatile("mcr p15, 0, %[fsr], c5, c0, 1 @ Write IFSR\n\t"
348 : : [fsr
] "r" (fsr
));
353 /* Read Data Fault Address Register */
354 static inline u32_t
read_dfar(void)
358 asm volatile("mrc p15, 0, %[far], c6, c0, 0 @ Read DFAR\n\t"
364 /* Write Data Fault Address Register */
365 static inline void write_dfar(u32_t far
)
367 asm volatile("mcr p15, 0, %[far], c6, c0, 0 @ Write DFAR\n\t"
368 : : [far
] "r" (far
));
373 /* Read Instruction Fault Address Register */
374 static inline u32_t
read_ifar(void)
378 asm volatile("mrc p15, 0, %[far], c6, c0, 2 @ Read IFAR\n\t"
384 /* Write Instruction Fault Address Register */
385 static inline void write_ifar(u32_t far
)
387 asm volatile("mcr p15, 0, %[far], c6, c0, 2 @ Write IFAR\n\t"
388 : : [far
] "r" (far
));
393 /* Read Vector Base Address Register */
394 static inline u32_t
read_vbar(void)
398 asm volatile("mrc p15, 0, %[vbar], c12, c0, 0 @ Read VBAR\n\t"
399 : [vbar
] "=r" (vbar
));
404 /* Write Vector Base Address Register */
405 static inline void write_vbar(u32_t vbar
)
407 asm volatile("mcr p15, 0, %[vbar], c12, c0, 0 @ Write VBAR\n\t"
408 : : [vbar
] "r" (vbar
));
413 /* Read the Main ID Register */
414 static inline u32_t
read_midr(void)
418 asm volatile("mrc p15, 0, %[id], c0, c0, 0 @ read MIDR\n\t"
424 /* Read Auxiliary Control Register */
425 static inline u32_t
read_actlr(void)
429 asm volatile("mrc p15, 0, %[ctl], c1, c0, 1 @ Read ACTLR\n\t"
435 /* Write Auxiliary Control Register */
436 static inline void write_actlr(u32_t ctl
)
438 //http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Babjbjbb.html
439 asm volatile("mcr p15, 0, %[ctl], c1, c0, 1 @ Write ACTLR\n\t"
440 : : [ctl
] "r" (ctl
));
445 /* Read Current Program Status Register */
446 static inline u32_t
read_cpsr(void)
450 asm volatile("mrs %[status], cpsr @ read CPSR"
451 : [status
] "=r" (status
));
456 /* Write Current Program Status Register */
457 static inline void write_cpsr(u32_t status
)
459 asm volatile("msr cpsr_c, %[status] @ write CPSR"
460 : : [status
] "r" (status
));
463 #endif /* _ARM_CPUFUNC_H */