From: Duke Zhai <duke.z...@amd.com> BZ #:4640 In V2: Improve coding style. 1.Remove the leading underscore and use double underscore at trailing in C header files. 2.Remove old tianocore licenses and redundant license description. 3.Improve coding style. For example: remove space between @param.
In V1: Initial AMD Smm access module. Contains description files for ACPI SMM Platform handler module. Signed-off-by: Duke Zhai <duke.z...@amd.com> Cc: Eric Xing <eric.x...@amd.com> Cc: Ken Yao <ken....@amd.com> Cc: Igniculus Fu <igniculus...@amd.com> Cc: Abner Chang <abner.ch...@amd.com> --- .../Smm/AcpiSmm/AcpiSmmPlatform.c | 183 ++++++++ .../Smm/AcpiSmm/AcpiSmmPlatform.h | 50 ++ .../Smm/AcpiSmm/AcpiSmmPlatform.inf | 57 +++ .../Smm/SmmAccessPei/SmmAccessPei.c | 436 ++++++++++++++++++ .../Smm/SmmAccessPei/SmmAccessPei.inf | 43 ++ 5 files changed, 769 insertions(+) create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.c create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.h create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.inf create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.c create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.inf diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.c b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.c new file mode 100644 index 0000000000..20a0ed6cb7 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.c @@ -0,0 +1,183 @@ +/** @file +ACPISMM Driver implementation file. + +This is QNC Smm platform driver + +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +Copyright (c) 2013-2019 Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <AcpiSmmPlatform.h> + +/** + Allocate EfiACPIMemoryNVS below 4G memory address. + + This function allocates EfiACPIMemoryNVS below 4G memory address. + + @param[in] Size Size of memory to allocate. + + @return Allocated address for output. + +**/ +VOID * +AllocateAcpiNvsMemoryBelow4G ( + IN UINTN Size + ) +{ + UINTN Pages; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + VOID *Buffer; + + Pages = EFI_SIZE_TO_PAGES (Size); + Address = 0xffffffff; + + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + Pages, + &Address + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Address; + ZeroMem (Buffer, Size); + + return Buffer; +} + +/** + Reserved S3 memory for InstallS3Memory + + @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete function. + @retval EFI_SUCCESS Function has completed successfully. + +**/ +EFI_STATUS +EFIAPI +ReservedS3Memory ( + UINTN SystemMemoryLength + + ) + +{ + VOID *GuidHob; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock; + VOID *AcpiReservedBase; + + UINTN TsegIndex; + UINTN TsegSize; + UINTN TsegBase; + RESERVED_ACPI_S3_RANGE *AcpiS3Range; + + DEBUG ((DEBUG_INFO, "ReservedS3Memory, SystemMemoryLength: 0x%08X\n", SystemMemoryLength)); + // + // Get Hob list for SMRAM desc + // + GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid); + ASSERT (GuidHob != NULL); + DEBUG ((DEBUG_INFO, "gEfiSmmPeiSmramMemoryReserveGuid: 0x%X \n", (UINTN)GuidHob)); + DescriptorBlock = GET_GUID_HOB_DATA (GuidHob); + ASSERT (DescriptorBlock != NULL); + + // + // Use the hob to get SMRAM capabilities + // + TsegIndex = DescriptorBlock->NumberOfSmmReservedRegions - 1; + DEBUG ((DEBUG_INFO, "DescriptorBlock->NumberOfSmmReservedRegions: 0x%X\n", DescriptorBlock->NumberOfSmmReservedRegions)); + DEBUG ((DEBUG_INFO, "TsegIndex: 0x%X\n", TsegIndex)); + ASSERT (TsegIndex <= (MAX_SMRAM_RANGES - 1)); + TsegBase = (UINTN)DescriptorBlock->Descriptor[TsegIndex].PhysicalStart; + TsegSize = (UINTN)DescriptorBlock->Descriptor[TsegIndex].PhysicalSize; + + DEBUG ((DEBUG_INFO, "SMM Base: %08X\n", TsegBase)); + DEBUG ((DEBUG_INFO, "SMM Size: %08X\n", TsegSize)); + + // + // Now find the location of the data structure that is used to store the address + // of the S3 reserved memory. + // + AcpiS3Range = (RESERVED_ACPI_S3_RANGE *)(UINTN)(TsegBase + RESERVED_ACPI_S3_RANGE_OFFSET); + DEBUG ((DEBUG_INFO, "AcpiS3Range: %08X\n", (UINTN)AcpiS3Range)); + // + // Allocate reserved ACPI memory for S3 resume. Pointer to this region is + // stored in SMRAM in the first page of TSEG. + // + AcpiReservedBase = AllocateAcpiNvsMemoryBelow4G (PcdGet32 (PcdS3AcpiReservedMemorySize)); + DEBUG ((DEBUG_INFO, "AcpiReservedBase: %08X\n", (UINTN)AcpiReservedBase)); + ASSERT (AcpiReservedBase != NULL); + if (AcpiReservedBase != NULL) { + AcpiS3Range->AcpiReservedMemoryBase = (UINT32)(UINTN)AcpiReservedBase; + AcpiS3Range->AcpiReservedMemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize); + } + + AcpiS3Range->SystemMemoryLength = (UINT32)SystemMemoryLength; + + DEBUG ((DEBUG_INFO, "S3 Memory Base: %08X\n", AcpiS3Range->AcpiReservedMemoryBase)); + DEBUG ((DEBUG_INFO, "S3 Memory Size: %08X\n", AcpiS3Range->AcpiReservedMemorySize)); + DEBUG ((DEBUG_INFO, "S3 SysMemoryLength: %08X\n", AcpiS3Range->SystemMemoryLength)); + + return EFI_SUCCESS; +} + +/** + Initializes the SMM S3 Handler Driver. + + @param[in] ImageHandle The image handle of Sleep State Wake driver. + @param[in] SystemTable The starndard EFI system table. + + @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete function. + @retval EFI_SUCCESS Function has completed successfully. + @retval Other Error occured during execution. + +**/ +EFI_STATUS +EFIAPI +InitAcpiSmmPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ + EFI_STATUS Status; + EFI_GLOBAL_NVS_AREA_PROTOCOL *AcpiNvsProtocol = NULL; + UINTN MemoryLength; + EFI_PEI_HOB_POINTERS Hob; + + Status = gBS->LocateProtocol ( + &gEfiGlobalNvsAreaProtocolGuid, + NULL, + (VOID **)&AcpiNvsProtocol + ); + ASSERT_EFI_ERROR (Status); + + // + // Calculate the system memory length by memory hobs + // + MemoryLength = 0x100000; + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); + ASSERT (Hob.Raw != NULL); + while ((Hob.Raw != NULL) && (!END_OF_HOB_LIST (Hob))) { + if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { + // + // Skip the memory region below 1MB + // + if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) { + MemoryLength += (UINTN)Hob.ResourceDescriptor->ResourceLength; + } + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); + } + + Status = ReservedS3Memory (MemoryLength); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.h b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.h new file mode 100644 index 0000000000..31ab4f083d --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.h @@ -0,0 +1,50 @@ +/** @file +Header file for SMM S3 Handler Driver. + +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +Copyright (c) 2013-2019 Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef ACPI_SMM_DRIVER_H_ +#define ACPI_SMM_DRIVER_H_ +// +// Include files +// +// +// Driver Consumed Protocol Prototypes +// +#include <Protocol/GlobalNvsArea.h> +#include <Library/UefiDriverEntryPoint.h> +#include <Library/IoLib.h> +#include <Library/PciLib.h> +#include <Library/PcdLib.h> +#include <Library/LockBoxLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/S3IoLib.h> +#include <Library/S3BootScriptLib.h> +#include <Guid/Acpi.h> +#include <Library/SmmServicesTableLib.h> +#include <Guid/SmramMemoryReserve.h> +#include <Library/HobLib.h> + +// +// This structure stores the base and size of the ACPI reserved memory used when +// resuming from S3. This region must be allocated by the platform code. +// +typedef struct { + UINT32 AcpiReservedMemoryBase; + UINT32 AcpiReservedMemorySize; + UINT32 SystemMemoryLength; +} RESERVED_ACPI_S3_RANGE; + +#define RESERVED_ACPI_S3_RANGE_OFFSET (EFI_PAGE_SIZE - sizeof (RESERVED_ACPI_S3_RANGE)) +#define MAX_SMRAM_RANGES 4 + +#endif diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.inf b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.inf new file mode 100644 index 0000000000..428e04b7d2 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.inf @@ -0,0 +1,57 @@ +## @file +# Component description file for ACPI SMM Platform handler module +# +# This is QNC Smm platform driver . +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +# Copyright (c) 2013-2019 Intel Corporation. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = AcpiSmmPlatform + FILE_GUID = 833AF7CC-C58F-4BF6-8FCD-A46667F2BAD3 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = InitAcpiSmmPlatform + +[Sources] + AcpiSmmPlatform.c + AcpiSmmPlatform.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ChachaniBoardPkg/Project.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + ReportStatusCodeLib + UefiDriverEntryPoint + DebugLib + IoLib + PciLib + BaseMemoryLib + BaseLib + SmmServicesTableLib + PcdLib + HobLib + S3BootScriptLib + LockBoxLib + +[Protocols] + gEfiGlobalNvsAreaProtocolGuid + +[Guids] + gEfiSmmPeiSmramMemoryReserveGuid + +[Pcd] + gPlatformPkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize + +[Depex] + gEfiGlobalNvsAreaProtocolGuid diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.c b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.c new file mode 100644 index 0000000000..7880acc2f3 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.c @@ -0,0 +1,436 @@ +/** @file +This is the driver that publishes the SMM Access Ppi +instance for the Quark SOC. + +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +Copyright (c) 2013-2019 Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include <PiPei.h> +#include <Ppi/SmmAccess.h> +#include <Guid/SmramMemoryReserve.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/DebugLib.h> +#include <Library/HobLib.h> +#include <Library/PciLib.h> +#include <Library/PeiServicesLib.h> +#include <AGESA.h> +#define SMMMASK_ADDRESS 0xC0010113 + +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \ + CR ( \ + a, \ + SMM_ACCESS_PRIVATE_DATA, \ + SmmAccess, \ + SMM_ACCESS_PRIVATE_DATA_SIGNATURE \ + ) + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + PEI_SMM_ACCESS_PPI SmmAccess; + UINTN NumberRegions; + EFI_SMRAM_DESCRIPTOR *SmramDesc; +} SMM_ACCESS_PRIVATE_DATA; + +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's', 'a') + +/** + CpuOpenSMRAM - read/write A0000-BFFFF + + @param VOID None. + + @retval VOID None. +**/ +VOID +EFIAPI +OpenSMRAM ( + VOID + ) +{ + volatile UINT64 RegValue; + + // Disable protection in ASeg and TSeg + RegValue = AsmReadMsr64 (SMMMASK_ADDRESS); + RegValue &= (UINT64)(~BIT0); + RegValue &= (UINT64)(~BIT1); + AsmWriteMsr64 (SMMMASK_ADDRESS, RegValue); + + // Enable FixMtrrModEn + RegValue = AsmReadMsr64 (SYS_CFG); + RegValue |= (UINT64)(1 << 19); + AsmWriteMsr64 (SYS_CFG, RegValue); + + // Enable Rd/Wr DRAM in ASeg + RegValue = AsmReadMsr64 (AMD_AP_MTRR_FIX16k_A0000); + RegValue |= 0x1010101010101010; + RegValue |= 0x0808080808080808; + AsmWriteMsr64 (AMD_AP_MTRR_FIX16k_A0000, RegValue); + + // Disable FixMtrrModEn + RegValue = AsmReadMsr64 (SYS_CFG); + RegValue &= ~(UINT64)(1 << 19); + AsmWriteMsr64 (SYS_CFG, RegValue); +} + +/** + CpuSmramWP - write protect from A0000-BFFFF + + @param VOID None. + + @retval VOID None. +**/ +VOID +EFIAPI +CloseSmram ( + VOID + ) +{ + volatile UINT64 RegValue; + + // Enable FixMtrrModEn + RegValue = AsmReadMsr64 (SYS_CFG); + RegValue |= (UINT64)(1 << 19); + AsmWriteMsr64 (SYS_CFG, RegValue); + + // Disable Rd/Wr DRAM in ASeg + RegValue = AsmReadMsr64 (AMD_AP_MTRR_FIX16k_A0000); + RegValue &= 0xEFEFEFEFEFEFEFEF; + RegValue &= 0xF7F7F7F7F7F7F7F7; + AsmWriteMsr64 (AMD_AP_MTRR_FIX16k_A0000, RegValue); + + // Disable FixMtrrModEn + RegValue = AsmReadMsr64 (SYS_CFG); + RegValue &= ~(UINT64)(1 << 19); + AsmWriteMsr64 (SYS_CFG, RegValue); + + RegValue = AsmReadMsr64 (SMMMASK_ADDRESS); + RegValue |= (UINT64)BIT0; + RegValue |= (UINT64)BIT1; + AsmWriteMsr64 (SMMMASK_ADDRESS, RegValue); +} + +/** + Setting the bit0 of MSRC001_0015 Hardware Configuration (HWCR) to do SMM code lock. + + @param VOID None. + + @retval VOID None. +**/ +VOID +EFIAPI +LockSmm ( + VOID + ) +{ + volatile UINT64 Data64; + + Data64 = AsmReadMsr64 (HWCR); + Data64 |= (UINT64)BIT0; // SMM_LOCK + AsmWriteMsr64 (HWCR, Data64); +} + +/** + This routine accepts a request to "open" a region of SMRAM. The + region could be legacy ABSEG, HSEG, or TSEG near top of physical memory. + The use of "open" means that the memory is visible from all PEIM + and SMM agents. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMM Access Interface. + @param[in] DescriptorIndex Region of SMRAM to Open. + + @retval EFI_SUCCESS The region was successfully opened. + @retval EFI_DEVICE_ERROR The region could not be opened because locked by + chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Open ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + + if (DescriptorIndex >= SmmAccess->NumberRegions) { + DEBUG ((DEBUG_WARN, "SMRAM region out of range in Open\n")); + return EFI_INVALID_PARAMETER; + } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) { + DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region in Open\n")); + return EFI_DEVICE_ERROR; + } + + // + // Open TSEG + // + OpenSMRAM (); + + SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED); + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_OPEN; + SmmAccess->SmmAccess.OpenState = TRUE; + + return EFI_SUCCESS; +} + +/** + This routine accepts a request to "close" a region of SMRAM. This is valid for + compatible SMRAM region. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMM Access Interface. + @param[in] DescriptorIndex Region of SMRAM to Close. + + @retval EFI_SUCCESS The region was successfully closed. + @retval EFI_DEVICE_ERROR The region could not be closed because locked by + chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Close ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + BOOLEAN OpenState; + UINT8 Index; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + + if (DescriptorIndex >= SmmAccess->NumberRegions) { + DEBUG ((DEBUG_WARN, "SMRAM region out of range in Close\n")); + return EFI_INVALID_PARAMETER; + } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) { + DEBUG ((DEBUG_WARN, "SmmAccess Close region is locked:%d\n", DescriptorIndex)); + return EFI_DEVICE_ERROR; + } + + if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_CLOSED) { + DEBUG ((DEBUG_WARN, "SmmAccess Close region is closed already:%d\n", DescriptorIndex)); + return EFI_DEVICE_ERROR; + } + + // + // Close TSEG + // + CloseSmram (); + + SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~EFI_SMRAM_OPEN; + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (EFI_SMRAM_CLOSED | EFI_ALLOCATED); + + // + // Find out if any regions are still open + // + OpenState = FALSE; + for (Index = 0; Index < SmmAccess->NumberRegions; Index++) { + if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) { + OpenState = TRUE; + } + } + + SmmAccess->SmmAccess.OpenState = OpenState; + + return EFI_SUCCESS; +} + +/** + This routine accepts a request to "lock" SMRAM. The + region could be legacy AB or TSEG near top of physical memory. + The use of "lock" means that the memory can no longer be opened + to PEIM. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMM Access Interface. + @param[in] DescriptorIndex Region of SMRAM to Lock. + + @retval EFI_SUCCESS The region was successfully locked. + @retval EFI_DEVICE_ERROR The region could not be locked because at least + one range is still open. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Lock ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + + if (DescriptorIndex >= SmmAccess->NumberRegions) { + DEBUG ((DEBUG_WARN, "SMRAM region out of range in Lock\n")); + return EFI_INVALID_PARAMETER; + } else if (SmmAccess->SmmAccess.OpenState) { + DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n")); + return EFI_DEVICE_ERROR; + } + + // + // Lock TSEG + // + LockSmm (); + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED; + SmmAccess->SmmAccess.LockState = TRUE; + + return EFI_SUCCESS; +} + +/** + This routine services a user request to discover the SMRAM + capabilities of this platform. This will report the possible + ranges that are possible for SMRAM access, based upon the + memory controller capabilities. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMRAM Access Interface. + @param[in, out] SmramMapSize Pointer to the variable containing size of the + buffer to contain the description information. + @param[in, out] SmramMap Buffer containing the data describing the Smram + region descriptors. + + @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buffer. + @retval EFI_SUCCESS The user provided a sufficiently-sized buffer. + +**/ +EFI_STATUS +EFIAPI +GetCapabilities ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ) +{ + EFI_STATUS Status; + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + UINTN BufferSize; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + BufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR); + + if (*SmramMapSize < BufferSize) { + DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n")); + Status = EFI_BUFFER_TOO_SMALL; + } else { + CopyMem (SmramMap, SmmAccess->SmramDesc, BufferSize); + Status = EFI_SUCCESS; + } + + *SmramMapSize = BufferSize; + + return Status; +} + +/** + This is the constructor for the SMM Access Ppi + + @param[in] FfsHeader FfsHeader. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Protocol successfully started and installed. + @retval EFI_UNSUPPORTED Protocol can't be started. +**/ +EFI_STATUS +EFIAPI +SmmAccessPeiEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + UINTN Index; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock = NULL; + SMM_ACCESS_PRIVATE_DATA *SmmAccessPrivate; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + EFI_HOB_GUID_TYPE *GuidHob; + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if (EFI_ERROR (Status) || (BootMode != BOOT_ON_S3_RESUME)) { + // + // If not in S3 boot path. do nothing + // + return EFI_SUCCESS; + } + + // + // Initialize private data + // + SmmAccessPrivate = AllocateZeroPool (sizeof (*SmmAccessPrivate)); + ASSERT (SmmAccessPrivate != NULL); + + PpiList = AllocateZeroPool (sizeof (*PpiList)); + ASSERT (PpiList != NULL); + + // + // Build SMM related information + // + SmmAccessPrivate->Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE; + SmmAccessPrivate->Handle = NULL; + + // + // Get Hob list + // + GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid); + ASSERT (GuidHob != NULL); + DescriptorBlock = GET_GUID_HOB_DATA (GuidHob); + ASSERT (DescriptorBlock != NULL); + + // + // Alloc space for SmmAccessPrivate->SmramDesc + // + SmmAccessPrivate->SmramDesc = AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof (EFI_SMRAM_DESCRIPTOR)); + if (SmmAccessPrivate->SmramDesc == NULL) { + DEBUG ((DEBUG_ERROR, "Alloc SmmAccessPrivate->SmramDesc fail.\n")); + return EFI_OUT_OF_RESOURCES; + } + + // + // Use the hob to publish SMRAM capabilities + // + for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) { + SmmAccessPrivate->SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart; + SmmAccessPrivate->SmramDesc[Index].CpuStart = DescriptorBlock->Descriptor[Index].CpuStart; + SmmAccessPrivate->SmramDesc[Index].PhysicalSize = DescriptorBlock->Descriptor[Index].PhysicalSize; + SmmAccessPrivate->SmramDesc[Index].RegionState = DescriptorBlock->Descriptor[Index].RegionState; + } + + SmmAccessPrivate->NumberRegions = Index; + SmmAccessPrivate->SmmAccess.Open = Open; + SmmAccessPrivate->SmmAccess.Close = Close; + SmmAccessPrivate->SmmAccess.Lock = Lock; + SmmAccessPrivate->SmmAccess.GetCapabilities = GetCapabilities; + SmmAccessPrivate->SmmAccess.LockState = FALSE; + SmmAccessPrivate->SmmAccess.OpenState = FALSE; + + PpiList->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + PpiList->Guid = &gPeiSmmAccessPpiGuid; + PpiList->Ppi = &SmmAccessPrivate->SmmAccess; + + Status = (**PeiServices).InstallPpi (PeiServices, PpiList); + ASSERT_EFI_ERROR (Status); + + DEBUG ( + (EFI_D_INFO, "SMM Base:Size %08X:%08X\n", + (UINTN)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalStart), + (UINTN)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalSize) + )); + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.inf b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.inf new file mode 100644 index 0000000000..741eddd43c --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.inf @@ -0,0 +1,43 @@ +## @file +# Component description file for SmmAccessPei module +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +# Copyright (c) 2013-2019 Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] +INF_VERSION = 0x00010005 +BASE_NAME = SmmAccessPei +FILE_GUID = C6E6E43A-5DB1-4810-AAB7-C5A2A0914713 +MODULE_TYPE = PEIM +VERSION_STRING = 1.0 +ENTRY_POINT = SmmAccessPeiEntryPoint + +[Sources] + SmmAccessPei.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ChachaniBoardPkg/Project.dec + AgesaPublic/AgesaPublic.dec + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + HobLib + +[Ppis] + gPeiSmmAccessPpiGuid # ALWAYS_PRODUCED + +[Guids] + gEfiSmmPeiSmramMemoryReserveGuid + +[Depex] + gEfiPeiMasterBootModePpiGuid AND gEfiPeiMemoryDiscoveredPpiGuid -- 2.31.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114510): https://edk2.groups.io/g/devel/message/114510 Mute This Topic: https://groups.io/mt/103971407/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-