1*c8b29f6dSkaashoek #include "types.h" 2*c8b29f6dSkaashoek #include "mp.h" 3*c8b29f6dSkaashoek #include "defs.h" 4*c8b29f6dSkaashoek #include "x86.h" 5*c8b29f6dSkaashoek #include "traps.h" 6*c8b29f6dSkaashoek #include "ioapic.h" 7*c8b29f6dSkaashoek 8*c8b29f6dSkaashoek struct ioapic { 9*c8b29f6dSkaashoek uint ioregsel; uint p01; uint p02; uint p03; 10*c8b29f6dSkaashoek uint iowin; uint p11; uint p12; uint p13; 11*c8b29f6dSkaashoek }; 12*c8b29f6dSkaashoek 13*c8b29f6dSkaashoek 14*c8b29f6dSkaashoek #define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2) 15*c8b29f6dSkaashoek #define IOAPIC_REDTBL_HI(i) (IOAPIC_REDTBL_LO(i) + 1) 16*c8b29f6dSkaashoek 17*c8b29f6dSkaashoek static uint 18*c8b29f6dSkaashoek ioapic_read(struct ioapic *io, int reg) 19*c8b29f6dSkaashoek { 20*c8b29f6dSkaashoek io->ioregsel = reg; 21*c8b29f6dSkaashoek return (io->iowin); 22*c8b29f6dSkaashoek } 23*c8b29f6dSkaashoek 24*c8b29f6dSkaashoek static void 25*c8b29f6dSkaashoek ioapic_write(struct ioapic *io, int reg, uint val) 26*c8b29f6dSkaashoek { 27*c8b29f6dSkaashoek io->ioregsel = reg; 28*c8b29f6dSkaashoek io->iowin = val; 29*c8b29f6dSkaashoek } 30*c8b29f6dSkaashoek 31*c8b29f6dSkaashoek void 32*c8b29f6dSkaashoek ioapic_init(void) 33*c8b29f6dSkaashoek { 34*c8b29f6dSkaashoek struct ioapic *io; 35*c8b29f6dSkaashoek uint l, h; 36*c8b29f6dSkaashoek int nintr; 37*c8b29f6dSkaashoek uchar id; 38*c8b29f6dSkaashoek int i; 39*c8b29f6dSkaashoek 40*c8b29f6dSkaashoek io = (struct ioapic *) IO_APIC_BASE; 41*c8b29f6dSkaashoek l = ioapic_read(io, IOAPIC_VER); 42*c8b29f6dSkaashoek nintr = ((l & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1; 43*c8b29f6dSkaashoek id = ioapic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT; 44*c8b29f6dSkaashoek if (id != ioapic_id) 45*c8b29f6dSkaashoek panic ("ioapic_init: id isn't equal to ioapic_id\n"); 46*c8b29f6dSkaashoek cprintf ("ioapic VER: 0x%x id %d nintr %d\n", l, id, nintr); 47*c8b29f6dSkaashoek for (i = 0; i < nintr; i++) { 48*c8b29f6dSkaashoek // active-hi and edge-triggered for ISA interrupts 49*c8b29f6dSkaashoek // Assume that pin 0 on the first I/O APIC is an ExtINT pin. 50*c8b29f6dSkaashoek // Assume that pins 1-15 are ISA interrupts and that all 51*c8b29f6dSkaashoek l = ioapic_read(io, IOAPIC_REDTBL_LO(i)); 52*c8b29f6dSkaashoek l = l & ~IOART_INTMASK; // allow INTs 53*c8b29f6dSkaashoek l |= IOART_INTMSET; 54*c8b29f6dSkaashoek l = l & ~IOART_INTPOL; // active hi 55*c8b29f6dSkaashoek l = l & ~IOART_TRGRMOD; // edgee triggered 56*c8b29f6dSkaashoek l = l & ~IOART_DELMOD; // fixed 57*c8b29f6dSkaashoek l = l & ~IOART_DESTMOD; // physical mode 58*c8b29f6dSkaashoek l = l | (IRQ_OFFSET + i); // vector 59*c8b29f6dSkaashoek ioapic_write(io, IOAPIC_REDTBL_LO(i), l); 60*c8b29f6dSkaashoek h = ioapic_read(io, IOAPIC_REDTBL_HI(i)); 61*c8b29f6dSkaashoek h &= ~IOART_DEST; 62*c8b29f6dSkaashoek ioapic_write(io, IOAPIC_REDTBL_HI(i), h); 63*c8b29f6dSkaashoek // cprintf("intr %d: lo 0x%x hi 0x%x\n", i, l, h); 64*c8b29f6dSkaashoek } 65*c8b29f6dSkaashoek } 66*c8b29f6dSkaashoek 67*c8b29f6dSkaashoek void 68*c8b29f6dSkaashoek ioapic_enable (int irq, int cpu) 69*c8b29f6dSkaashoek { 70*c8b29f6dSkaashoek uint l, h; 71*c8b29f6dSkaashoek struct ioapic *io; 72*c8b29f6dSkaashoek 73*c8b29f6dSkaashoek io = (struct ioapic *) IO_APIC_BASE; 74*c8b29f6dSkaashoek l = ioapic_read(io, IOAPIC_REDTBL_LO(irq)); 75*c8b29f6dSkaashoek l = l & ~IOART_INTMASK; // allow INTs 76*c8b29f6dSkaashoek ioapic_write(io, IOAPIC_REDTBL_LO(irq), l); 77*c8b29f6dSkaashoek h = ioapic_read(io, IOAPIC_REDTBL_HI(irq)); 78*c8b29f6dSkaashoek h &= ~IOART_DEST; 79*c8b29f6dSkaashoek h |= (cpu << APIC_ID_SHIFT); // for fun, disk interrupts to cpu 1 80*c8b29f6dSkaashoek ioapic_write(io, IOAPIC_REDTBL_HI(irq), h); 81*c8b29f6dSkaashoek cprintf("intr %d: lo 0x%x hi 0x%x\n", irq, l, h); 82*c8b29f6dSkaashoek } 83