From c8866aa88b7ba814ea03f8a505de634f8d842ab0 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 19 Dec 2022 11:34:42 +0200 Subject: [PATCH] Kernel: Move GDT and IDT assembly to inline assembly --- kernel/arch/i386/GDT.cpp | 17 ++++++ kernel/arch/i386/GDT_asm.S | 16 ------ kernel/arch/i386/IDT.cpp | 106 ++++++++++++++++++++++++----------- kernel/arch/i386/IDT_asm.S | 15 ----- kernel/arch/i386/make.config | 2 - 5 files changed, 91 insertions(+), 65 deletions(-) delete mode 100644 kernel/arch/i386/GDT_asm.S delete mode 100644 kernel/arch/i386/IDT_asm.S diff --git a/kernel/arch/i386/GDT.cpp b/kernel/arch/i386/GDT.cpp index 67d202fa..1ff92dd6 100644 --- a/kernel/arch/i386/GDT.cpp +++ b/kernel/arch/i386/GDT.cpp @@ -11,6 +11,23 @@ static GDTR s_gdtr; static SegmentDesriptor* s_gdt; extern "C" void load_gdt(void* gdt_ptr); +asm( +".global load_gdt;" +"load_gdt:" + "movl 4(%esp),%eax;" + "lgdt (%eax);" + + "movw $0x10, %ax;" + "movw %ax, %ds;" + "movw %ax, %es;" + "movw %ax, %fs;" + "movw %ax, %gs;" + "movw %ax, %ss;" + "jmp $0x08,$flush;" + +"flush:" + "ret;" +); void write_gdt_entry_raw(uint8_t segment, uint32_t low, uint32_t high) { diff --git a/kernel/arch/i386/GDT_asm.S b/kernel/arch/i386/GDT_asm.S deleted file mode 100644 index 5dd1fd3a..00000000 --- a/kernel/arch/i386/GDT_asm.S +++ /dev/null @@ -1,16 +0,0 @@ -.global load_gdt - -load_gdt: - movl 4(%esp),%eax - lgdt (%eax) - - movw $0x10, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - jmp $0x08,$flush - -flush: - ret \ No newline at end of file diff --git a/kernel/arch/i386/IDT.cpp b/kernel/arch/i386/IDT.cpp index 674eaead..e30f13f3 100644 --- a/kernel/arch/i386/IDT.cpp +++ b/kernel/arch/i386/IDT.cpp @@ -49,52 +49,94 @@ static void (*s_irq_handlers[0xFF])() { nullptr }; Kernel::panic(msg ", CR0={} CR2={} CR3={} CR4={}", cr0, cr2, cr3, cr4); \ } -INTERRUPT_HANDLER(0x00, "Divide error") -INTERRUPT_HANDLER(0x01, "Debug exception") -INTERRUPT_HANDLER(0x02, "Unknown error") +INTERRUPT_HANDLER(0x00, "Division Error") +INTERRUPT_HANDLER(0x01, "Debug") +INTERRUPT_HANDLER(0x02, "Non-maskable Interrupt") INTERRUPT_HANDLER(0x03, "Breakpoint") INTERRUPT_HANDLER(0x04, "Overflow") -INTERRUPT_HANDLER(0x05, "Bounds check") -INTERRUPT_HANDLER(0x06, "Invalid opcode") -INTERRUPT_HANDLER(0x07, "Coprocessor not available") -INTERRUPT_HANDLER(0x08, "Double fault") -INTERRUPT_HANDLER(0x09, "Coprocessor segment overrun") -INTERRUPT_HANDLER(0x0a, "Invalid TSS") -INTERRUPT_HANDLER(0x0b, "Segment not present") -INTERRUPT_HANDLER(0x0c, "Stack exception") -INTERRUPT_HANDLER(0x0d, "General protection fault") -INTERRUPT_HANDLER(0x0e, "Page fault") -INTERRUPT_HANDLER(0x0f, "Unknown error") -INTERRUPT_HANDLER(0x10, "Coprocessor error") +INTERRUPT_HANDLER(0x05, "Bound Range Exception") +INTERRUPT_HANDLER(0x06, "Invalid Opcode") +INTERRUPT_HANDLER(0x07, "Device Not Available") +INTERRUPT_HANDLER(0x08, "Double Fault") +INTERRUPT_HANDLER(0x09, "Coprocessor Segment Overrun") +INTERRUPT_HANDLER(0x0A, "Invalid TSS") +INTERRUPT_HANDLER(0x0B, "Segment Not Present") +INTERRUPT_HANDLER(0x0C, "Stack-Segment Fault") +INTERRUPT_HANDLER(0x0D, "Stack-Segment Fault") +INTERRUPT_HANDLER(0x0E, "Page Fault") +INTERRUPT_HANDLER(0x0F, "Unknown Exception 0x0F") +INTERRUPT_HANDLER(0x10, "x87 Floating-Point Exception") +INTERRUPT_HANDLER(0x11, "Alignment Check") +INTERRUPT_HANDLER(0x12, "Machine Check") +INTERRUPT_HANDLER(0x13, "SIMD Floating-Point Exception") +INTERRUPT_HANDLER(0x14, "Virtualization Exception") +INTERRUPT_HANDLER(0x15, "Control Protection Exception") +INTERRUPT_HANDLER(0x16, "Unknown Exception 0x16") +INTERRUPT_HANDLER(0x17, "Unknown Exception 0x17") +INTERRUPT_HANDLER(0x18, "Unknown Exception 0x18") +INTERRUPT_HANDLER(0x19, "Unknown Exception 0x19") +INTERRUPT_HANDLER(0x1A, "Unknown Exception 0x1A") +INTERRUPT_HANDLER(0x1B, "Unknown Exception 0x1B") +INTERRUPT_HANDLER(0x1C, "Hypervisor Injection Exception") +INTERRUPT_HANDLER(0x1D, "VMM Communication Exception") +INTERRUPT_HANDLER(0x1E, "Security Exception") +INTERRUPT_HANDLER(0x1F, "Unkown Exception 0x1F") + #define REGISTER_HANDLER(i) register_interrupt_handler(i, interrupt ## i) -void handle_irq() +extern "C" void handle_irq() { - uint16_t isr = PIC::get_isr(); - if (!isr) { - //kprint("Spurious IRQ\n"); - return; - } + uint32_t isr[8]; + APIC::GetISR(isr); - uint8_t irq = 0; - for (uint8_t i = 0; i < 16; ++i) { - if (i == 2) - continue; - if (isr & (1 << i)) { - irq = i; - break; - } - } + uint8_t irq = 0; + for (uint8_t i = 0; i < 8; i++) + { + for (uint8_t j = 0; j < 32; j++) + { + if (isr[i] & ((uint32_t)1 << j)) + { + irq = 32 * i + j; + goto found; + } + } + } + +found: + if (irq == 0) + { + dprintln("Spurious irq"); + return; + } if (s_irq_handlers[irq]) s_irq_handlers[irq](); else - kprint("no handler for irq {}\n", irq); + Kernel::panic("no handler for irq 0x{2H}\n", irq); - PIC::eoi(irq); + APIC::EOI(); } +extern "C" void handle_irq_common(); +asm( +".globl handle_irq_common;" +"handle_irq_common:" + "pusha;" + "pushw %ds;" + "pushw %es;" + "pushw %ss;" + "pushw %ss;" + "popw %ds;" + "popw %es;" + "call handle_irq;" + "popw %es;" + "popw %ds;" + "popa;" + "iret;" +); + + namespace IDT { diff --git a/kernel/arch/i386/IDT_asm.S b/kernel/arch/i386/IDT_asm.S deleted file mode 100644 index 523f1bf5..00000000 --- a/kernel/arch/i386/IDT_asm.S +++ /dev/null @@ -1,15 +0,0 @@ -.globl handle_irq_common - -handle_irq_common: - pusha - pushw %ds - pushw %es - pushw %ss - pushw %ss - popw %ds - popw %es - call handle_irq - popw %es - popw %ds - popa - iret \ No newline at end of file diff --git a/kernel/arch/i386/make.config b/kernel/arch/i386/make.config index cb3b248a..a4013aae 100644 --- a/kernel/arch/i386/make.config +++ b/kernel/arch/i386/make.config @@ -8,9 +8,7 @@ $(ARCHDIR)/APIC.o \ $(ARCHDIR)/boot.o \ $(ARCHDIR)/CPUID.o \ $(ARCHDIR)/font.o \ -$(ARCHDIR)/GDT_asm.o \ $(ARCHDIR)/GDT.o \ -$(ARCHDIR)/IDT_asm.o \ $(ARCHDIR)/IDT.o \ $(ARCHDIR)/tty.o \ $(ARCHDIR)/VESA.o \