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