📄 traps.s
字号:
jmpl %l1, %g0 rett %l2/* * Register window underflow handler. Come here when restore would move us * into the invalid window. This routine runs with traps disabled, and * must be careful not to touch the condition codes, as PSR is never * restored. * * We are called with %l0 = wim, %l1 = pc, %l2 = npc */ .globl SYM(win_underflow)SYM(win_underflow): sll %l0, 1, %l3 ! Rotate wim left srl %l0, NUMBER_OF_REGISTER_WINDOWS - 1, %l0 or %l0, %l3, %l0 mov %l0, %wim ! Install the new wim restore ! Users window restore ! His callers window ldd [%sp + 0 * 4], %l0 ! restore L & I registers ldd [%sp + 2 * 4], %l2 ldd [%sp + 4 * 4], %l4 ldd [%sp + 6 * 4], %l6 ldd [%sp + 8 * 4], %i0 ldd [%sp + 10 * 4], %i2 ldd [%sp + 12 * 4], %i4 ldd [%sp + 14 * 4], %i6 save %g0, %g0, %g0 ! Back to trap window save %g0, %g0, %g0 jmpl %l1, %g0 rett %l2/* * Register window flush handler, triggered by a "ta 3" instruction. * We are called with %l0 = wim, %l1 = pc, %l2 = npc */ .globl SYM(win_flush)SYM(win_flush): mov %psr, %l0 or %l0,0xf00,%l3 ! Disable interrupts mov %l3,%psr nop nop nop mov %wim, %l3 srl %l3, %l0, %l4 ! wim >> cwp cmp %l4, 1 bne flush_window_fine ! Branch if not in the invalid window nop/* Handle window overflow. We can't trap here. */ mov %g1, %l4 ! Save g1, we use it to hold the wim srl %l3, 1, %g1 ! Rotate wim right sll %l3, NUMBER_OF_REGISTER_WINDOWS - 1, %l3 or %l3, %g1, %g1 mov %g0, %wim ! Clear wim so that subsequent save nop ! wont trap nop nop save %g0, %g0, %g0 ! Slip into next window mov %g1, %wim ! Install the new wim std %l0, [%sp + 0 * 4] ! save L & I registers std %l2, [%sp + 2 * 4] std %l4, [%sp + 4 * 4] std %l6, [%sp + 6 * 4] std %i0, [%sp + 8 * 4] std %i2, [%sp + 10 * 4] std %i4, [%sp + 12 * 4] std %i6, [%sp + 14 * 4] restore ! Go back to trap window. mov %l4, %g1 ! Restore %g1flush_window_fine: mov %psr,%l5 ! enable traps or %l5,0x20,%l5 mov %l5, %psr nop nop nop set save_buf,%l5 st %l2,[%l5] ! The stack pointer currently contains a bogus value [when a trap ! occurs CWP is decremented and points to an unused window]. ! Give it something useful before we flush every window. ! This does what a "save %sp,-64,$sp" would, except that CWP has ! already been decremented. add %fp, -64, %sp save %sp, -64, %sp ! Flush user register window to stack save %sp, -64, %sp save %sp, -64, %sp save %sp, -64, %sp save %sp, -64, %sp save %sp, -64, %sp save %sp, -64, %sp save %sp, -64, %sp restore restore restore restore restore restore restore restore restore ! Make sure we have a valid window save %g0, %g0, %g0 set save_buf, %l2 ! Get our return address back ld [%l2],%l2 mov %psr,%l5 ! disable traps for rett andn %l5,0x20,%l5 mov %l5,%psr nop nop nop jmpl %l2, %g0 rett %l2+4/* * Read the TBR. */ .globl SYM(rdtbr)SYM(rdtbr): mov %tbr, %o0 nop retl nop/* * Read the psr */ .globl SYM(read_psr)SYM(read_psr): mov %psr, %o0 nop retl nop/* * Write the PSR. */ .globl SYM(write_psr)SYM(write_psr): mov %i0, %psr nop nop nop retl nop/* * Come here when no fpu exists. This just skips the offending * instruction. */ .globl SYM(no_fpu)SYM(no_fpu): jmpl %l2, %g0 rett %l2+4 .globl SYM(fltr_proto) .align 4SYM(fltr_proto): ! First level trap routine prototype sethi 0, %l0 jmpl 0+%l0, %g0 nop nop/* * Trap handler for memory errors. This just sets mem_err to be * non-zero. It assumes that l1 is non-zero. This should be safe, * as it is doubtful that 0 would ever contain code that could mem * fault. This routine will skip past the faulting instruction after * setting mem_err. */ .globl SYM(fltr_set_mem_err)SYM(fltr_set_mem_err): sethi %hi(SYM(mem_err)), %l0 st %l1, [%l0 + %lo(SYM(mem_err))] jmpl %l2, %g0 rett %l2+4 .data .align 4 .ascii "DaTa" .long SYM(sdata)in_trap_handler: .word 0save_buf: .word 0 /* place to save %g1 */ .word 0 /* place to save %g2 */ .text .align 4/* * This function is called when any SPARC trap (except window overflow * or underflow) occurs. It makes sure that the invalid register * window is still available before jumping into C code. It will also * restore the world if you return from handle_exception. */ .globl SYM(trap_low)SYM(trap_low): mov %psr, %l0 mov %wim, %l3 srl %l3, %l0, %l4 ! wim >> cwp cmp %l4, 1 bne window_fine ! Branch if not in the invalid window nop mov %g1, %l4 ! Save g1, we use it to hold the wim srl %l3, 1, %g1 ! Rotate wim right sll %l3, 8-1, %l5 or %l5, %g1, %g1 save %g0, %g0, %g0 ! Slip into next window mov %g1, %wim ! Install the new wim std %l0, [%sp + 0 * 4] ! save L & I registers std %l2, [%sp + 2 * 4] std %l4, [%sp + 4 * 4] std %l6, [%sp + 6 * 4] std %i0, [%sp + 8 * 4] std %i2, [%sp + 10 * 4] std %i4, [%sp + 12 * 4] std %i6, [%sp + 14 * 4] restore ! Go back to trap window. mov %l4, %g1 ! Restore g1window_fine: sethi %hi(in_trap_handler), %l4 ld [%lo(in_trap_handler) + %l4], %l5 tst %l5 bg recursive_trap inc %l5 /* use the stack we set in the linker script */ sethi %hi(__trap_stack), %l6 or %l6,%lo(__trap_stack),%l6 mov %l6, %sp ! set the stack pointerrecursive_trap: st %l5, [%lo(in_trap_handler) + %l4] sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals ! + hidden arg + arg spill ! + doubleword alignment ! + registers[72] local var std %g0, [%sp + (24 + 0) * 4] ! registers[Gx] std %g2, [%sp + (24 + 2) * 4] std %g4, [%sp + (24 + 4) * 4] std %g6, [%sp + (24 + 6) * 4] std %i0, [%sp + (24 + 8) * 4] ! registers[Ox] std %i2, [%sp + (24 + 10) * 4] std %i4, [%sp + (24 + 12) * 4] std %i6, [%sp + (24 + 14) * 4] ! F0->F31 not implemented mov %y, %l4 mov %tbr, %l5 st %l4, [%sp + (24 + 64) * 4] ! Y st %l0, [%sp + (24 + 65) * 4] ! PSR st %l3, [%sp + (24 + 66) * 4] ! WIM st %l5, [%sp + (24 + 67) * 4] ! TBR st %l1, [%sp + (24 + 68) * 4] ! PC st %l2, [%sp + (24 + 69) * 4] ! NPC ! CPSR and FPSR not implemented or %l0, 0xf20, %l4 mov %l4, %psr ! Turn on traps, disable interrupts call SYM(handle_exception) add %sp, 24 * 4, %o0 ! Pass address of registers/* Reload all of the registers that aren't on the stack */ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx] ldd [%sp + (24 + 2) * 4], %g2 ldd [%sp + (24 + 4) * 4], %g4 ldd [%sp + (24 + 6) * 4], %g6 ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox] ldd [%sp + (24 + 10) * 4], %i2 ldd [%sp + (24 + 12) * 4], %i4 ldd [%sp + (24 + 14) * 4], %i6 ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC restore ! Ensure that previous window is valid save %g0, %g0, %g0 ! by causing a window_underflow trap mov %l0, %y mov %l1, %psr ! Make sure that traps are disabled ! for rett sethi %hi(in_trap_handler), %l4 ld [%lo(in_trap_handler) + %l4], %l5 dec %l5 st %l5, [%lo(in_trap_handler) + %l4] jmpl %l2, %g0 ! Restore old PC rett %l3 ! Restore old nPC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -