📄 locore.s
字号:
std %f0, [%g7+(0*4)] std %f2, [%g7+(2*4)] std %f4, [%g7+(4*4)] std %f6, [%g7+(6*4)] std %f8, [%g7+(8*4)] std %f10, [%g7+(10*4)] std %f12, [%g7+(12*4)] std %f14, [%g7+(14*4)] std %f16, [%g7+(16*4)] std %f18, [%g7+(18*4)] std %f20, [%g7+(20*4)] std %f22, [%g7+(22*4)] std %f24, [%g7+(24*4)] std %f26, [%g7+(26*4)] std %f28, [%g7+(28*4)] std %f30, [%g7+(30*4)]1: set _scb, %g1 ! setup kadb tbr mov %g1, %tbr nop ! tbr delay call _cmd nop ! tbr delay mov %psr, %g1 ! disable traps, goto window 0 bclr PSR_CWP, %g1 mov %g1, %psr nop; nop; nop; ! psr delay wr %g1, PSR_ET, %psr nop; nop; nop; ! psr delay mov %g0, %wim ! zero wim so that we can move around ! ! Restore fpu ! ! If there is not an fpu, we are emulating and the ! registers are already in the right place, the u area. ! If we have not modified the u area there is no problem. ! If we have it is not the debuggers problem. ! sethi %hi(_fpu_exists), %g1 ld [%g1 + %lo(_fpu_exists)], %g1 tst %g1 ! don't bother if no fpu bz 2f ! its already in the u area nop set _regsave, %l3 ! was it on? ld [%l3 + R_PSR], %l0 set PSR_EF, %l5 ! FPU enable bit btst %l5, %l0 ! was the FPU enabled? bz 2f nop set fpuregs, %g7 ldd [%g7+(0*4)], %f0 ! restore registers ldd [%g7+(2*4)], %f2 ldd [%g7+(4*4)], %f4 ldd [%g7+(6*4)], %f6 ldd [%g7+(8*4)], %f8 ldd [%g7+(10*4)], %f10 ldd [%g7+(12*4)], %f12 ldd [%g7+(14*4)], %f14 ldd [%g7+(16*4)], %f16 ldd [%g7+(18*4)], %f18 ldd [%g7+(20*4)], %f20 ldd [%g7+(22*4)], %f22 ldd [%g7+(24*4)], %f24 ldd [%g7+(26*4)], %f26 ldd [%g7+(28*4)], %f28 ldd [%g7+(30*4)], %f30 ld [%g7+(32*4)], %fsr ! restore fsr2: set _regsave, %g7 add %g7, R_WINDOW, %g7 sethi %hi(_nwindows), %g6 ld [%g6 + %lo(_nwindows)], %g61: ld [%g7 + 0*4], %l0 ! restore locals ld [%g7 + 1*4], %l1 ld [%g7 + 2*4], %l2 ld [%g7 + 3*4], %l3 ld [%g7 + 4*4], %l4 ld [%g7 + 5*4], %l5 ld [%g7 + 6*4], %l6 ld [%g7 + 7*4], %l7 ld [%g7 + 8*4], %i0 ! restore ins ld [%g7 + 9*4], %i1 ld [%g7 + 10*4], %i2 ld [%g7 + 11*4], %i3 ld [%g7 + 12*4], %i4 ld [%g7 + 13*4], %i5 ld [%g7 + 14*4], %i6 ld [%g7 + 15*4], %i7 add %g7, WINDOWSIZE, %g7 subcc %g6, 1, %g6 ! all windows done? bnz 1b restore ! delay slot, increment CWP ! ! Should be back in window 0. ! set _regsave, %g7 ld [%g7 + R_PC], %l1 ! restore pc ld [%g7 + R_NPC], %l2 ! restore npc ld [%g7 + R_WIM], %g1 mov %g1, %wim ld [%g7 + R_TBR], %g1 srl %g1, 4, %g1 ! realign ... and %g1, 0xff, %g1 !... and mask to get trap number set (TRAPBRKNO | 0x80), %g2 cmp %g1, %g2 ! compare to see this is a breakpoint bne debugtrap ! a debugger trap return PC+1 nop ! ! return from breakpoint trap ! ld [%g7 + R_PSR], %g1 ! restore psr mov %g1, %psr nop; nop; nop; ! psr delay ld [%g7 + R_TBR], %g1 mov %g1, %tbr ld [%g7 + R_Y], %g1 mov %g1, %y mov %g7, %l3 ! put state ptr in local ld [%l3 + R_G1], %g1 ! restore globals ld [%l3 + R_G2], %g2 ld [%l3 + R_G3], %g3 ld [%l3 + R_G4], %g4 ld [%l3 + R_G5], %g5 ld [%l3 + R_G6], %g6 ld [%l3 + R_G7], %g7 nop jmp %l1 ! return from trap rett %l2 ! ! return from debugger trap !debugtrap: ld [%g7 + R_PSR], %g1 ! restore psr mov %g1, %psr nop; nop; nop; ! psr delay ld [%g7 + R_TBR], %g1 mov %g1, %tbr ld [%g7 + R_Y], %g1 mov %g1, %y mov %g7, %l3 ! put state ptr in local ld [%l3 + R_G1], %g1 ! restore globals ld [%l3 + R_G2], %g2 ld [%l3 + R_G3], %g3 ld [%l3 + R_G4], %g4 ld [%l3 + R_G5], %g5 ld [%l3 + R_G6], %g6 ld [%l3 + R_G7], %g7 jmp %l2 ! return from trap rett %l2 + 4/* * tcode handler for scbsync() */ .align 4 .global _tcode_tcode: sethi %hi(_trap), %l3 or %l3, %lo(_trap), %l3 jmp %l3 mov %psr, %l0LPSR = 0*4LPC = 1*4LNPC = 2*4LSP = 3*4LG1 = 4*4LG2 = 5*4LG3 = 6*4LG4 = 7*4LG5 = 8*4LG6 = 9*4LG7 = 10*4REGSIZE = 11*4/* * General debugger trap handler. * This is only used by traps that happen while the debugger is running. * It is not used for any debuggee traps. * Does overflow checking then vectors to trap handler. */sys_trap: ! ! Prepare to go to C (batten down the hatches). ! Save volatile regs. ! sub %fp, SA(MINFRAME+REGSIZE), %l7 ! make room for reg save area st %g1, [%l7 + MINFRAME + LG1] st %g2, [%l7 + MINFRAME + LG2] st %g3, [%l7 + MINFRAME + LG3] st %g4, [%l7 + MINFRAME + LG4] st %g5, [%l7 + MINFRAME + LG5] st %g6, [%l7 + MINFRAME + LG6] st %g7, [%l7 + MINFRAME + LG7] st %fp, [%l7 + MINFRAME + LSP] st %l0, [%l7 + MINFRAME + LPSR] st %l1, [%l7 + MINFRAME + LPC] st %l2, [%l7 + MINFRAME + LNPC] ! ! Check for window overflow. ! mov 0x01, %l5 ! CWM = 0x01 << CWP sll %l5, %l0, %l5 mov %wim, %l4 ! get WIM btst %l5, %l4 ! compare WIM and CWM bz st_have_window nop ! ! The next window is not empty. Save it. ! sethi %hi(_nwindows), %l6 ld [%l6 + %lo(_nwindows)], %l6 dec %l6 srl %l4, 1, %g1 ! WIM = %g1 = ror(WIM, 1, NWINDOW) sll %l4, %l6, %l4 ! %l6 = NWINDOW - 1 or %l4, %g1, %g1 save ! get into window to be saved mov %g1, %wim ! install new WIM SAVE_WINDOW(%sp) restore ! get back to original window ! ! The next window is available. !st_have_window: mov %l7, %sp ! install new sp mov %tbr, %o0 ! get trap number bclr PSR_PIL, %l0 ! PIL = 15 bset (15 << 8), %l0 wr %l0, PSR_ET, %psr ! enable traps srl %o0, 4, %o0 ! psr delay and %o0, 0xff, %o0 ld [%l7 + MINFRAME + LPC], %o1 ld [%l7 + MINFRAME + LNPC], %o2 mov %l3, %g1 jmpl %g1, %o7 ! call handler nop ! ! Return from trap. ! ld [%l7 + MINFRAME + LPSR], %l0 ! get saved psr bclr PSR_PIL, %l0 ! PIL = 14 bset (14 << 8), %l0 mov %psr, %g1 ! use current CWP mov %g1,%g3 and %g1, PSR_CWP, %g1 andn %l0, PSR_CWP, %l0 or %l0, %g1, %l0 mov %l0, %g1 mov %l0, %psr ! install old psr, disable traps nop;nop;nop ! ! Make sure that there is a window to return to. ! mov 0x2, %g1 ! compute mask for CWP + 1 sll %g1, %l0, %g1 sethi %hi(_nwindows), %g3 ld [%g3 + %lo(_nwindows)], %g3 srl %g1, %g3, %g2 or %g1, %g2, %g1 mov %wim, %g2 ! cmp with wim to check for underflow btst %g1, %g2 bz sr_out nop ! ! No window to return to. Restore it. ! sll %g2, 1, %g1 ! compute new WIM = rol(WIM, 1, NWINDOW) dec %g3 ! %g3 is now NWINDOW-1 srl %g2, %g3, %g2 or %g1, %g2, %g1 mov %g1, %wim ! install it nop; nop; nop; ! wim delay restore ! get into window to be restored RESTORE_WINDOW(%sp) save ! get back to original window ! ! There is a window to return to. ! Restore the volatile regs and return. !sr_out: mov %l0, %psr ! install old PSR_CC ld [%l7 + MINFRAME + LG1], %g1 ld [%l7 + MINFRAME + LG2], %g2 ld [%l7 + MINFRAME + LG3], %g3 ld [%l7 + MINFRAME + LG4], %g4 ld [%l7 + MINFRAME + LG5], %g5 ld [%l7 + MINFRAME + LG6], %g6 ld [%l7 + MINFRAME + LG7], %g7 ld [%l7 + MINFRAME + LSP], %fp ld [%l7 + MINFRAME + LPC], %l1 ld [%l7 + MINFRAME + LNPC], %l2 jmp %l1 rett %l2 .empty/* * Trap handlers. *//* * Window overflow trap handler. * On entry, %l3 = %wim, %l6 = nwindows-1 */ ENTRY(window_overflow) ! ! Compute new WIM. ! mov %g1, %l7 ! save %g1 srl %l3, 1, %g1 ! next WIM = %g1 = ror(WIM, 1, NWINDOW) sll %l3, %l6, %l4 ! %l6 = NWINDOW-1 or %l4, %g1, %g1 save ! get into window to be saved mov %g1, %wim ! install new wim nop; nop; nop; ! wim delay ! ! Put it on the stack. ! SAVE_WINDOW(%sp) restore ! go back to trap window mov %l7, %g1 ! restore g1 jmp %l1 ! reexecute save rett %l2/* * Window underflow trap handler. * On entry, %l3 = %wim, %l6 = nwindows-1 */ ENTRY(window_underflow) sll %l3, 1, %l4 ! next WIM = rol(WIM, 1, NWINDOW) srl %l3, %l6, %l5 ! %l6 = NWINDOW-1 or %l5, %l4, %l5 mov %l5, %wim ! install it nop; nop; nop; ! wim delay restore ! (wim delay 3) get into last window restore ! get into window to be restored RESTORE_WINDOW(%sp) save ! get back to original window save jmp %l1 ! reexecute restore rett %l2/* * Misc subroutines. *//* * Get trap base register. * * char * * gettbr() */ ENTRY(gettbr) mov %tbr, %o0 srl %o0, 12, %o0 retl sll %o0, 12, %o0/* * Set trap base register. * * void * settbr(t) * struct scb *t; */ ENTRY(settbr) srl %o0, 12, %o0 sll %o0, 12, %o0 retl mov %o0, %tbr/* * Return current sp value to caller * * char * * getsp() */ ENTRY(getsp) retl mov %sp, %o0/* * Get system enable register * * char * getenablereg() */ ENTRY(getenablereg) set ENABLEREG, %o0 lduba [%o0]ASI_CTL, %o0 retl nop/* * Set priority level hi. * * splhi() */ ENTRY(splhi) mov %psr, %o0 or %o0, PSR_PIL, %g1 mov %g1, %psr nop ! psr delay retl nop/* * Set priority level 13. * * spl13() */ ENTRY(spl13) mov %psr, %o0 bclr PSR_PIL, %o0 ! PIL = 13 mov %g0, %g1 bset (13 << 8), %g1 or %g1, %o0, %g1 mov %g1, %psr nop ! psr delay retl nop .seg "data" .align 4 .global _fpu_exists_fpu_exists: .word 1 ! assume FPU exists .seg "text" .align 4/* * FPU probe - try a floating point instruction to see if there * really is an FPU in the current configuration. */ ENTRY(fpu_probe) mov %psr, %g1 ! read psr set PSR_EF, %g2 ! enable floating-point bset %g2, %g1 mov %g1, %psr ! write psr nop ! psr delay, three cycles sethi %hi(zero), %g2 ! wait till the fpu bit is fixed or %g2, %lo(zero), %g2 ld [%g2], %fsr ! This causes less trouble with SAS. retl ! if no FPU, we get fp_disabled trap nop ! which will clear the fpu_exists flagzero: .word 0/* * floating point disabled trap. * if FPU does not exist, emulate instruction * otherwise, enable floating point */ .global _fp_disabled_fp_disabled: ! ! if we get an fp_disabled trap and the FPU is enabled ! then there is not an FPU in the configuration ! set PSR_EF, %l5 ! FPU enable bit btst %l5, %l0 ! was the FPU enabled? sethi %hi(_fpu_exists), %l6 bz,a 1f ! fp was disabled, fix up state ld [%l6 + %lo(_fpu_exists)], %l5 ! else clear fpu_exists ! ! fp_disable trap when the FPU is enabled; should only happen ! once from autoconf when there is not an FPU in the board ! clr [%l6 + %lo(_fpu_exists)] ! FPU does not exist in configuration set PSR_EF, %l4 bclr %l4, %l0 mov %l0, %psr nop;nop;nop1: jmp %l2 ! return from trap skip inst rett %l2 + 4 ENTRY(flush_windows) sethi %hi(_nwindows), %g7 ld [%g7 + %lo(_nwindows)], %g7 sub %g7, 2, %g61: deccc %g6 ! all windows done? bnz 1b save %sp, -WINDOWSIZE, %sp sub %g7, 2, %g62: deccc %g6 ! all windows done? bnz 2b restore ! delay slot, increment CWP retl nop /* * asm_trap(x) * int x; * * Do a "t x" instruction */ ENTRY(asm_trap) retl t %o0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -