summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/SConscript2
-rw-r--r--kernel/idt.c122
-rw-r--r--kernel/panic.c41
-rw-r--r--kernel/panic.h31
4 files changed, 160 insertions, 36 deletions
diff --git a/kernel/SConscript b/kernel/SConscript
index 8c17467..8b0ad5c 100644
--- a/kernel/SConscript
+++ b/kernel/SConscript
@@ -27,4 +27,4 @@ kernel_bld = Builder(
env.Append(BUILDERS = {'Kernel' : kernel_bld})
-kernel = env.Kernel('kernel', ['kernel.ld', 'entry.c', 'main.c', 'printf.c', 'gdt.c', 'idt.c'])
+kernel = env.Kernel('kernel', ['kernel.ld', 'entry.c', 'main.c', 'printf.c', 'gdt.c', 'idt.c', 'panic.c'])
diff --git a/kernel/idt.c b/kernel/idt.c
index 3fdc3dc..5633c61 100644
--- a/kernel/idt.c
+++ b/kernel/idt.c
@@ -1,40 +1,5 @@
#include "idt.h"
-#define outb(port, value) asm volatile("out %b0,%w1" : : "a" (value), "d" (port));
-
-#define isr_panic(num) void isr_ ## num(); \
-asm( \
- ".globl isr_" #num "\n" \
- "isr_" #num ":\n" \
- "push $" #num "\n" \
- "call panic\n" \
- "iret\n" \
-)
-
-char* panic_msg[] = {
- [0] = "Divide error.",
- [8] = "Double fault.",
- [14] = "Page fault."
-};
-
-isr_panic(0);
-isr_panic(8);
-isr_panic(14);
-
-void panic(uint32_t num) {
- char* str = panic_msg[num];
- while(*str) {
- outb(0x3f8, *str++);
- }
- outb(0x3f8, '\r');
- outb(0x3f8, '\n');
- asm volatile(
- "cli\n"
- "hlt\n"
- );
- while(1);
-}
-
idt_entry idt[] = {
{.base_low = 1}, // Keep IDT in .data.
[1 ... 255] = idt_entry_null
@@ -52,10 +17,97 @@ void idt_set_gate(uint8_t num, uint32_t base, uint16_t segment, uint16_t flags)
idt[num].flags = flags;
}
+#define isr_panic(num) void isr_ ## num(); \
+asm( \
+ ".globl isr_" #num "\n" \
+ "isr_" #num ":\n" \
+ "push $0\n" \
+ "push $" #num "\n" \
+ "pusha\n" \
+ "push %ds\n" \
+ "push %ss\n" \
+ "call panic\n" \
+)
+
+#define isr_panic_e(num) void isr_ ## num(); \
+asm( \
+ ".globl isr_" #num "\n" \
+ "isr_" #num ":\n" \
+ "push $" #num "\n" \
+ "pusha\n" \
+ "push %ds\n" \
+ "push %ss\n" \
+ "call panic\n" \
+)
+
+isr_panic(0);
+isr_panic(1);
+isr_panic(2);
+isr_panic(3);
+isr_panic(4);
+isr_panic(5);
+isr_panic(6);
+isr_panic(7);
+isr_panic_e(8);
+isr_panic(9);
+isr_panic_e(10);
+isr_panic_e(11);
+isr_panic_e(12);
+isr_panic_e(13);
+isr_panic_e(14);
+isr_panic(15);
+isr_panic(16);
+isr_panic_e(17);
+isr_panic(18);
+isr_panic(19);
+isr_panic(20);
+isr_panic(21);
+isr_panic(22);
+isr_panic(23);
+isr_panic(24);
+isr_panic(25);
+isr_panic(26);
+isr_panic(27);
+isr_panic(28);
+isr_panic(29);
+isr_panic(30);
+isr_panic(31);
+
+
void idt_init() {
idt_set_gate(0, (uint32_t)isr_0, 0x08, 0x8e00);
+ idt_set_gate(1, (uint32_t)isr_1, 0x08, 0x8e00);
+ idt_set_gate(2, (uint32_t)isr_2, 0x08, 0x8e00);
+ idt_set_gate(3, (uint32_t)isr_3, 0x08, 0x8e00);
+ idt_set_gate(4, (uint32_t)isr_4, 0x08, 0x8e00);
+ idt_set_gate(5, (uint32_t)isr_5, 0x08, 0x8e00);
+ idt_set_gate(6, (uint32_t)isr_6, 0x08, 0x8e00);
+ idt_set_gate(7, (uint32_t)isr_7, 0x08, 0x8e00);
idt_set_gate(8, (uint32_t)isr_8, 0x08, 0x8e00);
+ idt_set_gate(9, (uint32_t)isr_9, 0x08, 0x8e00);
+ idt_set_gate(10, (uint32_t)isr_10, 0x08, 0x8e00);
+ idt_set_gate(11, (uint32_t)isr_11, 0x08, 0x8e00);
+ idt_set_gate(12, (uint32_t)isr_12, 0x08, 0x8e00);
+ idt_set_gate(13, (uint32_t)isr_13, 0x08, 0x8e00);
idt_set_gate(14, (uint32_t)isr_14, 0x08, 0x8e00);
+ idt_set_gate(15, (uint32_t)isr_15, 0x08, 0x8e00);
+ idt_set_gate(16, (uint32_t)isr_16, 0x08, 0x8e00);
+ idt_set_gate(17, (uint32_t)isr_17, 0x08, 0x8e00);
+ idt_set_gate(18, (uint32_t)isr_18, 0x08, 0x8e00);
+ idt_set_gate(19, (uint32_t)isr_19, 0x08, 0x8e00);
+ idt_set_gate(10, (uint32_t)isr_20, 0x08, 0x8e00);
+ idt_set_gate(21, (uint32_t)isr_21, 0x08, 0x8e00);
+ idt_set_gate(22, (uint32_t)isr_22, 0x08, 0x8e00);
+ idt_set_gate(23, (uint32_t)isr_23, 0x08, 0x8e00);
+ idt_set_gate(24, (uint32_t)isr_24, 0x08, 0x8e00);
+ idt_set_gate(25, (uint32_t)isr_25, 0x08, 0x8e00);
+ idt_set_gate(26, (uint32_t)isr_26, 0x08, 0x8e00);
+ idt_set_gate(27, (uint32_t)isr_27, 0x08, 0x8e00);
+ idt_set_gate(28, (uint32_t)isr_28, 0x08, 0x8e00);
+ idt_set_gate(29, (uint32_t)isr_29, 0x08, 0x8e00);
+ idt_set_gate(30, (uint32_t)isr_30, 0x08, 0x8e00);
+ idt_set_gate(31, (uint32_t)isr_31, 0x08, 0x8e00);
+
asm volatile(
"lidt (%0)\n"
: : "r" (&idtr)
diff --git a/kernel/panic.c b/kernel/panic.c
new file mode 100644
index 0000000..bdd4e93
--- /dev/null
+++ b/kernel/panic.c
@@ -0,0 +1,41 @@
+#include "panic.h"
+#include "printf.h"
+
+char* panic_msg[] = {
+ "#DE - Divide error.",
+ "#DB",
+ "#2",
+ "#BP",
+ "#OF",
+ "#BR",
+ "#UD - Invalid opcode.",
+ "#NM",
+ "#DF - Double fault.",
+ "#9",
+ "#TS",
+ "#NP",
+ "#SS",
+ "#GP - General protection fault.",
+ "#PF - Page fault.",
+ "#15",
+ "#MF",
+ "#AC",
+ "#MC",
+ "#XM",
+ [20 ... 31] = "Undefined exception."
+};
+
+void panic(panic_stack_t stack) {
+ printf("Kernel panic: %s\n", panic_msg[stack.num]);
+ printf("INT: %8u EC: %08x\n", stack.num, stack.error_code);
+ printf(" CS: %04x DS: %04x SS: %04x\n", stack.cs, stack.ds, stack.ss);
+ printf("EIP: %08x EFLAGS: %08x\n", stack.eip, stack.eflags);
+ printf("EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n", stack.eax, stack.ebx, stack.ecx, stack.edx);
+ printf("ESP: %08x EBP: %08x ESI: %08x EDI: %08x\n", stack.esp, stack.ebp, stack.esi, stack.edi);
+
+ asm volatile(
+ "cli\n"
+ "hlt\n"
+ );
+ while(1);
+}
diff --git a/kernel/panic.h b/kernel/panic.h
new file mode 100644
index 0000000..6ed723a
--- /dev/null
+++ b/kernel/panic.h
@@ -0,0 +1,31 @@
+#ifndef PANIC_H
+#define PANIC_H
+
+#include "types.h"
+
+typedef struct {
+ uint32_t ss;
+ uint32_t ds;
+
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t ebx;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t eax;
+
+ uint32_t num;
+ uint32_t error_code;
+
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t user_esp;
+ uint32_t user_ss;
+} panic_stack_t;
+
+void panic(panic_stack_t stack);
+
+#endif