00001 #include "types.h"
00002 #include "defs.h"
00003 #include "param.h"
00004 #include "mmu.h"
00005 #include "proc.h"
00006 #include "x86.h"
00007 #include "traps.h"
00008 #include "spinlock.h"
00009
00010
00011 struct gatedesc idt[256];
00012 extern uint vectors[];
00013 struct spinlock tickslock;
00014 int ticks;
00015
00016 void
00017 tvinit(void)
00018 {
00019 int i;
00020
00021 for(i = 0; i < 256; i++)
00022 SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0);
00023 SETGATE(idt[T_SYSCALL], 1, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER);
00024
00025 initlock(&tickslock, "time");
00026 }
00027
00028 void
00029 idtinit(void)
00030 {
00031 lidt(idt, sizeof(idt));
00032 }
00033
00034 void
00035 trap(struct trapframe *tf)
00036 {
00037 if(tf->trapno == T_SYSCALL){
00038 if(proc->killed)
00039 exit();
00040 proc->tf = tf;
00041 syscall();
00042 if(proc->killed)
00043 exit();
00044 return;
00045 }
00046
00047 switch(tf->trapno){
00048 case T_IRQ0 + IRQ_TIMER:
00049 if(cpu->id == 0){
00050 acquire(&tickslock);
00051 ticks++;
00052 wakeup(&ticks);
00053 release(&tickslock);
00054 }
00055 lapiceoi();
00056 break;
00057 case T_IRQ0 + IRQ_IDE:
00058 ideintr();
00059 lapiceoi();
00060 break;
00061 case T_IRQ0 + IRQ_KBD:
00062 kbdintr();
00063 lapiceoi();
00064 break;
00065 case T_IRQ0 + IRQ_COM1:
00066 uartintr();
00067 lapiceoi();
00068 break;
00069 case T_IRQ0 + 7:
00070 case T_IRQ0 + IRQ_SPURIOUS:
00071 cprintf("cpu%d: spurious interrupt at %x:%x\n",
00072 cpu->id, tf->cs, tf->eip);
00073 lapiceoi();
00074 break;
00075
00076 default:
00077 if(proc == 0 || (tf->cs&3) == 0){
00078
00079 cprintf("unexpected trap %d from cpu %d eip %x\n",
00080 tf->trapno, cpu->id, tf->eip);
00081 panic("trap");
00082 }
00083
00084 cprintf("pid %d %s: trap %d err %d on cpu %d eip %x -- kill proc\n",
00085 proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip);
00086 proc->killed = 1;
00087 }
00088
00089
00090
00091
00092 if(proc && proc->killed && (tf->cs&3) == DPL_USER)
00093 exit();
00094
00095
00096
00097 if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER)
00098 yield();
00099
00100
00101 if(proc && proc->killed && (tf->cs&3) == DPL_USER)
00102 exit();
00103 }