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 uint 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], 1, 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 //PAGEBREAK: 41 35 void 36 trap(struct trapframe *tf) 37 { 38 if(tf->trapno == T_SYSCALL){ 39 if(proc->killed) 40 exit(); 41 proc->tf = tf; 42 syscall(); 43 if(proc->killed) 44 exit(); 45 return; 46 } 47 48 switch(tf->trapno){ 49 case T_IRQ0 + IRQ_TIMER: 50 if(cpu->id == 0){ 51 acquire(&tickslock); 52 ticks++; 53 wakeup(&ticks); 54 release(&tickslock); 55 } 56 lapiceoi(); 57 break; 58 case T_IRQ0 + IRQ_IDE: 59 ideintr(); 60 lapiceoi(); 61 break; 62 case T_IRQ0 + IRQ_IDE+1: 63 // Bochs generates spurious IDE1 interrupts. 64 break; 65 case T_IRQ0 + IRQ_KBD: 66 kbdintr(); 67 lapiceoi(); 68 break; 69 case T_IRQ0 + IRQ_COM1: 70 uartintr(); 71 lapiceoi(); 72 break; 73 case T_IRQ0 + 7: 74 case T_IRQ0 + IRQ_SPURIOUS: 75 cprintf("cpu%d: spurious interrupt at %x:%x\n", 76 cpu->id, tf->cs, tf->eip); 77 lapiceoi(); 78 break; 79 80 //PAGEBREAK: 13 81 default: 82 if(proc == 0 || (tf->cs&3) == 0){ 83 // In kernel, it must be our mistake. 84 cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n", 85 tf->trapno, cpu->id, tf->eip, rcr2()); 86 panic("trap"); 87 } 88 // In user space, assume process misbehaved. 89 cprintf("pid %d %s: trap %d err %d on cpu %d " 90 "eip 0x%x addr 0x%x--kill proc\n", 91 proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip, 92 rcr2()); 93 proc->killed = 1; 94 } 95 96 // Force process exit if it has been killed and is in user space. 97 // (If it is still executing in the kernel, let it keep running 98 // until it gets to the regular system call return.) 99 if(proc && proc->killed && (tf->cs&3) == DPL_USER) 100 exit(); 101 102 // Force process to give up CPU on clock tick. 103 // If interrupts were on while locks held, would need to check nlock. 104 if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER) 105 yield(); 106 107 // Check if the process has been killed since we yielded 108 if(proc && proc->killed && (tf->cs&3) == DPL_USER) 109 exit(); 110 } 111