From: Duke Zhai <Duke.Zhai@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.zhai@amd.com>
Cc: Eric Xing <eric.xing@amd.com>
Cc: Ken Yao <ken.yao@amd.com>
Cc: Igniculus Fu <igniculus.fu@amd.com>
Cc: Abner Chang <abner.chang@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 (#114593): https://edk2.groups.io/g/devel/message/114593
Mute This Topic: https://groups.io/mt/103975468/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2024 Red Hat, Inc.