diff options
author | Hongbin1 Zhang <hongbin1.zhang@intel.com> | 2024-05-09 10:06:09 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-08-28 15:25:27 +0000 |
commit | e98eca076af1793baf55bea26ca3bc6e20c52061 (patch) | |
tree | 2b198fc5643c17a15bff47517e903c2adff1d6ee /StandaloneMmPkg | |
parent | 8d764088ea3a182174d36caa9131198301515a89 (diff) | |
download | edk2-e98eca076af1793baf55bea26ca3bc6e20c52061.tar.gz edk2-e98eca076af1793baf55bea26ca3bc6e20c52061.tar.bz2 edk2-e98eca076af1793baf55bea26ca3bc6e20c52061.zip |
StandaloneMmPkg/MmIpl: Install MmCommunicationPpi
Install MmCommunicationPpi under PEI stage, PEIM could
use this PPI to communicate with MM handler
Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Wei6 Xu <wei6.xu@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
Diffstat (limited to 'StandaloneMmPkg')
3 files changed, 148 insertions, 1 deletions
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index 197e33cc3b..d92c2659ad 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -8,6 +8,119 @@ #include "StandaloneMmIplPei.h"
+EFI_PEI_MM_COMMUNICATION_PPI mMmCommunicationPpi = { Communicate };
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMmCommunicationPpiGuid,
+ &mMmCommunicationPpi
+};
+
+/**
+ 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_MM_COMMUNICATION_PPI instance.
+ @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM.
+ @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_MM_COMMUNICATION_PPI *This,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_MM_CONTROL_PPI *MmControl;
+ UINT8 SmiCommand;
+ UINTN Size;
+ UINTN TempCommSize;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_COMM_BUFFER *MmCommBuffer;
+ MM_COMM_BUFFER_STATUS *MmCommBufferStatus;
+
+ DEBUG ((DEBUG_INFO, "StandaloneMmIpl Communicate Enter\n"));
+
+ GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
+ if (GuidHob != NULL) {
+ MmCommBuffer = GET_GUID_HOB_DATA (GuidHob);
+ MmCommBufferStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)MmCommBuffer->Status;
+ } else {
+ DEBUG ((DEBUG_ERROR, "MmCommBuffer is not existed !!!\n"));
+ ASSERT (GuidHob != NULL);
+ return EFI_NOT_FOUND;
+ }
+
+ SmiCommand = 0;
+ Size = sizeof (SmiCommand);
+
+ //
+ // Check parameters
+ //
+ if ((CommBuffer == NULL) || (CommSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ TempCommSize = *CommSize;
+ //
+ // CommSize must hold HeaderGuid and MessageLength
+ //
+ if (TempCommSize < OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (TempCommSize > EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)) {
+ DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is over MAX (%d) size!", TempCommSize, EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem ((VOID *)(UINTN)MmCommBuffer->PhysicalStart, CommBuffer, TempCommSize);
+ MmCommBufferStatus->IsCommBufferValid = TRUE;
+
+ //
+ // Generate Software SMI
+ //
+ Status = PeiServicesLocatePpi (&gEfiPeiMmControlPpiGuid, 0, NULL, (VOID **)&MmControl);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = MmControl->Trigger (
+ (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (),
+ MmControl,
+ (INT8 *)&SmiCommand,
+ &Size,
+ FALSE,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Return status from software SMI
+ //
+ *CommSize = (UINTN)MmCommBufferStatus->ReturnBufferSize;
+
+ //
+ // Copy the returned data to the non-mmram buffer (CommBuffer)
+ //
+ CopyMem (CommBuffer, (VOID *)(MmCommBuffer->PhysicalStart), *CommSize);
+
+ Status = (EFI_STATUS)MmCommBufferStatus->ReturnStatus;
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "StandaloneMmIpl Communicate failed (%r)\n", Status));
+ } else {
+ MmCommBufferStatus->IsCommBufferValid = FALSE;
+ }
+
+ return Status;
+}
+
/**
Search all the available firmware volumes for MM Core driver.
@@ -431,5 +544,11 @@ StandaloneMmIplPeiEntry ( Status = ExecuteMmCoreFromMmram (MmCommBuffer);
ASSERT_EFI_ERROR (Status);
+ //
+ // Install MmCommunicationPpi
+ //
+ Status = PeiServicesInstallPpi (&mPpiList);
+ ASSERT_EFI_ERROR (Status);
+
return EFI_SUCCESS;
}
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index f099af5feb..c385d98ce4 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -20,5 +20,31 @@ #include <Library/BaseMemoryLib.h>
#include <Library/PeCoffLib.h>
#include <Library/CacheMaintenanceLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Ppi/MmControl.h>
+#include <Ppi/MmCommunication.h>
+#include <Protocol/MmCommunication.h>
+
+/**
+ 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_MM_COMMUNICATION_PPI instance.
+ @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM.
+ @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_MM_COMMUNICATION_PPI *This,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize
+ );
#endif
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index 0a03aa0af1..f462a10e35 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -47,9 +47,11 @@ gEfiSmmSmramMemoryGuid
[Ppis]
+ gEfiPeiMmControlPpiGuid
+ gEfiPeiMmCommunicationPpiGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages
[Depex]
- TRUE
+ gEfiPeiMmControlPpiGuid
|