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 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
.LowPart
= HalpAllocPhysicalMemory(LoaderBlock
,
107 if (PhysAddress
.LowPart
)
110 CachedTable
= HalpMapPhysicalMemory64(PhysAddress
, PageCount
);
114 /* No memory, so nothing to map */
121 CachedTable
= ExAllocatePoolWithTag(NonPagedPool
, Size
, ' laH');
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
;
156 PFN_NUMBER PageCount
;
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 DPRINT1("ACPI DSDT at 0x%p\n", Header
);
194 if (Header
->Signature
!= DSDT_SIGNATURE
)
200 HalpUnmapVirtualAddress(Header
, 2);
205 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
208 /* Didn't find anything */
214 /* Couldn't find it */
220 /* To find tables, we need the RSDT */
221 Rsdt
= HalpAcpiGetTable(LoaderBlock
, RSDT_SIGNATURE
);
224 /* Won't be using the XSDT */
229 /* Only other choice is to use the XSDT */
230 Xsdt
= HalpAcpiGetTable(LoaderBlock
, XSDT_SIGNATURE
);
231 if (!Xsdt
) return NULL
;
233 /* Won't be using the RSDT */
234 DPRINT1("ACPI XSDT at 0x%p\n", Xsdt
);
238 /* Smallest RSDT/XSDT is one without table entries */
239 Offset
= FIELD_OFFSET(RSDT
, Tables
);
242 /* Figure out total size of table and the offset */
243 TableLength
= Xsdt
->Header
.Length
;
244 if (TableLength
< Offset
) Offset
= Xsdt
->Header
.Length
;
246 /* The entries are each 64-bits, so count them */
247 EntryCount
= (TableLength
- Offset
) / sizeof(PHYSICAL_ADDRESS
);
251 /* Figure out total size of table and the offset */
252 TableLength
= Rsdt
->Header
.Length
;
253 if (TableLength
< Offset
) Offset
= Rsdt
->Header
.Length
;
255 /* The entries are each 32-bits, so count them */
256 EntryCount
= (TableLength
- Offset
) / sizeof(ULONG
);
259 /* Start at the beginning of the array and loop it */
260 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
; CurrentEntry
++)
262 /* Are we using the XSDT? */
265 /* Read the 32-bit physical address */
266 PhysicalAddress
.LowPart
= Rsdt
->Tables
[CurrentEntry
];
267 PhysicalAddress
.HighPart
= 0;
271 /* Read the 64-bit physical address */
272 PhysicalAddress
= Xsdt
->Tables
[CurrentEntry
];
275 /* Had we already mapped a table? */
282 HalpUnmapVirtualAddress(Header
, 2);
287 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
291 /* Now map this table */
294 /* Phase 1: Use HAL heap */
295 Header
= MmMapIoSpace(PhysicalAddress
, 2 * PAGE_SIZE
, MmNonCached
);
299 /* Phase 0: Use Mm */
300 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, 2);
303 /* Check if we mapped it */
307 DPRINT1("HAL: Failed to map ACPI table.\n");
311 /* We found it, break out */
312 DPRINT("Found ACPI table %c%c%c%c at 0x%p\n",
313 Header
->Signature
& 0xFF,
314 (Header
->Signature
& 0xFF00) >> 8,
315 (Header
->Signature
& 0xFF0000) >> 16,
316 (Header
->Signature
& 0xFF000000) >> 24,
318 if (Header
->Signature
== Signature
) break;
321 /* Did we end up here back at the last entry? */
322 if (CurrentEntry
== EntryCount
)
324 /* Yes, unmap the last table we processed */
328 HalpUnmapVirtualAddress(Header
, 2);
333 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
336 /* Didn't find anything */
341 /* Past this point, we assume something was found */
344 /* How many pages do we need? */
345 PageCount
= BYTES_TO_PAGES(Header
->Length
);
348 /* We assumed two, but this is not the case, free the current mapping */
352 HalpUnmapVirtualAddress(Header
, 2);
357 MmUnmapIoSpace(Header
, 2 * PAGE_SIZE
);
360 /* Now map this table using its correct size */
363 /* Phase 1: Use HAL heap */
364 Header
= MmMapIoSpace(PhysicalAddress
, PageCount
<< PAGE_SHIFT
, MmNonCached
);
368 /* Phase 0: Use Mm */
369 Header
= HalpMapPhysicalMemory64(PhysicalAddress
, PageCount
);
373 /* Fail if the remapped failed */
374 if (!Header
) return NULL
;
376 /* All tables in ACPI 3.0 other than the FACP should have correct checksum */
377 if ((Header
->Signature
!= FADT_SIGNATURE
) || (Header
->Revision
> 2))
379 /* Go to the end of the table */
381 CurrentByte
= (PCHAR
)Header
+ Header
->Length
;
382 while (CurrentByte
-- != (PCHAR
)Header
)
385 CheckSum
+= *CurrentByte
;
388 /* The correct checksum is always 0, anything else is illegal */
389 if (CheckSum
) HalpInvalidAcpiTable
= Header
->Signature
;
392 /* Return the table */
398 HalpAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
401 PFN_NUMBER PageCount
;
402 PDESCRIPTION_HEADER TableAddress
, BiosCopy
;
404 /* See if we have a cached table? */
405 TableAddress
= HalpAcpiGetCachedTable(Signature
);
408 /* No cache, search the BIOS */
409 TableAddress
= HalpAcpiGetTableFromBios(LoaderBlock
, Signature
);
412 /* Found it, copy it into our own memory */
413 BiosCopy
= HalpAcpiCopyBiosTable(LoaderBlock
, TableAddress
);
415 /* Get the pages, and unmap the BIOS copy */
416 PageCount
= BYTES_TO_PAGES(TableAddress
->Length
);
419 /* Phase 0, use the HAL heap */
420 HalpUnmapVirtualAddress(TableAddress
, PageCount
);
424 /* Phase 1, use Mm */
425 MmUnmapIoSpace(TableAddress
, PageCount
<< PAGE_SHIFT
);
428 /* Cache the bios copy */
429 TableAddress
= BiosCopy
;
430 if (BiosCopy
) HalpAcpiCacheTable(BiosCopy
);
434 /* Return the table */
440 HalAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
443 PDESCRIPTION_HEADER TableHeader
;
448 /* Initialize the cache first */
449 if (!NT_SUCCESS(HalpAcpiTableCacheInit(LoaderBlock
))) return NULL
;
454 ExAcquireFastMutex(&HalpAcpiTableCacheLock
);
458 TableHeader
= HalpAcpiGetTable(LoaderBlock
, Signature
);
460 /* Release the lock in phase 1 */
461 if (!LoaderBlock
) ExReleaseFastMutex(&HalpAcpiTableCacheLock
);
463 /* Return the table */
469 HalpNumaInitializeStaticConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
471 PACPI_SRAT SratTable
;
473 /* Get the SRAT, bail out if it doesn't exist */
474 SratTable
= HalAcpiGetTable(LoaderBlock
, SRAT_SIGNATURE
);
475 HalpAcpiSrat
= SratTable
;
476 if (!SratTable
) return;
481 HalpGetHotPlugMemoryInfo(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
483 PACPI_SRAT SratTable
;
485 /* Get the SRAT, bail out if it doesn't exist */
486 SratTable
= HalAcpiGetTable(LoaderBlock
, SRAT_SIGNATURE
);
487 HalpAcpiSrat
= SratTable
;
488 if (!SratTable
) return;
493 HalpDynamicSystemResourceConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
495 /* For this HAL, it means to get hot plug memory information */
496 HalpGetHotPlugMemoryInfo(LoaderBlock
);
501 HalpAcpiDetectMachineSpecificActions(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
502 IN PFADT DescriptionTable
)
504 /* Does this HAL specify something? */
505 if (HalpAcpiTableMatchList
.Flink
)
507 /* Great, but we don't support it */
508 DPRINT1("WARNING: Your HAL has specific ACPI hacks to apply!\n");
514 HalpInitBootTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
516 PBOOT_TABLE BootTable
;
518 /* Get the boot table */
519 BootTable
= HalAcpiGetTable(LoaderBlock
, BOOT_SIGNATURE
);
520 HalpSimpleBootFlagTable
= BootTable
;
521 DPRINT1("ACPI BOOT at 0x%p\n", HalpSimpleBootFlagTable
);
525 (BootTable
->Header
.Length
>= sizeof(BOOT_TABLE
)) &&
526 (BootTable
->CMOSIndex
>= 9))
528 DPRINT1("ACPI Boot table found, but not supported!\n");
532 /* Invalid or doesn't exist, ignore it */
533 HalpSimpleBootFlagTable
= 0;
536 /* Install the end of boot handler */
537 // HalEndOfBoot = HalpEndOfBoot;
542 HalpAcpiFindRsdtPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
543 OUT PACPI_BIOS_MULTI_NODE
* AcpiMultiNode
)
545 PCONFIGURATION_COMPONENT_DATA ComponentEntry
;
546 PCONFIGURATION_COMPONENT_DATA Next
= NULL
;
547 PCM_PARTIAL_RESOURCE_LIST ResourceList
;
548 PACPI_BIOS_MULTI_NODE NodeData
;
550 PFN_NUMBER PageCount
;
552 PHYSICAL_ADDRESS PhysicalAddress
;
554 /* Did we already do this once? */
555 if (HalpAcpiMultiNode
)
557 /* Return what we know */
558 *AcpiMultiNode
= HalpAcpiMultiNode
;
559 return STATUS_SUCCESS
;
563 *AcpiMultiNode
= NULL
;
565 /* Find the multi function adapter key */
566 ComponentEntry
= KeFindConfigurationNextEntry(LoaderBlock
->ConfigurationRoot
,
568 MultiFunctionAdapter
,
571 while (ComponentEntry
)
573 /* Find the ACPI BIOS key */
574 if (!_stricmp(ComponentEntry
->ComponentEntry
.Identifier
, "ACPI BIOS"))
581 Next
= ComponentEntry
;
582 ComponentEntry
= KeFindConfigurationNextEntry(LoaderBlock
->ConfigurationRoot
,
584 MultiFunctionAdapter
,
589 /* Make sure we found it */
592 DPRINT1("**** HalpAcpiFindRsdtPhase0: did NOT find RSDT\n");
593 return STATUS_NOT_FOUND
;
596 /* The configuration data is a resource list, and the BIOS node follows */
597 ResourceList
= ComponentEntry
->ConfigurationData
;
598 NodeData
= (PACPI_BIOS_MULTI_NODE
)(ResourceList
+ 1);
600 /* How many E820 memory entries are there? */
601 NodeLength
= sizeof(ACPI_BIOS_MULTI_NODE
) +
602 (NodeData
->Count
- 1) * sizeof(ACPI_E820_ENTRY
);
604 /* Convert to pages */
605 PageCount
= BYTES_TO_PAGES(NodeLength
);
607 /* Allocate the memory */
608 PhysicalAddress
.HighPart
= 0;
609 PhysicalAddress
.LowPart
= HalpAllocPhysicalMemory(LoaderBlock
,
613 if (PhysicalAddress
.LowPart
)
615 /* Map it if the allocation worked */
616 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, PageCount
);
620 /* Otherwise we'll have to fail */
621 MappedAddress
= NULL
;
624 /* Save the multi node, bail out if we didn't find it */
625 HalpAcpiMultiNode
= MappedAddress
;
626 if (!MappedAddress
) return STATUS_INSUFFICIENT_RESOURCES
;
628 /* Copy the multi-node data */
629 RtlCopyMemory(MappedAddress
, NodeData
, NodeLength
);
631 /* Return the data */
632 *AcpiMultiNode
= HalpAcpiMultiNode
;
633 return STATUS_SUCCESS
;
638 HalpAcpiTableCacheInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
640 PACPI_BIOS_MULTI_NODE AcpiMultiNode
;
641 NTSTATUS Status
= STATUS_SUCCESS
;
642 PHYSICAL_ADDRESS PhysicalAddress
;
646 PLOADER_PARAMETER_EXTENSION LoaderExtension
;
648 /* Only initialize once */
649 if (HalpAcpiTableCacheList
.Flink
) return Status
;
651 /* Setup the lock and table */
652 ExInitializeFastMutex(&HalpAcpiTableCacheLock
);
653 InitializeListHead(&HalpAcpiTableCacheList
);
656 Status
= HalpAcpiFindRsdtPhase0(LoaderBlock
, &AcpiMultiNode
);
657 if (!NT_SUCCESS(Status
)) return Status
;
659 PhysicalAddress
.QuadPart
= AcpiMultiNode
->RsdtAddress
.QuadPart
;
664 /* Phase0: Use HAL Heap to map the RSDT, we assume it's about 2 pages */
665 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, 2);
670 MappedAddress
= MmMapIoSpace(PhysicalAddress
, PAGE_SIZE
* 2, MmNonCached
);
674 Rsdt
= MappedAddress
;
677 /* Fail, no memory */
678 DPRINT1("HAL: Failed to map RSDT\n");
679 return STATUS_INSUFFICIENT_RESOURCES
;
683 DPRINT1("ACPI RSDT at 0x%p\n", Rsdt
);
684 if ((Rsdt
->Header
.Signature
!= RSDT_SIGNATURE
) &&
685 (Rsdt
->Header
.Signature
!= XSDT_SIGNATURE
))
687 /* Very bad: crash */
688 HalDisplayString("Bad RSDT pointer\n");
689 KeBugCheckEx(MISMATCHED_HAL
, 4, __LINE__
, 0, 0);
692 /* We assumed two pages -- do we need less or more? */
693 TableLength
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(PhysicalAddress
.LowPart
,
694 Rsdt
->Header
.Length
);
695 if (TableLength
!= 2)
697 /* Are we in phase 0 or 1? */
700 /* Unmap the old table, remap the new one, using Mm I/O space */
701 MmUnmapIoSpace(MappedAddress
, 2 * PAGE_SIZE
);
702 MappedAddress
= MmMapIoSpace(PhysicalAddress
,
703 TableLength
<< PAGE_SHIFT
,
708 /* Unmap the old table, remap the new one, using HAL heap */
709 HalpUnmapVirtualAddress(MappedAddress
, 2);
710 MappedAddress
= HalpMapPhysicalMemory64(PhysicalAddress
, TableLength
);
713 /* Get the remapped table */
714 Rsdt
= MappedAddress
;
717 /* Fail, no memory */
718 DPRINT1("HAL: Couldn't remap RSDT\n");
719 return STATUS_INSUFFICIENT_RESOURCES
;
723 /* Now take the BIOS copy and make our own local copy */
724 Rsdt
= HalpAcpiCopyBiosTable(LoaderBlock
, &Rsdt
->Header
);
727 /* Fail, no memory */
728 DPRINT1("HAL: Couldn't remap RSDT\n");
729 return STATUS_INSUFFICIENT_RESOURCES
;
732 /* Get rid of the BIOS mapping */
736 HalpUnmapVirtualAddress(MappedAddress
, TableLength
);
741 MmUnmapIoSpace(MappedAddress
, TableLength
<< PAGE_SHIFT
);
745 HalpAcpiCacheTable(&Rsdt
->Header
);
747 /* Check for compatible loader block extension */
748 LoaderExtension
= LoaderBlock
->Extension
;
749 if (LoaderExtension
->Size
>= 0x58)
751 /* Compatible loader: did it provide an ACPI table override? */
752 if ((LoaderExtension
->AcpiTable
) && (LoaderExtension
->AcpiTableSize
))
754 /* Great, because we don't support it! */
755 DPRINT1("ACPI Table Overrides Not Supported!\n");
765 HaliAcpiTimerInit(IN ULONG TimerPort
,
766 IN ULONG TimerValExt
)
770 /* Is this in the init phase? */
773 /* Get the data from the FADT */
774 TimerPort
= HalpFixedAcpiDescTable
.pm_tmr_blk_io_port
;
775 TimerValExt
= HalpFixedAcpiDescTable
.flags
& ACPI_TMR_VAL_EXT
;
778 /* FIXME: Now proceed to the timer initialization */
779 DPRINT1("ACPI Timer at: %Xh (EXT: %d)\n", TimerPort
, TimerValExt
);
780 //HalaAcpiTimerInit(TimerPort, TimerValExt);
785 HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
790 PHYSICAL_ADDRESS PhysicalAddress
;
792 /* Only do this once */
793 DPRINT("You are booting the ACPI HAL!\n");
794 if (HalpProcessedACPIPhase0
) return STATUS_SUCCESS
;
796 /* Setup the ACPI table cache */
797 Status
= HalpAcpiTableCacheInit(LoaderBlock
);
798 if (!NT_SUCCESS(Status
)) return Status
;
801 Fadt
= HalAcpiGetTable(LoaderBlock
, FADT_SIGNATURE
);
805 DPRINT1("HAL: Didn't find the FACP\n");
806 return STATUS_NOT_FOUND
;
809 /* Assume typical size, otherwise whatever the descriptor table says */
810 DPRINT1("ACPI FACP at 0x%p\n", Fadt
);
811 TableLength
= sizeof(FADT
);
812 if (Fadt
->Header
.Length
< sizeof(FADT
)) TableLength
= Fadt
->Header
.Length
;
814 /* Copy it in the HAL static buffer */
815 RtlCopyMemory(&HalpFixedAcpiDescTable
, Fadt
, TableLength
);
817 /* Anything special this HAL needs to do? */
818 HalpAcpiDetectMachineSpecificActions(LoaderBlock
, &HalpFixedAcpiDescTable
);
820 /* Get the debug table for KD */
821 HalpDebugPortTable
= HalAcpiGetTable(LoaderBlock
, DBGP_SIGNATURE
);
822 DPRINT1("ACPI DBGP at 0x%p\n", HalpDebugPortTable
);
824 /* Initialize NUMA through the SRAT */
825 HalpNumaInitializeStaticConfiguration(LoaderBlock
);
827 /* Initialize hotplug through the SRAT */
828 HalpDynamicSystemResourceConfiguration(LoaderBlock
);
829 DPRINT1("ACPI SRAT at 0x%p\n", HalpAcpiSrat
);
832 DPRINT1("Your machine has a SRAT, but NUMA/HotPlug are not supported!\n");
835 /* Can there be memory higher than 4GB? */
836 if (HalpMaxHotPlugMemoryAddress
.HighPart
>= 1)
838 /* We'll need this for DMA later */
839 HalpPhysicalMemoryMayAppearAbove4GB
= TRUE
;
842 /* Setup the ACPI timer */
843 HaliAcpiTimerInit(0, 0);
845 /* Do we have a low stub address yet? */
846 if (!HalpLowStubPhysicalAddress
.LowPart
)
849 HalpLowStubPhysicalAddress
.LowPart
= HalpAllocPhysicalMemory(LoaderBlock
,
853 if (HalpLowStubPhysicalAddress
.LowPart
)
856 HalpLowStub
= HalpMapPhysicalMemory64(HalpLowStubPhysicalAddress
, 1);
860 /* Grab a page for flushes */
861 PhysicalAddress
.QuadPart
= 0x100000;
862 HalpVirtAddrForFlush
= HalpMapPhysicalMemory64(PhysicalAddress
, 1);
863 HalpPteForFlush
= HalAddressToPte(HalpVirtAddrForFlush
);
865 /* Don't do this again */
866 HalpProcessedACPIPhase0
= TRUE
;
868 /* Setup the boot table */
869 HalpInitBootTable(LoaderBlock
);
872 return STATUS_SUCCESS
;
877 HalpInitializePciBus(VOID
)
879 /* Setup the PCI stub support */
880 HalpInitializePciStubs();
882 /* Set the NMI crash flag */
883 HalpGetNMICrashFlag();
888 HalpInitNonBusHandler(VOID
)
890 /* These should be written by the PCI driver later, but we give defaults */
891 HalPciTranslateBusAddress
= HalpTranslateBusAddress
;
892 HalPciAssignSlotResources
= HalpAssignSlotResources
;
893 HalFindBusAddressTranslation
= HalpFindBusAddressTranslation
;
898 HalpInitBusHandlers(VOID
)
900 /* On ACPI, we only have a fake PCI bus to worry about */
901 HalpInitNonBusHandler();
906 HalpBuildAddressMap(VOID
)
908 /* ACPI is magic baby */
913 HalpGetDebugPortTable(VOID
)
915 return ((HalpDebugPortTable
) &&
916 (HalpDebugPortTable
->BaseAddress
.AddressSpaceID
== 1));
921 HalpIs16BitPortDecodeSupported(VOID
)
923 /* All ACPI systems are at least "EISA" so they support this */
924 return CM_RESOURCE_PORT_16_BIT_DECODE
;
929 HalpAcpiDetectResourceListSize(OUT PULONG ListSize
)
933 /* One element if there is a SCI */
934 *ListSize
= HalpFixedAcpiDescTable
.sci_int_vector
? 1: 0;
939 HalpBuildAcpiResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
)
943 ASSERT(ResourceList
!= NULL
);
945 /* Initialize the list */
946 ResourceList
->BusNumber
= -1;
947 ResourceList
->AlternativeLists
= 1;
948 ResourceList
->InterfaceType
= PNPBus
;
949 ResourceList
->List
[0].Version
= 1;
950 ResourceList
->List
[0].Revision
= 1;
951 ResourceList
->List
[0].Count
= 0;
953 /* Is there a SCI? */
954 if (HalpFixedAcpiDescTable
.sci_int_vector
)
956 /* Fill out the entry for it */
957 ResourceList
->List
[0].Descriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
958 ResourceList
->List
[0].Descriptors
[0].Type
= CmResourceTypeInterrupt
;
959 ResourceList
->List
[0].Descriptors
[0].ShareDisposition
= CmResourceShareShared
;
961 /* Get the interrupt number */
962 Interrupt
= HalpPicVectorRedirect
[HalpFixedAcpiDescTable
.sci_int_vector
];
963 ResourceList
->List
[0].Descriptors
[0].u
.Interrupt
.MinimumVector
= Interrupt
;
964 ResourceList
->List
[0].Descriptors
[0].u
.Interrupt
.MaximumVector
= Interrupt
;
967 ++ResourceList
->List
[0].Count
;
971 return STATUS_SUCCESS
;
976 HalpQueryAcpiResourceRequirements(OUT PIO_RESOURCE_REQUIREMENTS_LIST
*Requirements
)
978 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
979 ULONG Count
= 0, ListSize
;
983 /* Get ACPI resources */
984 HalpAcpiDetectResourceListSize(&Count
);
985 DPRINT("Resource count: %d\n", Count
);
987 /* Compute size of the list and allocate it */
988 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
[0].Descriptors
) +
989 (Count
* sizeof(IO_RESOURCE_DESCRIPTOR
));
990 DPRINT("Resource list size: %d\n", ListSize
);
991 RequirementsList
= ExAllocatePoolWithTag(PagedPool
, ListSize
, ' laH');
992 if (RequirementsList
)
995 RtlZeroMemory(RequirementsList
, ListSize
);
996 RequirementsList
->ListSize
= ListSize
;
999 Status
= HalpBuildAcpiResourceList(RequirementsList
);
1000 if (NT_SUCCESS(Status
))
1002 /* It worked, return it */
1003 *Requirements
= RequirementsList
;
1005 /* Validate the list */
1006 ASSERT(RequirementsList
->List
[0].Count
== Count
);
1011 ExFreePoolWithTag(RequirementsList
, ' laH');
1012 Status
= STATUS_NO_SUCH_DEVICE
;
1017 /* Not enough memory */
1018 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1021 /* Return the status */
1030 HalReportResourceUsage(VOID
)
1032 INTERFACE_TYPE InterfaceType
;
1033 UNICODE_STRING HalString
;
1035 /* FIXME: Initialize DMA 64-bit support */
1037 /* FIXME: Initialize MCA bus */
1039 /* Initialize PCI bus. */
1040 HalpInitializePciBus();
1042 /* What kind of bus is this? */
1043 switch (HalpBusType
)
1046 case MACHINE_TYPE_ISA
:
1047 InterfaceType
= Isa
;
1051 case MACHINE_TYPE_EISA
:
1052 InterfaceType
= Eisa
;
1056 case MACHINE_TYPE_MCA
:
1057 InterfaceType
= MicroChannel
;
1062 InterfaceType
= Internal
;
1066 /* Build HAL usage */
1067 RtlInitUnicodeString(&HalString
, HalName
);
1068 HalpReportResourceUsage(&HalString
, InterfaceType
);
1070 /* Setup PCI debugging and Hibernation */
1071 HalpRegisterPciDebuggingDeviceInfo();