summaryrefslogtreecommitdiff
path: root/StandaloneMmPkg
diff options
context:
space:
mode:
authorDun Tan <dun.tan@intel.com>2024-06-12 11:04:37 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-08-28 15:25:27 +0000
commitcf9b5684059e9740ff63da9af7bbc8172c9247dd (patch)
treea18f7d9c80f17f34465a1d3ecc5a3992dc089944 /StandaloneMmPkg
parenteef29d5100b4f4879d8280f5074ccc00e5067e01 (diff)
downloadedk2-cf9b5684059e9740ff63da9af7bbc8172c9247dd.zip
edk2-cf9b5684059e9740ff63da9af7bbc8172c9247dd.tar.gz
edk2-cf9b5684059e9740ff63da9af7bbc8172c9247dd.tar.bz2
StandaloneMmPkg: Install gEfiMmCommunication2ProtocolGuid
Install gEfiMmCommunication2ProtocolGuid in the MmCommunicationDxe driver. Signed-off-by: Dun Tan <dun.tan@intel.com>
Diffstat (limited to 'StandaloneMmPkg')
-rw-r--r--StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c196
-rw-r--r--StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h51
-rw-r--r--StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf13
3 files changed, 260 insertions, 0 deletions
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c
index a985d9b..e216de5 100644
--- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c
+++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c
@@ -9,6 +9,161 @@
#include "MmCommunicationDxe.h"
+//
+// PI 1.7 MM Communication Protocol 2 instance
+//
+EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
+ MmCommunicate2
+};
+
+MM_COMM_BUFFER mMmCommonBuffer;
+EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2;
+
+/**
+ Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+ This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ It convers pointer to new virtual address.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+MmVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EfiConvertPointer (0x0, (VOID **)&mMmCommonBuffer.Status);
+ EfiConvertPointer (0x0, (VOID **)&mMmCommonBuffer.PhysicalStart);
+ EfiConvertPointer (0x0, (VOID **)&mSmmControl2);
+}
+
+/**
+ Processes the communication buffer for Mm communication protocols.
+
+ This function encapsulates the common logic for handling communication buffers
+ used by MmCommunicate2 functions.
+
+ @param[in, out] CommBuffer Pointer to the MM communication buffer
+ @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.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+**/
+EFI_STATUS
+EFIAPI
+ProcessCommunicationBuffer (
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+ MM_COMM_BUFFER_STATUS *CommonBufferStatus;
+ UINTN BufferSize;
+
+ //
+ // Check parameters
+ //
+ if (CommBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)CommBuffer;
+ BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+
+ if (CommSize != NULL) {
+ ASSERT (*CommSize == BufferSize);
+ }
+
+ CommonBufferStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommonBuffer.Status;
+
+ //
+ // Copy the content at input CommBuffer to fixed MM communication buffer
+ // if CommBuffer is not equal to fixed MM communication buffer.
+ //
+ if ((UINTN)CommBuffer != mMmCommonBuffer.PhysicalStart) {
+ CopyMem ((VOID *)(UINTN)mMmCommonBuffer.PhysicalStart, CommBuffer, BufferSize);
+ }
+
+ CommonBufferStatus->IsCommBufferValid = TRUE;
+
+ //
+ // Generate Software SMI
+ //
+ Status = mSmmControl2->Trigger (mSmmControl2, NULL, NULL, FALSE, 0);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Copy the returned data to the non-mmram buffer (CommBuffer)
+ //
+ if ((UINTN)CommBuffer != mMmCommonBuffer.PhysicalStart) {
+ CopyMem (CommBuffer, (VOID *)(UINTN)mMmCommonBuffer.PhysicalStart, CommonBufferStatus->ReturnBufferSize);
+ }
+
+ //
+ // Retrieve BufferSize and return status from CommonBufferStatus
+ //
+ if (CommSize != NULL) {
+ *CommSize = CommonBufferStatus->ReturnBufferSize;
+ }
+
+ CommonBufferStatus->IsCommBufferValid = FALSE;
+
+ return CommonBufferStatus->ReturnStatus;
+}
+
+/**
+ 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.
+ @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.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate2 (
+ IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual,
+ IN OUT UINTN *CommSize OPTIONAL
+ )
+{
+ return ProcessCommunicationBuffer (CommBufferVirtual, CommSize);
+}
+
/**
The Entry Point for MmCommunicateDxe driver.
@@ -26,5 +181,46 @@ MmCommunicationEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_COMM_BUFFER *MmCommonBuffer;
+
+ //
+ // Locate gMmCommBufferHobGuid and cache the content
+ //
+ GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
+ ASSERT (GuidHob != NULL);
+ MmCommonBuffer = GET_GUID_HOB_DATA (GuidHob);
+ CopyMem (&mMmCommonBuffer, MmCommonBuffer, sizeof (MM_COMM_BUFFER));
+
+ //
+ // Get SMM Control2 Protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID **)&mSmmControl2);
+ ASSERT_EFI_ERROR (Status);
+
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiMmCommunication2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mMmCommunication2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register the event to convert the pointer for runtime.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ MmVirtualAddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
return EFI_SUCCESS;
}
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h
index 1e98aa1..90cab5e 100644
--- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h
+++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h
@@ -8,4 +8,55 @@
#ifndef MM_COMMUNICATION_DXE_H_
#define MM_COMMUNICATION_DXE_H_
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeLib.h>
+
+#include <Protocol/SmmControl2.h>
+#include <Protocol/MmCommunication2.h>
+
+#include <Guid/MmCommBuffer.h>
+#include <Guid/EventGroup.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_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.
+ @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.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate2 (
+ IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual,
+ IN OUT UINTN *CommSize OPTIONAL
+ );
+
#endif
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf
index acfc5e4..55c6611 100644
--- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf
+++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf
@@ -29,9 +29,22 @@
[LibraryClasses]
UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+ HobLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiRuntimeLib
[Guids]
+ gMmCommBufferHobGuid
+ gEfiEventVirtualAddressChangeGuid
[Protocols]
+ gEfiMmCommunication2ProtocolGuid
+ gEfiSmmControl2ProtocolGuid
[Depex]
+ gEfiSmmControl2ProtocolGuid