diff --git a/boot/freeldr/freeldr/arch/i386/hwacpi.c b/boot/freeldr/freeldr/arch/i386/hwacpi.c index f2b43fde015..4241a89a2f3 100644 --- a/boot/freeldr/freeldr/arch/i386/hwacpi.c +++ b/boot/freeldr/freeldr/arch/i386/hwacpi.c @@ -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, diff --git a/boot/freeldr/freeldr/arch/uefi/uefihw.c b/boot/freeldr/freeldr/arch/uefi/uefihw.c index 674d4bff84d..42f2d5376d5 100644 --- a/boot/freeldr/freeldr/arch/uefi/uefihw.c +++ b/boot/freeldr/freeldr/arch/uefi/uefihw.c @@ -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, diff --git a/boot/freeldr/freeldr/freeldr.spec b/boot/freeldr/freeldr/freeldr.spec index eaab809e800..f43c37ac938 100644 --- a/boot/freeldr/freeldr/freeldr.spec +++ b/boot/freeldr/freeldr/freeldr.spec @@ -108,6 +108,7 @@ @ cdecl GetArgumentValue() @ cdecl GetBootMgrInfo() @ cdecl IsAcpiPresent() +@ cdecl FindAcpiTable() @ cdecl LoadSettings() @ cdecl MachHwDetect() @ cdecl MachPrepareForReactOS() diff --git a/boot/freeldr/freeldr/include/arch/pc/hardware.h b/boot/freeldr/freeldr/include/arch/pc/hardware.h index 6ca98ed6a0c..fb0c4b05677 100644 --- a/boot/freeldr/freeldr/include/arch/pc/hardware.h +++ b/boot/freeldr/freeldr/include/arch/pc/hardware.h @@ -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 */ diff --git a/boot/freeldr/freeldr/include/hwacpi.h b/boot/freeldr/freeldr/include/hwacpi.h new file mode 100644 index 00000000000..8ff783f77f4 --- /dev/null +++ b/boot/freeldr/freeldr/include/hwacpi.h @@ -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 + * Copyright 2024 Daniel Victor + */ + +#pragma once + +#include + +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 diff --git a/boot/freeldr/freeldr/include/ntldr/winldr.h b/boot/freeldr/freeldr/include/ntldr/winldr.h index 42ee1ba1da1..49f44ff3de3 100644 --- a/boot/freeldr/freeldr/include/ntldr/winldr.h +++ b/boot/freeldr/freeldr/include/ntldr/winldr.h @@ -8,29 +8,13 @@ #pragma once #include +#include // See freeldr/ntldr/winldr.h #define TAG_WLDR_DTE 'eDlW' #define TAG_WLDR_BDE 'dBlW' #define TAG_WLDR_NAME 'mNlW' -// Some definitions - -#include -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 - typedef struct _ARC_DISK_SIGNATURE_EX { ARC_DISK_SIGNATURE DiskSignature; diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c index 198c673d962..4e2cef15bf3 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.c +++ b/boot/freeldr/freeldr/ntldr/winldr.c @@ -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) diff --git a/boot/freeldr/freeldr/ntldr/wlmemory.c b/boot/freeldr/freeldr/ntldr/wlmemory.c index 1be38e97864..c9bce048110 100644 --- a/boot/freeldr/freeldr/ntldr/wlmemory.c +++ b/boot/freeldr/freeldr/ntldr/wlmemory.c @@ -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;