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); } }
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 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(); }
internal static IoApic [] CreateFromMpResources() { ArrayList ioApicEntries = MpResources.IoApicEntries; if (ioApicEntries == null) { DebugStub.Print("No I/O APICs found\n"); return(null); } // Scan IoApic entries and remove those that are marked unusable int usable = ioApicEntries.Count; foreach (MpIoApicEntry entry in ioApicEntries) { if (((int)entry.Flags & 0x1) != 0x1) { usable--; } } if (usable == 0) { DebugStub.Print("No usable I/O APICs found\n"); return(null); } IoApic [] apics = new IoApic[usable]; int i = 0; foreach (MpIoApicEntry entry in ioApicEntries) { if (((int)entry.Flags & 0x1) != 0x1) { continue; } apics[i] = new IoApic(new UIntPtr(entry.BaseAddress), 0); apics[i].SetId(entry.Id); i++; } return(apics); }
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 }
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(); }