* same with xv6
[mascara-docs.git] / i386 / ucla / src / lab2 / kern / trap.c
blob7e873c26481b7bb3cba065edb62740cd692253cc
1 #include <inc/mmu.h>
2 #include <inc/x86.h>
3 #include <inc/assert.h>
5 #include <kern/pmap.h>
6 #include <kern/trap.h>
7 #include <kern/console.h>
8 #include <kern/monitor.h>
10 static struct Taskstate ts;
12 /* Interrupt descriptor table. (Must be built at run time because
13 * shifted function addresses can't be represented in relocation records.)
15 struct Gatedesc idt[256] = { { 0 } };
16 struct Pseudodesc idt_pd = {
17 sizeof(idt) - 1, (uint32_t) idt
21 static const char *trapname(int trapno)
23 static const char * const excnames[] = {
24 "Divide error",
25 "Debug",
26 "Non-Maskable Interrupt",
27 "Breakpoint",
28 "Overflow",
29 "BOUND Range Exceeded",
30 "Invalid Opcode",
31 "Device Not Available",
32 "Double Fault",
33 "Coprocessor Segment Overrun",
34 "Invalid TSS",
35 "Segment Not Present",
36 "Stack Fault",
37 "General Protection",
38 "Page Fault",
39 "(unknown trap)",
40 "x87 FPU Floating-Point Error",
41 "Alignment Check",
42 "Machine-Check",
43 "SIMD Floating-Point Exception"
46 if (trapno < (int) (sizeof(excnames)/sizeof(excnames[0])))
47 return excnames[trapno];
48 if (trapno == T_SYSCALL)
49 return "System call";
50 return "(unknown trap)";
54 void
55 idt_init(void)
57 extern struct Segdesc gdt[];
59 // LAB 2: Your code here.
61 // Setup a TSS so that we get the right stack
62 // when we trap to the kernel.
63 ts.ts_esp0 = KSTACKTOP;
64 ts.ts_ss0 = GD_KD;
66 // Initialize the TSS field of the gdt.
67 gdt[GD_TSS >> 3] = SEG16(STS_T32A, (uint32_t) (&ts),
68 sizeof(struct Taskstate), 0);
69 gdt[GD_TSS >> 3].sd_s = 0;
71 // Load the TSS
72 ltr(GD_TSS);
74 // Load the IDT
75 asm volatile("lidt idt_pd");
79 void
80 print_trapframe(struct Trapframe *tf)
82 cprintf("TRAP frame at %p\n", tf);
83 print_regs(&tf->tf_regs);
84 cprintf(" es 0x----%04x\n", tf->tf_es);
85 cprintf(" ds 0x----%04x\n", tf->tf_ds);
86 cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
87 cprintf(" err 0x%08x\n", tf->tf_err);
88 cprintf(" eip 0x%08x\n", tf->tf_eip);
89 cprintf(" cs 0x----%04x\n", tf->tf_cs);
90 cprintf(" flag 0x%08x\n", tf->tf_eflags);
91 cprintf(" esp 0x%08x\n", tf->tf_esp);
92 cprintf(" ss 0x----%04x\n", tf->tf_ss);
95 void
96 print_regs(struct PushRegs *regs)
98 cprintf(" edi 0x%08x\n", regs->reg_edi);
99 cprintf(" esi 0x%08x\n", regs->reg_esi);
100 cprintf(" ebp 0x%08x\n", regs->reg_ebp);
101 cprintf(" oesp 0x%08x\n", regs->reg_oesp);
102 cprintf(" ebx 0x%08x\n", regs->reg_ebx);
103 cprintf(" edx 0x%08x\n", regs->reg_edx);
104 cprintf(" ecx 0x%08x\n", regs->reg_ecx);
105 cprintf(" eax 0x%08x\n", regs->reg_eax);
108 static void
109 trap_dispatch(struct Trapframe *tf)
111 // Handle the breakpoint exception.
112 // LAB 2: Your code here.
115 // Unexpected trap: The user process or the kernel has a bug.
116 print_trapframe(tf);
117 if (tf->tf_cs == GD_KT)
118 panic("unhandled trap in kernel");
119 else
120 panic("unhandled trap in user mode");
123 asmlinkage void
124 trap(struct Trapframe *tf)
126 // The environment may have set DF and some versions
127 // of GCC rely on DF being clear
128 asm volatile("cld" : : : "cc");
130 // Check that interrupts are disabled. If this assertion
131 // fails, DO NOT be tempted to fix it by inserting a "cli" in
132 // the interrupt path.
133 assert(!(read_eflags() & FL_IF));
135 // Dispatch based on what type of trap occurred
136 trap_dispatch(tf);