]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/l.s
Import sources from 2011-03-30 iso image - lib
[plan9front.git] / sys / src / 9 / kw / l.s
1 /*
2  * sheevaplug machine assist
3  * arm926ej-s processor at 1.2GHz
4  *
5  * loader uses R11 as scratch.
6  * R9 and R10 are used for `extern register' variables.
7  *
8  * ARM v7 arch. ref. man. (I know, this is v5) §B1.3.3 that
9  * we don't need barriers around moves to CPSR.  The ARM v6 manual
10  * seems to be silent on the subject.
11  */
12 #include "arm.s"
13
14 /*
15  * MCR and MRC are counter-intuitively named.
16  *      MCR     coproc, opcode1, Rd, CRn, CRm[, opcode2]        # arm -> coproc
17  *      MRC     coproc, opcode1, Rd, CRn, CRm[, opcode2]        # coproc -> arm
18  */
19
20 /*
21  * Entered here from Das U-Boot with MMU disabled.
22  * Until the MMU is enabled it is OK to call functions provided
23  * they are within ±32MiB relative and do not require any
24  * local variables or more than one argument (i.e. there is
25  * no stack).
26  */
27 TEXT _start(SB), 1, $-4
28         MOVW    $setR12(SB), R12                /* load the SB */
29 _main:
30         /* SVC mode, interrupts disabled */
31         MOVW    $(PsrDirq|PsrDfiq|PsrMsvc), R1
32         MOVW    R1, CPSR
33         BARRIERS
34
35         /*
36          * disable the MMU & caches,
37          * switch to system permission & 32-bit addresses.
38          */
39         MOVW    $(CpCsystem|CpCd32|CpCi32), R1
40         MCR     CpSC, 0, R1, C(CpCONTROL), C(0)
41         ISB
42
43         /*
44          * disable the Sheevaplug's L2 cache, invalidate all caches
45          */
46
47         /* flush caches.  926ejs manual says we have to do it iteratively. */
48 _dwbinv0:
49         MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
50         BNE     _dwbinv0
51         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
52         BARRIERS
53
54         /* make the l2 cache pay attention */
55         MOVW    $(PHYSIO+0x20100), R1   /* CPUCSREG */
56         MOVW    (4*10)(R1), R2
57         ORR     $(1<<3), R2             /* cpu->l2cfg |= L2exists */
58         MOVW    R2, (4*10)(R1)
59         ISB
60
61         /* invalidate l2 cache */
62         MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
63         ISB
64
65         /* disable l2 cache.  do this while l1 caches are off */
66         MRC     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
67         /* disabling write allocation is probably for cortex-a8 errata 460075 */
68         /* l2 off, no wr alloc, no streaming */
69         BIC     $(CpTCl2ena | CpTCl2wralloc | CpTCldcstream), R1
70         MCR     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
71         BARRIERS
72
73         /* flush caches.  926ejs manual says we have to do it iteratively. */
74 _dwbinv1:
75         MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
76         BNE     _dwbinv1
77         BARRIERS
78
79 WAVE('\r')
80         /* clear Mach */
81         MOVW    $PADDR(MACHADDR), R4            /* address of Mach */
82 _machZ:
83         MOVW    R0, (R4)
84         ADD     $4, R4                          /* bump PTE address */
85         CMP.S   $PADDR(L1+L1X(0)), R4
86         BNE     _machZ
87
88         /*
89          * set up the MMU page table
90          */
91
92         /* clear all PTEs first, to provide a default */
93 WAVE('\n')
94         MOVW    $PADDR(L1+L1X(0)), R4           /* address of PTE for 0 */
95 _ptenv0:
96         ZEROPTE()
97         CMP.S   $PADDR(L1+16*KiB), R4
98         BNE     _ptenv0
99
100         /* double map of PHYSDRAM, KZERO to PHYSDRAM for first few MBs */
101         MOVW    $PTEDRAM, R2                    /* PTE bits */
102         MOVW    $PHYSDRAM, R3                   /* pa */
103         MOVW    $PADDR(L1+L1X(PHYSDRAM)), R4  /* address of PTE for PHYSDRAM */
104         MOVW    $16, R5
105 _ptdbl:
106         FILLPTE()
107         SUB.S   $1, R5
108         BNE     _ptdbl
109
110         /*
111          * back up and fill in PTEs for memory at KZERO
112          * there is 1 bank of 512MB of SDRAM at PHYSDRAM
113          */
114         MOVW    $PTEDRAM, R2                    /* PTE bits */
115         MOVW    $PHYSDRAM, R3
116         MOVW    $PADDR(L1+L1X(KZERO)), R4       /* start with PTE for KZERO */
117         MOVW    $512, R5                        /* inner loop count */
118 _ptekrw:                                        /* set PTEs for 512MiB */
119         FILLPTE()
120         SUB.S   $1, R5
121         BNE     _ptekrw
122
123         /*
124          * back up and fill in PTE for MMIO
125          */
126         MOVW    $PTEIO, R2                      /* PTE bits */
127         MOVW    $PHYSIO, R3
128         MOVW    $PADDR(L1+L1X(VIRTIO)), R4      /* start with PTE for VIRTIO */
129         FILLPTE()
130
131         /* mmu.c sets up the vectors later */
132
133         /*
134          * set up a temporary stack; avoid data & bss segments
135          */
136         MOVW    $(PHYSDRAM | (128*1024*1024)), R13
137
138 WAVE('P')
139         /* set the domain access control */
140         MOVW    $Client, R0
141         BL      dacput(SB)
142
143         /* set the translation table base */
144         MOVW    $PADDR(L1), R0
145         BL      ttbput(SB)
146
147         MOVW    $0, R0
148         BL      pidput(SB)              /* paranoia */
149
150         /* the little dance to turn the MMU & caches on */
151 WAVE('l')
152         BL      cacheuwbinv(SB)
153         BL      mmuinvalidate(SB)
154         BL      mmuenable(SB)
155
156 WAVE('a')
157         /* warp the PC into the virtual map */
158         MOVW    $KZERO, R0
159         BL      _r15warp(SB)
160
161         /*
162          * now running at KZERO+something!
163          */
164
165         MOVW    $setR12(SB), R12                /* reload the SB */
166
167         /*
168          * set up temporary stack again, in case we've just switched
169          * to a new register set.
170          */
171         MOVW    $(KZERO|(128*1024*1024)), R13
172
173         /* can now execute arbitrary C code */
174
175         BL      cacheuwbinv(SB)
176
177 WAVE('n')
178         /* undo double map of 0, KZERO */
179         MOVW    $PADDR(L1+L1X(0)), R4           /* address of PTE for 0 */
180         MOVW    $0, R0
181         MOVW    $16, R5
182 _ptudbl:
183         MOVW    R0, (R4)
184         ADD     $4, R4                          /* bump PTE address */
185         ADD     $MiB, R0                        /* bump pa */
186         SUB.S   $1, R5
187         BNE     _ptudbl
188         BARRIERS
189         MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvd), CpTLBinvse
190         MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
191         BARRIERS
192
193 WAVE(' ')
194         /* pass Mach to main and set up the stack */
195         MOVW    $(MACHADDR), R0                 /* Mach */
196         MOVW    R0, R13
197         ADD     $(MACHSIZE), R13                /* stack pointer */
198         SUB     $4, R13                         /* space for link register */
199
200         BL      main(SB)                        /* void main(Mach*) */
201         /* fall through */
202
203
204 /* not used */
205 TEXT _reset(SB), 1, $-4
206         /* turn the caches off */
207         MOVW    $(PsrDirq|PsrDfiq|PsrMsvc), R0
208         MOVW    R0, CPSR
209         BARRIERS
210         BL      cacheuwbinv(SB)
211         MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
212         BIC     $(CpCwb|CpCicache|CpCdcache|CpCalign), R0
213         MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
214         BARRIERS
215 WAVE('R')
216
217         /* redo double map of 0, KZERO */
218         MOVW    $(L1+L1X(0)), R4                /* address of PTE for 0 */
219         MOVW    $PTEDRAM, R2                    /* PTE bits */
220         MOVW    $0, R3
221         MOVW    $16, R5
222 _ptrdbl:
223         ORR     R3, R2, R1              /* first identity-map 0 to 0, etc. */
224         MOVW    R1, (R4)
225         ADD     $4, R4                          /* bump PTE address */
226         ADD     $MiB, R3                        /* bump pa */
227         SUB.S   $1, R5
228         BNE     _ptrdbl
229
230         BARRIERS
231 WAVE('e')
232         MOVW    $0, R0
233         MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvd), CpTLBinv
234         MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
235         BARRIERS
236
237         /* back to 29- or 26-bit addressing, mainly for SB */
238         MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
239         BIC     $(CpCd32|CpCi32), R0
240         MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
241         BARRIERS
242
243         /* turn the MMU off */
244         MOVW    $PHYSDRAM, R0
245         BL      _r15warp(SB)
246         BL      mmuinvalidate(SB)
247         BL      mmudisable(SB)
248
249 WAVE('s')
250         /* set new reset vector */
251         MOVW    $0, R2
252         MOVW    $0xe59ff018, R3                 /* MOVW 0x18(R15), R15 */
253         MOVW    R3, (R2)
254 WAVE('e')
255
256         MOVW    $PHYSBOOTROM, R3
257         MOVW    R3, 0x20(R2)                    /* where $0xe59ff018 jumps to */
258         BARRIERS
259 WAVE('t')
260 WAVE('\r')
261 WAVE('\n')
262
263         /* ...and jump to it */
264         MOVW    R2, R15                         /* software reboot */
265 _limbo:                                         /* should not get here... */
266         B       _limbo                          /* ... and can't get out */
267         BL      _div(SB)                        /* hack to load _div, etc. */
268
269 TEXT _r15warp(SB), 1, $-4
270         BIC     $KSEGM, R14
271         ORR     R0, R14
272         BIC     $KSEGM, R13
273         ORR     R0, R13
274         RET
275
276 /* clobbers R1, R6 */
277 TEXT myputc(SB), 1, $-4
278         MOVW    $PHYSCONS, R6
279 _busy:
280         MOVW    20(R6), R1
281         BIC.S   $~(1<<5), R1                    /* (x->lsr & LSRthre) == 0? */
282         BEQ     _busy
283         MOVW    R3, (R6)                        /* print */
284         ISB
285         RET
286
287 /*
288  * l1 caches
289  */
290
291 TEXT l1cacheson(SB), 1, $-4
292         MOVW    CPSR, R5
293         ORR     $(PsrDirq|PsrDfiq), R5, R4
294         MOVW    R4, CPSR                        /* splhi */
295
296         MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
297         ORR     $(CpCdcache|CpCicache|CpCwb), R0
298         MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
299         BARRIERS
300
301         MOVW    R5, CPSR                        /* splx */
302         RET
303
304 TEXT l1cachesoff(SB), 1, $-4
305         MOVM.DB.W [R14], (SP)                   /* save lr on stack */
306
307         MOVW    CPSR, R5
308         ORR     $(PsrDirq|PsrDfiq), R5, R4
309         MOVW    R4, CPSR                        /* splhi */
310
311         BL      cacheuwbinv(SB)
312
313         MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
314         BIC     $(CpCdcache|CpCicache|CpCwb), R0
315         MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
316         BARRIERS
317
318         MOVW    R5, CPSR                        /* splx */
319         MOVM.IA.W (SP), [R14]                   /* restore lr */
320         RET
321
322 /*
323  * cache* functions affect only the L1 caches, which are VIVT.
324  */
325
326 TEXT cachedwb(SB), 1, $-4                       /* D writeback */
327         MOVW    CPSR, R3                        /* splhi */
328         ORR     $(PsrDirq), R3, R1
329         MOVW    R1, CPSR
330
331         BARRIERS                        /* force outstanding stores to cache */
332         /* keep writing back dirty cache lines until no more exist */
333 _dwb:
334         MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwb), CpCACHEtest
335         BNE     _dwb
336         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
337         BARRIERS
338
339         MOVW    R3, CPSR                        /* splx */
340         RET
341
342 TEXT cachedwbse(SB), 1, $-4                     /* D writeback SE */
343         MOVW    R0, R2                          /* first arg: address */
344
345         MOVW    CPSR, R3                        /* splhi */
346         ORR     $(PsrDirq), R3, R1
347         MOVW    R1, CPSR
348
349         BARRIERS                        /* force outstanding stores to cache */
350         MOVW    4(FP), R1                       /* second arg: size */
351
352 //      CMP.S   $(4*1024), R1
353 //      BGT     _dwb
354         ADD     R2, R1
355         BIC     $(CACHELINESZ-1), R2
356 _dwbse:
357         MCR     CpSC, 0, R2, C(CpCACHE), C(CpCACHEwb), CpCACHEse
358         ADD     $CACHELINESZ, R2
359         CMP.S   R2, R1
360         BGT     _dwbse
361         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
362         BARRIERS
363
364         MOVW    R3, CPSR                        /* splx */
365         RET
366
367 TEXT cachedwbinv(SB), 1, $-4                    /* D writeback+invalidate */
368         MOVW    CPSR, R3                        /* splhi */
369         ORR     $(PsrDirq), R3, R1
370         MOVW    R1, CPSR
371
372         BARRIERS                        /* force outstanding stores to cache */
373         /* keep writing back dirty cache lines until no more exist */
374 _dwbinv:
375         MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
376         BNE     _dwbinv
377         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
378         BARRIERS
379
380         MOVW    R3, CPSR                        /* splx */
381         RET
382
383 TEXT cachedwbinvse(SB), 1, $-4                  /* D writeback+invalidate SE */
384         MOVW    R0, R2                          /* first arg: address */
385
386         MOVW    CPSR, R3                        /* splhi */
387         ORR     $(PsrDirq), R3, R1
388         MOVW    R1, CPSR
389
390         BARRIERS                        /* force outstanding stores to cache */
391         MOVW    4(FP), R1                       /* second arg: size */
392
393         DSB
394 //      CMP.S   $(4*1024), R1
395 //      BGT     _dwbinv
396         ADD     R2, R1
397         BIC     $(CACHELINESZ-1), R2
398 _dwbinvse:
399         MCR     CpSC, 0, R2, C(CpCACHE), C(CpCACHEwbi), CpCACHEse
400         ADD     $CACHELINESZ, R2
401         CMP.S   R2, R1
402         BGT     _dwbinvse
403         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
404         BARRIERS
405
406         MOVW    R3, CPSR                        /* splx */
407         RET
408
409 TEXT cachedinvse(SB), 1, $-4                    /* D invalidate SE */
410         MOVW    R0, R2                          /* first arg: address */
411
412         MOVW    CPSR, R3                        /* splhi */
413         ORR     $(PsrDirq), R3, R1
414         MOVW    R1, CPSR
415
416         MOVW    4(FP), R1                       /* second arg: size */
417
418         DSB
419 //      CMP.S   $(4*1024), R1
420 //      BGT     _dinv
421         ADD     R2, R1
422         BIC     $(CACHELINESZ-1), R2
423 _dinvse:
424         MCR     CpSC, 0, R2, C(CpCACHE), C(CpCACHEinvd), CpCACHEse
425         ADD     $CACHELINESZ, R2
426         CMP.S   R2, R1
427         BGT     _dinvse
428         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
429         BARRIERS
430
431         MOVW    R3, CPSR                        /* splx */
432         RET
433
434 TEXT cacheuwbinv(SB), 1, $-4                    /* D+I writeback+invalidate */
435         MOVW    CPSR, R3                        /* splhi */
436         ORR     $(PsrDirq), R3, R1
437         MOVW    R1, CPSR
438
439         BARRIERS                        /* force outstanding stores to cache */
440         /* keep writing back dirty cache lines until no more exist */
441 _uwbinv:                                        /* D writeback+invalidate */
442         MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
443         BNE     _uwbinv
444         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
445         BARRIERS
446
447         MOVW    $0, R0                          /* I invalidate */
448         MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
449         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
450         BARRIERS
451
452         MOVW    R3, CPSR                        /* splx */
453         RET
454
455 TEXT cacheiinv(SB), 1, $-4                      /* I invalidate */
456         BARRIERS
457         MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
458         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
459         BARRIERS
460         RET
461
462 TEXT cachedinv(SB), 1, $-4                      /* D invalidate */
463 _dinv:
464         BARRIERS
465         MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEall
466         /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
467         BARRIERS
468         RET
469
470 /*
471  * l2 cache
472  *
473  * these functions assume that the necessary l1 cache operations have been
474  * or will be done explicitly by the caller.
475  */
476
477 /* enable l2 cache in config coproc. reg.  do this while l1 caches are off. */
478 TEXT l2cachecfgon(SB), 1, $-4
479         BARRIERS
480         MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
481         BARRIERS
482
483         MRC     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
484         ORR     $(CpTCl2ena | CpTCl2prefdis), R1  /* l2 on, prefetch off */
485         MCR     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
486         BARRIERS
487         RET
488
489 /* disable l2 cache in config coproc. reg.  do this while l1 caches are off. */
490 TEXT l2cachecfgoff(SB), 1, $-4
491         BARRIERS
492         MRC     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
493         BIC     $CpTCl2ena, R1
494         MCR     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
495         BARRIERS
496
497         MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
498         BARRIERS
499         RET
500
501 TEXT l2cacheuwb(SB), 1, $-4                     /* L2 unified writeback */
502         MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2flush), CpTCl2all
503         ISB
504         RET
505
506 TEXT l2cacheuwbse(SB), 1, $-4                   /* L2 unified writeback SE */
507         MOVW    R0, R2                          /* first arg: address */
508
509         MOVW    CPSR, R3                        /* splhi */
510         ORR     $(PsrDirq), R3, R1
511         MOVW    R1, CPSR
512
513         MOVW    4(FP), R1                       /* second arg: size */
514
515         ADD     R2, R1
516         BIC     $(CACHELINESZ-1), R2
517 _l2wbse:
518         MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2flush), CpTCl2seva
519         ADD     $CACHELINESZ, R2
520         CMP.S   R2, R1
521         BGT     _l2wbse
522         ISB
523
524         MOVW    R3, CPSR                        /* splx */
525         RET
526
527 TEXT l2cacheuwbinv(SB), 1, $-4          /* L2 unified writeback+invalidate */
528         MOVW    CPSR, R3                        /* splhi */
529         ORR     $(PsrDirq), R3, R1
530         MOVW    R1, CPSR
531
532         MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2flush), CpTCl2all
533         ISB
534         MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
535         ISB
536
537         MOVW    R3, CPSR                        /* splx */
538         RET
539
540 TEXT l2cacheuwbinvse(SB), 1, $-4        /* L2 unified writeback+invalidate SE */
541         MOVW    R0, R2                          /* first arg: address */
542
543         MOVW    CPSR, R3                        /* splhi */
544         ORR     $(PsrDirq), R3, R1
545         MOVW    R1, CPSR
546
547         MOVW    4(FP), R1                       /* second arg: size */
548
549         ADD     R2, R1
550         BIC     $(CACHELINESZ-1), R2
551 _l2wbinvse:
552         MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2flush), CpTCl2seva
553         ISB
554         MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2inv), CpTCl2seva
555         ADD     $CACHELINESZ, R2
556         CMP.S   R2, R1
557         BGT     _l2wbinvse
558         ISB
559
560         MOVW    R3, CPSR                        /* splx */
561         RET
562
563 TEXT l2cacheuinv(SB), 1, $-4                    /* L2 unified invalidate */
564         MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
565         ISB
566         RET
567
568 TEXT l2cacheuinvse(SB), 1, $-4                  /* L2 unified invalidate SE */
569         MOVW    R0, R2                          /* first arg: address */
570
571         MOVW    CPSR, R3                        /* splhi */
572         ORR     $(PsrDirq), R3, R1
573         MOVW    R1, CPSR
574
575         MOVW    4(FP), R1                       /* second arg: size */
576
577         ADD     R2, R1
578         BIC     $(CACHELINESZ-1), R2
579 _l2invse:
580         MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2inv), CpTCl2seva
581         ADD     $CACHELINESZ, R2
582         CMP.S   R2, R1
583         BGT     _l2invse
584         ISB
585
586         MOVW    R3, CPSR                        /* splx */
587         RET
588
589 /*
590  *  enable mmu, i and d caches, and high vector
591  */
592 TEXT mmuenable(SB), 1, $-4
593         MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
594         ORR     $(CpChv|CpCmmu|CpCdcache|CpCicache|CpCwb|CpCsystem), R0
595         BIC     $(CpCrom), R0
596         MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
597         BARRIERS
598         RET
599
600 TEXT mmudisable(SB), 1, $-4
601         MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
602         BIC     $(CpChv|CpCmmu|CpCdcache|CpCicache|CpCwb), R0
603         MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
604         BARRIERS
605         RET
606
607 TEXT mmuinvalidate(SB), 1, $-4                  /* invalidate all */
608         MOVW    $0, R0
609         MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
610         BARRIERS
611         RET
612
613 TEXT mmuinvalidateaddr(SB), 1, $-4              /* invalidate single entry */
614         MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinvse
615         BARRIERS
616         RET
617
618 TEXT cpidget(SB), 1, $-4                        /* main ID */
619         MRC     CpSC, 0, R0, C(CpID), C(0), CpIDid
620         RET
621
622 TEXT cpctget(SB), 1, $-4                        /* cache type */
623         MRC     CpSC, 0, R0, C(CpID), C(0), CpIDct
624         RET
625
626 TEXT controlget(SB), 1, $-4                     /* control */
627         MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
628         RET
629
630 TEXT ttbget(SB), 1, $-4                         /* translation table base */
631         MRC     CpSC, 0, R0, C(CpTTB), C(0)
632         RET
633
634 TEXT ttbput(SB), 1, $-4                         /* translation table base */
635         MCR     CpSC, 0, R0, C(CpTTB), C(0)
636         ISB
637         RET
638
639 TEXT dacget(SB), 1, $-4                         /* domain access control */
640         MRC     CpSC, 0, R0, C(CpDAC), C(0)
641         RET
642
643 TEXT dacput(SB), 1, $-4                         /* domain access control */
644         MCR     CpSC, 0, R0, C(CpDAC), C(0)
645         ISB
646         RET
647
648 TEXT fsrget(SB), 1, $-4                         /* fault status */
649         MRC     CpSC, 0, R0, C(CpFSR), C(0)
650         RET
651
652 TEXT farget(SB), 1, $-4                         /* fault address */
653         MRC     CpSC, 0, R0, C(CpFAR), C(0x0)
654         RET
655
656 TEXT pidget(SB), 1, $-4                         /* address translation pid */
657         MRC     CpSC, 0, R0, C(CpPID), C(0x0)
658         RET
659
660 TEXT pidput(SB), 1, $-4                         /* address translation pid */
661         MCR     CpSC, 0, R0, C(CpPID), C(0x0)
662         ISB
663         RET
664
665 TEXT splhi(SB), 1, $-4
666         MOVW    $(MACHADDR+4), R2               /* save caller pc in Mach */
667         MOVW    R14, 0(R2)
668
669         MOVW    CPSR, R0                        /* turn off interrupts */
670         ORR     $(PsrDirq), R0, R1
671         MOVW    R1, CPSR
672         RET
673
674 TEXT spllo(SB), 1, $-4
675         MOVW    CPSR, R0
676         BIC     $(PsrDirq), R0, R1
677         MOVW    R1, CPSR
678         RET
679
680 TEXT splx(SB), 1, $-4
681         MOVW    $(MACHADDR+0x04), R2            /* save caller pc in Mach */
682         MOVW    R14, 0(R2)
683
684         MOVW    R0, R1                          /* reset interrupt level */
685         MOVW    CPSR, R0
686         MOVW    R1, CPSR
687         RET
688
689 TEXT splxpc(SB), 1, $-4                         /* for iunlock */
690         MOVW    R0, R1
691         MOVW    CPSR, R0
692         MOVW    R1, CPSR
693         RET
694
695 TEXT spldone(SB), 1, $0
696         RET
697
698 TEXT islo(SB), 1, $-4
699         MOVW    CPSR, R0
700         AND     $(PsrDirq), R0
701         EOR     $(PsrDirq), R0
702         RET
703
704 TEXT splfhi(SB), $-4
705         MOVW    CPSR, R0
706         ORR     $(PsrDfiq|PsrDirq), R0, R1
707         MOVW    R1, CPSR
708         RET
709
710 //TEXT splflo(SB), $-4
711 //      MOVW    CPSR, R0
712 //      BIC     $(PsrDfiq), R0, R1
713 //      MOVW    R1, CPSR
714 //      RET
715
716 TEXT    tas(SB), $-4
717 TEXT    _tas(SB), $-4
718         MOVW    R0,R1
719         MOVW    $1,R0
720         SWPW    R0,(R1)                 /* fix: deprecated in armv7 */
721         RET
722
723 //TEXT tas32(SB), 1, $-4
724 //      MOVW    R0, R1
725 //      MOVW    $0xDEADDEAD, R0
726 //      MOVW    R0, R3
727 //      SWPW    R0, (R1)
728 //      CMP.S   R0, R3
729 //      BEQ     _tasout
730 //      EOR     R3, R3                  /* R3 = 0 */
731 //      CMP.S   R0, R3
732 //      BEQ     _tasout
733 //      MOVW    $1, R15                 /* abort: lock != 0 && lock != $0xDEADDEAD */
734 //_tasout:
735 //      RET
736
737 TEXT clz(SB), 1, $-4
738         CLZ(0, 0)                       /* 0 is R0 */
739         RET
740
741 TEXT setlabel(SB), 1, $-4
742         MOVW    R13, 0(R0)              /* sp */
743         MOVW    R14, 4(R0)              /* pc */
744         BARRIERS
745         MOVW    $0, R0
746         RET
747
748 TEXT gotolabel(SB), 1, $-4
749         MOVW    0(R0), R13              /* sp */
750         MOVW    4(R0), R14              /* pc */
751         BARRIERS
752         MOVW    $1, R0
753         RET
754
755 TEXT getcallerpc(SB), 1, $-4
756         MOVW    0(R13), R0
757         RET
758
759 TEXT _idlehands(SB), 1, $-4
760         MOVW    CPSR, R3
761 //      ORR     $PsrDirq, R3, R1                /* splhi */
762         BIC     $PsrDirq, R3, R1                /* spllo */
763         MOVW    R1, CPSR
764
765         MOVW    $0, R0                          /* wait for interrupt */
766         MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEintr), CpCACHEwait
767         ISB
768
769         MOVW    R3, CPSR                        /* splx */
770         RET
771
772 TEXT barriers(SB), 1, $-4
773         BARRIERS
774         RET