/** @file\r
\r
- Implement the Fault Tolerant Write (FTW) protocol based on SMM FTW \r
+ Implement the Fault Tolerant Write (FTW) protocol based on SMM FTW\r
module.\r
\r
-Copyright (c) 2011, Intel Corporation. All rights reserved. <BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved. <BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
**/\r
\r
IN UINTN Function\r
)\r
{\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; \r
- SMM_FTW_COMMUNICATE_FUNCTION_HEADER *SmmFtwFunctionHeader; \r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
+ SMM_FTW_COMMUNICATE_FUNCTION_HEADER *SmmFtwFunctionHeader;\r
\r
//\r
// The whole buffer size: SMM_COMMUNICATE_HEADER_SIZE + SMM_FTW_COMMUNICATE_HEADER_SIZE + DataSize.\r
//\r
SmmCommunicateHeader = AllocateZeroPool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FTW_COMMUNICATE_HEADER_SIZE);\r
ASSERT (SmmCommunicateHeader != NULL);\r
- \r
+\r
//\r
// Prepare data buffer.\r
//\r
CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmFaultTolerantWriteProtocolGuid);\r
SmmCommunicateHeader->MessageLength = DataSize + SMM_FTW_COMMUNICATE_HEADER_SIZE;\r
- \r
+\r
SmmFtwFunctionHeader = (SMM_FTW_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data;\r
SmmFtwFunctionHeader->Function = Function;\r
\r
*CommunicateBuffer = SmmCommunicateHeader;\r
if (DataPtr != NULL) {\r
*DataPtr = SmmFtwFunctionHeader->Data;\r
- } \r
+ }\r
}\r
\r
\r
/**\r
Send the data in communicate buffer to SMI handler and get response.\r
\r
- @param[out] SmmCommunicateHeader The communicate buffer.\r
+ @param[in, out] SmmCommunicateHeader The communicate buffer.\r
@param[in] DataSize The payload size.\r
- \r
+\r
**/\r
EFI_STATUS\r
SendCommunicateBuffer (\r
- IN EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader,\r
+ IN OUT EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader,\r
IN UINTN DataSize\r
)\r
{\r
EFI_STATUS Status;\r
UINTN CommSize;\r
- SMM_FTW_COMMUNICATE_FUNCTION_HEADER *SmmFtwFunctionHeader; \r
- \r
+ SMM_FTW_COMMUNICATE_FUNCTION_HEADER *SmmFtwFunctionHeader;\r
+\r
CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FTW_COMMUNICATE_HEADER_SIZE;\r
Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, &CommSize);\r
ASSERT_EFI_ERROR (Status);\r
/**\r
Get the FvbBaseAddress and FvbAttributes from the FVB handle FvbHandle.\r
\r
- @param[in] FvBlockHandle The handle of FVB protocol that provides services.\r
- @param[in] FvbBaseAddress The base address of the FVB attached with FvBlockHandle.\r
- @param[out] FvbAttributes The attributes of the FVB attached with FvBlockHandle.\r
- \r
+ @param[in] FvbHandle The handle of FVB protocol that provides services.\r
+ @param[out] FvbBaseAddress The base address of the FVB attached with FvbHandle.\r
+ @param[out] FvbAttributes The attributes of the FVB attached with FvbHandle.\r
+\r
@retval EFI_SUCCESS The function completed successfully.\r
@retval Others The function could not complete successfully.\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
Status = Fvb->GetPhysicalAddress (Fvb, FvbBaseAddress);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
Status = Fvb->GetAttributes (Fvb, FvbAttributes);\r
- return Status; \r
+ return Status;\r
}\r
\r
\r
{\r
EFI_STATUS Status;\r
UINTN PayloadSize;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; \r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *SmmFtwBlockSizeHeader;\r
\r
//\r
//\r
PayloadSize = sizeof (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER);\r
InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwBlockSizeHeader, PayloadSize, FTW_FUNCTION_GET_MAX_BLOCK_SIZE);\r
- \r
+\r
//\r
// Send data to SMM.\r
//\r
//\r
// Get data from SMM\r
//\r
- *BlockSize = SmmFtwBlockSizeHeader->BlockSize; \r
+ *BlockSize = SmmFtwBlockSizeHeader->BlockSize;\r
FreePool (SmmCommunicateHeader);\r
- \r
+\r
return Status;\r
}\r
\r
{\r
EFI_STATUS Status;\r
UINTN PayloadSize;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; \r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
SMM_FTW_ALLOCATE_HEADER *SmmFtwAllocateHeader;\r
\r
//\r
InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwAllocateHeader, PayloadSize, FTW_FUNCTION_ALLOCATE);\r
CopyGuid (&SmmFtwAllocateHeader->CallerId, CallerId);\r
SmmFtwAllocateHeader->PrivateDataSize = PrivateDataSize;\r
- SmmFtwAllocateHeader->NumberOfWrites = NumberOfWrites; \r
- \r
+ SmmFtwAllocateHeader->NumberOfWrites = NumberOfWrites;\r
+\r
//\r
// Send data to SMM.\r
//\r
{\r
EFI_STATUS Status;\r
UINTN PayloadSize;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; \r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
SMM_FTW_WRITE_HEADER *SmmFtwWriteHeader;\r
\r
//\r
InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwWriteHeader, PayloadSize, FTW_FUNCTION_WRITE);\r
\r
//\r
- // FvBlockHandle can not be used in SMM environment. Here we get the FVB protocol first, then get FVB base address \r
+ // FvBlockHandle can not be used in SMM environment. Here we get the FVB protocol first, then get FVB base address\r
// and its attribute. Send these information to SMM handler, the SMM handler will find the proper FVB to write data.\r
//\r
Status = ConvertFvbHandle (FvBlockHandle, &SmmFtwWriteHeader->FvbBaseAddress, &SmmFtwWriteHeader->FvbAttributes);\r
FreePool (SmmCommunicateHeader);\r
return EFI_ABORTED;\r
}\r
- \r
+\r
SmmFtwWriteHeader->Lba = Lba;\r
- SmmFtwWriteHeader->Offset = Offset; \r
+ SmmFtwWriteHeader->Offset = Offset;\r
SmmFtwWriteHeader->Length = Length;\r
CopyMem (SmmFtwWriteHeader->Data, Buffer, Length);\r
if (PrivateData == NULL) {\r
// Send data to SMM.\r
//\r
Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);\r
- FreePool (SmmCommunicateHeader); \r
+ FreePool (SmmCommunicateHeader);\r
return Status;\r
}\r
\r
{\r
EFI_STATUS Status;\r
UINTN PayloadSize;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; \r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
SMM_FTW_RESTART_HEADER *SmmFtwRestartHeader;\r
- \r
+\r
//\r
// Initialize the communicate buffer.\r
//\r
PayloadSize = sizeof (SMM_FTW_RESTART_HEADER);\r
- InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwRestartHeader, PayloadSize, FTW_FUNCTION_RESTART); \r
+ InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwRestartHeader, PayloadSize, FTW_FUNCTION_RESTART);\r
\r
//\r
- // FvBlockHandle can not be used in SMM environment. Here we get the FVB protocol first, then get FVB base address \r
+ // FvBlockHandle can not be used in SMM environment. Here we get the FVB protocol first, then get FVB base address\r
// and its attribute. Send these information to SMM handler, the SMM handler will find the proper FVB to write data.\r
//\r
Status = ConvertFvbHandle (FvBlockHandle, &SmmFtwRestartHeader->FvbBaseAddress, &SmmFtwRestartHeader->FvbAttributes);\r
if (EFI_ERROR (Status)) {\r
- FreePool (SmmCommunicateHeader); \r
+ FreePool (SmmCommunicateHeader);\r
return EFI_ABORTED;\r
}\r
\r
// Send data to SMM.\r
//\r
Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);\r
- FreePool (SmmCommunicateHeader); \r
+ FreePool (SmmCommunicateHeader);\r
return Status;\r
}\r
\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; \r
- \r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
+\r
//\r
// Initialize the communicate buffer.\r
//\r
InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, NULL, 0, FTW_FUNCTION_ABORT);\r
- \r
+\r
//\r
// Send data to SMM.\r
//\r
Status = SendCommunicateBuffer (SmmCommunicateHeader, 0);\r
\r
- FreePool (SmmCommunicateHeader); \r
+ FreePool (SmmCommunicateHeader);\r
return Status;\r
}\r
\r
{\r
EFI_STATUS Status;\r
UINTN PayloadSize;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; \r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
SMM_FTW_GET_LAST_WRITE_HEADER *SmmFtwGetLastWriteHeader;\r
\r
//\r
// Get data from SMM\r
//\r
*PrivateDataSize = SmmFtwGetLastWriteHeader->PrivateDataSize;\r
- if (!EFI_ERROR (Status)) {\r
+ if (Status == EFI_SUCCESS || Status == EFI_BUFFER_TOO_SMALL) {\r
*Lba = SmmFtwGetLastWriteHeader->Lba;\r
- *Offset = SmmFtwGetLastWriteHeader->Offset; \r
+ *Offset = SmmFtwGetLastWriteHeader->Offset;\r
*Length = SmmFtwGetLastWriteHeader->Length;\r
*Complete = SmmFtwGetLastWriteHeader->Complete;\r
CopyGuid (CallerId, &SmmFtwGetLastWriteHeader->CallerId);\r
- CopyMem (PrivateData, SmmFtwGetLastWriteHeader->Data, *PrivateDataSize);\r
+ if (Status == EFI_SUCCESS) {\r
+ CopyMem (PrivateData, SmmFtwGetLastWriteHeader->Data, *PrivateDataSize);\r
+ }\r
+ } else if (Status == EFI_NOT_FOUND) {\r
+ *Complete = SmmFtwGetLastWriteHeader->Complete;\r
}\r
\r
- FreePool (SmmCommunicateHeader); \r
+ FreePool (SmmCommunicateHeader);\r
return Status;\r
}\r
\r
//\r
// Just return to avoid install SMM FaultTolerantWriteProtocol again\r
// if Fault Tolerant Write protocol had been installed.\r
- // \r
+ //\r
Status = gBS->LocateProtocol (&gEfiFaultTolerantWriteProtocolGuid, NULL, (VOID **)&FtwProtocol);\r
if (!EFI_ERROR (Status)) {\r
return;\r
}\r
- \r
+\r
Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);\r
ASSERT_EFI_ERROR (Status);\r
\r
&mFaultTolerantWriteDriver\r
);\r
ASSERT_EFI_ERROR (Status);\r
- \r
+\r
Status = gBS->CloseEvent (Event);\r
- ASSERT_EFI_ERROR (Status); \r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
\r
//\r
EfiCreateProtocolNotifyEvent (\r
&gEfiSmmFaultTolerantWriteProtocolGuid,\r
- TPL_CALLBACK, \r
- SmmFtwReady, \r
- NULL, \r
+ TPL_CALLBACK,\r
+ SmmFtwReady,\r
+ NULL,\r
&SmmFtwRegistration\r
);\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r