root/ioapic.c

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

DEFINITIONS

This source file includes following definitions.
  1. ioapicread
  2. ioapicwrite
  3. ioapicinit
  4. ioapicenable

   1 // The I/O APIC manages hardware interrupts for an SMP system.
   2 // http://www.intel.com/design/chipsets/datashts/29056601.pdf
   3 // See also picirq.c.
   4 
   5 #include "types.h"
   6 #include "defs.h"
   7 #include "traps.h"
   8 
   9 #define IOAPIC  0xFEC00000   // Default physical address of IO APIC
  10 
  11 #define REG_ID     0x00  // Register index: ID
  12 #define REG_VER    0x01  // Register index: version
  13 #define REG_TABLE  0x10  // Redirection table base
  14 
  15 // The redirection table starts at REG_TABLE and uses
  16 // two registers to configure each interrupt.  
  17 // The first (low) register in a pair contains configuration bits.
  18 // The second (high) register contains a bitmask telling which
  19 // CPUs can serve that interrupt.
  20 #define INT_DISABLED   0x00010000  // Interrupt disabled
  21 #define INT_LEVEL      0x00008000  // Level-triggered (vs edge-)
  22 #define INT_ACTIVELOW  0x00002000  // Active low (vs high)
  23 #define INT_LOGICAL    0x00000800  // Destination is CPU id (vs APIC ID)
  24 
  25 volatile struct ioapic *ioapic;
  26 
  27 // IO APIC MMIO structure: write reg, then read or write data.
  28 struct ioapic {
  29   uint reg;
  30   uint pad[3];
  31   uint data;
  32 };
  33 
  34 static uint
  35 ioapicread(int reg)
  36 {
  37   ioapic->reg = reg;
  38   return ioapic->data;
  39 }
  40 
  41 static void
  42 ioapicwrite(int reg, uint data)
  43 {
  44   ioapic->reg = reg;
  45   ioapic->data = data;
  46 }
  47 
  48 void
  49 ioapicinit(void)
  50 {
  51   int i, id, maxintr;
  52 
  53   if(!ismp)
  54     return;
  55 
  56   ioapic = (volatile struct ioapic*)IOAPIC;
  57   maxintr = (ioapicread(REG_VER) >> 16) & 0xFF;
  58   id = ioapicread(REG_ID) >> 24;
  59   if(id != ioapicid)
  60     cprintf("ioapicinit: id isn't equal to ioapicid; not a MP\n");
  61 
  62   // Mark all interrupts edge-triggered, active high, disabled,
  63   // and not routed to any CPUs.
  64   for(i = 0; i <= maxintr; i++){
  65     ioapicwrite(REG_TABLE+2*i, INT_DISABLED | (T_IRQ0 + i));
  66     ioapicwrite(REG_TABLE+2*i+1, 0);
  67   }
  68 }
  69 
  70 void
  71 ioapicenable(int irq, int cpunum)
  72 {
  73   if(!ismp)
  74     return;
  75 
  76   // Mark interrupt edge-triggered, active high,
  77   // enabled, and routed to the given cpunum,
  78   // which happens to be that cpu's APIC ID.
  79   ioapicwrite(REG_TABLE+2*irq, T_IRQ0 + irq);
  80   ioapicwrite(REG_TABLE+2*irq+1, cpunum << 24);
  81 }

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