]> Joshua Wise's Git repositories - netwatch.git/blame - netwatch/traps.c
Add cross-compile support (for fools like me who build on OS X) to the Makefiles.
[netwatch.git] / netwatch / traps.c
CommitLineData
3c4e084d
JP
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
ed22a699
JP
11#include <output.h>
12#include <io.h>
13#include <paging.h>
14
15#include "traps.h"
16
db9fad13
JAW
17#define CS_SEGSEL 0x10
18
19asm (
20 "fault_wrapper_common:\n"
21 "push %eax\n"
22 "mov %cr2, %eax\n"
23 "push %eax\n"
24 "push %esp\n"
25 "call die\n"
26);
27
28#define FAULT_WRAPPER(func_name, code) asm ( \
29 ".global " #func_name "_wrapper\n" \
30 #func_name "_wrapper:\n" \
31 "mov $" #code ", %eax\n" \
32 "jmp fault_wrapper_common\n" \
33); void func_name##_wrapper(void);
ed22a699 34
db9fad13 35#define FAULT_WRAPPER1(func_name, code) asm ( \
ed22a699
JP
36 ".global " #func_name "_wrapper\n" \
37 #func_name "_wrapper:\n" \
db9fad13 38 "mov $0, %eax\n" \
ed22a699 39 "push %eax\n" \
db9fad13
JAW
40 "mov $" #code ", %eax\n" \
41 "jmp fault_wrapper_common\n" \
ed22a699
JP
42); void func_name##_wrapper(void);
43
44#define WRAPPER_INSTALL(idt, idt4_value, func_name, int_number) { \
45 *(int *)((void *)idt + (8 * int_number)) = \
46 ((int)func_name##_wrapper & 0xFFFF) | \
47 (CS_SEGSEL << 16); \
48 *(int *)((void *)idt + (8 * int_number) + 4) = \
49 ((int)func_name##_wrapper & 0xFFFF0000) | idt4_value; \
50}
51
52/* The 16 bits at offset 4 from the start of an interrupt gate are a
53 * bitfield, according to the Intel spec:
54 * 15 P - Segment Present - set to 1
db9fad13 55 * 14-13 DPL - Descriptor privilege level - set to 00, since we're always in ring 0
ed22a699
JP
56 * 12-8 01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates
57 * 7-0 Set to 0
ed22a699 58 */
db9fad13 59#define TRAP 0x8F00
ed22a699
JP
60
61typedef struct trap_t {
62 int cr2;
db9fad13 63 int fault_code;
ed22a699
JP
64 int error_code;
65 int eip;
66 int cs;
67 int eflags;
ed22a699
JP
68} trap_t;
69
db9fad13
JAW
70static const char const * trapcodes[20] = {
71 "Divide by Zero",
72 "Debug Trap",
73 "NMI",
74 "Breakpoint Trap",
75 "Overflow Trap",
76 "Bound Range Fault",
77 "Invalid Opcode",
78 "Device Not Available",
79 "Double Fault",
80 "Coprocessor Overrun",
81 "Invalid TSS",
82 "Segmnet Not Present",
83 "Stack Fault",
84 "GPF",
85 "Page Fault",
86 "Reserved Trap",
87 "x87 FPE Pending",
88 "Alignment Check",
89 "Machine Check",
90 "SIMD FPE Fault"
91};
92
ed22a699 93void die(struct trap_t * trap) {
ed22a699 94
db9fad13 95 DBG(0x40 + trap->fault_code);
ed22a699 96
db9fad13
JAW
97 if (trap->fault_code < 20) {
98 outputf("---\n%s", trapcodes[trap->fault_code]);
99 } else {
100 outputf("---\nUNKNOWN FAULT");
101 }
102
103 outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
104 outputf("%%cr2 %08x %%eflags %08x", trap->cr2, trap->eflags);
105 while(1) asm("hlt");
ed22a699
JP
106}
107
db9fad13
JAW
108FAULT_WRAPPER1(fault_divide, 0);
109FAULT_WRAPPER1(fault_db, 1);
110FAULT_WRAPPER1(fault_nmi, 2);
111FAULT_WRAPPER1(fault_3, 3);
112FAULT_WRAPPER1(fault_overflow, 4);
113FAULT_WRAPPER1(fault_oob, 5);
114FAULT_WRAPPER1(fault_opcode, 6);
115FAULT_WRAPPER1(fault_enofpu, 7);
116FAULT_WRAPPER(double_fault, 8);
117FAULT_WRAPPER1(fault_fpu, 9);
118FAULT_WRAPPER(fault_invalid_tss, 10);
119FAULT_WRAPPER(fault_noseg, 11);
120FAULT_WRAPPER(fault_stack, 12);
121FAULT_WRAPPER(fault_gp, 13);
122FAULT_WRAPPER(fault_page, 14);
123FAULT_WRAPPER1(fault_fpe, 16);
124FAULT_WRAPPER(fault_ac, 17);
125FAULT_WRAPPER1(fault_machine, 18);
126FAULT_WRAPPER1(fault_other, 19);
ed22a699
JP
127
128/* pseudo_descriptor and x86_gate structs from 15-410 basis code. */
129
130struct x86_gate {
db9fad13 131 unsigned int filler[2]; //64 bits, or 8 bytes.
ed22a699
JP
132};
133
134static struct x86_gate idt[64];
135
136struct pseudo_descriptor {
137 short pad;
138 unsigned short limit;
139 unsigned long linear_base;
ea82a4d1 140} __attribute__((packed));
ed22a699
JP
141
142void traps_install(void) {
db9fad13
JAW
143 DBG(0xCA);
144 int i;
ed22a699
JP
145
146 struct pseudo_descriptor pdesc;
147 pdesc.limit = sizeof(idt) - 1;
db9fad13
JAW
148 pdesc.linear_base = (int)&idt; //v2p(&idt);
149
150 DBG(0xCB);
151
152 for (i = 0; i < 32; i++)
153 WRAPPER_INSTALL(idt, TRAP, fault_other, i);
ed22a699
JP
154
155 WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR);
db9fad13
JAW
156 WRAPPER_INSTALL(idt, TRAP, fault_db, T_DEBUG);
157 WRAPPER_INSTALL(idt, TRAP, fault_nmi, T_NMI);
158 WRAPPER_INSTALL(idt, TRAP, fault_3, T_INT3);
159 WRAPPER_INSTALL(idt, TRAP, fault_overflow, T_OVERFLOW);
160 WRAPPER_INSTALL(idt, TRAP, fault_oob, T_OUT_OF_BOUNDS);
161 WRAPPER_INSTALL(idt, TRAP, fault_opcode, T_INVALID_OPCODE);
162 WRAPPER_INSTALL(idt, TRAP, fault_enofpu, T_NO_FPU);
163 WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
164 WRAPPER_INSTALL(idt, TRAP, fault_fpu, T_FPU_FAULT);
165 WRAPPER_INSTALL(idt, TRAP, fault_invalid_tss, T_INVALID_TSS);
166 WRAPPER_INSTALL(idt, TRAP, fault_noseg, T_SEGMENT_NOT_PRESENT);
167 WRAPPER_INSTALL(idt, TRAP, fault_stack, T_STACK_FAULT);
ed22a699
JP
168 WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION);
169 WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT);
db9fad13
JAW
170 WRAPPER_INSTALL(idt, TRAP, fault_fpe, T_FLOATING_POINT_ERROR);
171 WRAPPER_INSTALL(idt, TRAP, fault_ac, T_ALIGNMENT_CHECK);
172 WRAPPER_INSTALL(idt, TRAP, fault_machine, T_MACHINE_CHECK);
ed22a699 173
db9fad13 174 DBG(0xCC);
ed22a699 175 asm volatile("lidt %0" : : "m" (pdesc.limit));
db9fad13 176 DBG(0xCE);
ed22a699 177}
This page took 0.036054 seconds and 4 git commands to generate.