/* * Interrupt/exception handling. * Each entry in the vector table calls either _strayintr or _strayintrx depending * on whether an error code has been automatically pushed onto the stack * (_strayintrx) or not, in which case a dummy entry must be pushed before retrieving * the trap type from the vector table entry and placing it on the stack as part * of the Ureg structure. * The size of each entry in the vector table (6 bytes) is known in trapinit0(). * Volume 3A 6-14 * Stack is (high -> low) * SS, RSP, RFLAGS, CS, RIP, Error Code (if any), vectortable(SB) return PC * (SP) = Vectortable(SB) return PC. The first byte of this return PC will be the * byte we used to identify the trap type. * Removed the nested check that 9front does as we are not using different code * segments or tasks. */ TEXT _strayintr(SB), 1, $-4 /* no error code pushed */ PUSHQ AX /* some value to fill the ecode slot in the stack and also store AX value */ MOVQ 8(SP), AX /* vectortable(SB) PC */ /* Stack is SS, RSP, RFLAGS, CS, RIP, vectortable(SB) Return PC, AX AX = vectortable(SB) return PC */ JMP _intrcommon TEXT _strayintrx(SB), 1, $-4/* error code pushed */ XCHGQ AX, (SP) /* exchange AX with pointer to trap type */ /* Stack is SS, RSP, RFLAGS, CS, RIP, Error Code, AX AX = vectortable(SB) return PC */ _intrcommon: MOVBQZX (AX), AX /* extract trap type from the vectortable(SB) return PC -> AX */ XCHGQ AX, (SP) /* exchange vectortable(SB) return PC with the trap type in AX */ /* Stack is SS, RSP, RFLAGS, CS, RIP, Error Code or vectortable(SB) Return PC, trap type AX = AX */ PUSHW GS PUSHW FS MOVW ES, AX /* PUSHW ES is invalid in amd64, but showing the value for debugging */ PUSHW AX MOVW DS, AX /* PUSHW DS is invalid in amd64, but showing the value as JMP uses it */ PUSHW AX PUSHQ R15 /* RMACH m-> */ PUSHQ R14 /* RUSER up-> */ PUSHQ R13 PUSHQ R12 PUSHQ R11 PUSHQ R10 PUSHQ R9 PUSHQ R8 PUSHQ BP PUSHQ DI PUSHQ SI PUSHQ DX PUSHQ CX PUSHQ BX PUSHQ AX MOVQ SP, RARG /* Ureg* argument to trap */ PUSHQ SP CALL trap(SB) TEXT _intrr(SB), 1, $-4 _intrestore: POPQ AX /* ignore the SP pushed before the call to trap() */ POPQ AX /* restore registers */ POPQ BX POPQ CX POPQ DX POPQ SI POPQ DI POPQ BP POPQ R8 POPQ R9 POPQ R10 POPQ R11 POPQ R12 POPQ R13 POPQ R14 /* RUSER up-> */ POPQ R15 /* RMACH m-> */ ADDQ $8, SP /* to ignore the [DEFG]S registers as they should not be changing */ ADDQ $16, SP /* pop error code and trap type */ IRETQ TEXT noteret(SB), 1, $-4 CLI JMP _intrestore TEXT vectortable(SB), $0 CALL _strayintr(SB); BYTE $0x00 /* divide error */ CALL _strayintr(SB); BYTE $0x01 /* debug exception */ CALL _strayintr(SB); BYTE $0x02 /* NMI interrupt */ CALL _strayintr(SB); BYTE $0x03 /* breakpoint */ CALL _strayintr(SB); BYTE $0x04 /* overflow */ CALL _strayintr(SB); BYTE $0x05 /* bound */ CALL _strayintr(SB); BYTE $0x06 /* invalid opcode */ CALL _strayintr(SB); BYTE $0x07 /* no coprocessor available */ CALL _strayintrx(SB); BYTE $0x08 /* double fault */ CALL _strayintr(SB); BYTE $0x09 /* coprocessor segment overflow */ CALL _strayintrx(SB); BYTE $0x0A /* invalid TSS */ CALL _strayintrx(SB); BYTE $0x0B /* segment not available */ CALL _strayintrx(SB); BYTE $0x0C /* stack exception */ CALL _strayintrx(SB); BYTE $0x0D /* general protection error */ CALL _strayintrx(SB); BYTE $0x0E /* page fault */ CALL _strayintr(SB); BYTE $0x0F /* */ CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */ CALL _strayintrx(SB); BYTE $0x11 /* alignment check */ CALL _strayintr(SB); BYTE $0x12 /* machine check */ CALL _strayintr(SB); BYTE $0x13 /* simd error */ CALL _strayintr(SB); BYTE $0x14 CALL _strayintr(SB); BYTE $0x15 CALL _strayintr(SB); BYTE $0x16 CALL _strayintr(SB); BYTE $0x17 CALL _strayintr(SB); BYTE $0x18 CALL _strayintr(SB); BYTE $0x19 CALL _strayintr(SB); BYTE $0x1A CALL _strayintr(SB); BYTE $0x1B CALL _strayintr(SB); BYTE $0x1C CALL _strayintr(SB); BYTE $0x1D CALL _strayintr(SB); BYTE $0x1E CALL _strayintr(SB); BYTE $0x1F CALL _strayintr(SB); BYTE $0x20 /* VectorLAPIC */ CALL _strayintr(SB); BYTE $0x21 CALL _strayintr(SB); BYTE $0x22 CALL _strayintr(SB); BYTE $0x23 CALL _strayintr(SB); BYTE $0x24 CALL _strayintr(SB); BYTE $0x25 CALL _strayintr(SB); BYTE $0x26