From d05ffcacacdd584e8e2ff73c53448d494419fc53 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 19 Jul 2011 09:10:12 +0200 Subject: [PATCH] we use the same handler for exceptions and interrupts => interrupts has to push a virtual error code on the stack --- arch/x86/include/asm/stddef.h | 10 +++- arch/x86/kernel/entry.asm | 108 +++++++++++++++++++++++----------- arch/x86/kernel/isrs.c | 2 +- 3 files changed, 83 insertions(+), 37 deletions(-) diff --git a/arch/x86/include/asm/stddef.h b/arch/x86/include/asm/stddef.h index 9dd442f5..90c9b2a1 100644 --- a/arch/x86/include/asm/stddef.h +++ b/arch/x86/include/asm/stddef.h @@ -89,8 +89,14 @@ struct state { /// Interrupt number unsigned int int_no; - /// pushed by the processor automatically - unsigned int eip, cs, eflags, useresp, ss; + + // pushed by the processor automatically + unsigned int error; + unsigned int eip; + unsigned int cs; + unsigned int eflags; + unsigned int useresp; + unsigned int ss; }; /** @brief Read out APIC CPU ID diff --git a/arch/x86/kernel/entry.asm b/arch/x86/kernel/entry.asm index 9f15bc05..2a36ab76 100644 --- a/arch/x86/kernel/entry.asm +++ b/arch/x86/kernel/entry.asm @@ -161,7 +161,7 @@ isr0: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 0 - jmp irq_common_stub + jmp isr_common_stub ; 1: Debug Exception isr1: @@ -169,7 +169,7 @@ isr1: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 1 - jmp irq_common_stub + jmp isr_common_stub ; 2: Non Maskable Interrupt Exception isr2: @@ -177,7 +177,7 @@ isr2: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 2 - jmp irq_common_stub + jmp isr_common_stub ; 3: Int 3 Exception isr3: @@ -185,7 +185,7 @@ isr3: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 3 - jmp irq_common_stub + jmp isr_common_stub ; 4: INTO Exception isr4: @@ -193,7 +193,7 @@ isr4: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 4 - jmp irq_common_stub + jmp isr_common_stub ; 5: Out of Bounds Exception isr5: @@ -201,7 +201,7 @@ isr5: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 5 - jmp irq_common_stub + jmp isr_common_stub ; 6: Invalid Opcode Exception isr6: @@ -209,7 +209,7 @@ isr6: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 6 - jmp irq_common_stub + jmp isr_common_stub ; 7: Coprocessor Not Available Exception isr7: @@ -217,7 +217,7 @@ isr7: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 7 - jmp irq_common_stub + jmp isr_common_stub ; 8: Double Fault Exception (With Error Code!) isr8: @@ -225,7 +225,7 @@ isr8: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 8 - jmp irq_common_stub + jmp isr_common_stub ; 9: Coprocessor Segment Overrun Exception isr9: @@ -233,7 +233,7 @@ isr9: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 9 - jmp irq_common_stub + jmp isr_common_stub ; 10: Bad TSS Exception (With Error Code!) isr10: @@ -241,7 +241,7 @@ isr10: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 10 - jmp irq_common_stub + jmp isr_common_stub ; 11: Segment Not Present Exception (With Error Code!) isr11: @@ -249,7 +249,7 @@ isr11: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 11 - jmp irq_common_stub + jmp isr_common_stub ; 12: Stack Fault Exception (With Error Code!) isr12: @@ -257,7 +257,7 @@ isr12: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 12 - jmp irq_common_stub + jmp isr_common_stub ; 13: General Protection Fault Exception (With Error Code!) isr13: @@ -265,7 +265,7 @@ isr13: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 13 - jmp irq_common_stub + jmp isr_common_stub ; 14: Page Fault Exception (With Error Code!) isr14: @@ -273,7 +273,7 @@ isr14: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 14 - jmp irq_common_stub + jmp isr_common_stub ; 15: Reserved Exception isr15: @@ -281,7 +281,7 @@ isr15: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 15 - jmp irq_common_stub + jmp isr_common_stub ; 16: Floating Point Exception isr16: @@ -289,7 +289,7 @@ isr16: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 16 - jmp irq_common_stub + jmp isr_common_stub ; 17: Alignment Check Exception isr17: @@ -297,7 +297,7 @@ isr17: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 17 - jmp irq_common_stub + jmp isr_common_stub ; 18: Machine Check Exception isr18: @@ -305,7 +305,7 @@ isr18: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 18 - jmp irq_common_stub + jmp isr_common_stub ; 19: Reserved isr19: @@ -313,7 +313,7 @@ isr19: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 19 - jmp irq_common_stub + jmp isr_common_stub ; 20: Reserved isr20: @@ -321,7 +321,7 @@ isr20: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 20 - jmp irq_common_stub + jmp isr_common_stub ; 21: Reserved isr21: @@ -329,7 +329,7 @@ isr21: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 21 - jmp irq_common_stub + jmp isr_common_stub ; 22: Reserved isr22: @@ -337,7 +337,7 @@ isr22: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 22 - jmp irq_common_stub + jmp isr_common_stub ; 23: Reserved isr23: @@ -345,7 +345,7 @@ isr23: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 23 - jmp irq_common_stub + jmp isr_common_stub ; 24: Reserved isr24: @@ -353,7 +353,7 @@ isr24: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 24 - jmp irq_common_stub + jmp isr_common_stub ; 25: Reserved isr25: @@ -361,7 +361,7 @@ isr25: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 25 - jmp irq_common_stub + jmp isr_common_stub ; 26: Reserved isr26: @@ -369,7 +369,7 @@ isr26: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 26 - jmp irq_common_stub + jmp isr_common_stub ; 27: Reserved isr27: @@ -377,7 +377,7 @@ isr27: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 27 - jmp irq_common_stub + jmp isr_common_stub ; 28: Reserved isr28: @@ -385,7 +385,7 @@ isr28: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 28 - jmp irq_common_stub + jmp isr_common_stub ; 29: Reserved isr29: @@ -393,7 +393,7 @@ isr29: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 29 - jmp irq_common_stub + jmp isr_common_stub ; 30: Reserved isr30: @@ -401,7 +401,7 @@ isr30: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 30 - jmp irq_common_stub + jmp isr_common_stub ; 31: Reserved isr31: @@ -409,7 +409,19 @@ isr31: ; Therefore, the interrupt flag (IF) is already cleared. ; cli push byte 31 - jmp irq_common_stub + jmp isr_common_stub + +isr_common_stub: + pusha + + ; use the same handler for interrupts and exceptions + push esp + call irq_handler + add esp, 4 + + popa + add esp, 4 + iret extern syscall_handler @@ -508,6 +520,7 @@ irq0: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 32 Lirq0: @@ -534,7 +547,7 @@ hack2: no_task_switch2: popa - add esp, 4 + add esp, 8 iret ; 33: IRQ1 @@ -542,6 +555,7 @@ irq1: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 33 jmp irq_common_stub @@ -550,6 +564,7 @@ irq2: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 34 jmp irq_common_stub @@ -558,6 +573,7 @@ irq3: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 35 jmp irq_common_stub @@ -566,6 +582,7 @@ irq4: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 36 jmp irq_common_stub @@ -574,6 +591,7 @@ irq5: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 37 jmp irq_common_stub @@ -582,6 +600,7 @@ irq6: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 38 jmp irq_common_stub @@ -590,6 +609,7 @@ irq7: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 39 jmp irq_common_stub @@ -598,6 +618,7 @@ irq8: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 40 jmp irq_common_stub @@ -606,6 +627,7 @@ irq9: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 41 jmp irq_common_stub @@ -614,6 +636,7 @@ irq10: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 42 jmp irq_common_stub @@ -630,6 +653,7 @@ irq12: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 44 jmp irq_common_stub @@ -638,6 +662,7 @@ irq13: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 45 jmp irq_common_stub @@ -646,6 +671,7 @@ irq14: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 46 jmp irq_common_stub @@ -654,6 +680,7 @@ irq15: ; irq0 - irq15 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 47 jmp irq_common_stub @@ -662,6 +689,7 @@ irq16: ; irq16 - irq23 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 48 jmp irq_common_stub @@ -670,6 +698,7 @@ irq17: ; irq16- irq23 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 49 jmp irq_common_stub @@ -678,6 +707,7 @@ irq18: ; irq16 - irq23 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 50 jmp irq_common_stub @@ -686,6 +716,7 @@ irq19: ; irq16 - irq23 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 51 jmp irq_common_stub @@ -694,6 +725,7 @@ irq20: ; irq16- irq23 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 52 jmp irq_common_stub @@ -702,6 +734,7 @@ irq21: ; irq16 - irq23 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 53 jmp irq_common_stub @@ -718,6 +751,7 @@ irq23: ; irq16 - irq23 are registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 55 jmp irq_common_stub @@ -725,6 +759,7 @@ apic_timer: ; apic timer is registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 123 jmp Lirq0 @@ -732,6 +767,7 @@ apic_lint0: ; lint0 is registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 124 jmp irq_common_stub @@ -739,6 +775,7 @@ apic_lint1: ; lint1 is registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 125 jmp irq_common_stub @@ -746,6 +783,7 @@ apic_error: ; LVT error interrupt is registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 126 jmp irq_common_stub @@ -753,18 +791,20 @@ apic_svr: ; SVR is registered as "Interrupt Gate" ; Therefore, the interrupt flag (IF) is already cleared. ; cli + push byte 0 ; error code push byte 127 jmp irq_common_stub irq_common_stub: pusha + ; use the same handler for interrupts and exceptions push esp call irq_handler add esp, 4 popa - add esp, 4 + add esp, 8 iret SECTION .note.GNU-stack noalloc noexec nowrite progbits diff --git a/arch/x86/kernel/isrs.c b/arch/x86/kernel/isrs.c index 4e31cfef..f1c4497f 100644 --- a/arch/x86/kernel/isrs.c +++ b/arch/x86/kernel/isrs.c @@ -229,7 +229,7 @@ static void fault_handler(struct state *s) { if (s->int_no < 32) { kputs(exception_messages[s->int_no]); - kprintf(" Exception. (%d)\n", s->int_no); + kprintf(" Exception (%d) at 0x%x:0x%x, error code 0x%x\n", s->int_no, s->cs, s->eip, s->error); /* Now, we signalize that we have handled the interrupt */ if (apic_is_enabled())