#include "mem.h"
#include "arm7500.h"
#include "io.h"
/*
* Entered here from the boot loader with
* MMU, IDC and WB enabled.
*/
TEXT _startup(SB), $-4
MOVW $setR12(SB), R12
_main:
MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 /* SVC mode, interrupts disabled */
MOVW R1, CPSR
MOVW $(MACHADDR+BY2PG), R13 /* stack */
SUB $4, R13 /* link */
BL main(SB)
_mainloop:
BEQ _mainloop
BNE _mainloop
BL _div(SB) /* loader botch */
BL _mainloop
TEXT mmuregr(SB), $-4
CMP $CpCPUID, R0
BNE _fsrr
MRC CpMMU, 0, R0, C(CpCPUID), C(0)
RET
_fsrr:
CMP $CpFSR, R0
BNE _farr
MRC CpMMU, 0, R0, C(CpFSR), C(0)
RET
_farr:
CMP $CpFAR, R0
BNE _ctlr
MRC CpMMU, 0, R0, C(CpFAR), C(0)
RET
_ctlr:
CMP $CpControl, R0
BNE _mmuregbad
MCR CpMMU, 0, R0, C(CpControl), C(0)
RET
_mmuregbad:
MOVW $-1, R0
RET
TEXT mmuregw(SB), $-4
CMP $CpControl, R0
BNE _ttbw
MOVW 4(FP), R0
MCR CpMMU, 0, R0, C(CpControl), C(0)
RET
_ttbw:
CMP $CpTTB, R0
BNE _dacw
MOVW 4(FP), R0
MCR CpMMU, 0, R0, C(CpTTB), C(0)
RET
_dacw:
CMP $CpDAC, R0
BNE _TLBflushw
MOVW 4(FP), R0
MCR CpMMU, 0, R0, C(CpDAC), C(0)
RET
_TLBflushw:
CMP $CpTLBflush, R0
BNE _TLBpurgew
MCR CpMMU, 0, R0, C(CpTLBflush), C(0)
RET
_TLBpurgew:
CMP $CpTLBpurge, R0
BNE _IDCflushw
MOVW 4(FP), R0
MCR CpMMU, 0, R0, C(CpTLBpurge), C(0)
RET
_IDCflushw:
CMP $CpIDCflush, R0
BNE _WBdrain
MCR CpMMU, 0, R0, C(CpIDCflush), C(CpIDCflush)
RET
_WBdrain:
CMP $CpWBdrain, R0
BNE _mmuregbad
MCR CpMMU, 4, R0, C(CpIDCflush), C(CpWBdrain), 4
RET
TEXT mmuttb(SB), $-4
MCR CpMMU, 0, R0, C(CpIDCflush), C(CpIDCflush)
MCR CpMMU, 0, R0, C(CpTLBflush), C(0)
MCR CpMMU, 0, R0, C(CpTTB), C(0)
RET
TEXT mmureset(SB), $-4
MOVW CPSR, R0
ORR $(PsrDfiq|PsrDirq), R0, R0
MOVW R0, CPSR
MOVW $0, R0
MOVW $(CpCsystem), R1
MCR CpMMU, 0, R1, C(CpControl), C(0)
B (R0)
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 vectors(SB), $-4
MOVW 0x18(R15), R15 /* reset */
MOVW 0x18(R15), R15 /* undefined */
MOVW 0x18(R15), R15 /* SWI */
MOVW 0x18(R15), R15 /* prefetch abort */
MOVW 0x18(R15), R15 /* data abort */
MOVW 0x18(R15), R15 /* reserved */
MOVW 0x18(R15), R15 /* IRQ */
MOVW 0x18(R15), R15 /* FIQ */
TEXT vtable(SB), $-4
WORD $_vsvc(SB) /* reset, in svc mode already */
WORD $_vund(SB) /* undefined, switch to svc mode */
WORD $_vsvc(SB) /* swi, in svc mode already */
WORD $_vpab(SB) /* prefetch abort, switch to svc mode */
WORD $_vdab(SB) /* data abort, switch to svc mode */
WORD $_vsvc(SB) /* reserved */
WORD $_virq(SB) /* IRQ, switch to svc mode */
WORD $_vfiq(SB) /* FIQ, switch to svc mode */
TEXT _vund(SB), $-4 /* undefined */
MOVM.IA [R0-R3], (R13)
MOVW $PsrMund, R0
B _vswitch
TEXT _vsvc(SB), $-4 /* reset or SWI or reserved */
SUB $12, R13
MOVW R14, 8(R13)
MOVW CPSR, R14
MOVW R14, 4(R13)
MOVW $PsrMsvc, R14
MOVW R14, (R13)
MOVW 8(R13), R14
B _vsaveu
TEXT _vpab(SB), $-4 /* prefetch abort */
MOVM.IA [R0-R3], (R13)
MOVW $PsrMabt, R0
B _vswitch
TEXT _vdab(SB), $-4 /* data abort */
MOVM.IA [R0-R3], (R13)
MOVW $(PsrMabt+1), R0
B _vswitch
TEXT _virq(SB), $-4 /* IRQ */
MOVM.IA [R0-R3], (R13)
MOVW $PsrMirq, R0
B _vswitch
TEXT _vfiq(SB), $-4 /* FIQ */
MOVM.IA [R0-R3], (R13)
MOVW $PsrMfiq, R0
B _vswitch
_vswitch: /* switch to svc, type in R0 */
MOVW SPSR, R1 /* psr for ureg */
MOVW R14, R2 /* saved pc for ureg */
MOVW R13, R3 /* [R0-R3] save area */
MOVW CPSR, R14 /* switch */
BIC $PsrMask, R14
ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14
MOVW R14, CPSR
MOVM.DB.W [R0-R2], (R13) /* top of ureg */
MOVM.IA (R3), [R0-R3] /* restore [R0-R3] */
B _vsaveu
_vsaveu:
SUB $4, R13 /* save link */
MOVW R14, (R13)
MOVM.DB.W [R0-R14], (R13) /* save svc registers */
MOVW $setR12(SB), R12 /* safety */
MOVW R13, R0 /* argument is &ureg */
SUB $8, R13 /* space for argument+link */
BL exception(SB)
_vrfe:
ADD $(8+4*15), R13 /* [r0-R14]+argument+link */
MOVW (R13), R14 /* restore link */
MOVW 8(R13), R0 /* restore SPSR */
MOVW R0, SPSR
MOVM.DB (R13), [R0-R14] /* restore registers */
ADD $12, R13 /* skip saved link+type+SPSR */
RFE /* MOVM.IA.S.W (R13), [R15] */
TEXT splhi(SB), $-4
MOVW CPSR, R0
ORR $(PsrDfiq|PsrDirq), R0, R1
MOVW R1, CPSR
RET
TEXT spllo(SB), $-4
MOVW CPSR, R0
BIC $(PsrDfiq|PsrDirq), R0, R1
MOVW R1, CPSR
RET
TEXT splx(SB), $-4
MOVW R0, R1
MOVW CPSR, R0
MOVW R1, CPSR
RET
TEXT islo(SB), $-4
MOVW CPSR, R0
AND $(PsrDfiq|PsrDirq), R0
EOR $(PsrDfiq|PsrDirq), R0
RET
TEXT _exit(SB), $-4
MRC CpMMU, 0, R1, C(CpControl), C(0), 0 /* Read MMUCR */
BIC $MMUCR_M_ENABLE, R1 /* Clear MMU Enable bit */
MCR CpMMU, 0, R1, C(CpControl), C(0), 0 /* Write to MMU CR */
MCR CpMMU, 0, R1, C(CpIDCflush), C(7) /* Flush (inval) I,D-cache */
B (R0)
TEXT cpsrr(SB), $-4
MOVW CPSR, R0
RET
TEXT spsrr(SB), $-4
MOVW SPSR, R0
RET
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 */
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
RET
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
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
TEXT cleanDentry(SB), $-4
MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 1
RET
TEXT flushDentry(SB), $-4
MCR CpMMU, 0, R0, C(CpCacheCtl), C(6), 1
RET
TEXT drainWBuffer(SB), $-4
MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4
RET
TEXT writeBackDC(SB), $-4
MOVW $0xE0000000, R0
MOVW $8192, R1
ADD R0, R1
wbflush:
MOVW.P.W 32(R0), R2
CMP R1,R0
BNE wbflush
RET
TEXT flushDcache(SB), $-4
MCR CpMMU, 0, R0, C(CpCacheCtl), C(6), 0
RET
TEXT writeBackBDC(SB), $-4
MOVW $0xE4000000, R0
MOVW $0x200, R1
ADD R0, R1
wbbflush:
MOVW.P.W 32(R0), R2
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
TEXT flushIDC(SB), $-4
/*BUG*/
BL drainWBuffer(SB)
BL writeBackDC(SB)
BL flushDcache(SB)
BL flushIcache(SB)
RET