/* Copyright (C) 2021,2022 fef . All rights reserved. */ #include #include #include /* * XXX We should probably move to exclusively using the APIC on amd64 * (and i386 too, because the APIC was introduced with the 486 and we don't * support anything below 686 anyway) */ .data /* void (*irq_table[NUM_IRQ])(void); */ .extern irq_table /* there is probably a fancy CPU feature for this, but idk */ L_DATA(irq_count) .long 0 L_END(irq_count) .text /* bool in_irq(void); */ ENTRY(in_irq) movabsq $irq_count, %rdx xor %eax, %eax mov %eax, %ecx not %ecx testl %ecx, (%rdx) setne %al retq END(in_irq) .section .text.isr .macro gen_irq num ENTRY(_x86_isr_irq\num ) push %rax push %rcx push %rdx push %rdi push %rsi push %r8 push %r9 push %r10 push %r11 movabsq $irq_count, %rax incl (%rax) #if CFG_DEBUG_IRQ movl $\num, %edi #endif movabsq $(irq_table + \num * 8), %rax callq *%rax jmp leave_irq END(_x86_isr_irq\num ) .endm gen_irq 0 gen_irq 1 /* IRQ 2 is for cascading from PIC2 to PIC1 */ gen_irq 3 gen_irq 4 gen_irq 5 gen_irq 6 gen_irq 7 gen_irq 8 gen_irq 9 gen_irq 10 gen_irq 11 gen_irq 12 gen_irq 13 gen_irq 14 gen_irq 15 L_ENTRY(leave_irq) movabsq $irq_count, %rax decl (%rax) pop %r11 pop %r10 pop %r9 pop %r8 pop %rsi pop %rdi pop %rdx pop %rcx pop %rax iretq L_END(leave_irq)