@@ -173,6 +173,7 @@ MempSetupPagingForRegion(
173173BOOLEAN
174174WinLdrSetupMemoryLayout (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,65 @@ 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+ union
249+ {
250+ PDESCRIPTION_HEADER Header ;
251+ PRSDT_DESCRIPTOR Rsdt ;
252+ PXSDT_DESCRIPTOR Xsdt ;
253+ } AcpiTable = {.Header = Extension -> AcpiTable };
254+
255+ BOOLEAN is64BitsTable = _strnicmp (AcpiTable .Header -> Signature , "XSDT" , 4 ) == 0 ;
256+ ULONG Entries = (AcpiTable .Header -> Length - sizeof (DESCRIPTION_HEADER )) / (is64BitsTable ? 8 : 4 );
257+ ULONG EntryOffset = 0 ;
258+
259+ for (ULONG i = 0 ; i < Entries ; i ++ )
260+ {
261+ PDESCRIPTION_HEADER Entry = is64BitsTable ?
262+ (PVOID )((ULONG_PTR )AcpiTable .Xsdt -> PointerToOtherSDT [i ]) :
263+ (PVOID )((ULONG_PTR )AcpiTable .Rsdt -> PointerToOtherSDT [i ]);
264+
265+ EntryOffset += Entry -> Length ;
266+ }
267+
268+ PCHAR EntriesClone = MmAllocateMemoryWithType (EntryOffset , LoaderFirmwarePermanent );
269+ if (!EntriesClone )
270+ {
271+ ERR ("Cannot allocate ACPI table entries\n" );
272+ return FALSE;
273+ }
274+ EntryOffset = 0 ;
275+
276+ for (ULONG i = 0 ; i < Entries ; i ++ )
277+ {
278+ PDESCRIPTION_HEADER Entry = is64BitsTable ?
279+ (PVOID )((ULONG_PTR )AcpiTable .Xsdt -> PointerToOtherSDT [i ]) :
280+ (PVOID )((ULONG_PTR )AcpiTable .Rsdt -> PointerToOtherSDT [i ]);
281+
282+ PDESCRIPTION_HEADER EntryClone = (PDESCRIPTION_HEADER )(EntriesClone + EntryOffset );
283+ RtlCopyMemory (EntryClone , Entry , Entry -> Length );
284+
285+ if (is64BitsTable )
286+ AcpiTable .Xsdt -> PointerToOtherSDT [i ] = (ULONGLONG )((ULONG_PTR )EntryClone );
287+ else
288+ AcpiTable .Rsdt -> PointerToOtherSDT [i ] = (ULONG )((ULONG_PTR )EntryClone );
289+
290+ EntryOffset += Entry -> Length ;
291+ }
292+ }
293+
234294 /* Before creating the map, we need to map pages to kernel mode */
235295 LastPageIndex = 1 ;
236296 LastPageType = MemoryMap [1 ].PageAllocated ;
0 commit comments