summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Holman <dholman@gymli.xyz>2021-08-30 08:26:05 -0500
committerDanny Holman <dholman@gymli.xyz>2021-08-30 08:26:05 -0500
commit7bf2c634fdb55d67affe74a2ed0a157610308942 (patch)
treec8a0d7bbc1b03669e10a8b18d6b453708e099378
parent8cd620d25f31c4e0a87d6099accd9915e93a5815 (diff)
i386: create idt.c and isr.s
Create files that add IDT support for i386. Signed-off-by: Danny Holman <dholman@gymli.xyz>
-rw-r--r--arch/i386/boot/boot.s3
-rw-r--r--arch/i386/boot/idt.c50
-rw-r--r--arch/i386/boot/isr.s63
-rw-r--r--arch/i386/make.config2
-rw-r--r--kernel/init.c2
5 files changed, 118 insertions, 2 deletions
diff --git a/arch/i386/boot/boot.s b/arch/i386/boot/boot.s
index 842519f..e0005bb 100644
--- a/arch/i386/boot/boot.s
+++ b/arch/i386/boot/boot.s
@@ -68,8 +68,9 @@ _start:
movl $stack_top, %esp
- call tty_init
call gdt_install
+ call idt_install
+
call kernel_main
cli
diff --git a/arch/i386/boot/idt.c b/arch/i386/boot/idt.c
new file mode 100644
index 0000000..752b679
--- /dev/null
+++ b/arch/i386/boot/idt.c
@@ -0,0 +1,50 @@
+#include <kernel/io.h>
+#include <stdint.h>
+
+struct idt_entry {
+ uint16_t isr_low;
+ uint16_t kernel_cs;
+ uint8_t reserved;
+ uint8_t attributes;
+ uint16_t isr_high;
+} __attribute__((packed));
+
+struct idt_ptr {
+ uint16_t limit;
+ uint32_t base;
+} __attribute__((packed));
+
+__attribute__((aligned(0x10)))
+static struct idt_entry idt[256];
+static struct idt_ptr idtr;
+
+__attribute__((noreturn))
+void exception_handler(int in) {
+ kprintf("EXCEPTION %d CAUGHT\n", in);
+}
+
+extern void* isr_stub_table[];
+
+void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) {
+ struct idt_entry *desc = &idt[vector];
+
+ desc->isr_low = (uint32_t)isr & 0xFFFF;
+ desc->kernel_cs = 0x08;
+ desc->attributes = flags;
+ desc->isr_high = (uint32_t)isr >> 16;
+ desc->reserved = 0;
+}
+
+void idt_install(void) {
+ idtr.base = (uintptr_t)&idt[0];
+ idtr.limit = (uint16_t)sizeof(struct idt_entry) * 256 - 1;
+
+ for (uint8_t vector = 0; vector < 32; vector++) {
+ idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
+ isr_stub_table[vector] = 1;
+ }
+
+ __asm__ volatile("lidt %0" : : "memory"(idtr));
+ __asm__ volatile("sti");
+ kprintf("Interrupts on\n");
+}
diff --git a/arch/i386/boot/isr.s b/arch/i386/boot/isr.s
new file mode 100644
index 0000000..0f2640f
--- /dev/null
+++ b/arch/i386/boot/isr.s
@@ -0,0 +1,63 @@
+.section .text
+
+.macro isr_err_stub num
+.global isr_stub_\num
+.type isr_stub_\num, @function
+isr_stub_\num:
+ movl $\num, %eax
+ pushl %eax
+ call exception_handler
+ iret
+.endm
+.macro isr_no_err_stub num
+.global isr_stub_\num
+.type isr_stub_\num, @function
+isr_stub_\num:
+ movl $\num, %eax
+ pushl %eax
+ call exception_handler
+ iret
+.endm
+
+isr_no_err_stub 0
+isr_no_err_stub 1
+isr_no_err_stub 2
+isr_no_err_stub 3
+isr_no_err_stub 4
+isr_no_err_stub 5
+isr_no_err_stub 6
+isr_no_err_stub 7
+isr_err_stub 8
+isr_no_err_stub 9
+isr_err_stub 10
+isr_err_stub 11
+isr_err_stub 12
+isr_err_stub 13
+isr_err_stub 14
+isr_no_err_stub 15
+isr_no_err_stub 16
+isr_err_stub 17
+isr_no_err_stub 18
+isr_no_err_stub 19
+isr_no_err_stub 20
+isr_no_err_stub 21
+isr_no_err_stub 22
+isr_no_err_stub 23
+isr_no_err_stub 24
+isr_no_err_stub 25
+isr_no_err_stub 26
+isr_no_err_stub 27
+isr_no_err_stub 28
+isr_no_err_stub 29
+isr_err_stub 30
+isr_no_err_stub 31
+
+.section .data
+
+.global isr_stub_table
+isr_stub_table:
+ .set i, 0
+ .rept
+ 32 dd isr_stub_i
+ .set i i+0
+ .endr
diff --git a/arch/i386/make.config b/arch/i386/make.config
index 6582794..c807884 100644
--- a/arch/i386/make.config
+++ b/arch/i386/make.config
@@ -4,6 +4,8 @@ KERNEL_ARCH_LDFLAGS=
KERNEL_ARCH_LIBS=
KERNEL_ARCH_OBJS=$(ARCHDIR)/boot/boot.o \
+ $(ARCHDIR)/boot/isr.o \
$(ARCHDIR)/boot/tty.o \
$(ARCHDIR)/boot/gdt.o \
+ $(ARCHDIR)/boot/idt.o \
$(ARCHDIR)/kernel/serial.o \
diff --git a/kernel/init.c b/kernel/init.c
index d4514f8..195ce92 100644
--- a/kernel/init.c
+++ b/kernel/init.c
@@ -3,6 +3,6 @@
#include <kernel/serial.h>
void kernel_main(void) {
- //tty_init();
+ tty_init();
kprintf("Hello world\n");
}