lindows/lcrash/irq.s

112 lines
1.9 KiB
ArmAsm

.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