3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/generic/acpi/halacpi.c
5 * PURPOSE: HAL ACPI Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 LIST_ENTRY HalpAcpiTableCacheList
;
18 FAST_MUTEX HalpAcpiTableCacheLock
;
20 BOOLEAN HalpProcessedACPIPhase0
;
21 BOOLEAN HalpPhysicalMemoryMayAppearAbove4GB
;
23 FADT HalpFixedAcpiDescTable
;
24 PDEBUG_PORT_TABLE HalpDebugPortTable
;
25 PACPI_SRAT HalpAcpiSrat
;
26 PBOOT_TABLE HalpSimpleBootFlagTable
;
28 PHYSICAL_ADDRESS HalpMaxHotPlugMemoryAddress
;
29 PHYSICAL_ADDRESS HalpLowStubPhysicalAddress
;
30 PHARDWARE_PTE HalpPteForFlush
;
31 PVOID HalpVirtAddrForFlush
;
34 PACPI_BIOS_MULTI_NODE HalpAcpiMultiNode
;
36 LIST_ENTRY HalpAcpiTableMatchList
;
38 ULONG HalpInvalidAcpiTable
;
40 /* PRIVATE FUNCTIONS **********************************************************/
44 HalpAcpiGetCachedTable(IN ULONG Signature
)
46 PLIST_ENTRY ListHead
, NextEntry
;
47 PACPI_CACHED_TABLE CachedTable
;
49 /* Loop cached tables */
50 ListHead
= &HalpAcpiTableCacheList
;
51 NextEntry
= ListHead
->Flink
;
52 while (NextEntry
!= ListHead
)
55 CachedTable
= CONTAINING_RECORD(NextEntry
, ACPI_CACHED_TABLE
, Links
);
57 /* Compare signatures */
58 if (CachedTable
->Header
.Signature
== Signature
) return &CachedTable
->Header
;
61 NextEntry
= NextEntry
->Flink
;
70 HalpAcpiCacheTable(IN PDESCRIPTION_HEADER TableHeader
)
72 PACPI_CACHED_TABLE CachedTable
;
74 /* Get the cached table and link it */
75 CachedTable
= CONTAINING_RECORD(TableHeader
, ACPI_CACHED_TABLE
, Header
);
76 InsertTailList(&HalpAcpiTableCacheList
, &CachedTable
->Links
);
81 HalpAcpiCopyBiosTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
82 IN PDESCRIPTION_HEADER TableHeader
)
86 PHYSICAL_ADDRESS PhysAddress
;
87 PACPI_CACHED_TABLE CachedTable
;
88 PDESCRIPTION_HEADER CopiedTable
;
90 /* Size we'll need for the cached table */
91 Size
= TableHeader
->Length
+ FIELD_OFFSET(ACPI_CACHED_TABLE
, Header
);
94 /* Phase 0: Convert to pages and use the HAL heap */
95 PageCount
= BYTES_TO_PAGES(Size
);
96 PhysAddress
.LowPart
= HalpAllocPhysicalMemory(LoaderBlock
,
100 if (PhysAddress
.LowPart
)
103 CachedTable
= HalpMapPhysicalMemory64(PhysAddress
, PageCount
);
107 /* No memory, so nothing to map */
114 CachedTable
= ExAllocatePoolWithTag(NonPagedPool
, Size
, ' laH');
117 /* Do we have the cached table? */
121 CopiedTable
= &CachedTable
->Header
;
122 RtlCopyMemory(CopiedTable
, TableHeader
, TableHeader
->Length
);
126 /* Nothing to return */
130 /* Return the table */
136 HalpAcpiGetTableFromBios(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
139 PHYSICAL_ADDRESS PhysicalAddress
;
143 PDESCRIPTION_HEADER Header
= NULL
;
147 ULONG EntryCount
, CurrentEntry
;
149 PFN_NUMBER PageCount
;
151 /* Should not query the RSDT/XSDT by itself */
152 if ((Signature
== RSDT_SIGNATURE
) || (Signature
== XSDT_SIGNATURE
)) return NULL
;
154 /* Special case request for DSDT, because the FADT points to it */
155 if (Signature
== DSDT_SIGNATURE
)
158 Fadt
= HalpAcpiGetTable(LoaderBlock
, FADT_SIGNATURE
);
161 /* Grab the DSDT address and assume 2 pages */
162 PhysicalAddress
.LowPart
= Fadt
->dsdt
;
163 TableLength
= 2 * PAGE_SIZE
;
168 /* Phase 0, use HAL heap */
169 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, 2u);
173 /* Phase 1, use Mm */
174 Header
= MmMapIoSpace(PhysicalAddress
, 2 * PAGE_SIZE
, 0);
177 /* Fail if we couldn't map it */
180 DbgPrint("HAL: Failed to map ACPI table.\n");
184 /* Validate the signature */
185 DPRINT1("ACPI DSDT at 0x%p\n", Header
);
186 if (Header
->Signature
!= DSDT_SIGNATURE
)
192 HalpUnmapVirtualAddress(Header
, 2);
197 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
200 /* Didn't find anything */
206 /* Couldn't find it */
212 /* To find tables, we need the RSDT */
213 Rsdt
= HalpAcpiGetTable(LoaderBlock
, RSDT_SIGNATURE
);
216 /* Won't be using the XSDT */
221 /* Only other choice is to use the XSDT */
222 Xsdt
= HalpAcpiGetTable(LoaderBlock
, XSDT_SIGNATURE
);
223 if (!Xsdt
) return NULL
;
225 /* Won't be using the RSDT */
226 DPRINT1("ACPI XSDT at 0x%p\n", Xsdt
);
230 /* Smallest RSDT/XSDT is one without table entries */
231 Offset
= FIELD_OFFSET(RSDT
, Tables
);
234 /* Figure out total size of table and the offset */
235 TableLength
= Xsdt
->Header
.Length
;
236 if (TableLength
< Offset
) Offset
= Xsdt
->Header
.Length
;
238 /* The entries are each 64-bits, so count them */
239 EntryCount
= (TableLength
- Offset
) / sizeof(PHYSICAL_ADDRESS
);
243 /* Figure out total size of table and the offset */
244 TableLength
= Rsdt
->Header
.Length
;
245 if (TableLength
< Offset
) Offset
= Rsdt
->Header
.Length
;
247 /* The entries are each 32-bits, so count them */
248 EntryCount
= (TableLength
- Offset
) / sizeof(ULONG
);
251 /* Start at the beginning of the array and loop it */
252 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
; CurrentEntry
++)
254 /* Are we using the XSDT? */
257 /* Read the 32-bit physical address */
258 PhysicalAddress
.LowPart
= Rsdt
->Tables
[CurrentEntry
];
262 /* Read the 64-bit physical address */
263 PhysicalAddress
= Xsdt
->Tables
[CurrentEntry
];
266 /* Had we already mapped a table? */
273 HalpUnmapVirtualAddress(Header
, 2);
278 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
282 /* Now map this table */
285 /* Phase 1: Use HAL heap */
286 Header
= MmMapIoSpace(PhysicalAddress
, 2 * PAGE_SIZE
, MmNonCached
);
290 /* Phase 0: Use Mm */
291 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, 2);
294 /* Check if we mapped it */
298 DbgPrint("HAL: Failed to map ACPI table.\n");
302 /* We found it, break out */
303 DPRINT("Found ACPI table %c%c%c%c at 0x%p\n",
304 Header
->Signature
& 0xFF,
305 (Header
->Signature
& 0xFF00) >> 8,
306 (Header
->Signature
& 0xFF0000) >> 16,
307 (Header
->Signature
& 0xFF000000) >> 24,
309 if (Header
->Signature
== Signature
) break;
312 /* Did we end up here back at the last entry? */
313 if (CurrentEntry
== EntryCount
)
315 /* Yes, unmap the last table we processed */
319 HalpUnmapVirtualAddress(Header
, 2);
324 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
327 /* Didn't find anything */
332 /* Past this point, we assume something was found */
335 /* How many pages do we need? */
336 PageCount
= BYTES_TO_PAGES(Header
->Length
);
339 /* We assumed two, but this is not the case, free the current mapping */
343 HalpUnmapVirtualAddress(Header
, 2);
348 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
351 /* Now map this table using its correct size */
354 /* Phase 1: Use HAL heap */
355 Header
= MmMapIoSpace(PhysicalAddress
, PageCount
<< PAGE_SHIFT
, MmNonCached
);
359 /* Phase 0: Use Mm */
360 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, PageCount
);
364 /* Fail if the remapped failed */
365 if (!Header
) return NULL
;
367 /* All tables in ACPI 3.0 other than the FACP should have correct checksum */
368 if ((Header
->Signature
!= FADT_SIGNATURE
) || (Header
->Revision
> 2))
370 /* Go to the end of the table */
372 CurrentByte
= (PCHAR
)Header
+ Header
->Length
;
373 while (CurrentByte
-- != (PCHAR
)Header
)
376 CheckSum
+= *CurrentByte
;
379 /* The correct checksum is always 0, anything else is illegal */
380 if (CheckSum
) HalpInvalidAcpiTable
= Header
->Signature
;
383 /* Return the table */
389 HalpAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
392 PFN_NUMBER PageCount
;
393 PDESCRIPTION_HEADER TableAddress
, BiosCopy
;
395 /* See if we have a cached table? */
396 TableAddress
= HalpAcpiGetCachedTable(Signature
);
399 /* No cache, search the BIOS */
400 TableAddress
= HalpAcpiGetTableFromBios(LoaderBlock
, Signature
);
403 /* Found it, copy it into our own memory */
404 BiosCopy
= HalpAcpiCopyBiosTable(LoaderBlock
, TableAddress
);
406 /* Get the pages, and unmap the BIOS copy */
407 PageCount
= BYTES_TO_PAGES(TableAddress
->Length
);
410 /* Phase 0, use the HAL heap */
411 HalpUnmapVirtualAddress(TableAddress
, PageCount
);
415 /* Phase 1, use Mm */
416 MmUnmapIoSpace(TableAddress
, PageCount
<< 12);
419 /* Cache the bios copy */
420 TableAddress
= BiosCopy
;
421 if (BiosCopy
) HalpAcpiCacheTable(BiosCopy
);
425 /* Return the table */
431 HalAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
434 PDESCRIPTION_HEADER TableHeader
;
439 /* Initialize the cache first */
440 if (!NT_SUCCESS(HalpAcpiTableCacheInit(LoaderBlock
))) return NULL
;
445 ExAcquireFastMutex(&HalpAcpiTableCacheLock
);
449 TableHeader
= HalpAcpiGetTable(LoaderBlock
, Signature
);
451 /* Release the lock in phase 1 */
452 if (!LoaderBlock
) ExReleaseFastMutex(&HalpAcpiTableCacheLock
);
454 /* Return the table */
460 HalpNumaInitializeStaticConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
462 PACPI_SRAT SratTable
;
464 /* Get the SRAT, bail out if it doesn't exist */
465 SratTable
= HalAcpiGetTable(LoaderBlock
, SRAT_SIGNATURE
);
466 HalpAcpiSrat
= SratTable
;
467 if (!SratTable
) return;
472 HalpGetHotPlugMemoryInfo(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
474 PACPI_SRAT SratTable
;
476 /* Get the SRAT, bail out if it doesn't exist */
477 SratTable
= HalAcpiGetTable(LoaderBlock
, SRAT_SIGNATURE
);
478 HalpAcpiSrat
= SratTable
;
479 if (!SratTable
) return;
484 HalpDynamicSystemResourceConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
486 /* For this HAL, it means to get hot plug memory information */
487 HalpGetHotPlugMemoryInfo(LoaderBlock
);
492 HalpAcpiDetectMachineSpecificActions(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
493 IN PFADT DescriptionTable
)
495 /* Does this HAL specify something? */
496 if (HalpAcpiTableMatchList
.Flink
)
498 /* Great, but we don't support it */
499 DPRINT1("WARNING: Your HAL has specific ACPI hacks to apply!\n");
505 HalpInitBootTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
507 PBOOT_TABLE BootTable
;
509 /* Get the boot table */
510 BootTable
= HalAcpiGetTable(LoaderBlock
, BOOT_SIGNATURE
);
511 HalpSimpleBootFlagTable
= BootTable
;
512 DPRINT1("ACPI BOOT at 0x%p\n", HalpSimpleBootFlagTable
);
516 (BootTable
->Header
.Length
>= sizeof(BOOT_TABLE
)) &&
517 (BootTable
->CMOSIndex
>= 9))
519 DPRINT1("ACPI Boot table found, but not supported!\n");
523 /* Invalid or doesn't exist, ignore it */
524 HalpSimpleBootFlagTable
= 0;
527 /* Install the end of boot handler */
528 // HalEndOfBoot = HalpEndOfBoot;
533 HalpAcpiFindRsdtPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
534 OUT PACPI_BIOS_MULTI_NODE
* AcpiMultiNode
)
536 PCONFIGURATION_COMPONENT_DATA ComponentEntry
;
537 PCONFIGURATION_COMPONENT_DATA Next
= NULL
;
538 PCM_PARTIAL_RESOURCE_LIST ResourceList
;
539 PACPI_BIOS_MULTI_NODE NodeData
;
541 PFN_NUMBER PageCount
;
543 PHYSICAL_ADDRESS PhysicalAddress
;
545 /* Did we already do this once? */
546 if (HalpAcpiMultiNode
)
548 /* Return what we know */
549 *AcpiMultiNode
= HalpAcpiMultiNode
;
550 return STATUS_SUCCESS
;
554 *AcpiMultiNode
= NULL
;
556 /* Find the multi function adapter key */
557 ComponentEntry
= KeFindConfigurationNextEntry(LoaderBlock
->ConfigurationRoot
,
559 MultiFunctionAdapter
,
562 while (ComponentEntry
)
564 /* Find the ACPI BIOS key */
565 if (!_stricmp(ComponentEntry
->ComponentEntry
.Identifier
, "ACPI BIOS"))
572 Next
= ComponentEntry
;
573 ComponentEntry
= KeFindConfigurationNextEntry(LoaderBlock
->ConfigurationRoot
,
575 MultiFunctionAdapter
,
580 /* Make sure we found it */
583 DbgPrint("**** HalpAcpiFindRsdtPhase0: did NOT find RSDT\n");
584 return STATUS_NOT_FOUND
;
587 /* The configuration data is a resource list, and the BIOS node follows */
588 ResourceList
= ComponentEntry
->ConfigurationData
;
589 NodeData
= (PACPI_BIOS_MULTI_NODE
)(ResourceList
+ 1);
591 /* How many E820 memory entries are there? */
592 NodeLength
= sizeof(ACPI_BIOS_MULTI_NODE
) +
593 (NodeData
->Count
- 1) * sizeof(ACPI_E820_ENTRY
);
595 /* Convert to pages */
596 PageCount
= BYTES_TO_PAGES(NodeLength
);
598 /* Allocate the memory */
599 PhysicalAddress
.LowPart
= HalpAllocPhysicalMemory(LoaderBlock
,
603 if (PhysicalAddress
.LowPart
)
605 /* Map it if the allocation worked */
606 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, PageCount
);
610 /* Otherwise we'll have to fail */
611 MappedAddress
= NULL
;
614 /* Save the multi node, bail out if we didn't find it */
615 HalpAcpiMultiNode
= MappedAddress
;
616 if (!MappedAddress
) return STATUS_INSUFFICIENT_RESOURCES
;
618 /* Copy the multi-node data */
619 RtlCopyMemory(MappedAddress
, NodeData
, NodeLength
);
621 /* Return the data */
622 *AcpiMultiNode
= HalpAcpiMultiNode
;
623 return STATUS_SUCCESS
;
628 HalpAcpiTableCacheInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
630 PACPI_BIOS_MULTI_NODE AcpiMultiNode
;
631 NTSTATUS Status
= STATUS_SUCCESS
;
632 PHYSICAL_ADDRESS PhysicalAddress
;
636 PLOADER_PARAMETER_EXTENSION LoaderExtension
;
638 /* Only initialize once */
639 if (HalpAcpiTableCacheList
.Flink
) return Status
;
641 /* Setup the lock and table */
642 ExInitializeFastMutex(&HalpAcpiTableCacheLock
);
643 InitializeListHead(&HalpAcpiTableCacheList
);
646 Status
= HalpAcpiFindRsdtPhase0(LoaderBlock
, &AcpiMultiNode
);
647 if (!NT_SUCCESS(Status
)) return Status
;
652 /* Phase0: Use HAL Heap to map the RSDT, we assume it's about 2 pages */
653 PhysicalAddress
.QuadPart
= AcpiMultiNode
->RsdtAddress
.QuadPart
;
654 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, 2);
659 MappedAddress
= MmMapIoSpace(PhysicalAddress
, PAGE_SIZE
* 2, MmNonCached
);
663 Rsdt
= MappedAddress
;
666 /* Fail, no memory */
667 DbgPrint("HAL: Failed to map RSDT\n");
668 return STATUS_INSUFFICIENT_RESOURCES
;
672 DPRINT1("ACPI RSDT at 0x%p\n", Rsdt
);
673 if ((Rsdt
->Header
.Signature
!= RSDT_SIGNATURE
) &&
674 (Rsdt
->Header
.Signature
!= XSDT_SIGNATURE
))
676 /* Very bad: crash */
677 HalDisplayString("Bad RSDT pointer\n");
678 KeBugCheckEx(MISMATCHED_HAL
, 4, __LINE__
, 0, 0);
681 /* We assumed two pages -- do we need less or more? */
682 TableLength
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(PhysicalAddress
.LowPart
,
683 Rsdt
->Header
.Length
);
684 if (TableLength
!= 2)
686 /* Are we in phase 0 or 1? */
689 /* Unmap the old table, remap the new one, using Mm I/O space */
690 MmUnmapIoSpace(MappedAddress
, 2 * PAGE_SIZE
);
691 MappedAddress
= MmMapIoSpace(PhysicalAddress
,
692 TableLength
<< PAGE_SHIFT
,
697 /* Unmap the old table, remap the new one, using HAL heap */
698 HalpUnmapVirtualAddress(MappedAddress
, 2);
699 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, TableLength
);
702 /* Get the remapped table */
703 Rsdt
= MappedAddress
;
706 /* Fail, no memory */
707 DbgPrint("HAL: Couldn't remap RSDT\n");
708 return STATUS_INSUFFICIENT_RESOURCES
;
712 /* Now take the BIOS copy and make our own local copy */
713 Rsdt
= HalpAcpiCopyBiosTable(LoaderBlock
, &Rsdt
->Header
);
716 /* Fail, no memory */
717 DbgPrint("HAL: Couldn't remap RSDT\n");
718 return STATUS_INSUFFICIENT_RESOURCES
;
721 /* Get rid of the BIOS mapping */
725 HalpUnmapVirtualAddress(MappedAddress
, TableLength
);
730 MmUnmapIoSpace(MappedAddress
, TableLength
<< PAGE_SHIFT
);
734 HalpAcpiCacheTable(&Rsdt
->Header
);
736 /* Check for compatible loader block extension */
737 LoaderExtension
= LoaderBlock
->Extension
;
738 if (LoaderExtension
->Size
>= 0x58)
740 /* Compatible loader: did it provide an ACPI table override? */
741 if ((LoaderExtension
->AcpiTable
) && (LoaderExtension
->AcpiTableSize
))
743 /* Great, because we don't support it! */
744 DPRINT1("ACPI Table Overrides Not Supported!\n");
754 HaliAcpiTimerInit(IN ULONG TimerPort
,
755 IN ULONG TimerValExt
)
759 /* Is this in the init phase? */
762 /* Get the data from the FADT */
763 TimerPort
= HalpFixedAcpiDescTable
.pm_tmr_blk_io_port
;
764 TimerValExt
= HalpFixedAcpiDescTable
.flags
& ACPI_TMR_VAL_EXT
;
767 /* FIXME: Now proceed to the timer initialization */
768 DPRINT1("ACPI Timer at: %Xh (EXT: %d)\n", TimerPort
, TimerValExt
);
769 //HalaAcpiTimerInit(TimerPort, TimerValExt);
774 HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
779 PHYSICAL_ADDRESS PhysicalAddress
;
781 /* Only do this once */
782 DPRINT1("You are booting the ACPI HAL!\n");
783 if (HalpProcessedACPIPhase0
) return STATUS_SUCCESS
;
785 /* Setup the ACPI table cache */
786 Status
= HalpAcpiTableCacheInit(LoaderBlock
);
787 if (!NT_SUCCESS(Status
)) return Status
;
790 Fadt
= HalAcpiGetTable(LoaderBlock
, FADT_SIGNATURE
);
794 DbgPrint("HAL: Didn't find the FACP\n");
795 return STATUS_NOT_FOUND
;
798 /* Assume typical size, otherwise whatever the descriptor table says */
799 DPRINT1("ACPI FACP at 0x%p\n", Fadt
);
800 TableLength
= sizeof(FADT
);
801 if (Fadt
->Header
.Length
< sizeof(FADT
)) TableLength
= Fadt
->Header
.Length
;
803 /* Copy it in the HAL static buffer */
804 RtlCopyMemory(&HalpFixedAcpiDescTable
, Fadt
, TableLength
);
806 /* Anything special this HAL needs to do? */
807 HalpAcpiDetectMachineSpecificActions(LoaderBlock
, &HalpFixedAcpiDescTable
);
809 /* Get the debug table for KD */
810 HalpDebugPortTable
= HalAcpiGetTable(LoaderBlock
, DBGP_SIGNATURE
);
811 DPRINT1("ACPI DBGP at 0x%p\n", HalpDebugPortTable
);
813 /* Initialize NUMA through the SRAT */
814 HalpNumaInitializeStaticConfiguration(LoaderBlock
);
816 /* Initialize hotplug through the SRAT */
817 HalpDynamicSystemResourceConfiguration(LoaderBlock
);
818 DPRINT1("ACPI SRAT at 0x%p\n", HalpAcpiSrat
);
821 DPRINT1("Your machine has a SRAT, but NUMA/HotPlug are not supported!\n");
824 /* Can there be memory higher than 4GB? */
825 if (HalpMaxHotPlugMemoryAddress
.HighPart
>= 1)
827 /* We'll need this for DMA later */
828 HalpPhysicalMemoryMayAppearAbove4GB
= TRUE
;
831 /* Setup the ACPI timer */
832 HaliAcpiTimerInit(0, 0);
834 /* Do we have a low stub address yet? */
835 if (!HalpLowStubPhysicalAddress
.LowPart
)
838 HalpLowStubPhysicalAddress
.LowPart
= HalpAllocPhysicalMemory(LoaderBlock
,
842 if (HalpLowStubPhysicalAddress
.LowPart
)
845 HalpLowStub
= HalpMapPhysicalMemory64(HalpLowStubPhysicalAddress
, 1);
849 /* Grab a page for flushes */
850 PhysicalAddress
.QuadPart
= 0x100000;
851 HalpVirtAddrForFlush
= HalpMapPhysicalMemory64(PhysicalAddress
, 1);
852 HalpPteForFlush
= HalAddressToPte(HalpVirtAddrForFlush
);
854 /* Don't do this again */
855 HalpProcessedACPIPhase0
= TRUE
;
857 /* Setup the boot table */
858 HalpInitBootTable(LoaderBlock
);
861 return STATUS_SUCCESS
;