CS350 COS
COS
Loading...
Searching...
No Matches
trap.c
Go to the documentation of this file.
1
2#include <stdbool.h>
3#include <stdint.h>
4
5#include <sys/kconfig.h>
6#include <sys/kassert.h>
7#include <sys/kdebug.h>
8#include <sys/kmem.h>
9#include <sys/ktime.h>
10#include <sys/spinlock.h>
11#include <sys/irq.h>
12#include <sys/syscall.h>
13#include <sys/mp.h>
14
15#include <machine/amd64.h>
16#include <machine/lapic.h>
17#include <machine/trap.h>
18#include <machine/mp.h>
19
20#include <sys/thread.h>
21
23extern void trap_pop(TrapFrame *tf);
24extern void Debug_Breakpoint(TrapFrame *tf);
25extern void Debug_HaltIPI(TrapFrame *tf);
26extern void KTimer_Process();
27
28static InteruptGate64 idt[256];
30static uint64_t intStats[256];
31
32void
34{
35 int i;
36
37 kprintf("Initializing IDT... ");
38
39 for (i = 0; i < T_MAX; i++) {
40 idt[i].pc_low = trap_table[i] & 0x0000ffff;
41 idt[i].pc_mid = (trap_table[i] >> 16) & 0x0000ffff;
42 idt[i].pc_high = trap_table[i] >> 32;
43
44 idt[i].cs = 0x0008;
45 idt[i].type = 0x8E;
46
47 idt[i].ist = 0x00;
48 idt[i]._unused1 = 0x00000000;
49 }
50
51 for (; i < 256; i++) {
52 idt[i].pc_low = trap_table[63] & 0x0000ffff;
53 idt[i].pc_mid = (trap_table[63] >> 16) & 0x0000ffff;
54 idt[i].pc_high = trap_table[63] >> 32;
55
56 idt[i].cs = 0x0008;
57 idt[i].type = 0x8E;
58
59 idt[i].ist = 0;
60 idt[i]._unused1 = 0;
61 }
62
63 // Double fault handler
64 idt[T_NMI].ist = 0x01;
65 idt[T_DF].ist = 0x01;
66 idt[T_GP].ist = 0x01;
67 idt[T_NP].ist = 0x01;
68 idt[T_SS].ist = 0x01;
69
70 // Enable Breakpoint and Syscall from Userspace
71 idt[T_DB].type = 0xEE;
72 idt[T_BP].type = 0xEE;
73 idt[T_SYSCALL].type = 0xEE;
74
76 idtdesc.lim = sizeof(idt) - 1;
77
78 lidt(&idtdesc);
79
80 // Zero out interrupt stats
81 for (i = 0; i < 256; i++) {
82 intStats[i] = 0;
83 }
84
85 kprintf("Done!\n");
86}
87
88void
90{
91 lidt(&idtdesc);
92}
93
94void
96{
97 kprintf("CPU %d\n", CPU());
98 kprintf("Interrupt %d Error Code: %016llx\n",
99 tf->vector, tf->errcode);
100 kprintf("cr0: %016llx cr2: %016llx\n",
101 read_cr0(), read_cr2());
102 kprintf("cr3: %016llx cr4: %016llx\n",
103 read_cr3(), read_cr4());
104 kprintf("dr0: %016llx dr1: %016llx dr2: %016llx\n",
105 read_dr0(), read_dr1(), read_dr2());
106 kprintf("dr3: %016llx dr6: %016llx dr7: %016llx\n",
107 read_dr3(), read_dr6(), read_dr7());
108 kprintf("rip: %04x:%016llx rsp: %04x:%016llx\n",
109 tf->cs, tf->rip, tf->ss, tf->rsp);
110 kprintf("rflags: %016llx ds: %04x es: %04x fs: %04x gs: %04x\n",
111 tf->rflags, read_ds(), read_es(), read_fs(), read_gs());
112 kprintf("rax: %016llx rbx: %016llx rcx: %016llx\n",
113 tf->rax, tf->rbx, tf->rcx);
114 kprintf("rdx: %016llx rsi: %016llx rdi: %016llx\n",
115 tf->rdx, tf->rsi, tf->rdi);
116 kprintf("rbp: %016llx r8: %016llx r9: %016llx\n",
117 tf->rbp, tf->r8, tf->r9);
118 kprintf("r10: %016llx r11: %016llx r12: %016llx\n",
119 tf->r10, tf->r11, tf->r12);
120 kprintf("r13: %016llx r14: %016llx r15: %016llx\n",
121 tf->r13, tf->r14, tf->r15);
122}
123
124void
126{
127 uint64_t rsp;
128 uint64_t *data;
129
130 // XXX: This should use safe copy
131 for (rsp = tf->rsp; (rsp & 0xFFF) != 0; rsp += 8) {
132 data = (uint64_t *)rsp;
133 kprintf("%016llx: %016llx\n", rsp, *data);
134 }
135}
136
137extern int copy_unsafe(void *to, void *from, uintptr_t len);
138extern void copy_unsafe_done(void);
139extern void copy_unsafe_fault(void);
140
141extern int copystr_unsafe(void *to, void *from, uintptr_t len);
142extern void copystr_unsafe_done(void);
143extern void copystr_unsafe_fault(void);
144
145void
147{
148 // XXX: USE ATOMIC!
149 intStats[tf->vector]++;
150
151 // Debug NMI
152 if (tf->vector == T_NMI) {
154 kprintf("Kernel Fault: Vector %d\n", tf->vector);
155 Trap_Dump(tf);
157 return;
158 }
159
160 // Kernel
161 if (tf->cs == SEL_KCS)
162 {
163 // Kernel Debugger
164 if (tf->vector == T_BP || tf->vector == T_DE) {
166 return;
167 }
168
169 // User IO
170 if ((tf->vector == T_PF) &&
171 (tf->rip >= (uint64_t)&copy_unsafe) &&
172 (tf->rip <= (uint64_t)&copy_unsafe_done)) {
173 kprintf("Faulted in copy_unsafe\n");
175 return;
176 }
177
178 // User IO
179 if ((tf->vector == T_PF) &&
180 (tf->rip >= (uint64_t)&copystr_unsafe) &&
181 (tf->rip <= (uint64_t)&copystr_unsafe_done)) {
182 kprintf("Faulted in copystr_unsafe\n");
184 return;
185 }
186
187 // Halt on kernel errors
188 if (tf->vector <= T_CPU_LAST)
189 {
191 kprintf("Kernel Fault: Vector %d\n", tf->vector);
192 Trap_Dump(tf);
194 while (1)
195 hlt();
196 }
197 }
198
199 // User space exceptions
200 switch (tf->vector)
201 {
202 case T_DE:
203 kprintf("Divide by Zero\n");
204 return;
205 case T_DB:
206 case T_BP:
207 case T_UD: {
208 kprintf("Userlevel breakpoint\n");
210 return;
211 }
212 case T_PF: {
213 Trap_Dump(tf);
214 Trap_StackDump(tf);
216 }
217 case T_SYSCALL: {
218 VLOG(syscall, "Syscall %016llx\n", tf->rdi);
219 tf->rax = Syscall_Entry(tf->rdi, tf->rsi, tf->rdx, tf->rcx, tf->r8, tf->r9);
220 VLOG(syscall, "Return %016llx\n", tf->rax);
221 return;
222 }
223 }
224
225 // IRQs
226 if (tf->vector >= T_IRQ_BASE && tf->vector <= T_IRQ_MAX)
227 {
230 if (tf->vector == T_IRQ_TIMER) {
233 }
234
235 return;
236 }
237
238 // Debug IPI
239 if (tf->vector == T_DEBUGIPI) {
240 Debug_HaltIPI(tf);
242 }
243
244 // Cross calls
245 if (tf->vector == T_CROSSCALL)
246 {
249 return;
250 }
251
252 // LAPIC Special Vectors
253 if (tf->vector == T_IRQ_SPURIOUS)
254 {
255 kprintf("Spurious Interrupt!\n");
256 return;
257 }
258 if (tf->vector == T_IRQ_ERROR)
259 {
260 kprintf("LAPIC Error!\n");
261 while (1)
262 hlt();
263 }
264 if (tf->vector == T_IRQ_THERMAL)
265 {
266 kprintf("Thermal Error!\n");
267 while (1)
268 hlt();
269 }
270
271 kprintf("Unhandled Interrupt 0x%x!\n", tf->vector);
272 Trap_Dump(tf);
273 while (1)
274 hlt();
275}
276
277static void
278Debug_Traps(int argc, const char *argv[])
279{
280 int i;
281
282 kprintf("Trap Interrupts Trap Interrupts\n");
283 for (i = 0; i < T_MAX / 2; i++)
284 {
285 kprintf("%-4d %-12d %-4d %-12d\n",
286 i, intStats[i],
287 T_MAX / 2 + i, intStats[T_MAX / 2 + i]);
288 }
289}
290
291REGISTER_DBGCMD(traps, "Print trap statistics", Debug_Traps);
292
void MP_CrossCallTrap()
Definition: mp.c:140
uint64_t off
Definition: amd64.h:64
uint8_t type
Definition: amd64.h:96
uint16_t cs
Definition: amd64.h:94
uint32_t pc_high
Definition: amd64.h:98
uint16_t pc_low
Definition: amd64.h:93
#define SEL_KCS
Definition: amd64.h:80
uint16_t pc_mid
Definition: amd64.h:97
uint32_t _unused1
Definition: amd64.h:99
uint8_t ist
Definition: amd64.h:95
uint16_t lim
Definition: amd64.h:63
static INLINE uint64_t read_dr1()
Definition: amd64op.h:211
static INLINE void hlt()
Definition: amd64op.h:19
static INLINE uint16_t read_es()
Definition: amd64op.h:317
static INLINE uint16_t read_ds()
Definition: amd64op.h:300
static INLINE uint64_t read_cr2()
Definition: amd64op.h:146
static INLINE uint16_t read_fs()
Definition: amd64op.h:334
static INLINE uint64_t read_cr3()
Definition: amd64op.h:156
static INLINE uint64_t read_dr3()
Definition: amd64op.h:245
static INLINE uint64_t read_dr7()
Definition: amd64op.h:279
static INLINE uint64_t read_dr6()
Definition: amd64op.h:262
static INLINE uint16_t read_gs()
Definition: amd64op.h:351
static INLINE uint64_t read_cr4()
Definition: amd64op.h:173
static INLINE void lidt(PseudoDescriptor *idt)
Definition: amd64op.h:62
static INLINE uint64_t read_cr0()
Definition: amd64op.h:129
static INLINE uint64_t read_dr0()
Definition: amd64op.h:194
static INLINE uint64_t read_dr2()
Definition: amd64op.h:228
void Critical_Enter()
Definition: critical.c:28
#define CPU
Definition: mp.h:7
void Sched_Scheduler()
Definition: sched.c:189
void IRQ_Handler(int irq)
Definition: irq.c:25
#define VLOG(_module, _format,...)
Definition: kassert.h:42
int kprintf(const char *fmt,...)
Definition: printf.c:210
#define REGISTER_DBGCMD(_NAME, _DESC, _FUNC)
Definition: kdebug.h:11
void LAPIC_SendEOI()
Definition: lapic.c:102
uint64_t len
Definition: multiboot.h:2
uint64_t Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5)
Definition: syscall.c:673
void copy_unsafe_done(void)
int copystr_unsafe(void *to, void *from, uintptr_t len)
static uint64_t intStats[256]
Definition: trap.c:30
void trap_entry(TrapFrame *tf)
Definition: trap.c:146
void copy_unsafe_fault(void)
void Debug_HaltIPI(TrapFrame *tf)
Definition: debug.c:51
int copy_unsafe(void *to, void *from, uintptr_t len)
void Trap_InitAP()
Definition: trap.c:89
void Trap_StackDump(TrapFrame *tf)
Definition: trap.c:125
static InteruptGate64 idt[256]
Definition: trap.c:28
void Debug_Breakpoint(TrapFrame *tf)
Definition: debug.c:67
void KTimer_Process()
Definition: ktimer.c:88
void trap_pop(TrapFrame *tf)
void copystr_unsafe_done(void)
void Trap_Dump(TrapFrame *tf)
Definition: trap.c:95
static void Debug_Traps(int argc, const char *argv[])
Definition: trap.c:278
void copystr_unsafe_fault(void)
static PseudoDescriptor idtdesc
Definition: trap.c:29
void Trap_Init()
Definition: trap.c:33
uint64_t trap_table[T_MAX]
uint16_t cs
Definition: trap.h:73
#define T_PF
Definition: trap.h:18
#define T_SS
Definition: trap.h:16
#define T_DF
Definition: trap.h:13
#define T_GP
Definition: trap.h:17
#define T_DE
Definition: trap.h:5
uint64_t r8
Definition: trap.h:59
#define T_DEBUGIPI
Definition: trap.h:44
uint64_t r15
Definition: trap.h:52
uint64_t rsi
Definition: trap.h:62
uint64_t rbp
Definition: trap.h:60
uint16_t ss
Definition: trap.h:79
#define T_UD
Definition: trap.h:11
uint64_t rsp
Definition: trap.h:78
uint64_t r12
Definition: trap.h:55
#define T_CPU_LAST
Definition: trap.h:25
#define T_BP
Definition: trap.h:8
#define T_DB
Definition: trap.h:6
uint64_t rbx
Definition: trap.h:65
#define T_NMI
Definition: trap.h:7
uint64_t rip
Definition: trap.h:72
#define T_IRQ_TIMER
Definition: trap.h:32
#define T_SYSCALL
Definition: trap.h:42
#define T_NP
Definition: trap.h:15
uint64_t rdi
Definition: trap.h:61
uint64_t rax
Definition: trap.h:67
#define T_IRQ_BASE
Definition: trap.h:28
uint64_t r14
Definition: trap.h:53
uint64_t vector
Definition: trap.h:69
#define T_IRQ_ERROR
Definition: trap.h:39
uint64_t rcx
Definition: trap.h:64
uint32_t errcode
Definition: trap.h:70
#define T_IRQ_THERMAL
Definition: trap.h:40
uint64_t r10
Definition: trap.h:57
#define T_IRQ_MAX
Definition: trap.h:30
uint64_t r13
Definition: trap.h:54
#define T_MAX
Definition: trap.h:48
uint64_t r9
Definition: trap.h:58
uint64_t rflags
Definition: trap.h:77
#define T_CROSSCALL
Definition: trap.h:43
uint64_t rdx
Definition: trap.h:63
uint64_t r11
Definition: trap.h:56
#define T_IRQ_SPURIOUS
Definition: trap.h:38
Definition: trap.h:51
uint64_t uintptr_t
Definition: types.h:16
unsigned long uint64_t
Definition: types.h:13
int syscall(int number,...)