internal static IoApic [] CreateIOApics() { // Prefer to get the list of IoApics from the MADT Madt madt = AcpiTables.GetMadt(); if (madt != null) { ArrayList alist = madt.GetIoApics(); if (alist.Count > 0) { IoApic [] apics = new IoApic[alist.Count]; for (int i = 0; i < alist.Count; i++) { // Have to convert from a ...Hal.Acpi.IoApic into a Hal.IoApic: Microsoft.Singularity.Hal.Acpi.IoApic sourceEntry = (Microsoft.Singularity.Hal.Acpi.IoApic)alist[i]; IoApic destEntry = new IoApic(sourceEntry.Address, sourceEntry.InterruptBase); destEntry.SetId(sourceEntry.Id); apics[i] = destEntry; } DebugStub.Print("Created IoApics from MADT table\n"); return(apics); } } DebugStub.Print("Created IoApics from MpResources table table\n"); // Otherwise, create from Mp tables return(CreateFromMpResources()); }
private void InitializeProcessorCount() { Madt madt = AcpiTables.GetMadt(); if (madt != null) { processorCount = madt.GetLocalApics().Count; } else if (MpResources.ProcessorEntries != null) { processorCount = MpResources.ProcessorEntries.Count; } else { processorCount = 1; } // // Platform.ThePlatform.CpuRealCount was setup by // the boot loader and should be the same that we read here. // DebugStub.Assert(Platform.ThePlatform.CpuRealCount == processorCount); }
public override byte TranslatePciInterrupt(byte currentInterruptLine, byte pciInterruptPin, PciPort pciPort) { // // The pin number in the tables is zero based, while the pin number // from the PCI config space is 1-based. So convert to the table space. // pciInterruptPin -= 1; #if DEBUG_PCI_INTERRUPT_TRANSLATION DebugStub.Print("HalApic: Translating interrupt for PCI device 0x{0:x} pin {1} on Bus 0x{2:x}\n", __arglist(pciPort.Device, pciInterruptPin, pciPort.Bus)); #endif // // By default, if we can't find the device, we'll return the current // interrupt line. // byte resultLine = currentInterruptLine; foreach (MpInterruptEntry interruptEntry in MpResources.IoInterruptEntries) { #if DEBUG_PCI_INTERRUPT_TRANSLATION DebugStub.Print("Found interrupt entry bus 0x{0:x} busIrq 0x{1:x} => ApicId 0x{2:x} ApicLine 0x{3:x}\n", __arglist(interruptEntry.BusId, interruptEntry.BusIrq, interruptEntry.ApicId, interruptEntry.ApicLine)); #endif // // According to the MPS spec: for PCI buses, the bus IRQ in the table entry // contains the pin in the low two bits, and the device number in the next // five bits (and the rest are reserved). // if ((interruptEntry.BusId == pciPort.Bus) && ((interruptEntry.BusIrq & 3) == pciInterruptPin) && (((interruptEntry.BusIrq >> 2) & ((1 << 5) - 1)) == pciPort.Device)) { #if DEBUG_PCI_INTERRUPT_TRANSLATION DebugStub.Print("Found device 0x{0:x} connected to IoApic Id 0x{1:x}, line 0x{2:x}\n", __arglist(pciPort.Device, interruptEntry.ApicId, interruptEntry.ApicLine)); #endif // // And then we need to translate it into a global interrupt number. // foreach (Acpi.IoApic ioApic in AcpiTables.GetMadt().GetIoApics()) { #if DEBUG_PCI_INTERRUPT_TRANSLATION DebugStub.Print("Found IoApic 0x{0:x}, interrupt base 0x{1:x}\n", __arglist(ioApic.Id, ioApic.InterruptBase)); #endif if (ioApic.Id == interruptEntry.ApicId) { resultLine = (byte)(ioApic.InterruptBase + interruptEntry.ApicLine); #if DEBUG_PCI_INTERRUPT_TRANSLATION DebugStub.Print("Using global interrupt line 0x{0:x}\n", __arglist(resultLine)); #endif return(resultLine); } } break; } } #if DEBUG_PCI_INTERRUPT_TRANSLATION DebugStub.Print("HalApic: Translated PCI device 0x{0:x} pin {1} on bus 0x{2:x} to global interrupt 0x{3:x}\n", __arglist(pciPort.Device, pciInterruptPin, pciPort.Bus, resultLine)); #endif return(resultLine); }