#include "mem.h" #define SYSPSR (SPL(0x0)|PSREF|PSRSUPER) TEXT start(SB), $-4 /* get virtual, fast */ /* we are executing in segment 0, mapped to pmeg 0. stack is there too */ /* get virtual by mapping segment(KZERO) to pmeg 0., and next to 1 */ MOVW $KZERO, R7 MOVB R0, (R7, 3) MOVW $(KZERO+BY2SEGM), R7 MOVW $1, R8 MOVB R8, (R7, 3) /* now mapped correctly. jmpl to where we want to be */ MOVW $setSB(SB), R2 MOVW $startvirt(SB), R7 JMPL (R7) RETURN /* can't get here */ TEXT startvirt(SB), $-4 MOVW $BOOTSTACK, R1 MOVW $mach0(SB), R(MACH) MOVW $0x8, R7 MOVW R7, WIM JMPL main(SB) MOVW (R0), R0 RETURN TEXT swap1(SB), $0 MOVW keyaddr+0(FP), R8 TAS (R8), R7 /* LDSTUB, thank you ken */ RETURN TEXT swap1_should_work(SB), $0 MOVW keyaddr+0(FP), R8 MOVW $1, R7 SWAP (R8), R7 RETURN TEXT swap1x(SB), $0 MOVW keyaddr+0(FP), R8 MOVW PSR, R9 MOVW R9, R10 AND $~PSRET, R10 /* BUG: book says this is buggy */ MOVW R10, PSR OR R0, R0 OR R0, R0 OR R0, R0 MOVW (R8), R7 CMP R7, R0 BNE was1 MOVW $1, R10 MOVW R10, (R8) was1: MOVW R9, PSR RETURN TEXT spllo(SB), $0 MOVW PSR, R7 MOVW R7, R10 OR $PSRET, R10 MOVW R10, PSR OR R0, R0 OR R0, R0 OR R0, R0 RETURN TEXT splhi(SB), $0 MOVW PSR, R7 MOVW R7, R10 AND $~PSRET, R10 /* BUG: book says this is buggy */ MOVW R10, PSR OR R0, R0 OR R0, R0 OR R0, R0 RETURN TEXT splx(SB), $0 MOVW psr+0(FP), R7 MOVW R7, PSR /* BUG: book says this is buggy */ OR R0, R0 OR R0, R0 OR R0, R0 RETURN TEXT touser(SB), $-4 MOVW $SYSPSR, R7 MOVW R7, PSR OR R0, R0 OR R0, R0 OR R0, R0 MOVW sp+0(FP), R1 SAVE R0, R0 /* RETT is implicit RESTORE */ MOVW $(UTZERO+32), R7 /* PC; header appears in text */ MOVW $(UTZERO+32+4), R8 /* nPC */ RETT R7, R8 TEXT rfnote(SB), $0 MOVW 0(FP), R1 /* 1st arg is &uregpointer */ ADD $4, R1 /* point at ureg */ JMP restore TEXT traplink(SB), $-4 /* R8 to R23 are free to play with */ /* R17 contains PC, R18 contains nPC */ /* R19 has PSR loaded from vector code */ ANDCC $PSRPSUPER, R19, R0 BE usertrap kerneltrap: /* * Interrupt or fault from kernel */ ANDN $7, R1, R20 /* dbl aligned */ MOVW R1, (0-(4*(32+6))+(4*1))(R20) /* save R1=SP */ /* really clumsy: store these in Ureg so can be restored below */ MOVW R2, (0-(4*(32+6))+(4*2))(R20) /* SB */ MOVW R5, (0-(4*(32+6))+(4*5))(R20) /* USER */ MOVW R6, (0-(4*(32+6))+(4*6))(R20) /* MACH */ SUB $(4*(32+6)), R20, R1 trap1: MOVW Y, R20 MOVW R20, (4*(32+0))(R1) /* Y */ MOVW TBR, R20 MOVW R20, (4*(32+1))(R1) /* TBR */ AND $~0x1F, R19 /* force CWP=0 */ MOVW R19, (4*(32+2))(R1) /* PSR */ MOVW R18, (4*(32+3))(R1) /* nPC */ MOVW R17, (4*(32+4))(R1) /* PC */ MOVW R0, (4*0)(R1) MOVW R3, (4*3)(R1) MOVW R4, (4*4)(R1) MOVW R7, (4*7)(R1) RESTORE R0, R0 /* now our registers R8-R31 are same as before trap */ /* save registers two at a time */ MOVD R8, (4*8)(R1) MOVD R10, (4*10)(R1) MOVD R12, (4*12)(R1) MOVD R14, (4*14)(R1) MOVD R16, (4*16)(R1) MOVD R18, (4*18)(R1) MOVD R20, (4*20)(R1) MOVD R22, (4*22)(R1) MOVD R24, (4*24)(R1) MOVD R26, (4*26)(R1) MOVD R28, (4*28)(R1) MOVD R30, (4*30)(R1) /* SP and SB and u and m are already set; away we go */ MOVW R1, -4(R1) /* pointer to Ureg */ SUB $8, R1 MOVW $SYSPSR, R7 MOVW R7, PSR OR R0, R0 OR R0, R0 OR R0, R0 JMPL faultsparc(SB) ADD $8, R1 restore: MOVW (4*(32+2))(R1), R8 /* PSR */ MOVW R8, PSR OR R0, R0 OR R0, R0 OR R0, R0 MOVD (4*30)(R1), R30 MOVD (4*28)(R1), R28 MOVD (4*26)(R1), R26 MOVD (4*24)(R1), R24 MOVD (4*22)(R1), R22 MOVD (4*20)(R1), R20 MOVD (4*18)(R1), R18 MOVD (4*16)(R1), R16 MOVD (4*14)(R1), R14 MOVD (4*12)(R1), R12 MOVD (4*10)(R1), R10 MOVD (4*8)(R1), R8 SAVE R0, R0 MOVD (4*6)(R1), R6 MOVD (4*4)(R1), R4 MOVD (4*2)(R1), R2 MOVW (4*(32+0))(R1), R20 /* Y */ MOVW R20, Y MOVW (4*(32+4))(R1), R17 /* PC */ MOVW (4*(32+3))(R1), R18 /* nPC */ MOVW (4*1)(R1), R1 /* restore R1=SP */ RETT R17, R18 usertrap: /* * Interrupt or fault from user */ MOVW R1, R8 MOVW R2, R9 MOVW $setSB(SB), R2 MOVW $(USERADDR+BY2PG), R1 MOVW R8, (0-(4*(32+6))+(4*1))(R1) /* save R1=SP */ MOVW R9, (0-(4*(32+6))+(4*2))(R1) /* save R2=SB */ MOVW R5, (0-(4*(32+6))+(4*5))(R1) /* save R5=USER */ MOVW R6, (0-(4*(32+6))+(4*6))(R1) /* save R6=MACH */ MOVW $USERADDR, R(USER) MOVW $mach0(SB), R(MACH) SUB $(4*(32+6)), R1 JMP trap1 TEXT syslink(SB), $-4 /* R8 to R23 are free to play with */ /* R17 contains PC, R18 contains nPC */ /* R19 has PSR loaded from vector code */ /* assume user did it; syscall checks */ MOVW R1, R8 MOVW R2, R9 MOVW $setSB(SB), R2 MOVW $(USERADDR+BY2PG), R1 MOVW R8, (0-(4*(32+6))+4)(R1) /* save R1=SP */ SUB $(4*(32+6)), R1 MOVW R9, (4*2)(R1) /* save R2=SB */ MOVW R3, (4*3)(R1) /* global register */ MOVD R4, (4*4)(R1) /* global register, R5=USER */ MOVD R6, (4*6)(R1) /* save R6=MACH, R7=syscall# */ MOVW $USERADDR, R(USER) MOVW $mach0(SB), R(MACH) MOVW TBR, R20 MOVW R20, (4*(32+1))(R1) /* TBR */ AND $~0x1F, R19 MOVW R19, (4*(32+2))(R1) /* PSR */ MOVW R18, (4*(32+3))(R1) /* nPC */ MOVW R17, (4*(32+4))(R1) /* PC */ RESTORE R0, R0 /* now our registers R8-R31 are same as before trap */ MOVW R15, (4*15)(R1) /* SP and SB and u and m are already set; away we go */ MOVW R1, -4(R1) /* pointer to Ureg */ SUB $8, R1 MOVW $SYSPSR, R7 MOVW R7, PSR JMPL syscall(SB) /* R7 contains return value from syscall */ ADD $8, R1 MOVW (4*(32+2))(R1), R8 /* PSR */ MOVW R8, PSR OR R0, R0 OR R0, R0 OR R0, R0 MOVW (4*15)(R1), R15 SAVE R0, R0 MOVW (4*6)(R1), R6 MOVD (4*4)(R1), R4 MOVD (4*2)(R1), R2 MOVW (4*(32+4))(R1), R17 /* PC */ MOVW (4*(32+3))(R1), R18 /* nPC */ MOVW (4*1)(R1), R1 /* restore R1=SP */ RETT R17, R18 TEXT puttbr(SB), $0 MOVW tbr+0(FP), R7 MOVW R7, TBR OR R0, R0 OR R0, R0 OR R0, R0 RETURN TEXT gettbr(SB), $0 MOVW TBR, R7 RETURN TEXT r1(SB), $0 MOVW R1, R7 RETURN TEXT getwim(SB), $0 MOVW WIM, R7 RETURN TEXT setlabel(SB), $0 MOVW b+0(FP), R7 MOVW R1, (R7) MOVW R15, 4(R7) MOVW $0, R7 RETURN TEXT gotolabel(SB), $0 MOVW b+0(FP), R8 MOVW (R8), R1 MOVW 4(R8), R15 MOVW R15, 0(R1) MOVW $1, R7 RETURN TEXT putcxsegm(SB), $0 MOVW 0(FP), R8 /* context */ MOVW 4(FP), R9 /* segment addr */ MOVW 8(FP), R10 /* segment value */ MOVW $0xFFE80118, R7 JMPL (R7) RETURN TEXT putcxreg(SB), $0 MOVW $CONTEXT, R7 MOVW 0(FP), R8 MOVB R8, (R7, 2) RETURN TEXT putb2(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVB R8, (R7, 2) RETURN TEXT getb2(SB), $0 MOVW 0(FP), R7 MOVB (R7, 2), R7 RETURN TEXT getw2(SB), $0 MOVW 0(FP), R7 MOVW (R7, 2), R7 RETURN TEXT putw2(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 2) RETURN TEXT putw4(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 4) RETURN TEXT putwC(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 0xC) RETURN TEXT putwD(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 0xD) RETURN TEXT putwD16(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) ADD $(1<<4), R7 MOVW R8, (R7, 0xD) RETURN TEXT putwE(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 0xE) RETURN TEXT putwE16(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) ADD $(1<<4), R7 MOVW R8, (R7, 0xE) RETURN TEXT putsegm(SB), $0 MOVW 0(FP), R7 MOVW 4(FP), R8 MOVW R8, (R7, 3) RETURN TEXT clearfpintr(SB), $0 MOVW $fpq+BY2WD(SB), R7 ANDN $0x7, R7 /* must be D aligned */ MOVW $fpr+0(SB), R9 clrq: MOVD FQ, (R7) MOVW FSR, (R9) MOVW (R9), R8 AND $(1<<13), R8 /* queue not empty? */ BNE clrq RETURN TEXT getfsr(SB), $0 MOVW $fpr+0(SB), R7 MOVW FSR, (R7) MOVW (R7), R7 RETURN GLOBL mach0+0(SB), $MACHSIZE GLOBL fpq+0(SB), $(3*BY2WD) GLOBL fpr+0(SB), $BY2WD