BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / d46e09a34ca8cd546f3a4312976cf3b6a5a55ccf / kernel

// Related

Nucleus

Barry Improved context switching and interrupt handling d46e09a (3 years, 2 months ago)
diff --git a/kernel/idt.c b/kernel/idt.c
index d835d15..a9f7c79 100644
--- a/kernel/idt.c
+++ b/kernel/idt.c
@@ -21,7 +21,7 @@ static struct IDTEntry {
 	uint16_t offsetHigher;
 } __attribute__((packed)) *IDT;
 
-void (**exceptions)(struct InterruptFrame *, uint32_t);
+void (**exceptions)(struct InterruptFrame *);
 void (**interrupts)(struct InterruptFrame *);
 
 /* Install an IDT Entry */
@@ -35,294 +35,57 @@ install_idt_entry(uint8_t num, void *addr)
 	IDT[num].offsetHigher = (uintptr_t) addr >> 16;
 }
 
-/* First level generic exception handler */
-static void
-exc_handler(int num, struct InterruptFrame *frame, uint32_t err)
-{
-	asm volatile("cli");
-
-	if (!exceptions[num]) {
-		panic("Failed to handle exception %d (%#.8x)",
-		      num, err);
-	}
-
-	ASSERT(exceptions[num]);
-	exceptions[num](frame, err);
-
-	/* Send APIC EOI */
-	if (apic)
-		LAPIC(0xB0) = 0;
-
-	asm volatile("sti");
-}
-
-/* First level generic interrupt handler */
-static void
-int_handler(int num, struct InterruptFrame *frame)
+/* Generic ISR handler */
+void
+isr_handler(struct InterruptFrame frame)
 {
-	asm volatile("cli");
+	if (!exceptions[frame.intnum] && frame.intnum < 32)
+		panic("[CPU#%d] Failed to handle exception %d (%#.8x) @ %#.8x",
+		      CPUID, frame.intnum, frame.err, frame.eip);
 
-	if (interrupts[num - 32])
-		interrupts[num - 32](frame);
+	/* Run registered handler */
+	if (exceptions[frame.intnum])
+		exceptions[frame.intnum](&frame);
 
 	/* Send EOI */
-	if (num >= 32 + 8)
+	if (frame.intnum >= 40 && frame.intnum < 48)
 		outb(0xA0, 0x20);
-	outb(0x20, 0x20);
-	/* Send APIC EOI*/
-	if (apic)
-		LAPIC(0xB0) = 0;
-
-	asm volatile("sti");
-}
-
-/* Exceptions */
-__attribute__((interrupt))
-static void
-exc0(struct InterruptFrame *frame)
-{
-	exc_handler(0, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc1(struct InterruptFrame *frame)
-{
-	exc_handler(1, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc2(struct InterruptFrame *frame)
-{
-	exc_handler(2, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc3(struct InterruptFrame *frame)
-{
-	exc_handler(3, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc4(struct InterruptFrame *frame)
-{
-	exc_handler(4, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc5(struct InterruptFrame *frame)
-{
-	exc_handler(5, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc6(struct InterruptFrame *frame)
-{
-	exc_handler(6, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc7(struct InterruptFrame *frame)
-{
-	exc_handler(7, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc8(struct InterruptFrame *frame, uint32_t err)
-{
-	exc_handler(8, frame, err);
-}
-__attribute__((interrupt))
-static void
-exc9(struct InterruptFrame *frame)
-{
-	exc_handler(9, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc10(struct InterruptFrame *frame, uint32_t err)
-{
-	exc_handler(10, frame, err);
-}
-__attribute__((interrupt))
-static void
-exc11(struct InterruptFrame *frame, uint32_t err)
-{
-	exc_handler(11, frame, err);
-}
-__attribute__((interrupt))
-static void
-exc12(struct InterruptFrame *frame, uint32_t err)
-{
-	exc_handler(12, frame, err);
-}
-__attribute__((interrupt))
-static void
-exc13(struct InterruptFrame *frame, uint32_t err)
-{
-	exc_handler(13, frame, err);
-}
-__attribute__((interrupt))
-static void
-exc14(struct InterruptFrame *frame, uint32_t err)
-{
-	exc_handler(14, frame, err);
-}
-__attribute__((interrupt))
-static void
-exc15(struct InterruptFrame *frame)
-{
-	exc_handler(15, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc16(struct InterruptFrame *frame)
-{
-	exc_handler(16, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc17(struct InterruptFrame *frame, uint32_t err)
-{
-	exc_handler(17, frame, err);
-}
-__attribute__((interrupt))
-static void
-exc18(struct InterruptFrame *frame)
-{
-	exc_handler(18, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc19(struct InterruptFrame *frame)
-{
-	exc_handler(19, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc20(struct InterruptFrame *frame)
-{
-	exc_handler(20, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc30(struct InterruptFrame *frame)
-{
-	exc_handler(30, frame, 0);
-}
-__attribute__((interrupt))
-static void
-exc128(struct InterruptFrame *frame)
-{
-	uintptr_t esi, *eax;
-	asm volatile(
-		"mov %%esi, %0;"
-		"lea -12(%%ebp), %1;"
-		: "=r" (esi), "=r" (eax));
-	*eax = syscall_handler(*eax, esi);
+	if (frame.intnum >= 32 && frame.intnum < 48)
+		outb(0x20, 0x20);
 
 	/* Send APIC EOI */
 	if (apic)
 		LAPIC(0xB0) = 0;
 }
 
-/* Interrupts */
-__attribute__((interrupt))
-static void
-int0(struct InterruptFrame *frame)
-{
-	int_handler(32, frame);
-}
-__attribute__((interrupt))
-static void
-int1(struct InterruptFrame *frame)
-{
-	int_handler(33, frame);
-}
-__attribute__((interrupt))
-static void
-int2(struct InterruptFrame *frame)
-{
-	int_handler(34, frame);
-}
-__attribute__((interrupt))
-static void
-int3(struct InterruptFrame *frame)
-{
-	int_handler(35, frame);
-}
-__attribute__((interrupt))
-static void
-int4(struct InterruptFrame *frame)
-{
-	int_handler(36, frame);
-}
-__attribute__((interrupt))
-static void
-int5(struct InterruptFrame *frame)
-{
-	int_handler(37, frame);
-}
-__attribute__((interrupt))
-static void
-int6(struct InterruptFrame *frame)
-{
-	int_handler(38, frame);
-}
-__attribute__((interrupt))
-static void
-int7(struct InterruptFrame *frame)
-{
-	int_handler(39, frame);
-}
-__attribute__((interrupt))
-static void
-int8(struct InterruptFrame *frame)
-{
-	int_handler(40, frame);
-}
-__attribute__((interrupt))
-static void
-int9(struct InterruptFrame *frame)
-{
-	int_handler(41, frame);
-}
-__attribute__((interrupt))
-static void
-int10(struct InterruptFrame *frame)
-{
-	int_handler(42, frame);
-}
-__attribute__((interrupt))
-static void
-int11(struct InterruptFrame *frame)
-{
-	int_handler(43, frame);
-}
-__attribute__((interrupt))
-static void
-int12(struct InterruptFrame *frame)
-{
-	int_handler(44, frame);
-}
-__attribute__((interrupt))
-static void
-int13(struct InterruptFrame *frame)
-{
-	int_handler(45, frame);
-}
-__attribute__((interrupt))
-static void
-int14(struct InterruptFrame *frame)
+/* Register an exception handler */
+void
+register_exception(int num, exc_handler_t addr)
 {
-	int_handler(46, frame);
+	if ((num >= 0 && num < 32) || num >= 48)
+		exceptions[num] = addr;
 }
-__attribute__((interrupt))
-static void
-int15(struct InterruptFrame *frame)
+
+/* Register an interrupt handler */
+void
+register_interrupt(int num, int_handler_t addr)
 {
-	int_handler(47, frame);
+	if (num >= 0 && num < 16)
+		interrupts[num] = addr;
 }
 
+/* Exceptions */
+extern char exc0[],  exc1[],  exc2[],  exc3[],  exc4[],  exc5[],  exc6[],
+            exc7[],  exc8[],  exc9[],  exc10[], exc11[], exc12[], exc13[],
+            exc14[], exc15[], exc16[], exc17[], exc18[], exc19[], exc20[],
+            exc30[];
+/* Interrutps */
+extern char exc32[], exc33[], exc34[], exc35[], exc36[], exc37[], exc38[],
+            exc39[], exc40[], exc41[], exc42[], exc43[], exc44[], exc45[],
+            exc46[], exc47[];
+/* System Call */
+extern char exc128[];
+
 /* Initialise the IDT */
 void
 init_idt(void)
@@ -354,22 +117,22 @@ init_idt(void)
 	install_idt_entry(30, exc30);
 
 	/* Install interrupts */
-	install_idt_entry(32, int0);
-	install_idt_entry(33, int1);
-	install_idt_entry(34, int2);
-	install_idt_entry(35, int3);
-	install_idt_entry(36, int4);
-	install_idt_entry(37, int5);
-	install_idt_entry(38, int6);
-	install_idt_entry(39, int7);
-	install_idt_entry(40, int8);
-	install_idt_entry(41, int9);
-	install_idt_entry(42, int10);
-	install_idt_entry(43, int11);
-	install_idt_entry(44, int12);
-	install_idt_entry(45, int13);
-	install_idt_entry(46, int14);
-	install_idt_entry(47, int15);
+	install_idt_entry(32, exc32);
+	install_idt_entry(33, exc33);
+	install_idt_entry(34, exc34);
+	install_idt_entry(35, exc35);
+	install_idt_entry(36, exc36);
+	install_idt_entry(37, exc37);
+	install_idt_entry(38, exc38);
+	install_idt_entry(39, exc39);
+	install_idt_entry(40, exc40);
+	install_idt_entry(41, exc41);
+	install_idt_entry(42, exc42);
+	install_idt_entry(43, exc43);
+	install_idt_entry(44, exc44);
+	install_idt_entry(45, exc45);
+	install_idt_entry(46, exc46);
+	install_idt_entry(47, exc47);
 
 	/* Install system call handler */
 	install_idt_entry(128, exc128);
@@ -389,19 +152,3 @@ cpu_load_idt(void)
 	};
 	asm volatile("lidt %0" :: "m" (ptr));
 }
-
-/* Register an exception handler */
-void
-register_exception(int num, exc_handler_t addr)
-{
-	if (num >= 0 && num < 32)
-		exceptions[num] = addr;
-}
-
-/* Register an interrupt handler */
-void
-register_interrupt(int num, int_handler_t addr)
-{
-	if (num >= 0 && num < 224)
-		interrupts[num] = addr;
-}
diff --git a/kernel/isr.S b/kernel/isr.S
new file mode 100644
index 0000000..c807e7b
--- /dev/null
+++ b/kernel/isr.S
@@ -0,0 +1,94 @@
+/*
+ * This file contains the interrupt service routine stubs.  For the most part
+ * they just call into the generic handlers after setting up the stack for them.
+ */
+
+.extern isr_handler
+
+/* Exception with an error */
+.macro exc_err num
+.globl exc\num
+exc\num:
+	cli
+	push $\num
+	jmp isr_stub
+.endm
+/* Exception without an error */
+.macro exc_noerr num
+.globl exc\num
+exc\num:
+	cli
+	push $0
+	push $\num
+	jmp isr_stub
+.endm
+
+/* Exceptions */
+EXC_NOERR 0
+EXC_NOERR 1
+EXC_NOERR 2
+EXC_NOERR 3
+EXC_NOERR 4
+EXC_NOERR 5
+EXC_NOERR 6
+EXC_NOERR 7
+EXC_ERR   8
+EXC_NOERR 9
+EXC_ERR   10
+EXC_ERR   11
+EXC_ERR   12
+EXC_ERR   13
+EXC_ERR   14
+EXC_NOERR 15
+EXC_NOERR 16
+EXC_ERR   17
+EXC_NOERR 18
+EXC_NOERR 19
+EXC_NOERR 20
+EXC_NOERR 30
+/* Interrupts */
+EXC_NOERR 32
+EXC_NOERR 33
+EXC_NOERR 34
+EXC_NOERR 35
+EXC_NOERR 36
+EXC_NOERR 37
+EXC_NOERR 38
+EXC_NOERR 39
+EXC_NOERR 40
+EXC_NOERR 41
+EXC_NOERR 42
+EXC_NOERR 43
+EXC_NOERR 44
+EXC_NOERR 45
+EXC_NOERR 46
+EXC_NOERR 47
+/* System Call */
+EXC_NOERR 128
+
+/* Generic ISR stub */
+isr_stub:
+	pusha
+	mov %ds, %ax
+	pushl %eax
+
+	/* Switch to kernel segments */
+	mov $0x10, %ax
+	mov %ax, %ds
+	mov %ax, %es
+	mov %ax, %fs
+	mov %ax, %gs
+
+	call isr_handler
+
+	/* Restore original segments */
+	popl %ebx
+	mov %bx, %ds
+	mov %bx, %es
+	mov %bx, %fs
+	mov %bx, %gs
+
+	popa
+	addl $8, %esp
+	sti
+	iret
diff --git a/kernel/main.c b/kernel/main.c
index 5d95c4a..bf1fd8c 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -18,7 +18,7 @@
 #include "acpi/acpi.h"
 
 extern char _bss[], _end[];
-void page_fault_handler(struct InterruptFrame *frame, uint32_t err);
+void page_fault_handler(struct InterruptFrame *frame);
 
 /* Per-CPU Setup */
 void
diff --git a/kernel/panic.c b/kernel/panic.c
index a489a0a..2c07d24 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -30,8 +30,6 @@ panic(char *fmt, ...)
 	outb(0xE9, '\n');
 
 	/* Halt processor */
-	asm volatile("cli");
-	while (1)
-		asm volatile("hlt");
+	while (1) asm volatile("cli; hlt");
 	__builtin_unreachable();
 }