]> Joshua Wise's Git repositories - netwatch.git/commitdiff
add some fault handlers
authorJacob Potter <jdpotter@andrew.cmu.edu>
Mon, 10 Nov 2008 19:32:54 +0000 (14:32 -0500)
committerJacob Potter <jdpotter@andrew.cmu.edu>
Mon, 10 Nov 2008 19:32:54 +0000 (14:32 -0500)
aseg-paging/Makefile
aseg-paging/pagingstub.c
aseg-paging/traps.c [new file with mode: 0644]
aseg-paging/traps.h [new file with mode: 0644]

index 0bbe0489e106960d998566a78ab9cf6bc016ec83..a8d72cd9860c8086a1336e644c214350fabd64e5 100644 (file)
@@ -53,6 +53,7 @@ OBJS =        ../ich2/smi.o \
        smi.o \
        vga-overlay.o \
        main.o \
+       traps.o \
        firstrun.o
 
 
index d839966749dbb8dd919f897df80dcda5ac129471..0115713bf93d29e4e990243aade030bb27a22a36 100644 (file)
@@ -5,6 +5,7 @@
 #include <smi.h>
 #include <pci-bother.h>
 #include <serial.h>
+#include "traps.h"
 #include "../net/net.h"
 #include "vga-overlay.h"
 
@@ -114,6 +115,7 @@ void c_entry(void)
        set_cr0(get_cr0() | CR0_PG);
        
        outb(0x80, 0x43);
+
        if (!entry_initialized) {
                
                /* If needed, copy in data. */
@@ -123,6 +125,11 @@ void c_entry(void)
                        *bp = 0;
                serial_init();
                dolog("Paging enabled.");
+       }
+
+       traps_install();
+
+       if (!entry_initialized) {
                smi_init();
                
                entry_initialized = 1;
diff --git a/aseg-paging/traps.c b/aseg-paging/traps.c
new file mode 100644 (file)
index 0000000..8184bdb
--- /dev/null
@@ -0,0 +1,105 @@
+#include <output.h>
+#include <io.h>
+#include <paging.h>
+
+#include "traps.h"
+
+#define CS_SEGSEL      0x10
+
+#define FAULT_WRAPPER(func_name)        asm (           \
+        ".global " #func_name "_wrapper\n"              \
+        #func_name "_wrapper:\n"                        \
+        "mov %cr2, %eax\n"                              \
+        "push %eax\n"                                   \
+        "push %esp\n"                                   \
+        "call " #func_name "\n"                         \
+); void func_name##_wrapper(void);
+
+#define WRAPPER_INSTALL(idt, idt4_value, func_name, int_number) {      \
+       *(int *)((void *)idt + (8 * int_number)) =      \
+               ((int)func_name##_wrapper & 0xFFFF) |   \
+               (CS_SEGSEL << 16);              \
+       *(int *)((void *)idt + (8 * int_number) + 4) =  \
+               ((int)func_name##_wrapper & 0xFFFF0000) | idt4_value; \
+}
+
+/* The 16 bits at offset 4 from the start of an interrupt gate are a
+ * bitfield, according to the Intel spec:
+ * 15           P - Segment Present - set to 1
+ * 14-13        DPL - Descriptor privilege level - set to 11 for trap/int, 00 for IPI
+ * 12-8         01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates
+ * 7-0          Set to 0
+ * Trap:      binary 11101111 0000000, hex EF00.
+ * Interrupt: binary 11101110 0000000, hex EE00.
+ */
+#define TRAP           0xEF00
+#define INTERRUPT      0xEE00
+
+typedef struct trap_t {
+       int cr2;
+        int error_code;
+        int eip;
+        int cs;
+        int eflags;
+        int esp;
+        int ss;
+} trap_t;
+
+void die(struct trap_t * trap) {
+       outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
+       outputf("%%esp %08x %%eflags %08x", trap->esp, trap->eflags);
+       while(1) asm("hlt");
+}
+
+void fault_gp(struct trap_t * trap) {
+       outputf("GENERAL PROTECTION FAULT");
+       die(trap);
+}
+
+void fault_page(struct trap_t * trap) {
+       outputf("PAGE FAULT: %08x", trap->cr2);
+       die(trap);
+}
+void fault_divide(struct trap_t * trap) {
+       outputf("DIVISION FAULT");
+       die(trap);
+}
+void double_fault(struct trap_t * trap) {
+       outputf("DOUBLE FAULT");
+       die(trap);
+}
+
+FAULT_WRAPPER(fault_gp);
+FAULT_WRAPPER(fault_page);
+FAULT_WRAPPER(fault_divide);
+FAULT_WRAPPER(double_fault);
+
+/* pseudo_descriptor and x86_gate structs from 15-410 basis code. */
+
+struct x86_gate {
+unsigned int filler[2]; //64 bits; or 8 bytes.
+};
+
+static struct x86_gate idt[64];
+
+struct pseudo_descriptor {
+        short pad;
+        unsigned short limit;
+        unsigned long linear_base;
+};
+
+void traps_install(void) {
+
+        struct pseudo_descriptor pdesc;
+       pdesc.limit = sizeof(idt) - 1;
+       pdesc.linear_base = memory_v2p(&idt);
+
+       WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR);
+       WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION);
+       WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT);
+       WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
+
+        outb(0x80, 0xCC);
+       asm volatile("lidt %0" : : "m" (pdesc.limit));
+        outb(0x80, 0xCD);
+}
diff --git a/aseg-paging/traps.h b/aseg-paging/traps.h
new file mode 100644 (file)
index 0000000..f57e036
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef TRAPS_H
+#define TRAPS_H
+
+/* Trap vectors from 15-410 basis code. */
+
+#define T_DIVIDE_ERROR          0
+#define T_DEBUG                 1
+#define T_NMI                   2
+#define T_INT3                  3
+#define T_OVERFLOW              4
+#define T_OUT_OF_BOUNDS         5
+#define T_INVALID_OPCODE        6
+#define T_NO_FPU                7
+#define T_DOUBLE_FAULT          8
+#define T_FPU_FAULT             9
+#define T_INVALID_TSS           10
+#define T_SEGMENT_NOT_PRESENT   11
+#define T_STACK_FAULT           12
+#define T_GENERAL_PROTECTION    13
+#define T_PAGE_FAULT            14
+#define T_FLOATING_POINT_ERROR  16
+#define T_ALIGNMENT_CHECK       17
+#define T_MACHINE_CHECK         18
+
+void traps_install(void);
+
+#endif /* TRAPS_H */
This page took 0.035074 seconds and 4 git commands to generate.