root/ioapic.c

/* [previous][next][first][last][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)
     /* [previous][next][first][last][top][bottom][index][help]  */
  36 {
  37   ioapic->reg = reg;
  38   return ioapic->data;
  39 }
  40 
  41 static void
  42 ioapicwrite(int reg, uint data)
     /* [previous][next][first][last][top][bottom][index][help]  */
  43 {
  44   ioapic->reg = reg;
  45   ioapic->data = data;
  46 }
  47 
  48 void
  49 ioapicinit(void)
     /* [previous][next][first][last][top][bottom][index][help]  */
  50 {
  51   int i, id, maxintr;
  52 
  53   ioapic = (volatile struct ioapic*)IOAPIC;
  54   maxintr = (ioapicread(REG_VER) >> 16) & 0xFF;
  55   id = ioapicread(REG_ID) >> 24;
  56   if(id != ioapicid)
  57     cprintf("ioapicinit: id isn't equal to ioapicid; not a MP\n");
  58 
  59   // Mark all interrupts edge-triggered, active high, disabled,
  60   // and not routed to any CPUs.
  61   for(i = 0; i <= maxintr; i++){
  62     ioapicwrite(REG_TABLE+2*i, INT_DISABLED | (T_IRQ0 + i));
  63     ioapicwrite(REG_TABLE+2*i+1, 0);
  64   }
  65 }
  66 
  67 void
  68 ioapicenable(int irq, int cpunum)
     /* [previous][next][first][last][top][bottom][index][help]  */
  69 {
  70   // Mark interrupt edge-triggered, active high,
  71   // enabled, and routed to the given cpunum,
  72   // which happens to be that cpu's APIC ID.
  73   ioapicwrite(REG_TABLE+2*irq, T_IRQ0 + irq);
  74   ioapicwrite(REG_TABLE+2*irq+1, cpunum << 24);
  75 }

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