]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/ppc/l.s
pc/vga*: use 64-bit physical addresses and check pci membar types and sizes
[plan9front.git] / sys / src / 9 / ppc / l.s
1 #include        "mem.h"
2
3 /* use of SPRG registers in save/restore */
4 #define SAVER0  SPRG0
5 #define SAVER1  SPRG1
6 #define SAVELR  SPRG2
7 #define SAVEXX  SPRG3
8
9 #ifdef ucuconf
10 /* These only exist on the PPC 755: */
11 #define SAVER4  SPRG4
12 #define SAVER5  SPRG5
13 #define SAVER6  SPRG6
14 #define SAVER7  SPRG7
15 #endif /* ucuconf */
16
17 /* special instruction definitions */
18 #define BDNZ            BC      16, 0,
19 #define BDNE            BC      0, 2,
20 #define MTCRF(r, crm)   WORD    $((31<<26)|((r)<<21)|(crm<<12)|(144<<1))
21
22 /* #define      TLBIA   WORD    $((31<<26)|(370<<1)) Not implemented on the 603e */
23 #define TLBSYNC         WORD    $((31<<26)|(566<<1))
24 #define TLBLI(n)        WORD    $((31<<26)|((n)<<11)|(1010<<1))
25 #define TLBLD(n)        WORD    $((31<<26)|((n)<<11)|(978<<1))
26
27 /* on some models mtmsr doesn't synchronise enough (eg, 603e) */
28 #define MSRSYNC SYNC
29
30 #define UREGSPACE       (UREGSIZE+8)
31
32 TEXT start(SB), $-4
33
34         /*
35          * setup MSR
36          * turn off interrupts
37          * use 0x000 as exception prefix
38          * enable machine check
39          */
40         MOVW    MSR, R3
41         MOVW    $(MSR_ME|MSR_EE|MSR_IP), R4
42         ANDN    R4, R3
43         SYNC
44         MOVW    R3, MSR
45         MSRSYNC
46
47         /* except during trap handling, R0 is zero from now on */
48         MOVW    $0, R0
49
50         /* setup SB for pre mmu */
51         MOVW    $setSB(SB), R2
52         MOVW    $KZERO, R3
53         ANDN    R3, R2
54
55         /* before this we're not running above KZERO */
56         BL      mmuinit0(SB)
57         /* after this we are */
58
59 #ifdef ucuconf
60         MOVW    $0x2000000, R4          /* size */
61         MOVW    $0, R3                  /* base address */
62         RLWNM   $0, R3, $~(CACHELINESZ-1), R5
63         CMP     R4, $0
64         BLE     _dcf1
65         SUB     R5, R3
66         ADD     R3, R4
67         ADD     $(CACHELINESZ-1), R4
68         SRAW    $CACHELINELOG, R4
69         MOVW    R4, CTR
70 _dcf0:  DCBF    (R5)
71         ADD     $CACHELINESZ, R5
72         BDNZ    _dcf0
73 _dcf1:
74         SYNC
75
76         /* BAT0, 3 unused, copy of BAT2 */
77         MOVW    SPR(IBATL(2)), R3
78         MOVW    R3, SPR(IBATL(0))
79         MOVW    SPR(IBATU(2)), R3
80         MOVW    R3, SPR(IBATU(0))
81         MOVW    SPR(DBATL(2)), R3
82         MOVW    R3, SPR(DBATL(0))
83         MOVW    SPR(DBATU(2)), R3
84         MOVW    R3, SPR(DBATU(0))
85
86         MOVW    SPR(IBATL(2)), R3
87         MOVW    R3, SPR(IBATL(3))
88         MOVW    SPR(IBATU(2)), R3
89         MOVW    R3, SPR(IBATU(3))
90         MOVW    SPR(DBATL(2)), R3
91         MOVW    R3, SPR(DBATL(3))
92         MOVW    SPR(DBATU(2)), R3
93         MOVW    R3, SPR(DBATU(3))
94 #endif /* ucuconf */
95
96         /* running with MMU on!! */
97
98         /* set R2 to correct value */
99         MOVW    $setSB(SB), R2
100
101         /* set up Mach */
102         MOVW    $MACHADDR, R(MACH)
103         ADD     $(MACHSIZE-8), R(MACH), R1      /* set stack */
104
105         MOVW    R0, R(USER)             /* up-> set to zero */
106         MOVW    R0, 0(R(MACH))          /* machno set to zero */
107
108         BL      main(SB)
109
110         RETURN                          /* not reached */
111
112 /*
113  * on return from this function we will be running in virtual mode.
114  * We set up the Block Address Translation (BAT) registers thus:
115  * 1) first 3 BATs are 256M blocks, starting from KZERO->0
116  * 2) remaining BAT maps last 256M directly
117  */
118 TEXT mmuinit0(SB), $0
119         /* reset all the tlbs */
120         MOVW    $64, R3
121         MOVW    R3, CTR
122         MOVW    $0, R4
123
124 tlbloop:
125         TLBIE   R4
126         SYNC
127         ADD     $BIT(19), R4
128         BDNZ    tlbloop
129         TLBSYNC
130
131 #ifndef ucuconf
132         /* BATs 0 and 1 cover memory from 0x00000000 to 0x20000000 */
133
134         /* KZERO -> 0, IBAT and DBAT, 256 MB */
135         MOVW    $(KZERO|(0x7ff<<2)|2), R3
136         MOVW    $(PTEVALID|PTEWRITE), R4        /* PTEVALID => Cache coherency on */
137         MOVW    R3, SPR(IBATU(0))
138         MOVW    R4, SPR(IBATL(0))
139         MOVW    R3, SPR(DBATU(0))
140         MOVW    R4, SPR(DBATL(0))
141
142         /* KZERO+256M -> 256M, IBAT and DBAT, 256 MB */
143         ADD     $(1<<28), R3
144         ADD     $(1<<28), R4
145         MOVW    R3, SPR(IBATU(1))
146         MOVW    R4, SPR(IBATL(1))
147         MOVW    R3, SPR(DBATU(1))
148         MOVW    R4, SPR(DBATL(1))
149
150         /* FPGABASE -> FPGABASE, DBAT, 16 MB */
151         MOVW    $(FPGABASE|(0x7f<<2)|2), R3
152         MOVW    $(FPGABASE|PTEWRITE|PTEUNCACHED), R4    /* FPGA memory, don't cache */
153         MOVW    R3, SPR(DBATU(2))
154         MOVW    R4, SPR(DBATL(2))
155
156         /* IBAT 2 unused */
157         MOVW    R0, SPR(IBATU(2))
158         MOVW    R0, SPR(IBATL(2))
159
160         /* direct map last block, uncached, (not guarded, doesn't work for BAT), DBAT only */
161         MOVW    $(INTMEM|(0x7ff<<2)|2), R3
162         MOVW    $(INTMEM|PTEWRITE|PTEUNCACHED), R4      /* Don't set PTEVALID here */
163         MOVW    R3, SPR(DBATU(3))
164         MOVW    R4, SPR(DBATL(3))
165
166         /* IBAT 3 unused */
167         MOVW    R0, SPR(IBATU(3))
168         MOVW    R0, SPR(IBATL(3))
169 #else /* ucuconf */
170         /* BAT 2 covers memory from 0x00000000 to 0x10000000 */
171
172         /* KZERO -> 0, IBAT2 and DBAT2, 256 MB */
173         MOVW    $(KZERO|(0x7ff<<2)|2), R3
174         MOVW    $(PTEVALID|PTEWRITE), R4        /* PTEVALID => Cache coherency on */
175         MOVW    R3, SPR(DBATU(2))
176         MOVW    R4, SPR(DBATL(2))
177         MOVW    R3, SPR(IBATU(2))
178         MOVW    R4, SPR(IBATL(2))
179 #endif /* ucuconf */
180
181         /* enable MMU */
182         MOVW    LR, R3
183         OR      $KZERO, R3
184         MOVW    R3, SPR(SRR0)           /* Stored PC for RFI instruction */
185         MOVW    MSR, R4
186         OR      $(MSR_IR|MSR_DR|MSR_RI|MSR_FP), R4
187         MOVW    R4, SPR(SRR1)
188         RFI                             /* resume in kernel mode in caller */
189
190         RETURN
191
192 TEXT kfpinit(SB), $0
193         MOVFL   $0, FPSCR(7)
194         MOVFL   $0xD, FPSCR(6)          /* VE, OE, ZE */
195         MOVFL   $0, FPSCR(5)
196         MOVFL   $0, FPSCR(3)
197         MOVFL   $0, FPSCR(2)
198         MOVFL   $0, FPSCR(1)
199         MOVFL   $0, FPSCR(0)
200
201         FMOVD   $4503601774854144.0, F27
202         FMOVD   $0.5, F29
203         FSUB    F29, F29, F28
204         FADD    F29, F29, F30
205         FADD    F30, F30, F31
206         FMOVD   F28, F0
207         FMOVD   F28, F1
208         FMOVD   F28, F2
209         FMOVD   F28, F3
210         FMOVD   F28, F4
211         FMOVD   F28, F5
212         FMOVD   F28, F6
213         FMOVD   F28, F7
214         FMOVD   F28, F8
215         FMOVD   F28, F9
216         FMOVD   F28, F10
217         FMOVD   F28, F11
218         FMOVD   F28, F12
219         FMOVD   F28, F13
220         FMOVD   F28, F14
221         FMOVD   F28, F15
222         FMOVD   F28, F16
223         FMOVD   F28, F17
224         FMOVD   F28, F18
225         FMOVD   F28, F19
226         FMOVD   F28, F20
227         FMOVD   F28, F21
228         FMOVD   F28, F22
229         FMOVD   F28, F23
230         FMOVD   F28, F24
231         FMOVD   F28, F25
232         FMOVD   F28, F26
233         RETURN
234
235 TEXT splhi(SB), $0
236         MOVW    LR, R31
237         MOVW    R31, 4(R(MACH))         /* save PC in m->splpc */
238         MOVW    MSR, R3
239         RLWNM   $0, R3, $~MSR_EE, R4
240         SYNC
241         MOVW    R4, MSR
242         MSRSYNC
243         RETURN
244
245 TEXT splx(SB), $0
246         /* fall though */
247
248 TEXT splxpc(SB), $0
249         MOVW    LR, R31
250         MOVW    R31, 4(R(MACH))         /* save PC in m->splpc */
251         MOVW    MSR, R4
252         RLWMI   $0, R3, $MSR_EE, R4
253         SYNC
254         MOVW    R4, MSR
255         MSRSYNC
256         RETURN
257
258 TEXT spllo(SB), $0
259         MOVW    MSR, R3
260         OR      $MSR_EE, R3, R4
261         SYNC
262         MOVW    R4, MSR
263         MSRSYNC
264         RETURN
265
266 TEXT spldone(SB), $0
267         RETURN
268
269 TEXT islo(SB), $0
270         MOVW    MSR, R3
271         RLWNM   $0, R3, $MSR_EE, R3
272         RETURN
273
274 TEXT setlabel(SB), $-4
275         MOVW    LR, R31
276         MOVW    R1, 0(R3)
277         MOVW    R31, 4(R3)
278         MOVW    $0, R3
279         RETURN
280
281 TEXT gotolabel(SB), $-4
282         MOVW    4(R3), R31
283         MOVW    R31, LR
284         MOVW    0(R3), R1
285         MOVW    $1, R3
286         RETURN
287
288 TEXT touser(SB), $-4
289         MOVW    $(UTZERO+32), R5        /* header appears in text */
290         MOVW    $(MSR_EE|MSR_PR|MSR_IR|MSR_DR|MSR_RI), R4
291         MOVW    R4, SPR(SRR1)
292         MOVW    R3, R1
293         MOVW    R5, SPR(SRR0)
294         RFI
295
296 TEXT dczap(SB), $-4                     /* dczap(virtaddr, count) */
297         MOVW    n+4(FP), R4
298         RLWNM   $0, R3, $~(CACHELINESZ-1), R5
299         CMP     R4, $0
300         BLE     dcz1
301         SUB     R5, R3
302         ADD     R3, R4
303         ADD     $(CACHELINESZ-1), R4
304         SRAW    $CACHELINELOG, R4
305         MOVW    R4, CTR
306 dcz0:
307         DCBI    (R5)
308         ADD     $CACHELINESZ, R5
309         BDNZ    dcz0
310 dcz1:
311         SYNC
312         RETURN
313
314 TEXT dcflush(SB), $-4                   /* dcflush(virtaddr, count) */
315         MOVW    n+4(FP), R4
316         RLWNM   $0, R3, $~(CACHELINESZ-1), R5
317         CMP     R4, $0
318         BLE     dcf1
319         SUB     R5, R3
320         ADD     R3, R4
321         ADD     $(CACHELINESZ-1), R4
322         SRAW    $CACHELINELOG, R4
323         MOVW    R4, CTR
324 dcf0:   DCBST   (R5)
325         ADD     $CACHELINESZ, R5
326         BDNZ    dcf0
327 dcf1:
328         SYNC
329         RETURN
330
331 TEXT icflush(SB), $-4                   /* icflush(virtaddr, count) */
332         MOVW    n+4(FP), R4
333         RLWNM   $0, R3, $~(CACHELINESZ-1), R5
334         CMP     R4, $0
335         BLE     icf1
336         SUB     R5, R3
337         ADD     R3, R4
338         ADD     $(CACHELINESZ-1), R4
339         SRAW    $CACHELINELOG, R4
340         MOVW    R4, CTR
341 icf0:   ICBI    (R5)                    /* invalidate the instruction cache */
342         ADD     $CACHELINESZ, R5
343         BDNZ    icf0
344         ISYNC
345 icf1:
346         RETURN
347
348 TEXT tas(SB), $0
349 TEXT _tas(SB), $0
350         MOVW    R3, R4
351         MOVW    $0xdead, R5
352 tas1:
353         DCBF    (R4)                    /* fix for 603x bug */
354         SYNC
355         LWAR    (R4), R3
356         CMP     R3, $0
357         BNE     tas0
358         STWCCC  R5, (R4)
359         BNE     tas1
360         EIEIO
361 tas0:
362         SYNC
363         RETURN
364
365 TEXT tlbflushall(SB), $0
366         MOVW    $TLBENTRIES, R3
367         MOVW    R3, CTR
368         MOVW    $0, R4
369         ISYNC
370 tlbflushall0:
371         TLBIE   R4
372         SYNC
373         ADD     $BIT(19), R4
374         BDNZ    tlbflushall0
375         TLBSYNC
376         RETURN
377
378 TEXT tlbflush(SB), $0
379         ISYNC
380         TLBIE   R3
381         SYNC
382         TLBSYNC
383         RETURN
384
385 TEXT gotopc(SB), $0
386         MOVW    R3, CTR
387         MOVW    LR, R31                 /* for trace back */
388         BR      (CTR)
389
390 /* On an imiss, we get here.  If we can resolve it, we do.
391  * Otherwise take the real trap.  The code at the vector is
392  *      MOVW    R0, SPR(SAVER0) No point to this, of course
393  *      MOVW    LR, R0
394  *      MOVW    R0, SPR(SAVELR)
395  *      BL      imiss(SB)               or dmiss, as the case may be
396  *      BL      tlbvec(SB)
397  */
398 TEXT imiss(SB), $-4
399         /* Statistics */
400         MOVW    $MACHPADDR, R1
401         MOVW    0xc(R1), R3             /* count m->tlbfault */
402         ADD     $1, R3
403         MOVW    R3, 0xc(R1)
404         MOVW    0x10(R1), R3            /* count m->imiss */
405         ADD     $1, R3
406         MOVW    R3, 0x10(R1)
407
408         /* Real work */
409         MOVW    SPR(HASH1), R1          /* (phys) pointer into the hash table */
410         ADD     $BY2PTEG, R1, R2        /* end pointer */
411         MOVW    SPR(iCMP), R3           /* pattern to look for */
412 imiss1:
413         MOVW    (R1), R0
414         CMP     R3, R0
415         BEQ     imiss2                  /* found the entry */
416         ADD     $8, R1
417         CMP     R1, R2                  /* test end of loop */
418         BNE     imiss1                  /* Loop */
419         /* Failed to find an entry; take the full trap */
420         MOVW    SPR(SRR1), R1
421         MTCRF(1, 0x80)                  /* restore CR0 bits (they're auto saved in SRR1) */
422         RETURN
423 imiss2:
424         /* Found the entry */
425         MOVW    4(R1), R2               /* Phys addr */
426         MOVW    R2, SPR(RPA)
427         MOVW    SPR(IMISS), R3
428         TLBLI(3)
429
430         /* Restore Registers */
431         MOVW    SPR(SRR1), R1           /* Restore the CR0 field of the CR register from SRR1 */
432         MTCRF(1, 0x80)
433         MOVW    SPR(SAVELR), R0
434         MOVW    R0, LR
435         RFI
436
437 /* On a data load or store miss, we get here.  If we can resolve it, we do.
438  * Otherwise take the real trap
439  */
440 TEXT dmiss(SB), $-4
441         /* Statistics */
442         MOVW    $MACHPADDR, R1
443         MOVW    0xc(R1), R3             /* count m->tlbfault */
444         ADD     $1, R3
445         MOVW    R3, 0xc(R1)
446         MOVW    0x14(R1), R3            /* count m->dmiss */
447         ADD     $1, R3
448         MOVW    R3, 0x14(R1)
449         /* Real work */
450         MOVW    SPR(HASH1), R1          /* (phys) pointer into the hash table */
451         ADD     $BY2PTEG, R1, R2        /* end pointer */
452         MOVW    SPR(DCMP), R3           /* pattern to look for */
453 dmiss1:
454         MOVW    (R1), R0
455         CMP     R3, R0
456         BEQ     dmiss2                  /* found the entry */
457         ADD     $8, R1
458         CMP     R1, R2                  /* test end of loop */
459         BNE     dmiss1                  /* Loop */
460         /* Failed to find an entry; take the full trap */
461         MOVW    SPR(SRR1), R1
462         MTCRF(1, 0x80)                  /* restore CR0 bits (they're auto saved in SRR1) */
463         RETURN
464 dmiss2:
465         /* Found the entry */
466         MOVW    4(R1), R2               /* Phys addr */
467         MOVW    R2, SPR(RPA)
468         MOVW    SPR(DMISS), R3
469         TLBLD(3)
470         /* Restore Registers */
471         MOVW    SPR(SRR1), R1           /* Restore the CR0 field of the CR register from SRR1 */
472         MTCRF(1, 0x80)
473         MOVW    SPR(SAVELR), R0
474         MOVW    R0, LR
475         RFI
476
477 /*
478  * When a trap sets the TGPR bit (TLB miss traps do this),
479  * registers get remapped: R0-R31 are temporarily inaccessible,
480  * and Temporary Registers TR0-TR3 are mapped onto R0-R3.
481  * While this bit is set, R4-R31 cannot be used.
482  * The code at the vector has executed this code before
483  * coming to tlbvec:
484  *      MOVW    R0, SPR(SAVER0) No point to this, of course
485  *      MOVW    LR, R0
486  *      MOVW    R0, SPR(SAVELR)
487  *      BL      tlbvec(SB)
488  * SAVER0 can be reused.  We're not interested in the value of TR0
489  */
490 TEXT tlbvec(SB), $-4
491         MOVW    MSR, R1
492         RLWNM   $0, R1, $~MSR_TGPR, R1  /* Clear the dreaded TGPR bit in the MSR */
493         SYNC
494         MOVW    R1, MSR
495         MSRSYNC
496         /* Now the GPRs are what they're supposed to be, save R0 again */
497         MOVW    R0, SPR(SAVER0)
498         /* Fall through to trapvec */
499
500 /*
501  * traps force memory mapping off.
502  * the following code has been executed at the exception
503  * vector location
504  *      MOVW    R0, SPR(SAVER0)
505  *      MOVW    LR, R0
506  *      MOVW    R0, SPR(SAVELR)
507  *      bl      trapvec(SB)
508  *
509  */
510 TEXT trapvec(SB), $-4
511         MOVW    LR, R0
512         MOVW    R1, SPR(SAVER1)
513         MOVW    R0, SPR(SAVEXX)         /* vector */
514
515         /* did we come from user space */
516         MOVW    SPR(SRR1), R0
517         MOVW    CR, R1
518         MOVW    R0, CR
519         BC      4, 17, ktrap
520
521         /* switch to kernel stack */
522         MOVW    R1, CR
523         MOVW    $MACHPADDR, R1          /* PADDR(m->) */
524         MOVW    8(R1), R1               /* m->proc */
525         RLWNM   $0, R1, $~KZERO, R1     /* PADDR(m->proc) */
526         MOVW    8(R1), R1               /* m->proc->kstack */
527         RLWNM   $0, R1, $~KZERO, R1     /* PADDR(m->proc->kstack) */
528         ADD     $(KSTACK-UREGSIZE), R1  /* make room on stack */
529
530         BL      saveureg(SB)
531         BL      trap(SB)
532         BR      restoreureg
533
534 ktrap:
535         MOVW    R1, CR
536         MOVW    SPR(SAVER1), R1
537         RLWNM   $0, R1, $~KZERO, R1     /* set stack pointer */
538         SUB     $UREGSPACE, R1
539
540         BL      saveureg(SB)            /* addressed relative to PC */
541         BL      trap(SB)
542         BR      restoreureg
543
544 /*
545  * enter with stack set and mapped.
546  * on return, SB (R2) has been set, and R3 has the Ureg*,
547  * the MMU has been re-enabled, kernel text and PC are in KSEG,
548  * R(MACH) has been set, and R0 contains 0.
549  *
550  */
551 TEXT saveureg(SB), $-4
552 /*
553  * save state
554  */
555         MOVMW   R2, 48(R1)              /* save r2 .. r31 in 48(R1) .. 164(R1) */
556         MOVW    $MACHPADDR, R(MACH)     /* PADDR(m->) */
557         MOVW    8(R(MACH)), R(USER)     /* up-> */
558         MOVW    $MACHADDR, R(MACH)      /* m-> */
559         MOVW    SPR(SAVER1), R4
560         MOVW    R4, 44(R1)
561         MOVW    SPR(SAVER0), R5
562         MOVW    R5, 40(R1)
563         MOVW    CTR, R6
564         MOVW    R6, 36(R1)
565         MOVW    XER, R4
566         MOVW    R4, 32(R1)
567         MOVW    CR, R5
568         MOVW    R5, 28(R1)
569         MOVW    SPR(SAVELR), R6         /* LR */
570         MOVW    R6, 24(R1)
571         /* pad at 20(R1) */
572         MOVW    SPR(SRR0), R0
573         MOVW    R0, 16(R1)              /* old PC */
574         MOVW    SPR(SRR1), R0
575         MOVW    R0, 12(R1)              /* old status */
576         MOVW    SPR(SAVEXX), R0
577         MOVW    R0, 8(R1)               /* cause/vector */
578         MOVW    SPR(DCMP), R0
579         MOVW    R0, (160+8)(R1)
580         MOVW    SPR(iCMP), R0
581         MOVW    R0, (164+8)(R1)
582         MOVW    SPR(DMISS), R0
583         MOVW    R0, (168+8)(R1)
584         MOVW    SPR(IMISS), R0
585         MOVW    R0, (172+8)(R1)
586         MOVW    SPR(HASH1), R0
587         MOVW    R0, (176+8)(R1)
588         MOVW    SPR(HASH2), R0
589         MOVW    R0, (180+8)(R1)
590         MOVW    SPR(DAR), R0
591         MOVW    R0, (184+8)(R1)
592         MOVW    SPR(DSISR), R0
593         MOVW    R0, (188+8)(R1)
594         ADD     $8, R1, R3              /* Ureg* */
595         OR      $KZERO, R3              /* fix ureg */
596         STWCCC  R3, (R1)                /* break any pending reservations */
597         MOVW    $0, R0                  /* compiler/linker expect R0 to be zero */
598         MOVW    $setSB(SB), R2          /* SB register */
599
600         MOVW    MSR, R5
601         OR      $(MSR_IR|MSR_DR|MSR_FP|MSR_RI), R5      /* enable MMU */
602         MOVW    R5, SPR(SRR1)
603         MOVW    LR, R31
604         OR      $KZERO, R31             /* return PC in KSEG0 */
605         MOVW    R31, SPR(SRR0)
606         OR      $KZERO, R1              /* fix stack pointer */
607         RFI                             /* returns to trap handler */
608
609 /*
610  * restore state from Ureg and return from trap/interrupt
611  */
612 TEXT forkret(SB), $0
613         BR      restoreureg
614
615 restoreureg:
616         MOVMW   48(R1), R2              /* restore r2 through r31 */
617         /* defer R1 */
618         MOVW    40(R1), R0
619         MOVW    R0, SPR(SAVER0)         /* resave saved R0 */
620         MOVW    36(R1), R0
621         MOVW    R0, CTR
622         MOVW    32(R1), R0
623         MOVW    R0, XER
624         MOVW    28(R1), R0
625         MOVW    R0, CR                  /* Condition register*/
626         MOVW    24(R1), R0
627         MOVW    R0, LR
628         /* pad, skip */
629         MOVW    16(R1), R0
630         MOVW    R0, SPR(SRR0)           /* old PC */
631         MOVW    12(R1), R0
632         MOVW    R0, SPR(SRR1)           /* old MSR */
633         /* cause, skip */
634         MOVW    44(R1), R1              /* old SP */
635         MOVW    SPR(SAVER0), R0
636         RFI
637
638 TEXT getpvr(SB), $0
639         MOVW    SPR(PVR), R3
640         RETURN
641
642 TEXT getdec(SB), $0
643         MOVW    SPR(DEC), R3
644         RETURN
645
646 TEXT putdec(SB), $0
647         MOVW    R3, SPR(DEC)
648         RETURN
649
650 TEXT getdar(SB), $0
651         MOVW    SPR(DAR), R3
652         RETURN
653
654 TEXT getdsisr(SB), $0
655         MOVW    SPR(DSISR), R3
656         RETURN
657
658 TEXT getmsr(SB), $0
659         MOVW    MSR, R3
660         RETURN
661
662 TEXT putmsr(SB), $0
663         MOVW    R3, MSR
664         MSRSYNC
665         RETURN
666
667 TEXT putsdr1(SB), $0
668         SYNC
669         MOVW    R3, SPR(SDR1)
670         ISYNC
671         RETURN
672
673 TEXT putsr(SB), $0
674         MOVW    4(FP), R4
675         SYNC
676         MOVW    R4, SEG(R3)
677         MSRSYNC
678         RETURN
679
680 TEXT getsr(SB), $0
681         MOVW    SEG(R3), R3
682         RETURN
683
684 TEXT gethid0(SB), $0
685         MOVW    SPR(HID0), R3
686         RETURN
687
688 TEXT puthid0(SB), $0
689         SYNC
690         ISYNC
691         MOVW    R3, SPR(HID0)
692         SYNC
693         RETURN
694
695 TEXT gethid1(SB), $0
696         MOVW    SPR(HID1), R3
697         RETURN
698
699 TEXT gethid2(SB), $0
700         MOVW    SPR(HID2), R3
701         RETURN
702
703 TEXT puthid2(SB), $0
704         MOVW    R3, SPR(HID2)
705         RETURN
706
707 TEXT eieio(SB), $0
708         EIEIO
709         RETURN
710
711 TEXT sync(SB), $0
712         SYNC
713         RETURN
714
715 /* Power PC 603e specials */
716 TEXT getimiss(SB), $0
717         MOVW    SPR(IMISS), R3
718         RETURN
719
720 TEXT geticmp(SB), $0
721         MOVW    SPR(iCMP), R3
722         RETURN
723
724 TEXT puticmp(SB), $0
725         MOVW    R3, SPR(iCMP)
726         RETURN
727
728 TEXT getdmiss(SB), $0
729         MOVW    SPR(DMISS), R3
730         RETURN
731
732 TEXT getdcmp(SB), $0
733         MOVW    SPR(DCMP), R3
734         RETURN
735
736 TEXT putdcmp(SB), $0
737         MOVW    R3, SPR(DCMP)
738         RETURN
739
740 TEXT getsdr1(SB), $0
741         MOVW    SPR(SDR1), R3
742         RETURN
743
744 TEXT gethash1(SB), $0
745         MOVW    SPR(HASH1), R3
746         RETURN
747
748 TEXT puthash1(SB), $0
749         MOVW    R3, SPR(HASH1)
750         RETURN
751
752 TEXT gethash2(SB), $0
753         MOVW    SPR(HASH2), R3
754         RETURN
755
756 TEXT puthash2(SB), $0
757         MOVW    R3, SPR(HASH2)
758         RETURN
759
760 TEXT getrpa(SB), $0
761         MOVW    SPR(RPA), R3
762         RETURN
763
764 TEXT putrpa(SB), $0
765         MOVW    R3, SPR(RPA)
766         RETURN
767
768 TEXT tlbli(SB), $0
769         TLBLI(3)
770         ISYNC
771         RETURN
772
773 TEXT tlbld(SB), $0
774         SYNC
775         TLBLD(3)
776         ISYNC
777         RETURN
778
779 TEXT getsrr1(SB), $0
780         MOVW    SPR(SRR1), R3
781         RETURN
782
783 TEXT putsrr1(SB), $0
784         MOVW    R3, SPR(SRR1)
785         RETURN
786
787 TEXT fpsave(SB), $0
788         FMOVD   F0, (0*8)(R3)
789         FMOVD   F1, (1*8)(R3)
790         FMOVD   F2, (2*8)(R3)
791         FMOVD   F3, (3*8)(R3)
792         FMOVD   F4, (4*8)(R3)
793         FMOVD   F5, (5*8)(R3)
794         FMOVD   F6, (6*8)(R3)
795         FMOVD   F7, (7*8)(R3)
796         FMOVD   F8, (8*8)(R3)
797         FMOVD   F9, (9*8)(R3)
798         FMOVD   F10, (10*8)(R3)
799         FMOVD   F11, (11*8)(R3)
800         FMOVD   F12, (12*8)(R3)
801         FMOVD   F13, (13*8)(R3)
802         FMOVD   F14, (14*8)(R3)
803         FMOVD   F15, (15*8)(R3)
804         FMOVD   F16, (16*8)(R3)
805         FMOVD   F17, (17*8)(R3)
806         FMOVD   F18, (18*8)(R3)
807         FMOVD   F19, (19*8)(R3)
808         FMOVD   F20, (20*8)(R3)
809         FMOVD   F21, (21*8)(R3)
810         FMOVD   F22, (22*8)(R3)
811         FMOVD   F23, (23*8)(R3)
812         FMOVD   F24, (24*8)(R3)
813         FMOVD   F25, (25*8)(R3)
814         FMOVD   F26, (26*8)(R3)
815         FMOVD   F27, (27*8)(R3)
816         FMOVD   F28, (28*8)(R3)
817         FMOVD   F29, (29*8)(R3)
818         FMOVD   F30, (30*8)(R3)
819         FMOVD   F31, (31*8)(R3)
820         MOVFL   FPSCR, F0
821         FMOVD   F0, (32*8)(R3)
822         RETURN
823
824 TEXT fprestore(SB), $0
825         FMOVD   (32*8)(R3), F0
826         MOVFL   F0, FPSCR
827         FMOVD   (0*8)(R3), F0
828         FMOVD   (1*8)(R3), F1
829         FMOVD   (2*8)(R3), F2
830         FMOVD   (3*8)(R3), F3
831         FMOVD   (4*8)(R3), F4
832         FMOVD   (5*8)(R3), F5
833         FMOVD   (6*8)(R3), F6
834         FMOVD   (7*8)(R3), F7
835         FMOVD   (8*8)(R3), F8
836         FMOVD   (9*8)(R3), F9
837         FMOVD   (10*8)(R3), F10
838         FMOVD   (11*8)(R3), F11
839         FMOVD   (12*8)(R3), F12
840         FMOVD   (13*8)(R3), F13
841         FMOVD   (14*8)(R3), F14
842         FMOVD   (15*8)(R3), F15
843         FMOVD   (16*8)(R3), F16
844         FMOVD   (17*8)(R3), F17
845         FMOVD   (18*8)(R3), F18
846         FMOVD   (19*8)(R3), F19
847         FMOVD   (20*8)(R3), F20
848         FMOVD   (21*8)(R3), F21
849         FMOVD   (22*8)(R3), F22
850         FMOVD   (23*8)(R3), F23
851         FMOVD   (24*8)(R3), F24
852         FMOVD   (25*8)(R3), F25
853         FMOVD   (26*8)(R3), F26
854         FMOVD   (27*8)(R3), F27
855         FMOVD   (28*8)(R3), F28
856         FMOVD   (29*8)(R3), F29
857         FMOVD   (30*8)(R3), F30
858         FMOVD   (31*8)(R3), F31
859         RETURN
860
861 TEXT dcacheenb(SB), $0
862         SYNC
863         MOVW    SPR(HID0), R4           /* Get HID0 and clear unwanted bits */
864         RLWNM   $0, R4, $~(HID_DLOCK), R4
865         MOVW    $(HID_DCFI|HID_DCE), R5
866         OR      R4, R5
867         MOVW    $HID_DCE, R3
868         OR      R4, R3
869         SYNC
870 //      MOVW    R5, SPR(HID0)           /* Cache enable and flash invalidate */
871         MOVW    R3, SPR(HID0)           /* Cache enable */
872         SYNC
873         RETURN
874
875 TEXT icacheenb(SB), $0
876         SYNC
877         MOVW    SPR(HID0), R4           /* Get HID0 and clear unwanted bits */
878         RLWNM   $0, R4, $~(HID_ILOCK), R4
879         MOVW    $(HID_ICFI|HID_ICE), R5
880         OR      R4, R5
881         MOVW    $HID_ICE, R3
882         OR      R4, R3
883         SYNC
884         MOVW    R5, SPR(HID0)           /* Cache enable and flash invalidate */
885         MOVW    R3, SPR(HID0)           /* Cache enable */
886         SYNC
887         RETURN
888
889 #ifdef ucuconf
890 TEXT getpll(SB), $0
891         MOVW    SPR(1009), R3
892         ISYNC
893         RETURN
894
895 TEXT getl2pm(SB), $0
896         MOVW    SPR(1016), R3
897         RETURN
898
899 TEXT getl2cr(SB), $0
900         MOVW    SPR(1017), R3
901         RETURN
902
903 TEXT putl2cr(SB), $0
904         MOVW    R3, SPR(1017)
905         RETURN
906
907 TEXT dcachedis(SB), $0
908         SYNC
909 /*      MOVW    SPR(HID0), R4
910         RLWNM   $0, R4, $~(HID_DCE), R4
911         MOVW    R4, SPR(HID0)           /* L1 Cache disable */
912
913         MOVW    SPR(1017), R4
914         RLWNM   $0, R4, $~(0x80000000), R4
915         MOVW    R4, SPR(1017)           /* L2 Cache disable */
916
917         SYNC
918         RETURN
919
920 TEXT l2disable(SB), $0
921         SYNC
922         MOVW    SPR(1017), R4
923         RLWNM   $0, R4, $~(0x80000000), R4
924         MOVW    R4, SPR(1017)           /* L2 Cache disable */
925         SYNC
926         RETURN
927
928 TEXT getbats(SB), $0
929         MOVW    SPR(DBATU(0)), R4
930         MOVW    R4, 0(R3)
931         MOVW    SPR(DBATL(0)), R4
932         MOVW    R4, 4(R3)
933         MOVW    SPR(IBATU(0)), R4
934         MOVW    R4, 8(R3)
935         MOVW    SPR(IBATL(0)), R4
936         MOVW    R4, 12(R3)
937         MOVW    SPR(DBATU(1)), R4
938         MOVW    R4, 16(R3)
939         MOVW    SPR(DBATL(1)), R4
940         MOVW    R4, 20(R3)
941         MOVW    SPR(IBATU(1)), R4
942         MOVW    R4, 24(R3)
943         MOVW    SPR(IBATL(1)), R4
944         MOVW    R4, 28(R3)
945         MOVW    SPR(DBATU(2)), R4
946         MOVW    R4, 32(R3)
947         MOVW    SPR(DBATL(2)), R4
948         MOVW    R4, 36(R3)
949         MOVW    SPR(IBATU(2)), R4
950         MOVW    R4, 40(R3)
951         MOVW    SPR(IBATL(2)), R4
952         MOVW    R4, 44(R3)
953         MOVW    SPR(DBATU(3)), R4
954         MOVW    R4, 48(R3)
955         MOVW    SPR(DBATL(3)), R4
956         MOVW    R4, 52(R3)
957         MOVW    SPR(IBATU(3)), R4
958         MOVW    R4, 56(R3)
959         MOVW    SPR(IBATL(3)), R4
960         MOVW    R4, 60(R3)
961         RETURN
962
963 TEXT setdbat0(SB), $0
964         MOVW    0(R3), R4
965         MOVW    R4, SPR(DBATU(0))
966         MOVW    4(R3), R4
967         MOVW    R4, SPR(DBATL(0))
968         RETURN
969 #endif /* ucuconf */
970
971 TEXT mmudisable(SB), $0
972         /* disable MMU */
973         MOVW    LR, R4
974         MOVW    $KZERO, R5
975         ANDN    R5, R4
976         MOVW    R4, SPR(SRR0)           /* Stored PC for RFI instruction */
977
978         MOVW    MSR, R4
979         MOVW    $(MSR_IR|MSR_DR|MSR_RI|MSR_FP), R5
980         ANDN    R5, R4
981         MOVW    R4, SPR(SRR1)
982
983         MOVW    SPR(HID0), R4           /* Get HID0 and clear unwanted bits */
984         MOVW    $(HID_ICE|HID_DCE), R5
985         ANDN    R5, R4
986         MOVW    R4, SPR(HID0)           /* Cache disable */
987         RFI                             /* resume caller with MMU off */
988         RETURN
989
990 TEXT kreboot(SB), $0
991         BL      mmudisable(SB)
992         MOVW    R3, LR
993         RETURN
994
995 TEXT mul64fract(SB), $0
996         MOVW    a0+8(FP), R9
997         MOVW    a1+4(FP), R10
998         MOVW    b0+16(FP), R4
999         MOVW    b1+12(FP), R5
1000
1001         MULLW   R10, R5, R13            /* c2 = lo(a1*b1) */
1002
1003         MULLW   R10, R4, R12            /* c1 = lo(a1*b0) */
1004         MULHWU  R10, R4, R7             /* hi(a1*b0) */
1005         ADD     R7, R13                 /* c2 += hi(a1*b0) */
1006
1007         MULLW   R9, R5, R6              /* lo(a0*b1) */
1008         MULHWU  R9, R5, R7              /* hi(a0*b1) */
1009         ADDC    R6, R12                 /* c1 += lo(a0*b1) */
1010         ADDE    R7, R13                 /* c2 += hi(a0*b1) + carry */
1011
1012         MULHWU  R9, R4, R7              /* hi(a0*b0) */
1013         ADDC    R7, R12                 /* c1 += hi(a0*b0) */
1014         ADDE    R0, R13                 /* c2 += carry */
1015
1016         MOVW    R12, 4(R3)
1017         MOVW    R13, 0(R3)
1018         RETURN