Xv6 with picoc & Linkage editor  v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
ioapic.c
00001 // The I/O APIC manages hardware interrupts for an SMP system.
00002 // http://www.intel.com/design/chipsets/datashts/29056601.pdf
00003 // See also picirq.c.
00004 
00005 #include "types.h"
00006 #include "defs.h"
00007 #include "traps.h"
00008 
00009 #define IOAPIC  0xFEC00000   // Default physical address of IO APIC
00010 
00011 #define REG_ID     0x00  // Register index: ID
00012 #define REG_VER    0x01  // Register index: version
00013 #define REG_TABLE  0x10  // Redirection table base
00014 
00015 // The redirection table starts at REG_TABLE and uses
00016 // two registers to configure each interrupt.  
00017 // The first (low) register in a pair contains configuration bits.
00018 // The second (high) register contains a bitmask telling which
00019 // CPUs can serve that interrupt.
00020 #define INT_DISABLED   0x00010000  // Interrupt disabled
00021 #define INT_LEVEL      0x00008000  // Level-triggered (vs edge-)
00022 #define INT_ACTIVELOW  0x00002000  // Active low (vs high)
00023 #define INT_LOGICAL    0x00000800  // Destination is CPU id (vs APIC ID)
00024 
00025 volatile struct ioapic *ioapic;
00026 
00027 // IO APIC MMIO structure: write reg, then read or write data.
00028 struct ioapic {
00029   uint reg;
00030   uint pad[3];
00031   uint data;
00032 };
00033 
00034 static uint
00035 ioapicread(int reg)
00036 {
00037   ioapic->reg = reg;
00038   return ioapic->data;
00039 }
00040 
00041 static void
00042 ioapicwrite(int reg, uint data)
00043 {
00044   ioapic->reg = reg;
00045   ioapic->data = data;
00046 }
00047 
00048 void
00049 ioapicinit(void)
00050 {
00051   int i, id, maxintr;
00052 
00053   if(!ismp)
00054     return;
00055 
00056   ioapic = (volatile struct ioapic*)IOAPIC;
00057   maxintr = (ioapicread(REG_VER) >> 16) & 0xFF;
00058   id = ioapicread(REG_ID) >> 24;
00059   if(id != ioapicid)
00060     cprintf("ioapicinit: id isn't equal to ioapicid; not a MP\n");
00061 
00062   // Mark all interrupts edge-triggered, active high, disabled,
00063   // and not routed to any CPUs.
00064   for(i = 0; i <= maxintr; i++){
00065     ioapicwrite(REG_TABLE+2*i, INT_DISABLED | (T_IRQ0 + i));
00066     ioapicwrite(REG_TABLE+2*i+1, 0);
00067   }
00068 }
00069 
00070 void
00071 ioapicenable(int irq, int cpunum)
00072 {
00073   if(!ismp)
00074     return;
00075 
00076   // Mark interrupt edge-triggered, active high,
00077   // enabled, and routed to the given cpunum,
00078   // which happens to be that cpu's APIC ID.
00079   ioapicwrite(REG_TABLE+2*irq, T_IRQ0 + irq);
00080   ioapicwrite(REG_TABLE+2*irq+1, cpunum << 24);
00081 }
 All Data Structures