From 376ec895110deb142a9162984e50ad6f0616758e Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Sat, 9 Oct 2021 15:26:32 -0500 Subject: arch: i386: include more information in IDT Include information about the current stack frame in the IDT handler(s). Signed-off-by: Danny Holman --- arch/i386/boot/idt.c | 80 +++++++++++++++++++++--------------------- arch/i386/boot/isr.s | 76 +++++++++++++++++++++++++++------------ arch/i386/include/kernel/idt.h | 19 +++++----- arch/i386/include/kernel/isr.h | 27 +++++++++++++- 4 files changed, 129 insertions(+), 73 deletions(-) (limited to 'arch') diff --git a/arch/i386/boot/idt.c b/arch/i386/boot/idt.c index 7213fe5..d741381 100644 --- a/arch/i386/boot/idt.c +++ b/arch/i386/boot/idt.c @@ -10,56 +10,56 @@ struct idt_entry idt[256]; struct idt_ptr idtr; __attribute__((noreturn)) -void exception_handler(int number) { - kprintf("EXCEPTION %d CAUGHT\n", number); +void exception_handler(struct isr_frame *frame) { + kprintf("Error: CPU exception: %d\n", frame->vector); __asm__ volatile("cli;hlt"); } extern void idt_set_gate(uint8_t num, void (*handler)(void), uint16_t cs, uint8_t flags) { - idt[num].isr_low = (uint16_t)(((uint32_t)handler >> 0) & 0xFFFF); - idt[num].isr_high = (uint16_t)(((uint32_t)handler >> 16) & 0xFFFF); - idt[num].reserved = 0; - idt[num].kernel_cs = cs; - idt[num].flags = flags; + struct idt_entry *desc = &idt[num]; + desc->isr_low = (uint16_t)(((uint32_t)handler >> 0) & 0xFFFF); + desc->isr_high = (uint16_t)(((uint32_t)handler >> 16) & 0xFFFF); + desc->reserved = 0; + desc->kernel_cs = cs; + desc->flags = flags; } void idt_install(void) { idtr.limit = (uint16_t)sizeof(struct idt_entry) * 256 - 1; idtr.base = (uint32_t)&idt[0]; - memset(&idt, 0, sizeof(struct idt_entry) * 256); - idt_set_gate(0, isr_stub_0, 0x08, 0x8e); - idt_set_gate(1, isr_stub_1, 0x08, 0x8e); - idt_set_gate(2, isr_stub_2, 0x08, 0x8e); - idt_set_gate(3, isr_stub_3, 0x08, 0x8e); - idt_set_gate(4, isr_stub_4, 0x08, 0x8e); - idt_set_gate(5, isr_stub_5, 0x08, 0x8e); - idt_set_gate(6, isr_stub_6, 0x08, 0x8e); - idt_set_gate(7, isr_stub_7, 0x08, 0x8e); - idt_set_gate(8, isr_stub_8, 0x08, 0x8e); - idt_set_gate(9, isr_stub_9, 0x08, 0x8e); - idt_set_gate(10, isr_stub_10, 0x08, 0x8e); - idt_set_gate(11, isr_stub_11, 0x08, 0x8e); - idt_set_gate(12, isr_stub_12, 0x08, 0x8e); - idt_set_gate(13, isr_stub_13, 0x08, 0x8e); - idt_set_gate(14, isr_stub_14, 0x08, 0x8e); - idt_set_gate(15, isr_stub_15, 0x08, 0x8e); - idt_set_gate(16, isr_stub_16, 0x08, 0x8e); - idt_set_gate(17, isr_stub_17, 0x08, 0x8e); - idt_set_gate(18, isr_stub_18, 0x08, 0x8e); - idt_set_gate(19, isr_stub_19, 0x08, 0x8e); - idt_set_gate(20, isr_stub_20, 0x08, 0x8e); - idt_set_gate(21, isr_stub_21, 0x08, 0x8e); - idt_set_gate(22, isr_stub_22, 0x08, 0x8e); - idt_set_gate(23, isr_stub_23, 0x08, 0x8e); - idt_set_gate(24, isr_stub_24, 0x08, 0x8e); - idt_set_gate(25, isr_stub_25, 0x08, 0x8e); - idt_set_gate(26, isr_stub_26, 0x08, 0x8e); - idt_set_gate(27, isr_stub_27, 0x08, 0x8e); - idt_set_gate(28, isr_stub_28, 0x08, 0x8e); - idt_set_gate(29, isr_stub_29, 0x08, 0x8e); - idt_set_gate(30, isr_stub_30, 0x08, 0x8e); - idt_set_gate(31, isr_stub_31, 0x08, 0x8e); + idt_set_gate(0, isr_stub_0, 0x08, IDT_EXCEPTION); + idt_set_gate(1, isr_stub_1, 0x08, IDT_EXCEPTION); + idt_set_gate(2, isr_stub_2, 0x08, IDT_EXCEPTION); + idt_set_gate(3, isr_stub_3, 0x08, IDT_EXCEPTION); + idt_set_gate(4, isr_stub_4, 0x08, IDT_EXCEPTION); + idt_set_gate(5, isr_stub_5, 0x08, IDT_EXCEPTION); + idt_set_gate(6, isr_stub_6, 0x08, IDT_EXCEPTION); + idt_set_gate(7, isr_stub_7, 0x08, IDT_EXCEPTION); + idt_set_gate(8, isr_stub_8, 0x08, IDT_EXCEPTION); + idt_set_gate(9, isr_stub_9, 0x08, IDT_EXCEPTION); + idt_set_gate(10, isr_stub_10, 0x08, IDT_EXCEPTION); + idt_set_gate(11, isr_stub_11, 0x08, IDT_EXCEPTION); + idt_set_gate(12, isr_stub_12, 0x08, IDT_EXCEPTION); + idt_set_gate(13, isr_stub_13, 0x08, IDT_EXCEPTION); + idt_set_gate(14, isr_stub_14, 0x08, IDT_EXCEPTION); + idt_set_gate(15, isr_stub_15, 0x08, IDT_EXCEPTION); + idt_set_gate(16, isr_stub_16, 0x08, IDT_EXCEPTION); + idt_set_gate(17, isr_stub_17, 0x08, IDT_EXCEPTION); + idt_set_gate(18, isr_stub_18, 0x08, IDT_EXCEPTION); + idt_set_gate(19, isr_stub_19, 0x08, IDT_EXCEPTION); + idt_set_gate(20, isr_stub_20, 0x08, IDT_EXCEPTION); + idt_set_gate(21, isr_stub_21, 0x08, IDT_EXCEPTION); + idt_set_gate(22, isr_stub_22, 0x08, IDT_EXCEPTION); + idt_set_gate(23, isr_stub_23, 0x08, IDT_EXCEPTION); + idt_set_gate(24, isr_stub_24, 0x08, IDT_EXCEPTION); + idt_set_gate(25, isr_stub_25, 0x08, IDT_EXCEPTION); + idt_set_gate(26, isr_stub_26, 0x08, IDT_EXCEPTION); + idt_set_gate(27, isr_stub_27, 0x08, IDT_EXCEPTION); + idt_set_gate(28, isr_stub_28, 0x08, IDT_EXCEPTION); + idt_set_gate(29, isr_stub_29, 0x08, IDT_EXCEPTION); + idt_set_gate(30, isr_stub_30, 0x08, IDT_EXCEPTION); + idt_set_gate(31, isr_stub_31, 0x08, IDT_EXCEPTION); __asm__ volatile("lidt %0" : : "memory"(idtr)); __asm__ volatile("sti"); diff --git a/arch/i386/boot/isr.s b/arch/i386/boot/isr.s index 43ef3be..b5f8be5 100644 --- a/arch/i386/boot/isr.s +++ b/arch/i386/boot/isr.s @@ -4,42 +4,74 @@ .global isr_stub_\num .type isr_stub_\num, @function isr_stub_\num: - cli - pushl %eax - pushl %ecx - pushl %edx - pushl %ds - pushl %esp pushl $\num - call exception_handler - popl %esp - popl %ds - popl %edx - popl %ecx - popl %eax - addl $8, %esp - iret + jmp isr_frame_asm .endm .macro isr_no_err_stub num .global isr_stub_\num .type isr_stub_\num, @function isr_stub_\num: - cli + pushl $0 + pushl $\num + jmp isr_frame_asm +.endm + +isr_frame_asm: + pushl %ebp + movl %esp, %ebp pushl %eax + pushl %ebx + pushl %ecx pushl %ecx pushl %edx - pushl %ds - pushl %esp - pushl $\num + pushl %esi + pushl %edi + + movl %cr0, %eax + pushl %eax + movl %cr2, %eax + pushl %eax + movl %cr3, %eax + pushl %eax + movl %cr4, %eax + pushl %eax + + movw %ds, %ax + pushl %eax + pushl $0 + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + + lea 0xC(%esp), %edi + pushl %edi call exception_handler - popl %esp - popl %ds + + popl %eax + popl %eax + movw %ax, %ds + movw %ax, %es + + popl %eax + movl %eax, %cr4 + popl %eax + movl %eax, %cr3 + popl %eax + movl %eax, %cr2 + popl %eax + movl %eax, %cr0 + + popl %edi + popl %esi popl %edx popl %ecx + popl %ebx popl %eax - addl $8, %esp + + popl %ebp + add $0x10, %esp iret -.endm isr_no_err_stub 0 isr_no_err_stub 1 diff --git a/arch/i386/include/kernel/idt.h b/arch/i386/include/kernel/idt.h index 7ccad30..699eb96 100644 --- a/arch/i386/include/kernel/idt.h +++ b/arch/i386/include/kernel/idt.h @@ -4,14 +4,14 @@ #include // IDT Flags -#define SEGMENT_PRESENT 0x8 -#define SEGMENT_RING0 0x0 -#define SEGMENT_STORAGE 0x0 -#define SEGMENT_GATE 0xE -#define SEGMENT_DPL 0x8 +#define SEGMENT_PRESENT 0x80 +#define SEGMENT_RING0 0x00 +#define SEGMENT_RING3 0x60 +#define SEGMENT_STORAGE 0x00 +#define SEGMENT_INTERRUPT 0x0E +#define IDT_EXCEPTION (SEGMENT_PRESENT | SEGMENT_INTERRUPT) -#define SEGMENT_FLAG SEGMENT_PRESENT | SEGMENT_RING0 | SEGMENT_STORAGE |\ - SEGMENT_GATE | SEGMENT_DPL; +#define IDT_MAX_DESCRIPTORS 256 struct idt_entry { uint16_t isr_low; @@ -26,10 +26,9 @@ struct idt_ptr { uint32_t base; } __attribute__((packed)); -extern struct idt_entry idt[256]; +extern struct idt_entry idt[IDT_MAX_DESCRIPTORS]; extern struct idt_ptr idtr; extern void idt_set_gate(uint8_t num, void(*handler)(void), uint16_t cs, uint8_t flags); -extern void exception_handler(int num); -#endif \ No newline at end of file +#endif diff --git a/arch/i386/include/kernel/isr.h b/arch/i386/include/kernel/isr.h index a924cd6..61fe22f 100644 --- a/arch/i386/include/kernel/isr.h +++ b/arch/i386/include/kernel/isr.h @@ -1,6 +1,31 @@ #ifndef I386_ISR_H #define I386_ISR_H +#include + +struct isr_frame { + uint32_t cr4; + uint32_t cr3; + uint32_t cr2; + uint32_t cr0; + + uint32_t edi; + uint32_t esi; + uint32_t edx; + uint32_t ecx; + uint32_t ebx; + uint32_t eax; + + uint32_t ebp; + uint32_t vector; + uint32_t errno; + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t dss; +} __attribute__((packed)); + extern void isr_stub_0(void); extern void isr_stub_1(void); extern void isr_stub_2(void); @@ -34,4 +59,4 @@ extern void isr_stub_29(void); extern void isr_stub_30(void); extern void isr_stub_31(void); -#endif \ No newline at end of file +#endif -- cgit v1.2.3