summaryrefslogtreecommitdiff
path: root/Core/MdeModulePkg/Universal/FaultTolerantWritePei
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2017-04-27 11:05:07 +0800
committerGuo Mang <mang.guo@intel.com>2017-04-27 11:05:07 +0800
commitc23f114d3cfbb29b8734b87213d1ec0de404197b (patch)
tree4f3612573be055139a88213559212a40b7862fee /Core/MdeModulePkg/Universal/FaultTolerantWritePei
parent001e57a103fce87245bfb7ae9c32ffb499a64135 (diff)
downloadedk2-platforms-c23f114d3cfbb29b8734b87213d1ec0de404197b.tar.xz
MdeModulePkg: Move to new location
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Core/MdeModulePkg/Universal/FaultTolerantWritePei')
-rw-r--r--Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.c321
-rw-r--r--Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf67
-rw-r--r--Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.uni21
-rw-r--r--Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePeiExtra.uni19
4 files changed, 428 insertions, 0 deletions
diff --git a/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.c b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.c
new file mode 100644
index 0000000000..14e18e5ae2
--- /dev/null
+++ b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.c
@@ -0,0 +1,321 @@
+/** @file
+ This driver installs gEdkiiFaultTolerantWriteGuid PPI to inform
+ the check for FTW last write data has been done.
+
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+
+#include <Guid/SystemNvDataGuid.h>
+#include <Guid/FaultTolerantWrite.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEdkiiFaultTolerantWriteGuid,
+ NULL
+};
+
+/**
+ Get the last Write Header pointer.
+ The last write header is the header whose 'complete' state hasn't been set.
+ After all, this header may be a EMPTY header entry for next Allocate.
+
+
+ @param FtwWorkSpaceHeader Pointer of the working block header
+ @param FtwWorkSpaceSize Size of the work space
+ @param FtwWriteHeader Pointer to retrieve the last write header
+
+ @retval EFI_SUCCESS Get the last write record successfully
+ @retval EFI_ABORTED The FTW work space is damaged
+
+**/
+EFI_STATUS
+FtwGetLastWriteHeader (
+ IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader,
+ IN UINTN FtwWorkSpaceSize,
+ OUT EFI_FAULT_TOLERANT_WRITE_HEADER **FtwWriteHeader
+ )
+{
+ UINTN Offset;
+ EFI_FAULT_TOLERANT_WRITE_HEADER *FtwHeader;
+
+ *FtwWriteHeader = NULL;
+ FtwHeader = (EFI_FAULT_TOLERANT_WRITE_HEADER *) (FtwWorkSpaceHeader + 1);
+ Offset = sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);
+
+ while (FtwHeader->Complete == FTW_VALID_STATE) {
+ Offset += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites, FtwHeader->PrivateDataSize);
+ //
+ // If Offset exceed the FTW work space boudary, return error.
+ //
+ if (Offset >= FtwWorkSpaceSize) {
+ *FtwWriteHeader = FtwHeader;
+ return EFI_ABORTED;
+ }
+
+ FtwHeader = (EFI_FAULT_TOLERANT_WRITE_HEADER *) ((UINT8 *) FtwWorkSpaceHeader + Offset);
+ }
+ //
+ // Last write header is found
+ //
+ *FtwWriteHeader = FtwHeader;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get the last Write Record pointer. The last write Record is the Record
+ whose DestinationCompleted state hasn't been set. After all, this Record
+ may be a EMPTY record entry for next write.
+
+
+ @param FtwWriteHeader Pointer to the write record header
+ @param FtwWriteRecord Pointer to retrieve the last write record
+
+ @retval EFI_SUCCESS Get the last write record successfully
+ @retval EFI_ABORTED The FTW work space is damaged
+
+**/
+EFI_STATUS
+FtwGetLastWriteRecord (
+ IN EFI_FAULT_TOLERANT_WRITE_HEADER *FtwWriteHeader,
+ OUT EFI_FAULT_TOLERANT_WRITE_RECORD **FtwWriteRecord
+ )
+{
+ UINTN Index;
+ EFI_FAULT_TOLERANT_WRITE_RECORD *FtwRecord;
+
+ *FtwWriteRecord = NULL;
+ FtwRecord = (EFI_FAULT_TOLERANT_WRITE_RECORD *) (FtwWriteHeader + 1);
+
+ //
+ // Try to find the last write record "that has not completed"
+ //
+ for (Index = 0; Index < FtwWriteHeader->NumberOfWrites; Index += 1) {
+ if (FtwRecord->DestinationComplete != FTW_VALID_STATE) {
+ //
+ // The last write record is found
+ //
+ *FtwWriteRecord = FtwRecord;
+ return EFI_SUCCESS;
+ }
+
+ FtwRecord++;
+
+ if (FtwWriteHeader->PrivateDataSize != 0) {
+ FtwRecord = (EFI_FAULT_TOLERANT_WRITE_RECORD *) ((UINTN) FtwRecord + (UINTN) FtwWriteHeader->PrivateDataSize);
+ }
+ }
+ //
+ // if Index == NumberOfWrites, then
+ // the last record has been written successfully,
+ // but the Header->Complete Flag has not been set.
+ // also return the last record.
+ //
+ if (Index == FtwWriteHeader->NumberOfWrites) {
+ *FtwWriteRecord = (EFI_FAULT_TOLERANT_WRITE_RECORD *) ((UINTN) FtwRecord - FTW_RECORD_SIZE (FtwWriteHeader->PrivateDataSize));
+ return EFI_SUCCESS;
+ }
+
+ return EFI_ABORTED;
+}
+
+/**
+ Check to see if it is a valid work space.
+
+
+ @param WorkingHeader Pointer of working block header
+ @param WorkingLength Working block length
+
+ @retval TRUE The work space is valid.
+ @retval FALSE The work space is invalid.
+
+**/
+BOOLEAN
+IsValidWorkSpace (
+ IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader,
+ IN UINTN WorkingLength
+ )
+{
+ UINT8 Data;
+
+ if (WorkingHeader == NULL) {
+ return FALSE;
+ }
+
+ if ((WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) || (WorkingHeader->WorkingBlockInvalid == FTW_VALID_STATE)) {
+ DEBUG ((EFI_D_ERROR, "FtwPei: Work block header valid bit check error\n"));
+ return FALSE;
+ }
+
+ if (WorkingHeader->WriteQueueSize != (WorkingLength - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER))) {
+ DEBUG ((EFI_D_ERROR, "FtwPei: Work block header WriteQueueSize check error\n"));
+ return FALSE;
+ }
+
+ //
+ // Check signature with gEdkiiWorkingBlockSignatureGuid
+ //
+ if (!CompareGuid (&gEdkiiWorkingBlockSignatureGuid, &WorkingHeader->Signature)) {
+ DEBUG ((EFI_D_ERROR, "FtwPei: Work block header signature check error, it should be gEdkiiWorkingBlockSignatureGuid\n"));
+ //
+ // To be compatible with old signature gEfiSystemNvDataFvGuid.
+ //
+ if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {
+ return FALSE;
+ } else {
+ Data = *(UINT8 *) (WorkingHeader + 1);
+ if (Data != 0xff) {
+ DEBUG ((EFI_D_ERROR, "FtwPei: Old format FTW structure can't be handled\n"));
+ ASSERT (FALSE);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+
+}
+
+/**
+ Main entry for Fault Tolerant Write PEIM.
+
+ @param[in] FileHandle Handle of the file being invoked.
+ @param[in] PeiServices Pointer to PEI Services table.
+
+ @retval EFI_SUCCESS If the interface could be successfully installed
+ @retval Others Returned from PeiServicesInstallPpi()
+
+**/
+EFI_STATUS
+EFIAPI
+PeimFaultTolerantWriteInitialize (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkingBlockHeader;
+ EFI_FAULT_TOLERANT_WRITE_HEADER *FtwLastWriteHeader;
+ EFI_FAULT_TOLERANT_WRITE_RECORD *FtwLastWriteRecord;
+ EFI_PHYSICAL_ADDRESS WorkSpaceAddress;
+ UINTN WorkSpaceLength;
+ EFI_PHYSICAL_ADDRESS SpareAreaAddress;
+ UINTN SpareAreaLength;
+ EFI_PHYSICAL_ADDRESS WorkSpaceInSpareArea;
+ FAULT_TOLERANT_WRITE_LAST_WRITE_DATA FtwLastWrite;
+
+ FtwWorkingBlockHeader = NULL;
+ FtwLastWriteHeader = NULL;
+ FtwLastWriteRecord = NULL;
+
+ WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageFtwWorkingBase64);
+ if (WorkSpaceAddress == 0) {
+ WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
+ }
+ WorkSpaceLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
+
+ SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageFtwSpareBase64);
+ if (SpareAreaAddress == 0) {
+ SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwSpareBase);
+ }
+ SpareAreaLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwSpareSize);
+
+ //
+ // The address of FTW working base and spare base must not be 0.
+ //
+ ASSERT ((WorkSpaceAddress != 0) && (SpareAreaAddress != 0));
+
+ FtwWorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (UINTN) WorkSpaceAddress;
+ if (IsValidWorkSpace (FtwWorkingBlockHeader, WorkSpaceLength)) {
+ Status = FtwGetLastWriteHeader (
+ FtwWorkingBlockHeader,
+ WorkSpaceLength,
+ &FtwLastWriteHeader
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = FtwGetLastWriteRecord (
+ FtwLastWriteHeader,
+ &FtwLastWriteRecord
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ ASSERT (FtwLastWriteRecord != NULL);
+ if ((FtwLastWriteRecord->SpareComplete == FTW_VALID_STATE) && (FtwLastWriteRecord->DestinationComplete != FTW_VALID_STATE)) {
+ //
+ // If FTW last write was still in progress with SpareComplete set and DestinationComplete not set.
+ // It means the target buffer has been backed up in spare block, then target block has been erased,
+ // but the target buffer has not been writen in target block from spare block, we need to build
+ // FAULT_TOLERANT_WRITE_LAST_WRITE_DATA GUID hob to hold the FTW last write data.
+ //
+ FtwLastWrite.TargetAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) ((INT64) SpareAreaAddress + FtwLastWriteRecord->RelativeOffset);
+ FtwLastWrite.SpareAddress = SpareAreaAddress;
+ FtwLastWrite.Length = SpareAreaLength;
+ DEBUG ((
+ EFI_D_INFO,
+ "FtwPei last write data: TargetAddress - 0x%x SpareAddress - 0x%x Length - 0x%x\n",
+ (UINTN) FtwLastWrite.TargetAddress,
+ (UINTN) FtwLastWrite.SpareAddress,
+ (UINTN) FtwLastWrite.Length));
+ BuildGuidDataHob (&gEdkiiFaultTolerantWriteGuid, (VOID *) &FtwLastWrite, sizeof (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA));
+ }
+ }
+ } else {
+ FtwWorkingBlockHeader = NULL;
+ //
+ // If the working block workspace is not valid, try to find workspace in the spare block.
+ //
+ WorkSpaceInSpareArea = SpareAreaAddress + SpareAreaLength - WorkSpaceLength;
+ while (WorkSpaceInSpareArea >= SpareAreaAddress) {
+ if (CompareGuid (&gEdkiiWorkingBlockSignatureGuid, (EFI_GUID *) (UINTN) WorkSpaceInSpareArea)) {
+ //
+ // Found the workspace.
+ //
+ DEBUG ((EFI_D_INFO, "FtwPei: workspace in spare block is at 0x%x.\n", (UINTN) WorkSpaceInSpareArea));
+ FtwWorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (UINTN) WorkSpaceInSpareArea;
+ break;
+ }
+ WorkSpaceInSpareArea = WorkSpaceInSpareArea - sizeof (EFI_GUID);
+ }
+ if ((FtwWorkingBlockHeader != NULL) && IsValidWorkSpace (FtwWorkingBlockHeader, WorkSpaceLength)) {
+ //
+ // It was workspace self reclaim, build FAULT_TOLERANT_WRITE_LAST_WRITE_DATA GUID hob for it.
+ //
+ FtwLastWrite.TargetAddress = WorkSpaceAddress - (WorkSpaceInSpareArea - SpareAreaAddress);
+ FtwLastWrite.SpareAddress = SpareAreaAddress;
+ FtwLastWrite.Length = SpareAreaLength;
+ DEBUG ((
+ EFI_D_INFO,
+ "FtwPei last write data: TargetAddress - 0x%x SpareAddress - 0x%x Length - 0x%x\n",
+ (UINTN) FtwLastWrite.TargetAddress,
+ (UINTN) FtwLastWrite.SpareAddress,
+ (UINTN) FtwLastWrite.Length));
+ BuildGuidDataHob (&gEdkiiFaultTolerantWriteGuid, (VOID *) &FtwLastWrite, sizeof (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA));
+ } else {
+ //
+ // Both are invalid.
+ //
+ DEBUG ((EFI_D_ERROR, "FtwPei: Both working and spare block are invalid.\n"));
+ }
+ }
+
+ //
+ // Install gEdkiiFaultTolerantWriteGuid PPI to inform the check for FTW last write data has been done.
+ //
+ return PeiServicesInstallPpi (&mPpiListVariable);
+}
diff --git a/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
new file mode 100644
index 0000000000..12b26604e2
--- /dev/null
+++ b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
@@ -0,0 +1,67 @@
+## @file
+# Fault Tolerant Write PEI Driver.
+#
+# This module installs gEdkiiFaultTolerantWriteGuid PPI to inform the check for FTW last write data has been done.
+#
+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FaultTolerantWritePei
+ MODULE_UNI_FILE = FaultTolerantWritePei.uni
+ FILE_GUID = AAC33064-9ED0-4b89-A5AD-3EA767960B22
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeimFaultTolerantWriteInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ FaultTolerantWritePei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ PeiServicesLib
+ BaseLib
+ DebugLib
+ HobLib
+ BaseMemoryLib
+ PcdLib
+
+[Guids]
+ ## SOMETIMES_PRODUCES ## HOB
+ ## PRODUCES ## GUID # Install ppi
+ gEdkiiFaultTolerantWriteGuid
+ gEdkiiWorkingBlockSignatureGuid ## SOMETIMES_CONSUMES ## GUID
+ gEfiSystemNvDataFvGuid ## SOMETIMES_CONSUMES ## GUID
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ FaultTolerantWritePeiExtra.uni
diff --git a/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.uni b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.uni
new file mode 100644
index 0000000000..49dcc7b2bc
--- /dev/null
+++ b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.uni
@@ -0,0 +1,21 @@
+// /** @file
+// Fault Tolerant Write PEI Driver.
+//
+// This module installs gEdkiiFaultTolerantWriteGuid PPI to inform the check for FTW last write data has been done.
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "This module installs gEdkiiFaultTolerantWriteGuid PPI to inform the check for FTW last write data has been done."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module installs gEdkiiFaultTolerantWriteGuid PPI to inform the check for FTW last write data has been done."
+
diff --git a/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePeiExtra.uni b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePeiExtra.uni
new file mode 100644
index 0000000000..b9fd9425a9
--- /dev/null
+++ b/Core/MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePeiExtra.uni
@@ -0,0 +1,19 @@
+// /** @file
+// FaultTolerantWritePei Localized Strings and Content
+//
+// Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"FaultTolerantWrite PEI Module"
+
+