aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2021-02-22 09:59:58 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2021-02-22 09:59:58 +0200
commitfb9d73ff32de7c83552707622512be0ef1db241c (patch)
tree2187542a85c998c43952ecf39c8f9598ba8f6929
parentKconfig (diff)
downloadkernel.cpp-fb9d73ff32de7c83552707622512be0ef1db241c.tar.xz
Enable interrupts
-rw-r--r--drivers/ports.h4
-rw-r--r--libk/makefile3
-rw-r--r--libk/stdlib/abort.cc15
-rw-r--r--libk/stdlib/console.cc12
-rw-r--r--makefile2
-rw-r--r--src/idt.cc49
-rw-r--r--src/idt.h9
-rw-r--r--src/kernel.cc21
8 files changed, 79 insertions, 36 deletions
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*> Console::begin() {
return Iterator<Console*>(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 <uint8_t irq>
+__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<unsigned long>(t_irq<0x0>), 0x08, InterruptGate);
+ table[0x21] = Entry(reinterpret_cast<unsigned long>(t_irq<0x1>), 0x08, InterruptGate);
+ table[0x22] = Entry(reinterpret_cast<unsigned long>(t_irq<0x2>), 0x08, InterruptGate);
+ table[0x23] = Entry(reinterpret_cast<unsigned long>(t_irq<0x3>), 0x08, InterruptGate);
+ table[0x24] = Entry(reinterpret_cast<unsigned long>(t_irq<0x4>), 0x08, InterruptGate);
+ table[0x25] = Entry(reinterpret_cast<unsigned long>(t_irq<0x5>), 0x08, InterruptGate);
+ table[0x26] = Entry(reinterpret_cast<unsigned long>(t_irq<0x6>), 0x08, InterruptGate);
+ table[0x27] = Entry(reinterpret_cast<unsigned long>(t_irq<0x7>), 0x08, InterruptGate);
+ table[0x28] = Entry(reinterpret_cast<unsigned long>(t_irq<0x8>), 0x08, InterruptGate);
+ table[0x29] = Entry(reinterpret_cast<unsigned long>(t_irq<0x9>), 0x08, InterruptGate);
+ table[0x2a] = Entry(reinterpret_cast<unsigned long>(t_irq<0xa>), 0x08, InterruptGate);
+ table[0x2b] = Entry(reinterpret_cast<unsigned long>(t_irq<0xb>), 0x08, InterruptGate);
+ table[0x2c] = Entry(reinterpret_cast<unsigned long>(t_irq<0xc>), 0x08, InterruptGate);
+ table[0x2d] = Entry(reinterpret_cast<unsigned long>(t_irq<0xd>), 0x08, InterruptGate);
+ table[0x2e] = Entry(reinterpret_cast<unsigned long>(t_irq<0xe>), 0x08, InterruptGate);
- Pointer ptr{.limit = sizeof(table), .base = (uint32_t)table};
+ Pointer ptr{.limit = sizeof(table), .base = reinterpret_cast<uint32_t>(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"