From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../PiSmmCommunication/PiSmmCommunicationPei.c | 419 +++++++++++++++++++++ .../PiSmmCommunication/PiSmmCommunicationPei.inf | 64 ++++ .../PiSmmCommunication/PiSmmCommunicationPei.uni | 15 + .../PiSmmCommunicationPeiExtra.uni | 12 + .../PiSmmCommunication/PiSmmCommunicationPrivate.h | 24 ++ .../PiSmmCommunication/PiSmmCommunicationSmm.c | 207 ++++++++++ .../PiSmmCommunication/PiSmmCommunicationSmm.inf | 55 +++ .../PiSmmCommunication/PiSmmCommunicationSmm.uni | 13 + .../PiSmmCommunicationSmmExtra.uni | 12 + 9 files changed, 821 insertions(+) create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni create mode 100644 roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni (limited to 'roms/edk2/UefiCpuPkg/PiSmmCommunication') diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c new file mode 100644 index 000000000..68e5003ad --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c @@ -0,0 +1,419 @@ +/** @file +PiSmmCommunication PEI Driver. + +Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PiSmmCommunicationPrivate.h" + +/** + the whole picture is below: + + +----------------------------------+ + | ACPI_VARIABLE_HOB | + | SmramDescriptor | <- DRAM + | CpuStart |--- + +----------------------------------+ | + | + +----------------------------------+<-- + | SMM_S3_RESUME_STATE | + | Signature | <- SMRAM + | Smst |--- + +----------------------------------+ | + | + +----------------------------------+<-- + | EFI_SMM_SYSTEM_TABLE2 | + | NumberOfTableEntries | <- SMRAM + | SmmConfigurationTable |--- + +----------------------------------+ | + | + +----------------------------------+<-- + | EFI_SMM_COMMUNICATION_CONTEXT | + | SwSmiNumber | <- SMRAM + | BufferPtrAddress |---------------- + +----------------------------------+ | + | + +----------------------------------+ | + | EFI_SMM_COMMUNICATION_ACPI_TABLE | | + | SwSmiNumber | <- AcpiTable | + | BufferPtrAddress |--- | + +----------------------------------+ | | + | | + +----------------------------------+<--------------- + | Communication Buffer Pointer | <- AcpiNvs + +----------------------------------+--- + | + +----------------------------------+<-- + | EFI_SMM_COMMUNICATE_HEADER | + | HeaderGuid | <- DRAM + | MessageLength | + +----------------------------------+ + +**/ + +#if defined (MDE_CPU_IA32) +typedef struct { + EFI_TABLE_HEADER Hdr; + UINT64 SmmFirmwareVendor; + UINT64 SmmFirmwareRevision; + UINT64 SmmInstallConfigurationTable; + UINT64 SmmIoMemRead; + UINT64 SmmIoMemWrite; + UINT64 SmmIoIoRead; + UINT64 SmmIoIoWrite; + UINT64 SmmAllocatePool; + UINT64 SmmFreePool; + UINT64 SmmAllocatePages; + UINT64 SmmFreePages; + UINT64 SmmStartupThisAp; + UINT64 CurrentlyExecutingCpu; + UINT64 NumberOfCpus; + UINT64 CpuSaveStateSize; + UINT64 CpuSaveState; + UINT64 NumberOfTableEntries; + UINT64 SmmConfigurationTable; +} EFI_SMM_SYSTEM_TABLE2_64; + +typedef struct { + EFI_GUID VendorGuid; + UINT64 VendorTable; +} EFI_CONFIGURATION_TABLE64; +#endif + +#if defined (MDE_CPU_X64) +typedef EFI_SMM_SYSTEM_TABLE2 EFI_SMM_SYSTEM_TABLE2_64; +typedef EFI_CONFIGURATION_TABLE EFI_CONFIGURATION_TABLE64; +#endif + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_PEI_SMM_COMMUNICATION_PPI instance. + @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. + @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_NOT_STARTED The service is NOT started. +**/ +EFI_STATUS +EFIAPI +Communicate ( + IN CONST EFI_PEI_SMM_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ); + +EFI_PEI_SMM_COMMUNICATION_PPI mSmmCommunicationPpi = { Communicate }; + +EFI_PEI_PPI_DESCRIPTOR mPpiList = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiSmmCommunicationPpiGuid, + &mSmmCommunicationPpi +}; + +/** + Get SMM communication context. + + @return SMM communication context. +**/ +EFI_SMM_COMMUNICATION_CONTEXT * +GetCommunicationContext ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; + + GuidHob = GetFirstGuidHob (&gEfiPeiSmmCommunicationPpiGuid); + ASSERT (GuidHob != NULL); + + SmmCommunicationContext = (EFI_SMM_COMMUNICATION_CONTEXT *)GET_GUID_HOB_DATA (GuidHob); + + return SmmCommunicationContext; +} + +/** + Set SMM communication context. + + @param SmmCommunicationContext SMM communication context. +**/ +VOID +SetCommunicationContext ( + IN EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINTN BufferSize; + + BufferSize = sizeof (*SmmCommunicationContext); + Hob.Raw = BuildGuidHob ( + &gEfiPeiSmmCommunicationPpiGuid, + BufferSize + ); + ASSERT (Hob.Raw); + + CopyMem ((VOID *)Hob.Raw, SmmCommunicationContext, sizeof(*SmmCommunicationContext)); +} + +/** + Get VendorTable by VendorGuid in Smst. + + @param Signature Signature of SMM_S3_RESUME_STATE + @param Smst SMM system table + @param VendorGuid vendor guid + + @return vendor table. +**/ +VOID * +InternalSmstGetVendorTableByGuid ( + IN UINT64 Signature, + IN EFI_SMM_SYSTEM_TABLE2 *Smst, + IN EFI_GUID *VendorGuid + ) +{ + EFI_CONFIGURATION_TABLE *SmmConfigurationTable; + UINTN NumberOfTableEntries; + UINTN Index; + EFI_SMM_SYSTEM_TABLE2_64 *Smst64; + EFI_CONFIGURATION_TABLE64 *SmmConfigurationTable64; + + if ((sizeof(UINTN) == sizeof(UINT32)) && (Signature == SMM_S3_RESUME_SMM_64)) { + // + // 32 PEI + 64 DXE + // + Smst64 = (EFI_SMM_SYSTEM_TABLE2_64 *)Smst; + DEBUG ((EFI_D_INFO, "InitCommunicationContext - SmmConfigurationTable: %x\n", Smst64->SmmConfigurationTable)); + DEBUG ((EFI_D_INFO, "InitCommunicationContext - NumberOfTableEntries: %x\n", Smst64->NumberOfTableEntries)); + SmmConfigurationTable64 = (EFI_CONFIGURATION_TABLE64 *)(UINTN)Smst64->SmmConfigurationTable; + NumberOfTableEntries = (UINTN)Smst64->NumberOfTableEntries; + for (Index = 0; Index < NumberOfTableEntries; Index++) { + if (CompareGuid (&SmmConfigurationTable64[Index].VendorGuid, VendorGuid)) { + return (VOID *)(UINTN)SmmConfigurationTable64[Index].VendorTable; + } + } + return NULL; + } else { + DEBUG ((EFI_D_INFO, "InitCommunicationContext - SmmConfigurationTable: %x\n", Smst->SmmConfigurationTable)); + DEBUG ((EFI_D_INFO, "InitCommunicationContext - NumberOfTableEntries: %x\n", Smst->NumberOfTableEntries)); + SmmConfigurationTable = Smst->SmmConfigurationTable; + NumberOfTableEntries = Smst->NumberOfTableEntries; + for (Index = 0; Index < NumberOfTableEntries; Index++) { + if (CompareGuid (&SmmConfigurationTable[Index].VendorGuid, VendorGuid)) { + return (VOID *)SmmConfigurationTable[Index].VendorTable; + } + } + return NULL; + } +} + +/** + Init SMM communication context. +**/ +VOID +InitCommunicationContext ( + VOID + ) +{ + EFI_SMRAM_DESCRIPTOR *SmramDescriptor; + SMM_S3_RESUME_STATE *SmmS3ResumeState; + VOID *GuidHob; + EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; + + GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid); + ASSERT (GuidHob != NULL); + SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob); + SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart; + + DEBUG ((EFI_D_INFO, "InitCommunicationContext - SmmS3ResumeState: %x\n", SmmS3ResumeState)); + DEBUG ((EFI_D_INFO, "InitCommunicationContext - Smst: %x\n", SmmS3ResumeState->Smst)); + + SmmCommunicationContext = (EFI_SMM_COMMUNICATION_CONTEXT *)InternalSmstGetVendorTableByGuid ( + SmmS3ResumeState->Signature, + (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst, + &gEfiPeiSmmCommunicationPpiGuid + ); + ASSERT (SmmCommunicationContext != NULL); + + SetCommunicationContext (SmmCommunicationContext); + + return ; +} + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_PEI_SMM_COMMUNICATION_PPI instance. + @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. + @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_NOT_STARTED The service is NOT started. +**/ +EFI_STATUS +EFIAPI +Communicate ( + IN CONST EFI_PEI_SMM_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ) +{ + EFI_STATUS Status; + PEI_SMM_CONTROL_PPI *SmmControl; + PEI_SMM_ACCESS_PPI *SmmAccess; + UINT8 SmiCommand; + UINTN Size; + EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; + + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Enter\n")); + + if (CommBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Get needed resource + // + Status = PeiServicesLocatePpi ( + &gPeiSmmControlPpiGuid, + 0, + NULL, + (VOID **)&SmmControl + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_STARTED; + } + + Status = PeiServicesLocatePpi ( + &gPeiSmmAccessPpiGuid, + 0, + NULL, + (VOID **)&SmmAccess + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_STARTED; + } + + // + // Check SMRAM locked, it should be done after SMRAM lock. + // + if (!SmmAccess->LockState) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState)); + return EFI_NOT_STARTED; + } + + SmmCommunicationContext = GetCommunicationContext (); + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei BufferPtrAddress - 0x%016lx, BufferPtr: 0x%016lx\n", SmmCommunicationContext->BufferPtrAddress, *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress)); + + // + // No need to check if BufferPtr is 0, because it is in PEI phase. + // + *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer; + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei CommBuffer - %x\n", (UINTN)CommBuffer)); + + // + // Send command + // + SmiCommand = (UINT8)SmmCommunicationContext->SwSmiNumber; + Size = sizeof(SmiCommand); + Status = SmmControl->Trigger ( + (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), + SmmControl, + (INT8 *)&SmiCommand, + &Size, + FALSE, + 0 + ); + ASSERT_EFI_ERROR (Status); + + // + // Setting BufferPtr to 0 means this transaction is done. + // + *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = 0; + + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Exit\n")); + + return EFI_SUCCESS; +} + +/** + Entry Point for PI SMM communication PEIM. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Pointer to PEI Services table. + + @retval EFI_SUCCESS + @return Others Some error occurs. +**/ +EFI_STATUS +EFIAPI +PiSmmCommunicationPeiEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + PEI_SMM_ACCESS_PPI *SmmAccess; + EFI_BOOT_MODE BootMode; + UINTN Index; + + BootMode = GetBootModeHob (); + if (BootMode != BOOT_ON_S3_RESUME) { + return EFI_UNSUPPORTED; + } + + Status = PeiServicesLocatePpi ( + &gPeiSmmAccessPpiGuid, + 0, + NULL, + (VOID **)&SmmAccess + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_STARTED; + } + + // + // Check SMRAM locked, it should be done before SMRAM lock. + // + if (SmmAccess->LockState) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState)); + return EFI_ACCESS_DENIED; + } + + // + // Open all SMRAM + // + for (Index = 0; !EFI_ERROR (Status); Index++) { + Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); + } + + InitCommunicationContext (); + + PeiServicesInstallPpi (&mPpiList); + + return RETURN_SUCCESS; +} diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf new file mode 100644 index 000000000..4d274ce2b --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf @@ -0,0 +1,64 @@ +## @file +# PI SMM Communication PEIM which produces PEI SMM Communication PPI. +# +# This PEIM retrieves the SMM communication context and produces PEI SMM +# Communication PPIin the S3 boot mode. +# +# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PiSmmCommunicationPei + MODULE_UNI_FILE = PiSmmCommunicationPei.uni + FILE_GUID = 1C8B7F78-1699-40e6-AF33-9B995D16B043 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = PiSmmCommunicationPeiEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + PiSmmCommunicationPei.c + PiSmmCommunicationPrivate.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + PeimEntryPoint + PeiServicesTablePointerLib + PeiServicesLib + BaseLib + BaseMemoryLib + HobLib + DebugLib + +[Guids] + gEfiAcpiVariableGuid ## CONSUMES ## HOB + +[Ppis] + ## PRODUCES + ## UNDEFINED # HOB # SMM Configuration Table + gEfiPeiSmmCommunicationPpiGuid + gPeiSmmAccessPpiGuid ## CONSUMES + gPeiSmmControlPpiGuid ## CONSUMES + +# [BootMode] +# S3_RESUME ## CONSUMES + +[Depex] + gPeiSmmAccessPpiGuid AND + gPeiSmmControlPpiGuid AND + gEfiPeiMasterBootModePpiGuid + +[UserExtensions.TianoCore."ExtraFiles"] + PiSmmCommunicationPeiExtra.uni diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni new file mode 100644 index 000000000..29c22808a --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni @@ -0,0 +1,15 @@ +// /** @file +// PI SMM Communication PEIM which produces PEI SMM Communication PPI. +// +// This PEIM retrieves the SMM communication context and produces PEI SMM +// Communication PPIin the S3 boot mode. +// +// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "PI SMM Communication PEIM that produces PEI SMM Communication PPI" + +#string STR_MODULE_DESCRIPTION #language en-US "This PEIM retrieves the SMM communication context and produces PEI SMM Communication PPI in the S3 boot mode." diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni new file mode 100644 index 000000000..c76457846 --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// PiSmmCommunicationPei Localized Strings and Content +// +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"SMM Communication PEI Module" diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h new file mode 100644 index 000000000..cf1c57eef --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h @@ -0,0 +1,24 @@ +/** @file +PiSmmCommunication private data structure + +Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_COMMUNICATION_PRIVATE_H_ +#define _SMM_COMMUNICATION_PRIVATE_H_ + +#pragma pack(push, 1) + +#define SMM_COMMUNICATION_SIGNATURE SIGNATURE_32 ('S','M','M','C') + +typedef struct { + UINT32 Signature; + UINT32 SwSmiNumber; + EFI_PHYSICAL_ADDRESS BufferPtrAddress; +} EFI_SMM_COMMUNICATION_CONTEXT; + +#pragma pack(pop) + +#endif diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c new file mode 100644 index 000000000..30f7d57bd --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c @@ -0,0 +1,207 @@ +/** @file +PiSmmCommunication SMM Driver. + +Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PiSmmCommunicationPrivate.h" + +EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = { + SMM_COMMUNICATION_SIGNATURE +}; + +/** + Set SMM communication context. +**/ +VOID +SetCommunicationContext ( + VOID + ) +{ + EFI_STATUS Status; + + Status = gSmst->SmmInstallConfigurationTable ( + gSmst, + &gEfiPeiSmmCommunicationPpiGuid, + &mSmmCommunicationContext, + sizeof(mSmmCommunicationContext) + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Dispatch function for a Software SMI handler. + + @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the + handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-SMM environment into an SMM environment. + @param CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS Command is handled successfully. + +**/ +EFI_STATUS +EFIAPI +PiSmmCommunicationHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + UINTN CommSize; + EFI_STATUS Status; + EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader; + EFI_PHYSICAL_ADDRESS *BufferPtrAddress; + + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Enter\n")); + + BufferPtrAddress = (EFI_PHYSICAL_ADDRESS *)(UINTN)mSmmCommunicationContext.BufferPtrAddress; + CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)(UINTN)*BufferPtrAddress; + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateHeader - %x\n", CommunicateHeader)); + if (CommunicateHeader == NULL) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler is NULL, needn't to call dispatch function\n")); + Status = EFI_SUCCESS; + } else { + if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicateHeader, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data))) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader)); + Status = EFI_SUCCESS; + goto Done; + } + + CommSize = (UINTN)CommunicateHeader->MessageLength; + if (!SmmIsBufferOutsideSmmValid ((UINTN)&CommunicateHeader->Data[0], CommSize)) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateData invalid - 0x%x\n", &CommunicateHeader->Data[0])); + Status = EFI_SUCCESS; + goto Done; + } + + // + // Call dispatch function + // + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader->Data[0])); + Status = gSmst->SmiManage ( + &CommunicateHeader->HeaderGuid, + NULL, + &CommunicateHeader->Data[0], + &CommSize + ); + } + +Done: + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler %r\n", Status)); + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Exit\n")); + + return (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_INTERRUPT_PENDING; +} + +/** + Allocate EfiACPIMemoryNVS below 4G memory address. + + This function allocates EfiACPIMemoryNVS below 4G memory address. + + @param 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 + ); + ASSERT_EFI_ERROR (Status); + + Buffer = (VOID *) (UINTN) Address; + ZeroMem (Buffer, Size); + + return Buffer; +} + +/** + Entry Point for PI SMM communication SMM driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable A Pointer to the EFI System Table. + + @retval EFI_SUCCESS + @return Others Some error occurs. +**/ +EFI_STATUS +EFIAPI +PiSmmCommunicationSmmEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch2; + EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext; + EFI_HANDLE DispatchHandle; + EFI_PHYSICAL_ADDRESS *BufferPtrAddress; + + // + // Register software SMI handler + // + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSwDispatch2ProtocolGuid, + NULL, + (VOID **)&SmmSwDispatch2 + ); + ASSERT_EFI_ERROR (Status); + + SmmSwDispatchContext.SwSmiInputValue = (UINTN)-1; + Status = SmmSwDispatch2->Register ( + SmmSwDispatch2, + PiSmmCommunicationHandler, + &SmmSwDispatchContext, + &DispatchHandle + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_INFO, "SmmCommunication SwSmi: %x\n", (UINTN)SmmSwDispatchContext.SwSmiInputValue)); + + BufferPtrAddress = AllocateAcpiNvsMemoryBelow4G (sizeof(EFI_PHYSICAL_ADDRESS)); + ASSERT (BufferPtrAddress != NULL); + DEBUG ((EFI_D_INFO, "SmmCommunication BufferPtrAddress: 0x%016lx, BufferPtr: 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress, *BufferPtrAddress)); + + // + // Save context + // + mSmmCommunicationContext.SwSmiNumber = (UINT32)SmmSwDispatchContext.SwSmiInputValue; + mSmmCommunicationContext.BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress; + SetCommunicationContext (); + + return Status; +} diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf new file mode 100644 index 000000000..2d4b46001 --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf @@ -0,0 +1,55 @@ +## @file +# PI SMM Communication SMM driver that saves SMM communication context +# for use by SMM Communication PEIM in the S3 boot mode. +# +# Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PiSmmCommunicationSmm + MODULE_UNI_FILE = PiSmmCommunicationSmm.uni + FILE_GUID = E21F35A8-42FF-4050-82D6-93F7CDFA7073 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = PiSmmCommunicationSmmEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + PiSmmCommunicationSmm.c + PiSmmCommunicationPrivate.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + SmmServicesTableLib + BaseLib + BaseMemoryLib + DebugLib + SmmMemLib + +[Ppis] + gEfiPeiSmmCommunicationPpiGuid ## UNDEFINED # SMM Configuration Table + +[Protocols] + gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmSwDispatch2ProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + PiSmmCommunicationSmmExtra.uni diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni new file mode 100644 index 000000000..cfb642e67 --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni @@ -0,0 +1,13 @@ +// /** @file +// PI SMM Communication SMM driver that saves SMM communication context +// for use by SMM Communication PEIM in the S3 boot mode. +// +// Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "PI SMM Communication SMM driver that saves SMM communication context" + +#string STR_MODULE_DESCRIPTION #language en-US "PI SMM Communication SMM driver that saves SMM communication context for use by SMM Communication PEIM in the S3 boot mode." diff --git a/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni new file mode 100644 index 000000000..7d9c2b679 --- /dev/null +++ b/roms/edk2/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// PiSmmCommunicationSmm Localized Strings and Content +// +// Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"SMM Communication SMM Driver" -- cgit 1.2.3-korg