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