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 extern uint vectors[]; /* vectors.S, array of 256 entry point addresses */ 12 13 extern void trapenter(void); 14 extern void trapenter1(void); 15 16 void 17 tvinit(void) 18 { 19 int i; 20 21 for(i = 0; i < 256; i++){ 22 SETGATE(idt[i], 1, SEG_KCODE << 3, vectors[i], 0); 23 } 24 SETGATE(idt[T_SYSCALL], 1, SEG_KCODE << 3, vectors[48], 3); 25 } 26 27 void 28 idtinit(void) 29 { 30 lidt(idt, sizeof idt); 31 } 32 33 void 34 trap(struct trapframe *tf) 35 { 36 int v = tf->trapno; 37 38 if(cpus[cpu()].nlock){ 39 cprintf("trap v %d eip %x cpu %d nlock %d\n", 40 v, tf->eip, cpu(), cpus[cpu()].nlock); 41 panic("interrupt while holding a lock"); 42 } 43 44 if(cpu() == 1 && curproc[cpu()] == 0){ 45 if(&tf < cpus[cpu()].mpstack || &tf > cpus[cpu()].mpstack + 512){ 46 cprintf("&tf %x mpstack %x\n", &tf, cpus[cpu()].mpstack); 47 panic("trap cpu stack"); 48 } 49 } else if(curproc[cpu()]){ 50 if(&tf < curproc[cpu()]->kstack){ 51 panic("trap kstack"); 52 } 53 } 54 55 if(v == T_SYSCALL){ 56 struct proc *cp = curproc[cpu()]; 57 int num = cp->tf->eax; 58 if((read_eflags() & FL_IF) == 0) 59 panic("syscall but interrupts now disabled"); 60 if(cp == 0) 61 panic("syscall with no proc"); 62 if(cp->killed) 63 proc_exit(); 64 cp->tf = tf; 65 syscall(); 66 if(cp != curproc[cpu()]) 67 panic("trap ret wrong curproc"); 68 if(cp->state != RUNNING) 69 panic("trap ret but not RUNNING"); 70 if(tf != cp->tf) 71 panic("trap ret wrong tf"); 72 if(cpus[cpu()].nlock){ 73 cprintf("num=%d\n", num); 74 panic("syscall returning locks held"); 75 } 76 if((read_eflags() & FL_IF) == 0) 77 panic("syscall returning but FL_IF clear"); 78 if(read_esp() < (uint)cp->kstack || 79 read_esp() >= (uint)cp->kstack + KSTACKSIZE) 80 panic("trap ret esp wrong"); 81 if(cp->killed) 82 proc_exit(); 83 // XXX probably ought to lgdt on trap return 84 return; 85 } 86 87 //if(read_eflags() & FL_IF) 88 //panic("interrupt but interrupts enabled"); 89 90 if(v == (IRQ_OFFSET + IRQ_TIMER)){ 91 struct proc *cp = curproc[cpu()]; 92 lapic_timerintr(); 93 if(cp){ 94 // Force process exit if it has been killed 95 // and the interrupt came from user space. 96 // (If the kernel was executing at time of interrupt, 97 // don't kill the process. Let the process get back 98 // out to its regular system call return.) 99 if((tf->cs&3) == 3 && cp->killed) 100 proc_exit(); 101 102 // Force process to give up CPU and let others run. 103 if(cp->state == RUNNING) 104 yield(); 105 } 106 return; 107 } 108 109 if(v == (IRQ_OFFSET + IRQ_IDE)){ 110 ide_intr(); 111 if(cpus[cpu()].nlock) 112 panic("ide_intr returned while holding a lock"); 113 cli(); // prevent a waiting interrupt from overflowing stack 114 lapic_eoi(); 115 return; 116 } 117 118 if(v == (IRQ_OFFSET + IRQ_KBD)){ 119 kbd_intr(); 120 if(cpus[cpu()].nlock){ 121 panic("kbd_intr returned while holding a lock"); 122 } 123 cli(); // prevent a waiting interrupt from overflowing stack 124 lapic_eoi(); 125 return; 126 } 127 128 cprintf("trap %d\n", v); 129 130 return; 131 } 132