From: "Abdul Lateef Attar via groups.io" <AbdulLateef.Attar=amd.com@groups.io>
To: <devel@edk2.groups.io>
Cc: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>,
Abner Chang <abner.chang@amd.com>,
Paul Grimes <paul.grimes@amd.com>
Subject: [edk2-devel] [PATCH 4/5] AmdMinBoardPkg: Implement BoardInitLib for DXE phase
Date: Fri, 17 May 2024 09:19:12 +0530 [thread overview]
Message-ID: <fc284dcd746a7a7d061d866a24582fefe4deb7ea.1715917637.git.AbdulLateef.Attar@amd.com> (raw)
In-Reply-To: <cover.1715917637.git.AbdulLateef.Attar@amd.com>
DxeBoardInitLib library provides board-specific
initialization functions for the DXE phase.
Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
---
.../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc | 6 +-
.../Library/DxeBoardInitLib/DxeBoardInitLib.c | 253 +++++++++++++++
.../DxeBoardInitLib/DxeBoardInitLib.inf | 51 +++
.../DxeBoardInitLib/DxeBoardInitLibInternal.c | 306 ++++++++++++++++++
.../DxeBoardInitLib/DxeBoardInitLibInternal.h | 159 +++++++++
.../DxeBoardInitLib/MadtAcpiTablePatch.c | 243 ++++++++++++++
6 files changed, 1017 insertions(+), 1 deletion(-)
create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c
create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h
create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c
diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
index 335e875f70..e0afe1e755 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
@@ -40,6 +40,9 @@
SetCacheMtrrLib|AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf
BoardInitLib|AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
+[LibraryClasses.common.DXE_DRIVER]
+ BoardInitLib|AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
+
[Components]
AmdMinBoardPkg/Library/SpcrDeviceLib/SpcrDeviceLib.inf
@@ -49,4 +52,5 @@
AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
[Components.X64]
- AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
+ AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
+ AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
\ No newline at end of file
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
new file mode 100644
index 0000000000..7c41d3e38b
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
@@ -0,0 +1,253 @@
+/** @file
+ BoardInitLib library implementation for DXE phase.
+
+ Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include "DxeBoardInitLibInternal.h"
+
+EFI_HANDLE mImageHandle;
+EFI_SYSTEM_TABLE *mSystemTable;
+
+/**
+ This board service detects the board type.
+
+ @retval EFI_SUCCESS The board was detected successfully.
+ @retval EFI_NOT_FOUND The board could not be detected.
+**/
+EFI_STATUS
+EFIAPI
+BoardDetect (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This board service initializes board-specific debug devices.
+
+ @retval EFI_SUCCESS Board-specific debug initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This board service detects the boot mode.
+
+ @retval EFI_BOOT_MODE The boot mode.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+ VOID
+ )
+{
+ return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+ A hook for board-specific initialization prior to memory initialization.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ A hook for board-specific initialization after memory initialization.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ A hook for board-specific initialization prior to disabling temporary RAM.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ A hook for board-specific initialization after disabling temporary RAM.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ A hook for board-specific initialization prior to silicon initialization.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ A hook for board-specific initialization after silicon initialization.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ A hook for board-specific initialization after PCI enumeration.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterPciEnumeration (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "%a - ENTRY\n", __FUNCTION__));
+
+ Status = ReserveLegacyVgaIoSpace ();
+ DEBUG ((DEBUG_INFO, "ReserveLegacyVgaIoSpace...%r.\n", Status));
+
+ Status = ReservePcieExtendedConfigSpace (mImageHandle, mSystemTable);
+ DEBUG ((DEBUG_INFO, "ReservePcieExtendedConfigSpace...%r.\n", Status));
+
+ return Status;
+}
+
+/**
+ A hook for board-specific functionality for the ReadyToBoot event.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitReadyToBoot (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = UpdateReinstallAcpiTable (
+ EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ (PATCH_ACPITABLE)FadtAcpiTablePatch
+ );
+ DEBUG ((DEBUG_INFO, "Patching FADT ACPI Table ... Status = %r.\n", Status));
+
+ Status = UpdateReinstallAcpiTable (
+ EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+ (PATCH_ACPITABLE)MadtAcpiTablePatch
+ );
+ DEBUG ((DEBUG_INFO, "Patching MADT ACPI Table ... Status = %r.\n", Status));
+
+ UpdateReinstallAcpiTable (
+ EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ (PATCH_ACPITABLE)AcpiTableAmlUpdate
+ );
+
+ UpdateReinstallAcpiTable (
+ EFI_ACPI_6_5_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ (PATCH_ACPITABLE)AcpiTableAmlUpdate
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A hook for board-specific functionality for the ExitBootServices event.
+
+ @retval EFI_SUCCESS The board initialization was successful.
+ @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitEndOfFirmware (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ The constructor function caches the PCI Express Base Address and creates a
+ Set Virtual Address Map event to convert physical address to virtual addresses.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor completed successfully.
+ @retval Other value The constructor did not complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeBoardInitLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mImageHandle = ImageHandle;
+ mSystemTable = SystemTable;
+ return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
new file mode 100644
index 0000000000..919777d016
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
@@ -0,0 +1,51 @@
+## @file
+# Implements BoardInitLib Library Class in DXE phase.
+#
+# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = DxeBoardInitLib
+ FILE_GUID = B3C8F348-B528-4CA0-928E-3193ADEA65E6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardInitLib
+ CONSTRUCTOR = DxeBoardInitLibConstructor
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ LocalApicLib
+ PcdLib
+ PcieConfigLib
+ PlatformSocLib
+ SortLib
+
+[Packages]
+ AmdPlatformPkg/AmdPlatformPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ PcAtChipsetPkg/PcAtChipsetPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[Sources]
+ DxeBoardInitLib.c
+ DxeBoardInitLibInternal.c
+ DxeBoardInitLibInternal.h
+ MadtAcpiTablePatch.c
+
+[Protocols]
+ gEfiAcpiSdtProtocolGuid
+ gEfiAcpiTableProtocolGuid
+ gEfiMpServiceProtocolGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+
+[DEPEX]
+ gEfiMpServiceProtocolGuid
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c
new file mode 100644
index 0000000000..2ffc249792
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c
@@ -0,0 +1,306 @@
+/** @file
+ BoardInitLib library internal implementation for DXE phase.
+
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "DxeBoardInitLibInternal.h"
+
+/**
+ A helper function to uninstall or update the ACPI table.
+ It searches for ACPI table for provided table signature,
+ if found then creates a copy of the table and calls the callbackfunction.
+
+ @param[in] Signature ACPI table signature
+ @param[in] CallbackFunction The function to call to patch the searching ACPI table.
+ If NULL then uninstalls the table.
+
+ @return EFI_SUCCESS Successfully Re-install the ACPI Table
+ @return EFI_NOT_FOUND Table not found
+ @return EFI_STATUS returns non-EFI_SUCCESS value in case of failure
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateReinstallAcpiTable (
+ IN UINT32 Signature,
+ IN PATCH_ACPITABLE CallbackFunction
+ )
+{
+ EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_ACPI_SDT_HEADER *Table;
+ EFI_ACPI_TABLE_VERSION Version;
+ UINTN OriginalTableKey;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ EFI_ACPI_SDT_HEADER *NewTable;
+ UINTN NewTableKey;
+ BOOLEAN Found;
+
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error(%r): Unable to locate ACPI Table protocol.\n", Status));
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiSdtProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error(%r): Unable to locate ACPI SDT protocol.\n", Status));
+ return Status;
+ }
+
+ Found = FALSE;
+ Index = 0;
+ do {
+ Status = AcpiSdtProtocol->GetAcpiTable (Index, &Table, &Version, &OriginalTableKey);
+ if (EFI_ERROR (Status)) {
+ goto END_OF_SEARCH;
+ }
+
+ // Look for given table
+ if (Table->Signature == Signature) {
+ if (CallbackFunction == NULL) {
+ Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, OriginalTableKey);
+ return Status;
+ }
+
+ NewTable = AllocateCopyPool (Table->Length, Table);
+ if (NULL == NewTable) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "Error(%r): Not enough resource to allocate table.\n", Status));
+ return Status;
+ }
+
+ Status = CallbackFunction (NewTable);
+ if (!EFI_ERROR (Status)) {
+ // Uninstall the old table
+ Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, OriginalTableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error(%r): Uninstall old table error.\n", Status));
+ FreePool (NewTable);
+ return Status;
+ }
+
+ // Install the new table
+ Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, NewTable, NewTable->Length, &NewTableKey);
+ FreePool (NewTable);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error(%r): Failed to install new table.\n", Status));
+ return Status;
+ }
+
+ // If non SSDT table, then return status
+ if (Table->Signature != EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+ return Status;
+ }
+
+ // Atleast one SSDT table update is success
+ Found = TRUE;
+ }
+
+ // continue to search next SSDT table.
+ Status = EFI_SUCCESS;
+ }
+
+ Index++;
+ } while (!EFI_ERROR (Status));
+
+END_OF_SEARCH:
+ if (!Found) {
+ DEBUG ((DEBUG_ERROR, "Error(%r): Unable to locate ACPI Table.\n", Status));
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A Callback function to patch the ACPI FADT table.
+ Updates FADT table with AMD specific values, which
+ are different than MinPlatformPkg.
+
+ @param[in, out] NewTable Pointer to ACPI FADT table
+
+ @return EFI_SUCCESS Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+FadtAcpiTablePatch (
+ IN OUT EFI_ACPI_SDT_HEADER *NewTable
+ )
+{
+ EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *NewFadt;
+
+ NewFadt = (EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *)NewTable;
+ // Patch the Table
+ NewFadt->PLvl2Lat = 0x64;
+ NewFadt->Pm2CntLen = 0;
+ NewFadt->XGpe0Blk.RegisterBitWidth = 0x40;
+ NewFadt->FlushSize = 0x400;
+ NewFadt->FlushStride = 0x10;
+ NewFadt->XGpe1Blk.AccessSize = 0x01;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A Callback function to patch the ACPI DSDT/SSDT table.
+ Which has ASL code that needs to be updated.
+
+ @param[in, out] NewTable Pointer to ACPI FADT table
+
+ @return EFI_SUCCESS If table is modified.
+ EFI_NOT_FOUND If table is not modified.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiTableAmlUpdate (
+ IN OUT EFI_ACPI_SDT_HEADER *NewTable
+ )
+{
+ UINT64 OemTableId;
+
+ if ((AsciiStrnCmp (NewTable->OemTableId, "AmdTable", 8) == 0)) {
+ DEBUG ((DEBUG_INFO, "Found (D/S)SDT table for patching OemTableId.\n"));
+ OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ CopyMem (NewTable->OemTableId, &OemTableId, 8);
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Reserve Legacy VGA IO space.
+
+ @retval EFI_SUCCESS MMIO at Legacy VGA region has been allocated.
+ @retval !EFI_SUCCESS Error allocating the legacy VGA region.
+
+**/
+EFI_STATUS
+EFIAPI
+ReserveLegacyVgaIoSpace (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS VgaMemAddress;
+
+ VgaMemAddress = (EFI_PHYSICAL_ADDRESS)VGA_MEM_BASE;
+ Status = gBS->AllocatePages (
+ AllocateAddress,
+ EfiMemoryMappedIO,
+ EFI_SIZE_TO_PAGES (VGA_MEM_SIZE),
+ &VgaMemAddress
+ );
+ return Status;
+}
+
+/**
+ Helper function to get size of MMIO region required for the Bus Range
+ configured.
+
+ @param[in] BusRange Chipset representation of Bus Range
+
+ @retval Size of MMIO required for bus range
+**/
+UINT64
+DecodeMmioBusRange (
+ UINT64 BusRange
+ )
+{
+ // Minimum MMIO region required is 1MB (1 Segment - 1 Bus).
+ // Set Mmio Size to 1MB.
+ UINT64 MmioSize;
+
+ MmioSize = 0x100000;
+
+ if (BusRange > 0x0E) {
+ MmioSize = SIZE_32GB;
+ } else {
+ MmioSize = (MmioSize << BusRange);
+ }
+
+ return MmioSize;
+}
+
+/**
+ Reserve PCIe Extended Config Space MMIO in the GCD and mark it runtime
+
+ @param[in] ImageHandle ImageHandle of the loaded driver.
+ @param[in] SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS One or more of the drivers returned a success code.
+ @retval !EFI_SUCCESS Error initializing the Legacy PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+ReservePcieExtendedConfigSpace (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ AMD_MMIO_CFG_MSR MmioCfgMsr;
+ UINT64 MmioCfgBase;
+ UINT64 MmioCfgSize;
+
+ Status = EFI_SUCCESS;
+ //
+ // Reserve MMIO for PCI-Config space
+ //
+ MmioCfgMsr.AsUint64 = AsmReadMsr64 (AMD_MMIO_CFG_MSR_ADDR);
+ MmioCfgBase = MmioCfgMsr.AsUint64 & AMD_MMIO_CFG_ADDR_MASK;
+ MmioCfgSize = DecodeMmioBusRange (MmioCfgMsr.AsBits.BusRange);
+ DEBUG ((DEBUG_INFO, "\nMMIO_CFG MSR = 0x%08lX\n", MmioCfgMsr.AsUint64));
+ DEBUG ((DEBUG_INFO, " Enable = %d\n", MmioCfgMsr.AsBits.Enable));
+ DEBUG ((DEBUG_INFO, " BusRange = %d\n", MmioCfgMsr.AsBits.BusRange));
+ DEBUG ((DEBUG_INFO, " MmioCfgBase = 0x%08lX\n", MmioCfgBase));
+ DEBUG ((DEBUG_INFO, " MmioCfgSize = 0x%08lX\n", MmioCfgSize));
+
+ if (MmioCfgMsr.AsBits.Enable) {
+ // Free Memory if it is allocated (call will likely return Not Found)
+ Status = gDS->FreeMemorySpace (
+ MmioCfgBase,
+ MmioCfgSize
+ );
+ // Remove Memory Space from GCD map (could return Not Found)
+ Status = gDS->RemoveMemorySpace (
+ MmioCfgBase,
+ MmioCfgSize
+ );
+ // Make sure Adding memory space succeeds or assert
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeReserved,
+ MmioCfgBase,
+ MmioCfgSize,
+ EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
+ );
+ ASSERT_EFI_ERROR (Status);
+ // Make sure Allocating memory space succeed or assert
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeReserved,
+ 0,
+ MmioCfgSize,
+ &MmioCfgBase,
+ ImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "\nReserved PciCfg MMIO: Base = 0x%lX, Size = 0x%lX\n",
+ MmioCfgBase,
+ MmioCfgSize
+ ));
+ }
+
+ return Status;
+}
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h
new file mode 100644
index 0000000000..037328a34c
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h
@@ -0,0 +1,159 @@
+/** @file
+
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DXE_BOARD_INIT_LIB_INTERNAL_H_
+#define DXE_BOARD_INIT_LIB_INTERNAL_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Register/Intel/Cpuid.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Acpi65.h>
+#include <Library/SortLib.h>
+#include <Library/IoLib.h>
+#include <Register/IoApic.h>
+#include <Protocol/MpService.h>
+#include <Library/BaseLib.h>
+
+// Define temp buffer length for save IoApic data
+#define MAX_IOAPIC_NUM 0x20
+
+#define VGA_MEM_BASE 0xA0000
+#define VGA_MEM_SIZE 0x20000
+
+//
+// 48-bit MMIO space (MB-aligned)
+//
+#define AMD_MMIO_CFG_MSR_ADDR 0xC0010058UL
+#define AMD_MMIO_CFG_ADDR_MASK 0xFFFFFFF00000ULL
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+} STRUCTURE_HEADER;
+
+#pragma pack(1)
+typedef union {
+ struct {
+ // HACK-HACK: Use UINT32 to keep compiler from using SHIFT intrinsics on NOOPT build
+ UINT32 Enable : 1; // [0]
+ UINT32 Reserved1 : 1; // [1]
+ UINT32 BusRange : 4; // [5:2]
+ UINT32 Reserved2 : 14; // [19:6]
+ UINT32 MmioCfgBaseAddr : 28; // [47:20]
+ UINT32 Reserved3 : 16; // [63:48]
+ } AsBits;
+
+ UINT64 AsUint64;
+} AMD_MMIO_CFG_MSR;
+#pragma pack()
+
+/**
+ Reserve PCIe Extended Config Space MMIO in the GCD and mark it runtime
+
+ @param[in] ImageHandle ImageHandle of the loaded driver.
+ @param[in] SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS One or more of the drivers returned a success code.
+ @retval !EFI_SUCCESS Error initializing the Legacy PIC.
+**/
+EFI_STATUS
+EFIAPI
+ReservePcieExtendedConfigSpace (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Prototype for callback function to patch ACPI table.
+
+ @param[in, out] NewTable The pointer to ACPI table.
+ @return EFI_SUCCESS Always return EFI_SUCCESS
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PATCH_ACPITABLE)(
+ IN OUT EFI_ACPI_SDT_HEADER *NewTable
+ );
+
+/**
+ A helper function to update and re-install ACPI table.
+ It search for ACPI table for provided table signature,
+ if found then creates a copy of the table and invokes
+ the call back function.
+
+ @param[in] Signature ACPI table signature
+ @param[in] CallbackFunction The function to call to patch the searching ACPI table.
+
+ @return EFI_SUCCESS Successfully Re-install the ACPI Table
+ @return EFI_NOT_FOUND Table not found
+ @return EFI_STATUS returns non-EFI_SUCCESS value in case of failure
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateReinstallAcpiTable (
+ IN UINT32 Signature,
+ IN PATCH_ACPITABLE CallbackFunction
+ );
+
+/**
+ A Callback function to patch the ACPI FADT table.
+ Updates FADT table with AMD specific values, which
+ are different than MinPlatformPkg.
+
+ @param[in, out] NewTable Pointer to ACPI FADT table
+
+ @return EFI_SUCCESS Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+FadtAcpiTablePatch (
+ IN OUT EFI_ACPI_SDT_HEADER *NewTable
+ );
+
+EFI_STATUS
+EFIAPI
+MadtAcpiTablePatch (
+ IN OUT EFI_ACPI_SDT_HEADER *NewTable
+ );
+
+/**
+ A Callback function to patch the ACPI DSDT/SSDT table.
+ Which has ASL code that needs to be updated.
+
+ @param[in, out] NewTable Pointer to ACPI FADT table
+
+ @return EFI_SUCCESS Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiTableAmlUpdate (
+ IN OUT EFI_ACPI_SDT_HEADER *NewTable
+ );
+
+/**
+ Reserve Legacy VGA IO space.
+
+ @retval EFI_SUCCESS MMIO at Legacy VGA region has been allocated.
+ @retval !EFI_SUCCESS Error allocating the legacy VGA region.
+
+**/
+EFI_STATUS
+EFIAPI
+ReserveLegacyVgaIoSpace (
+ VOID
+ );
+
+#endif
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c
new file mode 100644
index 0000000000..aefb378981
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c
@@ -0,0 +1,243 @@
+/** @file
+ This file patches the ACPI MADT table for AMD specific values.
+
+ Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeBoardInitLibInternal.h"
+#include <Library/AmdPlatformSocLib.h>
+#include <Library/LocalApicLib.h>
+#define AMD_CPUID_EXTENDED_TOPOLOGY_V2 0x26
+#define AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_CCX 0x03
+#define AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_CCD 0x04
+#define AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE 0x05
+
+UINT32 mCcdOrder[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] LocalX2ApicLeft Pointer to Left Buffer.
+ @param[in] LocalX2ApicRight 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
+SortByCcd (
+ CONST VOID *LocalX2ApicLeft,
+ CONST VOID *LocalX2ApicRight
+ )
+{
+ CONST EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *Left;
+ CONST EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *Right;
+ EFI_CPU_PHYSICAL_LOCATION2 LeftLocation;
+ EFI_CPU_PHYSICAL_LOCATION2 RightLocation;
+ UINT32 LeftCcdIndex;
+ UINT32 RightCcdIndex;
+ UINT32 Index;
+
+ Left = (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)LocalX2ApicLeft;
+ Right = (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)LocalX2ApicRight;
+
+ GetProcessorLocation2ByApicId (
+ Left->X2ApicId,
+ &LeftLocation.Package,
+ &LeftLocation.Die,
+ &LeftLocation.Tile,
+ &LeftLocation.Module,
+ &LeftLocation.Core,
+ &LeftLocation.Thread
+ );
+
+ GetProcessorLocation2ByApicId (
+ Right->X2ApicId,
+ &RightLocation.Package,
+ &RightLocation.Die,
+ &RightLocation.Tile,
+ &RightLocation.Module,
+ &RightLocation.Core,
+ &RightLocation.Thread
+ );
+
+ // Get the CCD Index number
+ LeftCcdIndex = MAX_UINT32;
+ for (Index = 0; Index < ARRAY_SIZE (mCcdOrder); Index++) {
+ if (LeftLocation.Die == mCcdOrder[Index]) {
+ LeftCcdIndex = Index;
+ break;
+ }
+ }
+
+ RightCcdIndex = MAX_UINT32;
+ for (Index = 0; Index < ARRAY_SIZE (mCcdOrder); Index++) {
+ if (RightLocation.Die == mCcdOrder[Index]) {
+ RightCcdIndex = Index;
+ break;
+ }
+ }
+
+ // Now compare for quick sort
+ if (LeftCcdIndex < RightCcdIndex) {
+ return -1;
+ }
+
+ if (LeftCcdIndex > RightCcdIndex) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ A Callback function to patch the ACPI MADT table.
+ Updates MADT table with AMD specific values, which
+ are different than MinPlatformPkg.
+
+ @param[in, out] NewTable Pointer to ACPI MADT table
+
+ @return EFI_SUCCESS Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+MadtAcpiTablePatch (
+ IN OUT EFI_ACPI_SDT_HEADER *NewTable
+ )
+{
+ UINT32 Index;
+ EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *NewMadtTable;
+ UINT8 *TablePtr;
+ UINT64 Length;
+ EFI_ACPI_6_5_IO_APIC_STRUCTURE *NbioIoApic;
+ UINT8 IoApicCount;
+ UINTN LapicCount;
+ EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
+ EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *SortedItem;
+ EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *Src;
+ EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *Dst;
+
+ // Patch the Table
+ NewMadtTable = (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)NewTable;
+ NewMadtTable->Header.Revision = 6;
+ // Get the IoApic information
+ NbioIoApic = NULL;
+ IoApicCount = 0;
+ LapicCount = 0;
+ LocalX2ApicPtr = NULL;
+ GetIoApicInfo (&NbioIoApic, &IoApicCount);
+ if ((NbioIoApic == NULL) || (IoApicCount == 0)) {
+ DEBUG ((DEBUG_INFO, "%a:%d Cannot obtain NBIO IOAPIC information.\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+ }
+
+ // Create MADT header
+ TablePtr = (UINT8 *)NewMadtTable;
+ TablePtr = TablePtr + sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
+ Length = sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
+
+ // Get the IOAPIC structure
+ Index = 0; // now holds the IoApic Index
+ do {
+ if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_IO_APIC) {
+ // Patch the IoApic Strucure
+ if (Index >= IoApicCount) {
+ /// Mark the extra IOAPIC structure Type as reserved, so that OSPM can ignore it.
+ /// As per ACPI specification 6.5 for MADT table
+ /// Subtype 0x18-0x7F are reserved, OSPM skips structures of the reserved type.
+ ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->Type = 0x7F;
+ } else {
+ ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->IoApicId = NbioIoApic[Index].IoApicId;
+ ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->IoApicAddress = NbioIoApic[Index].IoApicAddress;
+ ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->GlobalSystemInterruptBase = NbioIoApic[Index].GlobalSystemInterruptBase;
+ }
+
+ Index++;
+ }
+
+ if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE) {
+ // Patch Flags
+ ((EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *)TablePtr)->Flags = 0xF;
+ }
+
+ if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_LOCAL_X2APIC_NMI) {
+ // Patch Flags - Edge-triggered, Active High
+ ((EFI_ACPI_6_5_LOCAL_X2APIC_NMI_STRUCTURE *)TablePtr)->Flags = 0x0005;
+ }
+
+ if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC) {
+ if (LapicCount == 0) {
+ // Get the first entry pointer
+ LocalX2ApicPtr = (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)TablePtr;
+ }
+
+ LapicCount += 1;
+ }
+
+ Length += ((STRUCTURE_HEADER *)TablePtr)->Length;
+ TablePtr += ((STRUCTURE_HEADER *)TablePtr)->Length;
+ } while (Length < NewMadtTable->Header.Length);
+
+ FreePool (NbioIoApic);
+
+ if (LocalX2ApicPtr != NULL) {
+ if (FixedPcdGet32 (PcdMaxCpuSocketCount) > 1) {
+ /// Sort by CCD location
+ PerformQuickSort (LocalX2ApicPtr, LapicCount/2, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE), SortByCcd);
+ PerformQuickSort (LocalX2ApicPtr+(LapicCount/2), LapicCount/2, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE), SortByCcd);
+ } else {
+ /// Sort by CCD location
+ PerformQuickSort (LocalX2ApicPtr, LapicCount, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE), SortByCcd);
+ }
+
+ /// Now allocate the Uid
+ SortedItem = LocalX2ApicPtr;
+ for (Index = 0; Index < LapicCount; Index++, SortedItem++) {
+ SortedItem->AcpiProcessorUid = Index;
+ }
+
+ // Now separate the second thread list
+ SortedItem = LocalX2ApicPtr + 1;
+ if ((SortedItem->X2ApicId & 0x1) == 0x1) {
+ // It has multi-thread on
+ SortedItem = NULL;
+ SortedItem = AllocateZeroPool (sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE) * LapicCount);
+ if (SortedItem == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Src = LocalX2ApicPtr;
+ Dst = SortedItem;
+ for (Index = 0; Index < LapicCount; Index++) {
+ if ((Src->X2ApicId & 0x1) == 0) {
+ CopyMem (Dst, Src, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE));
+ Src++;
+ Dst++;
+ } else {
+ Src++;
+ }
+ }
+
+ Src = LocalX2ApicPtr;
+ for (Index = 0; Index < LapicCount; Index++) {
+ if ((Src->X2ApicId & 0x1) == 1) {
+ CopyMem (Dst, Src, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE));
+ Src++;
+ Dst++;
+ } else {
+ Src++;
+ }
+ }
+
+ CopyMem (LocalX2ApicPtr, SortedItem, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE) * LapicCount);
+ FreePool (SortedItem);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
--
2.34.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118977): https://edk2.groups.io/g/devel/message/118977
Mute This Topic: https://groups.io/mt/106148092/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-05-17 3:49 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-17 3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
2024-05-17 3:49 ` [edk2-devel] [PATCH 1/5] AmdMinBoardPkg: Uncrustify PciHotPlug module Abdul Lateef Attar via groups.io
2024-05-17 3:49 ` [edk2-devel] [PATCH 2/5] AmdMinBoardPkg/Library: Uncrustify the Library module Abdul Lateef Attar via groups.io
2024-05-17 3:49 ` [edk2-devel] [PATCH 3/5] AmdMinBoardPkg: Implement BoardInitLib for PEI phase Abdul Lateef Attar via groups.io
2024-05-17 3:49 ` Abdul Lateef Attar via groups.io [this message]
2024-05-17 3:49 ` [edk2-devel] [PATCH 5/5] AmdMinBoardPkg: Implements BoardBdsHookLib library Abdul Lateef Attar via groups.io
2024-05-17 5:53 ` [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Chang, Abner via groups.io
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fc284dcd746a7a7d061d866a24582fefe4deb7ea.1715917637.git.AbdulLateef.Attar@amd.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox