2015-03-28 04:15:40 +00:00
|
|
|
|
#include "mem.h"
|
|
|
|
|
|
|
|
|
|
#define SP R29
|
|
|
|
|
|
|
|
|
|
#define NOOP NOR R0, R0, R0
|
|
|
|
|
#define WAIT NOOP; NOOP
|
|
|
|
|
#define RETURN RET; NOOP
|
|
|
|
|
#define CONST(i, v) MOVW $((i) & 0xffff0000), v; OR $((i) & 0xffff), v;
|
|
|
|
|
#define GETMACH(r) CONST(MACHADDR, r)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* R4000 instructions
|
|
|
|
|
*/
|
|
|
|
|
#define ERET WORD $0x42000018
|
|
|
|
|
#define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16))
|
|
|
|
|
#define SC(base, rt) WORD $((070<<26)|((base)<<21)|((rt)<<16))
|
|
|
|
|
|
|
|
|
|
#define MFC0(src,sel,dst) WORD $(0x40000000|((src)<<11)|((dst)<<16)|(sel))
|
|
|
|
|
#define MTC0(src,dst,sel) WORD $(0x40800000|((dst)<<11)|((src)<<16)|(sel))
|
|
|
|
|
#define RDHWR(hwr, r) WORD $(0x7c00003b|((hwr)<<11)|((r)<<16))
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* cache manipulation
|
|
|
|
|
*/
|
|
|
|
|
#define CACHE BREAK /* overloaded op-code */
|
|
|
|
|
|
|
|
|
|
#define PI R((0 /* primary I cache */
|
|
|
|
|
#define PD R((1 /* primary D cache */
|
|
|
|
|
#define SD R((3 /* secondary combined I/D cache */
|
|
|
|
|
|
|
|
|
|
#define IWBI (0<<2))) /* index write-back invalidate */
|
|
|
|
|
#define ILT (1<<2))) /* index load tag */
|
|
|
|
|
#define IST (2<<2))) /* index store tag */
|
|
|
|
|
#define CDE (3<<2))) /* create dirty exclusive */
|
|
|
|
|
#define HINV (4<<2))) /* hit invalidate */
|
|
|
|
|
#define HWBI (5<<2))) /* hit write back invalidate */
|
|
|
|
|
#define HWB (6<<2))) /* hit write back */
|
|
|
|
|
#define HSV (7<<2))) /* hit set virtual */
|
|
|
|
|
|
|
|
|
|
NOSCHED
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Boot only processor
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT start(SB), $-4
|
|
|
|
|
MOVW $setR30(SB), R30
|
|
|
|
|
|
|
|
|
|
MOVW $CU1, R1
|
|
|
|
|
MOVW R1, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
|
|
|
|
|
MOVW $(0x1C<<7), R1
|
|
|
|
|
MOVW R1, FCR31 /* permit only inexact and underflow */
|
|
|
|
|
NOOP
|
|
|
|
|
MOVD $0.5, F26
|
|
|
|
|
SUBD F26, F26, F24
|
|
|
|
|
ADDD F26, F26, F28
|
|
|
|
|
ADDD F28, F28, F30
|
|
|
|
|
|
|
|
|
|
MOVD F24, F0
|
|
|
|
|
MOVD F24, F2
|
|
|
|
|
MOVD F24, F4
|
|
|
|
|
MOVD F24, F6
|
|
|
|
|
MOVD F24, F8
|
|
|
|
|
MOVD F24, F10
|
|
|
|
|
MOVD F24, F12
|
|
|
|
|
MOVD F24, F14
|
|
|
|
|
MOVD F24, F16
|
|
|
|
|
MOVD F24, F18
|
|
|
|
|
MOVD F24, F20
|
|
|
|
|
MOVD F24, F22
|
|
|
|
|
|
|
|
|
|
MOVW $MACHADDR, R(MACH)
|
|
|
|
|
ADDU $(MACHSIZE-BY2V), R(MACH), SP
|
|
|
|
|
|
|
|
|
|
MOVW R(MACH), R1
|
|
|
|
|
clrmach:
|
|
|
|
|
MOVW R0, (R1)
|
|
|
|
|
ADDU $BY2WD, R1
|
|
|
|
|
BNE R1, SP, clrmach
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
MOVW $edata(SB), R1
|
|
|
|
|
MOVW $end(SB), R2
|
|
|
|
|
clrbss:
|
|
|
|
|
MOVB R0, (R1)
|
|
|
|
|
ADDU $1, R1
|
|
|
|
|
BNE R1, R2, clrbss
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
MOVW R0, 0(R(MACH)) /* m->machno = 0 */
|
|
|
|
|
MOVW R0, R(USER) /* up = nil */
|
|
|
|
|
|
|
|
|
|
JAL main(SB)
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
TEXT arcs(SB), $256
|
|
|
|
|
MOVW R24, 0x80(SP)
|
|
|
|
|
MOVW R25, 0x84(SP)
|
|
|
|
|
MOVW R26, 0x88(SP)
|
|
|
|
|
MOVW R27, 0x8C(SP)
|
|
|
|
|
|
|
|
|
|
MOVW $SPBADDR, R4
|
|
|
|
|
MOVW 0x20(R4), R5
|
|
|
|
|
ADDU R1, R5
|
|
|
|
|
MOVW (R5), R2
|
|
|
|
|
|
|
|
|
|
MOVW 16(FP), R7
|
|
|
|
|
MOVW 12(FP), R6
|
|
|
|
|
MOVW 8(FP), R5
|
|
|
|
|
MOVW 4(FP), R4
|
|
|
|
|
|
|
|
|
|
JAL (R2)
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
MOVW $setR30(SB), R30
|
|
|
|
|
|
|
|
|
|
MOVW 0x80(SP), R24
|
|
|
|
|
MOVW 0x84(SP), R25
|
|
|
|
|
MOVW 0x88(SP), R26
|
|
|
|
|
MOVW 0x8C(SP), R27
|
|
|
|
|
|
|
|
|
|
MOVW R2, R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Take first processor into user mode
|
|
|
|
|
* - argument is stack pointer to user
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT touser(SB), $-4
|
|
|
|
|
MOVW M(STATUS), R4
|
|
|
|
|
MOVW $(UTZERO+32), R2 /* header appears in text */
|
|
|
|
|
MOVW R2, M(EPC)
|
|
|
|
|
MOVW R1, SP
|
|
|
|
|
AND $(~KMODEMASK), R4
|
|
|
|
|
OR $(KUSER|IE|EXL), R4 /* switch to user mode, intrs on, exc */
|
|
|
|
|
MOVW R4, M(STATUS) /* " */
|
|
|
|
|
WAIT
|
|
|
|
|
ERET /* clears EXL */
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* manipulate interrupts
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* enable an interrupt; bit is in R1 */
|
|
|
|
|
TEXT intron(SB), $0
|
|
|
|
|
MOVW M(STATUS), R2
|
|
|
|
|
WAIT
|
|
|
|
|
OR R1, R2
|
|
|
|
|
MOVW R2, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/* disable an interrupt; bit is in R1 */
|
|
|
|
|
TEXT introff(SB), $0
|
|
|
|
|
MOVW M(STATUS), R2
|
|
|
|
|
WAIT
|
|
|
|
|
XOR $-1, R1
|
|
|
|
|
AND R1, R2
|
|
|
|
|
MOVW R2, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT splhi(SB), $0
|
|
|
|
|
MOVW R31, 12(R(MACH)) /* save PC in m->splpc */
|
|
|
|
|
MOVW M(STATUS), R1
|
|
|
|
|
WAIT
|
|
|
|
|
AND $~IE, R1, R2
|
|
|
|
|
MOVW R2, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT splx(SB), $0
|
|
|
|
|
MOVW R31, 12(R(MACH)) /* save PC in m->splpc */
|
|
|
|
|
MOVW M(STATUS), R2
|
|
|
|
|
WAIT
|
|
|
|
|
AND $IE, R1
|
|
|
|
|
AND $~IE, R2
|
|
|
|
|
OR R2, R1
|
|
|
|
|
MOVW R1, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT spllo(SB), $0
|
|
|
|
|
MOVW M(STATUS), R1
|
|
|
|
|
WAIT
|
|
|
|
|
OR $IE, R1, R2
|
|
|
|
|
MOVW R2, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT spldone(SB), $0
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT islo(SB), $0
|
|
|
|
|
MOVW M(STATUS), R1
|
|
|
|
|
WAIT
|
|
|
|
|
AND $IE, R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT coherence(SB), $-4
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* process switching
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT setlabel(SB), $-4
|
|
|
|
|
MOVW SP, 0(R1)
|
|
|
|
|
MOVW R31, 4(R1)
|
|
|
|
|
MOVW R0, R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT gotolabel(SB), $-4
|
|
|
|
|
MOVW 0(R1), SP
|
|
|
|
|
MOVW 4(R1), R31
|
|
|
|
|
MOVW $1, R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* the tlb routines need to be called at splhi.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT getwired(SB),$0
|
|
|
|
|
MOVW M(WIRED), R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT setwired(SB),$0
|
|
|
|
|
MOVW R1, M(WIRED)
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT getrandom(SB),$0
|
|
|
|
|
MOVW M(RANDOM), R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT getpagemask(SB),$0
|
|
|
|
|
MOVW M(PAGEMASK), R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT setpagemask(SB),$0
|
|
|
|
|
MOVW R1, M(PAGEMASK)
|
|
|
|
|
MOVW R0, R1 /* prevent accidents */
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT puttlbx(SB), $0 /* puttlbx(index, virt, phys0, phys1, pagemask) */
|
|
|
|
|
MOVW 4(FP), R2
|
|
|
|
|
MOVW 8(FP), R3
|
|
|
|
|
MOVW 12(FP), R4
|
|
|
|
|
MOVW $((2*BY2PG-1) & ~0x1fff), R5
|
|
|
|
|
MOVW R2, M(TLBVIRT)
|
|
|
|
|
MOVW R3, M(TLBPHYS0)
|
|
|
|
|
MOVW R4, M(TLBPHYS1)
|
|
|
|
|
MOVW R5, M(PAGEMASK)
|
|
|
|
|
MOVW R1, M(INDEX)
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
TLBWI
|
|
|
|
|
NOOP
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT tlbvirt(SB), $0
|
|
|
|
|
MOVW M(TLBVIRT), R1
|
|
|
|
|
NOOP
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT gettlbx(SB), $0 /* gettlbx(index, &entry) */
|
|
|
|
|
MOVW 4(FP), R4
|
|
|
|
|
MOVW R1, M(INDEX)
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
TLBR
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW M(TLBVIRT), R1
|
|
|
|
|
MOVW M(TLBPHYS0), R2
|
|
|
|
|
MOVW M(TLBPHYS1), R3
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW R1, 0(R4)
|
|
|
|
|
MOVW R2, 4(R4)
|
|
|
|
|
MOVW R3, 8(R4)
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT gettlbp(SB), $0 /* gettlbp(tlbvirt, &entry) */
|
|
|
|
|
MOVW 4(FP), R5
|
|
|
|
|
MOVW R1, M(TLBVIRT)
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
TLBP
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW M(INDEX), R1
|
|
|
|
|
NOOP
|
|
|
|
|
BLTZ R1, gettlbp1
|
|
|
|
|
TLBR
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW M(TLBVIRT), R2
|
|
|
|
|
MOVW M(TLBPHYS0), R3
|
|
|
|
|
MOVW M(TLBPHYS1), R4
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW R2, 0(R5)
|
|
|
|
|
MOVW R3, 4(R5)
|
|
|
|
|
MOVW R4, 8(R5)
|
|
|
|
|
gettlbp1:
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT gettlbvirt(SB), $0 /* gettlbvirt(index) */
|
|
|
|
|
MOVW R1, M(INDEX)
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
TLBR
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW M(TLBVIRT), R1
|
|
|
|
|
NOOP
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* compute stlb hash index.
|
|
|
|
|
*
|
|
|
|
|
* M(TLBVIRT) [page & asid] in arg, result in arg.
|
|
|
|
|
* stir in swizzled asid; we get best results with asid in both high & low bits.
|
|
|
|
|
*/
|
|
|
|
|
#define STLBHASH(arg, tmp) \
|
|
|
|
|
AND $0xFF, arg, tmp; \
|
|
|
|
|
SRL $(PGSHIFT+1), arg; \
|
|
|
|
|
XOR tmp, arg; \
|
|
|
|
|
SLL $(STLBLOG-8), tmp; \
|
|
|
|
|
XOR tmp, arg; \
|
|
|
|
|
CONST (STLBSIZE-1, tmp); \
|
|
|
|
|
AND tmp, arg
|
|
|
|
|
|
|
|
|
|
TEXT stlbhash(SB), $0 /* for mmu.c */
|
|
|
|
|
STLBHASH(R1, R2)
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT utlbmiss(SB), $-4
|
|
|
|
|
GETMACH (R26)
|
|
|
|
|
MOVW R27, 12(R26) /* m->splpc = R27 */
|
|
|
|
|
|
|
|
|
|
MOVW 16(R26), R27
|
|
|
|
|
ADDU $1, R27
|
|
|
|
|
MOVW R27,16(R26) /* m->tlbfault++ */
|
|
|
|
|
|
|
|
|
|
MOVW M(TLBVIRT), R27
|
|
|
|
|
NOOP
|
|
|
|
|
STLBHASH(R27, R26)
|
|
|
|
|
|
|
|
|
|
/* scale to a byte index (multiply by 12) */
|
|
|
|
|
SLL $1, R27, R26 /* × 2 */
|
|
|
|
|
ADDU R26, R27 /* × 3 */
|
|
|
|
|
SLL $2, R27 /* × 12 */
|
|
|
|
|
|
|
|
|
|
GETMACH (R26)
|
|
|
|
|
MOVW 4(R26), R26
|
|
|
|
|
ADDU R26, R27 /* R27 = &m->stb[hash] */
|
|
|
|
|
|
|
|
|
|
MOVW M(BADVADDR), R26
|
|
|
|
|
NOOP
|
|
|
|
|
AND $BY2PG, R26
|
|
|
|
|
|
|
|
|
|
BNE R26, utlbodd /* odd page? */
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
utlbeven:
|
|
|
|
|
MOVW 4(R27), R26 /* R26 = m->stb[hash].phys0 */
|
|
|
|
|
BEQ R26, stlbm /* nothing cached? do it the hard way */
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW R26, M(TLBPHYS0)
|
|
|
|
|
MOVW 8(R27), R26 /* R26 = m->stb[hash].phys1 */
|
|
|
|
|
JMP utlbcom
|
|
|
|
|
MOVW R26, M(TLBPHYS1) /* branch delay slot */
|
|
|
|
|
|
|
|
|
|
utlbodd:
|
|
|
|
|
MOVW 8(R27), R26 /* R26 = m->stb[hash].phys1 */
|
|
|
|
|
BEQ R26, stlbm /* nothing cached? do it the hard way */
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW R26, M(TLBPHYS1)
|
|
|
|
|
MOVW 4(R27), R26 /* R26 = m->stb[hash].phys0 */
|
|
|
|
|
MOVW R26, M(TLBPHYS0)
|
|
|
|
|
|
|
|
|
|
utlbcom:
|
|
|
|
|
WAIT
|
|
|
|
|
MOVW M(TLBVIRT), R26
|
|
|
|
|
MOVW 0(R27), R27 /* R27 = m->stb[hash].virt */
|
|
|
|
|
BEQ R27, stlbm /* nothing cached? do it the hard way */
|
|
|
|
|
NOOP
|
|
|
|
|
/* is the stlb entry for the right virtual address? */
|
|
|
|
|
BNE R26, R27, stlbm /* M(TLBVIRT) != m->stb[hash].virt? */
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
/* if an entry exists, overwrite it, else write a random one */
|
|
|
|
|
CONST (PGSZ, R27)
|
|
|
|
|
MOVW R27, M(PAGEMASK) /* select page size */
|
|
|
|
|
TLBP /* probe tlb */
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW M(INDEX), R26
|
|
|
|
|
NOOP
|
|
|
|
|
BGEZ R26, utlbindex /* if tlb entry found, rewrite it */
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW M(RANDOM), R26
|
|
|
|
|
MOVW R26, M(INDEX)
|
|
|
|
|
utlbindex:
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
TLBWI /* write indexed tlb entry */
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
utlbret:
|
|
|
|
|
GETMACH (R26)
|
|
|
|
|
MOVW 12(R26), R27 /* R27 = m->splpc */
|
|
|
|
|
MOVW M(EPC), R26
|
|
|
|
|
JMP (R27)
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
stlbm:
|
|
|
|
|
GETMACH (R26)
|
|
|
|
|
MOVW 12(R26), R27 /* R27 = m->splpc */
|
|
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
|
|
TEXT gevector(SB), $-4
|
|
|
|
|
MOVW M(STATUS), R26
|
|
|
|
|
WAIT
|
|
|
|
|
AND $KUSER, R26
|
|
|
|
|
|
|
|
|
|
BNE R26, wasuser
|
|
|
|
|
MOVW SP, R26 /* delay slot, old SP in R26 */
|
|
|
|
|
|
|
|
|
|
waskernel:
|
|
|
|
|
JMP dosave
|
|
|
|
|
SUBU $UREGSIZE, SP /* delay slot, allocate frame on kernel stack */
|
|
|
|
|
|
|
|
|
|
wasuser: /* get kernel stack for this user process */
|
|
|
|
|
GETMACH (SP)
|
|
|
|
|
MOVW 8(SP), SP /* m->proc */
|
|
|
|
|
MOVW 8(SP), SP /* m->proc->kstack */
|
|
|
|
|
ADDU $(KSTACK-UREGSIZE), SP
|
|
|
|
|
|
|
|
|
|
dosave:
|
|
|
|
|
MOVW R31, 0x28(SP)
|
|
|
|
|
|
|
|
|
|
JAL saveregs(SB)
|
|
|
|
|
MOVW R26, 0x10(SP) /* delay slot, save old SP */
|
|
|
|
|
|
|
|
|
|
GETMACH (R(MACH))
|
|
|
|
|
MOVW 8(R(MACH)), R(USER) /* R24 = m->proc */
|
|
|
|
|
MOVW $setR30(SB), R30
|
|
|
|
|
|
|
|
|
|
BEQ R26, dosys /* set by saveregs() */
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
dotrap:
|
|
|
|
|
MOVW $forkret(SB), R31
|
|
|
|
|
JMP trap(SB)
|
|
|
|
|
MOVW 4(SP), R1 /* delay slot, first arg to trap() */
|
|
|
|
|
|
|
|
|
|
dosys:
|
|
|
|
|
JAL syscall(SB)
|
|
|
|
|
MOVW 4(SP), R1 /* delay slot, first arg to syscall() */
|
|
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
|
|
TEXT forkret(SB), $-4
|
|
|
|
|
JAL restregs(SB) /* restores old PC in R26 */
|
|
|
|
|
MOVW 0x14(SP), R1 /* delay slot, CAUSE */
|
|
|
|
|
|
|
|
|
|
MOVW 0x28(SP), R31
|
|
|
|
|
|
|
|
|
|
JMP (R27)
|
|
|
|
|
MOVW 0x10(SP), SP /* delay slot */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* SP-> 0x00 --- (spill R31)
|
|
|
|
|
* 0x04 --- (trap()/syscall() arg1)
|
|
|
|
|
* 0x08 status
|
|
|
|
|
* 0x0C pc
|
|
|
|
|
* 0x10 sp/usp
|
|
|
|
|
* 0x14 cause
|
|
|
|
|
* 0x18 badvaddr
|
|
|
|
|
* 0x1C tlbvirt
|
|
|
|
|
* 0x20 hi
|
|
|
|
|
* 0x24 lo
|
|
|
|
|
* 0x28 r31
|
|
|
|
|
* .....
|
|
|
|
|
* 0x9c r1
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT saveregs(SB), $-4
|
|
|
|
|
MOVW R1, 0x9C(SP)
|
|
|
|
|
MOVW R2, 0x98(SP)
|
|
|
|
|
MOVW M(STATUS), R2
|
|
|
|
|
ADDU $8, SP, R1
|
|
|
|
|
MOVW R1, 0x04(SP) /* arg to base of regs */
|
|
|
|
|
MOVW $~KMODEMASK, R1
|
|
|
|
|
AND R2, R1
|
|
|
|
|
MOVW R1, M(STATUS) /* so we can take another trap */
|
|
|
|
|
MOVW R2, 0x08(SP)
|
|
|
|
|
MOVW M(EPC), R2
|
|
|
|
|
MOVW M(CAUSE), R1
|
|
|
|
|
MOVW R2, 0x0C(SP)
|
|
|
|
|
MOVW R1, 0x14(SP)
|
|
|
|
|
AND $(EXCMASK<<2), R1
|
|
|
|
|
SUBU $(CSYS<<2), R1, R26
|
|
|
|
|
|
|
|
|
|
BEQ R26, notsaved /* is syscall? */
|
|
|
|
|
MOVW R27, 0x34(SP) /* delay slot */
|
|
|
|
|
|
|
|
|
|
MOVW M(BADVADDR), R1
|
|
|
|
|
MOVW M(TLBVIRT), R2
|
|
|
|
|
MOVW R1, 0x18(SP)
|
|
|
|
|
MOVW R2, 0x1C(SP)
|
|
|
|
|
|
|
|
|
|
MOVW HI, R1
|
|
|
|
|
MOVW LO, R2
|
|
|
|
|
MOVW R1, 0x20(SP)
|
|
|
|
|
MOVW R2, 0x24(SP)
|
|
|
|
|
|
|
|
|
|
MOVW R25, 0x3C(SP)
|
|
|
|
|
MOVW R24, 0x40(SP)
|
|
|
|
|
MOVW R23, 0x44(SP)
|
|
|
|
|
MOVW R22, 0x48(SP)
|
|
|
|
|
MOVW R21, 0x4C(SP)
|
|
|
|
|
MOVW R20, 0x50(SP)
|
|
|
|
|
MOVW R19, 0x54(SP)
|
|
|
|
|
MOVW R18, 0x58(SP)
|
|
|
|
|
MOVW R17, 0x5C(SP)
|
|
|
|
|
MOVW R16, 0x60(SP)
|
|
|
|
|
MOVW R15, 0x64(SP)
|
|
|
|
|
MOVW R14, 0x68(SP)
|
|
|
|
|
MOVW R13, 0x6C(SP)
|
|
|
|
|
MOVW R12, 0x70(SP)
|
|
|
|
|
MOVW R11, 0x74(SP)
|
|
|
|
|
MOVW R10, 0x78(SP)
|
|
|
|
|
MOVW R9, 0x7C(SP)
|
|
|
|
|
MOVW R8, 0x80(SP)
|
|
|
|
|
MOVW R7, 0x84(SP)
|
|
|
|
|
MOVW R6, 0x88(SP)
|
|
|
|
|
MOVW R5, 0x8C(SP)
|
|
|
|
|
MOVW R4, 0x90(SP)
|
|
|
|
|
MOVW R3, 0x94(SP)
|
|
|
|
|
|
|
|
|
|
notsaved:
|
|
|
|
|
MOVW R30, 0x2C(SP)
|
|
|
|
|
|
|
|
|
|
RET
|
|
|
|
|
MOVW R28, 0x30(SP) /* delay slot */
|
|
|
|
|
|
|
|
|
|
TEXT restregs(SB), $-4
|
|
|
|
|
AND $(EXCMASK<<2), R1
|
|
|
|
|
SUBU $(CSYS<<2), R1, R26
|
|
|
|
|
|
|
|
|
|
BEQ R26, notrestored /* is syscall? */
|
|
|
|
|
MOVW 0x34(SP), R27 /* delay slot */
|
|
|
|
|
|
|
|
|
|
MOVW 0x3C(SP), R25
|
|
|
|
|
MOVW 0x40(SP), R24
|
|
|
|
|
MOVW 0x44(SP), R23
|
|
|
|
|
MOVW 0x48(SP), R22
|
|
|
|
|
MOVW 0x4C(SP), R21
|
|
|
|
|
MOVW 0x50(SP), R20
|
|
|
|
|
MOVW 0x54(SP), R19
|
|
|
|
|
MOVW 0x58(SP), R18
|
|
|
|
|
MOVW 0x5C(SP), R17
|
|
|
|
|
MOVW 0x60(SP), R16
|
|
|
|
|
MOVW 0x64(SP), R15
|
|
|
|
|
MOVW 0x68(SP), R14
|
|
|
|
|
MOVW 0x6C(SP), R13
|
|
|
|
|
MOVW 0x70(SP), R12
|
|
|
|
|
MOVW 0x74(SP), R11
|
|
|
|
|
MOVW 0x78(SP), R10
|
|
|
|
|
MOVW 0x7C(SP), R9
|
|
|
|
|
MOVW 0x80(SP), R8
|
|
|
|
|
MOVW 0x84(SP), R7
|
|
|
|
|
MOVW 0x88(SP), R6
|
|
|
|
|
MOVW 0x8C(SP), R5
|
|
|
|
|
MOVW 0x90(SP), R4
|
|
|
|
|
MOVW 0x94(SP), R3
|
|
|
|
|
|
|
|
|
|
MOVW 0x24(SP), R2
|
|
|
|
|
MOVW 0x20(SP), R1
|
|
|
|
|
MOVW R2, LO
|
|
|
|
|
MOVW R1, HI
|
|
|
|
|
|
|
|
|
|
MOVW 0x98(SP), R2
|
|
|
|
|
|
|
|
|
|
notrestored:
|
|
|
|
|
MOVW 0x08(SP), R1
|
|
|
|
|
MOVW R1, M(STATUS)
|
|
|
|
|
MOVW 0x0C(SP), R26 /* old PC */
|
|
|
|
|
MOVW R26, M(EPC)
|
|
|
|
|
|
|
|
|
|
MOVW 0x30(SP), R28
|
|
|
|
|
MOVW 0x2C(SP), R30
|
|
|
|
|
|
|
|
|
|
RET
|
|
|
|
|
MOVW 0x9C(SP), R1 /* delay slot */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* hardware interrupt vectors
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT vector0(SB), $-4
|
|
|
|
|
WAIT
|
|
|
|
|
CONST (SPBADDR+0x18, R26)
|
|
|
|
|
MOVW $eret(SB), R27
|
|
|
|
|
MOVW (R26), R26
|
|
|
|
|
JMP (R26)
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
TEXT vector180(SB), $-4
|
|
|
|
|
WAIT
|
|
|
|
|
CONST (SPBADDR+0x14, R26)
|
|
|
|
|
MOVW $eret(SB), R27
|
|
|
|
|
MOVW (R26), R26
|
|
|
|
|
JMP (R26)
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
TEXT eret(SB), $-4
|
|
|
|
|
ERET
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* floating-point stuff
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT clrfpintr(SB), $0
|
|
|
|
|
MOVW M(STATUS), R3
|
|
|
|
|
WAIT
|
|
|
|
|
OR $CU1, R3
|
|
|
|
|
MOVW R3, M(STATUS)
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
MOVW FCR31, R1
|
|
|
|
|
MOVW R1, R2
|
|
|
|
|
AND $~(0x3F<<12), R2
|
|
|
|
|
MOVW R2, FCR31
|
|
|
|
|
|
|
|
|
|
AND $~CU1, R3
|
|
|
|
|
MOVW R3, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT savefpregs(SB), $0
|
|
|
|
|
MOVW FCR31, R2
|
|
|
|
|
MOVW M(STATUS), R3
|
|
|
|
|
WAIT
|
|
|
|
|
AND $~(0x3F<<12), R2, R4
|
|
|
|
|
MOVW R4, FCR31
|
|
|
|
|
|
|
|
|
|
MOVD F0, 0x00(R1)
|
|
|
|
|
MOVD F2, 0x08(R1)
|
|
|
|
|
MOVD F4, 0x10(R1)
|
|
|
|
|
MOVD F6, 0x18(R1)
|
|
|
|
|
MOVD F8, 0x20(R1)
|
|
|
|
|
MOVD F10, 0x28(R1)
|
|
|
|
|
MOVD F12, 0x30(R1)
|
|
|
|
|
MOVD F14, 0x38(R1)
|
|
|
|
|
MOVD F16, 0x40(R1)
|
|
|
|
|
MOVD F18, 0x48(R1)
|
|
|
|
|
MOVD F20, 0x50(R1)
|
|
|
|
|
MOVD F22, 0x58(R1)
|
|
|
|
|
MOVD F24, 0x60(R1)
|
|
|
|
|
MOVD F26, 0x68(R1)
|
|
|
|
|
MOVD F28, 0x70(R1)
|
|
|
|
|
MOVD F30, 0x78(R1)
|
|
|
|
|
|
|
|
|
|
MOVW R2, 0x80(R1)
|
|
|
|
|
AND $~CU1, R3
|
|
|
|
|
MOVW R3, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT restfpregs(SB), $0
|
|
|
|
|
MOVW M(STATUS), R3
|
|
|
|
|
WAIT
|
|
|
|
|
OR $CU1, R3
|
|
|
|
|
MOVW R3, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
MOVW fpstat+4(FP), R2
|
|
|
|
|
NOOP
|
|
|
|
|
|
|
|
|
|
MOVD 0x00(R1), F0
|
|
|
|
|
MOVD 0x08(R1), F2
|
|
|
|
|
MOVD 0x10(R1), F4
|
|
|
|
|
MOVD 0x18(R1), F6
|
|
|
|
|
MOVD 0x20(R1), F8
|
|
|
|
|
MOVD 0x28(R1), F10
|
|
|
|
|
MOVD 0x30(R1), F12
|
|
|
|
|
MOVD 0x38(R1), F14
|
|
|
|
|
MOVD 0x40(R1), F16
|
|
|
|
|
MOVD 0x48(R1), F18
|
|
|
|
|
MOVD 0x50(R1), F20
|
|
|
|
|
MOVD 0x58(R1), F22
|
|
|
|
|
MOVD 0x60(R1), F24
|
|
|
|
|
MOVD 0x68(R1), F26
|
|
|
|
|
MOVD 0x70(R1), F28
|
|
|
|
|
MOVD 0x78(R1), F30
|
|
|
|
|
|
|
|
|
|
MOVW R2, FCR31
|
|
|
|
|
AND $~CU1, R3
|
|
|
|
|
MOVW R3, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT fcr31(SB), $0 /* fp csr */
|
|
|
|
|
MOVW FCR31, R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Emulate 68020 test and set: load linked / store conditional
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT tas(SB), $0
|
2015-07-07 17:17:55 +00:00
|
|
|
|
TEXT _tas(SB), $0
|
2015-03-28 04:15:40 +00:00
|
|
|
|
MOVW R1, R2 /* address of key */
|
|
|
|
|
tas1:
|
|
|
|
|
MOVW $1, R3
|
|
|
|
|
LL(2, 1)
|
|
|
|
|
NOOP
|
|
|
|
|
SC(2, 3)
|
|
|
|
|
NOOP
|
|
|
|
|
BEQ R3, tas1
|
|
|
|
|
NOOP
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/* used by the semaphore implementation */
|
|
|
|
|
TEXT cmpswap(SB), $0
|
|
|
|
|
MOVW R1, R2 /* address of key */
|
|
|
|
|
MOVW old+4(FP), R3 /* old value */
|
|
|
|
|
MOVW new+8(FP), R4 /* new value */
|
|
|
|
|
LL(2, 1) /* R1 = (R2) */
|
|
|
|
|
NOOP
|
|
|
|
|
BNE R1, R3, fail
|
|
|
|
|
NOOP
|
|
|
|
|
MOVW R4, R1
|
|
|
|
|
SC(2, 1) /* (R2) = R1 if (R2) hasn't changed; R1 = success */
|
|
|
|
|
NOOP
|
|
|
|
|
RETURN
|
|
|
|
|
fail:
|
|
|
|
|
MOVW R0, R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* cache manipulation
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */
|
|
|
|
|
MOVW M(STATUS), R10
|
|
|
|
|
WAIT
|
|
|
|
|
MOVW 4(FP), R9
|
|
|
|
|
MOVW $0, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
ADDU R1, R9 /* R9 = last address */
|
|
|
|
|
MOVW $(~0x3f), R8
|
|
|
|
|
AND R1, R8 /* R8 = first address, rounded down */
|
|
|
|
|
ADDU $0x3f, R9
|
|
|
|
|
AND $(~0x3f), R9 /* round last address up */
|
|
|
|
|
SUBU R8, R9 /* R9 = revised count */
|
|
|
|
|
icflush1: /* primary cache line size is 16 bytes */
|
|
|
|
|
CACHE PD+HWB, 0x00(R8)
|
|
|
|
|
CACHE PI+HINV, 0x00(R8)
|
|
|
|
|
CACHE PD+HWB, 0x10(R8)
|
|
|
|
|
CACHE PI+HINV, 0x10(R8)
|
|
|
|
|
CACHE PD+HWB, 0x20(R8)
|
|
|
|
|
CACHE PI+HINV, 0x20(R8)
|
|
|
|
|
CACHE PD+HWB, 0x30(R8)
|
|
|
|
|
CACHE PI+HINV, 0x30(R8)
|
|
|
|
|
SUBU $0x40, R9
|
|
|
|
|
ADDU $0x40, R8
|
|
|
|
|
BGTZ R9, icflush1
|
|
|
|
|
MOVW R10, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */
|
|
|
|
|
MOVW M(STATUS), R10
|
|
|
|
|
WAIT
|
|
|
|
|
MOVW 4(FP), R9
|
|
|
|
|
MOVW $0, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
ADDU R1, R9 /* R9 = last address */
|
|
|
|
|
MOVW $(~0x3f), R8
|
|
|
|
|
AND R1, R8 /* R8 = first address, rounded down */
|
|
|
|
|
ADDU $0x3f, R9
|
|
|
|
|
AND $(~0x3f), R9 /* round last address up */
|
|
|
|
|
SUBU R8, R9 /* R9 = revised count */
|
|
|
|
|
dcflush1: /* primary cache line size is 16 bytes */
|
|
|
|
|
CACHE PD+HWB, 0x00(R8)
|
|
|
|
|
CACHE PD+HWB, 0x10(R8)
|
|
|
|
|
CACHE PD+HWB, 0x20(R8)
|
|
|
|
|
CACHE PD+HWB, 0x30(R8)
|
|
|
|
|
SUBU $0x40, R9
|
|
|
|
|
ADDU $0x40, R8
|
|
|
|
|
BGTZ R9, dcflush1
|
|
|
|
|
MOVW R10, M(STATUS)
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
2015-03-31 23:31:31 +00:00
|
|
|
|
TEXT outl(SB), $0
|
|
|
|
|
MOVW 4(FP), R2
|
|
|
|
|
MOVW 8(FP), R3
|
|
|
|
|
SLL $2, R3
|
|
|
|
|
ADDU R2, R3
|
|
|
|
|
outl1:
|
|
|
|
|
BEQ R2, R3, outl2
|
|
|
|
|
MOVW (R2), R4
|
|
|
|
|
MOVW R4, (R1)
|
|
|
|
|
JMP outl1
|
|
|
|
|
ADDU $4, R2
|
|
|
|
|
outl2:
|
|
|
|
|
RETURN
|
|
|
|
|
|
2015-03-28 04:15:40 +00:00
|
|
|
|
/*
|
|
|
|
|
* access to CP0 registers
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TEXT prid(SB), $0
|
|
|
|
|
MOVW M(PRID), R1
|
|
|
|
|
WAIT
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT rdcount(SB), $0
|
|
|
|
|
MOVW M(COUNT), R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT wrcount(SB), $0
|
|
|
|
|
MOVW R1, M(COUNT)
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT wrcompare(SB), $0
|
|
|
|
|
MOVW R1, M(COMPARE)
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
TEXT rdcompare(SB), $0
|
|
|
|
|
MOVW M(COMPARE), R1
|
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
SCHED
|