Exemple #1
0
        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());
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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();
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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
        }
Exemple #6
0
        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;
        }