summaryrefslogtreecommitdiff
path: root/os/boot/rpcg/l.s
diff options
context:
space:
mode:
Diffstat (limited to 'os/boot/rpcg/l.s')
-rw-r--r--os/boot/rpcg/l.s388
1 files changed, 388 insertions, 0 deletions
diff --git a/os/boot/rpcg/l.s b/os/boot/rpcg/l.s
new file mode 100644
index 00000000..a1022ff3
--- /dev/null
+++ b/os/boot/rpcg/l.s
@@ -0,0 +1,388 @@
+#include "mem.h"
+
+/* special instruction definitions */
+#define BDNE BC 0,2,
+#define BDNZ BC 16,0,
+#define NOOP OR R0,R0,R0
+
+/*
+ * common ppc special purpose registers
+ */
+#define DSISR 18
+#define DAR 19 /* Data Address Register */
+#define DEC 22 /* Decrementer */
+#define SRR0 26 /* Saved Registers (exception) */
+#define SRR1 27
+#define SPRG0 272 /* Supervisor Private Registers */
+#define SPRG1 273
+#define SPRG2 274
+#define SPRG3 275
+#define TBRU 269 /* Time base Upper/Lower (Reading) */
+#define TBRL 268
+#define TBWU 285 /* Time base Upper/Lower (Writing) */
+#define TBWL 284
+#define PVR 287 /* Processor Version */
+
+/*
+ * mpc82x-specific special purpose registers of interest here
+ */
+#define EIE 80
+#define EID 81
+#define NRI 82
+#define IMMR 638
+#define IC_CST 560
+#define IC_ADR 561
+#define IC_DAT 562
+#define DC_CST 568
+#define DC_ADR 569
+#define DC_DAT 570
+#define MI_CTR 784
+#define MI_AP 786
+#define MI_EPN 787
+#define MI_TWC 789
+#define MI_RPN 790
+#define MI_DBCAM 816
+#define MI_DBRAM0 817
+#define MI_DBRAM1 818
+#define MD_CTR 792
+#define M_CASID 793
+#define MD_AP 794
+#define MD_EPN 795
+#define M_TWB 796
+#define MD_TWC 797
+#define MD_RPN 798
+#define M_TW 799
+#define MD_DBCAM 824
+#define MD_DBRAM0 825
+#define MD_DBRAM1 826
+
+/* as on 603e, apparently mtmsr needs help in some chip revisions */
+#define WAITMSR SYNC; ISYNC
+
+/* use of SPRG registers in save/restore */
+#define SAVER0 SPRG0
+#define SAVER1 SPRG1
+#define SAVELR SPRG2
+#define SAVECR SPRG3
+
+#define UREGSIZE ((8+32)*4)
+#define UREGSPACE (UREGSIZE+8) /* allow for arg to trap, and align */
+
+/*
+ * This code is loaded by the ROM loader at location 0x3000,
+ * or lives in flash memory at FLASHMEM+0x100
+ * Move it to high memory so that it can load the kernel at 0x0000.
+ */
+
+#define LOADCODEBASE 0x3000 /* when downloaded in S records */
+#define FLASHCODEBASE (FLASHMEM+0x20000+0x100) /* when in flash */
+
+ TEXT start(SB), $-4
+ MOVW MSR, R3
+ MOVW $(EE|IP|RI), R4
+ ANDN R4, R3
+ OR $ME, R3
+ SYNC
+ MOVW R3, MSR /* turn off interrupts but enable traps */
+ WAITMSR
+
+/*
+ * reset the caches and disable them for now
+ */
+ MOVW SPR(IC_CST), R4 /* read and clear */
+ MOVW $(5<<25), R4
+ MOVW R4, SPR(IC_CST) /* unlock all */
+ ISYNC
+ MOVW $(6<<25), R4
+ MOVW R4, SPR(IC_CST) /* invalidate all */
+ ISYNC
+ MOVW $(2<<25), R4
+ MOVW R4, SPR(IC_CST) /* disable i-cache */
+ ISYNC
+
+ SYNC
+ MOVW SPR(DC_CST), R4 /* read and clear */
+ MOVW $(10<<24), R4
+ MOVW R4, SPR(DC_CST) /* unlock all */
+ ISYNC
+ MOVW $(12<<24), R4
+ MOVW R4, SPR(DC_CST) /* invalidate all */
+ ISYNC
+ MOVW $(4<<24), R4
+ MOVW R4, SPR(DC_CST) /* disable i-cache */
+ ISYNC
+
+ MOVW $7, R4
+ MOVW R4, SPR(158) /* cancel `show cycle' for normal instruction execution */
+
+/*
+ * set other system configuration values
+ */
+ MOVW SPR(IMMR), R5 /* save initial space pointer */
+ MOVW $INTMEM, R4
+ MOVW R4, SPR(IMMR) /* set internal memory base */
+ MOVW $0xFFFFFF88, R3
+ MOVW R3, 4(R4) /* disable watchdog in sypcr */
+ MOVW $0x01012440, R3
+ MOVW R3, 0(R4) /* siumcr */
+
+/*
+ * system initialisation (init and map DRAM)
+ */
+ MOVW $0, R0
+ MOVW $setSB(SB), R2
+#ifndef confrpcg
+ MOVW $(0xF000<<16), R3
+/*MOVW R0, R3*/
+ ANDCC R5, R3 /* initial space is high? */
+ BEQ notrom
+ MOVW $FLASHCODEBASE, R5 /* where $start(SB) actually is now */
+ MOVW $start(SB), R4 /* logical start address */
+ SUB R4, R5, R6 /* text relocation value */
+ MOVW $etext(SB), R7
+ SUB R4, R7
+ ADD R5, R7 /* data address in ROM */
+ MOVW $bdata(SB), R8
+ SUB R8, R2
+ ADD R7, R2 /* relocate SB: SB' = romdata+(SB-bdata) */
+ MOVW $sysinit0(SB), R4
+ ADD R6, R4 /* relocate sysinit0's address */
+ MOVW R4, CTR
+ MOVW $inmem(SB), R4
+ ADD R6, R4
+ MOVW R4, LR /* and the return address */
+ BR (CTR) /* call sysinit0 */
+ TEXT inmem(SB), $-4
+ MOVW $FLASHCODEBASE, R3
+ BR cpu0
+notrom:
+ MOVW $start(SB), R6
+ SUB R6, R2
+ ADD $LOADCODEBASE, R2
+ BL sysinit0(SB)
+ MOVW $LOADCODEBASE, R3
+#endif
+
+/*
+ * cpu 0
+ * relocate bootstrap to our link addresses for text and data
+ * set new PC
+ */
+cpu0:
+ MOVW $setSB(SB), R2 /* set correct static base register */
+#ifndef confrpcg
+ MOVW $start(SB), R4
+ MOVW $etext(SB), R5
+ SUB R4, R5
+ CMP R4, R3 /* already there? */
+ BNE copytext
+ ADD R5, R3 /* start of data image */
+#else
+ MOVW $etext(SB), R3
+#endif
+ BR copydata
+
+copytext:
+ ADD $3, R5
+ SRAW $2, R5
+ MOVW R5, CTR
+ SUB $4, R4
+ SUB $4, R3
+copyt: /* copy text */
+ MOVWU 4(R3), R5
+ MOVWU R5, 4(R4)
+ BDNZ copyt
+ ADD $4, R3
+
+copydata:
+ /* copy data */
+ MOVW $bdata(SB), R4
+ CMP R4, R3 /* already there? */
+ BEQ loadkpc
+ MOVW $edata(SB), R5
+ SUB R4, R5
+ ADD $3, R5
+ SRAW $2, R5
+ MOVW R5, CTR
+ SUB $4, R4
+ SUB $4, R3
+copyd:
+ MOVWU 4(R3), R5
+ MOVWU R5, 4(R4)
+ BDNZ copyd
+#endif
+
+ /* load correct PC */
+loadkpc:
+ MOVW $start1(SB), R3
+ MOVW R3, LR
+ BR (LR)
+TEXT start1(SB), $-4
+ MOVW $edata(SB), R3
+ MOVW $end(SB), R4
+ SUBCC R3, R4
+ BLE skipz
+ SRAW $2, R4
+ MOVW R4, CTR
+ SUB $4, R3
+ MOVW $0, R0
+zero:
+ MOVWU R0, 4(R3)
+ BDNZ zero
+skipz:
+ MOVW $mach0(SB), R1
+ MOVW R1, m(SB)
+ ADD $(MACHSIZE-8), R1
+ MOVW $0, R0
+
+ BL sysinit0(SB)
+
+ BL main(SB)
+ BR 0(PC)
+
+TEXT ledx(SB), $0
+
+ MOVW $BCSRMEM, R8
+ MOVW 0(R8), R3
+ MOVW $(0x0800<<16), R5
+ ANDN R5, R3, R3
+ MOVW R3, 0(R8)
+ BR 0(PC)
+
+TEXT getmsr(SB), $0
+ MOVW MSR, R3
+ RETURN
+
+TEXT putmsr(SB), $0
+ SYNC
+ MOVW R3, MSR
+ WAITMSR
+ RETURN
+
+TEXT eieio(SB), $0
+ EIEIO
+ RETURN
+
+TEXT idle(SB), $0
+ RETURN
+
+TEXT spllo(SB), $0
+ MOVW MSR, R3
+ OR $EE, R3, R4
+ SYNC
+ MOVW R4, MSR
+ WAITMSR
+ RETURN
+
+TEXT splhi(SB), $0
+ MOVW MSR, R3
+ RLWNM $0, R3, $~EE, R4
+ SYNC
+ MOVW R4, MSR
+ WAITMSR
+ RETURN
+
+TEXT splx(SB), $0
+ MOVW MSR, R4
+ RLWMI $0, R3, $EE, R4
+ SYNC
+ MOVW R4, MSR
+ WAITMSR
+ RETURN
+
+TEXT gettbl(SB), $0
+/* MOVW SPR(TBRL), R3 */
+ WORD $0x7c6c42e6 /* mftbl on 8xx series */
+ RETURN
+
+TEXT getpvr(SB), $0
+ MOVW SPR(PVR), R3
+ RETURN
+
+TEXT getimmr(SB), $0
+ MOVW SPR(IMMR), R3
+ RETURN
+
+TEXT getdec(SB), $0
+ MOVW SPR(DEC), R3
+ RETURN
+
+TEXT putdec(SB), $0
+ MOVW R3, SPR(DEC)
+ RETURN
+
+/*
+ * save state in Ureg on kernel stack.
+ * enter with R0 giving the PC from the call to `exception' from the vector.
+ * on return, SB (R2) has been set, and R3 has the Ureg*
+ */
+TEXT saveureg(SB), $-4
+ SUB $UREGSPACE, R1
+ MOVMW R2, 48(R1) /* r2:r31 */
+ MOVW $setSB(SB), R2
+ MOVW SPR(SAVER1), R4
+ MOVW R4, 44(R1)
+ MOVW SPR(SAVER0), R5
+ MOVW R5, 40(R1)
+ MOVW CTR, R6
+ MOVW R6, 36(R1)
+ MOVW XER, R4
+ MOVW R4, 32(R1)
+ MOVW SPR(SAVECR), R5 /* CR */
+ MOVW R5, 28(R1)
+ MOVW SPR(SAVELR), R6 /* LR */
+ MOVW R6, 24(R1)
+ /* pad at 20(R1) */
+ MOVW SPR(SRR0), R4
+ MOVW R4, 16(R1) /* old PC */
+ MOVW SPR(SRR1), R5
+ MOVW R5, 12(R1)
+ MOVW R0, 8(R1) /* cause/vector, encoded in LR from vector */
+ ADD $8, R1, R3 /* Ureg* */
+ STWCCC R3, (R1) /* break any pending reservations */
+ MOVW $0, R0 /* R0ISZERO */
+ BR (LR)
+
+/*
+ * restore state from Ureg
+ * SB (R2) is unusable on return
+ */
+TEXT restoreureg(SB), $-4
+ MOVMW 48(R1), R2 /* r2:r31 */
+ /* defer R1 */
+ MOVW 40(R1), R0
+ MOVW R0, SPR(SAVER0)
+ MOVW 36(R1), R0
+ MOVW R0, CTR
+ MOVW 32(R1), R0
+ MOVW R0, XER
+ MOVW 28(R1), R0
+ MOVW R0, CR /* CR */
+ MOVW 24(R1), R0
+ MOVW R0, SPR(SAVELR) /* LR */
+ /* pad, skip */
+ MOVW 16(R1), R0
+ MOVW R0, SPR(SRR0) /* old PC */
+ MOVW 12(R1), R0
+ MOVW R0, SPR(SRR1) /* old MSR */
+ /* cause, skip */
+ MOVW 44(R1), R1 /* old SP */
+ BR (LR)
+
+TEXT exception(SB), $-4
+ MOVW R1, SPR(SAVER1)
+ MOVW CR, R0
+ MOVW R0, SPR(SAVECR)
+ MOVW LR, R0
+ BL saveureg(SB)
+ MOVW $0, R0
+ BL trap(SB)
+ BL restoreureg(SB)
+ MOVW SPR(SAVELR), R0
+ MOVW R0, LR
+ MOVW SPR(SAVER0), R0
+ ISYNC
+ RFI
+
+GLOBL mach0+0(SB), $MACHSIZE
+GLOBL m(SB), $4