From: Duke Zhai <duke.z...@amd.com>

BZ #:4640

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             | 194 ++++++++

 .../Smm/AcpiSmm/AcpiSmmPlatform.h             |  60 +++

 .../Smm/AcpiSmm/AcpiSmmPlatform.inf           |  65 +++

 .../Smm/SmmAccessPei/SmmAccessPei.c           | 447 ++++++++++++++++++

 .../Smm/SmmAccessPei/SmmAccessPei.inf         |  51 ++

 5 files changed, 817 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..383bcec471

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.c

@@ -0,0 +1,194 @@

+/** @file

+  Implements AMD AcpiSmmPlatform.c

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+ACPISMM Driver implementation file.

+

+This is QNC Smm platform driver

+

+Copyright (c) 2013-2019 Intel Corporation.

+

+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..ad519bca3b

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.h

@@ -0,0 +1,60 @@

+/** @file

+  Implements AMD AcpiSmmPlatform.h

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+Header file for SMM S3 Handler Driver.

+

+Copyright (c) 2013-2019 Intel Corporation.

+

+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..be252c4851

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/AcpiSmm/AcpiSmmPlatform.inf

@@ -0,0 +1,65 @@

+## @file

+#  AcpiSmmPlatform

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+## @file

+# Component description file for ACPI SMM Platform handler module

+#

+# This is QNC Smm platform driver .

+# 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..200aebf59c

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.c

@@ -0,0 +1,447 @@

+/** @file

+  Implements AMD SmmAccessPei.c

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+This is the driver that publishes the SMM Access Ppi

+instance for the Quark SOC.

+

+Copyright (c) 2013-2019 Intel Corporation.

+

+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..1572741d8e

--- /dev/null

+++ 
b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Smm/SmmAccessPei/SmmAccessPei.inf

@@ -0,0 +1,51 @@

+## @file

+#  SmmAccessPei

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+## @file

+# Component description file for SmmAccessPei module

+#

+# Copyright (c) 2013-2019 Intel Corporation.

+#

+# 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 (#114067): https://edk2.groups.io/g/devel/message/114067
Mute This Topic: https://groups.io/mt/103831179/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to