From fb9d73ff32de7c83552707622512be0ef1db241c Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Mon, 22 Feb 2021 09:59:58 +0200 Subject: Enable interrupts --- drivers/ports.h | 4 +++- libk/makefile | 3 ++- libk/stdlib/abort.cc | 15 +++++++++++++++ libk/stdlib/console.cc | 12 ------------ makefile | 2 +- src/idt.cc | 49 +++++++++++++++++++++++++++++++++++++++++-------- src/idt.h | 9 ++++++--- src/kernel.cc | 21 +++++++++++---------- 8 files changed, 79 insertions(+), 36 deletions(-) create mode 100644 libk/stdlib/abort.cc diff --git a/drivers/ports.h b/drivers/ports.h index 98cac72..f241299 100644 --- a/drivers/ports.h +++ b/drivers/ports.h @@ -56,4 +56,6 @@ typedef Port<0x2e8, uint8_t> com4_port_t; /* 8259 PIC */ typedef Port<0x20, uint8_t> pic1_t; -typedef Port<0xA0, uint8_t> pic2_t; +typedef Port<0xa0, uint8_t> pic2_t; + +typedef Port<0x60, uint8_t> kb_t; diff --git a/libk/makefile b/libk/makefile index 0f75e5a..966caae 100644 --- a/libk/makefile +++ b/libk/makefile @@ -1,3 +1,4 @@ -CXX_OBJ += libk/string/string.o libk/string/integerview.o libk/stdlib/console.o +CXX_OBJ += libk/string/string.o libk/string/integerview.o \ + libk/stdlib/abort.o libk/stdlib/console.o CXX_TEST_OBJ += libk/types/test.o libk/string/test.o diff --git a/libk/stdlib/abort.cc b/libk/stdlib/abort.cc new file mode 100644 index 0000000..56ca7ee --- /dev/null +++ b/libk/stdlib/abort.cc @@ -0,0 +1,15 @@ +#include "stdlib.h" + +void abort() { + /* + * On gcc, a 'while(true) {}' will infinitely loop + * but clang will optimize it away on -O2 if it's empty + * therefore, add no-op + */ + + asm volatile("cli"); + while (true) { + asm volatile("hlt"); + } + __builtin_unreachable(); +} diff --git a/libk/stdlib/console.cc b/libk/stdlib/console.cc index a234e6b..c076297 100644 --- a/libk/stdlib/console.cc +++ b/libk/stdlib/console.cc @@ -13,15 +13,3 @@ void Console::set(Console* ptr) { Iterator Console::begin() { return Iterator(global_console, last_console); } - -void abort() { - /* - * On gcc, a 'while(true) {}' will infinitely loop - * but clang will optimize it away on -O2 if it's empty - * therefore, add no-op - */ - while (true) { - asm volatile("nop"); - } - __builtin_unreachable(); -} diff --git a/makefile b/makefile index bbd42a4..f570a4f 100644 --- a/makefile +++ b/makefile @@ -32,7 +32,7 @@ $(CXX_OBJ) $(CXX_TEST_OBJ): $(OBJ_DIR)/%.o : %.cc @$(CXX) -target $(TARGET) $(CXX_FLAGS) $(CXX_INCLUDE) $(CXX_SYSTEM_INCLUDE) -MMD -c $< -o $@ clean: - @rm -rf $(AS_OBJ) $(CXX_OBJ) $(CXX_DEP) $(CXX_TEST_OBJ) glitch.elf isodir + @rm -rf $(autogen) $(AS_OBJ) $(CXX_OBJ) $(CXX_DEP) $(CXX_TEST_OBJ) glitch.elf isodir # testing test: $(CXX_TEST_OBJ) 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