xref: /minix3/minix/kernel/arch/earm/include/cpufunc.h (revision 6077d1ad241af1cd2881b708610d6ceb54ed9612)
1433d6423SLionel Sambuc #ifndef _ARM_CPUFUNC_H
2433d6423SLionel Sambuc #define _ARM_CPUFUNC_H
3433d6423SLionel Sambuc 
4433d6423SLionel Sambuc #if 0
5433d6423SLionel Sambuc /* check interrupt state */
6433d6423SLionel Sambuc static inline void check_int(unsigned int state, int line)
7433d6423SLionel Sambuc {
8433d6423SLionel Sambuc 	unsigned int cpsr = 0;
9433d6423SLionel Sambuc 
10433d6423SLionel Sambuc 	asm volatile("mrs %0, cpsr" : "=r" (cpsr));
11433d6423SLionel Sambuc 
12433d6423SLionel Sambuc 	if ((cpsr & PSR_F) != (state & PSR_F))
13433d6423SLionel Sambuc 	    printf("%d: FIQs are unexpectedly %s\n", line, (cpsr & PSR_F) ? "MASKED" : "UNMASKED");
14433d6423SLionel Sambuc 
15433d6423SLionel Sambuc 	if ((cpsr & PSR_I) != (state & PSR_I))
16433d6423SLionel Sambuc 	    printf("%d: IRQs are unexpectedly %s\n", line, (cpsr & PSR_I) ? "MASKED" : "UNMASKED");
17433d6423SLionel Sambuc 
18433d6423SLionel Sambuc }
19433d6423SLionel Sambuc #endif
20433d6423SLionel Sambuc 
21433d6423SLionel Sambuc /* Data memory barrier */
dmb(void)22433d6423SLionel Sambuc static inline void dmb(void)
23433d6423SLionel Sambuc {
24433d6423SLionel Sambuc 	asm volatile("dmb" : : : "memory");
25433d6423SLionel Sambuc }
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc /* Data synchronization barrier */
dsb(void)28433d6423SLionel Sambuc static inline void dsb(void)
29433d6423SLionel Sambuc {
30433d6423SLionel Sambuc 	asm volatile("dsb" : : : "memory");
31433d6423SLionel Sambuc }
32433d6423SLionel Sambuc 
33433d6423SLionel Sambuc /* Instruction synchronization barrier */
isb(void)34433d6423SLionel Sambuc static inline void isb(void)
35433d6423SLionel Sambuc {
36433d6423SLionel Sambuc 	asm volatile("isb" : : : "memory");
37433d6423SLionel Sambuc }
38433d6423SLionel Sambuc 
barrier(void)39433d6423SLionel Sambuc static inline void barrier(void)
40433d6423SLionel Sambuc {
41433d6423SLionel Sambuc 	dsb();
42433d6423SLionel Sambuc 	isb();
43433d6423SLionel Sambuc }
44433d6423SLionel Sambuc 
45433d6423SLionel Sambuc 
46433d6423SLionel Sambuc /* Read CLIDR, Cache Level ID Register */
read_clidr(void)47*6077d1adSDr. Florian Grätz static inline u32_t read_clidr(void){
48433d6423SLionel Sambuc 	u32_t clidr;
49433d6423SLionel Sambuc 	asm volatile("mrc p15, 1, %[clidr], c0, c0 , 1 @ READ CLIDR\n\t"
50433d6423SLionel Sambuc 				: [clidr] "=r" (clidr));
51433d6423SLionel Sambuc 	return clidr;
52433d6423SLionel Sambuc }
53433d6423SLionel Sambuc 
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc /* Read CSSELR, Cache Size Selection Register */
read_csselr(void)56*6077d1adSDr. Florian Grätz static inline u32_t read_csselr(void){
57433d6423SLionel Sambuc 	u32_t csselr;
58433d6423SLionel Sambuc 	asm volatile("mrc p15, 2, %[csselr], c0, c0 , 0 @ READ CSSELR\n\t"
59433d6423SLionel Sambuc 				: [csselr] "=r" (csselr));
60433d6423SLionel Sambuc 	return csselr;
61433d6423SLionel Sambuc }
62433d6423SLionel Sambuc 
63433d6423SLionel Sambuc /* Write CSSELR, Cache Size Selection Register */
write_csselr(u32_t csselr)64433d6423SLionel Sambuc static inline void write_csselr(u32_t csselr){
65433d6423SLionel Sambuc 	asm volatile("mcr p15, 2, %[csselr], c0, c0 , 0 @ WRITE CSSELR\n\t"
66433d6423SLionel Sambuc 				: : [csselr] "r" (csselr));
67433d6423SLionel Sambuc }
68433d6423SLionel Sambuc 
69433d6423SLionel Sambuc /* Read Cache Size ID Register */
read_ccsidr(void)70*6077d1adSDr. Florian Grätz static inline u32_t read_ccsidr(void)
71433d6423SLionel Sambuc {
72433d6423SLionel Sambuc 	u32_t ccsidr;
73433d6423SLionel Sambuc 	asm volatile("mrc p15, 1, %[ccsidr], c0, c0, 0 @ Read CCSIDR\n\t"
74433d6423SLionel Sambuc 			: [ccsidr] "=r" (ccsidr));
75433d6423SLionel Sambuc 	return ccsidr;
76433d6423SLionel Sambuc }
77433d6423SLionel Sambuc 
78433d6423SLionel Sambuc /* Read TLBTR, TLB Type Register */
read_tlbtr(void)79*6077d1adSDr. Florian Grätz static inline u32_t read_tlbtr(void)
80433d6423SLionel Sambuc {
81433d6423SLionel Sambuc 	u32_t tlbtr;
82433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[tlbtr], c0, c0, 3 @ Read TLBTR\n\t"
83433d6423SLionel Sambuc 			: [tlbtr] "=r" (tlbtr));
84433d6423SLionel Sambuc 	return tlbtr;
85433d6423SLionel Sambuc }
86433d6423SLionel Sambuc 
87433d6423SLionel Sambuc /* keesj:move these out */
ilog2(u32_t t)88433d6423SLionel Sambuc static inline u32_t ilog2(u32_t t)
89433d6423SLionel Sambuc {
90433d6423SLionel Sambuc 	u32_t counter =0;
91433d6423SLionel Sambuc 	while( (t = t >> 1) ) counter ++;
92433d6423SLionel Sambuc 	return counter;
93433d6423SLionel Sambuc }
94433d6423SLionel Sambuc 
95433d6423SLionel Sambuc /* keesj:move these out */
ipow2(u32_t t)96433d6423SLionel Sambuc static inline u32_t ipow2(u32_t t)
97433d6423SLionel Sambuc {
98433d6423SLionel Sambuc 	return 1 << t;
99433d6423SLionel Sambuc }
100433d6423SLionel Sambuc 
101433d6423SLionel Sambuc /*
102433d6423SLionel Sambuc  * type = 1 == CLEAN
103433d6423SLionel Sambuc  * type = 2 == INVALIDATE
104433d6423SLionel Sambuc  */
dcache_maint(int type)105433d6423SLionel Sambuc static inline void dcache_maint(int type){
106433d6423SLionel Sambuc 	u32_t cache_level ;
107433d6423SLionel Sambuc 	u32_t clidr;
108433d6423SLionel Sambuc 	u32_t ctype;
109433d6423SLionel Sambuc 	u32_t  ccsidr;
110433d6423SLionel Sambuc 	u32_t  line_size,line_length;
111433d6423SLionel Sambuc 	u32_t  number_of_sets,number_of_ways;
112433d6423SLionel Sambuc 	u32_t  set,way;
113433d6423SLionel Sambuc 
114433d6423SLionel Sambuc 	clidr = read_clidr();
115433d6423SLionel Sambuc 	u32_t loc =  ( clidr >> 24) & 0x7;
116433d6423SLionel Sambuc 	u32_t louu =  ( clidr >> 27) & 0x7;
117433d6423SLionel Sambuc 	u32_t louis =  ( clidr >> 21) & 0x7;
118433d6423SLionel Sambuc 	for (cache_level =0 ; cache_level < loc; cache_level++){
119433d6423SLionel Sambuc 		/* get current cache type */
120433d6423SLionel Sambuc 		ctype = ( clidr >> cache_level*3) & 0x7;
121433d6423SLionel Sambuc 		/* select data or unified or cache level */
122433d6423SLionel Sambuc 		write_csselr(cache_level << 1);
123433d6423SLionel Sambuc 		isb();
124433d6423SLionel Sambuc 		ccsidr = read_ccsidr();
125433d6423SLionel Sambuc 		line_size = ccsidr & 0x7;
126433d6423SLionel Sambuc 		line_length = 2 << (line_size + 1) ; /* 2**(line_size + 2) */
127433d6423SLionel Sambuc 		number_of_sets = ((ccsidr >> 13) & 0x7fff) + 1;
128433d6423SLionel Sambuc 		number_of_ways = ((ccsidr >> 3) & 0x3ff) + 1;
129433d6423SLionel Sambuc 
130433d6423SLionel Sambuc 		u32_t way_bits = ilog2(number_of_ways);
131433d6423SLionel Sambuc 		if(ipow2(ilog2(number_of_ways) < number_of_ways) ) {
132433d6423SLionel Sambuc 			way_bits++;
133433d6423SLionel Sambuc 		}
134433d6423SLionel Sambuc 
135433d6423SLionel Sambuc 		u32_t l = ilog2(line_length);
136433d6423SLionel Sambuc 		for (way =0 ; way < number_of_ways; way++) {
137433d6423SLionel Sambuc 			for (set =0 ; set < number_of_sets; set++) {
138433d6423SLionel Sambuc 				u32_t val = ( way << (32 - way_bits) ) |  (set << l) | (cache_level << 1 );
139433d6423SLionel Sambuc 				if (type == 1) {
140433d6423SLionel Sambuc 					/* DCCISW, Data Cache Clean and Invalidate by Set/Way */
141433d6423SLionel Sambuc 					asm volatile("mcr p15, 0, %[set], c7, c14, 2 @ DCCISW"
142433d6423SLionel Sambuc 							: : [set] "r" (val));
143433d6423SLionel Sambuc 				} else if (type ==2 ){
144433d6423SLionel Sambuc 					/* DCISW, Data Cache Invalidate by Set/Way */
145433d6423SLionel Sambuc 					asm volatile("mcr p15, 0, %[set], c7, c6, 2"
146433d6423SLionel Sambuc 							: : [set] "r" (val));
147433d6423SLionel Sambuc 				}
148433d6423SLionel Sambuc 			}
149433d6423SLionel Sambuc 		}
150433d6423SLionel Sambuc 	}
151433d6423SLionel Sambuc 	dsb();
152433d6423SLionel Sambuc 	isb();
153433d6423SLionel Sambuc 
154433d6423SLionel Sambuc }
dcache_clean(void)155*6077d1adSDr. Florian Grätz static inline void dcache_clean(void){
156433d6423SLionel Sambuc 	dcache_maint(1);
157433d6423SLionel Sambuc }
dcache_invalidate(void)158*6077d1adSDr. Florian Grätz static inline void dcache_invalidate(void){
159433d6423SLionel Sambuc 	dcache_maint(2);
160433d6423SLionel Sambuc }
161433d6423SLionel Sambuc 
refresh_tlb(void)162433d6423SLionel Sambuc static inline void refresh_tlb(void)
163433d6423SLionel Sambuc {
164433d6423SLionel Sambuc 	dsb();
165433d6423SLionel Sambuc 
166433d6423SLionel Sambuc 	/* Invalidate entire unified TLB */
167433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[zero], c8, c7, 0 @ TLBIALL\n\t" : : [zero] "r" (0));
168433d6423SLionel Sambuc 
169433d6423SLionel Sambuc #if 0
170433d6423SLionel Sambuc 	/* Invalidate entire data TLB */
171433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[zero], c8, c6, 0" : : [zero] "r" (0));
172433d6423SLionel Sambuc 
173433d6423SLionel Sambuc 	/* Invalidate entire instruction TLB */
174433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[zero], c8, c5, 0" : : [zero] "r" (0));
175433d6423SLionel Sambuc #endif
176433d6423SLionel Sambuc 
177433d6423SLionel Sambuc 	/*
178433d6423SLionel Sambuc 	 * Invalidate all instruction caches to PoU.
179433d6423SLionel Sambuc 	 * Also flushes branch target cache.
180433d6423SLionel Sambuc 	 */
181433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[zero], c7, c5, 0" : : [zero] "r" (0));
182433d6423SLionel Sambuc 
183433d6423SLionel Sambuc 	/* Invalidate entire branch predictor array */
184433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[zero], c7, c5, 6" : : [zero] "r" (0)); /* flush BTB */
185433d6423SLionel Sambuc 
186433d6423SLionel Sambuc 	dsb();
187433d6423SLionel Sambuc 	isb();
188433d6423SLionel Sambuc }
189433d6423SLionel Sambuc 
190433d6423SLionel Sambuc 
191433d6423SLionel Sambuc /* Read System Control Register */
read_sctlr(void)192*6077d1adSDr. Florian Grätz static inline u32_t read_sctlr(void)
193433d6423SLionel Sambuc {
194433d6423SLionel Sambuc 	u32_t ctl;
195433d6423SLionel Sambuc 
196433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[ctl], c1, c0, 0 @ Read SCTLR\n\t"
197433d6423SLionel Sambuc 			: [ctl] "=r" (ctl));
198433d6423SLionel Sambuc 
199433d6423SLionel Sambuc 	return ctl;
200433d6423SLionel Sambuc }
201433d6423SLionel Sambuc 
202433d6423SLionel Sambuc /* Write System Control Register */
write_sctlr(u32_t ctl)203433d6423SLionel Sambuc static inline void write_sctlr(u32_t ctl)
204433d6423SLionel Sambuc {
205433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[ctl], c1, c0, 0 @ Write SCTLR\n\t"
206433d6423SLionel Sambuc 			: : [ctl] "r" (ctl));
207433d6423SLionel Sambuc 	isb();
208433d6423SLionel Sambuc }
209433d6423SLionel Sambuc 
210433d6423SLionel Sambuc /* Read Translation Table Base Register 0 */
read_ttbr0(void)211*6077d1adSDr. Florian Grätz static inline u32_t read_ttbr0(void)
212433d6423SLionel Sambuc {
213433d6423SLionel Sambuc 	u32_t bar;
214433d6423SLionel Sambuc 
215433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[bar], c2, c0, 0 @ Read TTBR0\n\t"
216433d6423SLionel Sambuc 			: [bar] "=r" (bar));
217433d6423SLionel Sambuc 
218433d6423SLionel Sambuc 	return bar & ARM_TTBR_ADDR_MASK;
219433d6423SLionel Sambuc }
220433d6423SLionel Sambuc 
221433d6423SLionel Sambuc /* Write Translation Table Base Register 0 */
write_ttbr0(u32_t bar)222433d6423SLionel Sambuc static inline void write_ttbr0(u32_t bar)
223433d6423SLionel Sambuc {
224433d6423SLionel Sambuc 	barrier();
225433d6423SLionel Sambuc 	/* In our setup TTBR contains the base address *and* the flags
226433d6423SLionel Sambuc 	   but other pieces of the kernel code expect ttbr to be the
227433d6423SLionel Sambuc 	   base address of the l1 page table. We therefore add the
228433d6423SLionel Sambuc 	   flags here and remove them in the read_ttbr0 */
229433d6423SLionel Sambuc 	u32_t v  =  (bar  & ARM_TTBR_ADDR_MASK ) | ARM_TTBR_FLAGS_CACHED;
230433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[bar], c2, c0, 0 @ Write TTBR0\n\t"
231433d6423SLionel Sambuc 			: : [bar] "r" (v));
232433d6423SLionel Sambuc 
233433d6423SLionel Sambuc 	refresh_tlb();
234433d6423SLionel Sambuc }
235433d6423SLionel Sambuc 
236433d6423SLionel Sambuc /* Reload Translation Table Base Register 0 */
reload_ttbr0(void)237433d6423SLionel Sambuc static inline void reload_ttbr0(void)
238433d6423SLionel Sambuc {
239433d6423SLionel Sambuc 	reg_t ttbr = read_ttbr0();
240433d6423SLionel Sambuc 	write_ttbr0(ttbr);
241433d6423SLionel Sambuc }
242433d6423SLionel Sambuc 
243433d6423SLionel Sambuc /* Read Translation Table Base Register 1 */
read_ttbr1(void)244*6077d1adSDr. Florian Grätz static inline u32_t read_ttbr1(void)
245433d6423SLionel Sambuc {
246433d6423SLionel Sambuc 	u32_t bar;
247433d6423SLionel Sambuc 
248433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[bar], c2, c0, 1 @ Read TTBR1\n\t"
249433d6423SLionel Sambuc 			: [bar] "=r" (bar));
250433d6423SLionel Sambuc 
251433d6423SLionel Sambuc 	return bar;
252433d6423SLionel Sambuc }
253433d6423SLionel Sambuc 
254433d6423SLionel Sambuc /* Write Translation Table Base Register 1 */
write_ttbr1(u32_t bar)255433d6423SLionel Sambuc static inline void write_ttbr1(u32_t bar)
256433d6423SLionel Sambuc {
257433d6423SLionel Sambuc 	barrier();
258433d6423SLionel Sambuc 
259433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[bar], c2, c0, 1 @ Write TTBR1\n\t"
260433d6423SLionel Sambuc 			: : [bar] "r" (bar));
261433d6423SLionel Sambuc 
262433d6423SLionel Sambuc 	refresh_tlb();
263433d6423SLionel Sambuc }
264433d6423SLionel Sambuc 
265433d6423SLionel Sambuc /* Reload Translation Table Base Register 1 */
reload_ttbr1(void)266433d6423SLionel Sambuc static inline void reload_ttbr1(void)
267433d6423SLionel Sambuc {
268433d6423SLionel Sambuc 	reg_t ttbr = read_ttbr1();
269433d6423SLionel Sambuc 
270433d6423SLionel Sambuc 	write_ttbr1(ttbr);
271433d6423SLionel Sambuc }
272433d6423SLionel Sambuc 
273433d6423SLionel Sambuc /* Read Translation Table Base Control Register */
read_ttbcr(void)274*6077d1adSDr. Florian Grätz static inline u32_t read_ttbcr(void)
275433d6423SLionel Sambuc {
276433d6423SLionel Sambuc 	u32_t bcr;
277433d6423SLionel Sambuc 
278433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[bcr], c2, c0, 2 @ Read TTBCR\n\t"
279433d6423SLionel Sambuc 			: [bcr] "=r" (bcr));
280433d6423SLionel Sambuc 
281433d6423SLionel Sambuc 	return bcr;
282433d6423SLionel Sambuc }
283433d6423SLionel Sambuc 
284433d6423SLionel Sambuc /* Write Translation Table Base Control Register */
write_ttbcr(u32_t bcr)285433d6423SLionel Sambuc static inline void write_ttbcr(u32_t bcr)
286433d6423SLionel Sambuc {
287433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[bcr], c2, c0, 2 @ Write TTBCR\n\t"
288433d6423SLionel Sambuc 			: : [bcr] "r" (bcr));
289433d6423SLionel Sambuc 
290433d6423SLionel Sambuc 	isb();
291433d6423SLionel Sambuc }
292433d6423SLionel Sambuc 
293433d6423SLionel Sambuc /* Read Domain Access Control Register */
read_dacr(void)294*6077d1adSDr. Florian Grätz static inline u32_t read_dacr(void)
295433d6423SLionel Sambuc {
296433d6423SLionel Sambuc 	u32_t dacr;
297433d6423SLionel Sambuc 
298433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[dacr], c3, c0, 0 @ Read DACR\n\t"
299433d6423SLionel Sambuc 			: [dacr] "=r" (dacr));
300433d6423SLionel Sambuc 
301433d6423SLionel Sambuc 	return dacr;
302433d6423SLionel Sambuc }
303433d6423SLionel Sambuc 
304433d6423SLionel Sambuc /* Write Domain Access Control Register */
write_dacr(u32_t dacr)305433d6423SLionel Sambuc static inline void write_dacr(u32_t dacr)
306433d6423SLionel Sambuc {
307433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[dacr], c3, c0, 0 @ Write DACR\n\t"
308433d6423SLionel Sambuc 			: : [dacr] "r" (dacr));
309433d6423SLionel Sambuc 
310433d6423SLionel Sambuc 	isb();
311433d6423SLionel Sambuc }
312433d6423SLionel Sambuc 
313433d6423SLionel Sambuc /* Read Data Fault Status Register */
read_dfsr(void)314*6077d1adSDr. Florian Grätz static inline u32_t read_dfsr(void)
315433d6423SLionel Sambuc {
316433d6423SLionel Sambuc 	u32_t fsr;
317433d6423SLionel Sambuc 
318433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[fsr], c5, c0, 0 @ Read DFSR\n\t"
319433d6423SLionel Sambuc 			: [fsr] "=r" (fsr));
320433d6423SLionel Sambuc 
321433d6423SLionel Sambuc 	return fsr;
322433d6423SLionel Sambuc }
323433d6423SLionel Sambuc 
324433d6423SLionel Sambuc /* Write Data Fault Status Register */
write_dfsr(u32_t fsr)325433d6423SLionel Sambuc static inline void write_dfsr(u32_t fsr)
326433d6423SLionel Sambuc {
327433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[fsr], c5, c0, 0 @ Write DFSR\n\t"
328433d6423SLionel Sambuc 			: : [fsr] "r" (fsr));
329433d6423SLionel Sambuc 
330433d6423SLionel Sambuc 	isb();
331433d6423SLionel Sambuc }
332433d6423SLionel Sambuc 
333433d6423SLionel Sambuc /* Read Instruction Fault Status Register */
read_ifsr(void)334*6077d1adSDr. Florian Grätz static inline u32_t read_ifsr(void)
335433d6423SLionel Sambuc {
336433d6423SLionel Sambuc 	u32_t fsr;
337433d6423SLionel Sambuc 
338433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[fsr], c5, c0, 1 @ Read IFSR\n\t"
339433d6423SLionel Sambuc 			: [fsr] "=r" (fsr));
340433d6423SLionel Sambuc 
341433d6423SLionel Sambuc 	return fsr;
342433d6423SLionel Sambuc }
343433d6423SLionel Sambuc 
344433d6423SLionel Sambuc /* Write Instruction Fault Status Register */
write_ifsr(u32_t fsr)345433d6423SLionel Sambuc static inline void write_ifsr(u32_t fsr)
346433d6423SLionel Sambuc {
347433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[fsr], c5, c0, 1 @ Write IFSR\n\t"
348433d6423SLionel Sambuc 			: : [fsr] "r" (fsr));
349433d6423SLionel Sambuc 
350433d6423SLionel Sambuc 	isb();
351433d6423SLionel Sambuc }
352433d6423SLionel Sambuc 
353433d6423SLionel Sambuc /* Read Data Fault Address Register */
read_dfar(void)354*6077d1adSDr. Florian Grätz static inline u32_t read_dfar(void)
355433d6423SLionel Sambuc {
356433d6423SLionel Sambuc 	u32_t far;
357433d6423SLionel Sambuc 
358433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[far], c6, c0, 0 @ Read DFAR\n\t"
359433d6423SLionel Sambuc 			: [far] "=r" (far));
360433d6423SLionel Sambuc 
361433d6423SLionel Sambuc 	return far;
362433d6423SLionel Sambuc }
363433d6423SLionel Sambuc 
364433d6423SLionel Sambuc /* Write Data Fault Address Register */
write_dfar(u32_t far)365433d6423SLionel Sambuc static inline void write_dfar(u32_t far)
366433d6423SLionel Sambuc {
367433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[far], c6, c0, 0 @ Write DFAR\n\t"
368433d6423SLionel Sambuc 			: : [far] "r" (far));
369433d6423SLionel Sambuc 
370433d6423SLionel Sambuc 	isb();
371433d6423SLionel Sambuc }
372433d6423SLionel Sambuc 
373433d6423SLionel Sambuc /* Read Instruction Fault Address Register */
read_ifar(void)374*6077d1adSDr. Florian Grätz static inline u32_t read_ifar(void)
375433d6423SLionel Sambuc {
376433d6423SLionel Sambuc 	u32_t far;
377433d6423SLionel Sambuc 
378433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[far], c6, c0, 2 @ Read IFAR\n\t"
379433d6423SLionel Sambuc 			: [far] "=r" (far));
380433d6423SLionel Sambuc 
381433d6423SLionel Sambuc 	return far;
382433d6423SLionel Sambuc }
383433d6423SLionel Sambuc 
384433d6423SLionel Sambuc /* Write Instruction Fault Address Register */
write_ifar(u32_t far)385433d6423SLionel Sambuc static inline void write_ifar(u32_t far)
386433d6423SLionel Sambuc {
387433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[far], c6, c0, 2 @ Write IFAR\n\t"
388433d6423SLionel Sambuc 			: : [far] "r" (far));
389433d6423SLionel Sambuc 
390433d6423SLionel Sambuc 	isb();
391433d6423SLionel Sambuc }
392433d6423SLionel Sambuc 
393433d6423SLionel Sambuc /* Read Vector Base Address Register */
read_vbar(void)394*6077d1adSDr. Florian Grätz static inline u32_t read_vbar(void)
395433d6423SLionel Sambuc {
396433d6423SLionel Sambuc 	u32_t vbar;
397433d6423SLionel Sambuc 
398433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[vbar], c12, c0, 0 @ Read VBAR\n\t"
399433d6423SLionel Sambuc 			: [vbar] "=r" (vbar));
400433d6423SLionel Sambuc 
401433d6423SLionel Sambuc 	return vbar;
402433d6423SLionel Sambuc }
403433d6423SLionel Sambuc 
404433d6423SLionel Sambuc /* Write Vector Base Address Register */
write_vbar(u32_t vbar)405433d6423SLionel Sambuc static inline void write_vbar(u32_t vbar)
406433d6423SLionel Sambuc {
407433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[vbar], c12, c0, 0 @ Write VBAR\n\t"
408433d6423SLionel Sambuc 			: : [vbar] "r" (vbar));
409433d6423SLionel Sambuc 
410433d6423SLionel Sambuc 	isb();
411433d6423SLionel Sambuc }
412433d6423SLionel Sambuc 
413433d6423SLionel Sambuc /* Read the Main ID Register  */
read_midr(void)414*6077d1adSDr. Florian Grätz static inline u32_t read_midr(void)
415433d6423SLionel Sambuc {
416433d6423SLionel Sambuc 	u32_t id;
417433d6423SLionel Sambuc 
418433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[id], c0, c0, 0 @ read MIDR\n\t"
419433d6423SLionel Sambuc 			: [id] "=r" (id));
420433d6423SLionel Sambuc 
421433d6423SLionel Sambuc 	return id;
422433d6423SLionel Sambuc }
423433d6423SLionel Sambuc 
424433d6423SLionel Sambuc /* Read Auxiliary Control Register */
read_actlr(void)425*6077d1adSDr. Florian Grätz static inline u32_t read_actlr(void)
426433d6423SLionel Sambuc {
427433d6423SLionel Sambuc 	u32_t ctl;
428433d6423SLionel Sambuc 
429433d6423SLionel Sambuc 	asm volatile("mrc p15, 0, %[ctl], c1, c0, 1 @ Read ACTLR\n\t"
430433d6423SLionel Sambuc 			: [ctl] "=r" (ctl));
431433d6423SLionel Sambuc 
432433d6423SLionel Sambuc 	return ctl;
433433d6423SLionel Sambuc }
434433d6423SLionel Sambuc 
435433d6423SLionel Sambuc /* Write Auxiliary Control Register */
write_actlr(u32_t ctl)436433d6423SLionel Sambuc static inline void write_actlr(u32_t ctl)
437433d6423SLionel Sambuc {
438433d6423SLionel Sambuc //http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Babjbjbb.html
439433d6423SLionel Sambuc 	asm volatile("mcr p15, 0, %[ctl], c1, c0, 1 @ Write ACTLR\n\t"
440433d6423SLionel Sambuc 			: : [ctl] "r" (ctl));
441433d6423SLionel Sambuc 
442433d6423SLionel Sambuc 	isb();
443433d6423SLionel Sambuc }
444433d6423SLionel Sambuc 
445433d6423SLionel Sambuc /* Read Current Program Status Register */
read_cpsr(void)446*6077d1adSDr. Florian Grätz static inline u32_t read_cpsr(void)
447433d6423SLionel Sambuc {
448433d6423SLionel Sambuc 	u32_t status;
449433d6423SLionel Sambuc 
450433d6423SLionel Sambuc 	asm volatile("mrs %[status], cpsr @ read CPSR"
451433d6423SLionel Sambuc 			: [status] "=r" (status));
452433d6423SLionel Sambuc 
453433d6423SLionel Sambuc 	return status;
454433d6423SLionel Sambuc }
455433d6423SLionel Sambuc 
456433d6423SLionel Sambuc /* Write Current Program Status Register */
write_cpsr(u32_t status)457433d6423SLionel Sambuc static inline void write_cpsr(u32_t status)
458433d6423SLionel Sambuc {
459433d6423SLionel Sambuc 	asm volatile("msr cpsr_c, %[status] @ write CPSR"
460433d6423SLionel Sambuc 			: : [status] "r" (status));
461433d6423SLionel Sambuc }
462433d6423SLionel Sambuc 
463433d6423SLionel Sambuc #endif /* _ARM_CPUFUNC_H */
464