after SetVirtualAddressMap().\r
\r
@param[in] This The EFI_SMM_COMMUNICATION_PROTOCOL instance.\r
- @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM.\r
- @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data\r
+ @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM.\r
+ @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data\r
being returned. Zero if the handler does not wish to reply with any data.\r
+ This parameter is optional and may be NULL.\r
\r
@retval EFI_SUCCESS The message was successfully posted.\r
@retval EFI_INVALID_PARAMETER The CommBuffer was NULL.\r
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.\r
+ If this error is returned, the MessageLength field\r
+ in the CommBuffer header or the integer pointed by\r
+ CommSize, are updated to reflect the maximum payload\r
+ size the implementation can accommodate.\r
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,\r
+ if not omitted, are in address range that cannot be\r
+ accessed by the MM environment.\r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
SmmCommunicationCommunicate (\r
IN CONST EFI_SMM_COMMUNICATION_PROTOCOL *This,\r
IN OUT VOID *CommBuffer,\r
- IN OUT UINTN *CommSize\r
+ IN OUT UINTN *CommSize OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;\r
BOOLEAN OldInSmm;\r
+ UINTN TempCommSize;\r
\r
//\r
// Check parameters\r
//\r
- if ((CommBuffer == NULL) || (CommSize == NULL)) {\r
+ if (CommBuffer == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- //\r
- // CommSize must hold HeaderGuid and MessageLength\r
- //\r
- if (*CommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) {\r
- return EFI_INVALID_PARAMETER;\r
+ CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) CommBuffer;\r
+\r
+ if (CommSize == NULL) {\r
+ TempCommSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;\r
+ } else {\r
+ TempCommSize = *CommSize;\r
+ //\r
+ // CommSize must hold HeaderGuid and MessageLength\r
+ //\r
+ if (TempCommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
}\r
\r
//\r
// Put arguments for Software SMI in gSmmCorePrivate\r
//\r
gSmmCorePrivate->CommunicationBuffer = CommBuffer;\r
- gSmmCorePrivate->BufferSize = *CommSize;\r
+ gSmmCorePrivate->BufferSize = TempCommSize;\r
\r
//\r
// Generate Software SMI\r
//\r
// Return status from software SMI \r
//\r
- *CommSize = gSmmCorePrivate->BufferSize;\r
+ if (CommSize != NULL) {\r
+ *CommSize = gSmmCorePrivate->BufferSize;\r
+ }\r
return gSmmCorePrivate->ReturnStatus;\r
}\r
\r
//\r
// If we are in SMM, then the execution mode must be physical, which means that\r
// OS established virtual addresses can not be used. If SetVirtualAddressMap()\r
- // has been called, then a direct invocation of the Software SMI is not \r
- // not allowed so return EFI_INVALID_PARAMETER.\r
+ // has been called, then a direct invocation of the Software SMI is not allowed,\r
+ // so return EFI_INVALID_PARAMETER.\r
//\r
if (EfiGoneVirtual()) {\r
return EFI_INVALID_PARAMETER;\r
//\r
// Before SetVirtualAddressMap(), we are in SMM or SMRAM is open and unlocked, call SmiManage() directly.\r
//\r
- CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommBuffer;\r
- *CommSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
+ TempCommSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
Status = gSmmCorePrivate->Smst->SmiManage (\r
&CommunicateHeader->HeaderGuid, \r
NULL, \r
CommunicateHeader->Data, \r
- CommSize\r
+ &TempCommSize\r
);\r
-\r
- //\r
- // Update CommunicationBuffer, BufferSize and ReturnStatus\r
- // Communicate service finished, reset the pointer to CommBuffer to NULL\r
- //\r
- *CommSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
+ TempCommSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
+ if (CommSize != NULL) {\r
+ *CommSize = TempCommSize;\r
+ }\r
\r
//\r
// Restore original InSmm state\r