summaryrefslogtreecommitdiff
path: root/os/boot/puma/l.s
diff options
context:
space:
mode:
Diffstat (limited to 'os/boot/puma/l.s')
-rw-r--r--os/boot/puma/l.s427
1 files changed, 427 insertions, 0 deletions
diff --git a/os/boot/puma/l.s b/os/boot/puma/l.s
new file mode 100644
index 00000000..a4679fc2
--- /dev/null
+++ b/os/boot/puma/l.s
@@ -0,0 +1,427 @@
+/*
+ * File: l.s
+ * Purpose:
+ * Puma Board StrongARM 110 Architecture Specific Assembly
+ *
+ */
+
+#include "mem.h"
+#include "armv4.h"
+#include "puma.h"
+
+#define DRAMWAIT 100000 /* 3.125μsec per iteration */
+#define TL750R(r) (TL750_BASE+(r)*4)
+
+#define BOOTBASE 0x00200000
+
+TEXT _main(SB),1,$-4
+ MOVW R15, R7 /* save PC on entry */
+
+/*
+ * initialise DRAM controller on the TL750 (SDRAM mode)
+ */
+ MOVW $DRAMWAIT, R0 /* wait 312 ms after reset before touching DRAM */
+dram1:
+ SUB.S $1, R0
+ BNE dram1
+
+ MOVW $TL750R(0x103), R0 /* DMC_DELAY */
+ MOVW $0x03333333, R1 /* DRAM timing parameters */
+ MOVW R1, (R0)
+
+ MOVW $TL750R(0x101), R0 /* DMC_SDRAM */
+ MOVW $0x03133011, R1 /* SDRAM parameters for Puma */
+ MOVW R1, (R0)
+
+ MOVW $DRAMWAIT, R0 /* wait 312 ms for initialisation */
+dram2:
+ SUB.S $1, R0
+ BNE dram2
+
+ MOVW $setR12(SB),R12
+
+/*
+ * copy bootstrap to final location in DRAM
+ */
+ MOVW R7, baddr(SB)
+ MOVW $(BOOTBASE+8), R0
+ CMP R0, R7
+ BEQ inplace
+ MOVW $((128*1024)/4), R6
+copyboot:
+ MOVW.P 4(R7), R5
+ MOVW.P R5, 4(R0)
+ SUB.S $1, R6
+ BNE copyboot
+ MOVW $bootrel(SB), R7
+ MOVW R7, R15
+
+TEXT bootrel(SB), $-4
+
+/*
+ * set C environment and invoke main
+ */
+inplace:
+ MOVW $mach0(SB),R13
+ MOVW R13,m(SB)
+ ADD $(MACHSIZE-12),R13
+
+ /* disable MMU activity */
+ BL mmuctlregr(SB)
+ BIC $(CpCmmu|CpCDcache|CpCwb|CpCIcache), R0
+ BL mmuctlregw(SB)
+
+ BL main(SB)
+loop:
+ B loop
+
+TEXT idle(SB),$0
+ RET
+
+/*
+ * basic timing loop to determine CPU frequency
+ */
+TEXT aamloop(SB), $-4 /* 3 */
+_aamloop:
+ MOVW R0, R0 /* 1 */
+ MOVW R0, R0 /* 1 */
+ MOVW R0, R0 /* 1 */
+ SUB $1, R0 /* 1 */
+ CMP $0, R0 /* 1 */
+ BNE _aamloop /* 3 */
+ RET /* 3 */
+
+/*
+ * Function: setr13( mode, pointer )
+ * Purpose:
+ * Sets the stack pointer for a particular mode
+ */
+
+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
+
+/*
+ * Function: _vundcall
+ * Purpose:
+ * Undefined Instruction Trap Handler
+ *
+ */
+
+TEXT _vundcall(SB), $-4
+_vund:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMund, R0
+ B _vswitch
+
+/*
+ * Function: _vsvccall
+ * Purpose:
+ * Reset or SWI Handler
+ *
+ */
+
+TEXT _vsvccall(SB), $-4
+_vsvc:
+ SUB $12, R13
+ MOVW R14, 8(R13)
+ MOVW CPSR, R14
+ MOVW R14, 4(R13)
+ MOVW $PsrMsvc, R14
+ MOVW R14, (R13)
+ B _vsaveu
+
+/*
+ * Function: _pabcall
+ * Purpose:
+ * Prefetch Abort Trap Handler
+ *
+ */
+
+TEXT _vpabcall(SB), $-4
+_vpab:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMabt, R0
+ B _vswitch
+
+/*
+ * Function: _vdabcall
+ * Purpose:
+ * Data Abort Trap Handler
+ *
+ */
+
+TEXT _vdabcall(SB), $-4
+_vdab:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $(PsrMabt+1), R0
+ B _vswitch
+
+/*
+ * Function: _virqcall
+ * Purpose:
+ * IRQ Trap Handler
+ *
+ */
+
+TEXT _virqcall(SB), $-4 /* IRQ */
+_virq:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMirq, R0
+ B _vswitch
+
+/*
+ * Function: _vfiqcall
+ * Purpose:
+ * FIQ Trap Handler
+ *
+ */
+
+TEXT _vfiqcall(SB), $-4 /* FIQ */
+_vfiq:
+ MOVM.DB [R0-R3], (R13)
+ MOVW $PsrMfiq, R0
+ /* FALLTHROUGH */
+
+_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 */
+ SUB $4, R13 /* save link */
+ MOVW R14, (R13) /* MOVW.W R14,4(R13)*/
+
+ SUB $8, R13
+
+ MOVW R13, R14 /* ur->sp */
+ ADD $(6*4), R14
+ MOVW R14, 0(R13)
+
+ MOVW 8(SP), R14 /* ur->link */
+ MOVW R14, 4(SP)
+
+ 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] */
+
+
+/*
+ * Function: splhi
+ * Purpose:
+ * Disable Interrupts
+ * Returns:
+ * Previous interrupt state
+ */
+
+TEXT splhi(SB), $-4
+ MOVW CPSR, R0
+ ORR $(PsrDirq|PsrDfiq), R0, R1
+ MOVW R1, CPSR
+ RET
+
+/*
+ * Function: spllo
+ * Purpose:
+ * Enable Interrupts
+ * Returns:
+ * Previous interrupt state
+ */
+
+TEXT spllo(SB), $-4
+ MOVW CPSR, R0
+ BIC $(PsrDirq), R0, R1
+ MOVW R1, CPSR
+ RET
+
+/*
+ * Function: splx(level)
+ * Purpose:
+ * Restore interrupt level
+ */
+
+TEXT splx(SB), $-4
+ MOVW R0, R1
+ MOVW CPSR, R0
+ MOVW R1, CPSR
+ RET
+
+/*
+ * Function: islo
+ * Purpose:
+ * Check if interrupts are enabled
+ *
+ */
+
+TEXT islo(SB), $-4
+ MOVW CPSR, R0
+ AND $(PsrDirq), R0
+ EOR $(PsrDirq), R0
+ RET
+
+/*
+ * Function: cpsrr
+ * Purpose:
+ * Returns current program status register
+ *
+ */
+
+TEXT cpsrr(SB), $-4
+ MOVW CPSR, R0
+ RET
+
+/*
+ * Function: spsrr
+ * Purpose:
+ * Returns saved program status register
+ *
+ */
+
+TEXT spsrr(SB), $-4
+ MOVW SPSR, R0
+ RET
+
+/*
+ * MMU Operations
+ */
+TEXT mmuctlregr(SB), $-4
+ MRC CpMMU, 0, R0, C(CpControl), C(0)
+ RET
+
+TEXT mmuctlregw(SB), $-4
+ MCR CpMMU, 0, R0, C(CpControl), C(0)
+ MOVW R0, R0
+ MOVW R0, R0
+ RET
+
+/*
+ * Cache Routines
+ */
+
+/*
+ * Function: flushIcache
+ * Purpose:
+ * Flushes the *WHOLE* instruction cache
+ */
+
+TEXT flushIcache(SB), $-4
+ MCR CpMMU, 0, R0, C(CpCacheCtl), C(5), 0
+ MOVW R0,R0
+ MOVW R0,R0
+ MOVW R0,R0
+ MOVW R0,R0
+ RET
+
+
+
+/*
+ * Function: flushDentry
+ * Purpose:
+ * Flushes an entry of the data cache
+ */
+
+TEXT flushDentry(SB), $-4
+ MCR CpMMU, 0, R0, C(CpCacheCtl), C(6), 1
+ RET
+
+/*
+ * Function: drainWBuffer
+ * Purpose:
+ * Drains the Write Buffer
+ */
+
+TEXT drainWBuffer(SB), $-4
+ MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4
+ RET
+
+/*
+ * Function: writeBackDC
+ * Purpose:
+ * Drains the dcache prior to flush
+ */
+
+TEXT writeBackDC(SB), $-4
+ MOVW $0xE0000000, R0
+ MOVW $8192, R1
+ ADD R0, R1
+
+wbflush:
+ MOVW (R0), R2
+ ADD $32, R0
+ CMP R1,R0
+ BNE wbflush
+ RET
+
+/*
+ * Function: flushDcache(SB)
+ * Purpose:
+ * Flush the dcache
+ */
+
+TEXT flushDcache(SB), $-4
+ MCR CpMMU, 0, R0, C(CpCacheCtl), C(6), 0
+ RET
+
+/*
+ * Function: writeBackBDC(SB)
+ * Purpose:
+ * Write back the Baby D-Cache
+ */
+
+TEXT writeBackBDC(SB), $-4
+ MOVW $0xE4000000, R0
+ MOVW $0x200, R1
+ ADD R0, R1
+
+wbbflush:
+ MOVW (R0), R2
+ ADD $32, R0
+ CMP R1,R0
+ BNE wbbflush
+ MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4
+ MOVW R0,R0
+ MOVW R0,R0
+ MOVW R0,R0
+ MOVW R0,R0
+ RET
+
+GLOBL mach0+0(SB), $MACHSIZE
+GLOBL m(SB), $4
+GLOBL baddr(SB), $4