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