xref: /xv6-public/trap.c (revision 46bbd72f)
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(cpus[cpu()].clis){
40     cprintf("cpu %d v %d eip %x\n", cpu(), v, tf->tf_eip);
41     panic("interrupt while interrupts are off");
42   }
43 
44   if(v == T_SYSCALL){
45     struct proc *cp = curproc[cpu()];
46     int num = cp->tf->tf_regs.reg_eax;
47     if(cp == 0)
48       panic("syscall with no proc");
49     if(cp->killed)
50       proc_exit();
51     cp->tf = tf;
52     syscall();
53     if(cp != curproc[cpu()])
54       panic("trap ret wrong curproc");
55     if(cp->state != RUNNING)
56       panic("trap ret but not RUNNING");
57     if(tf != cp->tf)
58       panic("trap ret wrong tf");
59     if(cp->locks){
60       cprintf("num=%d\n", num);
61       panic("syscall returning locks held");
62     }
63     if(cpus[cpu()].clis)
64       panic("syscall returning but clis != 0");
65     if((read_eflags() & FL_IF) == 0)
66       panic("syscall returning but FL_IF clear");
67     if(read_esp() < (unsigned)cp->kstack ||
68        read_esp() >= (unsigned)cp->kstack + KSTACKSIZE)
69       panic("trap ret esp wrong");
70     if(cp->killed)
71       proc_exit();
72     return;
73   }
74 
75   if(v == (IRQ_OFFSET + IRQ_TIMER)){
76     struct proc *cp = curproc[cpu()];
77     lapic_timerintr();
78     if(cp && cp->locks)
79       panic("timer interrupt while holding a lock");
80     if(cp){
81 #if 1
82       if((read_eflags() & FL_IF) == 0)
83         panic("timer interrupt but interrupts now disabled");
84 #else
85       cpus[cpu()].clis += 1;
86       sti();
87 #endif
88       if(cp->killed)
89         proc_exit();
90       if(cp->state == RUNNING)
91         yield();
92     }
93     return;
94   }
95 
96   if(v == (IRQ_OFFSET + IRQ_IDE)){
97     ide_intr();
98     return;
99   }
100 
101 
102   // XXX probably ought to lgdt on trap return
103 
104   return;
105 }
106