123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534 |
- /** @file
- ACPI Platform Driver Hooks
- @copyright
- Copyright 1996 - 2020 Intel Corporation. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- //
- // Statements that include other files
- //
- #include "AcpiPlatformLibLocal.h"
- #include <Protocol/AcpiSystemDescriptionTable.h>
- #include <Library/UbaPlatLib.h>
- #include <Library/PlatformSpecificAcpiTableLib.h>
- #include <Protocol/DynamicSiLibraryProtocol.h>
- #include <Protocol/DynamicSiLibraryProtocol2.h>
- extern BIOS_ACPI_PARAM *mAcpiParameter;
- EFI_PLATFORM_INFO *mPlatformInfo;
- EFI_CPU_CSR_ACCESS_PROTOCOL *mCpuCsrAccess;
- EFI_ACPI_TABLE_PROTOCOL *mAcpiTable;
- extern EFI_IIO_UDS_PROTOCOL *mIioUds;
- CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr;
- UINT32 mNumOfBitShift;
- BOOLEAN mX2ApicEnabled;
- SYSTEM_MEMORY_MAP_HOB *mSystemMemoryMap;
- SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration;
- SOCKET_MP_LINK_CONFIGURATION mSocketMpLinkConfiguration;
- SOCKET_IIO_CONFIGURATION mSocketIioConfiguration;
- SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
- SOCKET_COMMONRC_CONFIGURATION mSocketCommonRcConfiguration;
- SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCoreConfiguration;
- CPU_CONFIG_CONTEXT_BUFFER *mCpuConfigLibConfigContextBuffer = NULL;
- EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *mSpcrTable = NULL;
- /**
- The constructor function of AcpiPlatormL Library.
- The constructor function caches the value of PCD entry
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
- **/
- EFI_STATUS
- EFIAPI
- AcpiPlatformLibConstructor (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_HOB_GUID_TYPE *GuidHob;
- DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
- mCpuConfigLibConfigContextBuffer = (CPU_CONFIG_CONTEXT_BUFFER *) (UINTN) PcdGet64 (PcdCpuConfigContextBuffer);
- if (mCpuConfigLibConfigContextBuffer == NULL) {
- ASSERT_EFI_ERROR (RETURN_NOT_FOUND);
- return RETURN_NOT_FOUND;
- }
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
- if (GuidHob == NULL) {
- ASSERT (GuidHob != NULL);
- return EFI_NOT_FOUND;
- }
- mPlatformInfo = GET_GUID_HOB_DATA (GuidHob);
- //
- // Locate the IIO Protocol Interface
- //
- Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid, NULL, (VOID **) &mIioUds);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- Status = gBS->LocateProtocol (&gEfiCpuCsrAccessGuid, NULL, (VOID **) &mCpuCsrAccess);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- mCpuCsrAccessVarPtr = DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar ();
- mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
- ASSERT (mSystemMemoryMap != NULL);
- mMpService = NULL;
- Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &mMpService);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- //
- // Determine the number of processors
- //
- mMpService->GetNumberOfProcessors (
- mMpService,
- &mNumberOfCPUs,
- &mNumberOfEnabledCPUs
- );
- ASSERT (mNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
- if (mNumberOfCPUs > MAX_CPU_NUM) {
- mNumberOfCPUs = MAX_CPU_NUM;
- }
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- return EFI_SUCCESS;
- }
- /**
- Platform hook to initialize Platform Specific ACPI Parameters
- @retval EFI_SUCCESS Platform specific parameters in mAcpiParameter
- initialized successfully.
- @retval EFI_INVALID_PARAMETER mAcpiParameter global was NULL.
- **/
- EFI_STATUS
- PlatformHookAfterAcpiParamInit (
- VOID
- )
- {
- EFI_STATUS Status;
- Status = EFI_SUCCESS;
- if (mAcpiParameter == NULL) {
- ASSERT (mAcpiParameter != NULL);
- return EFI_INVALID_PARAMETER;
- }
- DEBUG ((DEBUG_INFO, "ACPI Parameter Block Address: 0x%X\n", mAcpiParameter));
- //
- // Call for Local APIC ID Reorder
- //
- Status = SortCpuLocalApicInTable ();
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: SortCpuLocalApicInTable failed: %r\n", Status));
- return Status;
- }
- return Status;
- }
- EFI_STATUS
- AcpiPlatformHooksIsActiveTable (
- IN OUT EFI_ACPI_COMMON_HEADER *Table
- )
- {
- EFI_NFIT_TABLE_UPDATE_PROTOCOL *NfitTableUpdateProtocol;
- EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
- EFI_STATUS Status;
- SETUP_DATA SetupData;
- SYSTEM_CONFIGURATION SystemConfiguration;
- UINT8 *OemSkuAcpiName;
- Status = GetEntireConfig (&SetupData);
- ASSERT_EFI_ERROR (Status);
- CopyMem (&SystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM_CONFIGURATION));
- if (mSystemMemoryMap == NULL) {
- ASSERT (FALSE);
- return EFI_NOT_FOUND;
- }
- TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
- if (TableHeader->Signature == ACPI_PMTT_TABLE_SIGNATURE) {
- if (!mSystemMemoryMap->DcpmmPresent) {
- return EFI_NOT_FOUND;
- }
- }
- if (TableHeader->Signature == EFI_BDAT_TABLE_SIGNATURE) {
- if (mSocketMemoryConfiguration.bdatEn == 0) {
- return EFI_NOT_FOUND;
- }
- }
- if (TableHeader->Signature == NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE) {
- if (mSystemMemoryMap->DcpmmPresent == 0) {
- return EFI_NOT_FOUND;
- }
- }
- if (TableHeader->Signature == NVDIMM_FW_INTERFACE_TABLE_SIGNATURE) {
- Status = gBS->LocateProtocol (&gEfiNfitTableUpdateProtocolGuid, NULL, (VOID **) &NfitTableUpdateProtocol);
- if (EFI_ERROR (Status)){
- // If NfitTableUpdateProtocol is not found we assume no NVDIMM is present - it means don't publish NFIT
- DEBUG ((DEBUG_ERROR, "NfitTableUpdateProtocol is not installed.\n"));
- return EFI_NOT_FOUND;
- }
- }
- if (TableHeader->Signature == EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE) {
- //
- // Initialize the SPCR table pointer.
- // SPCR table is not ready yet, update it before booting.
- //
- mSpcrTable = (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *) Table;
- return EFI_NOT_READY;
- }
- if ((TableHeader->Signature == EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE) ||
- (TableHeader->Signature == EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE) ||
- (TableHeader->Signature == EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) ||
- TableHeader->Signature == EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE) {
- //
- // Only publish SRAT/SLIT/MSCT/HMAT if NUMA is enabled in setup.
- //
- if (!mSocketCommonRcConfiguration.NumaEn) {
- DEBUG ((DEBUG_INFO, "[ACPI] NUMA disabled, do not publish '%c%c%c%c' table\n",
- ((CHAR8*)&TableHeader->Signature)[0], ((CHAR8*)&TableHeader->Signature)[1],
- ((CHAR8*)&TableHeader->Signature)[2], ((CHAR8*)&TableHeader->Signature)[3]));
- return EFI_NOT_FOUND;
- }
- }
- if (TableHeader->Signature == EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE) {
- return EFI_NOT_FOUND;
- }
- if (TableHeader->Signature == EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
- OemSkuAcpiName = PcdGetPtr (PcdOemSkuAcpiName);
- if (OemSkuAcpiName == NULL) {
- return EFI_UNSUPPORTED;
- }
- if ( (0 == CompareMem (&(TableHeader->OemTableId), OemSkuAcpiName, 8)) ) {
- Status = PlatformGetAcpiFixTableDataPointer ((VOID ** ) &mAmlOffsetTablePointer);
- if (!EFI_ERROR(Status)) {
- DEBUG((DEBUG_INFO, "[ACPI] Platform DSDT Fixup table found\n"));
- DEBUG((DEBUG_INFO, "[ACPI] Platform SRP: Using %a DSDT\n", OemSkuAcpiName));
- return EFI_SUCCESS;
- } else {
- DEBUG((DEBUG_ERROR, "[ACPI] Platform DSDT Fixup table not found.\n"));
- return EFI_UNSUPPORTED;
- }
- } else {
- DEBUG ((DEBUG_INFO, "[ACPI] Platform DSDT OemSkuAcpiName '%c%c%c%c%c%c%c%c':\n",
- ((CHAR8*)OemSkuAcpiName)[0], ((CHAR8*)OemSkuAcpiName)[1],
- ((CHAR8*)OemSkuAcpiName)[2], ((CHAR8*)OemSkuAcpiName)[3],
- ((CHAR8*)OemSkuAcpiName)[4], ((CHAR8*)OemSkuAcpiName)[5],
- ((CHAR8*)OemSkuAcpiName)[6], ((CHAR8*)OemSkuAcpiName)[7]));
- DEBUG ((DEBUG_INFO, " no match for OemTableId '%c%c%c%c%c%c%c%c' from FwVol.\n",
- ((CHAR8*)&TableHeader->OemTableId)[0], ((CHAR8*)&TableHeader->OemTableId)[1],
- ((CHAR8*)&TableHeader->OemTableId)[2], ((CHAR8*)&TableHeader->OemTableId)[3],
- ((CHAR8*)&TableHeader->OemTableId)[4], ((CHAR8*)&TableHeader->OemTableId)[5],
- ((CHAR8*)&TableHeader->OemTableId)[6], ((CHAR8*)&TableHeader->OemTableId)[7]));
- return EFI_UNSUPPORTED;
- }
- }
- //
- // Hooks for checking additional platform ACPI Table is active or not.
- // If ACPI Table is not in list, it should be reported and returned EFI_SUCCESS.
- //
- return PlatformAcpiReportHooksTableIsActive (Table);
- }
- /**
- This function will update any runtime platform specific information.
- This currently includes:
- Setting OEM table values, ID, table ID, creator ID and creator revision.
- Enabling the proper processor entries in the APIC tables.
- @param Table - The table to update
- @retval EFI_SUCCESS - The function completed successfully.
- **/
- EFI_STATUS
- PlatformUpdateTables (
- IN OUT EFI_ACPI_COMMON_HEADER *Table,
- IN OUT EFI_ACPI_TABLE_VERSION *Version
- )
- {
- EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
- EFI_STATUS Status;
- ACPI_APIC_STRUCTURE_PTR *ProcessorLocalApicEntry;
- UINT64 TempOemTableId;
- UINT32 Data32;
- DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- TableHeader = NULL;
- ProcessorLocalApicEntry = NULL;
- Status = EFI_SUCCESS;
- //
- // By default, a table belongs in all ACPI table versions published.
- // Some tables will override this because they have different versions of the table.
- //
- *Version = EFI_ACPI_TABLE_VERSION_2_0;
- if (Table->Signature != EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE &&
- Table->Signature != EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
- Table->Signature != SIGNATURE_32('N', 'F', 'I', 'T') &&
- Table->Signature != SIGNATURE_32('P', 'C', 'A', 'T') &&
- Table->Signature != SIGNATURE_32('O', 'E', 'M', '1') &&
- Table->Signature != SIGNATURE_32('O', 'E', 'M', '2') &&
- Table->Signature != SIGNATURE_32('O', 'E', 'M', '3') &&
- Table->Signature != SIGNATURE_32('O', 'E', 'M', '4'))
- {
- TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
- //
- // Update the OEMID and OEM Table ID.
- //
- TempOemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
- CopyMem (TableHeader->OemId, PcdGetPtr(PcdAcpiDefaultOemId), sizeof(TableHeader->OemId));
- CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(TableHeader->OemTableId));
- //
- // Update the creator ID
- //
- TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
- //
- // Update the creator revision
- //
- TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
- }
- //
- // Complete this function
- //
- //ASSERT (mMaxNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
- //
- // Assign a invalid intial value for update
- //
- //
- // Update the processors in the APIC table
- //
- DEBUG ((DEBUG_INFO, "[ACPI] Patching '%c%c%c%c' table...\n",
- ((CHAR8*)&Table->Signature)[0], ((CHAR8*)&Table->Signature)[1],
- ((CHAR8*)&Table->Signature)[2], ((CHAR8*)&Table->Signature)[3]));
- switch (Table->Signature) {
- //
- // Do not allow a prebuilt MADT, since it is built dynamically.
- //
- case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
- DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: Prebuilt MADT found\n"));
- Status = EFI_INVALID_PARAMETER;
- ASSERT_EFI_ERROR (Status);
- break;
- case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
- Status = PatchFadtTable (Table);
- break;
- case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
- //
- // Patch the memory resource
- //
- Status = PatchDsdtTable (Table);
- break;
- case EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
- Status = PatchSsdtTable (Table,Version);
- break;
- case EFI_ACPI_6_2_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
- //
- // Adjust HPET Table to correct the Base Address
- // Get the address bits in RCRB that configure HPET MMIO space
- // and create an offset to the pre-defined HEPT base address
- //
- DynamicSiLibraryProtocol2->PchHpetBaseGet (&Data32);
- //
- // Add the offset to the base address and copy into HPET DSDT table
- //
- ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table)->BaseAddressLower32Bit.Address = Data32;
- break;
- case EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
- Status = PatchMcfgAcpiTable (Table);
- break;
- case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
- Status = PatchSpcrAcpiTable (Table);
- break;
- case ACPI_PMTT_TABLE_SIGNATURE:
- if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
- Status = PatchPlatformMemoryTopologyTable (Table);
- }
- break;
- case EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE:
- if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
- Status = PatchHmatAcpiTable (Table);
- }
- break;
- case EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE:
- if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
- Status = PatchMsctAcpiTable (Table);
- }
- break;
- case EFI_MIGT_ACPI_TABLE_SIGNATURE:
- if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
- if (PcdGetBool (ReservedB)) {
- Status = PatchMigtAcpiTable (Table);
- }
- }
- break;
- case EFI_BDAT_TABLE_SIGNATURE:
- if (!PcdGetBool (PcdPlatformNotSupportAcpiBdatTable)) {
- Status = PatchBdatAcpiTable (Table);
- }
- break;
- case NVDIMM_FW_INTERFACE_TABLE_SIGNATURE:
- Status = UpdateNfitTable (Table);
- break;
- case NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE:
- Status = UpdatePcatTable (Table);
- break;
- //Patch Dynamic OEM SSDT table
- case OEM1_SSDT_TABLE_SIGNATURE:
- Status = PatchOem1SsdtTable (Table); //CPU EIST
- break;
- case OEM2_SSDT_TABLE_SIGNATURE:
- Status = PatchOem2SsdtTable (Table); //CPU HWP
- break;
- case OEM3_SSDT_TABLE_SIGNATURE:
- Status = PatchOem3SsdtTable (Table); //CPU TST
- break;
- case OEM4_SSDT_TABLE_SIGNATURE:
- Status = PatchOem4SsdtTable (Table); //CPU CST
- break;
- case ACPI_WSMT_SIGNATURE:
- (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags) = (UINT32 ) (WSMT_PROTECTION_FLAG & PcdGet32(PcdWsmtProtectionFlags));
- DEBUG ((DEBUG_INFO, "[WSMT] ProtectionFlags = 0x%x\n", (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags)));
- break;
- default:
- //
- // Hooks for Platform only table. If the ACPI Table is Platform only, add this table in below hook. then continue to update other Table.
- //
- Status = PatchPlatformSpecificAcpiTableHooks (Table);
- break;
- }
- //
- //
- // Update the hardware signature in the FACS structure
- //
- //
- //
- return Status;
- }
- /**
- Give the platform a chance to build tables.
- Some tables can be built from scratch more efficiently than being prebuilt
- and updated. This function builds any such tables for the platform.
- @retval EFI_SUCCESS Any platform tables were successfully built.
- **/
- EFI_STATUS
- PlatformBuildTables (
- VOID
- )
- {
- EFI_STATUS ReturnStatus = EFI_SUCCESS;
- EFI_STATUS Status;
- Status = InstallMadtFromScratch ();
- if (EFI_ERROR (Status)) {
- ReturnStatus = Status;
- }
- if (mSocketCommonRcConfiguration.NumaEn) {
- Status = InstallSlitTable ();
- if (EFI_ERROR (Status)) {
- ReturnStatus = Status;
- }
- Status = InstallSratTable ();
- if (EFI_ERROR (Status)) {
- ReturnStatus = Status;
- }
- }
- //
- // Return the first error code that occured, or success.
- //
- return ReturnStatus;
- }
|