Skip to content

Commit 5ddfb38

Browse files
committed
[FREELDR] Pass the correct ACPI table for Windows
1 parent afb96ac commit 5ddfb38

File tree

8 files changed

+106
-36
lines changed

8 files changed

+106
-36
lines changed

boot/freeldr/freeldr/arch/i386/hwacpi.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,20 @@ FindAcpiBios(VOID)
5454
return NULL;
5555
}
5656

57+
PVOID
58+
FindAcpiTable(VOID)
59+
{
60+
PRSDP_DESCRIPTOR Rsdp = FindAcpiBios();
61+
if (!Rsdp)
62+
return NULL;
63+
64+
PVOID OutputPointer = (Rsdp->revision > 1 && Rsdp->xsdt_physical_address) ?
65+
(PVOID)((ULONG_PTR)Rsdp->xsdt_physical_address) :
66+
(PVOID)((ULONG_PTR)Rsdp->rsdt_physical_address);
67+
68+
TRACE("ACPI table at 0x%p\n", OutputPointer);
69+
return OutputPointer;
70+
}
5771

5872
VOID
5973
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
@@ -99,16 +113,11 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
99113
/* Fill the table */
100114
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
101115

102-
if (Rsdp->revision > 0)
103-
{
104-
TRACE("ACPI >1.0, using XSDT address\n");
116+
TRACE("ACPI %s1.0, using %cSDT address\n", Rsdp->revision > 1 ? ">" : "", Rsdp->revision > 1 ? 'X' : 'R');
117+
if (Rsdp->revision > 1 && Rsdp->xsdt_physical_address)
105118
AcpiBiosData->RSDTAddress.QuadPart = Rsdp->xsdt_physical_address;
106-
}
107119
else
108-
{
109-
TRACE("ACPI 1.0, using RSDT address\n");
110120
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
111-
}
112121

113122
AcpiBiosData->Count = PcBiosMapCount;
114123
memcpy(AcpiBiosData->MemoryMap, PcBiosMemoryMap,

boot/freeldr/freeldr/arch/uefi/uefihw.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ FindAcpiBios(VOID)
5050
return rsdp;
5151
}
5252

53+
PVOID
54+
FindAcpiTable(VOID)
55+
{
56+
PRSDP_DESCRIPTOR Rsdp = FindAcpiBios();
57+
if (!Rsdp)
58+
return NULL;
59+
60+
PVOID OutputPointer = (Rsdp->revision > 1 && Rsdp->xsdt_physical_address) ?
61+
(PVOID)((ULONG_PTR)Rsdp->xsdt_physical_address) :
62+
(PVOID)((ULONG_PTR)Rsdp->rsdt_physical_address);
63+
64+
TRACE("ACPI table at 0x%p\n", OutputPointer);
65+
return OutputPointer;
66+
}
67+
5368
VOID
5469
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
5570
{
@@ -93,16 +108,11 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
93108
/* Fill the table */
94109
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
95110

96-
if (Rsdp->revision > 0)
97-
{
98-
TRACE("ACPI >1.0, using XSDT address\n");
111+
TRACE("ACPI %s1.0, using %cSDT address\n", Rsdp->revision > 1 ? ">" : "", Rsdp->revision > 1 ? 'X' : 'R');
112+
if (Rsdp->revision > 1 && Rsdp->xsdt_physical_address)
99113
AcpiBiosData->RSDTAddress.QuadPart = Rsdp->xsdt_physical_address;
100-
}
101114
else
102-
{
103-
TRACE("ACPI 1.0, using RSDT address\n");
104115
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
105-
}
106116

107117
AcpiBiosData->Count = FreeldrDescCount;
108118
memcpy(AcpiBiosData->MemoryMap, EfiMemoryMap,

boot/freeldr/freeldr/freeldr.spec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
@ cdecl GetArgumentValue()
109109
@ cdecl GetBootMgrInfo()
110110
@ cdecl IsAcpiPresent()
111+
@ cdecl FindAcpiTable()
111112
@ cdecl LoadSettings()
112113
@ cdecl MachHwDetect()
113114
@ cdecl MachPrepareForReactOS()

boot/freeldr/freeldr/include/arch/pc/hardware.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
7373
PCONFIGURATION_COMPONENT_DATA BusKey);
7474

7575
/* hwacpi.c */
76+
PVOID FindAcpiTable(VOID);
7677
VOID DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber);
7778

7879
/* hwapm.c */
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* PROJECT: FreeLoader
3+
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4+
* PURPOSE: Define ACPI Structures
5+
* COPYRIGHT: Copyright 2006-2019 Aleksey Bragin <[email protected]>
6+
* Copyright 2024 Daniel Victor <[email protected]>
7+
*/
8+
9+
#pragma once
10+
11+
#include <pshpack1.h>
12+
13+
typedef struct /* ACPI Description Header */
14+
{
15+
CHAR Signature[4];
16+
ULONG Length;
17+
UCHAR Revision;
18+
UCHAR Checksum;
19+
CHAR OEMID[6];
20+
CHAR OEMTableID[8];
21+
ULONG OEMRevision;
22+
ULONG CreatorID;
23+
ULONG CreatorRev;
24+
} DESCRIPTION_HEADER, *PDESCRIPTION_HEADER;
25+
26+
typedef struct /* Root System Descriptor Table */
27+
{
28+
DESCRIPTION_HEADER Header;
29+
ULONG PointerToOtherSDT[];
30+
} RSDT_DESCRIPTOR, *PRSDT_DESCRIPTOR;
31+
32+
typedef struct /* eXtended System Descriptor Table */
33+
{
34+
DESCRIPTION_HEADER Header;
35+
ULONGLONG PointerToOtherSDT[];
36+
} XSDT_DESCRIPTOR, *PXSDT_DESCRIPTOR;
37+
38+
typedef struct /* Root System Descriptor Pointer */
39+
{
40+
CHAR signature [8]; /* contains "RSD PTR " */
41+
UCHAR checksum; /* to make sum of struct == 0 */
42+
CHAR oem_id [6]; /* OEM identification */
43+
UCHAR revision; /* Must be 0 for 1.0, 2 for 2.0 */
44+
ULONG rsdt_physical_address; /* 32-bit physical address of RSDT */
45+
ULONG length; /* XSDT Length in bytes including hdr */
46+
ULONGLONG xsdt_physical_address; /* 64-bit physical address of XSDT */
47+
UCHAR extended_checksum; /* Checksum of entire table */
48+
CHAR reserved [3]; /* reserved field must be 0 */
49+
} RSDP_DESCRIPTOR, *PRSDP_DESCRIPTOR;
50+
51+
#include <poppack.h>

boot/freeldr/freeldr/include/ntldr/winldr.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,13 @@
88
#pragma once
99

1010
#include <arc/setupblk.h>
11+
#include <hwacpi.h>
1112

1213
// See freeldr/ntldr/winldr.h
1314
#define TAG_WLDR_DTE 'eDlW'
1415
#define TAG_WLDR_BDE 'dBlW'
1516
#define TAG_WLDR_NAME 'mNlW'
1617

17-
// Some definitions
18-
19-
#include <pshpack1.h>
20-
typedef struct /* Root System Descriptor Pointer */
21-
{
22-
CHAR signature [8]; /* contains "RSD PTR " */
23-
UCHAR checksum; /* to make sum of struct == 0 */
24-
CHAR oem_id [6]; /* OEM identification */
25-
UCHAR revision; /* Must be 0 for 1.0, 2 for 2.0 */
26-
ULONG rsdt_physical_address; /* 32-bit physical address of RSDT */
27-
ULONG length; /* XSDT Length in bytes including hdr */
28-
ULONGLONG xsdt_physical_address; /* 64-bit physical address of XSDT */
29-
UCHAR extended_checksum; /* Checksum of entire table */
30-
CHAR reserved [3]; /* reserved field must be 0 */
31-
} RSDP_DESCRIPTOR, *PRSDP_DESCRIPTOR;
32-
#include <poppack.h>
33-
3418
typedef struct _ARC_DISK_SIGNATURE_EX
3519
{
3620
ARC_DISK_SIGNATURE DiskSignature;

boot/freeldr/freeldr/ntldr/winldr.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,11 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
246246
/* FIXME! HACK value for docking profile */
247247
Extension->Profile.Status = 2;
248248

249-
/* Check if FreeLdr detected a ACPI table */
250-
if (IsAcpiPresent())
249+
PDESCRIPTION_HEADER AcpiTable = FindAcpiTable();
250+
if (AcpiTable)
251251
{
252-
/* Set the pointer to something for compatibility */
253-
Extension->AcpiTable = (PVOID)1;
254-
// FIXME: Extension->AcpiTableSize;
252+
Extension->AcpiTable = AcpiTable;
253+
Extension->AcpiTableSize = AcpiTable->Length;
255254
}
256255

257256
if (VersionToBoot >= _WIN32_WINNT_VISTA)

boot/freeldr/freeldr/ntldr/wlmemory.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ MempSetupPagingForRegion(
173173
BOOLEAN
174174
WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
175175
{
176+
PLOADER_PARAMETER_EXTENSION Extension = VaToPa(LoaderBlock->Extension);
176177
PFN_NUMBER i, PagesCount, MemoryMapSizeInPages, NoEntries;
177178
PFN_NUMBER LastPageIndex, MemoryMapStartPage;
178179
PPAGE_LOOKUP_TABLE_ITEM MemoryMap;
@@ -231,6 +232,20 @@ WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
231232
return FALSE;
232233
}
233234

235+
// Always map the ACPI table if present, otherwise Windows will crash.
236+
if (Extension->AcpiTable)
237+
{
238+
PVOID AcpiTableClone = MmAllocateMemoryWithType(Extension->AcpiTableSize, LoaderFirmwarePermanent);
239+
if (!AcpiTableClone)
240+
{
241+
ERR("Cannot allocate ACPI table\n");
242+
return FALSE;
243+
}
244+
245+
RtlCopyMemory(AcpiTableClone, Extension->AcpiTable, Extension->AcpiTableSize);
246+
Extension->AcpiTable = AcpiTableClone;
247+
}
248+
234249
/* Before creating the map, we need to map pages to kernel mode */
235250
LastPageIndex = 1;
236251
LastPageType = MemoryMap[1].PageAllocated;

0 commit comments

Comments
 (0)