]> Joshua Wise's Git repositories - netwatch.git/blob - netwatch/traps.c
bf5ca803b221ef2968fb9dee73ee0be0a47345d1
[netwatch.git] / netwatch / traps.c
1 /* traps.c
2  * Trap handling routines
3  * NetWatch system management mode administration console
4  *
5  * Copyright (c) 2008 Jacob Potter and Joshua Wise.  All rights reserved.
6  * This program is free software; you can redistribute and/or modify it under
7  * the terms found in the file LICENSE in the root of this source tree.
8  *
9  */
10
11 #include <output.h>
12 #include <io.h>
13 #include <paging.h>
14
15 #include "traps.h"
16
17 #define CS_SEGSEL       0x8
18
19 #define FAULT_WRAPPER(func_name)        asm (           \
20         ".global " #func_name "_wrapper\n"              \
21         #func_name "_wrapper:\n"                        \
22         "mov %cr2, %eax\n"                              \
23         "push %eax\n"                                   \
24         "push %esp\n"                                   \
25         "call " #func_name "\n"                         \
26 ); void func_name##_wrapper(void);
27
28 #define WRAPPER_INSTALL(idt, idt4_value, func_name, int_number) {       \
29         *(int *)((void *)idt + (8 * int_number)) =      \
30                 ((int)func_name##_wrapper & 0xFFFF) |   \
31                 (CS_SEGSEL << 16);              \
32         *(int *)((void *)idt + (8 * int_number) + 4) =  \
33                 ((int)func_name##_wrapper & 0xFFFF0000) | idt4_value; \
34 }
35
36 /* The 16 bits at offset 4 from the start of an interrupt gate are a
37  * bitfield, according to the Intel spec:
38  * 15           P - Segment Present - set to 1
39  * 14-13        DPL - Descriptor privilege level - set to 11 for trap/int, 00 for IPI
40  * 12-8         01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates
41  * 7-0          Set to 0
42  * Trap:      binary 11101111 0000000, hex EF00.
43  * Interrupt: binary 11101110 0000000, hex EE00.
44  */
45 #define TRAP            0xEF00
46 #define INTERRUPT       0xEE00
47
48 typedef struct trap_t {
49         int cr2;
50         int error_code;
51         int eip;
52         int cs;
53         int eflags;
54         int esp;
55         int ss;
56 } trap_t;
57
58 void die(struct trap_t * trap) {
59         outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
60         outputf("%%esp %08x %%eflags %08x", trap->esp, trap->eflags);
61         while(1) asm("hlt");
62 }
63
64 void fault_gp(struct trap_t * trap) {
65         outputf("GENERAL PROTECTION FAULT");
66         die(trap);
67 }
68
69 void fault_page(struct trap_t * trap) {
70         outputf("PAGE FAULT: %08x", trap->cr2);
71         die(trap);
72 }
73 void fault_divide(struct trap_t * trap) {
74         outputf("DIVISION FAULT");
75         die(trap);
76 }
77 void double_fault(struct trap_t * trap) {
78         outputf("DOUBLE FAULT");
79         die(trap);
80 }
81
82 FAULT_WRAPPER(fault_gp);
83 FAULT_WRAPPER(fault_page);
84 FAULT_WRAPPER(fault_divide);
85 FAULT_WRAPPER(double_fault);
86
87 /* pseudo_descriptor and x86_gate structs from 15-410 basis code. */
88
89 struct x86_gate {
90 unsigned int filler[2]; //64 bits; or 8 bytes.
91 };
92
93 static struct x86_gate idt[64];
94
95 struct pseudo_descriptor {
96         short pad;
97         unsigned short limit;
98         unsigned long linear_base;
99 } __attribute__((packed));
100
101 void traps_install(void) {
102
103         struct pseudo_descriptor pdesc;
104         pdesc.limit = sizeof(idt) - 1;
105         pdesc.linear_base = v2p(&idt);
106
107         WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR);
108         WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION);
109         WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT);
110         WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
111
112         outb(0x80, 0xCC);
113         asm volatile("lidt %0" : : "m" (pdesc.limit));
114         outb(0x80, 0xCD);
115 }
This page took 0.020248 seconds and 2 git commands to generate.