[HALACPI]: Implement beginning of HAL ACPI support (HalpSetupAcpiPhase0). Tested...
authorSir Richard <sir_richard@svn.reactos.org>
Wed, 31 Mar 2010 04:43:39 +0000 (04:43 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Wed, 31 Mar 2010 04:43:39 +0000 (04:43 +0000)
[HALACPI]: Support depends on boot loader creating the ACPI BIOS Multi Node structure in MultiFunctionAdapter in the hardware tree. It seems that FreeLdr does this (wow!) correctly!
[HALACPI]: Implement HAL ACPI Table Cache.
[HALACPI]: HAL ACPI Table Overrides from the boot loader are not supported (doubt FreeLdr does this).
[HALACPI]: The next steps are to write the HAL ACPI PnP Driver and HAL ACPI Power Driver.

svn path=/trunk/; revision=46613

reactos/hal/halx86/generic/acpi/halacpi.c [new file with mode: 0644]
reactos/hal/halx86/generic/halinit.c
reactos/hal/halx86/generic/legacy/halpcat.c [new file with mode: 0644]
reactos/hal/halx86/hal_generic.rbuild

diff --git a/reactos/hal/halx86/generic/acpi/halacpi.c b/reactos/hal/halx86/generic/acpi/halacpi.c
new file mode 100644 (file)
index 0000000..f9fe873
--- /dev/null
@@ -0,0 +1,864 @@
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            hal/halx86/generic/acpi/halacpi.c
+ * PURPOSE:         HAL ACPI Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+LIST_ENTRY HalpAcpiTableCacheList;
+FAST_MUTEX HalpAcpiTableCacheLock;
+
+BOOLEAN HalpProcessedACPIPhase0;
+BOOLEAN HalpPhysicalMemoryMayAppearAbove4GB;
+
+FADT HalpFixedAcpiDescTable;
+PDEBUG_PORT_TABLE HalpDebugPortTable;
+PACPI_SRAT HalpAcpiSrat;
+PBOOT_TABLE HalpSimpleBootFlagTable;
+
+PHYSICAL_ADDRESS HalpMaxHotPlugMemoryAddress;
+PHYSICAL_ADDRESS HalpLowStubPhysicalAddress;
+PHARDWARE_PTE HalpPteForFlush;
+PVOID HalpVirtAddrForFlush;
+PVOID HalpLowStub;
+
+PACPI_BIOS_MULTI_NODE HalpAcpiMultiNode;
+
+LIST_ENTRY HalpAcpiTableMatchList;
+
+ULONG HalpInvalidAcpiTable;
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+PDESCRIPTION_HEADER
+NTAPI
+HalpAcpiGetCachedTable(IN ULONG Signature)
+{
+    PLIST_ENTRY ListHead, NextEntry;
+    PACPI_CACHED_TABLE CachedTable;
+    
+    /* Loop cached tables */
+    ListHead = &HalpAcpiTableCacheList;
+    NextEntry = ListHead->Flink;
+    while (NextEntry != ListHead)
+    {
+        /* Get the table */
+        CachedTable = CONTAINING_RECORD(NextEntry, ACPI_CACHED_TABLE, Links);
+        
+        /* Compare signatures */
+        if (CachedTable->Header.Signature == Signature) return &CachedTable->Header;
+        
+        /* Keep going */
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Nothing found */
+    return NULL;
+}
+
+VOID
+NTAPI
+HalpAcpiCacheTable(IN PDESCRIPTION_HEADER TableHeader)
+{
+    PACPI_CACHED_TABLE CachedTable;
+    
+    /* Get the cached table and link it */
+    CachedTable = CONTAINING_RECORD(TableHeader, ACPI_CACHED_TABLE, Header);
+    InsertTailList(&HalpAcpiTableCacheList, &CachedTable->Links);
+}
+
+PVOID
+NTAPI
+HalpAcpiCopyBiosTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                      IN PDESCRIPTION_HEADER TableHeader)
+{
+    ULONG Size;
+    PFN_NUMBER PageCount;
+    PHYSICAL_ADDRESS PhysAddress;
+    PACPI_CACHED_TABLE CachedTable;
+    PDESCRIPTION_HEADER CopiedTable;
+    
+    /* Size we'll need for the cached table */
+    Size = TableHeader->Length + FIELD_OFFSET(ACPI_CACHED_TABLE, Header);
+    if (LoaderBlock)
+    {
+        /* Phase 0: Convert to pages and use the HAL heap */
+        PageCount = BYTES_TO_PAGES(Size);
+        PhysAddress.LowPart = HalpAllocPhysicalMemory(LoaderBlock,
+                                                      0x1000000,
+                                                      PageCount,
+                                                      FALSE);
+        if (PhysAddress.LowPart)
+        {
+            /* Map it */
+            CachedTable = HalpMapPhysicalMemory64(PhysAddress, PageCount);
+        }
+        else
+        {
+            /* No memory, so nothing to map */
+            CachedTable = NULL;
+        }
+    }
+    else
+    {
+        /* Use Mm pool */
+        CachedTable = ExAllocatePoolWithTag(NonPagedPool, Size, ' laH');
+    }
+    
+    /* Do we have the cached table? */
+    if (CachedTable)
+    {
+        /* Copy the data */
+        CopiedTable = &CachedTable->Header;
+        RtlCopyMemory(CopiedTable, TableHeader, TableHeader->Length);
+    }
+    else
+    {
+        /* Nothing to return */
+        CopiedTable = NULL;
+    }
+    
+    /* Return the table */
+    return CopiedTable;
+}
+
+PVOID
+NTAPI
+HalpAcpiGetTableFromBios(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                         IN ULONG Signature)
+{
+    PHYSICAL_ADDRESS PhysicalAddress;
+    PXSDT Xsdt;
+    PRSDT Rsdt;
+    PFADT Fadt;
+    PDESCRIPTION_HEADER Header = NULL;
+    ULONG TableLength;
+    CHAR CheckSum = 0;
+    ULONG Offset;
+    ULONG EntryCount, CurrentEntry;
+    PCHAR CurrentByte;
+    PFN_NUMBER PageCount;
+  
+    /* Should not query the RSDT/XSDT by itself */
+    if ((Signature == RSDT_SIGNATURE) || (Signature == XSDT_SIGNATURE)) return NULL;
+
+    /* Special case request for DSDT, because the FADT points to it */
+    if (Signature == DSDT_SIGNATURE)
+    {
+        /* Grab the FADT */
+        Fadt = HalpAcpiGetTable(LoaderBlock, FADT_SIGNATURE);
+        if (Fadt)
+        {
+            /* Grab the DSDT address and assume 2 pages */
+            PhysicalAddress.LowPart = Fadt->dsdt;
+            TableLength = 2 * PAGE_SIZE;
+            
+            /* Map it */
+            if (LoaderBlock)
+            {
+                /* Phase 0, use HAL heap */
+                Header = HalpMapPhysicalMemory64(PhysicalAddress, 2u);
+            }
+            else
+            {
+                /* Phase 1, use Mm */
+                Header = MmMapIoSpace(PhysicalAddress, 2 * PAGE_SIZE, 0);
+            }
+
+            /* Fail if we couldn't map it */
+            if (!Header)
+            {
+                DbgPrint("HAL: Failed to map ACPI table.\n");
+                return NULL;
+            }
+            
+            /* Validate the signature */
+            DPRINT1("ACPI DSDT at 0x%p\n", Header);
+            if (Header->Signature != DSDT_SIGNATURE)
+            {
+                /* Fail and unmap */
+                if (LoaderBlock)
+                {
+                    /* Using HAL heap */
+                    HalpUnmapVirtualAddress(Header, 2);
+                }
+                else
+                {
+                    /* Using Mm */
+                    MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
+                }
+
+                /* Didn't find anything */
+                return NULL;
+            }
+        }
+        else
+        {
+            /* Couldn't find it */
+            return NULL;
+        }
+    }
+    else
+    {
+        /* To find tables, we need the RSDT */ 
+        Rsdt = HalpAcpiGetTable(LoaderBlock, RSDT_SIGNATURE);
+        if (Rsdt)
+        {
+            /* Won't be using the XSDT */
+            Xsdt = NULL;
+        }
+        else
+        {
+            /* Only other choice is to use the XSDT */
+            Xsdt = HalpAcpiGetTable(LoaderBlock, XSDT_SIGNATURE);
+            if (!Xsdt) return NULL;
+
+            /* Won't be using the RSDT */
+            DPRINT1("ACPI XSDT at 0x%p\n", Xsdt);
+            Rsdt = NULL;
+        }
+    
+        /* Smallest RSDT/XSDT is one without table entries */
+        Offset = FIELD_OFFSET(RSDT, Tables);
+        if (Xsdt)
+        {
+            /* Figure out total size of table and the offset */
+            TableLength = Xsdt->Header.Length;
+            if (TableLength < Offset) Offset = Xsdt->Header.Length;
+        
+            /* The entries are each 64-bits, so count them */
+            EntryCount = (TableLength - Offset) / sizeof(PHYSICAL_ADDRESS);
+        }
+        else
+        {
+            /* Figure out total size of table and the offset */
+            TableLength = Rsdt->Header.Length;
+            if (TableLength < Offset) Offset = Rsdt->Header.Length;
+        
+            /* The entries are each 32-bits, so count them */
+            EntryCount = (TableLength - Offset) / sizeof(ULONG);
+        }
+  
+        /* Start at the beginning of the array and loop it */
+        for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++)
+        {
+            /* Are we using the XSDT? */
+            if (!Xsdt)
+            {
+                /* Read the 32-bit physical address */
+                PhysicalAddress.LowPart = Rsdt->Tables[CurrentEntry];
+            }
+            else
+            {
+                /* Read the 64-bit physical address */
+                PhysicalAddress = Xsdt->Tables[CurrentEntry];
+            }
+        
+            /* Had we already mapped a table? */
+            if (Header)
+            {
+                /* Yes, unmap it */
+                if (LoaderBlock)
+                {
+                    /* Using HAL heap */
+                    HalpUnmapVirtualAddress(Header, 2);
+                }
+                else
+                {
+                    /* Using Mm */
+                    MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
+                }
+            }
+        
+            /* Now map this table */
+            if (!LoaderBlock)
+            {
+                /* Phase 1: Use HAL heap */
+                Header = MmMapIoSpace(PhysicalAddress, 2 * PAGE_SIZE, MmNonCached);
+            }
+            else
+            {
+                /* Phase 0: Use Mm */
+                Header = HalpMapPhysicalMemory64(PhysicalAddress, 2);
+            }
+        
+            /* Check if we mapped it */
+            if (!Header)
+            {
+                /* Game over */
+                DbgPrint("HAL: Failed to map ACPI table.\n");
+                return NULL;
+            }
+
+            /* We found it, break out */
+            DPRINT("Found ACPI table %c%c%c%c at 0x%p\n",
+                    Header->Signature & 0xFF,
+                    (Header->Signature & 0xFF00) >> 8,
+                    (Header->Signature & 0xFF0000) >> 16,
+                    (Header->Signature & 0xFF000000) >> 24,
+                    Header);
+            if (Header->Signature == Signature) break;
+        }
+    
+        /* Did we end up here back at the last entry? */
+        if (CurrentEntry == EntryCount)
+        {
+            /* Yes, unmap the last table we processed */
+            if (LoaderBlock)
+            {
+                /* Using HAL heap */
+                HalpUnmapVirtualAddress(Header, 2);
+            }
+            else
+            {
+                /* Using Mm */
+                MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
+            }
+     
+            /* Didn't find anything */
+            return NULL;
+        }
+    }
+    
+    /* Past this point, we assume something was found */
+    ASSERT(Header);
+    
+    /* How many pages do we need? */
+    PageCount = BYTES_TO_PAGES(Header->Length);    
+    if (PageCount != 2)
+    {
+        /* We assumed two, but this is not the case, free the current mapping */
+        if (LoaderBlock)
+        {
+            /* Using HAL heap */
+            HalpUnmapVirtualAddress(Header, 2);
+        }
+        else
+        {
+            /* Using Mm */
+            MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
+        }
+        
+        /* Now map this table using its correct size */
+        if (!LoaderBlock)
+        {
+            /* Phase 1: Use HAL heap */
+            Header = MmMapIoSpace(PhysicalAddress, PageCount << PAGE_SHIFT, MmNonCached);
+        }
+        else
+        {
+            /* Phase 0: Use Mm */
+            Header = HalpMapPhysicalMemory64(PhysicalAddress, PageCount);
+        }
+    }
+    
+    /* Fail if the remapped failed */
+    if (!Header) return NULL;
+
+    /* All tables in ACPI 3.0 other than the FACP should have correct checksum */
+    if ((Header->Signature != FADT_SIGNATURE) || (Header->Revision > 2))
+    {
+        /* Go to the end of the table */
+        CheckSum = 0;
+        CurrentByte = (PCHAR)Header + Header->Length;
+        while (CurrentByte-- != (PCHAR)Header)
+        {
+            /* Add this byte */
+            CheckSum += *CurrentByte;
+        }
+        
+        /* The correct checksum is always 0, anything else is illegal */
+        if (CheckSum) HalpInvalidAcpiTable = Header->Signature;
+    }
+    /* Return the table */
+    return Header;
+}
+
+PVOID
+NTAPI
+HalpAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                 IN ULONG Signature)
+{
+    PFN_NUMBER PageCount;
+    PDESCRIPTION_HEADER TableAddress, BiosCopy;
+
+    /* See if we have a cached table? */
+    TableAddress = HalpAcpiGetCachedTable(Signature);
+    if (!TableAddress)
+    {
+        /* No cache, search the BIOS */
+        TableAddress = HalpAcpiGetTableFromBios(LoaderBlock, Signature);
+        if (TableAddress)
+        {
+            /* Found it, copy it into our own memory */
+            BiosCopy = HalpAcpiCopyBiosTable(LoaderBlock, TableAddress);
+            
+            /* Get the pages, and unmap the BIOS copy */
+            PageCount = BYTES_TO_PAGES(TableAddress->Length);
+            if (LoaderBlock)
+            {
+                /* Phase 0, use the HAL heap */
+                HalpUnmapVirtualAddress(TableAddress, PageCount);
+            }
+            else
+            {
+                /* Phase 1, use Mm */
+                MmUnmapIoSpace(TableAddress, PageCount << 12);
+            }
+            
+            /* Cache the bios copy */
+            TableAddress = BiosCopy;
+            if (BiosCopy) HalpAcpiCacheTable(BiosCopy);
+        }
+    }
+    
+    /* Return the table */
+    return TableAddress;
+}
+
+PVOID
+NTAPI
+HalAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                IN ULONG Signature)
+{
+    PDESCRIPTION_HEADER TableHeader;
+    
+    /* Is this phase0 */
+    if (LoaderBlock)
+    {
+        /* Initialize the cache first */
+        if (!NT_SUCCESS(HalpAcpiTableCacheInit(LoaderBlock))) return NULL;
+    }
+    else
+    {
+        /* Lock the cache */
+        ExAcquireFastMutex(&HalpAcpiTableCacheLock);
+    }
+
+    /* Get the table */
+    TableHeader = HalpAcpiGetTable(LoaderBlock, Signature);
+    
+    /* Release the lock in phase 1 */
+    if (!LoaderBlock) ExReleaseFastMutex(&HalpAcpiTableCacheLock);
+
+    /* Return the table */
+    return TableHeader;
+}
+
+VOID
+NTAPI
+HalpNumaInitializeStaticConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    PACPI_SRAT SratTable;
+    
+    /* Get the SRAT, bail out if it doesn't exist */
+    SratTable = HalAcpiGetTable(LoaderBlock, SRAT_SIGNATURE);
+    HalpAcpiSrat = SratTable;
+    if (!SratTable) return;
+}
+
+VOID
+NTAPI
+HalpGetHotPlugMemoryInfo(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    PACPI_SRAT SratTable;
+    
+    /* Get the SRAT, bail out if it doesn't exist */
+    SratTable = HalAcpiGetTable(LoaderBlock, SRAT_SIGNATURE);
+    HalpAcpiSrat = SratTable;
+    if (!SratTable) return;
+}
+
+VOID
+NTAPI
+HalpDynamicSystemResourceConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    /* For this HAL, it means to get hot plug memory information */
+    HalpGetHotPlugMemoryInfo(LoaderBlock);
+}
+
+VOID
+NTAPI
+HalpAcpiDetectMachineSpecificActions(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                                     IN PFADT DescriptionTable)
+{
+    /* Does this HAL specify something? */
+    if (HalpAcpiTableMatchList.Flink)
+    {
+        /* Great, but we don't support it */
+        DPRINT1("WARNING: Your HAL has specific ACPI hacks to apply!\n");
+    }
+}
+
+VOID
+NTAPI
+HalpInitBootTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    PBOOT_TABLE BootTable;
+
+    /* Get the boot table */
+    BootTable = HalAcpiGetTable(LoaderBlock, BOOT_SIGNATURE);
+    HalpSimpleBootFlagTable = BootTable;
+    DPRINT1("ACPI BOOT at 0x%p\n", HalpSimpleBootFlagTable);
+    
+    /* Validate it */
+    if ((BootTable) &&
+        (BootTable->Header.Length >= sizeof(BOOT_TABLE)) &&
+        (BootTable->CMOSIndex >= 9))
+    {
+        DPRINT1("ACPI Boot table found, but not supported!\n");
+    }
+    else
+    {
+        /* Invalid or doesn't exist, ignore it */
+        HalpSimpleBootFlagTable = 0;
+    }
+    
+    /* Install the end of boot handler */
+//    HalEndOfBoot = HalpEndOfBoot;
+}
+
+NTSTATUS
+NTAPI
+HalpAcpiFindRsdtPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                       OUT PACPI_BIOS_MULTI_NODE* AcpiMultiNode)
+{
+    PCONFIGURATION_COMPONENT_DATA ComponentEntry;
+    PCONFIGURATION_COMPONENT_DATA Next = NULL;
+    PCM_PARTIAL_RESOURCE_LIST ResourceList;
+    PACPI_BIOS_MULTI_NODE NodeData;
+    ULONG NodeLength;
+    PFN_NUMBER PageCount;
+    PVOID MappedAddress;
+    PHYSICAL_ADDRESS PhysicalAddress;
+
+    /* Did we already do this once? */
+    if (HalpAcpiMultiNode)
+    {
+        /* Return what we know */
+        *AcpiMultiNode = HalpAcpiMultiNode;
+        return STATUS_SUCCESS;
+    }
+
+    /* Assume failure */
+    *AcpiMultiNode = NULL;
+    
+    /* Find the multi function adapter key */
+    ComponentEntry = KeFindConfigurationNextEntry(LoaderBlock->ConfigurationRoot,
+                                                  AdapterClass,
+                                                  MultiFunctionAdapter,
+                                                  0,
+                                                  &Next);
+    while (ComponentEntry)
+    {
+        /* Find the ACPI BIOS key */
+        if (!_stricmp(ComponentEntry->ComponentEntry.Identifier, "ACPI BIOS"))
+        {
+            /* Found it */
+            break;
+        }
+        
+        /* Keep searching */
+        Next = ComponentEntry;
+        ComponentEntry = KeFindConfigurationNextEntry(LoaderBlock->ConfigurationRoot,
+                                                      AdapterClass,
+                                                      MultiFunctionAdapter,
+                                                      NULL,
+                                                      &Next);
+    }
+    
+    /* Make sure we found it */
+    if (!ComponentEntry)
+    {
+        DbgPrint("**** HalpAcpiFindRsdtPhase0: did NOT find RSDT\n");
+        return STATUS_NOT_FOUND;
+    }
+    
+    /* The configuration data is a resource list, and the BIOS node follows */
+    ResourceList = ComponentEntry->ConfigurationData;
+    NodeData = (PACPI_BIOS_MULTI_NODE)(ResourceList + 1);
+    
+    /* How many E820 memory entries are there? */
+    NodeLength = sizeof(ACPI_BIOS_MULTI_NODE) +
+                 (NodeData->Count - 1) * sizeof(ACPI_E820_ENTRY);
+                 
+    /* Convert to pages */
+    PageCount = BYTES_TO_PAGES(NodeLength);
+
+    /* Allocate the memory */
+    PhysicalAddress.LowPart = HalpAllocPhysicalMemory(LoaderBlock,
+                                                      0x1000000,
+                                                      PageCount,
+                                                      FALSE);
+    if (PhysicalAddress.LowPart)
+    {
+        /* Map it if the allocation worked */
+        MappedAddress = HalpMapPhysicalMemory64(PhysicalAddress, PageCount);
+    }
+    else
+    {
+        /* Otherwise we'll have to fail */
+        MappedAddress = NULL;
+    }
+    
+    /* Save the multi node, bail out if we didn't find it */
+    HalpAcpiMultiNode = MappedAddress;
+    if (!MappedAddress) return STATUS_INSUFFICIENT_RESOURCES;
+    
+    /* Copy the multi-node data */
+    RtlCopyMemory(MappedAddress, NodeData, NodeLength);
+
+    /* Return the data */
+    *AcpiMultiNode = HalpAcpiMultiNode;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+HalpAcpiTableCacheInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    PACPI_BIOS_MULTI_NODE AcpiMultiNode;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PHYSICAL_ADDRESS PhysicalAddress;
+    PVOID MappedAddress;
+    ULONG TableLength;
+    PRSDT Rsdt;
+    PLOADER_PARAMETER_EXTENSION LoaderExtension;
+   
+    /* Only initialize once */
+    if (HalpAcpiTableCacheList.Flink) return Status;
+   
+    /* Setup the lock and table */
+    ExInitializeFastMutex(&HalpAcpiTableCacheLock);
+    InitializeListHead(&HalpAcpiTableCacheList);
+   
+    /* Find the RSDT */
+    Status = HalpAcpiFindRsdtPhase0(LoaderBlock, &AcpiMultiNode);
+    if (!NT_SUCCESS(Status)) return Status;
+   
+    /* Map the RSDT */
+    if (LoaderBlock)
+    {
+        /* Phase0: Use HAL Heap to map the RSDT, we assume it's about 2 pages */
+        PhysicalAddress.QuadPart = AcpiMultiNode->RsdtAddress.QuadPart;
+        MappedAddress = HalpMapPhysicalMemory64(PhysicalAddress, 2);
+    }
+    else
+    {
+        /* Use an I/O map */
+        MappedAddress = MmMapIoSpace(PhysicalAddress, PAGE_SIZE * 2, MmNonCached);
+    }
+   
+    /* Get the RSDT */
+    Rsdt = MappedAddress;
+    if (!MappedAddress)
+    {
+        /* Fail, no memory */
+        DbgPrint("HAL: Failed to map RSDT\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+   
+    /* Validate it */
+    DPRINT1("ACPI RSDT at 0x%p\n", Rsdt);
+    if ((Rsdt->Header.Signature != RSDT_SIGNATURE) &&
+        (Rsdt->Header.Signature != XSDT_SIGNATURE))
+    {
+        /* Very bad: crash */
+        HalDisplayString("Bad RSDT pointer\n");
+        KeBugCheckEx(MISMATCHED_HAL, 4, __LINE__, 0, 0);
+    }
+   
+    /* We assumed two pages -- do we need less or more? */
+    TableLength = ADDRESS_AND_SIZE_TO_SPAN_PAGES(PhysicalAddress.LowPart,
+                                                 Rsdt->Header.Length);
+    if (TableLength != 2)
+    {
+        /* Are we in phase 0 or 1? */
+        if (!LoaderBlock)
+        {
+            /* Unmap the old table, remap the new one, using Mm I/O space */
+            MmUnmapIoSpace(MappedAddress, 2 * PAGE_SIZE);
+            MappedAddress = MmMapIoSpace(PhysicalAddress,
+                                         TableLength << PAGE_SHIFT,
+                                         MmNonCached);
+        }
+        else
+        {
+            /* Unmap the old table, remap the new one, using HAL heap */
+            HalpUnmapVirtualAddress(MappedAddress, 2);
+            MappedAddress = HalpMapPhysicalMemory64(PhysicalAddress, TableLength);
+        }
+        
+        /* Get the remapped table */
+        Rsdt = MappedAddress;
+        if (!MappedAddress)
+        {
+            /* Fail, no memory */
+            DbgPrint("HAL: Couldn't remap RSDT\n");
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+    }
+    
+    /* Now take the BIOS copy and make our own local copy */
+    Rsdt = HalpAcpiCopyBiosTable(LoaderBlock, &Rsdt->Header);
+    if (!Rsdt)
+    {
+        /* Fail, no memory */
+        DbgPrint("HAL: Couldn't remap RSDT\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+    
+    /* Get rid of the BIOS mapping */
+    if (LoaderBlock)
+    {
+        /* Use HAL heap */
+        HalpUnmapVirtualAddress(MappedAddress, TableLength);
+    }
+    else
+    {
+        /* Use Mm */
+        MmUnmapIoSpace(MappedAddress, TableLength << PAGE_SHIFT);
+    }
+    
+    /* Cache the RSDT */    
+    HalpAcpiCacheTable(&Rsdt->Header);
+    
+    /* Check for compatible loader block extension */
+    LoaderExtension = LoaderBlock->Extension;
+    if (LoaderExtension->Size >= 0x58)
+    {
+        /* Compatible loader: did it provide an ACPI table override? */
+        if ((LoaderExtension->AcpiTable) && (LoaderExtension->AcpiTableSize))
+        {
+            /* Great, because we don't support it! */
+            DPRINT1("ACPI Table Overrides Not Supported!\n");
+        }
+    }
+
+    /* Done */
+    return Status;
+}
+
+VOID
+NTAPI
+HaliAcpiTimerInit(IN ULONG TimerPort,
+                  IN ULONG TimerValExt)
+{
+    PAGED_CODE();
+    
+    /* Is this in the init phase? */
+    if (!TimerPort )
+    {
+        /* Get the data from the FADT */
+        TimerPort = HalpFixedAcpiDescTable.pm_tmr_blk_io_port;
+        TimerValExt = HalpFixedAcpiDescTable.flags & ACPI_TMR_VAL_EXT;
+    }
+    
+    /* FIXME: Now proceed to the timer initialization */
+    DPRINT1("ACPI Timer at: %Xh (EXT: %d)\n", TimerPort, TimerValExt);
+    //HalaAcpiTimerInit(TimerPort, TimerValExt);
+}
+
+NTSTATUS
+NTAPI
+HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    NTSTATUS Status;
+    PFADT Fadt;
+    ULONG TableLength;
+    PHYSICAL_ADDRESS PhysicalAddress;
+
+    /* Only do this once */
+    DPRINT1("You are booting the ACPI HAL!\n");
+    if (HalpProcessedACPIPhase0) return STATUS_SUCCESS;
+
+    /* Setup the ACPI table cache */
+    Status = HalpAcpiTableCacheInit(LoaderBlock);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Grab the FADT */
+    Fadt = HalAcpiGetTable(LoaderBlock, FADT_SIGNATURE);
+    if (!Fadt)
+    {
+        /* Fail */
+        DbgPrint("HAL: Didn't find the FACP\n");
+        return STATUS_NOT_FOUND;
+    }
+    
+    /* Assume typical size, otherwise whatever the descriptor table says */
+    DPRINT1("ACPI FACP at 0x%p\n", Fadt);
+    TableLength = sizeof(FADT);
+    if (Fadt->Header.Length < sizeof(FADT)) TableLength = Fadt->Header.Length;
+
+    /* Copy it in the HAL static buffer */
+    RtlCopyMemory(&HalpFixedAcpiDescTable, Fadt, TableLength);
+    
+    /* Anything special this HAL needs to do? */
+    HalpAcpiDetectMachineSpecificActions(LoaderBlock, &HalpFixedAcpiDescTable);
+    
+    /* Get the debug table for KD */
+    HalpDebugPortTable = HalAcpiGetTable(LoaderBlock, DBGP_SIGNATURE);
+    DPRINT1("ACPI DBGP at 0x%p\n", HalpDebugPortTable);
+    
+    /* Initialize NUMA through the SRAT */
+    HalpNumaInitializeStaticConfiguration(LoaderBlock);
+    
+    /* Initialize hotplug through the SRAT */
+    HalpDynamicSystemResourceConfiguration(LoaderBlock);    
+    DPRINT1("ACPI SRAT at 0x%p\n", HalpAcpiSrat);
+    if (HalpAcpiSrat)
+    {
+        DPRINT1("Your machine has a SRAT, but NUMA/HotPlug are not supported!\n");
+    }
+
+    /* Can there be memory higher than 4GB? */
+    if (HalpMaxHotPlugMemoryAddress.HighPart >= 1)
+    {
+        /* We'll need this for DMA later */
+        HalpPhysicalMemoryMayAppearAbove4GB = TRUE;
+    }
+    
+    /* Setup the ACPI timer */
+    HaliAcpiTimerInit(0, 0);
+    
+    /* Do we have a low stub address yet? */
+    if (!HalpLowStubPhysicalAddress.LowPart)
+    {
+        /* Allocate it */
+        HalpLowStubPhysicalAddress.LowPart = HalpAllocPhysicalMemory(LoaderBlock,
+                                                                     0x100000,
+                                                                     1,
+                                                                     FALSE);
+        if (HalpLowStubPhysicalAddress.LowPart)
+        {
+            /* Map it */
+            HalpLowStub = HalpMapPhysicalMemory64(HalpLowStubPhysicalAddress, 1);
+        }
+    }
+    
+    /* Grab a page for flushes */
+    PhysicalAddress.QuadPart = 0x100000;
+    HalpVirtAddrForFlush = HalpMapPhysicalMemory64(PhysicalAddress, 1);
+    HalpPteForFlush = HalAddressToPte(HalpVirtAddrForFlush);
+    
+    /* Don't do this again */
+    HalpProcessedACPIPhase0 = TRUE;
+    
+    /* Setup the boot table */
+    HalpInitBootTable(LoaderBlock);
+
+    /* Return success */
+    return STATUS_SUCCESS;
+}
+
+/* EOF */
index 8704b39..4309ac1 100644 (file)
@@ -307,6 +307,9 @@ HalInitSystem(IN ULONG BootPhase,
         }
 
 #ifndef _MINIHAL_
         }
 
 #ifndef _MINIHAL_
+        /* Initialize ACPI */
+        HalpSetupAcpiPhase0(LoaderBlock);
+
         /* Initialize the PICs */
         HalpInitializePICs(TRUE);
 #endif
         /* Initialize the PICs */
         HalpInitializePICs(TRUE);
 #endif
diff --git a/reactos/hal/halx86/generic/legacy/halpcat.c b/reactos/hal/halx86/generic/legacy/halpcat.c
new file mode 100644 (file)
index 0000000..bbabb9c
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            hal/halx86/generic/acpi/halpcat.c
+ * PURPOSE:         HAL Legacy Support Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+NTSTATUS
+NTAPI
+HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    /* There is no ACPI on these HALs */
+    return STATUS_NO_SUCH_DEVICE;
+}
+
+/* EOF */
index cc295ad..d8f8fa2 100644 (file)
@@ -7,6 +7,9 @@
                <define name="_NTHALDLL_" />
                <define name="_NTHAL_" />
                <directory name="generic">
                <define name="_NTHALDLL_" />
                <define name="_NTHAL_" />
                <directory name="generic">
+               <directory name="legacy">
+               <file>halpcat.c</file>
+           </directory>
                        <directory name="bus">
                                <file>bushndlr.c</file>
                                <file>isabus.c</file>
                        <directory name="bus">
                                <file>bushndlr.c</file>
                                <file>isabus.c</file>
@@ -53,6 +56,9 @@
                <define name="_NTHALDLL_" />
                <define name="_NTHAL_" />
                <directory name="generic">
                <define name="_NTHALDLL_" />
                <define name="_NTHAL_" />
                <directory name="generic">
+                   <directory name="acpi">
+                       <file>halacpi.c</file>
+                   </directory>
                        <directory name="bus">
                                <file>bushndlr.c</file>
                                <file>isabus.c</file>
                        <directory name="bus">
                                <file>bushndlr.c</file>
                                <file>isabus.c</file>