summaryrefslogtreecommitdiff
path: root/os/ks32/l.s
diff options
context:
space:
mode:
Diffstat (limited to 'os/ks32/l.s')
-rw-r--r--os/ks32/l.s205
1 files changed, 205 insertions, 0 deletions
diff --git a/os/ks32/l.s b/os/ks32/l.s
new file mode 100644
index 00000000..30922a2d
--- /dev/null
+++ b/os/ks32/l.s
@@ -0,0 +1,205 @@
+#include "mem.h"
+
+/*
+ * Entered from the boot loader with
+ * supervisor mode, interrupts disabled;
+ */
+
+TEXT _startup(SB), $-4
+ MOVW $setR12(SB), R12 /* static base (SB) */
+ MOVW $Mach0(SB), R13
+ ADD $(KSTACK-4), R13 /* leave 4 bytes for link */
+
+ MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 /* Switch to SVC mode */
+ MOVW R1, CPSR
+
+ BL main(SB) /* jump to kernel */
+
+dead:
+ B dead
+ BL _div(SB) /* hack to get _div etc loaded */
+
+GLOBL Mach0(SB), $KSTACK
+
+TEXT setr13(SB), $-4
+ MOVW 4(FP), R1
+
+ MOVW CPSR, R2
+ BIC $PsrMask, R2, R3
+ ORR R0, R3
+ MOVW R3, CPSR
+
+ MOVW R13, R0
+ MOVW R1, R13
+
+ MOVW R2, CPSR
+ RET
+
+TEXT _vundcall(SB), $-4
+_vund:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMund, R0
+ B _vswitch
+
+TEXT _vsvccall(SB), $-4
+_vsvc:
+ MOVW.W R14, -4(R13)
+ MOVW CPSR, R14
+ MOVW.W R14, -4(R13)
+ BIC $PsrMask, R14
+ ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14
+ MOVW R14, CPSR
+ MOVW $PsrMsvc, R14
+ MOVW.W R14, -4(R13)
+ B _vsaveu
+
+TEXT _vpabcall(SB), $-4
+_vpab:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMabt, R0
+ B _vswitch
+
+TEXT _vdabcall(SB), $-4
+_vdab:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $(PsrMabt+1), R0
+ B _vswitch
+
+TEXT _vfiqcall(SB), $-4 /* IRQ */
+_vfiq: /* FIQ */
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMfiq, R0
+ B _vswitch
+
+TEXT _virqcall(SB), $-4 /* IRQ */
+_virq:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMirq, R0
+
+_vswitch: /* switch to svc mode */
+ MOVW SPSR, R1
+ MOVW R14, R2
+ MOVW R13, R3
+
+ MOVW CPSR, R14
+ BIC $PsrMask, R14
+ ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14
+ MOVW R14, CPSR
+
+ MOVM.DB.W [R0-R2], (R13)
+ MOVM.DB (R3), [R0-R3]
+
+_vsaveu: /* Save Registers */
+ MOVW.W R14, -4(R13) /* save link */
+/* MCR CpMMU, 0, R0, C(0), C(0), 0 */
+
+ SUB $8, R13
+ MOVM.DB.W [R0-R12], (R13)
+
+ MOVW R0, R0 /* gratuitous noop */
+
+ MOVW $setR12(SB), R12 /* static base (SB) */
+ MOVW R13, R0 /* argument is ureg */
+ SUB $8, R13 /* space for arg+lnk*/
+ BL trap(SB)
+
+
+_vrfe: /* Restore Regs */
+ MOVW CPSR, R0 /* splhi on return */
+ ORR $(PsrDirq|PsrDfiq), R0, R1
+ MOVW R1, CPSR
+ ADD $(8+4*15), R13 /* [r0-R14]+argument+link */
+ MOVW (R13), R14 /* restore link */
+ MOVW 8(R13), R0
+ MOVW R0, SPSR
+ MOVM.DB.S (R13), [R0-R14] /* restore user registers */
+ MOVW R0, R0 /* gratuitous nop */
+ ADD $12, R13 /* skip saved link+type+SPSR*/
+ RFE /* MOVM.IA.S.W (R13), [R15] */
+
+TEXT splhi(SB), $-4
+ MOVW CPSR, R0
+ ORR $(PsrDirq), R0, R1
+ MOVW R1, CPSR
+ RET
+
+TEXT spllo(SB), $-4
+ MOVW CPSR, R0
+ BIC $(PsrDirq|PsrDfiq), R0, R1
+ MOVW R1, CPSR
+ RET
+
+TEXT splx(SB), $-4
+ /* BUG - save PC in m->splpc - JB */
+
+TEXT splxpc(SB), $-4
+ MOVW R0, R1
+ MOVW CPSR, R0
+ MOVW R1, CPSR
+ RET
+
+TEXT islo(SB), $-4
+ MOVW CPSR, R0
+ AND $(PsrDirq), R0
+ EOR $(PsrDirq), R0
+ RET
+
+TEXT splfhi(SB), $-4
+ MOVW CPSR, R0
+ ORR $(PsrDfiq|PsrDirq), R0, R1
+ MOVW R1, CPSR
+ RET
+
+TEXT splflo(SB), $-4
+ MOVW CPSR, R0
+ BIC $(PsrDfiq), R0, R1
+ MOVW R1, CPSR
+ RET
+
+TEXT cpsrr(SB), $-4
+ MOVW CPSR, R0
+ RET
+
+TEXT spsrr(SB), $-4
+ MOVW SPSR, R0
+ RET
+
+TEXT getcallerpc(SB), $-4
+ MOVW 0(R13), R0
+ RET
+
+TEXT _tas(SB), $-4
+ MOVW R0, R1
+ MOVW $0xDEADDEAD, R2
+ SWPW R2, (R1), R0
+ RET
+
+TEXT setlabel(SB), $-4
+ MOVW R13, 0(R0) /* sp */
+ MOVW R14, 4(R0) /* pc */
+ MOVW $0, R0
+ RET
+
+TEXT gotolabel(SB), $-4
+ MOVW 0(R0), R13 /* sp */
+ MOVW 4(R0), R14 /* pc */
+ MOVW $1, R0
+ BX (R14)
+
+TEXT outs(SB), $-4
+ MOVW 4(FP),R1
+ WORD $0xe1c010b0 /* STR H R1,[R0+0] */
+ RET
+
+TEXT ins(SB), $-4
+ WORD $0xe1d000b0 /* LDRHU R0,[R0+0] */
+ RET
+
+/* for devboot */
+TEXT gotopc(SB), $-4
+/*
+ MOVW R0, R1
+ MOVW bootparam(SB), R0
+ MOVW R1, PC
+*/
+ RET