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); }
private void InitializeBsp(Processor rootProcessor) { DebugStub.Print("HalDevicesApic.Initialize()\n"); pmTimer = AcpiTables.GetPMTimer(); // Get PIC resources. Pic is masked by default. PnpConfig picConfig = (PnpConfig)IoSystem.YieldResources("/pnp/PNP0000", typeof(PicStub)); pic = new PicStub(picConfig); pic.Initialize(PicBaseVector); // Parse MP Table and create IO apics MpResources.ParseMpTables(); ioApics = IoApic.CreateIOApics(); halPic = new Apic(ioApics); halPic.Initialize(ApicBaseVector); // Apic timer is used to provide one-shot timer interrupts. halTimer = new ApicTimer(halPic); halTimer.Initialize(); // Calibrate timers Calibrate.CpuCycleCounter(pmTimer); Calibrate.ApicTimer(pmTimer, halTimer); // Legacy timer is used to time stalls when starting CPUs. PnpConfig i8254Config = (PnpConfig)IoSystem.YieldResources("/pnp/PNP0100", typeof(Timer8254Apic)); stallTimer = new Timer8254Apic(i8254Config); // Real-time clock PnpConfig rtClockConfig = (PnpConfig)IoSystem.YieldResources("/pnp/PNP0B00", typeof(RTClockApic)); rtClock = new RTClockApic(rtClockConfig, halPic); // Compose our HalClock from the component clocks we have available halClock = new HalClockApic(halPic, rtClock, new PMClock(pmTimer)); SystemClock.Initialize(halClock, TimeSpan.FromHours(8).Ticks); rootProcessor.AddPic(halPic); rootProcessor.AddTimer(halTimer.Interrupt, halTimer); rootProcessor.AddClock(halClock.Interrupt, halClock); InitializeProcessorCount(); DebugReportProcessors(); halTimer.Start(); // Get the screen resources. Since we have metadata above to // declare all fixed resources used by the screen, // YieldResources("") will keep the resource tracking correct: halScreen = new HalScreenDirect(IoSystem.YieldResources("", typeof(HalScreen))); Console.Screen = (HalScreen)halScreen; halPic.DumpState(); foreach (IoApic ioApic in ioApics) { ioApic.DumpRedirectionEntries(); } pic.DumpRegisters(); }
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); }
public static void RegisterPnpResources() { // Register our pseudo bus driver PseudoBus pseudo = new PseudoBus(); IoSystem.AddRootDevice("/pseudobus0", pseudo, pseudo.ReportConfig()); // : /pnp/PNP0700 : Floppy Controller : PC Standard // : /pnp/PNP0C01 : RAM : System Board // : /pnp/PNP0A03 : PCI : PCI Bus // : /pnp/PNP0501 : Generic Serial : 16550A COM Port // : /pnp/PNP0501 : Generic Serial : 16550A COM Port // : /pnp/PNP0400 : AT Parallel : LPT Port // : /pnp/PNP0000 : ISA 8259 PIC : AT Interrupt Controller // : /pnp/PNP0200 : ISA 8237 DMA : AT DMA Controller // : /pnp/PNP0100 : ISA 8254 Timer : AT Timer // : /pnp/PNP0B00 : ISA RTC Controller : AT RTC // : /pnp/PNP0800 : Other : ??? // : /pnp/PNP0C02 : Other : PnP Event Notification // : /pnp/PNP0C02 : Other : PnP Event Notification // : /pnp/PNP0C04 : Other : Math Coprocessor // : /pnp/PNP0303 : Keyboard controller : 101/102 Keyboard // : /pnp/PNP0F13 : Mouse Controller : Logitech PS/2 Mouse AcpiDevice[] deviceInfo = null; AcpiTables.Parse(); #if ACPI_ENABLED deviceInfo = AcpiTables.LoadDevices(); #endif // ACPI_ENABLED if (deviceInfo != null && deviceInfo.Length > 0) { AcpiBus !acpi = new AcpiBus(deviceInfo); IoSystem.AddRootDevice("/acpi0", acpi, acpi.ReportConfig()); } else { PnpBios bios = new PnpBios(Resources.GetPnpBiosInfo()); // in order for IoSystem accounting to work, we need to explicitly // tell it what the IoConfig of the root device is: IoSystem.AddRootDevice("/pnp0", bios, bios.ReportConfig()); } #if VESA_ENABLED // Add VESA Device if it exists. if (((!)Platform.ThePlatform).VesaBuffer != 0) { SortedList custom = new SortedList(); custom.Add("000", new PnpConfig( new String[] { "/pnp/vesa" }, new IoRange[] { new IoMemoryRange( Platform.ThePlatform.VesaBuffer, 0x300000, Access.ReadWrite) })); IoSystem.AddDevicesToTree(custom, "/vesa0/", false); } #endif // VESA_ENABLED }
public override void Initialize(Processor rootProcessor) { DebugStub.Print("HalDevices.Initialize() - Legacy\n"); pmTimer = AcpiTables.GetPMTimer(); // PIC PnpConfig picConfig = (PnpConfig)IoSystem.YieldResources("/pnp/PNP0000", typeof(Pic)); pic = new Pic(picConfig); pic.Initialize(); // Timer PnpConfig timerConfig = (PnpConfig)IoSystem.YieldResources("/pnp/PNP0100", typeof(Timer8254LegacyPC)); timer = new Timer8254LegacyPC(timerConfig, pic); byte timerInterrupt = timer.Initialize(); // Real-time clock PnpConfig clockConfig = (PnpConfig)IoSystem.YieldResources("/pnp/PNP0B00", typeof(RTClockLegacyPC)); clock = new RTClockLegacyPC(clockConfig, pic, timer); byte clockInterrupt = clock.Initialize(); bool noisyTimer = false; if (pmTimer != null) { noisyTimer = CalibrateTimers.Run(pmTimer, timer); } else { CalibrateTimers.Run(clock, timer); } clock.SetNoisyTimer(noisyTimer); clock.Start(); SystemClock.Initialize(clock, TimeSpan.FromHours(8).Ticks); rootProcessor.AddPic(pic); rootProcessor.AddTimer(timerInterrupt, timer); rootProcessor.AddClock(clockInterrupt, clock); // ---------------------------------------------------------- // Add Srat tables to the Processor halMemory = new HalMemorySrat(AcpiTables.GetSrat()); Processor.AddMemory(halMemory); timer.Start(); // Get the screen resources. Since we have metadata above to // declare all fixed resources used by the screen, // YieldResources("") will keep the resource tracking correct: halScreen = new HalScreenDirect(IoSystem.YieldResources("", typeof(HalScreen))); Console.Screen = (HalScreen)halScreen; }