* more re-work
[mascara-docs.git] / i386 / junos / standford / 2004 / src / lab5 / kern / trap.c
blob2200c903f59c734651838f23724dac6d07e20e00
2 #include <inc/mmu.h>
3 #include <inc/x86.h>
4 #include <inc/assert.h>
6 #include <kern/pmap.h>
7 #include <kern/trap.h>
8 #include <kern/env.h>
9 #include <kern/console.h>
10 #include <kern/syscall.h>
11 #include <kern/monitor.h>
12 #include <kern/sched.h>
13 #include <kern/kclock.h>
14 #include <kern/picirq.h>
16 u_int page_fault_mode = PFM_NONE;
17 static struct Taskstate ts;
19 /* Interrupt descriptor table. (Must be built at run time because
20 * shifted function addresses can't be represented in relocation records.)
22 struct Gatedesc idt[256] = { {0}, };
23 struct Pseudodesc idt_pd =
25 0, sizeof(idt) - 1, (unsigned long) idt,
29 static const char *trapname(int trapno)
31 static const char *excnames[] = {
32 "Divide error",
33 "Debug",
34 "Non-Maskable Interrupt",
35 "Breakpoint",
36 "Overflow",
37 "BOUND Range Exceeded",
38 "Invalid Opcode",
39 "Device Not Available",
40 "Double Falt",
41 "Coprocessor Segment Overrun",
42 "Invalid TSS",
43 "Segment Not Present",
44 "Stack Fault",
45 "General Protection",
46 "Page Fault",
47 "(unknown trap)",
48 "x87 FPU Floating-Point Error",
49 "Alignment Check",
50 "Machine-Check",
51 "SIMD Floating-Point Exception"
54 if (trapno < sizeof(excnames)/sizeof(excnames[0]))
55 return excnames[trapno];
56 if (trapno == T_SYSCALL)
57 return "System call";
59 return "(unknown trap)";
63 void
64 idt_init(void)
66 extern struct Segdesc gdt[];
68 // Setup a TSS so that we get the right stack
69 // when we trap to the kernel.
70 ts.ts_esp0 = KSTACKTOP;
71 ts.ts_ss0 = GD_KD;
73 // Love to put this code in the initialization of gdt,
74 // but the compiler generates an error incorrectly.
75 gdt[GD_TSS >> 3] = SEG16(STS_T32A, (u_long) (&ts),
76 sizeof(struct Taskstate), 0);
77 gdt[GD_TSS >> 3].sd_s = 0;
79 // Load the TSS
80 ltr(GD_TSS);
82 // Load the IDT
83 asm volatile("lidt idt_pd+2");
87 void
88 print_trapframe(struct Trapframe *tf)
90 printf("TRAP frame at %p\n", tf);
91 printf(" edi 0x%08x\n", tf->tf_edi);
92 printf(" esi 0x%08x\n", tf->tf_esi);
93 printf(" ebp 0x%08x\n", tf->tf_ebp);
94 printf(" oesp 0x%08x\n", tf->tf_oesp);
95 printf(" ebx 0x%08x\n", tf->tf_ebx);
96 printf(" edx 0x%08x\n", tf->tf_edx);
97 printf(" ecx 0x%08x\n", tf->tf_ecx);
98 printf(" eax 0x%08x\n", tf->tf_eax);
99 printf(" es 0x----%04x\n", tf->tf_es);
100 printf(" ds 0x----%04x\n", tf->tf_ds);
101 printf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
102 printf(" err 0x%08x\n", tf->tf_err);
103 printf(" eip 0x%08x\n", tf->tf_eip);
104 printf(" cs 0x----%04x\n", tf->tf_cs);
105 printf(" flag 0x%08x\n", tf->tf_eflags);
106 printf(" esp 0x%08x\n", tf->tf_esp);
107 printf(" ss 0x----%04x\n", tf->tf_ss);
110 void
111 trap(struct Trapframe *tf)
113 // print_trapframe(tf);
115 // Handle processor exceptions
116 // Your code here.
118 // Handle external interrupts
119 if (tf->tf_trapno == IRQ_OFFSET+0) {
120 // irq 0 -- clock interrupt
121 sched_yield();
123 if (tf->tf_trapno == IRQ_OFFSET+4) {
124 serial_intr();
125 return;
127 if (IRQ_OFFSET <= tf->tf_trapno
128 && tf->tf_trapno < IRQ_OFFSET+MAX_IRQS) {
129 // just ingore spurious interrupts
130 printf("spurious interrupt on irq %d\n",
131 tf->tf_trapno - IRQ_OFFSET);
132 print_trapframe(tf);
133 return;
136 // the user process or the kernel has a bug.
137 print_trapframe(tf);
138 if (tf->tf_cs == GD_KT)
139 panic("unhandled trap in kernel");
140 else {
141 env_destroy(curenv);
142 return;
147 void
148 page_fault_handler(struct Trapframe *tf)
150 u_int fault_va;
152 // Read processor's CR2 register to find the faulting address
153 fault_va = rcr2();
156 // User-mode exception - destroy the environment.
157 printf("[%08x] user fault va %08x ip %08x\n",
158 curenv->env_id, fault_va, tf->tf_eip);
159 print_trapframe(tf);
160 env_destroy(curenv);