diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc index 3e66104910c..e279111a9aa 100644 --- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc +++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc @@ -36,10 +36,12 @@ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + PciSegmentInfoLib|MdePkg/Library/BasePciSegmentInfoLibNull/BasePciSegmentInfoLibNull.inf PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf @@ -64,6 +66,7 @@ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf PlatformSocLib|AmdPlatformPkg/Library/DxePlatformSocLib/DxePlatformSocLibNull.inf SpiHcPlatformLib|AmdPlatformPkg/Universal/Spi/SpiFvb/SpiFvbDxe.inf + TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf [LibraryClasses.common.SMM_CORE] SmmCoreAmdSpiHcHookLib|AmdPlatformPkg/Library/SmmCoreAmdSpiHcHookLib/SmmCoreAmdSpiHcHookLib.inf @@ -77,10 +80,9 @@ [Components] AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManagerDxe.inf AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiFacsLib/AcpiFacsLib.inf - AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMadtLib/AcpiMadtLib.inf - AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMcfgLib/AcpiMcfgLib.inf AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiSsdtCpuTopologyLib/AcpiSsdtCpuTopologyLib.inf AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiSsdtPciLib/AcpiSsdtPciLib.inf + AmdPlatformPkg/DynamicTables/Library/SampleCmPlatOverrideLib/SamplecmPlatOverrideLib.inf AmdPlatformPkg/Library/BaseAlwaysFalseDepexLib/BaseAlwaysFalseDepexLib.inf AmdPlatformPkg/Library/DxePlatformSocLib/DxePlatformSocLibNull.inf AmdPlatformPkg/Library/SimulatorSerialPortLibPort80/SimulatorSerialPortLibPort80.inf diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/Acpi/Madt.c b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/Acpi/Madt.c new file mode 100755 index 00000000000..7ffc2c8330c --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/Acpi/Madt.c @@ -0,0 +1,372 @@ +/** @file + Collects the information required to update the MADT table. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ConfigurationManager.h" + +UINT32 mMadtCcdOrder[16] = { 0, 4, 8, 12, 2, 6, 10, 14, 3, 7, 11, 15, 1, 5, 9, 13 }; + +/** + Callback compare function. + Compares CCD number of provided arguments. + + @param[in] ProcessorInfoLeft Pointer to Left Buffer. + @param[in] ProcessorInfoRight Pointer to Right Buffer. + @return 0 If both are same + -1 If left value is less than righ value. + 1 If left value is greater than righ value. + +**/ +INTN +EFIAPI +MadtSortByCcd ( + CONST VOID *ProcessorInfoLeft, + CONST VOID *ProcessorInfoRight + ) +{ + CONST EFI_PROCESSOR_INFORMATION *Left; + CONST EFI_PROCESSOR_INFORMATION *Right; + UINT32 Index; + UINT32 LeftCcdIndex; + UINT32 RightCcdIndex; + + Left = (EFI_PROCESSOR_INFORMATION *)ProcessorInfoLeft; + Right = (EFI_PROCESSOR_INFORMATION *)ProcessorInfoRight; + + // Get the CCD Index number + LeftCcdIndex = MAX_UINT32; + for (Index = 0; Index < ARRAY_SIZE (mMadtCcdOrder); Index++) { + if (Left->ExtendedInformation.Location2.Die == mMadtCcdOrder[Index]) { + LeftCcdIndex = Index; + break; + } + } + + RightCcdIndex = MAX_UINT32; + for (Index = 0; Index < ARRAY_SIZE (mMadtCcdOrder); Index++) { + if (Right->ExtendedInformation.Location2.Die == mMadtCcdOrder[Index]) { + RightCcdIndex = Index; + break; + } + } + + // Now compare for quick sort + if (LeftCcdIndex < RightCcdIndex) { + return -1; + } + + if (LeftCcdIndex > RightCcdIndex) { + return 1; + } + + return 0; +} + +/** The UpdateMadtTable function updates the MADT table. + + @param [in, out] PlatformRepo Pointer to the platform repository information. + + @retval EFI_SUCCESS The MADT table is updated successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. +**/ +EFI_STATUS +EFIAPI +UpdateMadtTable ( + IN OUT EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpService; + UINTN NumberOfProcessors; + UINTN NumberOfEnabledProcessors; + UINT32 Index; + EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer; + UINTN NumSocket; + UINTN ThreadsPerCore; + UINTN Socket; + CM_X64_LOCAL_APIC_X2APIC_INFO *LocalApicInfo; + CM_X64_LOCAL_APIC_X2APIC_INFO *TempLocalApicInfo; + CM_X64_LOCAL_APIC_X2APIC_INFO *SrcLocalApicInfo; + CM_X64_LOCAL_APIC_X2APIC_INFO *DstLocalApicInfo; + UINT8 ApicMode; + CM_X64_IO_APIC_INFO *CmIoApicInfo; + EFI_ACPI_6_5_IO_APIC_STRUCTURE *IoApicInfo; + UINTN IoApicCount; + CM_X64_INTR_SOURCE_OVERRIDE_INFO *IntrSourceOverrideInfo; + UINTN IntrSourceOverrideCount; + CM_X64_LOCAL_APIC_X2APIC_NMI_INFO *LocalApicNmiInfo; + UINTN LocalApicNmiCount; + + if (PlatformRepo == NULL) { + return EFI_INVALID_PARAMETER; + } + + ApicMode = (UINT8)GetApicMode (); + PlatformRepo->MadtInfo.LocalApicAddress = PcdGet32 (PcdCpuLocalApicBaseAddress); + PlatformRepo->MadtInfo.Flags = EFI_ACPI_6_5_PCAT_COMPAT; + PlatformRepo->MadtInfo.ApicMode = ApicMode; + + Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpService); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a:%d Failed to locate MP Services Protocol. Status(%r)\n", + __func__, + __LINE__, + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status = MpService->GetNumberOfProcessors ( + MpService, + &NumberOfProcessors, + &NumberOfEnabledProcessors + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a:%d Failed to get number of processors. Status(%r)\n", + __func__, + __LINE__, + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; + } + + ProcessorInfoBuffer = AllocateZeroPool (NumberOfProcessors * sizeof (EFI_PROCESSOR_INFORMATION)); + if (ProcessorInfoBuffer == NULL) { + DEBUG (( + DEBUG_ERROR, + "%a:%d Failed to allocate memory for Processor Information Buffer. Status(%r)\n", + __func__, + __LINE__, + Status + )); + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); + return EFI_OUT_OF_RESOURCES; + } + + /// Get ProcessorInfoBuffer + NumSocket = 0; + ThreadsPerCore = 0; + for (Index = 0; Index < NumberOfProcessors; Index++) { + Status = MpService->GetProcessorInfo ( + MpService, + Index|CPU_V2_EXTENDED_TOPOLOGY, + &ProcessorInfoBuffer[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a:%d Failed to get Processor Information. Status(%r)\n", + __func__, + __LINE__, + Status + )); + ASSERT_EFI_ERROR (Status); + FreePool (ProcessorInfoBuffer); + return Status; + } + + if (ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Package > NumSocket) { + NumSocket = ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Package; + } + + if (ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Thread > ThreadsPerCore) { + ThreadsPerCore = ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Thread; + } + } + + /// Increment the NumSocket and ThreadsPerCore by 1, as it is 0 based + NumSocket++; + ThreadsPerCore++; + + /// Sort by CCD location + if (NumSocket > 1) { + PerformQuickSort ( + ProcessorInfoBuffer, + NumberOfProcessors/2, + sizeof (EFI_PROCESSOR_INFORMATION), + MadtSortByCcd + ); + PerformQuickSort ( + ProcessorInfoBuffer+(NumberOfProcessors/2), + NumberOfProcessors/2, + sizeof (EFI_PROCESSOR_INFORMATION), + MadtSortByCcd + ); + } else { + PerformQuickSort ( + ProcessorInfoBuffer, + NumberOfProcessors, + sizeof (EFI_PROCESSOR_INFORMATION), + MadtSortByCcd + ); + } + + LocalApicInfo = AllocateZeroPool (sizeof (CM_X64_LOCAL_APIC_X2APIC_INFO) * NumberOfProcessors); + if (LocalApicInfo == NULL) { + FreePool (ProcessorInfoBuffer); + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); + return EFI_OUT_OF_RESOURCES; + } + + for (Socket = 0; Socket < NumSocket; Socket++) { + for (Index = 0; Index < NumberOfProcessors; Index++) { + if (ProcessorInfoBuffer[Index].ProcessorId > MAX_UINT32) { + DEBUG ((DEBUG_ERROR, "%a:%d ProcessorId is greater than MAX_UINT32\n", __func__, __LINE__)); + FreePool (ProcessorInfoBuffer); + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + LocalApicInfo[Index].ApicId = (UINT32)ProcessorInfoBuffer[Index].ProcessorId; + if ((ProcessorInfoBuffer[Index].StatusFlag & PROCESSOR_ENABLED_BIT) != 0) { + LocalApicInfo[Index].Flags = 1; + } + + LocalApicInfo[Index].AcpiProcessorUid = Index; + } + } + + FreePool (ProcessorInfoBuffer); + + /// Now separate the first thread list + TempLocalApicInfo = NULL; + if (ThreadsPerCore > 1) { + TempLocalApicInfo = AllocateCopyPool ((sizeof (CM_X64_LOCAL_APIC_X2APIC_INFO) * NumberOfProcessors), (const void *)LocalApicInfo); + if (TempLocalApicInfo == NULL) { + FreePool (LocalApicInfo); + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); + return EFI_OUT_OF_RESOURCES; + } + + SrcLocalApicInfo = TempLocalApicInfo; + DstLocalApicInfo = LocalApicInfo; + for (Index = 0; Index < NumberOfProcessors; Index++) { + if ((SrcLocalApicInfo->ApicId & 0x1) == 0) { + CopyMem (DstLocalApicInfo, SrcLocalApicInfo, sizeof (CM_X64_LOCAL_APIC_X2APIC_INFO)); + SrcLocalApicInfo++; + DstLocalApicInfo++; + } else { + SrcLocalApicInfo++; + } + } + + SrcLocalApicInfo = TempLocalApicInfo; + for (Index = 0; Index < NumberOfProcessors; Index++) { + if ((SrcLocalApicInfo->ApicId & 0x1) == 1) { + CopyMem (DstLocalApicInfo, SrcLocalApicInfo, sizeof (CM_X64_LOCAL_APIC_X2APIC_INFO)); + SrcLocalApicInfo++; + DstLocalApicInfo++; + } else { + SrcLocalApicInfo++; + } + } + } + + if (TempLocalApicInfo != NULL) { + FreePool (TempLocalApicInfo); + } + + /// Now copy the LocalApicInfo to PlatformRepo + PlatformRepo->LocalApicX2ApicInfoCount = NumberOfProcessors; + PlatformRepo->LocalApicX2ApicInfo = LocalApicInfo; + + /// Get the IO APIC Information + + IoApicInfo = NULL; + IoApicCount = 0; + Status = GetIoApicInfo (&IoApicInfo, (UINT8 *)&IoApicCount); + if ((EFI_ERROR (Status) || (IoApicInfo == NULL) || (IoApicCount == 0))) { + DEBUG (( + DEBUG_ERROR, + "%a:%d GetIoApicInfo() failed. Status (%r).\n", + __func__, + __LINE__, + Status + )); + return Status; + } + + CmIoApicInfo = NULL; + CmIoApicInfo = AllocateZeroPool (sizeof (CM_X64_IO_APIC_INFO) * IoApicCount); + if (CmIoApicInfo == NULL) { + FreePool (IoApicInfo); + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); + return EFI_OUT_OF_RESOURCES; + } + + /// Copy the IO APIC Information + for (Index = 0; Index < IoApicCount; Index++) { + CmIoApicInfo[Index].IoApicId = IoApicInfo[Index].IoApicId; + CmIoApicInfo[Index].IoApicAddress = IoApicInfo[Index].IoApicAddress; + CmIoApicInfo[Index].GlobalSystemInterruptBase = IoApicInfo[Index].GlobalSystemInterruptBase; + } + + FreePool (IoApicInfo); + + PlatformRepo->IoApicInfoCount = IoApicCount; + PlatformRepo->IoApicInfo = CmIoApicInfo; + + /// Get the Interrupt Source Override Information + IntrSourceOverrideCount = 2; + IntrSourceOverrideInfo = AllocateZeroPool (sizeof (CM_X64_INTR_SOURCE_OVERRIDE_INFO) * IntrSourceOverrideCount); + if (IntrSourceOverrideInfo == NULL) { + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); + return EFI_OUT_OF_RESOURCES; + } + + IntrSourceOverrideInfo[0].Bus = 0x0; + IntrSourceOverrideInfo[0].Source = 0x0; + IntrSourceOverrideInfo[0].GlobalSystemInterrupt = 0x2; + IntrSourceOverrideInfo[0].Flags = 0xF; + + IntrSourceOverrideInfo[1].Bus = 0x0; + IntrSourceOverrideInfo[1].Source = 0x9; + IntrSourceOverrideInfo[1].GlobalSystemInterrupt = 0x9; + IntrSourceOverrideInfo[1].Flags = 0xF; + + PlatformRepo->IntrSourceOverrideInfoCount = IntrSourceOverrideCount; + PlatformRepo->IntrSourceOverrideInfo = IntrSourceOverrideInfo; + + /// Get the Local APIC NMI Information + LocalApicNmiCount = 1; + LocalApicNmiInfo = AllocateZeroPool (sizeof (CM_X64_LOCAL_APIC_X2APIC_NMI_INFO) * LocalApicNmiCount); + if (LocalApicNmiInfo == NULL) { + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); + return EFI_OUT_OF_RESOURCES; + } + + LocalApicNmiInfo[0].Flags = 0x5; + if (ApicMode == LOCAL_APIC_MODE_X2APIC) { + LocalApicNmiInfo[0].AcpiProcessorUid = MAX_UINT32; + } else { + LocalApicNmiInfo[0].AcpiProcessorUid = MAX_UINT8; + } + + LocalApicNmiInfo[0].LocalApicLint = 0x1; + + /// update the PlatformRepo + PlatformRepo->LocalApicX2ApicNmiInfoCount = LocalApicNmiCount; + PlatformRepo->LocalApicX2ApicNmiInfo = LocalApicNmiInfo; + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/Acpi/Mcfg.c b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/Acpi/Mcfg.c new file mode 100644 index 00000000000..572dc7b1234 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/Acpi/Mcfg.c @@ -0,0 +1,60 @@ +/** @file + This file contains the implementation of the MCFG table initialization for the + Configuration Manager DXE driver. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include "../ConfigurationManager.h" + +/** Updates ACPI MCFG table information in the platform repository. + + @param [in] PlatformRepo Pointer to the platform repository. + + @retval EFI_SUCCESS The ACPI MCFG table information is updated. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval EFI_NOT_FOUND The PCI segment information is not found. +**/ +EFI_STATUS +EFIAPI +UpdateMcfgTableInfo ( + IN EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo + ) +{ + PCI_SEGMENT_INFO *PciSegmentInfo; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo; + UINTN PciSegmentCount; + UINTN Index; + + if (PlatformRepo == NULL) { + return EFI_INVALID_PARAMETER; + } + + PciSegmentInfo = NULL; + PciSegmentCount = 0; + PciSegmentInfo = GetPciSegmentInfo (&PciSegmentCount); + if ((PciSegmentInfo == NULL) || (PciSegmentCount == 0)) { + return EFI_NOT_FOUND; + } + + PciConfigSpaceInfo = AllocateZeroPool (sizeof (CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO) * PciSegmentCount); + if (PciConfigSpaceInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < PciSegmentCount; Index++) { + PciConfigSpaceInfo[Index].BaseAddress = PciSegmentInfo[Index].BaseAddress; + PciConfigSpaceInfo[Index].PciSegmentGroupNumber = PciSegmentInfo[Index].SegmentNumber; + PciConfigSpaceInfo[Index].StartBusNumber = PciSegmentInfo[Index].StartBusNumber; + PciConfigSpaceInfo[Index].EndBusNumber = PciSegmentInfo[Index].EndBusNumber; + } + + PlatformRepo->PciConfigSpaceInfoCount = PciSegmentCount; + PlatformRepo->PciConfigSpaceInfo = PciConfigSpaceInfo; + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.c b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.c index 219512edb09..6d1b677a4a5 100755 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.c +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include "ConfigurationManager.h" /** The platform configuration repository information. @@ -64,6 +64,20 @@ EDKII_PLATFORM_REPOSITORY_INFO mAmdPlatformRepositoryInfo = { CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpmi), NULL }, + /// MCFG Table + { + EFI_ACPI_6_5_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg), + NULL + }, + /// MADT Table + { + EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION, + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt), + NULL + } }, /// PmProfile { @@ -175,7 +189,6 @@ EDKII_PLATFORM_REPOSITORY_INFO mAmdPlatformRepositoryInfo = { /** A structure describing the configuration manager protocol interface. */ STATIC -CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL mAmdPlatformConfigManagerProtocol = { CREATE_REVISION (1, 0), AmdPlatformGetObject, @@ -203,12 +216,19 @@ ConfigurationManagerDxeInitialize ( EFI_STATUS Status; UINTN Index; + Status = UpdateMcfgTableInfo (&mAmdPlatformRepositoryInfo); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR: Failed to update MCFG table info. Status = %r\n", Status)); + return Status; + } + /// set the OemTableId and OemRevision for the CmACpiTableList for (Index = 0; Index < ARRAY_SIZE (mAmdPlatformRepositoryInfo.CmAcpiTableList); Index++) { mAmdPlatformRepositoryInfo.CmAcpiTableList[Index].OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); mAmdPlatformRepositoryInfo.CmAcpiTableList[Index].OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); } + UpdateMadtTable (&mAmdPlatformRepositoryInfo); Status = gBS->InstallProtocolInterface ( &ImageHandle, &gEdkiiConfigurationManagerProtocolGuid, diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.h b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.h index b4c3b21588a..3ed47373731 100755 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.h +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManager.h @@ -12,47 +12,12 @@ #ifndef CONFIGURATION_MANAGER_H_ #define CONFIGURATION_MANAGER_H_ +#include #include #include #include - -/** The number of ACPI tables to install -*/ -#define PLAT_ACPI_TABLE_COUNT 5 - -/** The configuration manager version. -*/ -#define CONFIGURATION_MANAGER_REVISION CREATE_REVISION (1, 0) - -/** The OEM ID -*/ -#define CFG_MGR_OEM_ID { 'A', 'M', 'D', 'I', 'N', 'C' } - -/** A structure describing the platform configuration - manager repository information -*/ -typedef struct PlatformRepositoryInfo { - /// Configuration Manager Information - CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CmInfo; - - /// List of ACPI tables - CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT]; - CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO PowerManagementProfile; - CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID HypervisorVendorId; - CM_ARCH_COMMON_FIXED_FEATURE_FLAGS FixedFeatureFlags; - CM_X64_FADT_SCI_INTERRUPT SciInterrupt; - CM_X64_FADT_SCI_CMD_INFO SciCmdinfo; - CM_X64_FADT_PM_BLOCK_INFO PmBlockInfo; - CM_X64_FADT_GPE_BLOCK_INFO GpeBlockInfo; - CM_X64_FADT_X_PM_BLOCK_INFO XpmBlockInfo; - CM_X64_FADT_X_GPE_BLOCK_INFO XgpeBlockInfo; - CM_X64_FADT_SLEEP_BLOCK_INFO SleepBlockInfo; - CM_X64_FADT_RESET_BLOCK_INFO ResetBlockInfo; - CM_X64_FADT_MISC_INFO FadtMiscInfo; - CM_X64_HPET_INFO HpetInfo; - CM_X64_WSMT_FLAGS_INFO WsmtFlagsInfo; - CM_ARCH_COMMON_SPMI_INTERFACE_INFO SpmiInterfaceInfo; -} EDKII_PLATFORM_REPOSITORY_INFO; +#include +#include /** The SetObject function defines the interface implemented by the Configuration Manager Protocol for updating the Configuration @@ -100,4 +65,31 @@ AmdPlatformGetObject ( IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject ); +/** Updates ACPI MCFG table information in the platform repository. + + @param [in] PlatformRepo Pointer to the platform repository. + + @retval EFI_SUCCESS The ACPI MCFG table information is updated. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval EFI_UNSUPPORTED The operation is not supported. +**/ +EFI_STATUS +EFIAPI +UpdateMcfgTableInfo ( + IN EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo + ); + +/** The UpdateMadtTable function updates the MADT table. + + @param [in, out] PlatformRepo Pointer to the platform repository information. + + @retval EFI_SUCCESS The MADT table is updated successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. +**/ +EFI_STATUS +EFIAPI +UpdateMadtTable ( + IN OUT EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo + ); + #endif // CONFIGURATION_MANAGER_H_ diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManagerDxe.inf b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManagerDxe.inf index cf37ebaa453..48d1d5717ba 100755 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManagerDxe.inf +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/ConfigurationManagerDxe.inf @@ -22,9 +22,11 @@ # [Sources] + Acpi/Madt.c + Acpi/Mcfg.c ConfigurationManager.c - NameSpaceObject.c ConfigurationManager.h + NameSpaceObject.c [Packages] AmdPlatformPkg/AmdPlatformPkg.dec @@ -35,19 +37,27 @@ PcAtChipsetPkg/PcAtChipsetPkg.dec [LibraryClasses] + BaseMemoryLib DebugLib + LocalApicLib + MemoryAllocationLib + PciSegmentInfoLib + PlatformSocLib PrintLib + SortLib UefiBootServicesTableLib UefiDriverEntryPoint UefiRuntimeServicesTableLib [Protocols] gEdkiiConfigurationManagerProtocolGuid + gEfiMpServiceProtocolGuid [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress [Depex] TRUE diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/NameSpaceObject.c b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/NameSpaceObject.c index 13ceba08607..4f12b2aee8e 100644 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/NameSpaceObject.c +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/ConfigurationManagerDxe/NameSpaceObject.c @@ -8,8 +8,8 @@ #include #include #include +#include #include -#include #include "ConfigurationManager.h" /** A helper function for returning the Configuration Manager Objects. @@ -32,6 +32,14 @@ HandleCmObject ( IN OUT CM_OBJ_DESCRIPTOR *CONST CmObjectDesc ) { + if ((ObjectSize > MAX_UINT32) || (ObjectCount > MAX_UINT32)) { + return EFI_INVALID_PARAMETER; + } + + if (Object == NULL) { + return EFI_INVALID_PARAMETER; + } + CmObjectDesc->ObjectId = CmObjectId; CmObjectDesc->Size = (UINT32)ObjectSize; CmObjectDesc->Data = (VOID *)Object; @@ -84,6 +92,66 @@ SetHandleCmObject ( return EFI_SUCCESS; } +/** A helper function for setting the Configuration Manager Objects. + @param [in] CmObjectId The Configuration Manager Object ID. + @param [out] Object Pointer to the Object(s). + @param [in] ObjectSize Total size of the Object(s). + @param [in] ObjectCount Number of Objects. + @param [in] CmObjectDesc Pointer to the Configuration Manager Object + descriptor describing the requested Object. + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_BAD_BUFFER_SIZE The buffer size is invalid. + @retval EFI_OUT_OF_RESOURCES The buffer allocation failed. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small. +**/ +STATIC +EFI_STATUS +EFIAPI +SetHandleCmObjectBuffer ( + IN CM_OBJECT_ID CmObjectId, + OUT VOID **Object, + IN CONST UINTN ObjectSize, + IN UINTN *ObjectCount, + IN CM_OBJ_DESCRIPTOR *CONST CmObjectDesc + ) +{ + EFI_STATUS Status; + VOID *Buffer; + + if ((Object == NULL) || + (*Object == NULL) || + (ObjectCount == NULL) || + (CmObjectDesc == NULL) + ) + { + return EFI_INVALID_PARAMETER; + } + + if (*ObjectCount == 0) { + return EFI_BUFFER_TOO_SMALL; + } + + if (CmObjectDesc->Count != *ObjectCount) { + Buffer = AllocateZeroPool (CmObjectDesc->Size * CmObjectDesc->Count); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *ObjectCount = CmObjectDesc->Count; + } else { + Buffer = *Object; + } + + Status = SetHandleCmObject (CmObjectId, Buffer, CmObjectDesc->Size, *ObjectCount, CmObjectDesc); + if ((!EFI_ERROR (Status)) && (Buffer != *Object)) { + FreePool (*Object); + *Object = Buffer; + } + + return Status; +} + /** Return a standard namespace object. @param [in] This Pointer to the Configuration Manager Protocol. @@ -229,6 +297,15 @@ GetArchNameSpaceObject ( CmObject ); break; + case EArchCommonObjPciConfigSpaceInfo: + Status = HandleCmObject ( + CmObjectId, + PlatformRepo->PciConfigSpaceInfo, + sizeof (*(PlatformRepo->PciConfigSpaceInfo)) * PlatformRepo->PciConfigSpaceInfoCount, + PlatformRepo->PciConfigSpaceInfoCount, + CmObject + ); + break; default: { Status = EFI_NOT_FOUND; @@ -309,6 +386,15 @@ SetArchNameSpaceObject ( CmObject ); break; + case EArchCommonObjPciConfigSpaceInfo: + Status = SetHandleCmObjectBuffer ( + CmObjectId, + (VOID **)&PlatformRepo->PciConfigSpaceInfo, + sizeof (*(PlatformRepo->PciConfigSpaceInfo)) * PlatformRepo->PciConfigSpaceInfoCount, + (VOID *)&PlatformRepo->PciConfigSpaceInfoCount, + CmObject + ); + break; default: { Status = EFI_NOT_FOUND; @@ -459,6 +545,51 @@ GetX64NameSpaceObject ( CmObject ); break; + case EX64ObjMadtInfo: + Status = HandleCmObject ( + CmObjectId, + &PlatformRepo->MadtInfo, + sizeof (PlatformRepo->MadtInfo), + 1, + CmObject + ); + break; + case EX64ObjLocalApicX2ApicInfo: + Status = HandleCmObject ( + CmObjectId, + PlatformRepo->LocalApicX2ApicInfo, + sizeof (*(PlatformRepo->LocalApicX2ApicInfo)) * PlatformRepo->LocalApicX2ApicInfoCount, + PlatformRepo->LocalApicX2ApicInfoCount, + CmObject + ); + break; + case EX64ObjIoApicInfo: + Status = HandleCmObject ( + CmObjectId, + PlatformRepo->IoApicInfo, + sizeof (*(PlatformRepo->IoApicInfo)) * PlatformRepo->IoApicInfoCount, + PlatformRepo->IoApicInfoCount, + CmObject + ); + break; + case EX64ObjIntrSourceOverrideInfo: + Status = HandleCmObject ( + CmObjectId, + PlatformRepo->IntrSourceOverrideInfo, + sizeof (*(PlatformRepo->IntrSourceOverrideInfo)) * PlatformRepo->IntrSourceOverrideInfoCount, + PlatformRepo->IntrSourceOverrideInfoCount, + CmObject + ); + break; + case EX64ObjLocalApicX2ApicNmiInfo: + Status = HandleCmObject ( + CmObjectId, + PlatformRepo->LocalApicX2ApicNmiInfo, + sizeof (*(PlatformRepo->LocalApicX2ApicNmiInfo)) * PlatformRepo->LocalApicX2ApicNmiInfoCount, + PlatformRepo->LocalApicX2ApicNmiInfoCount, + CmObject + ); + break; default: { Status = EFI_NOT_FOUND; @@ -605,6 +736,51 @@ SetX64NameSpaceObject ( CmObject ); break; + case EX64ObjMadtInfo: + Status = SetHandleCmObject ( + CmObjectId, + &PlatformRepo->MadtInfo, + sizeof (PlatformRepo->MadtInfo), + 1, + CmObject + ); + break; + case EX64ObjLocalApicX2ApicInfo: + Status = SetHandleCmObjectBuffer ( + CmObjectId, + (VOID **)&PlatformRepo->LocalApicX2ApicInfo, + sizeof (*(PlatformRepo->LocalApicX2ApicInfo)) * PlatformRepo->LocalApicX2ApicInfoCount, + (VOID *)&PlatformRepo->LocalApicX2ApicInfoCount, + CmObject + ); + break; + case EX64ObjIoApicInfo: + Status = SetHandleCmObjectBuffer ( + CmObjectId, + (VOID **)&PlatformRepo->IoApicInfo, + sizeof (*(PlatformRepo->IoApicInfo)) * PlatformRepo->IoApicInfoCount, + (VOID *)&PlatformRepo->IoApicInfoCount, + CmObject + ); + break; + case EX64ObjIntrSourceOverrideInfo: + Status = SetHandleCmObjectBuffer ( + CmObjectId, + (VOID **)&PlatformRepo->IntrSourceOverrideInfo, + sizeof (*(PlatformRepo->IntrSourceOverrideInfo)) * PlatformRepo->IntrSourceOverrideInfoCount, + (VOID *)&PlatformRepo->IntrSourceOverrideInfoCount, + CmObject + ); + break; + case EX64ObjLocalApicX2ApicNmiInfo: + Status = SetHandleCmObjectBuffer ( + CmObjectId, + (VOID **)&PlatformRepo->LocalApicX2ApicNmiInfo, + sizeof (*(PlatformRepo->LocalApicX2ApicNmiInfo)) * PlatformRepo->LocalApicX2ApicNmiInfoCount, + (VOID *)&PlatformRepo->LocalApicX2ApicNmiInfoCount, + CmObject + ); + break; default: Status = EFI_NOT_FOUND; DEBUG (( diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMadtLib/AcpiMadtLib.c b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMadtLib/AcpiMadtLib.c deleted file mode 100644 index 16e2849ad9d..00000000000 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMadtLib/AcpiMadtLib.c +++ /dev/null @@ -1,816 +0,0 @@ -/** @file - - Generate ACPI MADT table for AMD platforms. - - Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. - - SPDX-License-Identifier BSD-2-Clause-Patent -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -UINT32 mMadtCcdOrder[16] = { 0, 4, 8, 12, 2, 6, 10, 14, 3, 7, 11, 15, 1, 5, 9, 13 }; - -/** - Callback compare function. - Compares CCD number of provided arguments. - - @param[in] ProcessorInfoLeft Pointer to Left Buffer. - @param[in] ProcessorInfoRight Pointer to Right Buffer. - @return 0 If both are same - -1 If left value is less than righ value. - 1 If left value is greater than righ value. - -**/ -INTN -EFIAPI -MadtSortByCcd ( - CONST VOID *ProcessorInfoLeft, - CONST VOID *ProcessorInfoRight - ) -{ - CONST EFI_PROCESSOR_INFORMATION *Left; - CONST EFI_PROCESSOR_INFORMATION *Right; - UINT32 Index; - UINT32 LeftCcdIndex; - UINT32 RightCcdIndex; - - Left = (EFI_PROCESSOR_INFORMATION *)ProcessorInfoLeft; - Right = (EFI_PROCESSOR_INFORMATION *)ProcessorInfoRight; - - // Get the CCD Index number - LeftCcdIndex = MAX_UINT32; - for (Index = 0; Index < ARRAY_SIZE (mMadtCcdOrder); Index++) { - if (Left->ExtendedInformation.Location2.Die == mMadtCcdOrder[Index]) { - LeftCcdIndex = Index; - break; - } - } - - RightCcdIndex = MAX_UINT32; - for (Index = 0; Index < ARRAY_SIZE (mMadtCcdOrder); Index++) { - if (Right->ExtendedInformation.Location2.Die == mMadtCcdOrder[Index]) { - RightCcdIndex = Index; - break; - } - } - - // Now compare for quick sort - if (LeftCcdIndex < RightCcdIndex) { - return -1; - } - - if (LeftCcdIndex > RightCcdIndex) { - return 1; - } - - return 0; -} - -/** - Get local NMI information for AMD platforms. - - @param[in, out] LocalNmi Pointer to the Local NMI information. - @param[in, out] LocalNmiSize Size of the Local NMI information. - - @retval EFI_SUCCESS Successfully got Local NMI information. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Local NMI information. - @retval EFI_INVALID_PARAMETER LocalNmi or LocalNmiSize is NULL. -**/ -EFI_STATUS -GenerateLocalNmi ( - IN OUT UINT8 **LocalNmi, - IN OUT UINTN *LocalNmiSize - ) -{ - EFI_ACPI_6_5_LOCAL_APIC_NMI_STRUCTURE *LocalApicNmiInfo; - EFI_ACPI_6_5_LOCAL_X2APIC_NMI_STRUCTURE *LocalX2ApicNmiInfo; - - if ((LocalNmi == NULL) || (LocalNmiSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (LOCAL_APIC_MODE_X2APIC == GetApicMode ()) { - LocalX2ApicNmiInfo = AllocateZeroPool (sizeof (EFI_ACPI_6_5_LOCAL_X2APIC_NMI_STRUCTURE)); - if (LocalX2ApicNmiInfo == NULL) { - DEBUG ((DEBUG_ERROR, "Failed to allocate memory for Local NMI Structure.\n")); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - LocalX2ApicNmiInfo->Type = EFI_ACPI_6_5_LOCAL_X2APIC_NMI; - LocalX2ApicNmiInfo->Length = sizeof (EFI_ACPI_6_5_LOCAL_X2APIC_NMI_STRUCTURE); - LocalX2ApicNmiInfo->Flags = 0x5; - LocalX2ApicNmiInfo->AcpiProcessorUid = 0xFFFFFFFF; - LocalX2ApicNmiInfo->LocalX2ApicLint = 0x1; - LocalX2ApicNmiInfo->Reserved[0] = 0; - LocalX2ApicNmiInfo->Reserved[1] = 0; - LocalX2ApicNmiInfo->Reserved[2] = 0; - *LocalNmi = (UINT8 *)LocalX2ApicNmiInfo; - *LocalNmiSize = sizeof (EFI_ACPI_6_5_LOCAL_X2APIC_NMI_STRUCTURE); - } else { - LocalApicNmiInfo = AllocateZeroPool (sizeof (EFI_ACPI_6_5_LOCAL_APIC_NMI_STRUCTURE)); - if (LocalApicNmiInfo == NULL) { - DEBUG ((DEBUG_ERROR, "Failed to allocate memory for Local NMI Structure.\n")); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - LocalApicNmiInfo->Type = EFI_ACPI_6_5_LOCAL_APIC_NMI; - LocalApicNmiInfo->Length = sizeof (EFI_ACPI_6_5_LOCAL_APIC_NMI_STRUCTURE); - LocalApicNmiInfo->AcpiProcessorUid = 0xFF; - LocalApicNmiInfo->Flags = 0x5; - LocalApicNmiInfo->LocalApicLint = 0x1; - *LocalNmi = (UINT8 *)LocalApicNmiInfo; - *LocalNmiSize = sizeof (EFI_ACPI_6_5_LOCAL_APIC_NMI_STRUCTURE); - } - - return EFI_SUCCESS; -} - -/** - Get Interrupt Source Override information for AMD platforms. - - @param[in, out] InterruptSourceOverride Pointer to the Interrupt Source Override information. - @param[in, out] InterruptSourceOverrideSize Size of the Interrupt Source Override information. - - @retval EFI_SUCCESS Successfully got Interrupt Source Override information. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Interrupt Source Override information. - -**/ -EFI_STATUS -GenerateinterruptSourceOverride ( - IN OUT EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE **InterruptSourceOverride, - IN OUT UINTN *InterruptSourceOverrideSize - ) -{ - EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *InterruptSourceOverrideInfo; - - if ((InterruptSourceOverride == NULL) || (InterruptSourceOverrideSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - InterruptSourceOverrideInfo = AllocateZeroPool ( - 2 * sizeof (EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE) - ); - if (InterruptSourceOverrideInfo == NULL) { - DEBUG ((DEBUG_ERROR, "Failed to allocate memory for Interrupt Source Override Structure.\n")); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - InterruptSourceOverrideInfo[0].Type = EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE; - InterruptSourceOverrideInfo[0].Length = sizeof (EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE); - InterruptSourceOverrideInfo[0].Bus = 0x0; - InterruptSourceOverrideInfo[0].Source = 0x0; - InterruptSourceOverrideInfo[0].GlobalSystemInterrupt = 0x2; - InterruptSourceOverrideInfo[0].Flags = 0xF; - - InterruptSourceOverrideInfo[1].Type = EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE; - InterruptSourceOverrideInfo[1].Length = sizeof (EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE); - InterruptSourceOverrideInfo[1].Bus = 0x0; - InterruptSourceOverrideInfo[1].Source = 0x9; - InterruptSourceOverrideInfo[1].GlobalSystemInterrupt = 0x9; - InterruptSourceOverrideInfo[1].Flags = 0xF; - - *InterruptSourceOverride = InterruptSourceOverrideInfo; - *InterruptSourceOverrideSize = 2 * sizeof (EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE); - return EFI_SUCCESS; -} - -/** - Get IO APIC information for AMD platforms. - - @param[in, out] IoApic Pointer to the IO APIC information. - @param[in, out] IoApicSize Number of IO APICs. - - @retval EFI_SUCCESS Successfully got IO APIC information. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for IO APIC information. - @retval Others Failed to get IO APIC information. -**/ -EFI_STATUS -GenerateIoApicStructure ( - IN OUT EFI_ACPI_6_5_IO_APIC_STRUCTURE **IoApic, - IN OUT UINTN *IoApicSize - ) -{ - EFI_ACPI_6_5_IO_APIC_STRUCTURE *IoApicInfo; - EFI_STATUS Status; - UINTN IoApicCount; - - if ((IoApic == NULL) || (IoApicSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - /// Get IOAPIC information - IoApicInfo = NULL; - IoApicCount = 0; - Status = GetIoApicInfo (&IoApicInfo, (UINT8 *)&IoApicCount); - if ((EFI_ERROR (Status) || (IoApicInfo == NULL) || (IoApicCount == 0))) { - DEBUG (( - DEBUG_ERROR, - "%a:%d GetIoApicInfo() failed. Status (%r).\n", - __func__, - __LINE__, - Status - )); - return Status; - } - - *IoApic = IoApicInfo; - *IoApicSize = IoApicCount * sizeof (EFI_ACPI_6_5_IO_APIC_STRUCTURE); - return EFI_SUCCESS; -} - -/** - Generate Processor Local APIC Structure for AMD platforms. - - @param[in, out] ProcessorLocalApic Pointer to the generated Processor Local APIC Structure. - @param[in, out] ProcessorLocalApicSize Size of the generated Processor Local APIC Structure. - - @retval EFI_SUCCESS Successfully generated Processor Local APIC Structure. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Processor Local APIC Structure. - @retval Others Failed to generate Processor Local APIC Structure. -**/ -EFI_STATUS -GenerateProcessorLocalApicStructure ( - IN OUT UINT8 **ProcessorLocalApic, - IN OUT UINTN *ProcessorLocalApicSize - ) -{ - EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE *DstApic; - EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApic; - EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE *SortedItemApic; - EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE *SrcApic; - EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *DstX2Apic; - EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2Apic; - EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *SortedItemX2Apic; - EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *SrcX2Apic; - EFI_MP_SERVICES_PROTOCOL *MpService; - EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer; - EFI_STATUS Status; - UINTN Index; - UINTN LocalApicSize; - UINTN NumberOfEnabledProcessors; - UINTN NumberOfProcessors; - UINTN NumSocket; - UINTN Socket; - UINTN ThreadsPerCore; - - /// Locate MP Services protocol - Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpService); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to locate MP Services Protocol. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; - } - - /// Get number of processors - Status = MpService->GetNumberOfProcessors ( - MpService, - &NumberOfProcessors, - &NumberOfEnabledProcessors - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to get number of processors. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; - } - - ProcessorInfoBuffer = AllocateZeroPool (NumberOfProcessors * sizeof (EFI_PROCESSOR_INFORMATION)); - if (ProcessorInfoBuffer == NULL) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to allocate memory for Processor Information Buffer. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - /// Get ProcessorInfoBuffer - NumSocket = 0; - ThreadsPerCore = 0; - for (Index = 0; Index < NumberOfProcessors; Index++) { - Status = MpService->GetProcessorInfo ( - MpService, - Index|CPU_V2_EXTENDED_TOPOLOGY, - &ProcessorInfoBuffer[Index] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to get Processor Information. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - FreePool (ProcessorInfoBuffer); - return Status; - } - - if (ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Package > NumSocket) { - NumSocket = ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Package; - } - - if (ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Thread > ThreadsPerCore) { - ThreadsPerCore = ProcessorInfoBuffer[Index].ExtendedInformation.Location2.Thread; - } - } - - /// increment the NumSocket and ThreadsPerCore by 1, as it is 0 based - NumSocket++; - ThreadsPerCore++; - - /// Sort by CCD location - if (NumSocket > 1) { - PerformQuickSort ( - ProcessorInfoBuffer, - NumberOfProcessors/2, - sizeof (EFI_PROCESSOR_INFORMATION), - MadtSortByCcd - ); - PerformQuickSort ( - ProcessorInfoBuffer+(NumberOfProcessors/2), - NumberOfProcessors/2, - sizeof (EFI_PROCESSOR_INFORMATION), - MadtSortByCcd - ); - } else { - PerformQuickSort ( - ProcessorInfoBuffer, - NumberOfProcessors, - sizeof (EFI_PROCESSOR_INFORMATION), - MadtSortByCcd - ); - } - - LocalApic = NULL; - LocalX2Apic = NULL; - /// check whether in APIC mode or x2APIC mode - if (LOCAL_APIC_MODE_X2APIC == GetApicMode ()) { - /// Allocate memory for processor local x2APIC structure - LocalApicSize = NumberOfProcessors * sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE); - LocalX2Apic = AllocateZeroPool (LocalApicSize); - if (LocalX2Apic == NULL) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to allocate memory for Processor Local X2APIC Structure. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - FreePool (ProcessorInfoBuffer); - return EFI_OUT_OF_RESOURCES; - } - } else { - /// Allocate memory for Processor Local APIC Structure - LocalApicSize = NumberOfProcessors * sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE); - LocalApic = AllocateZeroPool (LocalApicSize); - if (LocalApic == NULL) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to allocate memory for Processor Local APIC Structure. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - FreePool (ProcessorInfoBuffer); - return EFI_OUT_OF_RESOURCES; - } - } - - for (Socket = 0; Socket < NumSocket; Socket++) { - for (Index = 0; Index < NumberOfProcessors; Index++) { - if ((ProcessorInfoBuffer[Index].StatusFlag & PROCESSOR_ENABLED_BIT) != 0) { - if (LOCAL_APIC_MODE_X2APIC == GetApicMode ()) { - LocalX2Apic[Index].Type = EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC; - LocalX2Apic[Index].Length = sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE); - LocalX2Apic[Index].Reserved[0] = 0; - LocalX2Apic[Index].Reserved[1] = 0; - LocalX2Apic[Index].X2ApicId = (UINT32)ProcessorInfoBuffer[Index].ProcessorId; - LocalX2Apic[Index].Flags = 1; - LocalX2Apic[Index].AcpiProcessorUid = (UINT32)Index; - } else { - LocalApic[Index].Type = EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC; - LocalApic[Index].Length = sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE); - LocalApic[Index].ApicId = (UINT8)ProcessorInfoBuffer[Index].ProcessorId; - LocalApic[Index].Flags = 1; - LocalApic[Index].AcpiProcessorUid = (UINT8)Index; - } - } else { - if (LOCAL_APIC_MODE_X2APIC == GetApicMode ()) { - LocalX2Apic[Index].Type = EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC; - LocalX2Apic[Index].Length = sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE); - LocalX2Apic[Index].Reserved[0] = 0; - LocalX2Apic[Index].Reserved[1] = 0; - LocalX2Apic[Index].X2ApicId = MAX_UINT32; - LocalX2Apic[Index].Flags = 0; - LocalX2Apic[Index].AcpiProcessorUid = MAX_UINT32; - } else { - LocalApic[Index].Type = EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC; - LocalApic[Index].Length = sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE); - LocalApic[Index].AcpiProcessorUid = MAX_UINT8; - LocalApic[Index].ApicId = MAX_INT8; - LocalApic[Index].Flags = 0; - } - } - } - } - - FreePool (ProcessorInfoBuffer); - - /// Now separate the second thread list - if (ThreadsPerCore > 1) { - if (LOCAL_APIC_MODE_X2APIC == GetApicMode ()) { - SortedItemX2Apic = NULL; - SortedItemX2Apic = AllocateZeroPool ( - sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE) * NumberOfProcessors - ); - if (SortedItemX2Apic == NULL) { - FreePool (LocalX2Apic); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - SrcX2Apic = LocalX2Apic; - DstX2Apic = SortedItemX2Apic; - for (Index = 0; Index < NumberOfProcessors; Index++) { - if ((SrcX2Apic->X2ApicId & 0x1) == 0) { - CopyMem (DstX2Apic, SrcX2Apic, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE)); - SrcX2Apic++; - DstX2Apic++; - } else { - SrcX2Apic++; - } - } - - SrcX2Apic = LocalX2Apic; - for (Index = 0; Index < NumberOfProcessors; Index++) { - if ((SrcX2Apic->X2ApicId & 0x1) == 1) { - CopyMem (DstX2Apic, SrcX2Apic, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE)); - SrcX2Apic++; - DstX2Apic++; - } else { - SrcX2Apic++; - } - } - - CopyMem ( - LocalX2Apic, - SortedItemX2Apic, - sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE) * NumberOfProcessors - ); - FreePool (SortedItemX2Apic); - } else { - SortedItemApic = NULL; - SortedItemApic = AllocateZeroPool ( - sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE) * NumberOfProcessors - ); - if (SortedItemApic == NULL) { - FreePool (LocalApic); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - SrcApic = LocalApic; - DstApic = SortedItemApic; - for (Index = 0; Index < NumberOfProcessors; Index++) { - if ((SrcApic->ApicId & 0x1) == 0) { - CopyMem (DstApic, SrcApic, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE)); - SrcApic++; - DstApic++; - } else { - SrcApic++; - } - } - - SrcApic = LocalApic; - for (Index = 0; Index < NumberOfProcessors; Index++) { - if ((SrcApic->ApicId & 0x1) == 1) { - CopyMem (DstApic, SrcApic, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE)); - SrcApic++; - DstApic++; - } else { - SrcApic++; - } - } - - CopyMem ( - LocalApic, - SortedItemApic, - sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE) * NumberOfProcessors - ); - FreePool (SortedItemApic); - } - } - - /// copy the data to arguments - if (LOCAL_APIC_MODE_X2APIC == GetApicMode ()) { - *ProcessorLocalApic = (UINT8 *)LocalX2Apic; - } else { - *ProcessorLocalApic = (UINT8 *)LocalApic; - } - - *ProcessorLocalApicSize = LocalApicSize; - - return EFI_SUCCESS; -} - -/** - Generate ACPI MADT table for AMD platforms. - - @param[in, out] AcpiMadt Pointer to the generated MADT Table Header. - - @retval EFI_SUCCESS Successfully generated MADT Table. - @retval EFI_INVALID_PARAMETER AcpiMadt is NULL. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for MADT Table. -**/ -EFI_STATUS -GenerateMadtTableHeader ( - IN OUT EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER **AcpiMadt - ) -{ - EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtTableHeader; - - if (AcpiMadt == NULL) { - return EFI_INVALID_PARAMETER; - } - - /// Allocate memory for MADT Table - MadtTableHeader = AllocateZeroPool (sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER)); - if (MadtTableHeader == NULL) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to allocate memory for MADT Table.\n", - __func__, - __LINE__ - )); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - /// Initialize MADT Table Header - MadtTableHeader->Header.Signature = EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE; - MadtTableHeader->Header.Length = sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER); - MadtTableHeader->Header.Revision = EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION; - MadtTableHeader->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); - MadtTableHeader->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); - MadtTableHeader->Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); - MadtTableHeader->Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); - CopyMem ( - &MadtTableHeader->Header.OemId, - PcdGetPtr (PcdAcpiDefaultOemId), - sizeof (MadtTableHeader->Header.OemId) - ); - - /// Initialize Local APIC Address and Flags - MadtTableHeader->LocalApicAddress = PcdGet32 (PcdCpuLocalApicBaseAddress); - MadtTableHeader->Flags = EFI_ACPI_6_5_PCAT_COMPAT; - - *AcpiMadt = MadtTableHeader; - return EFI_SUCCESS; -} - -/** - Implementation of AcpiMadtLibConstructor for AMD platforms. - This is library constructor for AcpiMadtLib. - - @param[in] ImageHandle Image handle of the loaded driver. - @param[in] SystemTable Pointer to the EFI System Table. - - @retval EFI_SUCCESS Successfully generated and installed MADT Table. - @retval Others Failed to generate and install MADT Table. -**/ -EFI_STATUS -EFIAPI -AcpiMadtLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *InterruptSourceOverride; - EFI_ACPI_6_5_IO_APIC_STRUCTURE *IoApic; - EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *AcpiMadt; - EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *AcpiMadtHeader; - EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol; - EFI_STATUS Status; - UINT8 *AcpiMadtPtr; - UINT8 *LocalNmi; - UINT8 *ProcessorLocalApic; - UINTN HeaderSize; - UINTN InterruptSourceOverrideSize; - UINTN IoApicSize; - UINTN LocalNmiSize; - UINTN NewTableKey; - UINTN ProcessorLocalApicSize; - UINTN TableSize; - - /// MADT Table Generation code goes here - DEBUG ((DEBUG_INFO, "Generating ACPI MADT Table.\n")); - - /// Locate ACPI Table Protocol - Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiProtocol); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to locate ACPI Table Protocol. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; - } - - TableSize = 0; - AcpiMadt = NULL; - Status = GenerateMadtTableHeader (&AcpiMadtHeader); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to generate MADT Table Header. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; - } - - HeaderSize = sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER); - TableSize += HeaderSize; - - /// Generate Processor Local APIC Structure - Status = GenerateProcessorLocalApicStructure (&ProcessorLocalApic, &ProcessorLocalApicSize); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to generate Processor Local APIC Structure. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - FreePool (AcpiMadtHeader); - return Status; - } - - TableSize += ProcessorLocalApicSize; - - /// Generate IO APIC Structure - Status = GenerateIoApicStructure (&IoApic, &IoApicSize); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to generate IO APIC Structure. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - FreePool (ProcessorLocalApic); - FreePool (AcpiMadtHeader); - return Status; - } - - TableSize += IoApicSize; - - /// Generate Interrupt Source Override Structure - Status = GenerateinterruptSourceOverride (&InterruptSourceOverride, &InterruptSourceOverrideSize); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to generate Interrupt Source Override Structure. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - FreePool (IoApic); - FreePool (ProcessorLocalApic); - FreePool (AcpiMadtHeader); - return Status; - } - - TableSize += InterruptSourceOverrideSize; - - /// Generate Local NMI Structure - Status = GenerateLocalNmi (&LocalNmi, &LocalNmiSize); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to generate Local NMI Structure. Status(%r)\n", - __func__, - __LINE__, - Status - )); - ASSERT_EFI_ERROR (Status); - FreePool (InterruptSourceOverride); - FreePool (IoApic); - FreePool (ProcessorLocalApic); - FreePool (AcpiMadtHeader); - return Status; - } - - TableSize += LocalNmiSize; - - AcpiMadt = AllocateZeroPool (TableSize); - if (AcpiMadt == NULL) { - DEBUG (( - DEBUG_ERROR, - "%a:%d Failed to allocate memory for MADT Table.\n", - __func__, - __LINE__ - )); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - FreePool (InterruptSourceOverride); - FreePool (IoApic); - FreePool (ProcessorLocalApic); - FreePool (AcpiMadtHeader); - return EFI_OUT_OF_RESOURCES; - } - - AcpiMadtPtr = (UINT8 *)AcpiMadt; - CopyMem (AcpiMadtPtr, AcpiMadtHeader, HeaderSize); - FreePool (AcpiMadtHeader); - AcpiMadtPtr += HeaderSize; - - CopyMem (AcpiMadtPtr, ProcessorLocalApic, ProcessorLocalApicSize); - FreePool (ProcessorLocalApic); - AcpiMadtPtr += ProcessorLocalApicSize; - - CopyMem (AcpiMadtPtr, IoApic, IoApicSize); - FreePool (IoApic); - AcpiMadtPtr += IoApicSize; - - CopyMem (AcpiMadtPtr, InterruptSourceOverride, InterruptSourceOverrideSize); - FreePool (InterruptSourceOverride); - AcpiMadtPtr += InterruptSourceOverrideSize; - - CopyMem (AcpiMadtPtr, LocalNmi, LocalNmiSize); - FreePool (LocalNmi); - AcpiMadtPtr += LocalNmiSize; - - AcpiMadt->Header.Length = TableSize; - /// Install MADT Table - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - AcpiMadt, - TableSize, - &NewTableKey - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to install MADT Table. Status(%r)\n", Status)); - ASSERT_EFI_ERROR (Status); - } - - FreePool (AcpiMadt); - return Status; -} - -/** - Implementation of AcpiMadtLibDestructor for AMD platforms. - This is library destructor for AcpiMadtLib. - - @param[in] ImageHandle Image handle of the loaded driver. - @param[in] SystemTable Pointer to the EFI System Table. - - @retval EFI_SUCCESS The destructor always returns EFI_SUCCESS. -**/ -EFI_STATUS -EFIAPI -AcpiMadtLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EFI_SUCCESS; -} diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMadtLib/AcpiMadtLib.inf b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMadtLib/AcpiMadtLib.inf deleted file mode 100644 index a0a1ab114b4..00000000000 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMadtLib/AcpiMadtLib.inf +++ /dev/null @@ -1,55 +0,0 @@ -## @file -# Creates ACPI MADT/APIC tables for AMD platforms. -# -# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 1.30 - BASE_NAME = AcpiMadtLib - FILE_GUID = 2B53BFA1-DC75-4132-BD86-26DA42400AFF - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiMadtLibConstructor - DESTRUCTOR = AcpiMadtLibDestructor - -[Sources] - AcpiMadtLib.c - -[Packages] - AmdPlatformPkg/AmdPlatformPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - PcAtChipsetPkg/PcAtChipsetPkg.dec - UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - LocalApicLib - MemoryAllocationLib - PlatformSocLib - SortLib - UefiBootServicesTableLib - UefiLib - -[Protocols] - gEfiAcpiTableProtocolGuid - gEfiMpServiceProtocolGuid - -[Guids] - gEfiAcpiTableGuid - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## CONSUMES - gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress ## CONSUMES diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMcfgLib/AcpiMcfgLib.c b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMcfgLib/AcpiMcfgLib.c deleted file mode 100644 index 28193c904a6..00000000000 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMcfgLib/AcpiMcfgLib.c +++ /dev/null @@ -1,153 +0,0 @@ -/** @file - - Generate ACPI MCFG table for AMD platforms. - - Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. - - SPDX-License-Identifier BSD-2-Clause-Patent -**/ - -#include -#include -#include -#include -#include -#include -#include -#include - -/** - Implementation of AcpiMcfgLibConstructor for AMD platforms. - This is library constructor for AcpiMcfgLib. - - @param[in] ImageHandle Image handle of the loaded driver. - @param[in] SystemTable Pointer to the EFI System Table. - - @retval EFI_SUCCESS Successfully generated and installed MCFG Table. - @retval Others Failed to generate and install MCFG Table. -**/ -EFI_STATUS -EFIAPI -AcpiMcfgLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *AcpiMcfgTable; - EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *McfgStructure; - EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol; - EFI_STATUS Status; - PCI_SEGMENT_INFO *PciSegmentInfo; - UINTN Index; - UINTN NewTableKey; - UINTN PciSegmentCount; - UINTN TableSize; - - /// MCFG Table Generation code goes here - DEBUG ((DEBUG_INFO, "Generating ACPI MCFG Table.\n")); - - /// Get the PCI Segment Info - PciSegmentInfo = GetPciSegmentInfo (&PciSegmentCount); - if (PciSegmentInfo == NULL) { - DEBUG ((DEBUG_ERROR, "Failed to get PCI Segment Info.\n")); - ASSERT (PciSegmentInfo != NULL); - return EFI_NOT_FOUND; - } - - /// allocate zero based memory for McfgStructure - McfgStructure = AllocateZeroPool ( - PciSegmentCount * \ - sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) - ); - if (McfgStructure == NULL) { - DEBUG ((DEBUG_ERROR, "Failed to allocate memory for McfgStructure.\n")); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - return EFI_OUT_OF_RESOURCES; - } - - /// Fill the McfgStructure - for (Index = 0; Index < PciSegmentCount; Index++) { - McfgStructure[Index].BaseAddress = PciSegmentInfo[Index].BaseAddress; - McfgStructure[Index].PciSegmentGroupNumber = PciSegmentInfo[Index].SegmentNumber; - McfgStructure[Index].StartBusNumber = PciSegmentInfo[Index].StartBusNumber; - McfgStructure[Index].EndBusNumber = PciSegmentInfo[Index].EndBusNumber; - } - - /// Calculate the size of the MCFG Table - TableSize = sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) + \ - (PciSegmentCount * sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE)); - - /// Allocate memory for MCFG Table - AcpiMcfgTable = AllocateZeroPool (TableSize); - if (AcpiMcfgTable == NULL) { - DEBUG ((DEBUG_ERROR, "Failed to allocate memory for MCFG Table.\n")); - ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); - FreePool (McfgStructure); - return EFI_OUT_OF_RESOURCES; - } - - /// Locate ACPI Table Protocol - Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiProtocol); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to locate ACPI Table Protocol. Status(%r)\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; - } - - /// Update MCFG Table Header - AcpiMcfgTable->Header.Signature = EFI_ACPI_6_5_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE; - AcpiMcfgTable->Header.Length = (UINT32)TableSize; - AcpiMcfgTable->Header.Revision = EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION; - AcpiMcfgTable->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); - AcpiMcfgTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); - AcpiMcfgTable->Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); - AcpiMcfgTable->Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); - CopyMem ( - &AcpiMcfgTable->Header.OemId, - PcdGetPtr (PcdAcpiDefaultOemId), - sizeof (AcpiMcfgTable->Header.OemId) - ); - - /// Append the McfgStructure to MCFG Table - CopyMem ( - (VOID *)((UINTN)AcpiMcfgTable + sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER)), - McfgStructure, - PciSegmentCount * sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) - ); - - FreePool (McfgStructure); - - /// Install MCFG Table - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - AcpiMcfgTable, - AcpiMcfgTable->Header.Length, - &NewTableKey - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to install MCFG Table. Status(%r)\n", Status)); - ASSERT_EFI_ERROR (Status); - } - - FreePool (AcpiMcfgTable); - return Status; -} - -/** - Implementation of AcpiMcfgLibDestructor for AMD platforms. - This is library destructor for AcpiMcfgLib. - - @param[in] ImageHandle Image handle of the loaded driver. - @param[in] SystemTable Pointer to the EFI System Table. - - @retval EFI_SUCCESS The destructor always returns EFI_SUCCESS. -**/ -EFI_STATUS -EFIAPI -AcpiMcfgLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EFI_SUCCESS; -} diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMcfgLib/AcpiMcfgLib.inf b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMcfgLib/AcpiMcfgLib.inf deleted file mode 100644 index 531287af984..00000000000 --- a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/Acpi/AcpiMcfgLib/AcpiMcfgLib.inf +++ /dev/null @@ -1,39 +0,0 @@ -## @file -# Creates ACPI MCFG tables for AMD platforms. -# -# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 1.30 - BASE_NAME = AcpiMcfgLib - FILE_GUID = BE1B972D-DB21-463E-A56B-A43014219ECA - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiMcfgLibConstructor - DESTRUCTOR = AcpiMcfgLibDestructor - -[Sources] - AcpiMcfgLib.c - -[Packages] - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib - DebugLib - UefiBootServicesTableLib - UefiLib - MemoryAllocationLib - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## CONSUMES diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/SampleCmPlatOverrideLib/SampleCmPlatOverrideLib.c b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/SampleCmPlatOverrideLib/SampleCmPlatOverrideLib.c new file mode 100644 index 00000000000..0c1b8914392 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/SampleCmPlatOverrideLib/SampleCmPlatOverrideLib.c @@ -0,0 +1,204 @@ +/** @file + + Sample Code for CmPlatOverrideLib library. This library demonstrate the + functionality to override the default configuration of the Configuration Manager + Protocol. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +static EFI_EVENT mConfigurationManagerProtocolInstalledEvent = NULL; +static VOID *mConfigurationManagerProtocolRegistration = NULL; + +/** + This function is used to override the default configuration of the Configuration Manager. + + @param[in] ConfigurationManager A pointer to the Configuration Manager Protocol. + + @retval EFI_SUCCESS The default configuration is successfully overridden. + @retval EFI_INVALID_PARAMETER ConfigurationManager is NULL. + @retval Others The default configuration is not overridden. +**/ +EFI_STATUS +EFIAPI +PlatformOverrideConfigurationManager ( + IN EDKII_CONFIGURATION_MANAGER_PROTOCOL *ConfigurationManager + ) +{ + CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO PmProfile; + CM_OBJ_DESCRIPTOR PmProfileObjDesc; + EFI_STATUS Status; + + if (ConfigurationManager == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (ConfigurationManager->PlatRepoInfo == NULL) { + return EFI_INVALID_PARAMETER; + } + + /// + /// Example 1: Override the default PmProfile configuration using SetConfigurationData API. + /// + DEBUG ((DEBUG_INFO, "Override the default PmProfile configuration\n")); + PmProfile.PowerManagementProfile = 0x02; + PmProfileObjDesc.ObjectId = CREATE_CM_OBJECT_ID (EObjNameSpaceArchCommon, EArchCommonObjPowerManagementProfileInfo); + PmProfileObjDesc.Size = sizeof (CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO); + PmProfileObjDesc.Data = (VOID *)&PmProfile; + PmProfileObjDesc.Count = 1; + Status = ConfigurationManager->SetObject ( + ConfigurationManager, + PmProfileObjDesc.ObjectId, + CM_NULL_TOKEN, + &PmProfileObjDesc + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to set PowerManagementProfile configuration with Status: %r\n", Status)); + return Status; + } + + return EFI_SUCCESS; +} + +/** + This function is called when the Configuration Manager Protocol is installed. + It is used to override the default configuration of the Configuration Manager. + + @param[in] Event The Event that is being processed. + @param[in] Context Event Context. +**/ +VOID +EFIAPI +SampleCmPlatOverrideLibOnConfigurationManagerProtocolInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EDKII_CONFIGURATION_MANAGER_PROTOCOL *ConfigurationManager; + EFI_STATUS Status; + + gBS->CloseEvent (Event); + mConfigurationManagerProtocolInstalledEvent = NULL; + + /// + /// Locate gEdkiiConfigurationManagerProtocolGuid + /// + Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, + NULL, + (VOID **)&ConfigurationManager + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to locate Configuration Manager Protocol\n")); + return; + } + + Status = PlatformOverrideConfigurationManager (ConfigurationManager); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "PlatformOverrideConfigurationManager failed with Status: %r\n", Status)); + } + + return; +} + +/** + The constructor function initializes the library. + + The constructor function locates the Configuration Manager Protocol and + overrides the default configuration of the Configuration Manager. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor executed successfully. + @retval Others The constructor did not complete successfully. +**/ +EFI_STATUS +EFIAPI +SampleCmPlatOverrideLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EDKII_CONFIGURATION_MANAGER_PROTOCOL *ConfigurationManager; + EFI_STATUS Status; + + Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, + NULL, + (VOID **)&ConfigurationManager + ); + if (EFI_ERROR (Status)) { + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + SampleCmPlatOverrideLibOnConfigurationManagerProtocolInstalled, + NULL, + &mConfigurationManagerProtocolInstalledEvent + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to create event for Configuration Manager Protocol installation\n")); + return Status; + } + + Status = gBS->RegisterProtocolNotify ( + &gEdkiiConfigurationManagerProtocolGuid, + mConfigurationManagerProtocolInstalledEvent, + &mConfigurationManagerProtocolRegistration + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to register for Configuration Manager Protocol installation\n")); + return Status; + } + + return EFI_SUCCESS; + } + + Status = PlatformOverrideConfigurationManager (ConfigurationManager); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "PlatformOverrideConfigurationManager failed with Status: %r\n", Status)); + } + + return Status; +} + +/** + The destructor function frees resources allocated during initialization. + + The destructor function frees any resources allocated during the initialization + of the library. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The destructor executed successfully. + @retval Others The destructor did not complete successfully. +**/ +EFI_STATUS +EFIAPI +SampleCmPlatOverrideLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + if (mConfigurationManagerProtocolInstalledEvent != NULL) { + Status = gBS->CloseEvent (mConfigurationManagerProtocolInstalledEvent); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to close event for Configuration Manager Protocol installation\n")); + return Status; + } + } + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/SampleCmPlatOverrideLib/SamplecmPlatOverrideLib.inf b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/SampleCmPlatOverrideLib/SamplecmPlatOverrideLib.inf new file mode 100644 index 00000000000..1b6da6456e9 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/DynamicTables/Library/SampleCmPlatOverrideLib/SamplecmPlatOverrideLib.inf @@ -0,0 +1,39 @@ +## @file +# This is Sample library to demonstrate how to override the CM table in the platform. +# Using similar mechanism, platform engineer, IBV or OEM can override the CM table. +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = SampleCmPlatOverrideLib + FILE_GUID = 51FAD7D4-8C5B-4FE6-B531-AA0923A159ED + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = SampleCmPlatOverrideLibConstructor + DESTRUCTOR = SampleCmPlatOverrideLibDestructor + +[Sources] + SampleCmPlatOverrideLib.c + +[Packages] + AmdPlatformPkg/AmdPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UefiBootServicesTableLib + +[Protocols] + gEdkiiConfigurationManagerProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[Depex] + TRUE diff --git a/Platform/AMD/AmdPlatformPkg/Include/AmdConfigurationManager.h b/Platform/AMD/AmdPlatformPkg/Include/AmdConfigurationManager.h new file mode 100755 index 00000000000..85f348218fb --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Include/AmdConfigurationManager.h @@ -0,0 +1,72 @@ +/** @file + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#ifndef AMD_CONFIGURATION_MANAGER_H_ +#define AMD_CONFIGURATION_MANAGER_H_ + +#include +#include +#include +#include + +/** The number of ACPI tables to install +*/ +#define PLAT_ACPI_TABLE_COUNT 7 + +/** The configuration manager version. +*/ +#define CONFIGURATION_MANAGER_REVISION CREATE_REVISION (1, 0) + +/** The OEM ID +*/ +#define CFG_MGR_OEM_ID { 'A', 'M', 'D', 'I', 'N', 'C' } + +#pragma pack(1) + +/** A structure describing the platform configuration + manager repository information +*/ +typedef struct PlatformRepositoryInfo { + /// Configuration Manager Information + CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CmInfo; + + /// List of ACPI tables + CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT]; + CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO PowerManagementProfile; + CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID HypervisorVendorId; + CM_ARCH_COMMON_FIXED_FEATURE_FLAGS FixedFeatureFlags; + CM_X64_FADT_SCI_INTERRUPT SciInterrupt; + CM_X64_FADT_SCI_CMD_INFO SciCmdinfo; + CM_X64_FADT_PM_BLOCK_INFO PmBlockInfo; + CM_X64_FADT_GPE_BLOCK_INFO GpeBlockInfo; + CM_X64_FADT_X_PM_BLOCK_INFO XpmBlockInfo; + CM_X64_FADT_X_GPE_BLOCK_INFO XgpeBlockInfo; + CM_X64_FADT_SLEEP_BLOCK_INFO SleepBlockInfo; + CM_X64_FADT_RESET_BLOCK_INFO ResetBlockInfo; + CM_X64_FADT_MISC_INFO FadtMiscInfo; + CM_X64_HPET_INFO HpetInfo; + CM_X64_WSMT_FLAGS_INFO WsmtFlagsInfo; + CM_ARCH_COMMON_SPMI_INTERFACE_INFO SpmiInterfaceInfo; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo; + UINTN PciConfigSpaceInfoCount; + CM_X64_MADT_INFO MadtInfo; + CM_X64_LOCAL_APIC_X2APIC_INFO *LocalApicX2ApicInfo; + UINTN LocalApicX2ApicInfoCount; + CM_X64_IO_APIC_INFO *IoApicInfo; + UINTN IoApicInfoCount; + CM_X64_INTR_SOURCE_OVERRIDE_INFO *IntrSourceOverrideInfo; + UINTN IntrSourceOverrideInfoCount; + CM_X64_LOCAL_APIC_X2APIC_NMI_INFO *LocalApicX2ApicNmiInfo; + UINTN LocalApicX2ApicNmiInfoCount; +} EDKII_PLATFORM_REPOSITORY_INFO; +#pragma pack() + +#endif // AMD_CONFIGURATION_MANAGER_H_ diff --git a/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiConfigRouting.c b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiConfigRouting.c index 0a28d887e95..89d1ddbdf34 100644 --- a/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiConfigRouting.c +++ b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiConfigRouting.c @@ -11,6 +11,7 @@ **/ #include "AmdHiiConfigRouting.h" +#include HII_ELEMENT gElementInfo[] = { { L"GUID=", FIXED_STR_LEN (L"GUID=") }, @@ -21,6 +22,9 @@ HII_ELEMENT gElementInfo[] = { { L"VALUE=", FIXED_STR_LEN (L"VALUE=") } }; +CHAR16 mAmpersand[] = L"&"; +CHAR16 mAmpersandValueEqual[] = L"&VALUE="; + /** Converts the unicode character of the string from uppercase to lowercase. This is a internal function. @@ -250,6 +254,10 @@ GetValueOfNumber ( while (*EndOfString != L'\0' && *EndOfString != L'&') { EndOfString++; + if (StringLength == (MAX_UINTN - 1)) { + return EFI_OUT_OF_RESOURCES; + } + StringLength++; } @@ -283,7 +291,11 @@ GetValueOfNumber ( if ((Index & 1) == 0) { This->NumberPtr[Index / 2] = DigitUint8; } else { - This->NumberPtr[Index / 2] = (UINT8)((DigitUint8 << 4) + This->NumberPtr[Index / 2]); + if (((DigitUint8 << 4) + This->NumberPtr[Index / 2]) > MAX_UINT8) { + return EFI_OUT_OF_RESOURCES; + } + + This->NumberPtr[Index / 2] = (UINT8)(UINTN)(((DigitUint8 << 4) + This->NumberPtr[Index / 2]) & 0xFF); } } @@ -379,6 +391,18 @@ HiiStringSetMinBufferSize ( UINTN ThisStringSize; EFI_STRING NewAlloc; + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (This->StringLength == (MAX_UINTN - 1)) { + return EFI_OUT_OF_RESOURCES; + } + + if (This->StringLength >= (MAX_UINTN - 1) / sizeof (CHAR16)) { + return EFI_OUT_OF_RESOURCES; + } + ThisStringSize = (This->StringLength + 1) * sizeof (CHAR16); if (Size > This->PrivateBufferSize) { @@ -424,7 +448,7 @@ HiiStringAppend ( ThisStringSize = (This->StringLength + 1) * sizeof (CHAR16); StringSize = HII_STR_SIZE (String); - if (ThisStringSize + StringSize > This->PrivateBufferSize) { + if ((ThisStringSize > (MAX_UINTN - StringSize)) || ((ThisStringSize + StringSize) > This->PrivateBufferSize)) { MaxLen = (ThisStringSize + StringSize) * 2; Status = HiiStringSetMinBufferSize (This, MaxLen); if (EFI_ERROR (Status)) { @@ -453,9 +477,9 @@ HiiStringAppend ( **/ EFI_STATUS HiiStringAppendValue ( - IN OUT HII_STRING *This, - IN UINT8 *Number, - IN UINTN Length + IN OUT HII_STRING *This, + IN CONST UINT8 *Number, + IN UINTN Length ) { EFI_STATUS Status; @@ -471,8 +495,20 @@ HiiStringAppendValue ( return EFI_INVALID_PARAMETER; } + if ((This == NULL) || (Number == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (This->StringLength >= (MAX_UINTN - 1) / sizeof (CHAR16)) { + return EFI_OUT_OF_RESOURCES; + } + ThisStringSize = (This->StringLength + 1) * sizeof (CHAR16); + if (ThisStringSize > (MAX_UINTN - Length * 2 * sizeof (CHAR16))) { + return EFI_OUT_OF_RESOURCES; + } + if (ThisStringSize + Length * 2 * sizeof (CHAR16) > This->PrivateBufferSize) { MaxLen = (ThisStringSize + Length * 2 * sizeof (CHAR16)) * 2; // Double requested string length. Status = HiiStringSetMinBufferSize (This, MaxLen); @@ -655,15 +691,15 @@ HiiBlockToConfig ( OUT EFI_STRING *Progress ) { - EFI_STATUS Status; - EFI_STRING StringPtr; - EFI_STRING OrigPtr; - CHAR16 CharBackup; - UINTN Offset; - UINTN Width; - UINT8 *Value; - HII_STRING HiiString; - HII_NUMBER HiiNumber; + EFI_STATUS Status; + EFI_STRING StringPtr; + EFI_STRING OrigPtr; + CHAR16 CharBackup; + UINTN Offset; + UINTN Width; + CONST UINT8 *Value; + HII_STRING HiiString; + HII_NUMBER HiiNumber; if ((This == NULL) || (Progress == NULL) || (Config == NULL)) { return EFI_INVALID_PARAMETER; @@ -792,7 +828,7 @@ HiiBlockToConfig ( goto Exit; } - Value = (UINT8 *)Block + Offset; + Value = Block + Offset; CharBackup = *StringPtr; *StringPtr = L'\0'; @@ -805,7 +841,7 @@ HiiBlockToConfig ( *StringPtr = CharBackup; // End of section of string OrigPtr - Status = HiiStringAppend (&HiiString, L"&VALUE="); + Status = HiiStringAppend (&HiiString, mAmpersandValueEqual); if (EFI_ERROR (Status)) { *Progress = ConfigRequest; // Out of memory goto Exit; @@ -829,7 +865,7 @@ HiiBlockToConfig ( break; } - Status = HiiStringAppend (&HiiString, L"&"); + Status = HiiStringAppend (&HiiString, mAmpersand); if (EFI_ERROR (Status)) { *Progress = ConfigRequest; // Out of memory goto Exit;