]> Joshua Wise's Git repositories - netwatch.git/blame_incremental - netwatch/traps.c
Fix smm_type detection to actually detect, and add a state_num_regs routine.
[netwatch.git] / netwatch / traps.c
... / ...
CommitLineData
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 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);
34
35#define FAULT_WRAPPER1(func_name, code) asm ( \
36 ".global " #func_name "_wrapper\n" \
37 #func_name "_wrapper:\n" \
38 "mov $0, %eax\n" \
39 "push %eax\n" \
40 "mov $" #code ", %eax\n" \
41 "jmp fault_wrapper_common\n" \
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
55 * 14-13 DPL - Descriptor privilege level - set to 00, since we're always in ring 0
56 * 12-8 01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates
57 * 7-0 Set to 0
58 */
59#define TRAP 0x8F00
60
61typedef struct trap_t {
62 int cr2;
63 int fault_code;
64 int error_code;
65 int eip;
66 int cs;
67 int eflags;
68} trap_t;
69
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
93void die(struct trap_t * trap) {
94
95 DBG(0x40 + trap->fault_code);
96
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");
106}
107
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);
127
128/* pseudo_descriptor and x86_gate structs from 15-410 basis code. */
129
130struct x86_gate {
131 unsigned int filler[2]; //64 bits, or 8 bytes.
132};
133
134static struct x86_gate idt[64];
135
136struct pseudo_descriptor {
137 short pad;
138 unsigned short limit;
139 unsigned long linear_base;
140} __attribute__((packed));
141
142void traps_install(void) {
143 DBG(0xCA);
144 int i;
145
146 struct pseudo_descriptor pdesc;
147 pdesc.limit = sizeof(idt) - 1;
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);
154
155 WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR);
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);
168 WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION);
169 WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT);
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);
173
174 DBG(0xCC);
175 asm volatile("lidt %0" : : "m" (pdesc.limit));
176 DBG(0xCE);
177}
This page took 0.027084 seconds and 4 git commands to generate.