struct spinlock;
struct stat;
struct superblock;
+struct ioapic;
// bio.c
void binit(void);
// ioapic.c
void ioapicenable(int irq, int cpu);
extern uchar ioapicid;
+extern volatile struct ioapic* ioapic;
void ioapicinit(void);
// kalloc.c
#define REG_TABLE 0x10 // Redirection table base
// The redirection table starts at REG_TABLE and uses
-// two registers to configure each interrupt.
+// two registers to configure each interrupt.
// The first (low) register in a pair contains configuration bits.
// The second (high) register contains a bitmask telling which
// CPUs can serve that interrupt.
#define INT_ACTIVELOW 0x00002000 // Active low (vs high)
#define INT_LOGICAL 0x00000800 // Destination is CPU id (vs APIC ID)
-volatile struct ioapic *ioapic;
+volatile struct ioapic *ioapic; // Initialized in mp.c
// IO APIC MMIO structure: write reg, then read or write data.
struct ioapic {
if(!ismp)
return;
- ioapic = (volatile struct ioapic*)IOAPIC;
+ if(ioapic == 0) {
+ ioapic = (volatile struct ioapic*)IOAPIC;
+ cprintf("ioapicinit: falling back to default ioapic address\n");
+ }
maxintr = (ioapicread(REG_VER) >> 16) & 0xFF;
id = ioapicread(REG_ID) >> 24;
if(id != ioapicid)
struct mp *mp;
struct mpconf *conf;
struct mpproc *proc;
- struct mpioapic *ioapic;
+ struct mpioapic *mioapic;
if((conf = mpconfig(&mp)) == 0)
return;
p += sizeof(struct mpproc);
continue;
case MPIOAPIC:
- ioapic = (struct mpioapic*)p;
- if(!(ioapic->flags & MP_APIC_ENABLED)){
- cprintf("mpinit: ioapic %d disabled, ignored\n", ioapic->apicid);
+ mioapic = (struct mpioapic*)p;
+ if(!(mioapic->flags & MP_APIC_ENABLED)){
+ cprintf("mpinit: ioapic %d disabled, ignored\n", mioapic->apicid);
p += sizeof(struct mpioapic);
continue;
}
- ioapicid = ioapic->apicid;
+ if(ioapic == 0){
+ ioapic = (volatile struct ioapic*)mioapic->addr;
+ ioapicid = mioapic->apicid;
+ } else {
+ cprintf("mpinit: ignored extra ioapic %d\n", mioapic->apicid);
+ }
p += sizeof(struct mpioapic);
continue;
case MPBUS:
// Didn't like what we found; fall back to no MP.
ncpu = 1;
lapic = 0;
+ ioapic = 0;
ioapicid = 0;
return;
}