From 482e65d13d9d2932d244483c6ca2209823941583 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 8 May 2023 08:08:33 +0100 Subject: [PATCH] x86_64: irq: add array of asm irq entry points --- arch/x86_64/irq.c | 839 +++++++++++++++++++++++----------------------- 1 file changed, 422 insertions(+), 417 deletions(-) diff --git a/arch/x86_64/irq.c b/arch/x86_64/irq.c index 07bad5a..d703cf1 100644 --- a/arch/x86_64/irq.c +++ b/arch/x86_64/irq.c @@ -12,6 +12,170 @@ #define MAX_ISR_HANDLERS 16 +extern void syscall_gate(); +extern uintptr_t pf_faultptr(void); + +static int_hook isr_handlers[NR_IDT_ENTRIES]; +static struct queue irq_hooks[223]; + +static struct idt idt; +static int idt_initialised = 0; +static uintptr_t int_entry_points[NR_IDT_ENTRIES]; + +static void set_idt_gate(struct idt *idt, uint8_t index, uintptr_t base, uint16_t sel, uint8_t flags) +{ + idt->i_entries[index].base_low = base & 0xFFFF; + idt->i_entries[index].base_middle = (base >> 16) & 0xFFFF; + idt->i_entries[index].base_high = (base >> 32) & 0xFFFFFFFF; + idt->i_entries[index].selector = sel; + idt->i_entries[index].always0 = 0; + idt->i_entries[index].present = 1; + idt->i_entries[index].dpl = 3; + idt->i_entries[index].zero = 0; + idt->i_entries[index].type = 0xE; + idt->i_entries[index].reserved = 0; +} + +static void gpf_handler(struct cpu_context *regs) +{ + int ext = regs->err_no & 1; + int table = (regs->err_no >> 1) & 0x03; + int index = (regs->err_no >> 3) & 0x1FFF; + + panic_irq(regs, "general protection fault (%016llx %02x %02x %04x %016llx)", + regs->err_no, ext, table, index, regs->rip); +} + +static void pf_handler(struct cpu_context *regs) +{ + panic_irq(regs, "page fault (%016llx %016llx %016llx)", pf_faultptr(), regs->rip, regs->err_no); +} + +#if 0 +static void set_syscall_gate(uintptr_t rip) +{ + /* sysret adds 0x10 to this to get cs, and 0x8 to get ss + * note that the CPU should force the RPL to 3 when loading + * the selector by using user_cs | 3. However, this doesn't happen + * in certain scenarios (specifically, QEMU + KVM on a Ryzen 5 1600X). */ + uint64_t user_cs = 0x13; + uint64_t kernel_cs = 0x8; + + uintptr_t star_reg = 0xC0000081; + uintptr_t lstar_reg = 0xC0000082; + uintptr_t sfmask_reg = 0xC0000084; + + uint64_t selectors = 0; + selectors |= (user_cs) << 48; + selectors |= (kernel_cs) << 32; + + /* disable interrupts */ + uint64_t flag_mask = 0x200; + + write_msr(star_reg, selectors); + write_msr(lstar_reg, rip); + write_msr(sfmask_reg, flag_mask); +} +#endif + +static void init_pic() +{ + // Remap the PIC + outportb(0x20, 0x11); + outportb(0xA0, 0x11); + outportb(0x21, 0x20); + outportb(0xA1, 0x28); + outportb(0x21, 0x04); + outportb(0xA1, 0x02); + outportb(0x21, 0x01); + outportb(0xA1, 0x01); + outportb(0x21, 0x0); + outportb(0xA1, 0x0); + + isr_handlers[13] = gpf_handler; + isr_handlers[14] = pf_handler; +} + +static void init_global_idt(void) +{ + memset((void *)&idt.i_entries, 0, sizeof idt.i_entries); + + for (int i = 0; i < NR_IDT_ENTRIES; i++) { + set_idt_gate(&idt, i, int_entry_points[i], 0x08, 0x8E); + } + + init_pic(); + + idt_initialised = 1; +} + +int idt_init(struct idt_ptr *ptr) +{ + if (idt_initialised == 0) { + init_global_idt(); + } + + ptr->i_limit = sizeof(idt) - 1; + ptr->i_base = (uintptr_t)&idt; + + return 0; +} + +int idt_load(struct idt_ptr *ptr) +{ + __asm__ __volatile__("lidt (%0)" ::"r" (ptr)); + return 0; +} + +void isr_dispatch(struct cpu_context *regs) +{ + printk("received ISR#%u on CPU %u", regs->int_no, this_cpu()); + int_hook h = isr_handlers[regs->int_no]; + if (h) { + h(regs); + } else { + panic_irq(regs, "unhandled exception %u", regs->int_no); + } +} + +void irq_dispatch(struct cpu_context *regs) +{ + end_charge_period(); + + if (regs->int_no != IRQ0) { + printk("received IRQ#%u on CPU %u", regs->int_no - IRQ0, this_cpu()); + } + + irq_ack(regs->int_no); + struct queue *hooks = &irq_hooks[regs->int_no - IRQ0]; + queue_foreach(struct irq_hook, hook, hooks, irq_entry) { + hook->irq_callback(); + } + + if (need_resched()) { + schedule(SCHED_IRQ); + } + + start_charge_period(); +} + +void syscall_dispatch(struct cpu_context *regs) +{ + +} + +void hook_irq(enum irq_vector vec, struct irq_hook *hook) +{ + struct queue *hook_queue = &irq_hooks[vec - IRQ0]; + queue_push_back(hook_queue, &hook->irq_entry); +} + +void unhook_irq(enum irq_vector vec, struct irq_hook *hook) +{ + struct queue *hook_queue = &irq_hooks[vec - IRQ0]; + queue_delete(hook_queue, &hook->irq_entry); +} + extern void _isr0(); extern void _isr1(); extern void _isr2(); @@ -270,420 +434,261 @@ extern void _irq221(); extern void _irq222(); extern void _irq223(); -extern void syscall_gate(); -extern uintptr_t pf_faultptr(void); - -static int_hook isr_handlers[NR_IDT_ENTRIES]; -static struct queue irq_hooks[223]; - -static struct idt idt; -static int idt_initialised = 0; - -static void set_idt_gate(struct idt *idt, uint8_t index, uintptr_t base, uint16_t sel, uint8_t flags) -{ - idt->i_entries[index].base_low = base & 0xFFFF; - idt->i_entries[index].base_middle = (base >> 16) & 0xFFFF; - idt->i_entries[index].base_high = (base >> 32) & 0xFFFFFFFF; - idt->i_entries[index].selector = sel; - idt->i_entries[index].always0 = 0; - idt->i_entries[index].present = 1; - idt->i_entries[index].dpl = 3; - idt->i_entries[index].zero = 0; - idt->i_entries[index].type = 0xE; - idt->i_entries[index].reserved = 0; -} - -static void gpf_handler(struct cpu_context *regs) -{ - int ext = regs->err_no & 1; - int table = (regs->err_no >> 1) & 0x03; - int index = (regs->err_no >> 3) & 0x1FFF; - - panic_irq(regs, "general protection fault (%016llx %02x %02x %04x %016llx)", - regs->err_no, ext, table, index, regs->rip); -} - -static void pf_handler(struct cpu_context *regs) -{ - panic_irq(regs, "page fault (%016llx %016llx %016llx)", pf_faultptr(), regs->rip, regs->err_no); -} - -#if 0 -static void set_syscall_gate(uintptr_t rip) -{ - /* sysret adds 0x10 to this to get cs, and 0x8 to get ss - * note that the CPU should force the RPL to 3 when loading - * the selector by using user_cs | 3. However, this doesn't happen - * in certain scenarios (specifically, QEMU + KVM on a Ryzen 5 1600X). */ - uint64_t user_cs = 0x13; - uint64_t kernel_cs = 0x8; - - uintptr_t star_reg = 0xC0000081; - uintptr_t lstar_reg = 0xC0000082; - uintptr_t sfmask_reg = 0xC0000084; - - uint64_t selectors = 0; - selectors |= (user_cs) << 48; - selectors |= (kernel_cs) << 32; - - /* disable interrupts */ - uint64_t flag_mask = 0x200; - - write_msr(star_reg, selectors); - write_msr(lstar_reg, rip); - write_msr(sfmask_reg, flag_mask); -} -#endif - -static void init_pic() -{ - // Remap the PIC - outportb(0x20, 0x11); - outportb(0xA0, 0x11); - outportb(0x21, 0x20); - outportb(0xA1, 0x28); - outportb(0x21, 0x04); - outportb(0xA1, 0x02); - outportb(0x21, 0x01); - outportb(0xA1, 0x01); - outportb(0x21, 0x0); - outportb(0xA1, 0x0); - - isr_handlers[13] = gpf_handler; - isr_handlers[14] = pf_handler; -} - -static void init_global_idt(void) -{ - memset((void *)&idt.i_entries, 0, sizeof idt.i_entries); - - set_idt_gate(&idt, 0, (uintptr_t)_isr0, 0x08, 0x8E); - set_idt_gate(&idt, 1, (uintptr_t)_isr1, 0x08, 0x8E); - set_idt_gate(&idt, 2, (uintptr_t)_isr2, 0x08, 0x8E); - set_idt_gate(&idt, 3, (uintptr_t)_isr3, 0x08, 0x8E); - set_idt_gate(&idt, 4, (uintptr_t)_isr4, 0x08, 0x8E); - set_idt_gate(&idt, 5, (uintptr_t)_isr5, 0x08, 0x8E); - set_idt_gate(&idt, 6, (uintptr_t)_isr6, 0x08, 0x8E); - set_idt_gate(&idt, 7, (uintptr_t)_isr7, 0x08, 0x8E); - set_idt_gate(&idt, 8, (uintptr_t)_isr8, 0x08, 0x8E); - set_idt_gate(&idt, 9, (uintptr_t)_isr9, 0x08, 0x8E); - set_idt_gate(&idt, 10, (uintptr_t)_isr10, 0x08, 0x8E); - set_idt_gate(&idt, 11, (uintptr_t)_isr11, 0x08, 0x8E); - set_idt_gate(&idt, 12, (uintptr_t)_isr12, 0x08, 0x8E); - set_idt_gate(&idt, 13, (uintptr_t)_isr13, 0x08, 0x8E); - set_idt_gate(&idt, 14, (uintptr_t)_isr14, 0x08, 0x8E); - set_idt_gate(&idt, 15, (uintptr_t)_isr15, 0x08, 0x8E); - set_idt_gate(&idt, 16, (uintptr_t)_isr16, 0x08, 0x8E); - set_idt_gate(&idt, 17, (uintptr_t)_isr17, 0x08, 0x8E); - set_idt_gate(&idt, 18, (uintptr_t)_isr18, 0x08, 0x8E); - set_idt_gate(&idt, 19, (uintptr_t)_isr19, 0x08, 0x8E); - set_idt_gate(&idt, 20, (uintptr_t)_isr20, 0x08, 0x8E); - set_idt_gate(&idt, 21, (uintptr_t)_isr21, 0x08, 0x8E); - set_idt_gate(&idt, 22, (uintptr_t)_isr22, 0x08, 0x8E); - set_idt_gate(&idt, 23, (uintptr_t)_isr23, 0x08, 0x8E); - set_idt_gate(&idt, 24, (uintptr_t)_isr24, 0x08, 0x8E); - set_idt_gate(&idt, 25, (uintptr_t)_isr25, 0x08, 0x8E); - set_idt_gate(&idt, 26, (uintptr_t)_isr26, 0x08, 0x8E); - set_idt_gate(&idt, 27, (uintptr_t)_isr27, 0x08, 0x8E); - set_idt_gate(&idt, 28, (uintptr_t)_isr28, 0x08, 0x8E); - set_idt_gate(&idt, 29, (uintptr_t)_isr29, 0x08, 0x8E); - set_idt_gate(&idt, 30, (uintptr_t)_isr30, 0x08, 0x8E); - set_idt_gate(&idt, 31, (uintptr_t)_isr31, 0x08, 0x8E); - - init_pic(); - - // Install the IRQs - set_idt_gate(&idt, 32, (uintptr_t)_irq0, 0x08, 0x8E); - set_idt_gate(&idt, 33, (uintptr_t)_irq1, 0x08, 0x8E); - set_idt_gate(&idt, 34, (uintptr_t)_irq2, 0x08, 0x8E); - set_idt_gate(&idt, 35, (uintptr_t)_irq3, 0x08, 0x8E); - set_idt_gate(&idt, 36, (uintptr_t)_irq4, 0x08, 0x8E); - set_idt_gate(&idt, 37, (uintptr_t)_irq5, 0x08, 0x8E); - set_idt_gate(&idt, 38, (uintptr_t)_irq6, 0x08, 0x8E); - set_idt_gate(&idt, 39, (uintptr_t)_irq7, 0x08, 0x8E); - set_idt_gate(&idt, 40, (uintptr_t)_irq8, 0x08, 0x8E); - set_idt_gate(&idt, 41, (uintptr_t)_irq9, 0x08, 0x8E); - set_idt_gate(&idt, 42, (uintptr_t)_irq10, 0x08, 0x8E); - set_idt_gate(&idt, 43, (uintptr_t)_irq11, 0x08, 0x8E); - set_idt_gate(&idt, 44, (uintptr_t)_irq12, 0x08, 0x8E); - set_idt_gate(&idt, 45, (uintptr_t)_irq13, 0x08, 0x8E); - set_idt_gate(&idt, 46, (uintptr_t)_irq14, 0x08, 0x8E); - set_idt_gate(&idt, 47, (uintptr_t)_irq15, 0x08, 0x8E); - set_idt_gate(&idt, 48, (uintptr_t)_irq16, 0x08, 0x8E); - set_idt_gate(&idt, 49, (uintptr_t)_irq17, 0x08, 0x8E); - set_idt_gate(&idt, 50, (uintptr_t)_irq18, 0x08, 0x8E); - set_idt_gate(&idt, 51, (uintptr_t)_irq19, 0x08, 0x8E); - set_idt_gate(&idt, 52, (uintptr_t)_irq20, 0x08, 0x8E); - set_idt_gate(&idt, 53, (uintptr_t)_irq21, 0x08, 0x8E); - set_idt_gate(&idt, 54, (uintptr_t)_irq22, 0x08, 0x8E); - set_idt_gate(&idt, 55, (uintptr_t)_irq23, 0x08, 0x8E); - set_idt_gate(&idt, 56, (uintptr_t)_irq24, 0x08, 0x8E); - set_idt_gate(&idt, 57, (uintptr_t)_irq25, 0x08, 0x8E); - set_idt_gate(&idt, 58, (uintptr_t)_irq26, 0x08, 0x8E); - set_idt_gate(&idt, 59, (uintptr_t)_irq27, 0x08, 0x8E); - set_idt_gate(&idt, 60, (uintptr_t)_irq28, 0x08, 0x8E); - set_idt_gate(&idt, 61, (uintptr_t)_irq29, 0x08, 0x8E); - set_idt_gate(&idt, 62, (uintptr_t)_irq30, 0x08, 0x8E); - set_idt_gate(&idt, 63, (uintptr_t)_irq31, 0x08, 0x8E); - set_idt_gate(&idt, 64, (uintptr_t)_irq32, 0x08, 0x8E); - set_idt_gate(&idt, 65, (uintptr_t)_irq33, 0x08, 0x8E); - set_idt_gate(&idt, 66, (uintptr_t)_irq34, 0x08, 0x8E); - set_idt_gate(&idt, 67, (uintptr_t)_irq35, 0x08, 0x8E); - set_idt_gate(&idt, 68, (uintptr_t)_irq36, 0x08, 0x8E); - set_idt_gate(&idt, 69, (uintptr_t)_irq37, 0x08, 0x8E); - set_idt_gate(&idt, 70, (uintptr_t)_irq38, 0x08, 0x8E); - set_idt_gate(&idt, 71, (uintptr_t)_irq39, 0x08, 0x8E); - set_idt_gate(&idt, 72, (uintptr_t)_irq40, 0x08, 0x8E); - set_idt_gate(&idt, 73, (uintptr_t)_irq41, 0x08, 0x8E); - set_idt_gate(&idt, 74, (uintptr_t)_irq42, 0x08, 0x8E); - set_idt_gate(&idt, 75, (uintptr_t)_irq43, 0x08, 0x8E); - set_idt_gate(&idt, 76, (uintptr_t)_irq44, 0x08, 0x8E); - set_idt_gate(&idt, 77, (uintptr_t)_irq45, 0x08, 0x8E); - set_idt_gate(&idt, 78, (uintptr_t)_irq46, 0x08, 0x8E); - set_idt_gate(&idt, 79, (uintptr_t)_irq47, 0x08, 0x8E); - set_idt_gate(&idt, 80, (uintptr_t)_irq48, 0x08, 0x8E); - set_idt_gate(&idt, 81, (uintptr_t)_irq49, 0x08, 0x8E); - set_idt_gate(&idt, 82, (uintptr_t)_irq50, 0x08, 0x8E); - set_idt_gate(&idt, 83, (uintptr_t)_irq51, 0x08, 0x8E); - set_idt_gate(&idt, 84, (uintptr_t)_irq52, 0x08, 0x8E); - set_idt_gate(&idt, 85, (uintptr_t)_irq53, 0x08, 0x8E); - set_idt_gate(&idt, 86, (uintptr_t)_irq54, 0x08, 0x8E); - set_idt_gate(&idt, 87, (uintptr_t)_irq55, 0x08, 0x8E); - set_idt_gate(&idt, 88, (uintptr_t)_irq56, 0x08, 0x8E); - set_idt_gate(&idt, 89, (uintptr_t)_irq57, 0x08, 0x8E); - set_idt_gate(&idt, 90, (uintptr_t)_irq58, 0x08, 0x8E); - set_idt_gate(&idt, 91, (uintptr_t)_irq59, 0x08, 0x8E); - set_idt_gate(&idt, 92, (uintptr_t)_irq60, 0x08, 0x8E); - set_idt_gate(&idt, 93, (uintptr_t)_irq61, 0x08, 0x8E); - set_idt_gate(&idt, 94, (uintptr_t)_irq62, 0x08, 0x8E); - set_idt_gate(&idt, 95, (uintptr_t)_irq63, 0x08, 0x8E); - set_idt_gate(&idt, 96, (uintptr_t)_irq64, 0x08, 0x8E); - set_idt_gate(&idt, 97, (uintptr_t)_irq65, 0x08, 0x8E); - set_idt_gate(&idt, 98, (uintptr_t)_irq66, 0x08, 0x8E); - set_idt_gate(&idt, 99, (uintptr_t)_irq67, 0x08, 0x8E); - set_idt_gate(&idt, 100, (uintptr_t)_irq68, 0x08, 0x8E); - set_idt_gate(&idt, 101, (uintptr_t)_irq69, 0x08, 0x8E); - set_idt_gate(&idt, 102, (uintptr_t)_irq70, 0x08, 0x8E); - set_idt_gate(&idt, 103, (uintptr_t)_irq71, 0x08, 0x8E); - set_idt_gate(&idt, 104, (uintptr_t)_irq72, 0x08, 0x8E); - set_idt_gate(&idt, 105, (uintptr_t)_irq73, 0x08, 0x8E); - set_idt_gate(&idt, 106, (uintptr_t)_irq74, 0x08, 0x8E); - set_idt_gate(&idt, 107, (uintptr_t)_irq75, 0x08, 0x8E); - set_idt_gate(&idt, 108, (uintptr_t)_irq76, 0x08, 0x8E); - set_idt_gate(&idt, 109, (uintptr_t)_irq77, 0x08, 0x8E); - set_idt_gate(&idt, 110, (uintptr_t)_irq78, 0x08, 0x8E); - set_idt_gate(&idt, 111, (uintptr_t)_irq79, 0x08, 0x8E); - set_idt_gate(&idt, 112, (uintptr_t)_irq80, 0x08, 0x8E); - set_idt_gate(&idt, 113, (uintptr_t)_irq81, 0x08, 0x8E); - set_idt_gate(&idt, 114, (uintptr_t)_irq82, 0x08, 0x8E); - set_idt_gate(&idt, 115, (uintptr_t)_irq83, 0x08, 0x8E); - set_idt_gate(&idt, 116, (uintptr_t)_irq84, 0x08, 0x8E); - set_idt_gate(&idt, 117, (uintptr_t)_irq85, 0x08, 0x8E); - set_idt_gate(&idt, 118, (uintptr_t)_irq86, 0x08, 0x8E); - set_idt_gate(&idt, 119, (uintptr_t)_irq87, 0x08, 0x8E); - set_idt_gate(&idt, 120, (uintptr_t)_irq88, 0x08, 0x8E); - set_idt_gate(&idt, 121, (uintptr_t)_irq89, 0x08, 0x8E); - set_idt_gate(&idt, 122, (uintptr_t)_irq90, 0x08, 0x8E); - set_idt_gate(&idt, 123, (uintptr_t)_irq91, 0x08, 0x8E); - set_idt_gate(&idt, 124, (uintptr_t)_irq92, 0x08, 0x8E); - set_idt_gate(&idt, 125, (uintptr_t)_irq93, 0x08, 0x8E); - set_idt_gate(&idt, 126, (uintptr_t)_irq94, 0x08, 0x8E); - set_idt_gate(&idt, 127, (uintptr_t)_irq95, 0x08, 0x8E); - set_idt_gate(&idt, 128, (uintptr_t)_irq96, 0x08, 0x8E); - set_idt_gate(&idt, 129, (uintptr_t)_irq97, 0x08, 0x8E); - set_idt_gate(&idt, 130, (uintptr_t)_irq98, 0x08, 0x8E); - set_idt_gate(&idt, 131, (uintptr_t)_irq99, 0x08, 0x8E); - set_idt_gate(&idt, 132, (uintptr_t)_irq100, 0x08, 0x8E); - set_idt_gate(&idt, 133, (uintptr_t)_irq101, 0x08, 0x8E); - set_idt_gate(&idt, 134, (uintptr_t)_irq102, 0x08, 0x8E); - set_idt_gate(&idt, 135, (uintptr_t)_irq103, 0x08, 0x8E); - set_idt_gate(&idt, 136, (uintptr_t)_irq104, 0x08, 0x8E); - set_idt_gate(&idt, 137, (uintptr_t)_irq105, 0x08, 0x8E); - set_idt_gate(&idt, 138, (uintptr_t)_irq106, 0x08, 0x8E); - set_idt_gate(&idt, 139, (uintptr_t)_irq107, 0x08, 0x8E); - set_idt_gate(&idt, 140, (uintptr_t)_irq108, 0x08, 0x8E); - set_idt_gate(&idt, 141, (uintptr_t)_irq109, 0x08, 0x8E); - set_idt_gate(&idt, 142, (uintptr_t)_irq110, 0x08, 0x8E); - set_idt_gate(&idt, 143, (uintptr_t)_irq111, 0x08, 0x8E); - set_idt_gate(&idt, 144, (uintptr_t)_irq112, 0x08, 0x8E); - set_idt_gate(&idt, 145, (uintptr_t)_irq113, 0x08, 0x8E); - set_idt_gate(&idt, 146, (uintptr_t)_irq114, 0x08, 0x8E); - set_idt_gate(&idt, 147, (uintptr_t)_irq115, 0x08, 0x8E); - set_idt_gate(&idt, 148, (uintptr_t)_irq116, 0x08, 0x8E); - set_idt_gate(&idt, 149, (uintptr_t)_irq117, 0x08, 0x8E); - set_idt_gate(&idt, 150, (uintptr_t)_irq118, 0x08, 0x8E); - set_idt_gate(&idt, 151, (uintptr_t)_irq119, 0x08, 0x8E); - set_idt_gate(&idt, 152, (uintptr_t)_irq120, 0x08, 0x8E); - set_idt_gate(&idt, 153, (uintptr_t)_irq121, 0x08, 0x8E); - set_idt_gate(&idt, 154, (uintptr_t)_irq122, 0x08, 0x8E); - set_idt_gate(&idt, 155, (uintptr_t)_irq123, 0x08, 0x8E); - set_idt_gate(&idt, 156, (uintptr_t)_irq124, 0x08, 0x8E); - set_idt_gate(&idt, 157, (uintptr_t)_irq125, 0x08, 0x8E); - set_idt_gate(&idt, 158, (uintptr_t)_irq126, 0x08, 0x8E); - set_idt_gate(&idt, 159, (uintptr_t)_irq127, 0x08, 0x8E); - set_idt_gate(&idt, 160, (uintptr_t)_irq128, 0x08, 0x8E); - set_idt_gate(&idt, 161, (uintptr_t)_irq129, 0x08, 0x8E); - set_idt_gate(&idt, 162, (uintptr_t)_irq130, 0x08, 0x8E); - set_idt_gate(&idt, 163, (uintptr_t)_irq131, 0x08, 0x8E); - set_idt_gate(&idt, 164, (uintptr_t)_irq132, 0x08, 0x8E); - set_idt_gate(&idt, 165, (uintptr_t)_irq133, 0x08, 0x8E); - set_idt_gate(&idt, 166, (uintptr_t)_irq134, 0x08, 0x8E); - set_idt_gate(&idt, 167, (uintptr_t)_irq135, 0x08, 0x8E); - set_idt_gate(&idt, 168, (uintptr_t)_irq136, 0x08, 0x8E); - set_idt_gate(&idt, 169, (uintptr_t)_irq137, 0x08, 0x8E); - set_idt_gate(&idt, 170, (uintptr_t)_irq138, 0x08, 0x8E); - set_idt_gate(&idt, 171, (uintptr_t)_irq139, 0x08, 0x8E); - set_idt_gate(&idt, 172, (uintptr_t)_irq140, 0x08, 0x8E); - set_idt_gate(&idt, 173, (uintptr_t)_irq141, 0x08, 0x8E); - set_idt_gate(&idt, 174, (uintptr_t)_irq142, 0x08, 0x8E); - set_idt_gate(&idt, 175, (uintptr_t)_irq143, 0x08, 0x8E); - set_idt_gate(&idt, 176, (uintptr_t)_irq144, 0x08, 0x8E); - set_idt_gate(&idt, 177, (uintptr_t)_irq145, 0x08, 0x8E); - set_idt_gate(&idt, 178, (uintptr_t)_irq146, 0x08, 0x8E); - set_idt_gate(&idt, 179, (uintptr_t)_irq147, 0x08, 0x8E); - set_idt_gate(&idt, 180, (uintptr_t)_irq148, 0x08, 0x8E); - set_idt_gate(&idt, 181, (uintptr_t)_irq149, 0x08, 0x8E); - set_idt_gate(&idt, 182, (uintptr_t)_irq150, 0x08, 0x8E); - set_idt_gate(&idt, 183, (uintptr_t)_irq151, 0x08, 0x8E); - set_idt_gate(&idt, 184, (uintptr_t)_irq152, 0x08, 0x8E); - set_idt_gate(&idt, 185, (uintptr_t)_irq153, 0x08, 0x8E); - set_idt_gate(&idt, 186, (uintptr_t)_irq154, 0x08, 0x8E); - set_idt_gate(&idt, 187, (uintptr_t)_irq155, 0x08, 0x8E); - set_idt_gate(&idt, 188, (uintptr_t)_irq156, 0x08, 0x8E); - set_idt_gate(&idt, 189, (uintptr_t)_irq157, 0x08, 0x8E); - set_idt_gate(&idt, 190, (uintptr_t)_irq158, 0x08, 0x8E); - set_idt_gate(&idt, 191, (uintptr_t)_irq159, 0x08, 0x8E); - set_idt_gate(&idt, 192, (uintptr_t)_irq160, 0x08, 0x8E); - set_idt_gate(&idt, 193, (uintptr_t)_irq161, 0x08, 0x8E); - set_idt_gate(&idt, 194, (uintptr_t)_irq162, 0x08, 0x8E); - set_idt_gate(&idt, 195, (uintptr_t)_irq163, 0x08, 0x8E); - set_idt_gate(&idt, 196, (uintptr_t)_irq164, 0x08, 0x8E); - set_idt_gate(&idt, 197, (uintptr_t)_irq165, 0x08, 0x8E); - set_idt_gate(&idt, 198, (uintptr_t)_irq166, 0x08, 0x8E); - set_idt_gate(&idt, 199, (uintptr_t)_irq167, 0x08, 0x8E); - set_idt_gate(&idt, 200, (uintptr_t)_irq168, 0x08, 0x8E); - set_idt_gate(&idt, 201, (uintptr_t)_irq169, 0x08, 0x8E); - set_idt_gate(&idt, 202, (uintptr_t)_irq170, 0x08, 0x8E); - set_idt_gate(&idt, 203, (uintptr_t)_irq171, 0x08, 0x8E); - set_idt_gate(&idt, 204, (uintptr_t)_irq172, 0x08, 0x8E); - set_idt_gate(&idt, 205, (uintptr_t)_irq173, 0x08, 0x8E); - set_idt_gate(&idt, 206, (uintptr_t)_irq174, 0x08, 0x8E); - set_idt_gate(&idt, 207, (uintptr_t)_irq175, 0x08, 0x8E); - set_idt_gate(&idt, 208, (uintptr_t)_irq176, 0x08, 0x8E); - set_idt_gate(&idt, 209, (uintptr_t)_irq177, 0x08, 0x8E); - set_idt_gate(&idt, 210, (uintptr_t)_irq178, 0x08, 0x8E); - set_idt_gate(&idt, 211, (uintptr_t)_irq179, 0x08, 0x8E); - set_idt_gate(&idt, 212, (uintptr_t)_irq180, 0x08, 0x8E); - set_idt_gate(&idt, 213, (uintptr_t)_irq181, 0x08, 0x8E); - set_idt_gate(&idt, 214, (uintptr_t)_irq182, 0x08, 0x8E); - set_idt_gate(&idt, 215, (uintptr_t)_irq183, 0x08, 0x8E); - set_idt_gate(&idt, 216, (uintptr_t)_irq184, 0x08, 0x8E); - set_idt_gate(&idt, 217, (uintptr_t)_irq185, 0x08, 0x8E); - set_idt_gate(&idt, 218, (uintptr_t)_irq186, 0x08, 0x8E); - set_idt_gate(&idt, 219, (uintptr_t)_irq187, 0x08, 0x8E); - set_idt_gate(&idt, 220, (uintptr_t)_irq188, 0x08, 0x8E); - set_idt_gate(&idt, 221, (uintptr_t)_irq189, 0x08, 0x8E); - set_idt_gate(&idt, 222, (uintptr_t)_irq190, 0x08, 0x8E); - set_idt_gate(&idt, 223, (uintptr_t)_irq191, 0x08, 0x8E); - set_idt_gate(&idt, 224, (uintptr_t)_irq192, 0x08, 0x8E); - set_idt_gate(&idt, 225, (uintptr_t)_irq193, 0x08, 0x8E); - set_idt_gate(&idt, 226, (uintptr_t)_irq194, 0x08, 0x8E); - set_idt_gate(&idt, 227, (uintptr_t)_irq195, 0x08, 0x8E); - set_idt_gate(&idt, 228, (uintptr_t)_irq196, 0x08, 0x8E); - set_idt_gate(&idt, 229, (uintptr_t)_irq197, 0x08, 0x8E); - set_idt_gate(&idt, 230, (uintptr_t)_irq198, 0x08, 0x8E); - set_idt_gate(&idt, 231, (uintptr_t)_irq199, 0x08, 0x8E); - set_idt_gate(&idt, 232, (uintptr_t)_irq200, 0x08, 0x8E); - set_idt_gate(&idt, 233, (uintptr_t)_irq201, 0x08, 0x8E); - set_idt_gate(&idt, 234, (uintptr_t)_irq202, 0x08, 0x8E); - set_idt_gate(&idt, 235, (uintptr_t)_irq203, 0x08, 0x8E); - set_idt_gate(&idt, 236, (uintptr_t)_irq204, 0x08, 0x8E); - set_idt_gate(&idt, 237, (uintptr_t)_irq205, 0x08, 0x8E); - set_idt_gate(&idt, 238, (uintptr_t)_irq206, 0x08, 0x8E); - set_idt_gate(&idt, 239, (uintptr_t)_irq207, 0x08, 0x8E); - set_idt_gate(&idt, 240, (uintptr_t)_irq208, 0x08, 0x8E); - set_idt_gate(&idt, 241, (uintptr_t)_irq209, 0x08, 0x8E); - set_idt_gate(&idt, 242, (uintptr_t)_irq210, 0x08, 0x8E); - set_idt_gate(&idt, 243, (uintptr_t)_irq211, 0x08, 0x8E); - set_idt_gate(&idt, 244, (uintptr_t)_irq212, 0x08, 0x8E); - set_idt_gate(&idt, 245, (uintptr_t)_irq213, 0x08, 0x8E); - set_idt_gate(&idt, 246, (uintptr_t)_irq214, 0x08, 0x8E); - set_idt_gate(&idt, 247, (uintptr_t)_irq215, 0x08, 0x8E); - set_idt_gate(&idt, 248, (uintptr_t)_irq216, 0x08, 0x8E); - set_idt_gate(&idt, 249, (uintptr_t)_irq217, 0x08, 0x8E); - set_idt_gate(&idt, 250, (uintptr_t)_irq218, 0x08, 0x8E); - set_idt_gate(&idt, 251, (uintptr_t)_irq219, 0x08, 0x8E); - set_idt_gate(&idt, 252, (uintptr_t)_irq220, 0x08, 0x8E); - set_idt_gate(&idt, 253, (uintptr_t)_irq221, 0x08, 0x8E); - set_idt_gate(&idt, 254, (uintptr_t)_irq222, 0x08, 0x8E); - set_idt_gate(&idt, 255, (uintptr_t)_irq223, 0x08, 0x8E); - - idt_initialised = 1; -} - -int idt_init(struct idt_ptr *ptr) -{ - if (idt_initialised == 0) { - init_global_idt(); - } - - ptr->i_limit = sizeof(idt) - 1; - ptr->i_base = (uintptr_t)&idt; - - return 0; -} - -int idt_load(struct idt_ptr *ptr) -{ - __asm__ __volatile__("lidt (%0)" ::"r" (ptr)); - return 0; -} - -void isr_dispatch(struct cpu_context *regs) -{ - printk("received ISR#%u on CPU %u", regs->int_no, this_cpu()); - int_hook h = isr_handlers[regs->int_no]; - if (h) { - h(regs); - } else { - panic_irq(regs, "unhandled exception %u", regs->int_no); - } -} - -void irq_dispatch(struct cpu_context *regs) -{ - end_charge_period(); - - if (regs->int_no != IRQ0) { - printk("received IRQ#%u on CPU %u", regs->int_no, this_cpu()); - } - - irq_ack(regs->int_no); - struct queue *hooks = &irq_hooks[regs->int_no - IRQ0]; - queue_foreach(struct irq_hook, hook, hooks, irq_entry) { - hook->irq_callback(); - } - - if (need_resched()) { - schedule(SCHED_IRQ); - } - - start_charge_period(); -} - -void syscall_dispatch(struct cpu_context *regs) -{ - -} - -void hook_irq(enum irq_vector vec, struct irq_hook *hook) -{ - struct queue *hook_queue = &irq_hooks[vec - IRQ0]; - queue_push_back(hook_queue, &hook->irq_entry); -} - -void unhook_irq(enum irq_vector vec, struct irq_hook *hook) -{ - struct queue *hook_queue = &irq_hooks[vec - IRQ0]; - queue_delete(hook_queue, &hook->irq_entry); -} +static uintptr_t int_entry_points[NR_IDT_ENTRIES] = { + [0] = (uintptr_t)_isr0, + [1] = (uintptr_t)_isr1, + [2] = (uintptr_t)_isr2, + [3] = (uintptr_t)_isr3, + [4] = (uintptr_t)_isr4, + [5] = (uintptr_t)_isr5, + [6] = (uintptr_t)_isr6, + [7] = (uintptr_t)_isr7, + [8] = (uintptr_t)_isr8, + [9] = (uintptr_t)_isr9, + [10] = (uintptr_t)_isr10, + [11] = (uintptr_t)_isr11, + [12] = (uintptr_t)_isr12, + [13] = (uintptr_t)_isr13, + [14] = (uintptr_t)_isr14, + [15] = (uintptr_t)_isr15, + [16] = (uintptr_t)_isr16, + [17] = (uintptr_t)_isr17, + [18] = (uintptr_t)_isr18, + [19] = (uintptr_t)_isr19, + [20] = (uintptr_t)_isr20, + [21] = (uintptr_t)_isr21, + [22] = (uintptr_t)_isr22, + [23] = (uintptr_t)_isr23, + [24] = (uintptr_t)_isr24, + [25] = (uintptr_t)_isr25, + [26] = (uintptr_t)_isr26, + [27] = (uintptr_t)_isr27, + [28] = (uintptr_t)_isr28, + [29] = (uintptr_t)_isr29, + [30] = (uintptr_t)_isr30, + [31] = (uintptr_t)_isr31, + [32] = (uintptr_t)_irq0, + [33] = (uintptr_t)_irq1, + [34] = (uintptr_t)_irq2, + [35] = (uintptr_t)_irq3, + [36] = (uintptr_t)_irq4, + [37] = (uintptr_t)_irq5, + [38] = (uintptr_t)_irq6, + [39] = (uintptr_t)_irq7, + [40] = (uintptr_t)_irq8, + [41] = (uintptr_t)_irq9, + [42] = (uintptr_t)_irq10, + [43] = (uintptr_t)_irq11, + [44] = (uintptr_t)_irq12, + [45] = (uintptr_t)_irq13, + [46] = (uintptr_t)_irq14, + [47] = (uintptr_t)_irq15, + [48] = (uintptr_t)_irq16, + [49] = (uintptr_t)_irq17, + [50] = (uintptr_t)_irq18, + [51] = (uintptr_t)_irq19, + [52] = (uintptr_t)_irq20, + [53] = (uintptr_t)_irq21, + [54] = (uintptr_t)_irq22, + [55] = (uintptr_t)_irq23, + [56] = (uintptr_t)_irq24, + [57] = (uintptr_t)_irq25, + [58] = (uintptr_t)_irq26, + [59] = (uintptr_t)_irq27, + [60] = (uintptr_t)_irq28, + [61] = (uintptr_t)_irq29, + [62] = (uintptr_t)_irq30, + [63] = (uintptr_t)_irq31, + [64] = (uintptr_t)_irq32, + [65] = (uintptr_t)_irq33, + [66] = (uintptr_t)_irq34, + [67] = (uintptr_t)_irq35, + [68] = (uintptr_t)_irq36, + [69] = (uintptr_t)_irq37, + [70] = (uintptr_t)_irq38, + [71] = (uintptr_t)_irq39, + [72] = (uintptr_t)_irq40, + [73] = (uintptr_t)_irq41, + [74] = (uintptr_t)_irq42, + [75] = (uintptr_t)_irq43, + [76] = (uintptr_t)_irq44, + [77] = (uintptr_t)_irq45, + [78] = (uintptr_t)_irq46, + [79] = (uintptr_t)_irq47, + [80] = (uintptr_t)_irq48, + [81] = (uintptr_t)_irq49, + [82] = (uintptr_t)_irq50, + [83] = (uintptr_t)_irq51, + [84] = (uintptr_t)_irq52, + [85] = (uintptr_t)_irq53, + [86] = (uintptr_t)_irq54, + [87] = (uintptr_t)_irq55, + [88] = (uintptr_t)_irq56, + [89] = (uintptr_t)_irq57, + [90] = (uintptr_t)_irq58, + [91] = (uintptr_t)_irq59, + [92] = (uintptr_t)_irq60, + [93] = (uintptr_t)_irq61, + [94] = (uintptr_t)_irq62, + [95] = (uintptr_t)_irq63, + [96] = (uintptr_t)_irq64, + [97] = (uintptr_t)_irq65, + [98] = (uintptr_t)_irq66, + [99] = (uintptr_t)_irq67, + [100] = (uintptr_t)_irq68, + [101] = (uintptr_t)_irq69, + [102] = (uintptr_t)_irq70, + [103] = (uintptr_t)_irq71, + [104] = (uintptr_t)_irq72, + [105] = (uintptr_t)_irq73, + [106] = (uintptr_t)_irq74, + [107] = (uintptr_t)_irq75, + [108] = (uintptr_t)_irq76, + [109] = (uintptr_t)_irq77, + [110] = (uintptr_t)_irq78, + [111] = (uintptr_t)_irq79, + [112] = (uintptr_t)_irq80, + [113] = (uintptr_t)_irq81, + [114] = (uintptr_t)_irq82, + [115] = (uintptr_t)_irq83, + [116] = (uintptr_t)_irq84, + [117] = (uintptr_t)_irq85, + [118] = (uintptr_t)_irq86, + [119] = (uintptr_t)_irq87, + [120] = (uintptr_t)_irq88, + [121] = (uintptr_t)_irq89, + [122] = (uintptr_t)_irq90, + [123] = (uintptr_t)_irq91, + [124] = (uintptr_t)_irq92, + [125] = (uintptr_t)_irq93, + [126] = (uintptr_t)_irq94, + [127] = (uintptr_t)_irq95, + [128] = (uintptr_t)_irq96, + [129] = (uintptr_t)_irq97, + [130] = (uintptr_t)_irq98, + [131] = (uintptr_t)_irq99, + [132] = (uintptr_t)_irq100, + [133] = (uintptr_t)_irq101, + [134] = (uintptr_t)_irq102, + [135] = (uintptr_t)_irq103, + [136] = (uintptr_t)_irq104, + [137] = (uintptr_t)_irq105, + [138] = (uintptr_t)_irq106, + [139] = (uintptr_t)_irq107, + [140] = (uintptr_t)_irq108, + [141] = (uintptr_t)_irq109, + [142] = (uintptr_t)_irq110, + [143] = (uintptr_t)_irq111, + [144] = (uintptr_t)_irq112, + [145] = (uintptr_t)_irq113, + [146] = (uintptr_t)_irq114, + [147] = (uintptr_t)_irq115, + [148] = (uintptr_t)_irq116, + [149] = (uintptr_t)_irq117, + [150] = (uintptr_t)_irq118, + [151] = (uintptr_t)_irq119, + [152] = (uintptr_t)_irq120, + [153] = (uintptr_t)_irq121, + [154] = (uintptr_t)_irq122, + [155] = (uintptr_t)_irq123, + [156] = (uintptr_t)_irq124, + [157] = (uintptr_t)_irq125, + [158] = (uintptr_t)_irq126, + [159] = (uintptr_t)_irq127, + [160] = (uintptr_t)_irq128, + [161] = (uintptr_t)_irq129, + [162] = (uintptr_t)_irq130, + [163] = (uintptr_t)_irq131, + [164] = (uintptr_t)_irq132, + [165] = (uintptr_t)_irq133, + [166] = (uintptr_t)_irq134, + [167] = (uintptr_t)_irq135, + [168] = (uintptr_t)_irq136, + [169] = (uintptr_t)_irq137, + [170] = (uintptr_t)_irq138, + [171] = (uintptr_t)_irq139, + [172] = (uintptr_t)_irq140, + [173] = (uintptr_t)_irq141, + [174] = (uintptr_t)_irq142, + [175] = (uintptr_t)_irq143, + [176] = (uintptr_t)_irq144, + [177] = (uintptr_t)_irq145, + [178] = (uintptr_t)_irq146, + [179] = (uintptr_t)_irq147, + [180] = (uintptr_t)_irq148, + [181] = (uintptr_t)_irq149, + [182] = (uintptr_t)_irq150, + [183] = (uintptr_t)_irq151, + [184] = (uintptr_t)_irq152, + [185] = (uintptr_t)_irq153, + [186] = (uintptr_t)_irq154, + [187] = (uintptr_t)_irq155, + [188] = (uintptr_t)_irq156, + [189] = (uintptr_t)_irq157, + [190] = (uintptr_t)_irq158, + [191] = (uintptr_t)_irq159, + [192] = (uintptr_t)_irq160, + [193] = (uintptr_t)_irq161, + [194] = (uintptr_t)_irq162, + [195] = (uintptr_t)_irq163, + [196] = (uintptr_t)_irq164, + [197] = (uintptr_t)_irq165, + [198] = (uintptr_t)_irq166, + [199] = (uintptr_t)_irq167, + [200] = (uintptr_t)_irq168, + [201] = (uintptr_t)_irq169, + [202] = (uintptr_t)_irq170, + [203] = (uintptr_t)_irq171, + [204] = (uintptr_t)_irq172, + [205] = (uintptr_t)_irq173, + [206] = (uintptr_t)_irq174, + [207] = (uintptr_t)_irq175, + [208] = (uintptr_t)_irq176, + [209] = (uintptr_t)_irq177, + [210] = (uintptr_t)_irq178, + [211] = (uintptr_t)_irq179, + [212] = (uintptr_t)_irq180, + [213] = (uintptr_t)_irq181, + [214] = (uintptr_t)_irq182, + [215] = (uintptr_t)_irq183, + [216] = (uintptr_t)_irq184, + [217] = (uintptr_t)_irq185, + [218] = (uintptr_t)_irq186, + [219] = (uintptr_t)_irq187, + [220] = (uintptr_t)_irq188, + [221] = (uintptr_t)_irq189, + [222] = (uintptr_t)_irq190, + [223] = (uintptr_t)_irq191, + [224] = (uintptr_t)_irq192, + [225] = (uintptr_t)_irq193, + [226] = (uintptr_t)_irq194, + [227] = (uintptr_t)_irq195, + [228] = (uintptr_t)_irq196, + [229] = (uintptr_t)_irq197, + [230] = (uintptr_t)_irq198, + [231] = (uintptr_t)_irq199, + [232] = (uintptr_t)_irq200, + [233] = (uintptr_t)_irq201, + [234] = (uintptr_t)_irq202, + [235] = (uintptr_t)_irq203, + [236] = (uintptr_t)_irq204, + [237] = (uintptr_t)_irq205, + [238] = (uintptr_t)_irq206, + [239] = (uintptr_t)_irq207, + [240] = (uintptr_t)_irq208, + [241] = (uintptr_t)_irq209, + [242] = (uintptr_t)_irq210, + [243] = (uintptr_t)_irq211, + [244] = (uintptr_t)_irq212, + [245] = (uintptr_t)_irq213, + [246] = (uintptr_t)_irq214, + [247] = (uintptr_t)_irq215, + [248] = (uintptr_t)_irq216, + [249] = (uintptr_t)_irq217, + [250] = (uintptr_t)_irq218, + [251] = (uintptr_t)_irq219, + [252] = (uintptr_t)_irq220, + [253] = (uintptr_t)_irq221, + [254] = (uintptr_t)_irq222, + [255] = (uintptr_t)_irq223, +};