xref: /xv6-public/trap.c (revision 6f2b626d)
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 struct Gatedesc idt[256];
11 struct Pseudodesc idt_pd = { 0, sizeof(idt) - 1, (unsigned) &idt };
12 extern unsigned vectors[]; /* vectors.S, array of 256 entry point addresses */
13 
14 extern void trapenter();
15 extern void trapenter1();
16 
17 void
18 tvinit()
19 {
20   int i;
21 
22   for(i = 0; i < 256; i++){
23     SETGATE(idt[i], 1, SEG_KCODE << 3, vectors[i], 0);
24   }
25   SETGATE(idt[T_SYSCALL], T_SYSCALL, SEG_KCODE << 3, vectors[48], 3);
26 }
27 
28 void
29 idtinit()
30 {
31   asm volatile("lidt %0" : : "g" (idt_pd.pd_lim));
32 }
33 
34 void
35 trap(struct Trapframe *tf)
36 {
37   int v = tf->tf_trapno;
38 
39   if(v == T_SYSCALL){
40     struct proc *cp = curproc[cpu()];
41     int num = cp->tf->tf_regs.reg_eax;
42     if(cp == 0)
43       panic("syscall with no proc");
44     if(cp->killed)
45       proc_exit();
46     cp->tf = tf;
47     syscall();
48     if(cp != curproc[cpu()])
49       panic("trap ret wrong curproc");
50     if(cp->state != RUNNING)
51       panic("trap ret but not RUNNING");
52     if(tf != cp->tf)
53       panic("trap ret wrong tf");
54     if(cpus[cpu()].nlock){
55       cprintf("num=%d\n", num);
56       panic("syscall returning locks held");
57     }
58     if((read_eflags() & FL_IF) == 0)
59       panic("syscall returning but FL_IF clear");
60     if(read_esp() < (unsigned)cp->kstack ||
61        read_esp() >= (unsigned)cp->kstack + KSTACKSIZE)
62       panic("trap ret esp wrong");
63     if(cp->killed)
64       proc_exit();
65     return;
66   }
67 
68   if(v == (IRQ_OFFSET + IRQ_TIMER)){
69     struct proc *cp = curproc[cpu()];
70     lapic_timerintr();
71     if(cpus[cpu()].nlock)
72       panic("timer interrupt while holding a lock");
73     if(cp){
74       if((read_eflags() & FL_IF) == 0)
75         panic("timer interrupt but interrupts now disabled");
76       if(cp->killed)
77         proc_exit();
78       if(cp->state == RUNNING)
79         yield();
80     }
81     return;
82   }
83 
84   if(v == (IRQ_OFFSET + IRQ_IDE)){
85     ide_intr();
86     return;
87   }
88 
89 
90   // XXX probably ought to lgdt on trap return
91 
92   return;
93 }
94