.section .text .align 4 .macro ISR_ERROR index .global _isr\index .type _isr\index, @function _isr\index: cli pushq $\index jmp isr_common_stub .endm .macro ISR_NO_ERROR index .global _isr\index .type _isr\index, @function _isr\index: cli pushq $0 pushq $\index jmp isr_common_stub .endm .macro IRQ id byte .global _irq\id .type _irq\id, @function _irq\id: cli pushq $\id pushq $\byte jmp irq_common_stub .endm .macro PUSH_REGS push %rax push %rcx push %rdx push %rbx pushq $0 push %rbp push %rsi push %rdi push %r8 push %r9 push %r10 push %r11 push %r12 push %r13 push %r14 push %r15 .endm .macro POP_REGS pop %r15 pop %r14 pop %r13 pop %r12 pop %r11 pop %r10 pop %r9 pop %r8 pop %rdi pop %rsi pop %rbp add $8, %rsp pop %rbx pop %rdx pop %rcx pop %rax .endm ISR_NO_ERROR 0 ISR_NO_ERROR 1 ISR_NO_ERROR 2 ISR_NO_ERROR 3 ISR_NO_ERROR 4 ISR_NO_ERROR 5 ISR_NO_ERROR 6 ISR_NO_ERROR 7 ISR_ERROR 8 ISR_NO_ERROR 9 ISR_ERROR 10 ISR_ERROR 11 ISR_ERROR 12 ISR_ERROR 13 ISR_ERROR 14 ISR_NO_ERROR 15 ISR_NO_ERROR 16 ISR_NO_ERROR 17 ISR_NO_ERROR 18 ISR_NO_ERROR 19 ISR_NO_ERROR 20 ISR_NO_ERROR 21 ISR_NO_ERROR 22 ISR_NO_ERROR 23 ISR_NO_ERROR 24 ISR_NO_ERROR 25 ISR_NO_ERROR 26 ISR_NO_ERROR 27 ISR_NO_ERROR 28 ISR_NO_ERROR 29 ISR_NO_ERROR 30 ISR_NO_ERROR 31 ISR_NO_ERROR 128 IRQ 0, 32 IRQ 1, 33 IRQ 2, 34 IRQ 3, 35 IRQ 4, 36 IRQ 5, 37 IRQ 6, 38 IRQ 7, 39 IRQ 8, 40 IRQ 9, 41 IRQ 10, 42 IRQ 11, 43 IRQ 12, 44 IRQ 13, 45 IRQ 14, 46 IRQ 15, 47 .global isr_common_stub .type isr_common_stub, @function isr_common_stub: PUSH_REGS mov %rsp, %rdi call isr_dispatch POP_REGS add $16, %rsp iretq .global irq_common_stub .type irq_common_stub, @function irq_common_stub: PUSH_REGS mov %rsp, %rdi call irq_dispatch POP_REGS add $16, %rsp iretq .global syscall_gate .type syscall_gate, @function .extern syscall_dispatch .type syscall_dispatch, @function syscall_gate: swapgs movq %rsp, %gs:20 # GS+20 = rsp2 in the current TSS block (user stack storage) movq %gs:4, %rsp # GS+4 = rsp0 in the current TSS block (per-thread kstack) # start building a pf_cpu_context pushq $0x1b pushq %gs:20 push %r11 push $0x23 push %rcx pushq $0 pushq $0x80 PUSH_REGS mov %rsp, %rdi # switch back to user gs while in syscall_dispatch. Interrupts are enabled in syscall_dispatch, # and if the task gets pre-empted, the incoming task will expect %gs to have its usermode value. swapgs call syscall_dispatch POP_REGS add $16, %rsp pop %rcx add $8, %rsp pop %r11 add $16, %rsp swapgs movq %gs:20, %rsp # GS+20 = rsp2 in the current TSS block swapgs # back to usermode sysretq .global pf_faultptr .type pf_faultptr, @function pf_faultptr: mov %cr2, %rax ret