diff options
-rw-r--r-- | sys/arch/sparc64/sparc64/locore.s | 207 |
1 files changed, 11 insertions, 196 deletions
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s index baab493741f..8873ab23073 100644 --- a/sys/arch/sparc64/sparc64/locore.s +++ b/sys/arch/sparc64/sparc64/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.96 2007/10/27 20:04:28 miod Exp $ */ +/* $OpenBSD: locore.s,v 1.97 2007/10/29 21:27:25 kettenis Exp $ */ /* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */ /* @@ -713,8 +713,8 @@ _C_LABEL(trapbase): UTRAP 0x019; UTRAP 0x01a; UTRAP 0x01b; UTRAP 0x01c; UTRAP 0x01d UTRAP 0x01e; UTRAP 0x01f TRAP T_FPDISABLED ! 020 = fp instr, but EF bit off in psr - VTRAP T_FP_IEEE_754, fp_exception ! 021 = ieee 754 exception - VTRAP T_FP_OTHER, fp_exception ! 022 = other fp exception + TRAP T_FP_IEEE_754 ! 021 = ieee 754 exception + TRAP T_FP_OTHER ! 022 = other fp exception TRAP T_TAGOF ! 023 = tag overflow UCLEANWIN ! 024-027 = clean window trap TRAP T_DIV0 ! 028 = divide by zero @@ -875,8 +875,8 @@ ktextfault: UTRAP 0x019; UTRAP 0x01a; UTRAP 0x01b; UTRAP 0x01c; UTRAP 0x01d UTRAP 0x01e; UTRAP 0x01f TRAP T_FPDISABLED ! 020 = fp instr, but EF bit off in psr - VTRAP T_FP_IEEE_754, fp_exception ! 021 = ieee 754 exception - VTRAP T_FP_OTHER, fp_exception ! 022 = other fp exception + TRAP T_FP_IEEE_754 ! 021 = ieee 754 exception + TRAP T_FP_OTHER ! 022 = other fp exception TRAP T_TAGOF ! 023 = tag overflow KCLEANWIN ! 024-027 = clean window trap TRAP T_DIV0 ! 028 = divide by zero @@ -2556,29 +2556,6 @@ text_error: NOTREACHED /* - * fp_exception has to check to see if we are trying to save - * the FP state, and if so, continue to save the FP state. - * - * We do not even bother checking to see if we were in kernel mode, - * since users have no access to the special_fp_store instruction. - * - * This whole idea was stolen from Sprite. - */ -/* - * XXX I don't think this is at all revelent for V9. - */ -fp_exception: - rdpr %tpc, %g1 - set special_fp_store, %g4 ! see if we came from the special one - cmp %g1, %g4 ! pc == special_fp_store? - bne slowtrap ! no, go handle per usual - sethi %hi(savefpcont), %g4 ! yes, "return" to the special code - or %lo(savefpcont), %g4, %g4 - wrpr %g0, %g4, %tnpc - done - NOTREACHED - -/* * We're here because we took an alignment fault in NUCLEUS context. * This could be a kernel bug or it could be due to saving or restoring * a user window to/from an invalid stack pointer. @@ -8998,10 +8975,9 @@ ENTRY(clearfpstate) wrpr %o1, 0, %pstate /* - * savefpstate(f) struct fpstate *f; + * savefpstate(struct fpstate *f) * - * Store the current FPU state. The first `st %fsr' may cause a trap; - * our trap handler knows how to recover (by `returning' to savefpcont). + * Store the current FPU state. * * Since the kernel may need to use the FPU and we have problems atomically * testing and enabling the FPU, we leave here with the FPRS_FEF bit set. @@ -9009,37 +8985,18 @@ ENTRY(clearfpstate) */ /* XXXXXXXXXX Assume caller created a proper stack frame */ ENTRY(savefpstate) -! flushw ! Make sure we don't have stack probs & lose hibits of %o rdpr %pstate, %o1 ! enable FP before we begin rd %fprs, %o5 wr %g0, FPRS_FEF, %fprs or %o1, PSTATE_PEF, %o1 wrpr %o1, 0, %pstate - /* do some setup work while we wait for PSR_EF to turn on */ - set FSR_QNE, %o2 ! QNE = 0x2000, too big for immediate - clr %o3 ! qsize = 0; -special_fp_store: - /* This may need to be done w/rdpr/stx combo */ + stx %fsr, [%o0 + FS_FSR] ! f->fs_fsr = getfsr(); - /* - * Even if the preceding instruction did not trap, the queue - * is not necessarily empty: this state save might be happening - * because user code tried to store %fsr and took the FPU - * from `exception pending' mode to `exception' mode. - * So we still have to check the blasted QNE bit. - * With any luck it will usually not be set. - */ + rd %gsr, %o4 ! Save %gsr st %o4, [%o0 + FS_GSR] - ldx [%o0 + FS_FSR], %o4 ! if (f->fs_fsr & QNE) - btst %o2, %o4 - add %o0, FS_REGS, %o2 - bnz Lfp_storeq ! goto storeq; -Lfp_finish: - btst BLOCK_ALIGN, %o2 ! Needs to be re-executed - bnz,pn %icc, 3f ! Check alignment - st %o3, [%o0 + FS_QSIZE] ! f->fs_qsize = qsize; + add %o0, FS_REGS, %o2 ! This is zero... btst FPRS_DL, %o5 ! Lower FPU clean? bz,a,pt %icc, 1f ! Then skip it add %o2, 128, %o2 ! Skip a block @@ -9062,103 +9019,12 @@ Lfp_finish: membar #Sync ! Finish operation so we can retl wr %g0, FPRS_FEF, %fprs ! Mark FPU clean -3: -#ifdef DIAGNOSTIC - btst 7, %o2 ! 32-bit aligned!?!? - bnz,pn %icc, 6f -#endif /* DIAGNOSTIC */ - btst FPRS_DL, %o5 ! Lower FPU clean? - bz,a,pt %icc, 4f ! Then skip it - add %o0, 128, %o0 - - membar #Sync - std %f0, [%o0 + FS_REGS + (4*0)] ! f->fs_f0 = etc; - std %f2, [%o0 + FS_REGS + (4*2)] - std %f4, [%o0 + FS_REGS + (4*4)] - std %f6, [%o0 + FS_REGS + (4*6)] - std %f8, [%o0 + FS_REGS + (4*8)] - std %f10, [%o0 + FS_REGS + (4*10)] - std %f12, [%o0 + FS_REGS + (4*12)] - std %f14, [%o0 + FS_REGS + (4*14)] - std %f16, [%o0 + FS_REGS + (4*16)] - std %f18, [%o0 + FS_REGS + (4*18)] - std %f20, [%o0 + FS_REGS + (4*20)] - std %f22, [%o0 + FS_REGS + (4*22)] - std %f24, [%o0 + FS_REGS + (4*24)] - std %f26, [%o0 + FS_REGS + (4*26)] - std %f28, [%o0 + FS_REGS + (4*28)] - std %f30, [%o0 + FS_REGS + (4*30)] -4: - btst FPRS_DU, %o5 ! Upper FPU clean? - bz,pt %icc, 5f ! Then skip it - nop - - membar #Sync - std %f32, [%o0 + FS_REGS + (4*32)] - std %f34, [%o0 + FS_REGS + (4*34)] - std %f36, [%o0 + FS_REGS + (4*36)] - std %f38, [%o0 + FS_REGS + (4*38)] - std %f40, [%o0 + FS_REGS + (4*40)] - std %f42, [%o0 + FS_REGS + (4*42)] - std %f44, [%o0 + FS_REGS + (4*44)] - std %f46, [%o0 + FS_REGS + (4*46)] - std %f48, [%o0 + FS_REGS + (4*48)] - std %f50, [%o0 + FS_REGS + (4*50)] - std %f52, [%o0 + FS_REGS + (4*52)] - std %f54, [%o0 + FS_REGS + (4*54)] - std %f56, [%o0 + FS_REGS + (4*56)] - std %f58, [%o0 + FS_REGS + (4*58)] - std %f60, [%o0 + FS_REGS + (4*60)] - std %f62, [%o0 + FS_REGS + (4*62)] -5: - membar #Sync - retl - wr %g0, FPRS_FEF, %fprs ! Mark FPU clean - - !! - !! Damn thing is *NOT* aligned on a 64-bit boundary - !! -6: - wr %g0, FPRS_FEF, %fprs - ta 1 - retl - nop - -/* - * Store the (now known nonempty) FP queue. - * We have to reread the fsr each time in order to get the new QNE bit. - * - * UltraSPARCs don't have floating point queues. - */ -Lfp_storeq: - add %o0, FS_QUEUE, %o1 ! q = &f->fs_queue[0]; -1: - rdpr %fq, %o4 - stx %o4, [%o1 + %o3] ! q[qsize++] = fsr_qfront(); - stx %fsr, [%o0 + FS_FSR] ! reread fsr - ldx [%o0 + FS_FSR], %o4 ! if fsr & QNE, loop - btst %o5, %o4 - bnz 1b - inc 8, %o3 - b Lfp_finish ! set qsize and finish storing fregs - srl %o3, 3, %o3 ! (but first fix qsize) - -/* - * The fsr store trapped. Do it again; this time it will not trap. - * We could just have the trap handler return to the `st %fsr', but - * if for some reason it *does* trap, that would lock us into a tight - * loop. This way we panic instead. Whoopee. - */ -savefpcont: - b special_fp_store + 4 ! continue - stx %fsr, [%o0 + FS_FSR] ! but first finish the %fsr store /* * Load FPU state. */ /* XXXXXXXXXX Should test to see if we only need to do a partial restore */ ENTRY(loadfpstate) - flushw ! Make sure we don't have stack probs & lose hibits of %o rdpr %pstate, %o1 ! enable FP before we begin ld [%o0 + FS_GSR], %o4 ! Restore %gsr set PSTATE_PEF, %o2 @@ -9167,9 +9033,7 @@ ENTRY(loadfpstate) wrpr %o1, 0, %pstate ldx [%o0 + FS_FSR], %fsr ! setfsr(f->fs_fsr); add %o0, FS_REGS, %o3 ! This is zero... - btst BLOCK_ALIGN, %o3 - bne,pt %icc, 1f ! Only use block loads on aligned blocks - wr %o4, %g0, %gsr + wr %o4, %g0, %gsr membar #Sync ldda [%o3] ASI_BLK_P, %f0 inc BLOCK_SIZE, %o3 @@ -9181,55 +9045,6 @@ ENTRY(loadfpstate) membar #Sync ! Make sure loads are complete retl wr %g0, FPRS_FEF, %fprs ! Clear dirty bits -1: -#ifdef DIAGNOSTIC - btst 7, %o3 - bne,pn %icc, 1f - nop -#endif /* DIAGNOSTIC */ - /* Unaligned -- needs to be done the long way - membar #Sync - ldd [%o3 + (4*0)], %f0 - ldd [%o3 + (4*2)], %f2 - ldd [%o3 + (4*4)], %f4 - ldd [%o3 + (4*6)], %f6 - ldd [%o3 + (4*8)], %f8 - ldd [%o3 + (4*10)], %f10 - ldd [%o3 + (4*12)], %f12 - ldd [%o3 + (4*14)], %f14 - ldd [%o3 + (4*16)], %f16 - ldd [%o3 + (4*18)], %f18 - ldd [%o3 + (4*20)], %f20 - ldd [%o3 + (4*22)], %f22 - ldd [%o3 + (4*24)], %f24 - ldd [%o3 + (4*26)], %f26 - ldd [%o3 + (4*28)], %f28 - ldd [%o3 + (4*30)], %f30 - ldd [%o3 + (4*32)], %f32 - ldd [%o3 + (4*34)], %f34 - ldd [%o3 + (4*36)], %f36 - ldd [%o3 + (4*38)], %f38 - ldd [%o3 + (4*40)], %f40 - ldd [%o3 + (4*42)], %f42 - ldd [%o3 + (4*44)], %f44 - ldd [%o3 + (4*46)], %f46 - ldd [%o3 + (4*48)], %f48 - ldd [%o3 + (4*50)], %f50 - ldd [%o3 + (4*52)], %f52 - ldd [%o3 + (4*54)], %f54 - ldd [%o3 + (4*56)], %f56 - ldd [%o3 + (4*58)], %f58 - ldd [%o3 + (4*60)], %f60 - ldd [%o3 + (4*62)], %f62 - membar #Sync - retl - wr %g0, FPRS_FEF, %fprs ! Clear dirty bits - -1: - wr %g0, FPRS_FEF, %fprs ! Clear dirty bits - ta 1 - retl - nop /* XXX belongs elsewhere (ctlreg.h?) */ #define AFSR_CECC_ERROR 0x100000 /* AFSR Correctable ECC err */ |