root/trap.c

/* [previous][next][first][last][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)
     /* [previous][next][first][last][top][bottom][index][help]  */
  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)
     /* [previous][next][first][last][top][bottom][index][help]  */
  31 {
  32   lidt(idt, sizeof(idt));
  33 }
  34 
  35 //PAGEBREAK: 41
  36 void
  37 trap(struct trapframe *tf)
     /* [previous][next][first][last][top][bottom][index][help]  */
  38 {
  39   if(tf->trapno == T_SYSCALL){
  40     if(myproc()->killed)
  41       exit();
  42     myproc()->tf = tf;
  43     syscall();
  44     if(myproc()->killed)
  45       exit();
  46     return;
  47   }
  48 
  49   switch(tf->trapno){
  50   case T_IRQ0 + IRQ_TIMER:
  51     if(cpuid() == 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             cpuid(), tf->cs, tf->eip);
  78     lapiceoi();
  79     break;
  80 
  81   //PAGEBREAK: 13
  82   default:
  83     if(myproc() == 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, cpuid(), 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             myproc()->pid, myproc()->name, tf->trapno,
  93             tf->err, cpuid(), tf->eip, rcr2());
  94     myproc()->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(myproc() && myproc()->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(myproc() && myproc()->state == RUNNING &&
 106      tf->trapno == T_IRQ0+IRQ_TIMER)
 107     yield();
 108 
 109   // Check if the process has been killed since we yielded
 110   if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER)
 111     exit();
 112 }

/* [previous][next][first][last][top][bottom][index][help]  */