public static void PrintApic(IoApic ioApic) { DebugStub.Print("Io Apic\n"); DebugStub.Print(" Id: {0:x2} Version: {1:x4} ArbitrationId: {2:x2}\n", __arglist( ioApic.GetId(), ioApic.GetVersion(), ioApic.GetArbitrationId())); for (uint i = 0; i < ioApic.RedirectionEntryCount; i++) { RedirectionEntry e = ioApic.GetRedirectionEntry(i); IoBits ib = (IoBits)((int)e.IoBits & ~(int)IoBits.DelModMask); DebugStub.Print(" IoRedTbl[{0:x2}]" + "Dst: {1:x2} IntVec: {2:x2} Control: {3} {4} {5} {6} {7} {8}" + "Delivery Mode ", __arglist( i, e.Destination, e.InterruptVector, ((ib & IoBits.DstLogical) != 0) ? "Logical" : "Physical", ((ib & IoBits.IrqMask) != 0) ? "Masked" : "Unmasked", ((ib & IoBits.TriggerModeMask) != 0) ? "Level" : "Edge", ((ib & IoBits.RemoteIRR) != 0) ? "Accept" : "Recv", ((ib & IoBits.IntPolMask) != 0) ? "Hi active" : "Lo active", ((ib & IoBits.DeliveryStatus) != 0) ? "Pending" : "Idle")); DescribeModMask(e.IoBits); } }
private void InitializeRouteableEntries() { DebugStub.Print("Initializing Apic routeable entries\n"); // Initialize entries that may not be part of MP set // configuration, but might be utilizable via a // programmable interrupt routing on PCI-LPC bridge // or elsewhere. byte irq = 16; IoBits stdPciBits = (IoBits.DstPhysical | IoBits.DelModFixed | IoBits.IrqMask | IoBits.IntPolActiveLow | IoBits.TriggerModeLevel); for (int id = 0; id < ioApics.Length; id++) { uint start = (id == 0) ? 16u : 0u; uint end = ioApics[id].RedirectionEntryCount; for (uint index = start; index < end; index++) { RedirectionEntry re = new RedirectionEntry(this.Id, stdPciBits, IrqToInterrupt(irq)); ioApics[id].SetRedirectionEntry(index, ref re); irq++; #if PRINT_IO_APICS DebugStub.Print("Added routeable entry for apic 0x{0:x}: IRQ 0x{1:x} => 0x{2:x}\n", __arglist(id, irq, IrqToInterrupt(irq))); #endif } } maxIrq = (byte)(irq - 1); PrintIoApics(); }
private void InitializeMpResourceEntries() { if (MpResources.FloatingPointer != null) { DebugStub.Print("Initializing Apic redirections from MpResources\n"); foreach (MpInterruptEntry e in MpResources.IoInterruptEntries) { IoApic ioApic = GetIoApic(e.ApicId); if (ioApic == null) { DebugStub.Print("Could not find I/O Apic with id {0}\n", __arglist(e.ApicId)); continue; } MpBusEntry be = MpResources.GetBusEntryById(e.BusId); if (be == null) { DebugStub.Print("Unknown bus device id {0:x2}\n", __arglist(e.BusId)); continue; } if (be.BusType == BusType.ISA) { ConfigureIsaInterrupt(ioApic, e); } else if (be.BusType == BusType.PCI) { ConfigurePciInterrupt(ioApic, e); } else { DebugStub.Print("Unhandled device on bus {0:x2}\n", __arglist(e.BusId)); continue; } } } else { DebugStub.Print("Initializing Apic redirections to defaults\n"); // If there are no MP tables, set up a standard mapping for the IRQs on CPU 0 uint end = 16; IoBits stdBits = (IoBits.DstPhysical | IoBits.DelModFixed | IoBits.IrqMask | IoBits.IntPolActiveLow | IoBits.TriggerModeEdge); for (uint z = 0; z < end; z++) { RedirectionEntry re = new RedirectionEntry(this.Id, stdBits, IrqToInterrupt((byte)z)); ioApics[0].SetRedirectionEntry((byte)z, ref re); } } PrintIoApics(); }
public void SetRedirectionEntry(uint index, ref RedirectionEntry entry) { bool enabled = AcquireLock(); try { RangeCheck(index, IndexLimit, "offset"); WriteRegister(RedLoBase + index * 2, MaskBit); uint hi = ReadRegister(RedHiBase + index * 2) & 0xffffffu; hi |= ((uint)entry.Destination) << 24; WriteRegister(RedHiBase + index * 2, hi); uint lo = ReadRegister(RedLoBase + index * 2) & 0x1ffffu; lo |= ((uint)entry.IoBits) << 8; lo |= (uint)entry.InterruptVector; WriteRegister(RedLoBase + index * 2, lo); } finally { ReleaseLock(enabled); } }
internal void ConfigurePciInterrupt(IoApic ioApic, MpInterruptEntry e) { byte vector = IrqToInterrupt(e.ApicLine); IoBits iobits = (e.PolarityType == Polarity.ActiveHigh) ? IoBits.IntPolActiveHigh : IoBits.IntPolActiveLow; iobits |= (e.TriggerType == Trigger.Edge) ? IoBits.TriggerModeEdge : IoBits.TriggerModeLevel; iobits |= IoBits.DstPhysical; iobits |= IoBits.DelModFixed; iobits |= IoBits.IrqMask; RedirectionEntry r = new RedirectionEntry(this.Id, iobits, vector); ioApic.SetRedirectionEntry(e.ApicLine, ref r); #if PRINT_IO_APICS DebugStub.Print("Added PCI interrupt for apic 0x{0:x}: Line 0x{1:x} => 0x{2:x}\n", __arglist(ioApic.GetId(), e.ApicLine, vector)); #endif }