StandaloneMmPkg: MmCommunicationDxe: Add EFI_MM_COMMUNICATION3_PROTOCOL REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3398 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3430 This change added support of installing `EFI_MM_COMMUNICATION3_PROTOCOL`. MmCommunicate v3 routine will no longer need to supply buffer length in the input parameters but instead inference from the returned communicate buffer. Signed-off-by: Kun Qin <kuqin12@gmail.com>
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c index 7b1e063..ba0b2ec 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c
@@ -10,6 +10,13 @@ #include "MmCommunicationDxe.h" // +// PI 1.9 MM Communication Protocol 3 instance +// +EFI_MM_COMMUNICATION3_PROTOCOL mMmCommunication3 = { + MmCommunicate3 +}; + +// // PI 1.7 MM Communication Protocol 2 instance // EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = { @@ -260,10 +267,11 @@ IN OUT UINTN *CommSize OPTIONAL ) { - EFI_STATUS Status; - EFI_MM_COMMUNICATE_HEADER *CommunicateHeader; - MM_COMM_BUFFER_STATUS *CommonBufferStatus; - UINTN BufferSize; + EFI_STATUS Status; + EFI_MM_COMMUNICATE_HEADER *CommunicateHeader; + EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeaderV3; + MM_COMM_BUFFER_STATUS *CommonBufferStatus; + UINTN BufferSize; // // Check parameters @@ -273,7 +281,16 @@ } CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)CommBuffer; - BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength; + if (CompareGuid (&CommunicateHeader->HeaderGuid, &gEfiMmCommunicateHeaderV3Guid)) { + CommunicateHeaderV3 = (EFI_MM_COMMUNICATE_HEADER_V3 *)CommBuffer; + if (CommunicateHeaderV3->BufferSize < sizeof (EFI_MM_COMMUNICATE_HEADER_V3) + CommunicateHeaderV3->MessageSize) { + return EFI_INVALID_PARAMETER; + } + + BufferSize = ((EFI_MM_COMMUNICATE_HEADER_V3 *)CommBuffer)->BufferSize; + } else { + BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength; + } if (CommSize != NULL) { ASSERT (*CommSize == BufferSize); @@ -323,6 +340,38 @@ This function provides a service to send and receive messages from a registered UEFI service. + @param[in] This The EFI_MM_COMMUNICATION3_PROTOCOL instance. + @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must + start with EFI_MM_COMMUNICATE_HEADER_V3. + @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must + start with EFI_MM_COMMUNICATE_HEADER_V3. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL. + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. + If this error is returned, the MessageSize field + in the CommBuffer header, are updated to reflect + the maximum payload size the implementation can accommodate. + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter are in address range + that cannot be accessed by the MM environment. + +**/ +EFI_STATUS +EFIAPI +MmCommunicate3 ( + IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This, + IN OUT VOID *CommBufferPhysical, + IN OUT VOID *CommBufferVirtual + ) +{ + return ProcessCommunicationBuffer (CommBufferVirtual, NULL); +} + +/** + 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_MM_COMMUNICATION_PROTOCOL instance. @param[in, out] CommBufferPhysical Physical address of the MM communication buffer. @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer. @@ -435,6 +484,14 @@ Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, + &gEfiMmCommunication3ProtocolGuid, + EFI_NATIVE_INTERFACE, + &mMmCommunication3 + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->InstallProtocolInterface ( + &Handle, &gEfiMmCommunication2ProtocolGuid, EFI_NATIVE_INTERFACE, &mMmCommunication2
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h index d84d821..3b399da 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h
@@ -22,6 +22,7 @@ #include <Library/ReportStatusCodeLib.h> #include <Protocol/SmmControl2.h> +#include <Protocol/MmCommunication3.h> #include <Protocol/MmCommunication2.h> #include <Protocol/MmCommunication.h> #include <Protocol/DxeMmReadyToLock.h> @@ -54,6 +55,35 @@ This function provides a service to send and receive messages from a registered UEFI service. + @param[in] This The EFI_MM_COMMUNICATION3_PROTOCOL instance. + @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must + start with EFI_MM_COMMUNICATE_HEADER_V3. + @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must + start with EFI_MM_COMMUNICATE_HEADER_V3. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL. + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. + If this error is returned, the MessageSize field + in the CommBuffer header, are updated to reflect + the maximum payload size the implementation can accommodate. + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter are in address range + that cannot be accessed by the MM environment. + +**/ +EFI_STATUS +EFIAPI +MmCommunicate3 ( + IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This, + IN OUT VOID *CommBufferPhysical, + IN OUT VOID *CommBufferVirtual + ); + +/** + 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_MM_COMMUNICATION_PROTOCOL instance. @param[in, out] CommBufferPhysical Physical address of the MM communication buffer. @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer.
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf index 821df02..dd5a0b1 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf
@@ -44,8 +44,10 @@ gEfiEventVirtualAddressChangeGuid gEfiEndOfDxeEventGroupGuid gEfiEventExitBootServicesGuid + gEfiMmCommunicateHeaderV3Guid [Protocols] + gEfiMmCommunication3ProtocolGuid gEfiMmCommunication2ProtocolGuid gEfiSmmControl2ProtocolGuid gEfiMmCommunicationProtocolGuid