Esempio n. 1
0
        /// <summary>
        /// Parses the MADT
        /// </summary>
        /// <param name="madt">The MADT</param>
        private static void parseMADT(MADT *madt)
        {
            m_madt = madt;
            LocalApic.SetLocalControllerAddress(madt->LocalControllerAddress);

            m_intSourceOverrides = new ISAOverride[16];
            for (uint i = 0; i < 16; i++)
            {
                m_intSourceOverrides[i].GSI      = i;
                m_intSourceOverrides[i].Polarity = IOApic.IOAPIC_REDIR_POLARITY_HIGH;
                m_intSourceOverrides[i].Trigger  = IOApic.IOAPIC_REDIR_TRIGGER_EDGE;
            }

            // After the flags field, the rest of the table contains a variable length of records
            uint current = (uint)madt + (uint)sizeof(MADT);
            uint end     = current + madt->Header.Length - (uint)sizeof(MADT);

            while (current < end)
            {
                ApicEntryHeader *   header = (ApicEntryHeader *)current;
                ApicEntryHeaderType type   = (ApicEntryHeaderType)header->Type;

                switch (type)
                {
                case ApicEntryHeaderType.LOCAL_APIC:
                    ApicLocalApic *localAPIC = (ApicLocalApic *)(current + sizeof(ApicEntryHeader));
                    Console.Write("[ACPI] Found CPU ");
                    Console.WriteNum(localAPIC->ProcessorID);
                    Console.Write('\n');
                    break;

                case ApicEntryHeaderType.IO_APIC:
                    ApicIOApic *IOApicStruct = (ApicIOApic *)(current + sizeof(ApicEntryHeader));

                    Console.Write("[ACPI] Found IO APIC at ");
                    Console.WriteHex(IOApicStruct->IOAPICAddress);
                    Console.Write('\n');

                    IOApic IOApic = new IOApic(IOApicStruct->IOAPIC_ID, (void *)IOApicStruct->IOAPICAddress, IOApicStruct->GlobalSystemInterruptBase);
                    IOApicManager.Add(IOApic);

                    break;

                case ApicEntryHeaderType.INTERRUPT_SOURCE_OVERRIDE:
                    ApicInterruptSourceOverride *intSourceOverride = (ApicInterruptSourceOverride *)(current + sizeof(ApicEntryHeader));

                    m_intSourceOverrides[intSourceOverride->IRQSource].GSI      = intSourceOverride->GlobalSystemInterrupt;
                    m_intSourceOverrides[intSourceOverride->IRQSource].Polarity = (uint)(intSourceOverride->Flags & 0x3);
                    m_intSourceOverrides[intSourceOverride->IRQSource].Trigger  = (uint)((intSourceOverride->Flags >> 2) & 0x3);

                    break;
                }

                current += header->Length;
            }
        }
Esempio n. 2
0
        public override void Initialize()
        {
            Device.Name = "ACPI";

            Pointer rsdpPtr;

            for (uint addr = 0x000E0000; addr <= 0x000FFFFF; addr += 8)
            {
                rsdpPtr = (Pointer)addr;

                if (rsdpPtr.Load64() == 0x2052545020445352)                 // 'RSD PTR '
                {
                    Descriptor = (RSDPDescriptor *)rsdpPtr;
                }
            }

            if (Descriptor == null)
            {
                return;
            }

            /*if (Descriptor->Revision == 2) // ACPI v2.0+
             * {
             *      Descriptor20 = (RSDPDescriptor20*)rsdpPtr;
             *
             *      XSDT = (XSDT*)HAL.GetPhysicalMemory((Pointer)Descriptor20->XsdtAddress, 0xFFFF).Address;
             *      FADT = (FADT*)HAL.GetPhysicalMemory((Pointer)FindBySignature("FACP", true), 0xFFFF).Address;
             *      MADT = (MADT*)HAL.GetPhysicalMemory((Pointer)FindBySignature("APIC", true), 0xFFFF).Address;
             * }
             * else
             * {*/
            RSDT = (RSDT *)HAL.GetPhysicalMemory((Pointer)Descriptor->RsdtAddress, 0xFFFF).Address;
            FADT = (FADT *)HAL.GetPhysicalMemory((Pointer)FindBySignature("FACP", false), 0xFFFF).Address;
            MADT = (MADT *)HAL.GetPhysicalMemory((Pointer)FindBySignature("APIC", false), 0xFFFF).Address;

            //}

            if (FADT == null)
            {
                return;
            }

            if (MADT != null)
            {
                ProcessorIDs     = new byte[256];
                LocalApicAddress = MADT->LocalApicAddress;

                Pointer ptr  = (Pointer)MADT;
                Pointer ptr2 = ptr + MADT->h.Length;

                for (ptr += 0x2C; ptr < ptr2;)
                {
                    MADTEntry *entry = (MADTEntry *)ptr;

                    switch (entry->Type)
                    {
                    case 0:                             // Processor Local APIC
                        ProcessorLocalAPICEntry *plan = (ProcessorLocalAPICEntry *)ptr;
                        if ((plan->Flags & 1) != 0)
                        {
                            ProcessorIDs[ProcessorCount++] = plan->ApicID;
                        }
                        break;

                    case 1:                             // I/O APIC
                        IOAPICEntry *ipe = (IOAPICEntry *)ptr;
                        IOApicAddress = ipe->ApicAddress;
                        break;

                    case 5:                             // 64-bit LAPIC
                        LongLocalAPICEntry *llpe = (LongLocalAPICEntry *)ptr;
                        LocalApicAddress = (uint)(llpe->ApicAddress);
                        break;
                    }

                    ptr += entry->Length;
                }
            }

            Pointer dsdt = (Pointer)FADT->Dsdt;

            if (dsdt.Load32() == 0x54445344)             //DSDT
            {
                Pointer S5Addr     = dsdt + sizeof(ACPISDTHeader);
                int     dsdtLength = (int)dsdt.Load32() + 1 - sizeof(ACPISDTHeader);

                for (int k = 0; k < dsdtLength; k++)
                {
                    if (S5Addr.Load32() == 0x5f35535f)                     //_S5_
                    {
                        break;
                    }
                    S5Addr++;
                }

                if (dsdtLength > 0)
                {
                    if (((S5Addr - 1).Load8() == 0x08 || ((S5Addr - 2).Load8() == 0x08 && (S5Addr - 1).Load8() == '\\')) && (S5Addr + 4).Load8() == 0x12)
                    {
                        S5Addr += 5;
                        S5Addr += ((S5Addr.Load32() & 0xC0) >> 6) + 2;
                        if (S5Addr.Load8() == 0x0A)
                        {
                            S5Addr++;
                        }
                        SLP_TYPa = (short)(S5Addr.Load16() << 10);
                        S5Addr++;
                        if (S5Addr.Load8() == 0x0A)
                        {
                            S5Addr++;
                        }
                        SLP_TYPb = (short)(S5Addr.Load16() << 10);
                        SLP_EN   = 1 << 13;

                        SMI_CommandPort = HAL.GetWriteIOPort((ushort)FADT->SMI_CommandPort);

                        bool has64BitPtr = false;

                        if (Descriptor->Revision == 2)
                        {
                            ResetAddress = HAL.GetWriteIOPort((ushort)FADT->ResetReg.Address);
                            ResetValue   = FADT->ResetValue;

                            if (Pointer.Size == 8)                             // 64-bit
                            {
                                has64BitPtr = true;

                                PM1aControlBlock = HAL.GetWriteIOPort((ushort)FADT->X_PM1aControlBlock.Address);
                                if (FADT->X_PM1bControlBlock.Address != 0)
                                {
                                    PM1bControlBlock = HAL.GetWriteIOPort((ushort)FADT->X_PM1bControlBlock.Address);
                                }
                            }
                        }

                        if (!has64BitPtr)
                        {
                            PM1aControlBlock = HAL.GetWriteIOPort((ushort)FADT->PM1aControlBlock);
                            if (FADT->PM1bControlBlock != 0)
                            {
                                PM1bControlBlock = HAL.GetWriteIOPort((ushort)FADT->PM1bControlBlock);
                            }
                        }
                    }
                }
            }
        }