.align 0x1000 .global IrqHandlerApplyStateChange .local a IrqHandlerApplyStateChange: push %r14 push %r15 // Disable interrupts cli // Get pointer to IrqHandlerApplyStateChange lea (%rip), %r15 a: sub $(a - IrqHandlerApplyStateChange), %r15 // Get pointer to IrqHandlerApplyStateChangeReprotect mov %r15, %r14 add $(IrqHandlerApplyStateChangeFinish - IrqHandlerApplyStateChange), %r14 // Jump far sub $6, %rsp movl %r14d, (%rsp) movw %cs, 4(%rsp) .code32 // HACK: This isn't correct it's valid in 64-bit mode, but GAS doesn't seem to agree ljmp *(%esp) .code64 .local IrqHandlerApplyStateChangeFinish IrqHandlerApplyStateChangeFinish: // Fix registers add $6, %rsp pop %r15 pop %r14 // Enable interrupts // sti // Return ret // Generate IRQ handlers .macro gen_irqh int, err .set pta, . // Disable interrupts cli // Call the thing .if \err popq %rsi movq %rsp, %rdi movq $\int, %rdx call IrqHandlerHandleException .else movq %rsp, %rdi movq $\int, %rsi call IrqHandlerHandleInterrupt .endif // Re-enable interrupts sti // Goodbye :3 iretq // Pad area .if (0x20 - (. - pta)) < 0 .error "IRQ Handler is too long" .elseif (0x20 - (. - pta)) > 0 .zero 0x20 - (. - pta) .endif .endm .global IrqHandlerISRTable IrqHandlerISRTable: gen_irqh 0, 0 gen_irqh 1, 0 gen_irqh 2, 0 gen_irqh 3, 0 gen_irqh 4, 0 gen_irqh 5, 0 gen_irqh 6, 0 gen_irqh 7, 0 gen_irqh 8, 1 gen_irqh 9, 0 gen_irqh 10, 1 gen_irqh 11, 1 gen_irqh 12, 1 gen_irqh 13, 1 gen_irqh 14, 1 gen_irqh 15, 0 gen_irqh 16, 0 gen_irqh 17, 1 gen_irqh 18, 0 gen_irqh 19, 0 gen_irqh 20, 0 gen_irqh 21, 1 gen_irqh 22, 0 gen_irqh 23, 0 gen_irqh 24, 0 gen_irqh 25, 0 gen_irqh 26, 0 gen_irqh 27, 0 gen_irqh 28, 0 gen_irqh 29, 1 gen_irqh 30, 1 gen_irqh 31, 0 .equ i, 32 .rept 256 - 32 gen_irqh i, 0 .equ i, i + 1 .endr