xv6

port of xv6 to x86-64
git clone http://frotz.net/git/xv6.git
Log | Files | Refs | README | LICENSE

trap.c (2627B)


      1 #include "types.h"
      2 #include "defs.h"
      3 #include "param.h"
      4 #include "memlayout.h"
      5 #include "mmu.h"
      6 #include "proc.h"
      7 #include "x86.h"
      8 #include "traps.h"
      9 #include "spinlock.h"
     10 
     11 // Interrupt descriptor table (shared by all CPUs).
     12 struct gatedesc idt[256];
     13 extern uintp vectors[];  // in vectors.S: array of 256 entry pointers
     14 struct spinlock tickslock;
     15 uint ticks;
     16 
     17 #ifndef X64
     18 void
     19 tvinit(void)
     20 {
     21   int i;
     22 
     23   for(i = 0; i < 256; i++)
     24     SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0);
     25   SETGATE(idt[T_SYSCALL], 1, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER);
     26   
     27   initlock(&tickslock, "time");
     28 }
     29 
     30 void
     31 idtinit(void)
     32 {
     33   lidt(idt, sizeof(idt));
     34 }
     35 #endif
     36 
     37 //PAGEBREAK: 41
     38 void
     39 trap(struct trapframe *tf)
     40 {
     41   if(tf->trapno == T_SYSCALL){
     42     if(proc->killed)
     43       exit();
     44     proc->tf = tf;
     45     syscall();
     46     if(proc->killed)
     47       exit();
     48     return;
     49   }
     50 
     51   switch(tf->trapno){
     52   case T_IRQ0 + IRQ_TIMER:
     53     if(cpu->id == 0){
     54       acquire(&tickslock);
     55       ticks++;
     56       wakeup(&ticks);
     57       release(&tickslock);
     58     }
     59     lapiceoi();
     60     break;
     61   case T_IRQ0 + IRQ_IDE:
     62     ideintr();
     63     lapiceoi();
     64     break;
     65   case T_IRQ0 + IRQ_IDE+1:
     66     // Bochs generates spurious IDE1 interrupts.
     67     break;
     68   case T_IRQ0 + IRQ_KBD:
     69     kbdintr();
     70     lapiceoi();
     71     break;
     72   case T_IRQ0 + IRQ_COM1:
     73     uartintr();
     74     lapiceoi();
     75     break;
     76   case T_IRQ0 + 7:
     77   case T_IRQ0 + IRQ_SPURIOUS:
     78     cprintf("cpu%d: spurious interrupt at %x:%x\n",
     79             cpu->id, tf->cs, tf->eip);
     80     lapiceoi();
     81     break;
     82    
     83   //PAGEBREAK: 13
     84   default:
     85     if(proc == 0 || (tf->cs&3) == 0){
     86       // In kernel, it must be our mistake.
     87       cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n",
     88               tf->trapno, cpu->id, tf->eip, rcr2());
     89       panic("trap");
     90     }
     91     // In user space, assume process misbehaved.
     92     cprintf("pid %d %s: trap %d err %d on cpu %d "
     93             "eip 0x%x addr 0x%x--kill proc\n",
     94             proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip, 
     95             rcr2());
     96     proc->killed = 1;
     97   }
     98 
     99   // Force process exit if it has been killed and is in user space.
    100   // (If it is still executing in the kernel, let it keep running 
    101   // until it gets to the regular system call return.)
    102   if(proc && proc->killed && (tf->cs&3) == DPL_USER)
    103     exit();
    104 
    105   // Force process to give up CPU on clock tick.
    106   // If interrupts were on while locks held, would need to check nlock.
    107   if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER)
    108     yield();
    109 
    110   // Check if the process has been killed since we yielded
    111   if(proc && proc->killed && (tf->cs&3) == DPL_USER)
    112     exit();
    113 }