예제 #1
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);
                            }
                        }
                    }
                }
            }
        }