root/trap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tvinit
  2. idtinit
  3. trap

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

/* [<][>][^][v][top][bottom][index][help] */