From fb9d73ff32de7c83552707622512be0ef1db241c Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Mon, 22 Feb 2021 09:59:58 +0200 Subject: Enable interrupts --- src/idt.cc | 49 +++++++++++++++++++++++++++++++++++++++++-------- src/idt.h | 9 ++++++--- src/kernel.cc | 21 +++++++++++---------- 3 files changed, 58 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/idt.cc b/src/idt.cc index fe4c159..e4c21b7 100644 --- a/src/idt.cc +++ b/src/idt.cc @@ -22,12 +22,29 @@ static_assert(sizeof(IDT::Entry) == 8); #define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ #define ICW4_SFNM 0x10 /* Special fully nested (not) */ +template +__attribute__((interrupt)) void t_irq(interrupt_frame*) { + static_assert(irq <= 15); + + com1_port_t com1; + com1.write("0123456789abcdef"[irq]); + com1.write('\n'); + com1.write('\r'); + + pic1_t pic1; + pic1.write(0x20); + if constexpr (irq > 7) { + pic2_t pic2; + pic2.write(0x20); + } +}; + IDT::IDT() { pic1_t pic1; pic2_t pic2; - const auto mask1 = pic1.read(0x1); - const auto mask2 = pic2.read(0x1); + // const auto mask1 = pic1.read(0x1); + // const auto mask2 = pic2.read(0x1); pic1.write(ICW1_INIT | ICW1_ICW4); pic2.write(ICW1_INIT | ICW1_ICW4); @@ -38,14 +55,30 @@ IDT::IDT() { pic1.write(ICW4_8086, 0x1); pic2.write(ICW4_8086, 0x1); - pic1.write(mask1); - pic2.write(mask2); + // pic1.write(mask1); + // pic2.write(mask2); + pic1.write(0xfd, 0x1); // only enable irq1 + pic2.write(0xff, 0x1); - table[32] = Entry((unsigned long)kirq<0x0>, 0x08, InterruptGate); - table[33] = Entry((unsigned long)kirq<0x1>, 0x08, InterruptGate); + table[0x20] = Entry(reinterpret_cast(t_irq<0x0>), 0x08, InterruptGate); + table[0x21] = Entry(reinterpret_cast(t_irq<0x1>), 0x08, InterruptGate); + table[0x22] = Entry(reinterpret_cast(t_irq<0x2>), 0x08, InterruptGate); + table[0x23] = Entry(reinterpret_cast(t_irq<0x3>), 0x08, InterruptGate); + table[0x24] = Entry(reinterpret_cast(t_irq<0x4>), 0x08, InterruptGate); + table[0x25] = Entry(reinterpret_cast(t_irq<0x5>), 0x08, InterruptGate); + table[0x26] = Entry(reinterpret_cast(t_irq<0x6>), 0x08, InterruptGate); + table[0x27] = Entry(reinterpret_cast(t_irq<0x7>), 0x08, InterruptGate); + table[0x28] = Entry(reinterpret_cast(t_irq<0x8>), 0x08, InterruptGate); + table[0x29] = Entry(reinterpret_cast(t_irq<0x9>), 0x08, InterruptGate); + table[0x2a] = Entry(reinterpret_cast(t_irq<0xa>), 0x08, InterruptGate); + table[0x2b] = Entry(reinterpret_cast(t_irq<0xb>), 0x08, InterruptGate); + table[0x2c] = Entry(reinterpret_cast(t_irq<0xc>), 0x08, InterruptGate); + table[0x2d] = Entry(reinterpret_cast(t_irq<0xd>), 0x08, InterruptGate); + table[0x2e] = Entry(reinterpret_cast(t_irq<0xe>), 0x08, InterruptGate); - Pointer ptr{.limit = sizeof(table), .base = (uint32_t)table}; + Pointer ptr{.limit = sizeof(table), .base = reinterpret_cast(table)}; asm volatile("lidt %0" : : "m"(ptr)); + asm volatile("sti"); - printk("IDT installed at ", (uint32_t)table, '\n'); + printk("IDT installed at ", uhex{ptr.base}, '\n'); } diff --git a/src/idt.h b/src/idt.h index 3aa5a1e..628eb23 100644 --- a/src/idt.h +++ b/src/idt.h @@ -18,11 +18,14 @@ public: class Entry { public: - Entry(uint32_t offset = 0, uint16_t select = 0, InterruptType t = Null) { + constexpr Entry(uint32_t offset = 0, uint16_t select = 0, InterruptType t = Null) { offset_0_15 = offset & 0xffff; offset_16_31 = (offset & 0xffff0000) >> 16; selector = select; type = t; + if (offset != 0) { + e = true; + } } private: @@ -32,8 +35,8 @@ public: InterruptType type : 3; // 40-42 type [[maybe_unused]] bool d : 1 = true; // 43 true: 32-bit, false: 16-bit segment [[maybe_unused]] uint8_t u : 1 = 0; // 44 unused - uint8_t dpl : 2 = 0; // 45-46 descriptor privilege level - [[maybe_unused]] bool e : 1 = true; // 47 enable + [[maybe_unused]] uint8_t dpl : 2 = 0; // 45-46 descriptor privilege level + [[maybe_unused]] bool e : 1 = false; // 47 enable uint16_t offset_16_31; // 48-63 offset high } __attribute__((packed)); diff --git a/src/kernel.cc b/src/kernel.cc index ff95d16..4337edb 100644 --- a/src/kernel.cc +++ b/src/kernel.cc @@ -32,28 +32,29 @@ void dump_gdt(); void kernel_main([[maybe_unused]] uint32_t mb_magic, [[maybe_unused]] uint32_t mb_addr) { #ifdef HAS_SERIAL0 - if (serial0.self_check()) Console::set(&serial0); + if constexpr (serial0_console) + if (serial0.self_check()) Console::set(&serial0); #endif #ifdef HAS_VIDEO0 - Console::set(&video0); + if constexpr (video0_console) Console::set(&video0); #endif - printk("Hello, kernel World!\n"); + // printk("Hello, kernel World!\n"); - dump_multiboot(mb_magic, mb_addr); - dump_gdt(); + // dump_multiboot(mb_magic, mb_addr); + // dump_gdt(); - printk("GDT::SegmentDescriptor tests\n"); + // printk("GDT::SegmentDescriptor tests\n"); auto x = GDT::SegmentDescriptor::make<0xffff>(0xdeadbeef, {}); - printk("x.base(): ", uhex{x.base()}, '\n'); + // printk("x.base(): ", uhex{x.base()}, '\n'); - printk("Setting new GDT\n"); + // printk("Setting new GDT\n"); GDT gdt; - dump_gdt(); + // dump_gdt(); IDT idt; - // abort(); + while (true) asm volatile("hlt"); } } // extern "C" -- cgit v1.2.1