[FREELDR] Pass the correct ACPI table for Windows (#7486)

JIRA issue: CORE-11954 and CORE-18969

This PR passes the real ACPI table instead of a hardcoded (PVOID)1.
This commit is contained in:
Daniel Victor
2025-03-24 21:49:39 +01:00
committed by GitHub
parent 74599f6c97
commit 185225a5fc
8 changed files with 106 additions and 36 deletions
+16 -7
View File
@@ -54,6 +54,20 @@ FindAcpiBios(VOID)
return NULL;
}
PVOID
FindAcpiTable(VOID)
{
PRSDP_DESCRIPTOR Rsdp = FindAcpiBios();
if (!Rsdp)
return NULL;
PVOID OutputPointer = (Rsdp->revision > 1 && Rsdp->xsdt_physical_address) ?
(PVOID)((ULONG_PTR)Rsdp->xsdt_physical_address) :
(PVOID)((ULONG_PTR)Rsdp->rsdt_physical_address);
TRACE("ACPI table at 0x%p\n", OutputPointer);
return OutputPointer;
}
VOID
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
@@ -99,16 +113,11 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
/* Fill the table */
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
if (Rsdp->revision > 0)
{
TRACE("ACPI >1.0, using XSDT address\n");
TRACE("ACPI %s1.0, using %cSDT address\n", Rsdp->revision > 1 ? ">" : "", Rsdp->revision > 1 ? 'X' : 'R');
if (Rsdp->revision > 1 && Rsdp->xsdt_physical_address)
AcpiBiosData->RSDTAddress.QuadPart = Rsdp->xsdt_physical_address;
}
else
{
TRACE("ACPI 1.0, using RSDT address\n");
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
}
AcpiBiosData->Count = PcBiosMapCount;
memcpy(AcpiBiosData->MemoryMap, PcBiosMemoryMap,
+17 -7
View File
@@ -50,6 +50,21 @@ FindAcpiBios(VOID)
return rsdp;
}
PVOID
FindAcpiTable(VOID)
{
PRSDP_DESCRIPTOR Rsdp = FindAcpiBios();
if (!Rsdp)
return NULL;
PVOID OutputPointer = (Rsdp->revision > 1 && Rsdp->xsdt_physical_address) ?
(PVOID)((ULONG_PTR)Rsdp->xsdt_physical_address) :
(PVOID)((ULONG_PTR)Rsdp->rsdt_physical_address);
TRACE("ACPI table at 0x%p\n", OutputPointer);
return OutputPointer;
}
VOID
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
@@ -93,16 +108,11 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
/* Fill the table */
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
if (Rsdp->revision > 0)
{
TRACE("ACPI >1.0, using XSDT address\n");
TRACE("ACPI %s1.0, using %cSDT address\n", Rsdp->revision > 1 ? ">" : "", Rsdp->revision > 1 ? 'X' : 'R');
if (Rsdp->revision > 1 && Rsdp->xsdt_physical_address)
AcpiBiosData->RSDTAddress.QuadPart = Rsdp->xsdt_physical_address;
}
else
{
TRACE("ACPI 1.0, using RSDT address\n");
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
}
AcpiBiosData->Count = FreeldrDescCount;
memcpy(AcpiBiosData->MemoryMap, EfiMemoryMap,
+1
View File
@@ -108,6 +108,7 @@
@ cdecl GetArgumentValue()
@ cdecl GetBootMgrInfo()
@ cdecl IsAcpiPresent()
@ cdecl FindAcpiTable()
@ cdecl LoadSettings()
@ cdecl MachHwDetect()
@ cdecl MachPrepareForReactOS()
@@ -84,6 +84,7 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
PCONFIGURATION_COMPONENT_DATA BusKey);
/* hwacpi.c */
PVOID FindAcpiTable(VOID);
VOID DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber);
/* hwapm.c */
+51
View File
@@ -0,0 +1,51 @@
/*
* PROJECT: FreeLoader
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Define ACPI Structures
* COPYRIGHT: Copyright 2006-2019 Aleksey Bragin <[email protected]>
* Copyright 2024 Daniel Victor <[email protected]>
*/
#pragma once
#include <pshpack1.h>
typedef struct /* ACPI Description Header */
{
CHAR Signature[4];
ULONG Length;
UCHAR Revision;
UCHAR Checksum;
CHAR OEMID[6];
CHAR OEMTableID[8];
ULONG OEMRevision;
ULONG CreatorID;
ULONG CreatorRev;
} DESCRIPTION_HEADER, *PDESCRIPTION_HEADER;
typedef struct /* Root System Descriptor Table */
{
DESCRIPTION_HEADER Header;
ULONG PointerToOtherSDT[];
} RSDT_DESCRIPTOR, *PRSDT_DESCRIPTOR;
typedef struct /* eXtended System Descriptor Table */
{
DESCRIPTION_HEADER Header;
ULONGLONG PointerToOtherSDT[];
} XSDT_DESCRIPTOR, *PXSDT_DESCRIPTOR;
typedef struct /* Root System Descriptor Pointer */
{
CHAR signature [8]; /* contains "RSD PTR " */
UCHAR checksum; /* to make sum of struct == 0 */
CHAR oem_id [6]; /* OEM identification */
UCHAR revision; /* Must be 0 for 1.0, 2 for 2.0 */
ULONG rsdt_physical_address; /* 32-bit physical address of RSDT */
ULONG length; /* XSDT Length in bytes including hdr */
ULONGLONG xsdt_physical_address; /* 64-bit physical address of XSDT */
UCHAR extended_checksum; /* Checksum of entire table */
CHAR reserved [3]; /* reserved field must be 0 */
} RSDP_DESCRIPTOR, *PRSDP_DESCRIPTOR;
#include <poppack.h>
+1 -17
View File
@@ -8,29 +8,13 @@
#pragma once
#include <arc/setupblk.h>
#include <hwacpi.h>
// See freeldr/ntldr/winldr.h
#define TAG_WLDR_DTE 'eDlW'
#define TAG_WLDR_BDE 'dBlW'
#define TAG_WLDR_NAME 'mNlW'
// Some definitions
#include <pshpack1.h>
typedef struct /* Root System Descriptor Pointer */
{
CHAR signature [8]; /* contains "RSD PTR " */
UCHAR checksum; /* to make sum of struct == 0 */
CHAR oem_id [6]; /* OEM identification */
UCHAR revision; /* Must be 0 for 1.0, 2 for 2.0 */
ULONG rsdt_physical_address; /* 32-bit physical address of RSDT */
ULONG length; /* XSDT Length in bytes including hdr */
ULONGLONG xsdt_physical_address; /* 64-bit physical address of XSDT */
UCHAR extended_checksum; /* Checksum of entire table */
CHAR reserved [3]; /* reserved field must be 0 */
} RSDP_DESCRIPTOR, *PRSDP_DESCRIPTOR;
#include <poppack.h>
typedef struct _ARC_DISK_SIGNATURE_EX
{
ARC_DISK_SIGNATURE DiskSignature;
+4 -5
View File
@@ -246,12 +246,11 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
/* FIXME! HACK value for docking profile */
Extension->Profile.Status = 2;
/* Check if FreeLdr detected a ACPI table */
if (IsAcpiPresent())
PDESCRIPTION_HEADER AcpiTable = FindAcpiTable();
if (AcpiTable)
{
/* Set the pointer to something for compatibility */
Extension->AcpiTable = (PVOID)1;
// FIXME: Extension->AcpiTableSize;
Extension->AcpiTable = AcpiTable;
Extension->AcpiTableSize = AcpiTable->Length;
}
if (VersionToBoot >= _WIN32_WINNT_VISTA)
+15
View File
@@ -173,6 +173,7 @@ MempSetupPagingForRegion(
BOOLEAN
WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PLOADER_PARAMETER_EXTENSION Extension = VaToPa(LoaderBlock->Extension);
PFN_NUMBER i, PagesCount, MemoryMapSizeInPages, NoEntries;
PFN_NUMBER LastPageIndex, MemoryMapStartPage;
PPAGE_LOOKUP_TABLE_ITEM MemoryMap;
@@ -231,6 +232,20 @@ WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
return FALSE;
}
// Always map the ACPI table if present, otherwise Windows will crash.
if (Extension->AcpiTable)
{
PVOID AcpiTableClone = MmAllocateMemoryWithType(Extension->AcpiTableSize, LoaderFirmwarePermanent);
if (!AcpiTableClone)
{
ERR("Cannot allocate ACPI table\n");
return FALSE;
}
RtlCopyMemory(AcpiTableClone, Extension->AcpiTable, Extension->AcpiTableSize);
Extension->AcpiTable = AcpiTableClone;
}
/* Before creating the map, we need to map pages to kernel mode */
LastPageIndex = 1;
LastPageType = MemoryMap[1].PageAllocated;