internal static void ParseMpTables() { UIntPtr mpFloat = GetMpFloatBase(); if (mpFloat == UIntPtr.Zero) { DebugStub.Print("MP Floating Pointer Structure not found.\n"); return; } mpFloatRegion = IoMemory.MapPhysicalMemory(mpFloat, new UIntPtr(16), true, false); FloatingPointer = MpFloatingPointer.Parse(mpFloatRegion); if (FloatingPointer == null) { DebugStub.Print("Failed to parse MP Floating Pointer " + "Structure.\n"); return; } if (FloatingPointer.MpConfTablePresent) { mpConfTableRegion = IoMemory.MapPhysicalMemory( new UIntPtr(FloatingPointer.ConfTableBase), new UIntPtr(0x2c), true, false); DebugStub.Print("Found MP Conf Table\n"); ConfTable = MpConfTable.Parse(mpConfTableRegion); if (ConfTable == null) { DebugStub.Print("Failed to parse MP Configuration table.\n"); } IoMemory mpResourceRegion = IoMemory.MapPhysicalMemory( new UIntPtr(FloatingPointer.ConfTableBase + 0x2c), new UIntPtr(ConfTable.BaseTableLength - 0x2c), true, false); DebugStub.Print("Parsing MP Conf Table Resources\n"); MpResources.Parse(mpResourceRegion, ConfTable.BaseTableLength - 0x2c, ConfTable.EntryCount); } else { DebugStub.Print("MP Configuration table not present.\n"); DebugStub.Print("MP Floating Pointer features: " + "{0:x8} {1:x8} {2:x8} {3:x8} {4:x8}\n", __arglist( FloatingPointer.Feature[0], FloatingPointer.Feature[1], FloatingPointer.Feature[2], FloatingPointer.Feature[3], FloatingPointer.Feature[4])); } }
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(); }
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(); }