xref: /xv6-public/trap.c (revision e9367434)
1 #include "types.h"
2 #include "param.h"
3 #include "mmu.h"
4 #include "proc.h"
5 #include "defs.h"
6 #include "x86.h"
7 #include "traps.h"
8 #include "syscall.h"
9 
10 // Interrupt descriptor table (shared by all CPUs).
11 struct gatedesc idt[256];
12 extern uint vectors[];  // in vectors.S: array of 256 entry pointers
13 
14 void
15 tvinit(void)
16 {
17   int i;
18 
19   for(i = 0; i < 256; i++)
20     SETGATE(idt[i], 0, SEG_KCODE << 3, vectors[i], 0);
21   SETGATE(idt[T_SYSCALL], 0, SEG_KCODE << 3, vectors[T_SYSCALL], 3);
22 }
23 
24 void
25 idtinit(void)
26 {
27   lidt(idt, sizeof idt);
28 }
29 
30 void
31 trap(struct trapframe *tf)
32 {
33   int v = tf->trapno;
34   struct proc *cp = curproc[cpu()];
35 
36   if(v == T_SYSCALL){
37     if(cp->killed)
38       proc_exit();
39     cp->tf = tf;
40     syscall();
41     if(cp->killed)
42       proc_exit();
43     return;
44   }
45 
46   // PAGEBREAK: 10
47   // Increment nlock to make sure interrupts stay off
48   // during interrupt handler.  Decrement before returning.
49   cpus[cpu()].nlock++;
50 
51   switch(v){
52   case IRQ_OFFSET + IRQ_TIMER:
53     lapic_timerintr();
54     cpus[cpu()].nlock--;
55     if(cp){
56       // Force process exit if it has been killed and is in user space.
57       // (If it is still executing in the kernel, let it keep running
58       // until it gets to the regular system call return.)
59       if((tf->cs&3) == 3 && cp->killed)
60         proc_exit();
61 
62       // Force process to give up CPU and let others run.
63       if(cp->state == RUNNING)
64         yield();
65     }
66     return;
67 
68   case IRQ_OFFSET + IRQ_IDE:
69     ide_intr();
70     lapic_eoi();
71     break;
72 
73   case IRQ_OFFSET + IRQ_KBD:
74     kbd_intr();
75     lapic_eoi();
76     break;
77 
78   case IRQ_OFFSET + IRQ_SPURIOUS:
79     cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip);
80     break;
81 
82   default:
83     if(curproc[cpu()]) {
84       // Assume process divided by zero or dereferenced null, etc.
85       cprintf("pid %d: unhandled trap %d on cpu %d eip %x -- kill proc\n",
86               curproc[cpu()]->pid, v, cpu(), tf->eip);
87       proc_exit();
88     }
89 
90     // Otherwise it's our mistake.
91     cprintf("unexpected trap %d from cpu %d eip %x\n", v, cpu(), tf->eip);
92     panic("trap");
93   }
94 
95   cpus[cpu()].nlock--;
96 }
97