3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/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 ULONG HalpPicVectorRedirect
[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15};
42 /* This determines the HAL type */
43 BOOLEAN HalDisableFirmwareMapper
= TRUE
;
44 PWCHAR HalHardwareIdString
= L
"acpipic_up";
45 PWCHAR HalName
= L
"ACPI Compatible Eisa/Isa HAL";
47 /* PRIVATE FUNCTIONS **********************************************************/
51 HalpAcpiGetCachedTable(IN ULONG Signature
)
53 PLIST_ENTRY ListHead
, NextEntry
;
54 PACPI_CACHED_TABLE CachedTable
;
56 /* Loop cached tables */
57 ListHead
= &HalpAcpiTableCacheList
;
58 NextEntry
= ListHead
->Flink
;
59 while (NextEntry
!= ListHead
)
62 CachedTable
= CONTAINING_RECORD(NextEntry
, ACPI_CACHED_TABLE
, Links
);
64 /* Compare signatures */
65 if (CachedTable
->Header
.Signature
== Signature
) return &CachedTable
->Header
;
68 NextEntry
= NextEntry
->Flink
;
77 HalpAcpiCacheTable(IN PDESCRIPTION_HEADER TableHeader
)
79 PACPI_CACHED_TABLE CachedTable
;
81 /* Get the cached table and link it */
82 CachedTable
= CONTAINING_RECORD(TableHeader
, ACPI_CACHED_TABLE
, Header
);
83 InsertTailList(&HalpAcpiTableCacheList
, &CachedTable
->Links
);
88 HalpAcpiCopyBiosTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
89 IN PDESCRIPTION_HEADER TableHeader
)
93 PHYSICAL_ADDRESS PhysAddress
;
94 PACPI_CACHED_TABLE CachedTable
;
95 PDESCRIPTION_HEADER CopiedTable
;
97 /* Size we'll need for the cached table */
98 Size
= TableHeader
->Length
+ FIELD_OFFSET(ACPI_CACHED_TABLE
, Header
);
101 /* Phase 0: Convert to pages and use the HAL heap */
102 PageCount
= BYTES_TO_PAGES(Size
);
103 PhysAddress
.QuadPart
= HalpAllocPhysicalMemory(LoaderBlock
,
107 if (PhysAddress
.QuadPart
)
110 CachedTable
= HalpMapPhysicalMemory64(PhysAddress
, PageCount
);
114 /* No memory, so nothing to map */
121 CachedTable
= ExAllocatePoolWithTag(NonPagedPool
, Size
, TAG_HAL
);
124 /* Do we have the cached table? */
128 CopiedTable
= &CachedTable
->Header
;
129 RtlCopyMemory(CopiedTable
, TableHeader
, TableHeader
->Length
);
133 /* Nothing to return */
137 /* Return the table */
143 HalpAcpiGetTableFromBios(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
146 PHYSICAL_ADDRESS PhysicalAddress
;
150 PDESCRIPTION_HEADER Header
= NULL
;
154 ULONG EntryCount
, CurrentEntry
;
158 /* Should not query the RSDT/XSDT by itself */
159 if ((Signature
== RSDT_SIGNATURE
) || (Signature
== XSDT_SIGNATURE
)) return NULL
;
161 /* Special case request for DSDT, because the FADT points to it */
162 if (Signature
== DSDT_SIGNATURE
)
165 Fadt
= HalpAcpiGetTable(LoaderBlock
, FADT_SIGNATURE
);
168 /* Grab the DSDT address and assume 2 pages */
169 PhysicalAddress
.HighPart
= 0;
170 PhysicalAddress
.LowPart
= Fadt
->dsdt
;
171 TableLength
= 2 * PAGE_SIZE
;
176 /* Phase 0, use HAL heap */
177 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, 2u);
181 /* Phase 1, use Mm */
182 Header
= MmMapIoSpace(PhysicalAddress
, 2 * PAGE_SIZE
, 0);
185 /* Fail if we couldn't map it */
188 DPRINT1("HAL: Failed to map ACPI table.\n");
192 /* Validate the signature */
193 if (Header
->Signature
!= DSDT_SIGNATURE
)
199 HalpUnmapVirtualAddress(Header
, 2);
204 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
207 /* Didn't find anything */
213 /* Couldn't find it */
219 /* To find tables, we need the RSDT */
220 Rsdt
= HalpAcpiGetTable(LoaderBlock
, RSDT_SIGNATURE
);
223 /* Won't be using the XSDT */
228 /* Only other choice is to use the XSDT */
229 Xsdt
= HalpAcpiGetTable(LoaderBlock
, XSDT_SIGNATURE
);
230 if (!Xsdt
) return NULL
;
232 /* Won't be using the RSDT */
236 /* Smallest RSDT/XSDT is one without table entries */
237 Offset
= FIELD_OFFSET(RSDT
, Tables
);
240 /* Figure out total size of table and the offset */
241 TableLength
= Xsdt
->Header
.Length
;
242 if (TableLength
< Offset
) Offset
= Xsdt
->Header
.Length
;
244 /* The entries are each 64-bits, so count them */
245 EntryCount
= (TableLength
- Offset
) / sizeof(PHYSICAL_ADDRESS
);
249 /* Figure out total size of table and the offset */
250 TableLength
= Rsdt
->Header
.Length
;
251 if (TableLength
< Offset
) Offset
= Rsdt
->Header
.Length
;
253 /* The entries are each 32-bits, so count them */
254 EntryCount
= (TableLength
- Offset
) / sizeof(ULONG
);
257 /* Start at the beginning of the array and loop it */
258 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
; CurrentEntry
++)
260 /* Are we using the XSDT? */
263 /* Read the 32-bit physical address */
264 PhysicalAddress
.LowPart
= Rsdt
->Tables
[CurrentEntry
];
265 PhysicalAddress
.HighPart
= 0;
269 /* Read the 64-bit physical address */
270 PhysicalAddress
= Xsdt
->Tables
[CurrentEntry
];
273 /* Had we already mapped a table? */
280 HalpUnmapVirtualAddress(Header
, 2);
285 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
289 /* Now map this table */
292 /* Phase 1: Use HAL heap */
293 Header
= MmMapIoSpace(PhysicalAddress
, 2 * PAGE_SIZE
, MmNonCached
);
297 /* Phase 0: Use Mm */
298 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, 2);
301 /* Check if we mapped it */
305 DPRINT1("HAL: Failed to map ACPI table.\n");
309 /* We found it, break out */
310 DPRINT("Found ACPI table %c%c%c%c at 0x%p\n",
311 Header
->Signature
& 0xFF,
312 (Header
->Signature
& 0xFF00) >> 8,
313 (Header
->Signature
& 0xFF0000) >> 16,
314 (Header
->Signature
& 0xFF000000) >> 24,
316 if (Header
->Signature
== Signature
) break;
319 /* Did we end up here back at the last entry? */
320 if (CurrentEntry
== EntryCount
)
322 /* Yes, unmap the last table we processed */
326 HalpUnmapVirtualAddress(Header
, 2);
331 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
334 /* Didn't find anything */
339 /* Past this point, we assume something was found */
342 /* How many pages do we need? */
343 PageCount
= BYTES_TO_PAGES(Header
->Length
);
346 /* We assumed two, but this is not the case, free the current mapping */
350 HalpUnmapVirtualAddress(Header
, 2);
355 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
358 /* Now map this table using its correct size */
361 /* Phase 1: Use HAL heap */
362 Header
= MmMapIoSpace(PhysicalAddress
, PageCount
<< PAGE_SHIFT
, MmNonCached
);
366 /* Phase 0: Use Mm */
367 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, PageCount
);
371 /* Fail if the remapped failed */
372 if (!Header
) return NULL
;
374 /* All tables in ACPI 3.0 other than the FACP should have correct checksum */
375 if ((Header
->Signature
!= FADT_SIGNATURE
) || (Header
->Revision
> 2))
377 /* Go to the end of the table */
379 CurrentByte
= (PCHAR
)Header
+ Header
->Length
;
380 while (CurrentByte
-- != (PCHAR
)Header
)
383 CheckSum
+= *CurrentByte
;
386 /* The correct checksum is always 0, anything else is illegal */
389 HalpInvalidAcpiTable
= Header
->Signature
;
390 DPRINT1("Checksum failed on ACPI table %c%c%c%c\n",
392 (Signature
& 0xFF00) >> 8,
393 (Signature
& 0xFF0000) >> 16,
394 (Signature
& 0xFF000000) >> 24);
398 /* Return the table */
404 HalpAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
408 PDESCRIPTION_HEADER TableAddress
, BiosCopy
;
410 /* See if we have a cached table? */
411 TableAddress
= HalpAcpiGetCachedTable(Signature
);
414 /* No cache, search the BIOS */
415 TableAddress
= HalpAcpiGetTableFromBios(LoaderBlock
, Signature
);
418 /* Found it, copy it into our own memory */
419 BiosCopy
= HalpAcpiCopyBiosTable(LoaderBlock
, TableAddress
);
421 /* Get the pages, and unmap the BIOS copy */
422 PageCount
= BYTES_TO_PAGES(TableAddress
->Length
);
425 /* Phase 0, use the HAL heap */
426 HalpUnmapVirtualAddress(TableAddress
, PageCount
);
430 /* Phase 1, use Mm */
431 MmUnmapIoSpace(TableAddress
, PageCount
<< PAGE_SHIFT
);
434 /* Cache the bios copy */
435 TableAddress
= BiosCopy
;
436 if (BiosCopy
) HalpAcpiCacheTable(BiosCopy
);
440 /* Return the table */
446 HalAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
449 PDESCRIPTION_HEADER TableHeader
;
454 /* Initialize the cache first */
455 if (!NT_SUCCESS(HalpAcpiTableCacheInit(LoaderBlock
))) return NULL
;
460 ExAcquireFastMutex(&HalpAcpiTableCacheLock
);
464 TableHeader
= HalpAcpiGetTable(LoaderBlock
, Signature
);
466 /* Release the lock in phase 1 */
467 if (!LoaderBlock
) ExReleaseFastMutex(&HalpAcpiTableCacheLock
);
469 /* Return the table */
475 HalpNumaInitializeStaticConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
477 PACPI_SRAT SratTable
;
479 /* Get the SRAT, bail out if it doesn't exist */
480 SratTable
= HalAcpiGetTable(LoaderBlock
, SRAT_SIGNATURE
);
481 HalpAcpiSrat
= SratTable
;
482 if (!SratTable
) return;
487 HalpGetHotPlugMemoryInfo(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
489 PACPI_SRAT SratTable
;
491 /* Get the SRAT, bail out if it doesn't exist */
492 SratTable
= HalAcpiGetTable(LoaderBlock
, SRAT_SIGNATURE
);
493 HalpAcpiSrat
= SratTable
;
494 if (!SratTable
) return;
499 HalpDynamicSystemResourceConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
501 /* For this HAL, it means to get hot plug memory information */
502 HalpGetHotPlugMemoryInfo(LoaderBlock
);
507 HalpAcpiDetectMachineSpecificActions(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
508 IN PFADT DescriptionTable
)
510 /* Does this HAL specify something? */
511 if (HalpAcpiTableMatchList
.Flink
)
513 /* Great, but we don't support it */
514 DPRINT1("WARNING: Your HAL has specific ACPI hacks to apply!\n");
520 HalpInitBootTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
522 PBOOT_TABLE BootTable
;
524 /* Get the boot table */
525 BootTable
= HalAcpiGetTable(LoaderBlock
, BOOT_SIGNATURE
);
526 HalpSimpleBootFlagTable
= BootTable
;
530 (BootTable
->Header
.Length
>= sizeof(BOOT_TABLE
)) &&
531 (BootTable
->CMOSIndex
>= 9))
533 DPRINT1("ACPI Boot table found, but not supported!\n");
537 /* Invalid or doesn't exist, ignore it */
538 HalpSimpleBootFlagTable
= 0;
541 /* Install the end of boot handler */
542 // HalEndOfBoot = HalpEndOfBoot;
547 HalpAcpiFindRsdtPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
548 OUT PACPI_BIOS_MULTI_NODE
* AcpiMultiNode
)
550 PCONFIGURATION_COMPONENT_DATA ComponentEntry
;
551 PCONFIGURATION_COMPONENT_DATA Next
= NULL
;
552 PCM_PARTIAL_RESOURCE_LIST ResourceList
;
553 PACPI_BIOS_MULTI_NODE NodeData
;
557 PHYSICAL_ADDRESS PhysicalAddress
;
559 /* Did we already do this once? */
560 if (HalpAcpiMultiNode
)
562 /* Return what we know */
563 *AcpiMultiNode
= HalpAcpiMultiNode
;
564 return STATUS_SUCCESS
;
568 *AcpiMultiNode
= NULL
;
570 /* Find the multi function adapter key */
571 ComponentEntry
= KeFindConfigurationNextEntry(LoaderBlock
->ConfigurationRoot
,
573 MultiFunctionAdapter
,
576 while (ComponentEntry
)
578 /* Find the ACPI BIOS key */
579 if (!_stricmp(ComponentEntry
->ComponentEntry
.Identifier
, "ACPI BIOS"))
586 Next
= ComponentEntry
;
587 ComponentEntry
= KeFindConfigurationNextEntry(LoaderBlock
->ConfigurationRoot
,
589 MultiFunctionAdapter
,
594 /* Make sure we found it */
597 DPRINT1("**** HalpAcpiFindRsdtPhase0: did NOT find RSDT\n");
598 return STATUS_NOT_FOUND
;
601 /* The configuration data is a resource list, and the BIOS node follows */
602 ResourceList
= ComponentEntry
->ConfigurationData
;
603 NodeData
= (PACPI_BIOS_MULTI_NODE
)(ResourceList
+ 1);
605 /* How many E820 memory entries are there? */
606 NodeLength
= sizeof(ACPI_BIOS_MULTI_NODE
) +
607 (NodeData
->Count
- 1) * sizeof(ACPI_E820_ENTRY
);
609 /* Convert to pages */
610 PageCount
= (PFN_COUNT
)BYTES_TO_PAGES(NodeLength
);
612 /* Allocate the memory */
613 PhysicalAddress
.QuadPart
= HalpAllocPhysicalMemory(LoaderBlock
,
617 if (PhysicalAddress
.QuadPart
)
619 /* Map it if the allocation worked */
620 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, PageCount
);
624 /* Otherwise we'll have to fail */
625 MappedAddress
= NULL
;
628 /* Save the multi node, bail out if we didn't find it */
629 HalpAcpiMultiNode
= MappedAddress
;
630 if (!MappedAddress
) return STATUS_INSUFFICIENT_RESOURCES
;
632 /* Copy the multi-node data */
633 RtlCopyMemory(MappedAddress
, NodeData
, NodeLength
);
635 /* Return the data */
636 *AcpiMultiNode
= HalpAcpiMultiNode
;
637 return STATUS_SUCCESS
;
642 HalpAcpiTableCacheInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
644 PACPI_BIOS_MULTI_NODE AcpiMultiNode
;
645 NTSTATUS Status
= STATUS_SUCCESS
;
646 PHYSICAL_ADDRESS PhysicalAddress
;
650 PLOADER_PARAMETER_EXTENSION LoaderExtension
;
652 /* Only initialize once */
653 if (HalpAcpiTableCacheList
.Flink
) return Status
;
655 /* Setup the lock and table */
656 ExInitializeFastMutex(&HalpAcpiTableCacheLock
);
657 InitializeListHead(&HalpAcpiTableCacheList
);
660 Status
= HalpAcpiFindRsdtPhase0(LoaderBlock
, &AcpiMultiNode
);
661 if (!NT_SUCCESS(Status
)) return Status
;
663 PhysicalAddress
.QuadPart
= AcpiMultiNode
->RsdtAddress
.QuadPart
;
668 /* Phase0: Use HAL Heap to map the RSDT, we assume it's about 2 pages */
669 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, 2);
674 MappedAddress
= MmMapIoSpace(PhysicalAddress
, PAGE_SIZE
* 2, MmNonCached
);
678 Rsdt
= MappedAddress
;
681 /* Fail, no memory */
682 DPRINT1("HAL: Failed to map RSDT\n");
683 return STATUS_INSUFFICIENT_RESOURCES
;
687 if ((Rsdt
->Header
.Signature
!= RSDT_SIGNATURE
) &&
688 (Rsdt
->Header
.Signature
!= XSDT_SIGNATURE
))
690 /* Very bad: crash */
691 HalDisplayString("Bad RSDT pointer\r\n");
692 KeBugCheckEx(MISMATCHED_HAL
, 4, __LINE__
, 0, 0);
695 /* We assumed two pages -- do we need less or more? */
696 TableLength
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(PhysicalAddress
.LowPart
,
697 Rsdt
->Header
.Length
);
698 if (TableLength
!= 2)
700 /* Are we in phase 0 or 1? */
703 /* Unmap the old table, remap the new one, using Mm I/O space */
704 MmUnmapIoSpace(MappedAddress
, 2 * PAGE_SIZE
);
705 MappedAddress
= MmMapIoSpace(PhysicalAddress
,
706 TableLength
<< PAGE_SHIFT
,
711 /* Unmap the old table, remap the new one, using HAL heap */
712 HalpUnmapVirtualAddress(MappedAddress
, 2);
713 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, TableLength
);
716 /* Get the remapped table */
717 Rsdt
= MappedAddress
;
720 /* Fail, no memory */
721 DPRINT1("HAL: Couldn't remap RSDT\n");
722 return STATUS_INSUFFICIENT_RESOURCES
;
726 /* Now take the BIOS copy and make our own local copy */
727 Rsdt
= HalpAcpiCopyBiosTable(LoaderBlock
, &Rsdt
->Header
);
730 /* Fail, no memory */
731 DPRINT1("HAL: Couldn't remap RSDT\n");
732 return STATUS_INSUFFICIENT_RESOURCES
;
735 /* Get rid of the BIOS mapping */
739 HalpUnmapVirtualAddress(MappedAddress
, TableLength
);
741 LoaderExtension
= LoaderBlock
->Extension
;
746 MmUnmapIoSpace(MappedAddress
, TableLength
<< PAGE_SHIFT
);
748 LoaderExtension
= NULL
;
752 HalpAcpiCacheTable(&Rsdt
->Header
);
754 /* Check for compatible loader block extension */
755 if (LoaderExtension
&& (LoaderExtension
->Size
>= 0x58))
757 /* Compatible loader: did it provide an ACPI table override? */
758 if ((LoaderExtension
->AcpiTable
) && (LoaderExtension
->AcpiTableSize
))
760 /* Great, because we don't support it! */
761 DPRINT1("ACPI Table Overrides Not Supported!\n");
771 HaliAcpiTimerInit(IN ULONG TimerPort
,
772 IN ULONG TimerValExt
)
776 /* Is this in the init phase? */
779 /* Get the data from the FADT */
780 TimerPort
= HalpFixedAcpiDescTable
.pm_tmr_blk_io_port
;
781 TimerValExt
= HalpFixedAcpiDescTable
.flags
& ACPI_TMR_VAL_EXT
;
782 DPRINT1("ACPI Timer at: %Xh (EXT: %d)\n", TimerPort
, TimerValExt
);
785 /* FIXME: Now proceed to the timer initialization */
786 //HalaAcpiTimerInit(TimerPort, TimerValExt);
791 HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
796 PHYSICAL_ADDRESS PhysicalAddress
;
798 /* Only do this once */
799 if (HalpProcessedACPIPhase0
) return STATUS_SUCCESS
;
801 /* Setup the ACPI table cache */
802 Status
= HalpAcpiTableCacheInit(LoaderBlock
);
803 if (!NT_SUCCESS(Status
)) return Status
;
806 Fadt
= HalAcpiGetTable(LoaderBlock
, FADT_SIGNATURE
);
810 DPRINT1("HAL: Didn't find the FACP\n");
811 return STATUS_NOT_FOUND
;
814 /* Assume typical size, otherwise whatever the descriptor table says */
815 TableLength
= sizeof(FADT
);
816 if (Fadt
->Header
.Length
< sizeof(FADT
)) TableLength
= Fadt
->Header
.Length
;
818 /* Copy it in the HAL static buffer */
819 RtlCopyMemory(&HalpFixedAcpiDescTable
, Fadt
, TableLength
);
821 /* Anything special this HAL needs to do? */
822 HalpAcpiDetectMachineSpecificActions(LoaderBlock
, &HalpFixedAcpiDescTable
);
824 /* Get the debug table for KD */
825 HalpDebugPortTable
= HalAcpiGetTable(LoaderBlock
, DBGP_SIGNATURE
);
827 /* Initialize NUMA through the SRAT */
828 HalpNumaInitializeStaticConfiguration(LoaderBlock
);
830 /* Initialize hotplug through the SRAT */
831 HalpDynamicSystemResourceConfiguration(LoaderBlock
);
834 DPRINT1("Your machine has a SRAT, but NUMA/HotPlug are not supported!\n");
837 /* Can there be memory higher than 4GB? */
838 if (HalpMaxHotPlugMemoryAddress
.HighPart
>= 1)
840 /* We'll need this for DMA later */
841 HalpPhysicalMemoryMayAppearAbove4GB
= TRUE
;
844 /* Setup the ACPI timer */
845 HaliAcpiTimerInit(0, 0);
847 /* Do we have a low stub address yet? */
848 if (!HalpLowStubPhysicalAddress
.QuadPart
)
851 HalpLowStubPhysicalAddress
.QuadPart
= HalpAllocPhysicalMemory(LoaderBlock
,
855 if (HalpLowStubPhysicalAddress
.QuadPart
)
858 HalpLowStub
= HalpMapPhysicalMemory64(HalpLowStubPhysicalAddress
, 1);
862 /* Grab a page for flushes */
863 PhysicalAddress
.QuadPart
= 0x100000;
864 HalpVirtAddrForFlush
= HalpMapPhysicalMemory64(PhysicalAddress
, 1);
865 HalpPteForFlush
= HalAddressToPte(HalpVirtAddrForFlush
);
867 /* Don't do this again */
868 HalpProcessedACPIPhase0
= TRUE
;
870 /* Setup the boot table */
871 HalpInitBootTable(LoaderBlock
);
875 PLIST_ENTRY ListHead
, NextEntry
;
876 PACPI_CACHED_TABLE CachedTable
;
878 /* Loop cached tables */
879 ListHead
= &HalpAcpiTableCacheList
;
880 NextEntry
= ListHead
->Flink
;
881 while (NextEntry
!= ListHead
)
884 CachedTable
= CONTAINING_RECORD(NextEntry
, ACPI_CACHED_TABLE
, Links
);
886 /* Compare signatures */
887 if ((CachedTable
->Header
.Signature
== RSDT_SIGNATURE
) ||
888 (CachedTable
->Header
.Signature
== XSDT_SIGNATURE
))
890 DPRINT1("ACPI %d.0 Detected. Tables: ", (CachedTable
->Header
.Revision
+ 1));
893 DbgPrint("[%c%c%c%c] ",
894 (CachedTable
->Header
.Signature
& 0xFF),
895 (CachedTable
->Header
.Signature
& 0xFF00) >> 8,
896 (CachedTable
->Header
.Signature
& 0xFF0000) >> 16,
897 (CachedTable
->Header
.Signature
& 0xFF000000) >> 24);
900 NextEntry
= NextEntry
->Flink
;
906 return STATUS_SUCCESS
;
911 HalpInitializePciBus(VOID
)
913 /* Setup the PCI stub support */
914 HalpInitializePciStubs();
916 /* Set the NMI crash flag */
917 HalpGetNMICrashFlag();
922 HalpInitNonBusHandler(VOID
)
924 /* These should be written by the PCI driver later, but we give defaults */
925 HalPciTranslateBusAddress
= HalpTranslateBusAddress
;
926 HalPciAssignSlotResources
= HalpAssignSlotResources
;
927 HalFindBusAddressTranslation
= HalpFindBusAddressTranslation
;
932 HalpInitBusHandlers(VOID
)
934 /* On ACPI, we only have a fake PCI bus to worry about */
935 HalpInitNonBusHandler();
940 HalpBuildAddressMap(VOID
)
942 /* ACPI is magic baby */
947 HalpGetDebugPortTable(VOID
)
949 return ((HalpDebugPortTable
) &&
950 (HalpDebugPortTable
->BaseAddress
.AddressSpaceID
== 1));
955 HalpIs16BitPortDecodeSupported(VOID
)
957 /* All ACPI systems are at least "EISA" so they support this */
958 return CM_RESOURCE_PORT_16_BIT_DECODE
;
963 HalpAcpiDetectResourceListSize(OUT PULONG ListSize
)
967 /* One element if there is a SCI */
968 *ListSize
= HalpFixedAcpiDescTable
.sci_int_vector
? 1: 0;
973 HalpBuildAcpiResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
)
977 ASSERT(ResourceList
!= NULL
);
979 /* Initialize the list */
980 ResourceList
->BusNumber
= -1;
981 ResourceList
->AlternativeLists
= 1;
982 ResourceList
->InterfaceType
= PNPBus
;
983 ResourceList
->List
[0].Version
= 1;
984 ResourceList
->List
[0].Revision
= 1;
985 ResourceList
->List
[0].Count
= 0;
987 /* Is there a SCI? */
988 if (HalpFixedAcpiDescTable
.sci_int_vector
)
990 /* Fill out the entry for it */
991 ResourceList
->List
[0].Descriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
992 ResourceList
->List
[0].Descriptors
[0].Type
= CmResourceTypeInterrupt
;
993 ResourceList
->List
[0].Descriptors
[0].ShareDisposition
= CmResourceShareShared
;
995 /* Get the interrupt number */
996 Interrupt
= HalpPicVectorRedirect
[HalpFixedAcpiDescTable
.sci_int_vector
];
997 ResourceList
->List
[0].Descriptors
[0].u
.Interrupt
.MinimumVector
= Interrupt
;
998 ResourceList
->List
[0].Descriptors
[0].u
.Interrupt
.MaximumVector
= Interrupt
;
1001 ++ResourceList
->List
[0].Count
;
1005 return STATUS_SUCCESS
;
1010 HalpQueryAcpiResourceRequirements(OUT PIO_RESOURCE_REQUIREMENTS_LIST
*Requirements
)
1012 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
1013 ULONG Count
= 0, ListSize
;
1017 /* Get ACPI resources */
1018 HalpAcpiDetectResourceListSize(&Count
);
1019 DPRINT("Resource count: %d\n", Count
);
1021 /* Compute size of the list and allocate it */
1022 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
[0].Descriptors
) +
1023 (Count
* sizeof(IO_RESOURCE_DESCRIPTOR
));
1024 DPRINT("Resource list size: %d\n", ListSize
);
1025 RequirementsList
= ExAllocatePoolWithTag(PagedPool
, ListSize
, TAG_HAL
);
1026 if (RequirementsList
)
1029 RtlZeroMemory(RequirementsList
, ListSize
);
1030 RequirementsList
->ListSize
= ListSize
;
1033 Status
= HalpBuildAcpiResourceList(RequirementsList
);
1034 if (NT_SUCCESS(Status
))
1036 /* It worked, return it */
1037 *Requirements
= RequirementsList
;
1039 /* Validate the list */
1040 ASSERT(RequirementsList
->List
[0].Count
== Count
);
1045 ExFreePoolWithTag(RequirementsList
, TAG_HAL
);
1046 Status
= STATUS_NO_SUCH_DEVICE
;
1051 /* Not enough memory */
1052 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1055 /* Return the status */
1064 HalReportResourceUsage(VOID
)
1066 INTERFACE_TYPE InterfaceType
;
1067 UNICODE_STRING HalString
;
1069 /* FIXME: Initialize DMA 64-bit support */
1071 /* FIXME: Initialize MCA bus */
1073 /* Initialize PCI bus. */
1074 HalpInitializePciBus();
1076 /* What kind of bus is this? */
1077 switch (HalpBusType
)
1080 case MACHINE_TYPE_ISA
:
1081 InterfaceType
= Isa
;
1085 case MACHINE_TYPE_EISA
:
1086 InterfaceType
= Eisa
;
1090 case MACHINE_TYPE_MCA
:
1091 InterfaceType
= MicroChannel
;
1096 InterfaceType
= Internal
;
1100 /* Build HAL usage */
1101 RtlInitUnicodeString(&HalString
, HalName
);
1102 HalpReportResourceUsage(&HalString
, InterfaceType
);
1104 /* Setup PCI debugging and Hibernation */
1105 HalpRegisterPciDebuggingDeviceInfo();