From 53c71d097b13311e2bd8dda6ae54b5766a1c7d6d Mon Sep 17 00:00:00 2001 From: qhuang8 Date: Wed, 18 Jul 2007 14:32:48 +0000 Subject: Adjust directory structures. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3325 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Crc32SectionExtractDxe/Crc32SectionExtract.c | 265 ++++++ .../Crc32SectionExtractDxe/Crc32SectionExtract.h | 105 +++ .../Crc32SectionExtractDxe/Crc32SectionExtract.msa | 66 ++ .../Crc32SectionExtractDxe.inf | 53 ++ .../FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c | 931 +++++++++++++++++++++ .../FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h | 695 +++++++++++++++ .../FaultTolerantWriteDxe/FtwLite.inf | 141 ++++ .../FaultTolerantWriteDxe/FtwLite.msa | 103 +++ .../FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c | 530 ++++++++++++ .../FaultTolerantWriteDxe/FtwWorkSpace.c | 561 +++++++++++++ .../FaultTolerantWriteDxe/Ia32/Ia32FtwMisc.c | 403 +++++++++ .../FaultTolerantWriteDxe/Ipf/IpfFtwMisc.c | 143 ++++ .../FaultTolerantWriteDxe/x64/x64FtwMisc.c | 140 ++++ .../FaultTolerantWriteLite/Dxe/FtwLite.c | 931 --------------------- .../FaultTolerantWriteLite/Dxe/FtwLite.dxs | 27 - .../FaultTolerantWriteLite/Dxe/FtwLite.h | 695 --------------- .../FaultTolerantWriteLite/Dxe/FtwLite.inf | 141 ---- .../FaultTolerantWriteLite/Dxe/FtwLite.msa | 103 --- .../FaultTolerantWriteLite/Dxe/FtwMisc.c | 530 ------------ .../FaultTolerantWriteLite/Dxe/FtwWorkSpace.c | 561 ------------- .../FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c | 403 --------- .../FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c | 143 ---- .../FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c | 140 ---- .../Crc32SectionExtract/Dxe/Crc32SectionExtract.c | 265 ------ .../Dxe/Crc32SectionExtract.dxs | 26 - .../Crc32SectionExtract/Dxe/Crc32SectionExtract.h | 105 --- .../Dxe/Crc32SectionExtract.inf | 53 -- .../Dxe/Crc32SectionExtract.msa | 66 -- 28 files changed, 4136 insertions(+), 4189 deletions(-) create mode 100644 MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.c create mode 100644 MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.h create mode 100644 MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.msa create mode 100644 MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtractDxe.inf create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.msa create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ia32/Ia32FtwMisc.c create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ipf/IpfFtwMisc.c create mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/x64/x64FtwMisc.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.dxs delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.h delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.inf delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwMisc.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwWorkSpace.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.dxs delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.h delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.inf delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa (limited to 'MdeModulePkg/Universal/FirmwareVolume') diff --git a/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.c b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.c new file mode 100644 index 0000000..ca5ee21 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.c @@ -0,0 +1,265 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. 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. + +Module Name: + + Crc32SectionExtract.c + +Abstract: + + Implements GUIDed section extraction protocol interface with + a specific GUID: CRC32. + + Please refer to the Framewokr Firmware Volume Specification 0.9. + +--*/ + + +#include + +EFI_STATUS +GuidedSectionExtractionProtocolConstructor ( + OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL **GuidedSep, + IN EFI_EXTRACT_GUIDED_SECTION ExtractSection + ) +/*++ + +Routine Description: + + Constructor for the GUIDed section extraction protocol. Initializes + instance data. + +Arguments: + + This Instance to construct + +Returns: + + EFI_SUCCESS: Instance initialized. + +--*/ +// TODO: GuidedSep - add argument and description to function comment +// TODO: ExtractSection - add argument and description to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +{ + *GuidedSep = AllocatePool (sizeof (EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL)); + if (*GuidedSep == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + (*GuidedSep)->ExtractSection = ExtractSection; + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +InitializeCrc32GuidedSectionExtractionProtocol ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Entry point of the CRC32 GUIDed section extraction protocol. + Creates and initializes an instance of the GUIDed section + extraction protocol with CRC32 GUID. + +Arguments: + + ImageHandle EFI_HANDLE: A handle for the image that is initializing + this driver + SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table + +Returns: + + EFI_SUCCESS: Driver initialized successfully + EFI_LOAD_ERROR: Failed to Initialize or has been loaded + EFI_OUT_OF_RESOURCES: Could not allocate needed resources + +--*/ +{ + EFI_STATUS Status; + EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *Crc32GuidedSep; + EFI_HANDLE Handle; + + // + // Call all constructors per produced protocols + // + Status = GuidedSectionExtractionProtocolConstructor ( + &Crc32GuidedSep, + (EFI_EXTRACT_GUIDED_SECTION) Crc32ExtractSection + ); + if (EFI_ERROR (Status)) { + if (Crc32GuidedSep != NULL) { + FreePool (Crc32GuidedSep); + } + + return Status; + } + // + // Pass in a NULL to install to a new handle + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiCrc32GuidedSectionExtractionProtocolGuid, + EFI_NATIVE_INTERFACE, + Crc32GuidedSep + ); + if (EFI_ERROR (Status)) { + FreePool (Crc32GuidedSep); + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} + +STATIC +UINT32 +EFIAPI +GetSectionLength ( + IN EFI_COMMON_SECTION_HEADER *CommonHeader + ) +/*++ + + Routine Description: + Get a length of section. + + Parameters: + CommonHeader - Pointer to the common section header. + + Return Value: + The length of the section, including the section header. + +--*/ +// TODO: function comment is missing 'Arguments:' +// TODO: function comment is missing 'Returns:' +// TODO: CommonHeader - add argument and description to function comment +{ + UINT32 Size; + + Size = *(UINT32 *) CommonHeader->Size & 0x00FFFFFF; + + return Size; +} + +STATIC +EFI_STATUS +EFIAPI +Crc32ExtractSection ( + IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, + IN VOID *InputSection, + OUT VOID **OutputBuffer, + OUT UINTN *OutputSize, + OUT UINT32 *AuthenticationStatus + ) +/*++ + + Routine Description: + This function reads and extracts contents of a section from an + encapsulating section. + + Parameters: + This - Indicates the calling context. + InputSection - Buffer containing the input GUIDed section + to be processed. + OutputBuffer - *OutputBuffer is allocated from boot services + pool memory and containing the new section + stream. The caller is responsible for freeing + this buffer. + AuthenticationStatus - Pointer to a caller allocated UINT32 that + indicates the authentication status of the + output buffer + + Return Value: + EFI_SUCCESS + EFI_OUT_OF_RESOURCES + EFI_INVALID_PARAMETER + EFI_NOT_AVAILABLE_YET + +--*/ +// TODO: function comment is missing 'Arguments:' +// TODO: function comment is missing 'Returns:' +// TODO: This - add argument and description to function comment +// TODO: InputSection - add argument and description to function comment +// TODO: OutputBuffer - add argument and description to function comment +// TODO: OutputSize - add argument and description to function comment +// TODO: AuthenticationStatus - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + CRC32_SECTION_HEADER *Crc32SectionHeader; + EFI_GUID_DEFINED_SECTION *GuidedSectionHeader; + UINT8 *Image; + UINT32 Crc32Checksum; + VOID *DummyInterface; + + if (OutputBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + *OutputBuffer = NULL; + + // + // Points to the section header + // + Crc32SectionHeader = (CRC32_SECTION_HEADER *) InputSection; + GuidedSectionHeader = (EFI_GUID_DEFINED_SECTION *) InputSection; + + // + // Check if the GUID is a CRC32 section GUID + // + if (!CompareGuid ( + &(GuidedSectionHeader->SectionDefinitionGuid), + &gEfiCrc32GuidedSectionExtractionProtocolGuid + )) { + return EFI_INVALID_PARAMETER; + } + + Image = (UINT8 *) InputSection + (UINT32) (GuidedSectionHeader->DataOffset); + *OutputSize = GetSectionLength ((EFI_COMMON_SECTION_HEADER *) InputSection) - (UINT32) GuidedSectionHeader->DataOffset; + + *OutputBuffer = AllocatePool (*OutputSize); + if (*OutputBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Implictly CRC32 GUIDed section should have STATUS_VALID bit set + // + ASSERT (GuidedSectionHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID); + *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; + + // + // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID. + // + Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface); + if (!EFI_ERROR (Status)) { + *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE; + } else { + // + // Calculate CRC32 Checksum of Image + // + gBS->CalculateCrc32 (Image, *OutputSize, &Crc32Checksum); + if (Crc32Checksum != Crc32SectionHeader->CRC32Checksum) { + *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; + } + } + + CopyMem (*OutputBuffer, Image, *OutputSize); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.h b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.h new file mode 100644 index 0000000..e7bf276 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.h @@ -0,0 +1,105 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. 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. + +Module Name: + + Crc32SectionExtract.h + +Abstract: + + Header file for Crc32SectionExtract.c + Please refer to the Framewokr Firmware Volume Specification 0.9. + +--*/ + +#ifndef _CRC32_GUIDED_SECTION_EXTRACTION_H +#define _CRC32_GUIDED_SECTION_EXTRACTION_H + +#include +#include +#include +#include +#include +#include +#include +#include + + + +typedef struct { + EFI_GUID_DEFINED_SECTION GuidedSectionHeader; + UINT32 CRC32Checksum; +} CRC32_SECTION_HEADER; + +// +// Function prototype declarations +// +STATIC +EFI_STATUS +EFIAPI +Crc32ExtractSection ( + IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, + IN VOID *InputSection, + OUT VOID **OutputBuffer, + OUT UINTN *OutputSize, + OUT UINT32 *AuthenticationStatus + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + InputSection - TODO: add argument description + OutputBuffer - TODO: add argument description + OutputSize - TODO: add argument description + AuthenticationStatus - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +InitializeCrc32GuidedSectionExtractionProtocol ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Entry point of the CRC32 GUIDed section extraction protocol. + Creates and initializes an instance of the GUIDed section + extraction protocol with CRC32 GUID. + +Arguments: + + ImageHandle EFI_HANDLE: A handle for the image that is initializing + this driver + SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table + +Returns: + + EFI_SUCCESS: Driver initialized successfully + EFI_LOAD_ERROR: Failed to Initialize or has been loaded + EFI_OUT_OF_RESOURCES: Could not allocate needed resources + +--*/ +; + +#endif diff --git a/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.msa b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.msa new file mode 100644 index 0000000..a4ab182 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtract.msa @@ -0,0 +1,66 @@ + + + + Crc32SectionExtract + DXE_DRIVER + 51C9F40C-5243-4473-B265-B3C8FFAFF9FA + 1.0 + Component description file for Crc32SectionExtract module. + This driver implements CRC32 GUIDed section extraction protocol interface. + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + Crc32SectionExtract + + + + DebugLib + + + UefiDriverEntryPoint + + + BaseMemoryLib + + + UefiBootServicesTableLib + + + MemoryAllocationLib + + + + Crc32SectionExtract.c + Crc32SectionExtract.h + GuidedSection.c + GuidedSection.h + Crc32SectionExtract.dxs + + + + + + + gEfiSecurityPolicyProtocolGuid + + + gEfiCrc32GuidedSectionExtractionProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + InitializeCrc32GuidedSectionExtractionProtocol + + + diff --git a/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtractDxe.inf b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtractDxe.inf new file mode 100644 index 0000000..8b19b78 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/Crc32SectionExtractDxe/Crc32SectionExtractDxe.inf @@ -0,0 +1,53 @@ +#/** @file +# Component description file for Crc32SectionExtract module. +# +# This driver implements CRC32 GUIDed section extraction protocol interface. +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. 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 = Crc32SectionExtractDxe + FILE_GUID = 51C9F40C-5243-4473-B265-B3C8FFAFF9FA + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = InitializeCrc32GuidedSectionExtractionProtocol + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + Crc32SectionExtract.h + Crc32SectionExtract.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + MemoryAllocationLib + UefiBootServicesTableLib + BaseMemoryLib + UefiDriverEntryPoint + DebugLib + +[Protocols] + gEfiSecurityPolicyProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiCrc32GuidedSectionExtractionProtocolGuid # PROTOCOL ALWAYS_PRODUCED + +[Depex] + gEfiRuntimeArchProtocolGuid diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c new file mode 100644 index 0000000..38fe11d --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c @@ -0,0 +1,931 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. 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. + + +Module Name: + + FtwLite.c + +Abstract: + + This is a simple fault tolerant write driver, based on PlatformFd library. + And it only supports write BufferSize <= SpareAreaLength. + + This boot service only protocol provides fault tolerant write capability for + block devices. The protocol has internal non-volatile intermediate storage + of the data and private information. It should be able to recover + automatically from a critical fault, such as power failure. + +Notes: + + The implementation uses an FTW Lite (Fault Tolerant Write) Work Space. + This work space is a memory copy of the work space on the Woring Block, + the size of the work space is the FTW_WORK_SPACE_SIZE bytes. + +--*/ + +#include + +// +// In write function, we should check the target range to prevent the user +// from writing Spare block and Working space directly. +// +// +// Fault Tolerant Write Protocol API +// +EFI_STATUS +EFIAPI +FtwLiteWrite ( + IN EFI_FTW_LITE_PROTOCOL *This, + IN EFI_HANDLE FvbHandle, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN VOID *Buffer + ) +/*++ + +Routine Description: + Starts a target block update. This function will record data about write + in fault tolerant storage and will complete the write in a recoverable + manner, ensuring at all times that either the original contents or + the modified contents are available. + +Arguments: + This - Calling context + FvbHandle - The handle of FVB protocol that provides services for + reading, writing, and erasing the target block. + Lba - The logical block address of the target block. + Offset - The offset within the target block to place the data. + NumBytes - The number of bytes to write to the target block. + Buffer - The data to write. + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_BAD_BUFFER_SIZE - The write would span a target block, which is not + a valid action. + EFI_ACCESS_DENIED - No writes have been allocated. + EFI_NOT_FOUND - Cannot find FVB by handle. + EFI_OUT_OF_RESOURCES - Cannot allocate memory. + EFI_ABORTED - The function could not complete successfully. + +--*/ +{ + EFI_STATUS Status; + EFI_FTW_LITE_DEVICE *FtwLiteDevice; + EFI_FTW_LITE_RECORD *Record; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_PHYSICAL_ADDRESS FvbPhysicalAddress; + UINTN MyLength; + UINTN MyOffset; + UINTN MyBufferSize; + UINT8 *MyBuffer; + UINTN SpareBufferSize; + UINT8 *SpareBuffer; + UINTN Index; + UINT8 *Ptr; + EFI_DEV_PATH_PTR DevPtr; + + // + // Refresh work space and get last record + // + FtwLiteDevice = FTW_LITE_CONTEXT_FROM_THIS (This); + Status = WorkSpaceRefresh (FtwLiteDevice); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + Record = FtwLiteDevice->FtwLastRecord; + + // + // Check the flags of last write record + // + if ((Record->WriteAllocated == FTW_VALID_STATE) || (Record->SpareCompleted == FTW_VALID_STATE)) { + return EFI_ACCESS_DENIED; + } + // + // IF former record has completed, THEN use next record + // + if (Record->WriteCompleted == FTW_VALID_STATE) { + Record++; + FtwLiteDevice->FtwLastRecord = Record; + } + + MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; + + // + // Check if the input data can fit within the target block + // + if ((Offset +*NumBytes) > FtwLiteDevice->SpareAreaLength) { + return EFI_BAD_BUFFER_SIZE; + } + // + // Check if there is enough free space for allocate a record + // + if ((MyOffset + WRITE_TOTAL_SIZE) > FtwLiteDevice->FtwWorkSpaceSize) { + Status = FtwReclaimWorkSpace (FtwLiteDevice); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim work space - %r", Status)); + return EFI_ABORTED; + } + } + // + // Get the FVB protocol by handle + // + Status = FtwGetFvbByHandle (FvbHandle, &Fvb); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Allocate a write record in workspace. + // Update Header->WriteAllocated as VALID + // + Status = FtwUpdateFvState ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase + MyOffset, + WRITE_ALLOCATED + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Allocate record - %r\n", Status)); + return EFI_ABORTED; + } + + Record->WriteAllocated = FTW_VALID_STATE; + + // + // Prepare data of write record, filling DevPath with memory mapped address. + // + DevPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath; + DevPtr.MemMap->Header.Type = HARDWARE_DEVICE_PATH; + DevPtr.MemMap->Header.SubType = HW_MEMMAP_DP; + SetDevicePathNodeLength (&DevPtr.MemMap->Header, sizeof (MEMMAP_DEVICE_PATH)); + + Status = Fvb->GetPhysicalAddress (Fvb, &FvbPhysicalAddress); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Get FVB physical address - %r\n", Status)); + return EFI_ABORTED; + } + + DevPtr.MemMap->MemoryType = EfiMemoryMappedIO; + DevPtr.MemMap->StartingAddress = FvbPhysicalAddress; + DevPtr.MemMap->EndingAddress = FvbPhysicalAddress +*NumBytes; + // + // ignored! + // + Record->Lba = Lba; + Record->Offset = Offset; + Record->NumBytes = *NumBytes; + + // + // Write the record to the work space. + // + MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; + MyLength = FTW_LITE_RECORD_SIZE; + + Status = FtwLiteDevice->FtwFvBlock->Write ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase + MyOffset, + &MyLength, + (UINT8 *) Record + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Record has been written to working block, then write data. + // + // + // Allocate a memory buffer + // + MyBufferSize = FtwLiteDevice->SpareAreaLength; + MyBuffer = AllocatePool (MyBufferSize); + if (MyBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Starting at Lba, if the number of the rest blocks on Fvb is less + // than NumberOfSpareBlock. + // + // + // Read all original data from target block to memory buffer + // + if (IsInWorkingBlock (FtwLiteDevice, Fvb, Lba)) { + // + // If target block falls into working block, we must follow the process of + // updating working block. + // + Ptr = MyBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + MyLength = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwFvBlock->Read ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkBlockLba + Index, + 0, + &MyLength, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (MyBuffer); + return EFI_ABORTED; + } + + Ptr += MyLength; + } + // + // Update Offset by adding the offset from the start LBA of working block to + // the target LBA. The target block can not span working block! + // + Offset = (((UINTN) (Lba - FtwLiteDevice->FtwWorkBlockLba)) * FtwLiteDevice->SizeOfSpareBlock + Offset); + ASSERT ((Offset +*NumBytes) <= FtwLiteDevice->SpareAreaLength); + + } else { + + Ptr = MyBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + MyLength = FtwLiteDevice->SizeOfSpareBlock; + Status = Fvb->Read (Fvb, Lba + Index, 0, &MyLength, Ptr); + if (EFI_ERROR (Status)) { + FreePool (MyBuffer); + return EFI_ABORTED; + } + + Ptr += MyLength; + } + } + // + // Overwrite the updating range data with + // the input buffer content + // + CopyMem (MyBuffer + Offset, Buffer, *NumBytes); + + // + // Try to keep the content of spare block + // Save spare block into a spare backup memory buffer (Sparebuffer) + // + SpareBufferSize = FtwLiteDevice->SpareAreaLength; + SpareBuffer = AllocatePool (SpareBufferSize); + if (SpareBuffer == NULL) { + FreePool (MyBuffer); + return EFI_OUT_OF_RESOURCES; + } + + Ptr = SpareBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + MyLength = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Read ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &MyLength, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (MyBuffer); + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Ptr += MyLength; + } + // + // Write the memory buffer to spare block + // Don't forget to erase Flash first. + // + Status = FtwEraseSpareBlock (FtwLiteDevice); + Ptr = MyBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + MyLength = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Write ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &MyLength, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (MyBuffer); + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Ptr += MyLength; + } + // + // Free MyBuffer + // + FreePool (MyBuffer); + + // + // Set the SpareCompleteD in the FTW record, + // + MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; + Status = FtwUpdateFvState ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase + MyOffset, + SPARE_COMPLETED + ); + if (EFI_ERROR (Status)) { + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Record->SpareCompleted = FTW_VALID_STATE; + + // + // Since the content has already backuped in spare block, the write is + // guaranteed to be completed with fault tolerant manner. + // + Status = FtwWriteRecord (FtwLiteDevice, Fvb); + if (EFI_ERROR (Status)) { + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Record++; + FtwLiteDevice->FtwLastRecord = Record; + + // + // Restore spare backup buffer into spare block , if no failure happened during FtwWrite. + // + Status = FtwEraseSpareBlock (FtwLiteDevice); + Ptr = SpareBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + MyLength = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Write ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &MyLength, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Ptr += MyLength; + } + // + // All success. + // + FreePool (SpareBuffer); + + DEBUG ( + (EFI_D_FTW_LITE, + "FtwLite: Write() success, (Lba:Offset)=(%lx:0x%x), NumBytes: 0x%x\n", + Lba, + Offset, + *NumBytes) + ); + + return EFI_SUCCESS; +} + + +EFI_STATUS +FtwWriteRecord ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb + ) +/*++ + +Routine Description: + Write a record with fault tolerant mannaer. + Since the content has already backuped in spare block, the write is + guaranteed to be completed with fault tolerant manner. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + Fvb - The FVB protocol that provides services for + reading, writing, and erasing the target block. + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully + +--*/ +{ + EFI_STATUS Status; + EFI_FTW_LITE_RECORD *Record; + EFI_LBA WorkSpaceLbaOffset; + UINTN Offset; + + // + // Spare Complete but Destination not complete, + // Recover the targt block with the spare block. + // + Record = FtwLiteDevice->FtwLastRecord; + + // + // IF target block is working block, THEN Flush Spare Block To Working Block; + // ELSE IF target block is boot block, THEN Flush Spare Block To boot Block; + // ELSE flush spare block to normal target block.ENDIF + // + if (IsInWorkingBlock (FtwLiteDevice, Fvb, Record->Lba)) { + // + // If target block is working block, Attention: + // it's required to set SPARE_COMPLETED to spare block. + // + WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba; + Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; + Status = FtwUpdateFvState ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset, + FtwLiteDevice->FtwWorkSpaceBase + Offset, + SPARE_COMPLETED + ); + ASSERT_EFI_ERROR (Status); + + Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); + } else if (IsBootBlock (FtwLiteDevice, Fvb, Record->Lba)) { + // + // Update boot block + // + Status = FlushSpareBlockToBootBlock (FtwLiteDevice); + } else { + // + // Update blocks other than working block or boot block + // + Status = FlushSpareBlockToTargetBlock (FtwLiteDevice, Fvb, Record->Lba); + } + + ASSERT_EFI_ERROR (Status); + + // + // Set WriteCompleted flag in record + // + Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; + Status = FtwUpdateFvState ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase + Offset, + WRITE_COMPLETED + ); + ASSERT_EFI_ERROR (Status); + + Record->WriteCompleted = FTW_VALID_STATE; + return EFI_SUCCESS; +} + + +EFI_STATUS +FtwRestart ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Restarts a previously interrupted write. The caller must provide the + block protocol needed to complete the interrupted write. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + FvbHandle - The handle of FVB protocol that provides services for + reading, writing, and erasing the target block. + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ACCESS_DENIED - No pending writes exist + EFI_NOT_FOUND - FVB protocol not found by the handle + EFI_ABORTED - The function could not complete successfully + +--*/ +{ + EFI_STATUS Status; + EFI_FTW_LITE_RECORD *Record; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_DEV_PATH_PTR DevPathPtr; + + // + // Spare Completed but Destination not complete, + // Recover the targt block with the spare block. + // + Record = FtwLiteDevice->FtwLastRecord; + + // + // Only support memory mapped FVB device path by now. + // + DevPathPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath; + if (!((DevPathPtr.MemMap->Header.Type == HARDWARE_DEVICE_PATH) && (DevPathPtr.MemMap->Header.SubType == HW_MEMMAP_DP)) + ) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Device Path is not memory mapped\n")); + return EFI_ABORTED; + } + + Status = GetFvbByAddress (DevPathPtr.MemMap->StartingAddress, &Fvb); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Since the content has already backuped in spare block, the write is + // guaranteed to be completed with fault tolerant manner. + // + Status = FtwWriteRecord (FtwLiteDevice, Fvb); + DEBUG ((EFI_D_FTW_INFO, "FtwLite: Restart() - %r\n", Status)); + + Record++; + FtwLiteDevice->FtwLastRecord = Record; + + // + // Erase Spare block + // This is restart, no need to keep spareblock content. + // + FtwEraseSpareBlock (FtwLiteDevice); + + return Status; +} + + +EFI_STATUS +FtwAbort ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Aborts all previous allocated writes. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + EFI_NOT_FOUND - No allocated writes exist. + +--*/ +{ + EFI_STATUS Status; + UINTN Offset; + + if (FtwLiteDevice->FtwLastRecord->WriteCompleted == FTW_VALID_STATE) { + return EFI_NOT_FOUND; + } + // + // Update the complete state of the header as VALID and abort. + // + Offset = (UINT8 *) FtwLiteDevice->FtwLastRecord - FtwLiteDevice->FtwWorkSpace; + Status = FtwUpdateFvState ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase + Offset, + WRITE_COMPLETED + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + FtwLiteDevice->FtwLastRecord->WriteCompleted = FTW_VALID_STATE; + + Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); + + // + // Erase the spare block + // + Status = FtwEraseSpareBlock (FtwLiteDevice); + + DEBUG ((EFI_D_FTW_INFO, "FtwLite: Abort() success \n")); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +InitializeFtwLite ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + Routine Description: + This function is the entry point of the Fault Tolerant Write driver. + + Arguments: + ImageHandle - EFI_HANDLE: A handle for the image that is initializing + this driver + SystemTable - EFI_SYSTEM_TABLE: A pointer to the EFI system table + + Returns: + EFI_SUCCESS - FTW has finished the initialization + EFI_ABORTED - FTW initialization error + +--*/ +{ + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + UINTN Index; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_PHYSICAL_ADDRESS BaseAddress; + EFI_FTW_LITE_DEVICE *FtwLiteDevice; + EFI_FTW_LITE_RECORD *Record; + UINTN Length; + EFI_STATUS Status; + UINTN Offset; + EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry; + UINT32 LbaIndex; + + // + // Allocate Private data of this driver, + // INCLUDING THE FtwWorkSpace[FTW_WORK_SPACE_SIZE]. + // + FtwLiteDevice = NULL; + FtwLiteDevice = AllocatePool (sizeof (EFI_FTW_LITE_DEVICE) + FTW_WORK_SPACE_SIZE); + if (FtwLiteDevice != NULL) { + Status = EFI_SUCCESS; + } else { + Status = EFI_OUT_OF_RESOURCES; + } + + ASSERT_EFI_ERROR (Status); + + ZeroMem (FtwLiteDevice, sizeof (EFI_FTW_LITE_DEVICE)); + FtwLiteDevice->Signature = FTW_LITE_DEVICE_SIGNATURE; + + // + // Initialize other parameters, and set WorkSpace as FTW_ERASED_BYTE. + // + FtwLiteDevice->FtwWorkSpace = (UINT8 *) (FtwLiteDevice + 1); + FtwLiteDevice->FtwWorkSpaceSize = FTW_WORK_SPACE_SIZE; + SetMem ( + FtwLiteDevice->FtwWorkSpace, + FtwLiteDevice->FtwWorkSpaceSize, + FTW_ERASED_BYTE + ); + FtwLiteDevice->FtwWorkSpaceHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FtwLiteDevice->FtwWorkSpace; + + FtwLiteDevice->FtwLastRecord = NULL; + + FtwLiteDevice->WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwWorkingBase); + FtwLiteDevice->WorkSpaceLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwWorkingSize); + + FtwLiteDevice->SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwSpareBase); + FtwLiteDevice->SpareAreaLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwSpareSize); + + ASSERT ((FtwLiteDevice->WorkSpaceLength != 0) && (FtwLiteDevice->SpareAreaLength != 0)); + + // + // Locate FVB protocol + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeBlockProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + ASSERT_EFI_ERROR (Status); + + ASSERT (HandleCount > 0); + + FtwLiteDevice->FtwFvBlock = NULL; + FtwLiteDevice->FtwBackupFvb = NULL; + FtwLiteDevice->FtwWorkSpaceLba = (EFI_LBA) (-1); + FtwLiteDevice->FtwSpareLba = (EFI_LBA) (-1); + for (Index = 0; Index < HandleCount; Index += 1) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &Fvb + ); + ASSERT_EFI_ERROR (Status); + + Status = Fvb->GetPhysicalAddress (Fvb, &BaseAddress); + if (EFI_ERROR (Status)) { + continue; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) BaseAddress); + + if ((FtwLiteDevice->WorkSpaceAddress >= BaseAddress) && + (FtwLiteDevice->WorkSpaceAddress <= (BaseAddress + FwVolHeader->FvLength)) + ) { + FtwLiteDevice->FtwFvBlock = Fvb; + // + // To get the LBA of work space + // + if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) { + // + // FV may have multiple types of BlockLength + // + FvbMapEntry = &FwVolHeader->BlockMap[0]; + while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) { + for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { + if (FtwLiteDevice->WorkSpaceAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex)) { + FtwLiteDevice->FtwWorkSpaceLba = LbaIndex - 1; + // + // Get the Work space size and Base(Offset) + // + FtwLiteDevice->FtwWorkSpaceSize = FtwLiteDevice->WorkSpaceLength; + FtwLiteDevice->FtwWorkSpaceBase = (UINTN) (FtwLiteDevice->WorkSpaceAddress - (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1))); + break; + } + } + // + // end for + // + FvbMapEntry++; + } + // + // end while + // + } + } + + if ((FtwLiteDevice->SpareAreaAddress >= BaseAddress) && + (FtwLiteDevice->SpareAreaAddress <= (BaseAddress + FwVolHeader->FvLength)) + ) { + FtwLiteDevice->FtwBackupFvb = Fvb; + // + // To get the LBA of spare + // + if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) { + // + // FV may have multiple types of BlockLength + // + FvbMapEntry = &FwVolHeader->BlockMap[0]; + while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) { + for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { + if (FtwLiteDevice->SpareAreaAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex)) { + // + // Get the NumberOfSpareBlock and SizeOfSpareBlock + // + FtwLiteDevice->FtwSpareLba = LbaIndex - 1; + FtwLiteDevice->SizeOfSpareBlock = FvbMapEntry->Length; + FtwLiteDevice->NumberOfSpareBlock = FtwLiteDevice->SpareAreaLength / FtwLiteDevice->SizeOfSpareBlock; + // + // Check the range of spare area to make sure that it's in FV range + // + ASSERT ((FtwLiteDevice->FtwSpareLba + FtwLiteDevice->NumberOfSpareBlock) <= FvbMapEntry->NumBlocks); + break; + } + } + + FvbMapEntry++; + } + // + // end while + // + } + } + } + // + // Calculate the start LBA of working block. Working block is an area which + // contains working space in its last block and has the same size as spare + // block, unless there are not enough blocks before the block that contains + // working space. + // + FtwLiteDevice->FtwWorkBlockLba = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->NumberOfSpareBlock + 1; + if ((INT64) (FtwLiteDevice->FtwWorkBlockLba) < 0) { + FtwLiteDevice->FtwWorkBlockLba = 0; + } + + if ((FtwLiteDevice->FtwFvBlock == NULL) || + (FtwLiteDevice->FtwBackupFvb == NULL) || + (FtwLiteDevice->FtwWorkSpaceLba == (EFI_LBA) (-1)) || + (FtwLiteDevice->FtwSpareLba == (EFI_LBA) (-1)) + ) { + DEBUG ((EFI_D_ERROR, "FtwLite: Working or spare FVB not ready\n")); + ASSERT_EFI_ERROR (Status); + } + // + // Refresh workspace data from working block + // + Status = WorkSpaceRefresh (FtwLiteDevice); + ASSERT_EFI_ERROR (Status); + + // + // If the working block workspace is not valid, try the spare block + // + if (!IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace invalid, read from backup\n")); + // + // Read from spare block + // + Length = FtwLiteDevice->FtwWorkSpaceSize; + Status = FtwLiteDevice->FtwBackupFvb->Read ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba, + FtwLiteDevice->FtwWorkSpaceBase, + &Length, + FtwLiteDevice->FtwWorkSpace + ); + ASSERT_EFI_ERROR (Status); + + // + // If spare block is valid, then replace working block content. + // + if (IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) { + Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart working block in Init() - %r\n", Status)); + ASSERT_EFI_ERROR (Status); + + FtwAbort (FtwLiteDevice); + // + // Refresh work space. + // + Status = WorkSpaceRefresh (FtwLiteDevice); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + } else { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Both are invalid, init workspace\n")); + // + // If both are invalid, then initialize work space. + // + SetMem ( + FtwLiteDevice->FtwWorkSpace, + FtwLiteDevice->FtwWorkSpaceSize, + FTW_ERASED_BYTE + ); + InitWorkSpaceHeader (FtwLiteDevice->FtwWorkSpaceHeader); + // + // Write to work space on the working block + // + Length = FtwLiteDevice->FtwWorkSpaceSize; + Status = FtwLiteDevice->FtwFvBlock->Write ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase, + &Length, + FtwLiteDevice->FtwWorkSpace + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + } + } + // + // Hook the protocol API + // + FtwLiteDevice->FtwLiteInstance.Write = FtwLiteWrite; + + // + // Install protocol interface + // + Status = gBS->InstallProtocolInterface ( + &FtwLiteDevice->Handle, + &gEfiFaultTolerantWriteLiteProtocolGuid, + EFI_NATIVE_INTERFACE, + &FtwLiteDevice->FtwLiteInstance + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // If (!SpareCompleted) THEN Abort to rollback. + // + if ((FtwLiteDevice->FtwLastRecord->WriteAllocated == FTW_VALID_STATE) && + (FtwLiteDevice->FtwLastRecord->SpareCompleted != FTW_VALID_STATE) + ) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Init.. record not SpareCompleted, abort()\n")); + FtwAbort (FtwLiteDevice); + } + // + // if (SpareCompleted) THEN Restart to fault tolerant write. + // + if ((FtwLiteDevice->FtwLastRecord->SpareCompleted == FTW_VALID_STATE) && + (FtwLiteDevice->FtwLastRecord->WriteCompleted != FTW_VALID_STATE) + ) { + + Status = FtwRestart (FtwLiteDevice); + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart last write - %r\n", Status)); + if (EFI_ERROR (Status)) { + return Status; + } + } + // + // To check the workspace buffer behind last records is EMPTY or not. + // If it's not EMPTY, FTW_LITE also need to call reclaim(). + // + Record = FtwLiteDevice->FtwLastRecord; + Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; + if (FtwLiteDevice->FtwWorkSpace[Offset] != FTW_ERASED_BYTE) { + Offset += WRITE_TOTAL_SIZE; + } + + if (!IsErasedFlashBuffer ( + FTW_ERASE_POLARITY, + FtwLiteDevice->FtwWorkSpace + Offset, + FtwLiteDevice->FtwWorkSpaceSize - Offset + )) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace is dirty, call reclaim...\n")); + Status = FtwReclaimWorkSpace (FtwLiteDevice); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace reclaim - %r\n", Status)); + return EFI_ABORTED; + } + } + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h new file mode 100644 index 0000000..8bc122d --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h @@ -0,0 +1,695 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. 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. + + +Module Name: + + FtwLite.h + +Abstract: + + This is a simple fault tolerant write driver, based on PlatformFd library. + And it only supports write BufferSize <= SpareAreaLength. + + This boot service only protocol provides fault tolerant write capability for + block devices. The protocol has internal non-volatile intermediate storage + of the data and private information. It should be able to recover + automatically from a critical fault, such as power failure. + +--*/ + +#ifndef _EFI_FAULT_TOLERANT_WRITE_LITE_H_ +#define _EFI_FAULT_TOLERANT_WRITE_LITE_H_ + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include + +#include + +#define EFI_D_FTW_LITE EFI_D_ERROR +#define EFI_D_FTW_INFO EFI_D_INFO + +// +// Flash erase polarity is 1 +// +#define FTW_ERASE_POLARITY 1 + +#define FTW_VALID_STATE 0 +#define FTW_INVALID_STATE 1 + +#define FTW_ERASED_BYTE ((UINT8) (255)) +#define FTW_POLARITY_REVERT ((UINT8) (255)) + +typedef struct { + UINT8 WriteAllocated : 1; + UINT8 SpareCompleted : 1; + UINT8 WriteCompleted : 1; + UINT8 Reserved : 5; +#define WRITE_ALLOCATED 0x1 +#define SPARE_COMPLETED 0x2 +#define WRITE_COMPLETED 0x4 + + EFI_DEV_PATH DevPath; + EFI_LBA Lba; + UINTN Offset; + UINTN NumBytes; + // + // UINTN SpareAreaOffset; + // +} EFI_FTW_LITE_RECORD; + +#define FTW_LITE_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'T', 'W', 'L') + +// +// MACRO for Block size. +// Flash Erasing will do in block granularity. +// +#ifdef FV_BLOCK_SIZE +#define FTW_BLOCK_SIZE FV_BLOCK_SIZE +#else +#define FV_BLOCK_SIZE 0x10000 +#define FTW_BLOCK_SIZE FV_BLOCK_SIZE +#endif +// +// MACRO for FTW WORK SPACE Base & Size +// +#ifdef EFI_FTW_WORKING_OFFSET +#define FTW_WORK_SPACE_BASE EFI_FTW_WORKING_OFFSET +#else +#define FTW_WORK_SPACE_BASE 0x00E000 +#endif + +#ifdef EFI_FTW_WORKING_LENGTH +#define FTW_WORK_SPACE_SIZE EFI_FTW_WORKING_LENGTH +#else +#define FTW_WORK_SPACE_SIZE 0x002000 +#endif +// +// MACRO for FTW header and record +// +#define FTW_WORKING_QUEUE_SIZE (FTW_WORK_SPACE_SIZE - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)) +#define FTW_LITE_RECORD_SIZE (sizeof (EFI_FTW_LITE_RECORD)) +#define WRITE_TOTAL_SIZE FTW_LITE_RECORD_SIZE + +// +// EFI Fault tolerant protocol private data structure +// +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_FTW_LITE_PROTOCOL FtwLiteInstance; + EFI_PHYSICAL_ADDRESS WorkSpaceAddress; + UINTN WorkSpaceLength; + EFI_PHYSICAL_ADDRESS SpareAreaAddress; + UINTN SpareAreaLength; + UINTN NumberOfSpareBlock; // Number of the blocks in spare block + UINTN SizeOfSpareBlock; // Block size in bytes of the blocks in spare block + EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader; + EFI_FTW_LITE_RECORD *FtwLastRecord; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwFvBlock; // FVB of working block + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwBackupFvb; // FVB of spare block + EFI_LBA FtwSpareLba; + EFI_LBA FtwWorkBlockLba; // Start LBA of working block + EFI_LBA FtwWorkSpaceLba; // Start LBA of working space + UINTN FtwWorkSpaceBase; // Offset from LBA start addr + UINTN FtwWorkSpaceSize; + UINT8 *FtwWorkSpace; + // + // Following a buffer of FtwWorkSpace[FTW_WORK_SPACE_SIZE], + // Allocated with EFI_FTW_LITE_DEVICE. + // +} EFI_FTW_LITE_DEVICE; + +#define FTW_LITE_CONTEXT_FROM_THIS(a) CR (a, EFI_FTW_LITE_DEVICE, FtwLiteInstance, FTW_LITE_DEVICE_SIGNATURE) + +// +// Driver entry point +// +EFI_STATUS +EFIAPI +InitializeFtwLite ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + This function is the entry point of the Fault Tolerant Write driver. + +Arguments: + ImageHandle - EFI_HANDLE: A handle for the image that is initializing + this driver + SystemTable - EFI_SYSTEM_TABLE: A pointer to the EFI system table + +Returns: + EFI_SUCCESS - FTW has finished the initialization + EFI_ABORTED - FTW initialization error + +--*/ +; + +// +// Fault Tolerant Write Protocol API +// +EFI_STATUS +EFIAPI +FtwLiteWrite ( + IN EFI_FTW_LITE_PROTOCOL *This, + IN EFI_HANDLE FvbHandle, + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN VOID *Buffer + ) +/*++ + +Routine Description: + Starts a target block update. This function will record data about write + in fault tolerant storage and will complete the write in a recoverable + manner, ensuring at all times that either the original contents or + the modified contents are available. + +Arguments: + This - Calling context + FvbHandle - The handle of FVB protocol that provides services for + reading, writing, and erasing the target block. + Lba - The logical block address of the target block. + Offset - The offset within the target block to place the data. + NumBytes - The number of bytes to write to the target block. + Buffer - The data to write. + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_BAD_BUFFER_SIZE - The write would span a target block, which is not + a valid action. + EFI_ACCESS_DENIED - No writes have been allocated. + EFI_NOT_FOUND - Cannot find FVB by handle. + EFI_OUT_OF_RESOURCES - Cannot allocate memory. + EFI_ABORTED - The function could not complete successfully. + +--*/ +; + +// +// Internal functions +// +EFI_STATUS +FtwRestart ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Restarts a previously interrupted write. The caller must provide the + block protocol needed to complete the interrupted write. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + FvbHandle - The handle of FVB protocol that provides services for + reading, writing, and erasing the target block. + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ACCESS_DENIED - No pending writes exist + EFI_NOT_FOUND - FVB protocol not found by the handle + EFI_ABORTED - The function could not complete successfully + +--*/ +; + +EFI_STATUS +FtwAbort ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Aborts all previous allocated writes. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + EFI_NOT_FOUND - No allocated writes exist. + +--*/ +; + + +EFI_STATUS +FtwWriteRecord ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb + ) +/*++ + +Routine Description: + Write a record with fault tolerant mannaer. + Since the content has already backuped in spare block, the write is + guaranteed to be completed with fault tolerant manner. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + Fvb - The FVB protocol that provides services for + reading, writing, and erasing the target block. + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully + +--*/ +; + +EFI_STATUS +FtwEraseBlock ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + To Erase one block. The size is FTW_BLOCK_SIZE + +Arguments: + FtwLiteDevice - Calling context + FvBlock - FVB Protocol interface + Lba - Lba of the firmware block + +Returns: + EFI_SUCCESS - Block LBA is Erased successfully + Others - Error occurs + +--*/ +; + +EFI_STATUS +FtwEraseSpareBlock ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + + Erase spare block. + +Arguments: + + FtwLiteDevice - Calling context + +Returns: + + Status code + +--*/ +; + +EFI_STATUS +FtwGetFvbByHandle ( + IN EFI_HANDLE FvBlockHandle, + OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock + ) +/*++ + +Routine Description: + Retrive the proper FVB protocol interface by HANDLE. + +Arguments: + FvBlockHandle - The handle of FVB protocol that provides services for + reading, writing, and erasing the target block. + FvBlock - The interface of FVB protocol + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully +--*/ +; + +EFI_STATUS +GetFvbByAddress ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock + ) +/*++ + +Routine Description: + + Get firmware block by address. + +Arguments: + + Address - Address specified the block + FvBlock - The block caller wanted + +Returns: + + Status code + + EFI_NOT_FOUND - Block not found + +--*/ +; + +BOOLEAN +IsInWorkingBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + + Is it in working block? + +Arguments: + + FtwLiteDevice - Calling context + FvBlock - Fvb protocol instance + Lba - The block specified + +Returns: + + In working block or not + +--*/ +; + +BOOLEAN +IsBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + + Check whether the block is a boot block. + +Arguments: + + FtwLiteDevice - Calling context + FvBlock - Fvb protocol instance + Lba - Lba value + +Returns: + + Is a boot block or not + +--*/ +; + +EFI_STATUS +FlushSpareBlockToTargetBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Target block is accessed by FvBlock protocol interface. LBA is Lba. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + FvBlock - FVB Protocol interface to access target block + Lba - Lba of the target block + +Returns: + EFI_SUCCESS - Spare block content is copied to target block + EFI_INVALID_PARAMETER - Input parameter error + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +--*/ +; + +EFI_STATUS +FlushSpareBlockToWorkingBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Working block is accessed by FTW working FVB protocol interface. LBA is + FtwLiteDevice->FtwWorkBlockLba. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - Spare block content is copied to target block + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +Notes: + Since the working block header is important when FTW initializes, the + state of the operation should be handled carefully. The Crc value is + calculated without STATE element. + +--*/ +; + +EFI_STATUS +FlushSpareBlockToBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Boot block is accessed by BootFvb protocol interface. LBA is 0. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - Spare block content is copied to boot block + EFI_INVALID_PARAMETER - Input parameter error + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +Notes: + +--*/ +; + +EFI_STATUS +FtwUpdateFvState ( + IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINT8 NewBit + ) +/*++ + +Routine Description: + Update a bit of state on a block device. The location of the bit is + calculated by the (Lba, Offset, bit). Here bit is determined by the + the name of a certain bit. + +Arguments: + FvBlock - FVB Protocol interface to access SrcBlock and DestBlock + Lba - Lba of a block + Offset - Offset on the Lba + NewBit - New value that will override the old value if it can be change + +Returns: + EFI_SUCCESS - A state bit has been updated successfully + Others - Access block device error. + +Notes: + Assume all bits of State are inside the same BYTE. + + EFI_ABORTED - Read block fail +--*/ +; + +EFI_STATUS +FtwGetLastRecord ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + OUT EFI_FTW_LITE_RECORD **FtwLastRecord + ) +/*++ + +Routine Description: + Get the last Write record pointer. + The last record is the record whose 'complete' state hasn't been set. + After all, this header may be a EMPTY header entry for next Allocate. + +Arguments: + FtwLiteDevice - Private data of this driver + FtwLastRecord - Pointer to retrieve the last write record + +Returns: + EFI_SUCCESS - Get the last write record successfully + EFI_ABORTED - The FTW work space is damaged + +--*/ +; + +BOOLEAN +IsErasedFlashBuffer ( + IN BOOLEAN Polarity, + IN UINT8 *Buffer, + IN UINTN BufferSize + ) +/*++ + +Routine Description: + + Check whether a flash buffer is erased. + +Arguments: + + Polarity - All 1 or all 0 + Buffer - Buffer to check + BufferSize - Size of the buffer + +Returns: + + Erased or not. + +--*/ +; + +EFI_STATUS +InitWorkSpaceHeader ( + IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader + ) +/*++ + +Routine Description: + Initialize a work space when there is no work space. + +Arguments: + WorkingHeader - Pointer of working block header + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + +--*/ +; + +EFI_STATUS +WorkSpaceRefresh ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Read from working block to refresh the work space in memory. + +Arguments: + FtwLiteDevice - Point to private data of FTW driver + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + +--*/ +; + +BOOLEAN +IsValidWorkSpace ( + IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader + ) +/*++ + +Routine Description: + Check to see if it is a valid work space. + +Arguments: + WorkingHeader - Pointer of working block header + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + +--*/ +; + +EFI_STATUS +CleanupWorkSpace ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + IN OUT UINT8 *BlockBuffer, + IN UINTN BufferSize + ) +/*++ + +Routine Description: + Reclaim the work space. Get rid of all the completed write records + and write records in the Fault Tolerant work space. + +Arguments: + FtwLiteDevice - Point to private data of FTW driver + FtwSpaceBuffer - Buffer to contain the reclaimed clean data + BufferSize - Size of the FtwSpaceBuffer + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_BUFFER_TOO_SMALL - The FtwSpaceBuffer is too small + EFI_ABORTED - The function could not complete successfully. + +--*/ +; + +EFI_STATUS +FtwReclaimWorkSpace ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Reclaim the work space on the working block. + +Arguments: + FtwLiteDevice - Point to private data of FTW driver + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +--*/ +; + +#endif diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf new file mode 100644 index 0000000..4f47d60 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf @@ -0,0 +1,141 @@ +#/** @file +# Component description file for FtwLite module. +# +# This driver provides fault tolerant write capability for block devices. +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. 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 Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FtwLite + FILE_GUID = 4C862FC6-0E54-4e36-8C8F-FF6F3167951F + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = InitializeFtwLite + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + FtwWorkSpace.c + FtwMisc.c + FtwLite.c + FtwLite.h + +[Sources.Ia32] + Ia32/Ia32FtwMisc.c + +[Sources.X64] + x64/x64FtwMisc.c + +[Sources.IPF] + Ipf/IpfFtwMisc.c + +[Sources.EBC] + Ia32/Ia32FtwMisc.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + UefiDriverEntryPoint + DebugLib + PcdLib + HobLib + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gEfiSystemNvDataFvGuid # ALWAYS_CONSUMED + gEfiFlashMapHobGuid + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiFaultTolerantWriteLiteProtocolGuid # PROTOCOL ALWAYS_PRODUCED + +[Protocols.IA32] + gEfiPciRootBridgeIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[Protocols.EBC] + gEfiPciRootBridgeIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED + + +################################################################################ +# +# Pcd DYNAMIC - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsDynamic.common] + PcdFlashNvStorageFtwWorkingSize|gEfiMdeModulePkgTokenSpaceGuid + PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid + PcdFlashNvStorageFtwSpareSize|gEfiMdeModulePkgTokenSpaceGuid + PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + gEfiFirmwareVolumeBlockProtocolGuid AND gEfiAlternateFvBlockGuid diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.msa b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.msa new file mode 100644 index 0000000..7362f47 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.msa @@ -0,0 +1,103 @@ + + + + FtwLite + DXE_DRIVER + 4C862FC6-0E54-4e36-8C8F-FF6F3167951F + 1.0 + Component description file for FtwLite module. + This driver provides fault tolerant write capability for block devices. + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + FtwLite + + + + PcdLib + + + DebugLib + + + UefiDriverEntryPoint + + + BaseMemoryLib + + + MemoryAllocationLib + + + UefiBootServicesTableLib + + + + FtwLite.h + FtwLite.c + FtwMisc.c + FtwWorkSpace.c + FtwLite.dxs + Ia32/Ia32FtwMisc.c + x64/x64FtwMisc.c + Ipf/IpfFtwMisc.c + + + + + + + + gEfiFaultTolerantWriteLiteProtocolGuid + + + gEfiPciRootBridgeIoProtocolGuid + + + gEfiFirmwareVolumeBlockProtocolGuid + + + + + gEfiSystemNvDataFvGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + InitializeFtwLite + + + + + PcdFlashNvStorageFtwSpareBase + gEfiGenericPlatformTokenSpaceGuid + To get base address of the FTW spare block section in NV firmware volume. + + + PcdFlashNvStorageFtwSpareSize + gEfiGenericPlatformTokenSpaceGuid + To get size of the FTW spare block section in NV firmware volume. + + + PcdFlashNvStorageFtwWorkingBase + gEfiGenericPlatformTokenSpaceGuid + To get base address of the FTW working block section in NV firmware volume. + + + PcdFlashNvStorageFtwWorkingSize + gEfiGenericPlatformTokenSpaceGuid + To get size of the FTW working block section in NV firmware volume. + + + diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c new file mode 100644 index 0000000..eb334ea --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c @@ -0,0 +1,530 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. 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. + +Module Name: + + FtwMisc.c + +Abstract: + + Internal functions to support fault tolerant write. + +Revision History + +--*/ + +#include + +BOOLEAN +IsErasedFlashBuffer ( + IN BOOLEAN Polarity, + IN UINT8 *Buffer, + IN UINTN BufferSize + ) +/*++ + +Routine Description: + + Check whether a flash buffer is erased. + +Arguments: + + Polarity - All 1 or all 0 + Buffer - Buffer to check + BufferSize - Size of the buffer + +Returns: + + Erased or not. + +--*/ +{ + UINT8 ErasedValue; + UINT8 *Ptr; + + if (Polarity) { + ErasedValue = 0xFF; + } else { + ErasedValue = 0; + } + + Ptr = Buffer; + while (BufferSize--) { + if (*Ptr++ != ErasedValue) { + return FALSE; + } + } + + return TRUE; +} + +EFI_STATUS +FtwEraseBlock ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + To Erase one block. The size is FTW_BLOCK_SIZE + +Arguments: + FtwLiteDevice - Calling context + FvBlock - FVB Protocol interface + Lba - Lba of the firmware block + +Returns: + EFI_SUCCESS - Block LBA is Erased successfully + Others - Error occurs + +--*/ +{ + return FvBlock->EraseBlocks ( + FvBlock, + Lba, + FtwLiteDevice->NumberOfSpareBlock, + EFI_LBA_LIST_TERMINATOR + ); +} + +EFI_STATUS +FtwEraseSpareBlock ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + + Erase spare block. + +Arguments: + + FtwLiteDevice - Calling context + +Returns: + + Status code + +--*/ +{ + return FtwLiteDevice->FtwBackupFvb->EraseBlocks ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba, + FtwLiteDevice->NumberOfSpareBlock, + EFI_LBA_LIST_TERMINATOR + ); +} + +EFI_STATUS +FtwGetFvbByHandle ( + IN EFI_HANDLE FvBlockHandle, + OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock + ) +/*++ + +Routine Description: + Retrive the proper FVB protocol interface by HANDLE. + +Arguments: + FvBlockHandle - The handle of FVB protocol that provides services for + reading, writing, and erasing the target block. + FvBlock - The interface of FVB protocol + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully +--*/ +{ + // + // To get the FVB protocol interface on the handle + // + return gBS->HandleProtocol ( + FvBlockHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) FvBlock + ); +} + +EFI_STATUS +GetFvbByAddress ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock + ) +/*++ + +Routine Description: + + Get firmware block by address. + +Arguments: + + Address - Address specified the block + FvBlock - The block caller wanted + +Returns: + + Status code + + EFI_NOT_FOUND - Block not found + +--*/ +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_PHYSICAL_ADDRESS FvbBaseAddress; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + + *FvBlock = NULL; + // + // Locate all handles of Fvb protocol + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeBlockProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Search all FVB until find the right one + // + for (Index = 0; Index < HandleCount; Index += 1) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &Fvb + ); + if (EFI_ERROR (Status)) { + Status = EFI_NOT_FOUND; + break; + } + // + // Compare the address and select the right one + // + Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress); + if (EFI_ERROR (Status)) { + continue; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress); + if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + (FwVolHeader->FvLength - 1)))) { + *FvBlock = Fvb; + Status = EFI_SUCCESS; + break; + } + } + + FreePool (HandleBuffer); + return Status; +} + +BOOLEAN +IsInWorkingBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + + Is it in working block? + +Arguments: + + FtwLiteDevice - Calling context + FvBlock - Fvb protocol instance + Lba - The block specified + +Returns: + + In working block or not + +--*/ +{ + // + // If matching the following condition, the target block is in working block. + // 1. Target block is on the FV of working block (Using the same FVB protocol instance). + // 2. Lba falls into the range of working block. + // + return (BOOLEAN) + ( + (FvBlock == FtwLiteDevice->FtwFvBlock) && + (Lba >= FtwLiteDevice->FtwWorkBlockLba) && + (Lba <= FtwLiteDevice->FtwWorkSpaceLba) + ); +} + +EFI_STATUS +FlushSpareBlockToTargetBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Target block is accessed by FvBlock protocol interface. LBA is Lba. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + FvBlock - FVB Protocol interface to access target block + Lba - Lba of the target block + +Returns: + EFI_SUCCESS - Spare block content is copied to target block + EFI_INVALID_PARAMETER - Input parameter error + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +--*/ +{ + EFI_STATUS Status; + UINTN Length; + UINT8 *Buffer; + UINTN Count; + UINT8 *Ptr; + UINTN Index; + + if ((FtwLiteDevice == NULL) || (FvBlock == NULL)) { + return EFI_INVALID_PARAMETER; + } + // + // Allocate a memory buffer + // + Length = FtwLiteDevice->SpareAreaLength; + Buffer = AllocatePool (Length); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Read all content of spare block to memory buffer + // + Ptr = Buffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Count = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Read ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &Count, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + Ptr += Count; + } + // + // Erase the target block + // + Status = FtwEraseBlock (FtwLiteDevice, FvBlock, Lba); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return EFI_ABORTED; + } + // + // Write memory buffer to block, using the FvbBlock protocol interface + // + Ptr = Buffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Count = FtwLiteDevice->SizeOfSpareBlock; + Status = FvBlock->Write (FvBlock, Lba + Index, 0, &Count, Ptr); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status)); + FreePool (Buffer); + return Status; + } + + Ptr += Count; + } + + FreePool (Buffer); + + return Status; +} + +EFI_STATUS +FlushSpareBlockToWorkingBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Working block is accessed by FTW working FVB protocol interface. LBA is + FtwLiteDevice->FtwWorkBlockLba. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - Spare block content is copied to target block + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +Notes: + Since the working block header is important when FTW initializes, the + state of the operation should be handled carefully. The Crc value is + calculated without STATE element. + +--*/ +{ + EFI_STATUS Status; + UINTN Length; + UINT8 *Buffer; + EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader; + EFI_LBA WorkSpaceLbaOffset; + UINTN Count; + UINT8 *Ptr; + UINTN Index; + + // + // Allocate a memory buffer + // + Length = FtwLiteDevice->SpareAreaLength; + Buffer = AllocatePool (Length); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // To guarantee that the WorkingBlockValid is set on spare block + // + WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba; + FtwUpdateFvState ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset, + FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), + WORKING_BLOCK_VALID + ); + // + // Read from spare block to memory buffer + // + Ptr = Buffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Count = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Read ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &Count, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + Ptr += Count; + } + // + // Clear the CRC and STATE, copy data from spare to working block. + // + WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (Buffer + (UINTN) WorkSpaceLbaOffset * FtwLiteDevice->SizeOfSpareBlock + FtwLiteDevice->FtwWorkSpaceBase); + InitWorkSpaceHeader (WorkingBlockHeader); + WorkingBlockHeader->WorkingBlockValid = FTW_ERASE_POLARITY; + WorkingBlockHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY; + + // + // target block is working block, then + // Set WorkingBlockInvalid in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER + // before erase the working block. + // + // Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER, + // WorkingBlockInvalid); + // To skip Signature and Crc: sizeof(EFI_GUID)+sizeof(UINT32). + // + Status = FtwUpdateFvState ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), + WORKING_BLOCK_INVALID + ); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return EFI_ABORTED; + } + + FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockInvalid = FTW_VALID_STATE; + + // + // Erase the working block + // + Status = FtwEraseBlock ( + FtwLiteDevice, + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkBlockLba + ); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return EFI_ABORTED; + } + // + // Write memory buffer to working block, using the FvbBlock protocol interface + // + Ptr = Buffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Count = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwFvBlock->Write ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkBlockLba + Index, + 0, + &Count, + Ptr + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status)); + FreePool (Buffer); + return Status; + } + + Ptr += Count; + } + // + // Since the memory buffer will not be used, free memory Buffer. + // + FreePool (Buffer); + + // + // Update the VALID of the working block + // + // Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER, + // WorkingBlockValid); + // Hardcode offset sizeof(EFI_GUID)+sizeof(UINT32), to skip Signature and Crc + // + Status = FtwUpdateFvState ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), + WORKING_BLOCK_VALID + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockValid = FTW_VALID_STATE; + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c new file mode 100644 index 0000000..00d7d8e --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c @@ -0,0 +1,561 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. 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. + +Module Name: + + FtwWorkSpace.c + +Abstract: + +Revision History + +--*/ + + +#include + +BOOLEAN +IsValidWorkSpace ( + IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader + ) +/*++ + +Routine Description: + Check to see if it is a valid work space. + +Arguments: + WorkingHeader - Pointer of working block header + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + +--*/ +{ + EFI_STATUS Status; + EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader; + + ASSERT (WorkingHeader != NULL); + if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) { + return FALSE; + } + // + // Check signature with gEfiSystemNvDataFvGuid + // + if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) { + return FALSE; + } + // + // Check the CRC of header + // + CopyMem ( + &WorkingBlockHeader, + WorkingHeader, + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER) + ); + + // + // Filter out the Crc and State fields + // + SetMem ( + &WorkingBlockHeader.Crc, + sizeof (UINT32), + FTW_ERASED_BYTE + ); + WorkingBlockHeader.WorkingBlockValid = FTW_ERASE_POLARITY; + WorkingBlockHeader.WorkingBlockInvalid = FTW_ERASE_POLARITY; + + // + // Calculate the Crc of woking block header + // + Status = gBS->CalculateCrc32 ( + (UINT8 *) &WorkingBlockHeader, + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), + &WorkingBlockHeader.Crc + ); + ASSERT_EFI_ERROR (Status); + + if (WorkingBlockHeader.Crc != WorkingHeader->Crc) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Work block header CRC check error\n")); + return FALSE; + } + + return TRUE; +} + +EFI_STATUS +InitWorkSpaceHeader ( + IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader + ) +/*++ + +Routine Description: + Initialize a work space when there is no work space. + +Arguments: + WorkingHeader - Pointer of working block header + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + +--*/ +{ + EFI_STATUS Status; + + ASSERT (WorkingHeader != NULL); + + // + // Here using gEfiSystemNvDataFvGuid as the signature. + // + CopyMem ( + &WorkingHeader->Signature, + &gEfiSystemNvDataFvGuid, + sizeof (EFI_GUID) + ); + WorkingHeader->WriteQueueSize = FTW_WORKING_QUEUE_SIZE; + + // + // Crc is calculated with all the fields except Crc and STATE + // + WorkingHeader->WorkingBlockValid = FTW_ERASE_POLARITY; + WorkingHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY; + SetMem (&WorkingHeader->Crc, sizeof (UINT32), FTW_ERASED_BYTE); + + // + // Calculate the CRC value + // + Status = gBS->CalculateCrc32 ( + (UINT8 *) WorkingHeader, + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), + &WorkingHeader->Crc + ); + ASSERT_EFI_ERROR (Status); + + // + // Restore the WorkingBlockValid flag to VALID state + // + WorkingHeader->WorkingBlockValid = FTW_VALID_STATE; + WorkingHeader->WorkingBlockInvalid = FTW_INVALID_STATE; + + return EFI_SUCCESS; +} + +EFI_STATUS +FtwUpdateFvState ( + IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINT8 NewBit + ) +/*++ + +Routine Description: + Update a bit of state on a block device. The location of the bit is + calculated by the (Lba, Offset, bit). Here bit is determined by the + the name of a certain bit. + +Arguments: + FvBlock - FVB Protocol interface to access SrcBlock and DestBlock + Lba - Lba of a block + Offset - Offset on the Lba + NewBit - New value that will override the old value if it can be change + +Returns: + EFI_SUCCESS - A state bit has been updated successfully + Others - Access block device error. + +Notes: + Assume all bits of State are inside the same BYTE. + + EFI_ABORTED - Read block fail +--*/ +{ + EFI_STATUS Status; + UINT8 State; + UINTN Length; + + // + // Read state from device, assume State is only one byte. + // + Length = sizeof (UINT8); + Status = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + State ^= FTW_POLARITY_REVERT; + State = (UINT8) (State | NewBit); + State ^= FTW_POLARITY_REVERT; + + // + // Write state back to device + // + Length = sizeof (UINT8); + Status = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State); + + return Status; +} + +EFI_STATUS +FtwGetLastRecord ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + OUT EFI_FTW_LITE_RECORD **FtwLastRecord + ) +/*++ + +Routine Description: + Get the last Write record pointer. + The last record is the record whose 'complete' state hasn't been set. + After all, this header may be a EMPTY header entry for next Allocate. + +Arguments: + FtwLiteDevice - Private data of this driver + FtwLastRecord - Pointer to retrieve the last write record + +Returns: + EFI_SUCCESS - Get the last write record successfully + EFI_ABORTED - The FTW work space is damaged + +--*/ +{ + EFI_FTW_LITE_RECORD *Record; + + Record = (EFI_FTW_LITE_RECORD *) (FtwLiteDevice->FtwWorkSpaceHeader + 1); + while (Record->WriteCompleted == FTW_VALID_STATE) { + // + // If Offset exceed the FTW work space boudary, return error. + // + if ((UINTN) ((UINT8 *) Record - FtwLiteDevice->FtwWorkSpace) > FtwLiteDevice->FtwWorkSpaceSize) { + return EFI_ABORTED; + } + + Record++; + } + // + // Last write record is found + // + *FtwLastRecord = Record; + return EFI_SUCCESS; +} + +EFI_STATUS +WorkSpaceRefresh ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Read from working block to refresh the work space in memory. + +Arguments: + FtwLiteDevice - Point to private data of FTW driver + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully. + +--*/ +{ + EFI_STATUS Status; + UINTN Length; + UINTN Offset; + EFI_FTW_LITE_RECORD *Record; + + // + // Initialize WorkSpace as FTW_ERASED_BYTE + // + SetMem ( + FtwLiteDevice->FtwWorkSpace, + FtwLiteDevice->FtwWorkSpaceSize, + FTW_ERASED_BYTE + ); + + // + // Read from working block + // + Length = FtwLiteDevice->FtwWorkSpaceSize; + Status = FtwLiteDevice->FtwFvBlock->Read ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkSpaceLba, + FtwLiteDevice->FtwWorkSpaceBase, + &Length, + FtwLiteDevice->FtwWorkSpace + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Refresh the FtwLastRecord + // + Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); + + Record = FtwLiteDevice->FtwLastRecord; + Offset = (UINTN) (UINT8 *) Record - (UINTN) FtwLiteDevice->FtwWorkSpace; + + // + // IF work space has error or Record is out of the workspace limit, THEN + // call reclaim. + // + if (EFI_ERROR (Status) || (Offset + WRITE_TOTAL_SIZE >= FtwLiteDevice->FtwWorkSpaceSize)) { + // + // reclaim work space in working block. + // + Status = FtwReclaimWorkSpace (FtwLiteDevice); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: Reclaim workspace - %r\n", Status)); + return EFI_ABORTED; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +CleanupWorkSpace ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + IN OUT UINT8 *FtwSpaceBuffer, + IN UINTN BufferSize + ) +/*++ + +Routine Description: + Reclaim the work space. Get rid of all the completed write records + and write records in the Fault Tolerant work space. + +Arguments: + FtwLiteDevice - Point to private data of FTW driver + FtwSpaceBuffer - Buffer to contain the reclaimed clean data + BufferSize - Size of the FtwSpaceBuffer + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_BUFFER_TOO_SMALL - The FtwSpaceBuffer is too small + EFI_ABORTED - The function could not complete successfully. + +--*/ +{ + UINTN Length; + EFI_FTW_LITE_RECORD *Record; + + // + // To check if the buffer is large enough + // + Length = FtwLiteDevice->FtwWorkSpaceSize; + if (BufferSize < Length) { + return EFI_BUFFER_TOO_SMALL; + } + // + // Clear the content of buffer that will save the new work space data + // + SetMem (FtwSpaceBuffer, Length, FTW_ERASED_BYTE); + + // + // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer + // + CopyMem ( + FtwSpaceBuffer, + FtwLiteDevice->FtwWorkSpaceHeader, + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER) + ); + + // + // Get the last record + // + Record = FtwLiteDevice->FtwLastRecord; + if ((Record != NULL) && (Record->WriteAllocated == FTW_VALID_STATE) && (Record->WriteCompleted != FTW_VALID_STATE)) { + CopyMem ( + (UINT8 *) FtwSpaceBuffer + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), + Record, + WRITE_TOTAL_SIZE + ); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +FtwReclaimWorkSpace ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Reclaim the work space on the working block. + +Arguments: + FtwLiteDevice - Point to private data of FTW driver + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +--*/ +{ + EFI_STATUS Status; + UINT8 *TempBuffer; + UINTN TempBufferSize; + UINT8 *Ptr; + UINTN Length; + UINTN Index; + UINTN SpareBufferSize; + UINT8 *SpareBuffer; + EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader; + + DEBUG ((EFI_D_FTW_LITE, "FtwLite: start to reclaim work space\n")); + + // + // Read all original data from working block to a memory buffer + // + TempBufferSize = FtwLiteDevice->SpareAreaLength; + TempBuffer = AllocateZeroPool (TempBufferSize); + if (TempBuffer != NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ptr = TempBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Length = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwFvBlock->Read ( + FtwLiteDevice->FtwFvBlock, + FtwLiteDevice->FtwWorkBlockLba + Index, + 0, + &Length, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (TempBuffer); + return EFI_ABORTED; + } + + Ptr += Length; + } + // + // Clean up the workspace, remove all the completed records. + // + Ptr = TempBuffer + + ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) * + FtwLiteDevice->SizeOfSpareBlock + FtwLiteDevice->FtwWorkSpaceBase; + + Status = CleanupWorkSpace ( + FtwLiteDevice, + Ptr, + FtwLiteDevice->FtwWorkSpaceSize + ); + + CopyMem ( + FtwLiteDevice->FtwWorkSpace, + Ptr, + FtwLiteDevice->FtwWorkSpaceSize + ); + + Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); + + // + // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID + // + WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr; + WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE; + WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE; + + // + // Try to keep the content of spare block + // Save spare block into a spare backup memory buffer (Sparebuffer) + // + SpareBufferSize = FtwLiteDevice->SpareAreaLength; + SpareBuffer = AllocatePool (SpareBufferSize); + if (SpareBuffer == NULL) { + FreePool (TempBuffer); + return EFI_OUT_OF_RESOURCES; + } + + Ptr = SpareBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Length = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Read ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &Length, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (TempBuffer); + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Ptr += Length; + } + // + // Write the memory buffer to spare block + // + Status = FtwEraseSpareBlock (FtwLiteDevice); + Ptr = TempBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Length = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Write ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &Length, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (TempBuffer); + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Ptr += Length; + } + // + // Free TempBuffer + // + FreePool (TempBuffer); + + // + // Write the spare block to working block + // + Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); + if (EFI_ERROR (Status)) { + FreePool (SpareBuffer); + return Status; + } + // + // Restore spare backup buffer into spare block , if no failure happened during FtwWrite. + // + Status = FtwEraseSpareBlock (FtwLiteDevice); + Ptr = SpareBuffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Length = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Write ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &Length, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (SpareBuffer); + return EFI_ABORTED; + } + + Ptr += Length; + } + + FreePool (SpareBuffer); + + DEBUG ((EFI_D_FTW_LITE, "FtwLite: reclaim work space success\n")); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ia32/Ia32FtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ia32/Ia32FtwMisc.c new file mode 100644 index 0000000..6425f29 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ia32/Ia32FtwMisc.c @@ -0,0 +1,403 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. 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. + +Module Name: + + Ia32FtwMisc.c + +Abstract: + + Ia32 platform related code to support FtwLite.. + +Revision History + +--*/ + + +#include + +// +// MACROs for boot block update +// +#define BOOT_BLOCK_BASE 0xFFFF0000 + +// +// (LPC -- D31:F0) +// +#define LPC_BUS_NUMBER 0x00 +#define LPC_DEVICE_NUMBER 0x1F +#define LPC_IF 0xF0 +// +// Top swap +// +#define GEN_STATUS 0xD4 +#define TOP_SWAP_BIT (1 << 13) + +STATIC +UINT32 +ReadPciRegister ( + IN UINT32 Offset + ) +/*++ + +Routine Description: + + Read PCI register value. + +Arguments: + + Offset - Offset of the register + +Returns: + + The value. + +--*/ +{ + EFI_STATUS Status; + UINT32 Value; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + Value = 0; + Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status)); + return 0; + } + + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + EfiPciWidthUint32, + EFI_PCI_ADDRESS ( + LPC_BUS_NUMBER, + LPC_DEVICE_NUMBER, + LPC_IF, + Offset + ), + 1, + &Value + ); + ASSERT_EFI_ERROR (Status); + + return Value; +} + +STATIC +EFI_STATUS +GetSwapState ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + OUT BOOLEAN *SwapState + ) +/*++ + +Routine Description: + + Get swap state + +Arguments: + + FtwLiteDevice - Calling context + SwapState - Swap state + +Returns: + + EFI_SUCCESS - State successfully got + +--*/ +{ + // + // Top swap status is 13 bit + // + *SwapState = (BOOLEAN) ((ReadPciRegister (GEN_STATUS) & TOP_SWAP_BIT) != 0); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SetSwapState ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + IN BOOLEAN TopSwap + ) +/*++ + +Routine Description: + Set swap state. + +Arguments: + FtwLiteDevice - Indicates a pointer to the calling context. + TopSwap - New swap state + +Returns: + EFI_SUCCESS - The function completed successfully + +Note: + the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that + software will not be able to clear the Top-Swap bit until the system is + rebooted without GNT[A]# being pulled down. + +--*/ +{ + UINT32 GenStatus; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + EFI_STATUS Status; + + // + // Top-Swap bit (bit 13, D31: F0, Offset D4h) + // + GenStatus = ReadPciRegister (GEN_STATUS); + + // + // Set 13 bit, according to input NewSwapState + // + if (TopSwap) { + GenStatus |= TOP_SWAP_BIT; + } else { + GenStatus &= ~TOP_SWAP_BIT; + } + + Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status)); + return Status; + } + // + // Write back the GenStatus register + // + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + EfiPciWidthUint32, + EFI_PCI_ADDRESS ( + LPC_BUS_NUMBER, + LPC_DEVICE_NUMBER, + LPC_IF, + GEN_STATUS + ), + 1, + &GenStatus + ); + + DEBUG_CODE_BEGIN (); + if (TopSwap) { + DEBUG ((EFI_D_ERROR, "SAR: Set top swap\n")); + } else { + DEBUG ((EFI_D_ERROR, "SAR: Clear top swap\n")); + } + DEBUG_CODE_END (); + + return EFI_SUCCESS; +} + +BOOLEAN +IsBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + + Check whether the block is a boot block. + +Arguments: + + FtwLiteDevice - Calling context + FvBlock - Fvb protocol instance + Lba - Lba value + +Returns: + + Is a boot block or not + +--*/ +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *BootFvb; + + Status = GetFvbByAddress (BOOT_BLOCK_BASE, &BootFvb); + if (EFI_ERROR (Status)) { + return FALSE; + } + // + // Compare the Fvb + // + return (BOOLEAN) (FvBlock == BootFvb); +} + +EFI_STATUS +FlushSpareBlockToBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Boot block is accessed by BootFvb protocol interface. LBA is 0. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - Spare block content is copied to boot block + EFI_INVALID_PARAMETER - Input parameter error + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +Notes: + FTW will do extra work on boot block update. + FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL, + which is produced by a chipset driver. + + FTW updating boot block steps: + 1. Erase top swap block (0xFFFE-0xFFFEFFFF) and write data to it ready + 2. Read data from top swap block to memory buffer + 3. SetSwapState(EFI_SWAPPED) + 4. Erasing boot block (0xFFFF-0xFFFFFFFF) + 5. Programming boot block until the boot block is ok. + 6. SetSwapState(UNSWAPPED) + + Notes: + 1. Since the SwapState bit is saved in CMOS, FTW can restore and continue + even in the scenario of power failure. + 2. FTW shall not allow to update boot block when battery state is error. + +--*/ +{ + EFI_STATUS Status; + UINTN Length; + UINT8 *Buffer; + UINTN Count; + UINT8 *Ptr; + UINTN Index; + BOOLEAN TopSwap; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *BootFvb; + EFI_LBA BootLba; + + // + // Allocate a memory buffer + // + Length = FtwLiteDevice->SpareAreaLength; + Buffer = AllocatePool (Length); + if (Buffer == NULL) { + } + // + // Get TopSwap bit state + // + Status = GetSwapState (FtwLiteDevice, &TopSwap); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FtwLite: Get Top Swapped status - %r\n", Status)); + FreePool (Buffer); + return EFI_ABORTED; + } + + if (TopSwap) { + // + // Get FVB of current boot block + // + Status = GetFvbByAddress (FtwLiteDevice->SpareAreaAddress + FTW_BLOCK_SIZE, &BootFvb); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + // + // Read data from current boot block + // + BootLba = 0; + Ptr = Buffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Count = FtwLiteDevice->SizeOfSpareBlock; + Status = BootFvb->Read ( + BootFvb, + BootLba + Index, + 0, + &Count, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + Ptr += Count; + } + + } else { + // + // Read data from spare block + // + Ptr = Buffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Count = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Read ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &Count, + Ptr + ); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + Ptr += Count; + } + // + // Set TopSwap bit + // + Status = SetSwapState (FtwLiteDevice, TRUE); + DEBUG ((EFI_D_ERROR, "FtwLite: Set Swap State - %r\n", Status)); + ASSERT_EFI_ERROR (Status); + } + // + // Erase boot block. After setting TopSwap bit, it's spare block now! + // + Status = FtwEraseSpareBlock (FtwLiteDevice); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return EFI_ABORTED; + } + // + // Write memory buffer to currenet spare block + // + Ptr = Buffer; + for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { + Count = FtwLiteDevice->SizeOfSpareBlock; + Status = FtwLiteDevice->FtwBackupFvb->Write ( + FtwLiteDevice->FtwBackupFvb, + FtwLiteDevice->FtwSpareLba + Index, + 0, + &Count, + Ptr + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write boot block - %r\n", Status)); + FreePool (Buffer); + return Status; + } + + Ptr += Count; + } + + FreePool (Buffer); + + // + // Clear TopSwap bit + // + Status = SetSwapState (FtwLiteDevice, FALSE); + DEBUG ((EFI_D_ERROR, "FtwLite: Clear Swap State - %r\n", Status)); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ipf/IpfFtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ipf/IpfFtwMisc.c new file mode 100644 index 0000000..d31883b --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/Ipf/IpfFtwMisc.c @@ -0,0 +1,143 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. 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. + +Module Name: + + IpfFtwMisc.c + +Abstract: + + Ipf platform related code to support FtwLite.. + +Revision History + +--*/ + + +#include + +// +// MACROs for boot block update +// +#define BOOT_BLOCK_BASE + +STATIC +EFI_STATUS +GetSwapState ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + OUT BOOLEAN *SwapState + ) +/*++ + +Routine Description: + + Get swap state + +Arguments: + + FtwLiteDevice - Calling context + SwapState - Swap state + +Returns: + + EFI_SUCCESS - State successfully got + +--*/ +{ + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SetSwapState ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + IN BOOLEAN TopSwap + ) +/*++ + +Routine Description: + Set swap state. + +Arguments: + FtwLiteDevice - Indicates a pointer to the calling context. + TopSwap - New swap state + +Returns: + EFI_SUCCESS - The function completed successfully + +Note: + the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that + software will not be able to clear the Top-Swap bit until the system is + rebooted without GNT[A]# being pulled down. + +--*/ +{ + return EFI_SUCCESS; +} + +BOOLEAN +IsBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + + Check whether the block is a boot block. + +Arguments: + + FtwLiteDevice - Calling context + FvBlock - Fvb protocol instance + Lba - Lba value + +Returns: + + Is a boot block or not + +--*/ +{ + // + // IPF doesn't support safe bootblock update + // so treat bootblock as normal block + // + return FALSE; +} + +EFI_STATUS +FlushSpareBlockToBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Boot block is accessed by BootFvb protocol interface. LBA is 0. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - Spare block content is copied to boot block + EFI_INVALID_PARAMETER - Input parameter error + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +Notes: + +--*/ +{ + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/x64/x64FtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/x64/x64FtwMisc.c new file mode 100644 index 0000000..d8e3a03 --- /dev/null +++ b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/x64/x64FtwMisc.c @@ -0,0 +1,140 @@ + +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. 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. + +Module Name: + + x64FtwMisc.c + +Abstract: + + X64 platform related code to support FtwLite.. + +Revision History + +--*/ + + +#include + +// +// MACROs for boot block update +// +#define BOOT_BLOCK_BASE + +// STATIC +EFI_STATUS +GetSwapState ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + OUT BOOLEAN *SwapState + ) +/*++ + +Routine Description: + + Get swap state + +Arguments: + + FtwLiteDevice - Calling context + SwapState - Swap state + +Returns: + + EFI_SUCCESS - State successfully got + +--*/ +{ + return EFI_SUCCESS; +} + +// STATIC +EFI_STATUS +SetSwapState ( + IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, + IN BOOLEAN TopSwap + ) +/*++ + +Routine Description: + Set swap state. + +Arguments: + FtwLiteDevice - Indicates a pointer to the calling context. + TopSwap - New swap state + +Returns: + EFI_SUCCESS - The function completed successfully + +Note: + the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that + software will not be able to clear the Top-Swap bit until the system is + rebooted without GNT[A]# being pulled down. + +--*/ +{ + return EFI_SUCCESS; +} + +BOOLEAN +IsBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice, + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, + EFI_LBA Lba + ) +/*++ + +Routine Description: + + Check whether the block is a boot block. + +Arguments: + + FtwLiteDevice - Calling context + FvBlock - Fvb protocol instance + Lba - Lba value + +Returns: + + Is a boot block or not + +--*/ +{ + return FALSE; +} + +EFI_STATUS +FlushSpareBlockToBootBlock ( + EFI_FTW_LITE_DEVICE *FtwLiteDevice + ) +/*++ + +Routine Description: + Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. + Spare block is accessed by FTW backup FVB protocol interface. LBA is + FtwLiteDevice->FtwSpareLba. + Boot block is accessed by BootFvb protocol interface. LBA is 0. + +Arguments: + FtwLiteDevice - The private data of FTW_LITE driver + +Returns: + EFI_SUCCESS - Spare block content is copied to boot block + EFI_INVALID_PARAMETER - Input parameter error + EFI_OUT_OF_RESOURCES - Allocate memory error + EFI_ABORTED - The function could not complete successfully + +Notes: + +--*/ +{ + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.c deleted file mode 100644 index 38fe11d..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.c +++ /dev/null @@ -1,931 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. 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. - - -Module Name: - - FtwLite.c - -Abstract: - - This is a simple fault tolerant write driver, based on PlatformFd library. - And it only supports write BufferSize <= SpareAreaLength. - - This boot service only protocol provides fault tolerant write capability for - block devices. The protocol has internal non-volatile intermediate storage - of the data and private information. It should be able to recover - automatically from a critical fault, such as power failure. - -Notes: - - The implementation uses an FTW Lite (Fault Tolerant Write) Work Space. - This work space is a memory copy of the work space on the Woring Block, - the size of the work space is the FTW_WORK_SPACE_SIZE bytes. - ---*/ - -#include - -// -// In write function, we should check the target range to prevent the user -// from writing Spare block and Working space directly. -// -// -// Fault Tolerant Write Protocol API -// -EFI_STATUS -EFIAPI -FtwLiteWrite ( - IN EFI_FTW_LITE_PROTOCOL *This, - IN EFI_HANDLE FvbHandle, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN VOID *Buffer - ) -/*++ - -Routine Description: - Starts a target block update. This function will record data about write - in fault tolerant storage and will complete the write in a recoverable - manner, ensuring at all times that either the original contents or - the modified contents are available. - -Arguments: - This - Calling context - FvbHandle - The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - Lba - The logical block address of the target block. - Offset - The offset within the target block to place the data. - NumBytes - The number of bytes to write to the target block. - Buffer - The data to write. - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_BAD_BUFFER_SIZE - The write would span a target block, which is not - a valid action. - EFI_ACCESS_DENIED - No writes have been allocated. - EFI_NOT_FOUND - Cannot find FVB by handle. - EFI_OUT_OF_RESOURCES - Cannot allocate memory. - EFI_ABORTED - The function could not complete successfully. - ---*/ -{ - EFI_STATUS Status; - EFI_FTW_LITE_DEVICE *FtwLiteDevice; - EFI_FTW_LITE_RECORD *Record; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_PHYSICAL_ADDRESS FvbPhysicalAddress; - UINTN MyLength; - UINTN MyOffset; - UINTN MyBufferSize; - UINT8 *MyBuffer; - UINTN SpareBufferSize; - UINT8 *SpareBuffer; - UINTN Index; - UINT8 *Ptr; - EFI_DEV_PATH_PTR DevPtr; - - // - // Refresh work space and get last record - // - FtwLiteDevice = FTW_LITE_CONTEXT_FROM_THIS (This); - Status = WorkSpaceRefresh (FtwLiteDevice); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - Record = FtwLiteDevice->FtwLastRecord; - - // - // Check the flags of last write record - // - if ((Record->WriteAllocated == FTW_VALID_STATE) || (Record->SpareCompleted == FTW_VALID_STATE)) { - return EFI_ACCESS_DENIED; - } - // - // IF former record has completed, THEN use next record - // - if (Record->WriteCompleted == FTW_VALID_STATE) { - Record++; - FtwLiteDevice->FtwLastRecord = Record; - } - - MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; - - // - // Check if the input data can fit within the target block - // - if ((Offset +*NumBytes) > FtwLiteDevice->SpareAreaLength) { - return EFI_BAD_BUFFER_SIZE; - } - // - // Check if there is enough free space for allocate a record - // - if ((MyOffset + WRITE_TOTAL_SIZE) > FtwLiteDevice->FtwWorkSpaceSize) { - Status = FtwReclaimWorkSpace (FtwLiteDevice); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim work space - %r", Status)); - return EFI_ABORTED; - } - } - // - // Get the FVB protocol by handle - // - Status = FtwGetFvbByHandle (FvbHandle, &Fvb); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - // - // Allocate a write record in workspace. - // Update Header->WriteAllocated as VALID - // - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + MyOffset, - WRITE_ALLOCATED - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Allocate record - %r\n", Status)); - return EFI_ABORTED; - } - - Record->WriteAllocated = FTW_VALID_STATE; - - // - // Prepare data of write record, filling DevPath with memory mapped address. - // - DevPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath; - DevPtr.MemMap->Header.Type = HARDWARE_DEVICE_PATH; - DevPtr.MemMap->Header.SubType = HW_MEMMAP_DP; - SetDevicePathNodeLength (&DevPtr.MemMap->Header, sizeof (MEMMAP_DEVICE_PATH)); - - Status = Fvb->GetPhysicalAddress (Fvb, &FvbPhysicalAddress); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Get FVB physical address - %r\n", Status)); - return EFI_ABORTED; - } - - DevPtr.MemMap->MemoryType = EfiMemoryMappedIO; - DevPtr.MemMap->StartingAddress = FvbPhysicalAddress; - DevPtr.MemMap->EndingAddress = FvbPhysicalAddress +*NumBytes; - // - // ignored! - // - Record->Lba = Lba; - Record->Offset = Offset; - Record->NumBytes = *NumBytes; - - // - // Write the record to the work space. - // - MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; - MyLength = FTW_LITE_RECORD_SIZE; - - Status = FtwLiteDevice->FtwFvBlock->Write ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + MyOffset, - &MyLength, - (UINT8 *) Record - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Record has been written to working block, then write data. - // - // - // Allocate a memory buffer - // - MyBufferSize = FtwLiteDevice->SpareAreaLength; - MyBuffer = AllocatePool (MyBufferSize); - if (MyBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Starting at Lba, if the number of the rest blocks on Fvb is less - // than NumberOfSpareBlock. - // - // - // Read all original data from target block to memory buffer - // - if (IsInWorkingBlock (FtwLiteDevice, Fvb, Lba)) { - // - // If target block falls into working block, we must follow the process of - // updating working block. - // - Ptr = MyBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - MyLength = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwFvBlock->Read ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkBlockLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (MyBuffer); - return EFI_ABORTED; - } - - Ptr += MyLength; - } - // - // Update Offset by adding the offset from the start LBA of working block to - // the target LBA. The target block can not span working block! - // - Offset = (((UINTN) (Lba - FtwLiteDevice->FtwWorkBlockLba)) * FtwLiteDevice->SizeOfSpareBlock + Offset); - ASSERT ((Offset +*NumBytes) <= FtwLiteDevice->SpareAreaLength); - - } else { - - Ptr = MyBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - MyLength = FtwLiteDevice->SizeOfSpareBlock; - Status = Fvb->Read (Fvb, Lba + Index, 0, &MyLength, Ptr); - if (EFI_ERROR (Status)) { - FreePool (MyBuffer); - return EFI_ABORTED; - } - - Ptr += MyLength; - } - } - // - // Overwrite the updating range data with - // the input buffer content - // - CopyMem (MyBuffer + Offset, Buffer, *NumBytes); - - // - // Try to keep the content of spare block - // Save spare block into a spare backup memory buffer (Sparebuffer) - // - SpareBufferSize = FtwLiteDevice->SpareAreaLength; - SpareBuffer = AllocatePool (SpareBufferSize); - if (SpareBuffer == NULL) { - FreePool (MyBuffer); - return EFI_OUT_OF_RESOURCES; - } - - Ptr = SpareBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - MyLength = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (MyBuffer); - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += MyLength; - } - // - // Write the memory buffer to spare block - // Don't forget to erase Flash first. - // - Status = FtwEraseSpareBlock (FtwLiteDevice); - Ptr = MyBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - MyLength = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (MyBuffer); - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += MyLength; - } - // - // Free MyBuffer - // - FreePool (MyBuffer); - - // - // Set the SpareCompleteD in the FTW record, - // - MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + MyOffset, - SPARE_COMPLETED - ); - if (EFI_ERROR (Status)) { - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Record->SpareCompleted = FTW_VALID_STATE; - - // - // Since the content has already backuped in spare block, the write is - // guaranteed to be completed with fault tolerant manner. - // - Status = FtwWriteRecord (FtwLiteDevice, Fvb); - if (EFI_ERROR (Status)) { - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Record++; - FtwLiteDevice->FtwLastRecord = Record; - - // - // Restore spare backup buffer into spare block , if no failure happened during FtwWrite. - // - Status = FtwEraseSpareBlock (FtwLiteDevice); - Ptr = SpareBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - MyLength = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += MyLength; - } - // - // All success. - // - FreePool (SpareBuffer); - - DEBUG ( - (EFI_D_FTW_LITE, - "FtwLite: Write() success, (Lba:Offset)=(%lx:0x%x), NumBytes: 0x%x\n", - Lba, - Offset, - *NumBytes) - ); - - return EFI_SUCCESS; -} - - -EFI_STATUS -FtwWriteRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb - ) -/*++ - -Routine Description: - Write a record with fault tolerant mannaer. - Since the content has already backuped in spare block, the write is - guaranteed to be completed with fault tolerant manner. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - Fvb - The FVB protocol that provides services for - reading, writing, and erasing the target block. - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully - ---*/ -{ - EFI_STATUS Status; - EFI_FTW_LITE_RECORD *Record; - EFI_LBA WorkSpaceLbaOffset; - UINTN Offset; - - // - // Spare Complete but Destination not complete, - // Recover the targt block with the spare block. - // - Record = FtwLiteDevice->FtwLastRecord; - - // - // IF target block is working block, THEN Flush Spare Block To Working Block; - // ELSE IF target block is boot block, THEN Flush Spare Block To boot Block; - // ELSE flush spare block to normal target block.ENDIF - // - if (IsInWorkingBlock (FtwLiteDevice, Fvb, Record->Lba)) { - // - // If target block is working block, Attention: - // it's required to set SPARE_COMPLETED to spare block. - // - WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba; - Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset, - FtwLiteDevice->FtwWorkSpaceBase + Offset, - SPARE_COMPLETED - ); - ASSERT_EFI_ERROR (Status); - - Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); - } else if (IsBootBlock (FtwLiteDevice, Fvb, Record->Lba)) { - // - // Update boot block - // - Status = FlushSpareBlockToBootBlock (FtwLiteDevice); - } else { - // - // Update blocks other than working block or boot block - // - Status = FlushSpareBlockToTargetBlock (FtwLiteDevice, Fvb, Record->Lba); - } - - ASSERT_EFI_ERROR (Status); - - // - // Set WriteCompleted flag in record - // - Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + Offset, - WRITE_COMPLETED - ); - ASSERT_EFI_ERROR (Status); - - Record->WriteCompleted = FTW_VALID_STATE; - return EFI_SUCCESS; -} - - -EFI_STATUS -FtwRestart ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Restarts a previously interrupted write. The caller must provide the - block protocol needed to complete the interrupted write. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - FvbHandle - The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ACCESS_DENIED - No pending writes exist - EFI_NOT_FOUND - FVB protocol not found by the handle - EFI_ABORTED - The function could not complete successfully - ---*/ -{ - EFI_STATUS Status; - EFI_FTW_LITE_RECORD *Record; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_DEV_PATH_PTR DevPathPtr; - - // - // Spare Completed but Destination not complete, - // Recover the targt block with the spare block. - // - Record = FtwLiteDevice->FtwLastRecord; - - // - // Only support memory mapped FVB device path by now. - // - DevPathPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath; - if (!((DevPathPtr.MemMap->Header.Type == HARDWARE_DEVICE_PATH) && (DevPathPtr.MemMap->Header.SubType == HW_MEMMAP_DP)) - ) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Device Path is not memory mapped\n")); - return EFI_ABORTED; - } - - Status = GetFvbByAddress (DevPathPtr.MemMap->StartingAddress, &Fvb); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - // - // Since the content has already backuped in spare block, the write is - // guaranteed to be completed with fault tolerant manner. - // - Status = FtwWriteRecord (FtwLiteDevice, Fvb); - DEBUG ((EFI_D_FTW_INFO, "FtwLite: Restart() - %r\n", Status)); - - Record++; - FtwLiteDevice->FtwLastRecord = Record; - - // - // Erase Spare block - // This is restart, no need to keep spareblock content. - // - FtwEraseSpareBlock (FtwLiteDevice); - - return Status; -} - - -EFI_STATUS -FtwAbort ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Aborts all previous allocated writes. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - EFI_NOT_FOUND - No allocated writes exist. - ---*/ -{ - EFI_STATUS Status; - UINTN Offset; - - if (FtwLiteDevice->FtwLastRecord->WriteCompleted == FTW_VALID_STATE) { - return EFI_NOT_FOUND; - } - // - // Update the complete state of the header as VALID and abort. - // - Offset = (UINT8 *) FtwLiteDevice->FtwLastRecord - FtwLiteDevice->FtwWorkSpace; - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + Offset, - WRITE_COMPLETED - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - FtwLiteDevice->FtwLastRecord->WriteCompleted = FTW_VALID_STATE; - - Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); - - // - // Erase the spare block - // - Status = FtwEraseSpareBlock (FtwLiteDevice); - - DEBUG ((EFI_D_FTW_INFO, "FtwLite: Abort() success \n")); - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -InitializeFtwLite ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -/*++ - Routine Description: - This function is the entry point of the Fault Tolerant Write driver. - - Arguments: - ImageHandle - EFI_HANDLE: A handle for the image that is initializing - this driver - SystemTable - EFI_SYSTEM_TABLE: A pointer to the EFI system table - - Returns: - EFI_SUCCESS - FTW has finished the initialization - EFI_ABORTED - FTW initialization error - ---*/ -{ - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - UINTN Index; - EFI_HANDLE *HandleBuffer; - UINTN HandleCount; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_PHYSICAL_ADDRESS BaseAddress; - EFI_FTW_LITE_DEVICE *FtwLiteDevice; - EFI_FTW_LITE_RECORD *Record; - UINTN Length; - EFI_STATUS Status; - UINTN Offset; - EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry; - UINT32 LbaIndex; - - // - // Allocate Private data of this driver, - // INCLUDING THE FtwWorkSpace[FTW_WORK_SPACE_SIZE]. - // - FtwLiteDevice = NULL; - FtwLiteDevice = AllocatePool (sizeof (EFI_FTW_LITE_DEVICE) + FTW_WORK_SPACE_SIZE); - if (FtwLiteDevice != NULL) { - Status = EFI_SUCCESS; - } else { - Status = EFI_OUT_OF_RESOURCES; - } - - ASSERT_EFI_ERROR (Status); - - ZeroMem (FtwLiteDevice, sizeof (EFI_FTW_LITE_DEVICE)); - FtwLiteDevice->Signature = FTW_LITE_DEVICE_SIGNATURE; - - // - // Initialize other parameters, and set WorkSpace as FTW_ERASED_BYTE. - // - FtwLiteDevice->FtwWorkSpace = (UINT8 *) (FtwLiteDevice + 1); - FtwLiteDevice->FtwWorkSpaceSize = FTW_WORK_SPACE_SIZE; - SetMem ( - FtwLiteDevice->FtwWorkSpace, - FtwLiteDevice->FtwWorkSpaceSize, - FTW_ERASED_BYTE - ); - FtwLiteDevice->FtwWorkSpaceHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FtwLiteDevice->FtwWorkSpace; - - FtwLiteDevice->FtwLastRecord = NULL; - - FtwLiteDevice->WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwWorkingBase); - FtwLiteDevice->WorkSpaceLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwWorkingSize); - - FtwLiteDevice->SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwSpareBase); - FtwLiteDevice->SpareAreaLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwSpareSize); - - ASSERT ((FtwLiteDevice->WorkSpaceLength != 0) && (FtwLiteDevice->SpareAreaLength != 0)); - - // - // Locate FVB protocol - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareVolumeBlockProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - ASSERT_EFI_ERROR (Status); - - ASSERT (HandleCount > 0); - - FtwLiteDevice->FtwFvBlock = NULL; - FtwLiteDevice->FtwBackupFvb = NULL; - FtwLiteDevice->FtwWorkSpaceLba = (EFI_LBA) (-1); - FtwLiteDevice->FtwSpareLba = (EFI_LBA) (-1); - for (Index = 0; Index < HandleCount; Index += 1) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID **) &Fvb - ); - ASSERT_EFI_ERROR (Status); - - Status = Fvb->GetPhysicalAddress (Fvb, &BaseAddress); - if (EFI_ERROR (Status)) { - continue; - } - - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) BaseAddress); - - if ((FtwLiteDevice->WorkSpaceAddress >= BaseAddress) && - (FtwLiteDevice->WorkSpaceAddress <= (BaseAddress + FwVolHeader->FvLength)) - ) { - FtwLiteDevice->FtwFvBlock = Fvb; - // - // To get the LBA of work space - // - if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) { - // - // FV may have multiple types of BlockLength - // - FvbMapEntry = &FwVolHeader->BlockMap[0]; - while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) { - for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { - if (FtwLiteDevice->WorkSpaceAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex)) { - FtwLiteDevice->FtwWorkSpaceLba = LbaIndex - 1; - // - // Get the Work space size and Base(Offset) - // - FtwLiteDevice->FtwWorkSpaceSize = FtwLiteDevice->WorkSpaceLength; - FtwLiteDevice->FtwWorkSpaceBase = (UINTN) (FtwLiteDevice->WorkSpaceAddress - (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1))); - break; - } - } - // - // end for - // - FvbMapEntry++; - } - // - // end while - // - } - } - - if ((FtwLiteDevice->SpareAreaAddress >= BaseAddress) && - (FtwLiteDevice->SpareAreaAddress <= (BaseAddress + FwVolHeader->FvLength)) - ) { - FtwLiteDevice->FtwBackupFvb = Fvb; - // - // To get the LBA of spare - // - if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) { - // - // FV may have multiple types of BlockLength - // - FvbMapEntry = &FwVolHeader->BlockMap[0]; - while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) { - for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { - if (FtwLiteDevice->SpareAreaAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex)) { - // - // Get the NumberOfSpareBlock and SizeOfSpareBlock - // - FtwLiteDevice->FtwSpareLba = LbaIndex - 1; - FtwLiteDevice->SizeOfSpareBlock = FvbMapEntry->Length; - FtwLiteDevice->NumberOfSpareBlock = FtwLiteDevice->SpareAreaLength / FtwLiteDevice->SizeOfSpareBlock; - // - // Check the range of spare area to make sure that it's in FV range - // - ASSERT ((FtwLiteDevice->FtwSpareLba + FtwLiteDevice->NumberOfSpareBlock) <= FvbMapEntry->NumBlocks); - break; - } - } - - FvbMapEntry++; - } - // - // end while - // - } - } - } - // - // Calculate the start LBA of working block. Working block is an area which - // contains working space in its last block and has the same size as spare - // block, unless there are not enough blocks before the block that contains - // working space. - // - FtwLiteDevice->FtwWorkBlockLba = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->NumberOfSpareBlock + 1; - if ((INT64) (FtwLiteDevice->FtwWorkBlockLba) < 0) { - FtwLiteDevice->FtwWorkBlockLba = 0; - } - - if ((FtwLiteDevice->FtwFvBlock == NULL) || - (FtwLiteDevice->FtwBackupFvb == NULL) || - (FtwLiteDevice->FtwWorkSpaceLba == (EFI_LBA) (-1)) || - (FtwLiteDevice->FtwSpareLba == (EFI_LBA) (-1)) - ) { - DEBUG ((EFI_D_ERROR, "FtwLite: Working or spare FVB not ready\n")); - ASSERT_EFI_ERROR (Status); - } - // - // Refresh workspace data from working block - // - Status = WorkSpaceRefresh (FtwLiteDevice); - ASSERT_EFI_ERROR (Status); - - // - // If the working block workspace is not valid, try the spare block - // - if (!IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace invalid, read from backup\n")); - // - // Read from spare block - // - Length = FtwLiteDevice->FtwWorkSpaceSize; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba, - FtwLiteDevice->FtwWorkSpaceBase, - &Length, - FtwLiteDevice->FtwWorkSpace - ); - ASSERT_EFI_ERROR (Status); - - // - // If spare block is valid, then replace working block content. - // - if (IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) { - Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart working block in Init() - %r\n", Status)); - ASSERT_EFI_ERROR (Status); - - FtwAbort (FtwLiteDevice); - // - // Refresh work space. - // - Status = WorkSpaceRefresh (FtwLiteDevice); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - } else { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Both are invalid, init workspace\n")); - // - // If both are invalid, then initialize work space. - // - SetMem ( - FtwLiteDevice->FtwWorkSpace, - FtwLiteDevice->FtwWorkSpaceSize, - FTW_ERASED_BYTE - ); - InitWorkSpaceHeader (FtwLiteDevice->FtwWorkSpaceHeader); - // - // Write to work space on the working block - // - Length = FtwLiteDevice->FtwWorkSpaceSize; - Status = FtwLiteDevice->FtwFvBlock->Write ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase, - &Length, - FtwLiteDevice->FtwWorkSpace - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - } - } - // - // Hook the protocol API - // - FtwLiteDevice->FtwLiteInstance.Write = FtwLiteWrite; - - // - // Install protocol interface - // - Status = gBS->InstallProtocolInterface ( - &FtwLiteDevice->Handle, - &gEfiFaultTolerantWriteLiteProtocolGuid, - EFI_NATIVE_INTERFACE, - &FtwLiteDevice->FtwLiteInstance - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // If (!SpareCompleted) THEN Abort to rollback. - // - if ((FtwLiteDevice->FtwLastRecord->WriteAllocated == FTW_VALID_STATE) && - (FtwLiteDevice->FtwLastRecord->SpareCompleted != FTW_VALID_STATE) - ) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Init.. record not SpareCompleted, abort()\n")); - FtwAbort (FtwLiteDevice); - } - // - // if (SpareCompleted) THEN Restart to fault tolerant write. - // - if ((FtwLiteDevice->FtwLastRecord->SpareCompleted == FTW_VALID_STATE) && - (FtwLiteDevice->FtwLastRecord->WriteCompleted != FTW_VALID_STATE) - ) { - - Status = FtwRestart (FtwLiteDevice); - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart last write - %r\n", Status)); - if (EFI_ERROR (Status)) { - return Status; - } - } - // - // To check the workspace buffer behind last records is EMPTY or not. - // If it's not EMPTY, FTW_LITE also need to call reclaim(). - // - Record = FtwLiteDevice->FtwLastRecord; - Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; - if (FtwLiteDevice->FtwWorkSpace[Offset] != FTW_ERASED_BYTE) { - Offset += WRITE_TOTAL_SIZE; - } - - if (!IsErasedFlashBuffer ( - FTW_ERASE_POLARITY, - FtwLiteDevice->FtwWorkSpace + Offset, - FtwLiteDevice->FtwWorkSpaceSize - Offset - )) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace is dirty, call reclaim...\n")); - Status = FtwReclaimWorkSpace (FtwLiteDevice); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace reclaim - %r\n", Status)); - return EFI_ABORTED; - } - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.dxs b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.dxs deleted file mode 100644 index 93aa216..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.dxs +++ /dev/null @@ -1,27 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. 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. - - -Module Name: - - FtwLite.dxs - -Abstract: - - Dependency expression source file. - ---*/ -#include - - -DEPENDENCY_START - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND EFI_ALTERNATE_FV_BLOCK_GUID -DEPENDENCY_END diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.h b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.h deleted file mode 100644 index 8bc122d..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.h +++ /dev/null @@ -1,695 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. 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. - - -Module Name: - - FtwLite.h - -Abstract: - - This is a simple fault tolerant write driver, based on PlatformFd library. - And it only supports write BufferSize <= SpareAreaLength. - - This boot service only protocol provides fault tolerant write capability for - block devices. The protocol has internal non-volatile intermediate storage - of the data and private information. It should be able to recover - automatically from a critical fault, such as power failure. - ---*/ - -#ifndef _EFI_FAULT_TOLERANT_WRITE_LITE_H_ -#define _EFI_FAULT_TOLERANT_WRITE_LITE_H_ - -// -// The package level header files this module uses -// -#include -// -// The protocols, PPI and GUID defintions for this module -// -#include -#include -#include -#include -// -// The Library classes this module consumes -// -#include -#include -#include -#include -#include -#include - -#include - -#define EFI_D_FTW_LITE EFI_D_ERROR -#define EFI_D_FTW_INFO EFI_D_INFO - -// -// Flash erase polarity is 1 -// -#define FTW_ERASE_POLARITY 1 - -#define FTW_VALID_STATE 0 -#define FTW_INVALID_STATE 1 - -#define FTW_ERASED_BYTE ((UINT8) (255)) -#define FTW_POLARITY_REVERT ((UINT8) (255)) - -typedef struct { - UINT8 WriteAllocated : 1; - UINT8 SpareCompleted : 1; - UINT8 WriteCompleted : 1; - UINT8 Reserved : 5; -#define WRITE_ALLOCATED 0x1 -#define SPARE_COMPLETED 0x2 -#define WRITE_COMPLETED 0x4 - - EFI_DEV_PATH DevPath; - EFI_LBA Lba; - UINTN Offset; - UINTN NumBytes; - // - // UINTN SpareAreaOffset; - // -} EFI_FTW_LITE_RECORD; - -#define FTW_LITE_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'T', 'W', 'L') - -// -// MACRO for Block size. -// Flash Erasing will do in block granularity. -// -#ifdef FV_BLOCK_SIZE -#define FTW_BLOCK_SIZE FV_BLOCK_SIZE -#else -#define FV_BLOCK_SIZE 0x10000 -#define FTW_BLOCK_SIZE FV_BLOCK_SIZE -#endif -// -// MACRO for FTW WORK SPACE Base & Size -// -#ifdef EFI_FTW_WORKING_OFFSET -#define FTW_WORK_SPACE_BASE EFI_FTW_WORKING_OFFSET -#else -#define FTW_WORK_SPACE_BASE 0x00E000 -#endif - -#ifdef EFI_FTW_WORKING_LENGTH -#define FTW_WORK_SPACE_SIZE EFI_FTW_WORKING_LENGTH -#else -#define FTW_WORK_SPACE_SIZE 0x002000 -#endif -// -// MACRO for FTW header and record -// -#define FTW_WORKING_QUEUE_SIZE (FTW_WORK_SPACE_SIZE - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)) -#define FTW_LITE_RECORD_SIZE (sizeof (EFI_FTW_LITE_RECORD)) -#define WRITE_TOTAL_SIZE FTW_LITE_RECORD_SIZE - -// -// EFI Fault tolerant protocol private data structure -// -typedef struct { - UINTN Signature; - EFI_HANDLE Handle; - EFI_FTW_LITE_PROTOCOL FtwLiteInstance; - EFI_PHYSICAL_ADDRESS WorkSpaceAddress; - UINTN WorkSpaceLength; - EFI_PHYSICAL_ADDRESS SpareAreaAddress; - UINTN SpareAreaLength; - UINTN NumberOfSpareBlock; // Number of the blocks in spare block - UINTN SizeOfSpareBlock; // Block size in bytes of the blocks in spare block - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader; - EFI_FTW_LITE_RECORD *FtwLastRecord; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwFvBlock; // FVB of working block - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwBackupFvb; // FVB of spare block - EFI_LBA FtwSpareLba; - EFI_LBA FtwWorkBlockLba; // Start LBA of working block - EFI_LBA FtwWorkSpaceLba; // Start LBA of working space - UINTN FtwWorkSpaceBase; // Offset from LBA start addr - UINTN FtwWorkSpaceSize; - UINT8 *FtwWorkSpace; - // - // Following a buffer of FtwWorkSpace[FTW_WORK_SPACE_SIZE], - // Allocated with EFI_FTW_LITE_DEVICE. - // -} EFI_FTW_LITE_DEVICE; - -#define FTW_LITE_CONTEXT_FROM_THIS(a) CR (a, EFI_FTW_LITE_DEVICE, FtwLiteInstance, FTW_LITE_DEVICE_SIGNATURE) - -// -// Driver entry point -// -EFI_STATUS -EFIAPI -InitializeFtwLite ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -/*++ - -Routine Description: - This function is the entry point of the Fault Tolerant Write driver. - -Arguments: - ImageHandle - EFI_HANDLE: A handle for the image that is initializing - this driver - SystemTable - EFI_SYSTEM_TABLE: A pointer to the EFI system table - -Returns: - EFI_SUCCESS - FTW has finished the initialization - EFI_ABORTED - FTW initialization error - ---*/ -; - -// -// Fault Tolerant Write Protocol API -// -EFI_STATUS -EFIAPI -FtwLiteWrite ( - IN EFI_FTW_LITE_PROTOCOL *This, - IN EFI_HANDLE FvbHandle, - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN VOID *Buffer - ) -/*++ - -Routine Description: - Starts a target block update. This function will record data about write - in fault tolerant storage and will complete the write in a recoverable - manner, ensuring at all times that either the original contents or - the modified contents are available. - -Arguments: - This - Calling context - FvbHandle - The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - Lba - The logical block address of the target block. - Offset - The offset within the target block to place the data. - NumBytes - The number of bytes to write to the target block. - Buffer - The data to write. - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_BAD_BUFFER_SIZE - The write would span a target block, which is not - a valid action. - EFI_ACCESS_DENIED - No writes have been allocated. - EFI_NOT_FOUND - Cannot find FVB by handle. - EFI_OUT_OF_RESOURCES - Cannot allocate memory. - EFI_ABORTED - The function could not complete successfully. - ---*/ -; - -// -// Internal functions -// -EFI_STATUS -FtwRestart ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Restarts a previously interrupted write. The caller must provide the - block protocol needed to complete the interrupted write. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - FvbHandle - The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ACCESS_DENIED - No pending writes exist - EFI_NOT_FOUND - FVB protocol not found by the handle - EFI_ABORTED - The function could not complete successfully - ---*/ -; - -EFI_STATUS -FtwAbort ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Aborts all previous allocated writes. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - EFI_NOT_FOUND - No allocated writes exist. - ---*/ -; - - -EFI_STATUS -FtwWriteRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb - ) -/*++ - -Routine Description: - Write a record with fault tolerant mannaer. - Since the content has already backuped in spare block, the write is - guaranteed to be completed with fault tolerant manner. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - Fvb - The FVB protocol that provides services for - reading, writing, and erasing the target block. - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully - ---*/ -; - -EFI_STATUS -FtwEraseBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - To Erase one block. The size is FTW_BLOCK_SIZE - -Arguments: - FtwLiteDevice - Calling context - FvBlock - FVB Protocol interface - Lba - Lba of the firmware block - -Returns: - EFI_SUCCESS - Block LBA is Erased successfully - Others - Error occurs - ---*/ -; - -EFI_STATUS -FtwEraseSpareBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - - Erase spare block. - -Arguments: - - FtwLiteDevice - Calling context - -Returns: - - Status code - ---*/ -; - -EFI_STATUS -FtwGetFvbByHandle ( - IN EFI_HANDLE FvBlockHandle, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ) -/*++ - -Routine Description: - Retrive the proper FVB protocol interface by HANDLE. - -Arguments: - FvBlockHandle - The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - FvBlock - The interface of FVB protocol - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully ---*/ -; - -EFI_STATUS -GetFvbByAddress ( - IN EFI_PHYSICAL_ADDRESS Address, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ) -/*++ - -Routine Description: - - Get firmware block by address. - -Arguments: - - Address - Address specified the block - FvBlock - The block caller wanted - -Returns: - - Status code - - EFI_NOT_FOUND - Block not found - ---*/ -; - -BOOLEAN -IsInWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - - Is it in working block? - -Arguments: - - FtwLiteDevice - Calling context - FvBlock - Fvb protocol instance - Lba - The block specified - -Returns: - - In working block or not - ---*/ -; - -BOOLEAN -IsBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - - Check whether the block is a boot block. - -Arguments: - - FtwLiteDevice - Calling context - FvBlock - Fvb protocol instance - Lba - Lba value - -Returns: - - Is a boot block or not - ---*/ -; - -EFI_STATUS -FlushSpareBlockToTargetBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Target block is accessed by FvBlock protocol interface. LBA is Lba. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - FvBlock - FVB Protocol interface to access target block - Lba - Lba of the target block - -Returns: - EFI_SUCCESS - Spare block content is copied to target block - EFI_INVALID_PARAMETER - Input parameter error - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - ---*/ -; - -EFI_STATUS -FlushSpareBlockToWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Working block is accessed by FTW working FVB protocol interface. LBA is - FtwLiteDevice->FtwWorkBlockLba. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - Spare block content is copied to target block - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - -Notes: - Since the working block header is important when FTW initializes, the - state of the operation should be handled carefully. The Crc value is - calculated without STATE element. - ---*/ -; - -EFI_STATUS -FlushSpareBlockToBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Boot block is accessed by BootFvb protocol interface. LBA is 0. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - Spare block content is copied to boot block - EFI_INVALID_PARAMETER - Input parameter error - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - -Notes: - ---*/ -; - -EFI_STATUS -FtwUpdateFvState ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINT8 NewBit - ) -/*++ - -Routine Description: - Update a bit of state on a block device. The location of the bit is - calculated by the (Lba, Offset, bit). Here bit is determined by the - the name of a certain bit. - -Arguments: - FvBlock - FVB Protocol interface to access SrcBlock and DestBlock - Lba - Lba of a block - Offset - Offset on the Lba - NewBit - New value that will override the old value if it can be change - -Returns: - EFI_SUCCESS - A state bit has been updated successfully - Others - Access block device error. - -Notes: - Assume all bits of State are inside the same BYTE. - - EFI_ABORTED - Read block fail ---*/ -; - -EFI_STATUS -FtwGetLastRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - OUT EFI_FTW_LITE_RECORD **FtwLastRecord - ) -/*++ - -Routine Description: - Get the last Write record pointer. - The last record is the record whose 'complete' state hasn't been set. - After all, this header may be a EMPTY header entry for next Allocate. - -Arguments: - FtwLiteDevice - Private data of this driver - FtwLastRecord - Pointer to retrieve the last write record - -Returns: - EFI_SUCCESS - Get the last write record successfully - EFI_ABORTED - The FTW work space is damaged - ---*/ -; - -BOOLEAN -IsErasedFlashBuffer ( - IN BOOLEAN Polarity, - IN UINT8 *Buffer, - IN UINTN BufferSize - ) -/*++ - -Routine Description: - - Check whether a flash buffer is erased. - -Arguments: - - Polarity - All 1 or all 0 - Buffer - Buffer to check - BufferSize - Size of the buffer - -Returns: - - Erased or not. - ---*/ -; - -EFI_STATUS -InitWorkSpaceHeader ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ) -/*++ - -Routine Description: - Initialize a work space when there is no work space. - -Arguments: - WorkingHeader - Pointer of working block header - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - ---*/ -; - -EFI_STATUS -WorkSpaceRefresh ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Read from working block to refresh the work space in memory. - -Arguments: - FtwLiteDevice - Point to private data of FTW driver - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - ---*/ -; - -BOOLEAN -IsValidWorkSpace ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ) -/*++ - -Routine Description: - Check to see if it is a valid work space. - -Arguments: - WorkingHeader - Pointer of working block header - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - ---*/ -; - -EFI_STATUS -CleanupWorkSpace ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN OUT UINT8 *BlockBuffer, - IN UINTN BufferSize - ) -/*++ - -Routine Description: - Reclaim the work space. Get rid of all the completed write records - and write records in the Fault Tolerant work space. - -Arguments: - FtwLiteDevice - Point to private data of FTW driver - FtwSpaceBuffer - Buffer to contain the reclaimed clean data - BufferSize - Size of the FtwSpaceBuffer - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_BUFFER_TOO_SMALL - The FtwSpaceBuffer is too small - EFI_ABORTED - The function could not complete successfully. - ---*/ -; - -EFI_STATUS -FtwReclaimWorkSpace ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Reclaim the work space on the working block. - -Arguments: - FtwLiteDevice - Point to private data of FTW driver - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - ---*/ -; - -#endif diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.inf b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.inf deleted file mode 100644 index 4f47d60..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.inf +++ /dev/null @@ -1,141 +0,0 @@ -#/** @file -# Component description file for FtwLite module. -# -# This driver provides fault tolerant write capability for block devices. -# Copyright (c) 2006 - 2007, Intel Corporation -# -# All rights reserved. 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 Section - statements that will be processed to create a Makefile. -# -################################################################################ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = FtwLite - FILE_GUID = 4C862FC6-0E54-4e36-8C8F-FF6F3167951F - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - EDK_RELEASE_VERSION = 0x00020000 - EFI_SPECIFICATION_VERSION = 0x00020000 - - ENTRY_POINT = InitializeFtwLite - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -################################################################################ -# -# Sources Section - list of files that are required for the build to succeed. -# -################################################################################ - -[Sources.common] - FtwWorkSpace.c - FtwMisc.c - FtwLite.c - FtwLite.h - -[Sources.Ia32] - Ia32/Ia32FtwMisc.c - -[Sources.X64] - x64/x64FtwMisc.c - -[Sources.IPF] - Ipf/IpfFtwMisc.c - -[Sources.EBC] - Ia32/Ia32FtwMisc.c - - -################################################################################ -# -# Package Dependency Section - list of Package files that are required for -# this module. -# -################################################################################ - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - - - -################################################################################ -# -# Library Class Section - list of Library Classes that are required for -# this module. -# -################################################################################ - -[LibraryClasses] - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - UefiDriverEntryPoint - DebugLib - PcdLib - HobLib - -################################################################################ -# -# Guid C Name Section - list of Guids that this module uses or produces. -# -################################################################################ - -[Guids] - gEfiSystemNvDataFvGuid # ALWAYS_CONSUMED - gEfiFlashMapHobGuid - -################################################################################ -# -# Protocol C Name Section - list of Protocol and Protocol Notify C Names -# that this module uses or produces. -# -################################################################################ - -[Protocols] - gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiFaultTolerantWriteLiteProtocolGuid # PROTOCOL ALWAYS_PRODUCED - -[Protocols.IA32] - gEfiPciRootBridgeIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED - -[Protocols.EBC] - gEfiPciRootBridgeIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED - - -################################################################################ -# -# Pcd DYNAMIC - list of PCDs that this module is coded for. -# -################################################################################ - -[PcdsDynamic.common] - PcdFlashNvStorageFtwWorkingSize|gEfiMdeModulePkgTokenSpaceGuid - PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid - PcdFlashNvStorageFtwSpareSize|gEfiMdeModulePkgTokenSpaceGuid - PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid - -################################################################################ -# -# Dependency Expression Section - list of Dependency expressions that are required for -# this module. -# -################################################################################ - -[Depex] - gEfiFirmwareVolumeBlockProtocolGuid AND gEfiAlternateFvBlockGuid diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa deleted file mode 100644 index 7362f47..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa +++ /dev/null @@ -1,103 +0,0 @@ - - - - FtwLite - DXE_DRIVER - 4C862FC6-0E54-4e36-8C8F-FF6F3167951F - 1.0 - Component description file for FtwLite module. - This driver provides fault tolerant write capability for block devices. - Copyright (c) 2006 - 2007, Intel Corporation - All rights reserved. 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. - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 - - - IA32 X64 IPF EBC - false - FtwLite - - - - PcdLib - - - DebugLib - - - UefiDriverEntryPoint - - - BaseMemoryLib - - - MemoryAllocationLib - - - UefiBootServicesTableLib - - - - FtwLite.h - FtwLite.c - FtwMisc.c - FtwWorkSpace.c - FtwLite.dxs - Ia32/Ia32FtwMisc.c - x64/x64FtwMisc.c - Ipf/IpfFtwMisc.c - - - - - - - - gEfiFaultTolerantWriteLiteProtocolGuid - - - gEfiPciRootBridgeIoProtocolGuid - - - gEfiFirmwareVolumeBlockProtocolGuid - - - - - gEfiSystemNvDataFvGuid - - - - EFI_SPECIFICATION_VERSION 0x00020000 - EDK_RELEASE_VERSION 0x00020000 - - InitializeFtwLite - - - - - PcdFlashNvStorageFtwSpareBase - gEfiGenericPlatformTokenSpaceGuid - To get base address of the FTW spare block section in NV firmware volume. - - - PcdFlashNvStorageFtwSpareSize - gEfiGenericPlatformTokenSpaceGuid - To get size of the FTW spare block section in NV firmware volume. - - - PcdFlashNvStorageFtwWorkingBase - gEfiGenericPlatformTokenSpaceGuid - To get base address of the FTW working block section in NV firmware volume. - - - PcdFlashNvStorageFtwWorkingSize - gEfiGenericPlatformTokenSpaceGuid - To get size of the FTW working block section in NV firmware volume. - - - diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwMisc.c deleted file mode 100644 index eb334ea..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwMisc.c +++ /dev/null @@ -1,530 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. 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. - -Module Name: - - FtwMisc.c - -Abstract: - - Internal functions to support fault tolerant write. - -Revision History - ---*/ - -#include - -BOOLEAN -IsErasedFlashBuffer ( - IN BOOLEAN Polarity, - IN UINT8 *Buffer, - IN UINTN BufferSize - ) -/*++ - -Routine Description: - - Check whether a flash buffer is erased. - -Arguments: - - Polarity - All 1 or all 0 - Buffer - Buffer to check - BufferSize - Size of the buffer - -Returns: - - Erased or not. - ---*/ -{ - UINT8 ErasedValue; - UINT8 *Ptr; - - if (Polarity) { - ErasedValue = 0xFF; - } else { - ErasedValue = 0; - } - - Ptr = Buffer; - while (BufferSize--) { - if (*Ptr++ != ErasedValue) { - return FALSE; - } - } - - return TRUE; -} - -EFI_STATUS -FtwEraseBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - To Erase one block. The size is FTW_BLOCK_SIZE - -Arguments: - FtwLiteDevice - Calling context - FvBlock - FVB Protocol interface - Lba - Lba of the firmware block - -Returns: - EFI_SUCCESS - Block LBA is Erased successfully - Others - Error occurs - ---*/ -{ - return FvBlock->EraseBlocks ( - FvBlock, - Lba, - FtwLiteDevice->NumberOfSpareBlock, - EFI_LBA_LIST_TERMINATOR - ); -} - -EFI_STATUS -FtwEraseSpareBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - - Erase spare block. - -Arguments: - - FtwLiteDevice - Calling context - -Returns: - - Status code - ---*/ -{ - return FtwLiteDevice->FtwBackupFvb->EraseBlocks ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba, - FtwLiteDevice->NumberOfSpareBlock, - EFI_LBA_LIST_TERMINATOR - ); -} - -EFI_STATUS -FtwGetFvbByHandle ( - IN EFI_HANDLE FvBlockHandle, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ) -/*++ - -Routine Description: - Retrive the proper FVB protocol interface by HANDLE. - -Arguments: - FvBlockHandle - The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - FvBlock - The interface of FVB protocol - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully ---*/ -{ - // - // To get the FVB protocol interface on the handle - // - return gBS->HandleProtocol ( - FvBlockHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID **) FvBlock - ); -} - -EFI_STATUS -GetFvbByAddress ( - IN EFI_PHYSICAL_ADDRESS Address, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ) -/*++ - -Routine Description: - - Get firmware block by address. - -Arguments: - - Address - Address specified the block - FvBlock - The block caller wanted - -Returns: - - Status code - - EFI_NOT_FOUND - Block not found - ---*/ -{ - EFI_STATUS Status; - EFI_HANDLE *HandleBuffer; - UINTN HandleCount; - UINTN Index; - EFI_PHYSICAL_ADDRESS FvbBaseAddress; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - - *FvBlock = NULL; - // - // Locate all handles of Fvb protocol - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareVolumeBlockProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - // - // Search all FVB until find the right one - // - for (Index = 0; Index < HandleCount; Index += 1) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID **) &Fvb - ); - if (EFI_ERROR (Status)) { - Status = EFI_NOT_FOUND; - break; - } - // - // Compare the address and select the right one - // - Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress); - if (EFI_ERROR (Status)) { - continue; - } - - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress); - if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + (FwVolHeader->FvLength - 1)))) { - *FvBlock = Fvb; - Status = EFI_SUCCESS; - break; - } - } - - FreePool (HandleBuffer); - return Status; -} - -BOOLEAN -IsInWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - - Is it in working block? - -Arguments: - - FtwLiteDevice - Calling context - FvBlock - Fvb protocol instance - Lba - The block specified - -Returns: - - In working block or not - ---*/ -{ - // - // If matching the following condition, the target block is in working block. - // 1. Target block is on the FV of working block (Using the same FVB protocol instance). - // 2. Lba falls into the range of working block. - // - return (BOOLEAN) - ( - (FvBlock == FtwLiteDevice->FtwFvBlock) && - (Lba >= FtwLiteDevice->FtwWorkBlockLba) && - (Lba <= FtwLiteDevice->FtwWorkSpaceLba) - ); -} - -EFI_STATUS -FlushSpareBlockToTargetBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Target block is accessed by FvBlock protocol interface. LBA is Lba. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - FvBlock - FVB Protocol interface to access target block - Lba - Lba of the target block - -Returns: - EFI_SUCCESS - Spare block content is copied to target block - EFI_INVALID_PARAMETER - Input parameter error - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - ---*/ -{ - EFI_STATUS Status; - UINTN Length; - UINT8 *Buffer; - UINTN Count; - UINT8 *Ptr; - UINTN Index; - - if ((FtwLiteDevice == NULL) || (FvBlock == NULL)) { - return EFI_INVALID_PARAMETER; - } - // - // Allocate a memory buffer - // - Length = FtwLiteDevice->SpareAreaLength; - Buffer = AllocatePool (Length); - if (Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Read all content of spare block to memory buffer - // - Ptr = Buffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Count = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - // - // Erase the target block - // - Status = FtwEraseBlock (FtwLiteDevice, FvBlock, Lba); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return EFI_ABORTED; - } - // - // Write memory buffer to block, using the FvbBlock protocol interface - // - Ptr = Buffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Count = FtwLiteDevice->SizeOfSpareBlock; - Status = FvBlock->Write (FvBlock, Lba + Index, 0, &Count, Ptr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status)); - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - - FreePool (Buffer); - - return Status; -} - -EFI_STATUS -FlushSpareBlockToWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Working block is accessed by FTW working FVB protocol interface. LBA is - FtwLiteDevice->FtwWorkBlockLba. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - Spare block content is copied to target block - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - -Notes: - Since the working block header is important when FTW initializes, the - state of the operation should be handled carefully. The Crc value is - calculated without STATE element. - ---*/ -{ - EFI_STATUS Status; - UINTN Length; - UINT8 *Buffer; - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader; - EFI_LBA WorkSpaceLbaOffset; - UINTN Count; - UINT8 *Ptr; - UINTN Index; - - // - // Allocate a memory buffer - // - Length = FtwLiteDevice->SpareAreaLength; - Buffer = AllocatePool (Length); - if (Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // To guarantee that the WorkingBlockValid is set on spare block - // - WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba; - FtwUpdateFvState ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset, - FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), - WORKING_BLOCK_VALID - ); - // - // Read from spare block to memory buffer - // - Ptr = Buffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Count = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - // - // Clear the CRC and STATE, copy data from spare to working block. - // - WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (Buffer + (UINTN) WorkSpaceLbaOffset * FtwLiteDevice->SizeOfSpareBlock + FtwLiteDevice->FtwWorkSpaceBase); - InitWorkSpaceHeader (WorkingBlockHeader); - WorkingBlockHeader->WorkingBlockValid = FTW_ERASE_POLARITY; - WorkingBlockHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY; - - // - // target block is working block, then - // Set WorkingBlockInvalid in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER - // before erase the working block. - // - // Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER, - // WorkingBlockInvalid); - // To skip Signature and Crc: sizeof(EFI_GUID)+sizeof(UINT32). - // - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), - WORKING_BLOCK_INVALID - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return EFI_ABORTED; - } - - FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockInvalid = FTW_VALID_STATE; - - // - // Erase the working block - // - Status = FtwEraseBlock ( - FtwLiteDevice, - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkBlockLba - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return EFI_ABORTED; - } - // - // Write memory buffer to working block, using the FvbBlock protocol interface - // - Ptr = Buffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Count = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwFvBlock->Write ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkBlockLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status)); - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - // - // Since the memory buffer will not be used, free memory Buffer. - // - FreePool (Buffer); - - // - // Update the VALID of the working block - // - // Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER, - // WorkingBlockValid); - // Hardcode offset sizeof(EFI_GUID)+sizeof(UINT32), to skip Signature and Crc - // - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), - WORKING_BLOCK_VALID - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockValid = FTW_VALID_STATE; - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwWorkSpace.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwWorkSpace.c deleted file mode 100644 index 00d7d8e..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwWorkSpace.c +++ /dev/null @@ -1,561 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. 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. - -Module Name: - - FtwWorkSpace.c - -Abstract: - -Revision History - ---*/ - - -#include - -BOOLEAN -IsValidWorkSpace ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ) -/*++ - -Routine Description: - Check to see if it is a valid work space. - -Arguments: - WorkingHeader - Pointer of working block header - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - ---*/ -{ - EFI_STATUS Status; - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader; - - ASSERT (WorkingHeader != NULL); - if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) { - return FALSE; - } - // - // Check signature with gEfiSystemNvDataFvGuid - // - if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) { - return FALSE; - } - // - // Check the CRC of header - // - CopyMem ( - &WorkingBlockHeader, - WorkingHeader, - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER) - ); - - // - // Filter out the Crc and State fields - // - SetMem ( - &WorkingBlockHeader.Crc, - sizeof (UINT32), - FTW_ERASED_BYTE - ); - WorkingBlockHeader.WorkingBlockValid = FTW_ERASE_POLARITY; - WorkingBlockHeader.WorkingBlockInvalid = FTW_ERASE_POLARITY; - - // - // Calculate the Crc of woking block header - // - Status = gBS->CalculateCrc32 ( - (UINT8 *) &WorkingBlockHeader, - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), - &WorkingBlockHeader.Crc - ); - ASSERT_EFI_ERROR (Status); - - if (WorkingBlockHeader.Crc != WorkingHeader->Crc) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Work block header CRC check error\n")); - return FALSE; - } - - return TRUE; -} - -EFI_STATUS -InitWorkSpaceHeader ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ) -/*++ - -Routine Description: - Initialize a work space when there is no work space. - -Arguments: - WorkingHeader - Pointer of working block header - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - ---*/ -{ - EFI_STATUS Status; - - ASSERT (WorkingHeader != NULL); - - // - // Here using gEfiSystemNvDataFvGuid as the signature. - // - CopyMem ( - &WorkingHeader->Signature, - &gEfiSystemNvDataFvGuid, - sizeof (EFI_GUID) - ); - WorkingHeader->WriteQueueSize = FTW_WORKING_QUEUE_SIZE; - - // - // Crc is calculated with all the fields except Crc and STATE - // - WorkingHeader->WorkingBlockValid = FTW_ERASE_POLARITY; - WorkingHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY; - SetMem (&WorkingHeader->Crc, sizeof (UINT32), FTW_ERASED_BYTE); - - // - // Calculate the CRC value - // - Status = gBS->CalculateCrc32 ( - (UINT8 *) WorkingHeader, - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), - &WorkingHeader->Crc - ); - ASSERT_EFI_ERROR (Status); - - // - // Restore the WorkingBlockValid flag to VALID state - // - WorkingHeader->WorkingBlockValid = FTW_VALID_STATE; - WorkingHeader->WorkingBlockInvalid = FTW_INVALID_STATE; - - return EFI_SUCCESS; -} - -EFI_STATUS -FtwUpdateFvState ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINT8 NewBit - ) -/*++ - -Routine Description: - Update a bit of state on a block device. The location of the bit is - calculated by the (Lba, Offset, bit). Here bit is determined by the - the name of a certain bit. - -Arguments: - FvBlock - FVB Protocol interface to access SrcBlock and DestBlock - Lba - Lba of a block - Offset - Offset on the Lba - NewBit - New value that will override the old value if it can be change - -Returns: - EFI_SUCCESS - A state bit has been updated successfully - Others - Access block device error. - -Notes: - Assume all bits of State are inside the same BYTE. - - EFI_ABORTED - Read block fail ---*/ -{ - EFI_STATUS Status; - UINT8 State; - UINTN Length; - - // - // Read state from device, assume State is only one byte. - // - Length = sizeof (UINT8); - Status = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - State ^= FTW_POLARITY_REVERT; - State = (UINT8) (State | NewBit); - State ^= FTW_POLARITY_REVERT; - - // - // Write state back to device - // - Length = sizeof (UINT8); - Status = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State); - - return Status; -} - -EFI_STATUS -FtwGetLastRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - OUT EFI_FTW_LITE_RECORD **FtwLastRecord - ) -/*++ - -Routine Description: - Get the last Write record pointer. - The last record is the record whose 'complete' state hasn't been set. - After all, this header may be a EMPTY header entry for next Allocate. - -Arguments: - FtwLiteDevice - Private data of this driver - FtwLastRecord - Pointer to retrieve the last write record - -Returns: - EFI_SUCCESS - Get the last write record successfully - EFI_ABORTED - The FTW work space is damaged - ---*/ -{ - EFI_FTW_LITE_RECORD *Record; - - Record = (EFI_FTW_LITE_RECORD *) (FtwLiteDevice->FtwWorkSpaceHeader + 1); - while (Record->WriteCompleted == FTW_VALID_STATE) { - // - // If Offset exceed the FTW work space boudary, return error. - // - if ((UINTN) ((UINT8 *) Record - FtwLiteDevice->FtwWorkSpace) > FtwLiteDevice->FtwWorkSpaceSize) { - return EFI_ABORTED; - } - - Record++; - } - // - // Last write record is found - // - *FtwLastRecord = Record; - return EFI_SUCCESS; -} - -EFI_STATUS -WorkSpaceRefresh ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Read from working block to refresh the work space in memory. - -Arguments: - FtwLiteDevice - Point to private data of FTW driver - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_ABORTED - The function could not complete successfully. - ---*/ -{ - EFI_STATUS Status; - UINTN Length; - UINTN Offset; - EFI_FTW_LITE_RECORD *Record; - - // - // Initialize WorkSpace as FTW_ERASED_BYTE - // - SetMem ( - FtwLiteDevice->FtwWorkSpace, - FtwLiteDevice->FtwWorkSpaceSize, - FTW_ERASED_BYTE - ); - - // - // Read from working block - // - Length = FtwLiteDevice->FtwWorkSpaceSize; - Status = FtwLiteDevice->FtwFvBlock->Read ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase, - &Length, - FtwLiteDevice->FtwWorkSpace - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Refresh the FtwLastRecord - // - Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); - - Record = FtwLiteDevice->FtwLastRecord; - Offset = (UINTN) (UINT8 *) Record - (UINTN) FtwLiteDevice->FtwWorkSpace; - - // - // IF work space has error or Record is out of the workspace limit, THEN - // call reclaim. - // - if (EFI_ERROR (Status) || (Offset + WRITE_TOTAL_SIZE >= FtwLiteDevice->FtwWorkSpaceSize)) { - // - // reclaim work space in working block. - // - Status = FtwReclaimWorkSpace (FtwLiteDevice); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: Reclaim workspace - %r\n", Status)); - return EFI_ABORTED; - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -CleanupWorkSpace ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN OUT UINT8 *FtwSpaceBuffer, - IN UINTN BufferSize - ) -/*++ - -Routine Description: - Reclaim the work space. Get rid of all the completed write records - and write records in the Fault Tolerant work space. - -Arguments: - FtwLiteDevice - Point to private data of FTW driver - FtwSpaceBuffer - Buffer to contain the reclaimed clean data - BufferSize - Size of the FtwSpaceBuffer - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_BUFFER_TOO_SMALL - The FtwSpaceBuffer is too small - EFI_ABORTED - The function could not complete successfully. - ---*/ -{ - UINTN Length; - EFI_FTW_LITE_RECORD *Record; - - // - // To check if the buffer is large enough - // - Length = FtwLiteDevice->FtwWorkSpaceSize; - if (BufferSize < Length) { - return EFI_BUFFER_TOO_SMALL; - } - // - // Clear the content of buffer that will save the new work space data - // - SetMem (FtwSpaceBuffer, Length, FTW_ERASED_BYTE); - - // - // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer - // - CopyMem ( - FtwSpaceBuffer, - FtwLiteDevice->FtwWorkSpaceHeader, - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER) - ); - - // - // Get the last record - // - Record = FtwLiteDevice->FtwLastRecord; - if ((Record != NULL) && (Record->WriteAllocated == FTW_VALID_STATE) && (Record->WriteCompleted != FTW_VALID_STATE)) { - CopyMem ( - (UINT8 *) FtwSpaceBuffer + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), - Record, - WRITE_TOTAL_SIZE - ); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -FtwReclaimWorkSpace ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Reclaim the work space on the working block. - -Arguments: - FtwLiteDevice - Point to private data of FTW driver - -Returns: - EFI_SUCCESS - The function completed successfully - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - ---*/ -{ - EFI_STATUS Status; - UINT8 *TempBuffer; - UINTN TempBufferSize; - UINT8 *Ptr; - UINTN Length; - UINTN Index; - UINTN SpareBufferSize; - UINT8 *SpareBuffer; - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader; - - DEBUG ((EFI_D_FTW_LITE, "FtwLite: start to reclaim work space\n")); - - // - // Read all original data from working block to a memory buffer - // - TempBufferSize = FtwLiteDevice->SpareAreaLength; - TempBuffer = AllocateZeroPool (TempBufferSize); - if (TempBuffer != NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Ptr = TempBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Length = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwFvBlock->Read ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkBlockLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (TempBuffer); - return EFI_ABORTED; - } - - Ptr += Length; - } - // - // Clean up the workspace, remove all the completed records. - // - Ptr = TempBuffer + - ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) * - FtwLiteDevice->SizeOfSpareBlock + FtwLiteDevice->FtwWorkSpaceBase; - - Status = CleanupWorkSpace ( - FtwLiteDevice, - Ptr, - FtwLiteDevice->FtwWorkSpaceSize - ); - - CopyMem ( - FtwLiteDevice->FtwWorkSpace, - Ptr, - FtwLiteDevice->FtwWorkSpaceSize - ); - - Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); - - // - // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID - // - WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr; - WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE; - WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE; - - // - // Try to keep the content of spare block - // Save spare block into a spare backup memory buffer (Sparebuffer) - // - SpareBufferSize = FtwLiteDevice->SpareAreaLength; - SpareBuffer = AllocatePool (SpareBufferSize); - if (SpareBuffer == NULL) { - FreePool (TempBuffer); - return EFI_OUT_OF_RESOURCES; - } - - Ptr = SpareBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Length = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (TempBuffer); - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += Length; - } - // - // Write the memory buffer to spare block - // - Status = FtwEraseSpareBlock (FtwLiteDevice); - Ptr = TempBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Length = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (TempBuffer); - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += Length; - } - // - // Free TempBuffer - // - FreePool (TempBuffer); - - // - // Write the spare block to working block - // - Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); - if (EFI_ERROR (Status)) { - FreePool (SpareBuffer); - return Status; - } - // - // Restore spare backup buffer into spare block , if no failure happened during FtwWrite. - // - Status = FtwEraseSpareBlock (FtwLiteDevice); - Ptr = SpareBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Length = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += Length; - } - - FreePool (SpareBuffer); - - DEBUG ((EFI_D_FTW_LITE, "FtwLite: reclaim work space success\n")); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c deleted file mode 100644 index 6425f29..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c +++ /dev/null @@ -1,403 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. 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. - -Module Name: - - Ia32FtwMisc.c - -Abstract: - - Ia32 platform related code to support FtwLite.. - -Revision History - ---*/ - - -#include - -// -// MACROs for boot block update -// -#define BOOT_BLOCK_BASE 0xFFFF0000 - -// -// (LPC -- D31:F0) -// -#define LPC_BUS_NUMBER 0x00 -#define LPC_DEVICE_NUMBER 0x1F -#define LPC_IF 0xF0 -// -// Top swap -// -#define GEN_STATUS 0xD4 -#define TOP_SWAP_BIT (1 << 13) - -STATIC -UINT32 -ReadPciRegister ( - IN UINT32 Offset - ) -/*++ - -Routine Description: - - Read PCI register value. - -Arguments: - - Offset - Offset of the register - -Returns: - - The value. - ---*/ -{ - EFI_STATUS Status; - UINT32 Value; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - Value = 0; - Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status)); - return 0; - } - - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - EFI_PCI_ADDRESS ( - LPC_BUS_NUMBER, - LPC_DEVICE_NUMBER, - LPC_IF, - Offset - ), - 1, - &Value - ); - ASSERT_EFI_ERROR (Status); - - return Value; -} - -STATIC -EFI_STATUS -GetSwapState ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - OUT BOOLEAN *SwapState - ) -/*++ - -Routine Description: - - Get swap state - -Arguments: - - FtwLiteDevice - Calling context - SwapState - Swap state - -Returns: - - EFI_SUCCESS - State successfully got - ---*/ -{ - // - // Top swap status is 13 bit - // - *SwapState = (BOOLEAN) ((ReadPciRegister (GEN_STATUS) & TOP_SWAP_BIT) != 0); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -SetSwapState ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN BOOLEAN TopSwap - ) -/*++ - -Routine Description: - Set swap state. - -Arguments: - FtwLiteDevice - Indicates a pointer to the calling context. - TopSwap - New swap state - -Returns: - EFI_SUCCESS - The function completed successfully - -Note: - the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that - software will not be able to clear the Top-Swap bit until the system is - rebooted without GNT[A]# being pulled down. - ---*/ -{ - UINT32 GenStatus; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - EFI_STATUS Status; - - // - // Top-Swap bit (bit 13, D31: F0, Offset D4h) - // - GenStatus = ReadPciRegister (GEN_STATUS); - - // - // Set 13 bit, according to input NewSwapState - // - if (TopSwap) { - GenStatus |= TOP_SWAP_BIT; - } else { - GenStatus &= ~TOP_SWAP_BIT; - } - - Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status)); - return Status; - } - // - // Write back the GenStatus register - // - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint32, - EFI_PCI_ADDRESS ( - LPC_BUS_NUMBER, - LPC_DEVICE_NUMBER, - LPC_IF, - GEN_STATUS - ), - 1, - &GenStatus - ); - - DEBUG_CODE_BEGIN (); - if (TopSwap) { - DEBUG ((EFI_D_ERROR, "SAR: Set top swap\n")); - } else { - DEBUG ((EFI_D_ERROR, "SAR: Clear top swap\n")); - } - DEBUG_CODE_END (); - - return EFI_SUCCESS; -} - -BOOLEAN -IsBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - - Check whether the block is a boot block. - -Arguments: - - FtwLiteDevice - Calling context - FvBlock - Fvb protocol instance - Lba - Lba value - -Returns: - - Is a boot block or not - ---*/ -{ - EFI_STATUS Status; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *BootFvb; - - Status = GetFvbByAddress (BOOT_BLOCK_BASE, &BootFvb); - if (EFI_ERROR (Status)) { - return FALSE; - } - // - // Compare the Fvb - // - return (BOOLEAN) (FvBlock == BootFvb); -} - -EFI_STATUS -FlushSpareBlockToBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Boot block is accessed by BootFvb protocol interface. LBA is 0. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - Spare block content is copied to boot block - EFI_INVALID_PARAMETER - Input parameter error - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - -Notes: - FTW will do extra work on boot block update. - FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL, - which is produced by a chipset driver. - - FTW updating boot block steps: - 1. Erase top swap block (0xFFFE-0xFFFEFFFF) and write data to it ready - 2. Read data from top swap block to memory buffer - 3. SetSwapState(EFI_SWAPPED) - 4. Erasing boot block (0xFFFF-0xFFFFFFFF) - 5. Programming boot block until the boot block is ok. - 6. SetSwapState(UNSWAPPED) - - Notes: - 1. Since the SwapState bit is saved in CMOS, FTW can restore and continue - even in the scenario of power failure. - 2. FTW shall not allow to update boot block when battery state is error. - ---*/ -{ - EFI_STATUS Status; - UINTN Length; - UINT8 *Buffer; - UINTN Count; - UINT8 *Ptr; - UINTN Index; - BOOLEAN TopSwap; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *BootFvb; - EFI_LBA BootLba; - - // - // Allocate a memory buffer - // - Length = FtwLiteDevice->SpareAreaLength; - Buffer = AllocatePool (Length); - if (Buffer == NULL) { - } - // - // Get TopSwap bit state - // - Status = GetSwapState (FtwLiteDevice, &TopSwap); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: Get Top Swapped status - %r\n", Status)); - FreePool (Buffer); - return EFI_ABORTED; - } - - if (TopSwap) { - // - // Get FVB of current boot block - // - Status = GetFvbByAddress (FtwLiteDevice->SpareAreaAddress + FTW_BLOCK_SIZE, &BootFvb); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return Status; - } - // - // Read data from current boot block - // - BootLba = 0; - Ptr = Buffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Count = FtwLiteDevice->SizeOfSpareBlock; - Status = BootFvb->Read ( - BootFvb, - BootLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - - } else { - // - // Read data from spare block - // - Ptr = Buffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Count = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - // - // Set TopSwap bit - // - Status = SetSwapState (FtwLiteDevice, TRUE); - DEBUG ((EFI_D_ERROR, "FtwLite: Set Swap State - %r\n", Status)); - ASSERT_EFI_ERROR (Status); - } - // - // Erase boot block. After setting TopSwap bit, it's spare block now! - // - Status = FtwEraseSpareBlock (FtwLiteDevice); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return EFI_ABORTED; - } - // - // Write memory buffer to currenet spare block - // - Ptr = Buffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Count = FtwLiteDevice->SizeOfSpareBlock; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write boot block - %r\n", Status)); - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - - FreePool (Buffer); - - // - // Clear TopSwap bit - // - Status = SetSwapState (FtwLiteDevice, FALSE); - DEBUG ((EFI_D_ERROR, "FtwLite: Clear Swap State - %r\n", Status)); - ASSERT_EFI_ERROR (Status); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c deleted file mode 100644 index d31883b..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c +++ /dev/null @@ -1,143 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. 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. - -Module Name: - - IpfFtwMisc.c - -Abstract: - - Ipf platform related code to support FtwLite.. - -Revision History - ---*/ - - -#include - -// -// MACROs for boot block update -// -#define BOOT_BLOCK_BASE - -STATIC -EFI_STATUS -GetSwapState ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - OUT BOOLEAN *SwapState - ) -/*++ - -Routine Description: - - Get swap state - -Arguments: - - FtwLiteDevice - Calling context - SwapState - Swap state - -Returns: - - EFI_SUCCESS - State successfully got - ---*/ -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -SetSwapState ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN BOOLEAN TopSwap - ) -/*++ - -Routine Description: - Set swap state. - -Arguments: - FtwLiteDevice - Indicates a pointer to the calling context. - TopSwap - New swap state - -Returns: - EFI_SUCCESS - The function completed successfully - -Note: - the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that - software will not be able to clear the Top-Swap bit until the system is - rebooted without GNT[A]# being pulled down. - ---*/ -{ - return EFI_SUCCESS; -} - -BOOLEAN -IsBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - - Check whether the block is a boot block. - -Arguments: - - FtwLiteDevice - Calling context - FvBlock - Fvb protocol instance - Lba - Lba value - -Returns: - - Is a boot block or not - ---*/ -{ - // - // IPF doesn't support safe bootblock update - // so treat bootblock as normal block - // - return FALSE; -} - -EFI_STATUS -FlushSpareBlockToBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Boot block is accessed by BootFvb protocol interface. LBA is 0. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - Spare block content is copied to boot block - EFI_INVALID_PARAMETER - Input parameter error - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - -Notes: - ---*/ -{ - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c deleted file mode 100644 index d8e3a03..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c +++ /dev/null @@ -1,140 +0,0 @@ - -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. 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. - -Module Name: - - x64FtwMisc.c - -Abstract: - - X64 platform related code to support FtwLite.. - -Revision History - ---*/ - - -#include - -// -// MACROs for boot block update -// -#define BOOT_BLOCK_BASE - -// STATIC -EFI_STATUS -GetSwapState ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - OUT BOOLEAN *SwapState - ) -/*++ - -Routine Description: - - Get swap state - -Arguments: - - FtwLiteDevice - Calling context - SwapState - Swap state - -Returns: - - EFI_SUCCESS - State successfully got - ---*/ -{ - return EFI_SUCCESS; -} - -// STATIC -EFI_STATUS -SetSwapState ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN BOOLEAN TopSwap - ) -/*++ - -Routine Description: - Set swap state. - -Arguments: - FtwLiteDevice - Indicates a pointer to the calling context. - TopSwap - New swap state - -Returns: - EFI_SUCCESS - The function completed successfully - -Note: - the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that - software will not be able to clear the Top-Swap bit until the system is - rebooted without GNT[A]# being pulled down. - ---*/ -{ - return EFI_SUCCESS; -} - -BOOLEAN -IsBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -/*++ - -Routine Description: - - Check whether the block is a boot block. - -Arguments: - - FtwLiteDevice - Calling context - FvBlock - Fvb protocol instance - Lba - Lba value - -Returns: - - Is a boot block or not - ---*/ -{ - return FALSE; -} - -EFI_STATUS -FlushSpareBlockToBootBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -/*++ - -Routine Description: - Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. - Spare block is accessed by FTW backup FVB protocol interface. LBA is - FtwLiteDevice->FtwSpareLba. - Boot block is accessed by BootFvb protocol interface. LBA is 0. - -Arguments: - FtwLiteDevice - The private data of FTW_LITE driver - -Returns: - EFI_SUCCESS - Spare block content is copied to boot block - EFI_INVALID_PARAMETER - Input parameter error - EFI_OUT_OF_RESOURCES - Allocate memory error - EFI_ABORTED - The function could not complete successfully - -Notes: - ---*/ -{ - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.c b/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.c deleted file mode 100644 index ca5ee21..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.c +++ /dev/null @@ -1,265 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. 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. - -Module Name: - - Crc32SectionExtract.c - -Abstract: - - Implements GUIDed section extraction protocol interface with - a specific GUID: CRC32. - - Please refer to the Framewokr Firmware Volume Specification 0.9. - ---*/ - - -#include - -EFI_STATUS -GuidedSectionExtractionProtocolConstructor ( - OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL **GuidedSep, - IN EFI_EXTRACT_GUIDED_SECTION ExtractSection - ) -/*++ - -Routine Description: - - Constructor for the GUIDed section extraction protocol. Initializes - instance data. - -Arguments: - - This Instance to construct - -Returns: - - EFI_SUCCESS: Instance initialized. - ---*/ -// TODO: GuidedSep - add argument and description to function comment -// TODO: ExtractSection - add argument and description to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -{ - *GuidedSep = AllocatePool (sizeof (EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL)); - if (*GuidedSep == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - (*GuidedSep)->ExtractSection = ExtractSection; - - return EFI_SUCCESS; -} - - -EFI_STATUS -EFIAPI -InitializeCrc32GuidedSectionExtractionProtocol ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -/*++ - -Routine Description: - - Entry point of the CRC32 GUIDed section extraction protocol. - Creates and initializes an instance of the GUIDed section - extraction protocol with CRC32 GUID. - -Arguments: - - ImageHandle EFI_HANDLE: A handle for the image that is initializing - this driver - SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table - -Returns: - - EFI_SUCCESS: Driver initialized successfully - EFI_LOAD_ERROR: Failed to Initialize or has been loaded - EFI_OUT_OF_RESOURCES: Could not allocate needed resources - ---*/ -{ - EFI_STATUS Status; - EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *Crc32GuidedSep; - EFI_HANDLE Handle; - - // - // Call all constructors per produced protocols - // - Status = GuidedSectionExtractionProtocolConstructor ( - &Crc32GuidedSep, - (EFI_EXTRACT_GUIDED_SECTION) Crc32ExtractSection - ); - if (EFI_ERROR (Status)) { - if (Crc32GuidedSep != NULL) { - FreePool (Crc32GuidedSep); - } - - return Status; - } - // - // Pass in a NULL to install to a new handle - // - Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &Handle, - &gEfiCrc32GuidedSectionExtractionProtocolGuid, - EFI_NATIVE_INTERFACE, - Crc32GuidedSep - ); - if (EFI_ERROR (Status)) { - FreePool (Crc32GuidedSep); - return EFI_LOAD_ERROR; - } - - return EFI_SUCCESS; -} - -STATIC -UINT32 -EFIAPI -GetSectionLength ( - IN EFI_COMMON_SECTION_HEADER *CommonHeader - ) -/*++ - - Routine Description: - Get a length of section. - - Parameters: - CommonHeader - Pointer to the common section header. - - Return Value: - The length of the section, including the section header. - ---*/ -// TODO: function comment is missing 'Arguments:' -// TODO: function comment is missing 'Returns:' -// TODO: CommonHeader - add argument and description to function comment -{ - UINT32 Size; - - Size = *(UINT32 *) CommonHeader->Size & 0x00FFFFFF; - - return Size; -} - -STATIC -EFI_STATUS -EFIAPI -Crc32ExtractSection ( - IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, - IN VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus - ) -/*++ - - Routine Description: - This function reads and extracts contents of a section from an - encapsulating section. - - Parameters: - This - Indicates the calling context. - InputSection - Buffer containing the input GUIDed section - to be processed. - OutputBuffer - *OutputBuffer is allocated from boot services - pool memory and containing the new section - stream. The caller is responsible for freeing - this buffer. - AuthenticationStatus - Pointer to a caller allocated UINT32 that - indicates the authentication status of the - output buffer - - Return Value: - EFI_SUCCESS - EFI_OUT_OF_RESOURCES - EFI_INVALID_PARAMETER - EFI_NOT_AVAILABLE_YET - ---*/ -// TODO: function comment is missing 'Arguments:' -// TODO: function comment is missing 'Returns:' -// TODO: This - add argument and description to function comment -// TODO: InputSection - add argument and description to function comment -// TODO: OutputBuffer - add argument and description to function comment -// TODO: OutputSize - add argument and description to function comment -// TODO: AuthenticationStatus - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - CRC32_SECTION_HEADER *Crc32SectionHeader; - EFI_GUID_DEFINED_SECTION *GuidedSectionHeader; - UINT8 *Image; - UINT32 Crc32Checksum; - VOID *DummyInterface; - - if (OutputBuffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - *OutputBuffer = NULL; - - // - // Points to the section header - // - Crc32SectionHeader = (CRC32_SECTION_HEADER *) InputSection; - GuidedSectionHeader = (EFI_GUID_DEFINED_SECTION *) InputSection; - - // - // Check if the GUID is a CRC32 section GUID - // - if (!CompareGuid ( - &(GuidedSectionHeader->SectionDefinitionGuid), - &gEfiCrc32GuidedSectionExtractionProtocolGuid - )) { - return EFI_INVALID_PARAMETER; - } - - Image = (UINT8 *) InputSection + (UINT32) (GuidedSectionHeader->DataOffset); - *OutputSize = GetSectionLength ((EFI_COMMON_SECTION_HEADER *) InputSection) - (UINT32) GuidedSectionHeader->DataOffset; - - *OutputBuffer = AllocatePool (*OutputSize); - if (*OutputBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Implictly CRC32 GUIDed section should have STATUS_VALID bit set - // - ASSERT (GuidedSectionHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID); - *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; - - // - // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID. - // - Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface); - if (!EFI_ERROR (Status)) { - *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE; - } else { - // - // Calculate CRC32 Checksum of Image - // - gBS->CalculateCrc32 (Image, *OutputSize, &Crc32Checksum); - if (Crc32Checksum != Crc32SectionHeader->CRC32Checksum) { - *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; - } - } - - CopyMem (*OutputBuffer, Image, *OutputSize); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.dxs b/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.dxs deleted file mode 100644 index d42975a..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.dxs +++ /dev/null @@ -1,26 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. 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. - -Module Name: - - Crc32SectionExtraction.dxs - -Abstract: - - Dependency expression file. - ---*/ -#include "DxeDepex.h" - -DEPENDENCY_START - EFI_RUNTIME_ARCH_PROTOCOL_GUID -DEPENDENCY_END - diff --git a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.h b/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.h deleted file mode 100644 index e7bf276..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.h +++ /dev/null @@ -1,105 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. 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. - -Module Name: - - Crc32SectionExtract.h - -Abstract: - - Header file for Crc32SectionExtract.c - Please refer to the Framewokr Firmware Volume Specification 0.9. - ---*/ - -#ifndef _CRC32_GUIDED_SECTION_EXTRACTION_H -#define _CRC32_GUIDED_SECTION_EXTRACTION_H - -#include -#include -#include -#include -#include -#include -#include -#include - - - -typedef struct { - EFI_GUID_DEFINED_SECTION GuidedSectionHeader; - UINT32 CRC32Checksum; -} CRC32_SECTION_HEADER; - -// -// Function prototype declarations -// -STATIC -EFI_STATUS -EFIAPI -Crc32ExtractSection ( - IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, - IN VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - InputSection - TODO: add argument description - OutputBuffer - TODO: add argument description - OutputSize - TODO: add argument description - AuthenticationStatus - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -InitializeCrc32GuidedSectionExtractionProtocol ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -/*++ - -Routine Description: - - Entry point of the CRC32 GUIDed section extraction protocol. - Creates and initializes an instance of the GUIDed section - extraction protocol with CRC32 GUID. - -Arguments: - - ImageHandle EFI_HANDLE: A handle for the image that is initializing - this driver - SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table - -Returns: - - EFI_SUCCESS: Driver initialized successfully - EFI_LOAD_ERROR: Failed to Initialize or has been loaded - EFI_OUT_OF_RESOURCES: Could not allocate needed resources - ---*/ -; - -#endif diff --git a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.inf b/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.inf deleted file mode 100644 index 5b0c65d..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.inf +++ /dev/null @@ -1,53 +0,0 @@ -#/** @file -# Component description file for Crc32SectionExtract module. -# -# This driver implements CRC32 GUIDed section extraction protocol interface. -# Copyright (c) 2006 - 2007, Intel Corporation -# -# All rights reserved. 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 = Crc32SectionExtract - FILE_GUID = 51C9F40C-5243-4473-B265-B3C8FFAFF9FA - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - EDK_RELEASE_VERSION = 0x00020000 - EFI_SPECIFICATION_VERSION = 0x00020000 - - ENTRY_POINT = InitializeCrc32GuidedSectionExtractionProtocol - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources.common] - Crc32SectionExtract.h - Crc32SectionExtract.c - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - MemoryAllocationLib - UefiBootServicesTableLib - BaseMemoryLib - UefiDriverEntryPoint - DebugLib - -[Protocols] - gEfiSecurityPolicyProtocolGuid # PROTOCOL SOMETIMES_CONSUMED - gEfiCrc32GuidedSectionExtractionProtocolGuid # PROTOCOL ALWAYS_PRODUCED - -[Depex] - gEfiRuntimeArchProtocolGuid diff --git a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa b/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa deleted file mode 100644 index a4ab182..0000000 --- a/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa +++ /dev/null @@ -1,66 +0,0 @@ - - - - Crc32SectionExtract - DXE_DRIVER - 51C9F40C-5243-4473-B265-B3C8FFAFF9FA - 1.0 - Component description file for Crc32SectionExtract module. - This driver implements CRC32 GUIDed section extraction protocol interface. - Copyright (c) 2006 - 2007, Intel Corporation - All rights reserved. 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. - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 - - - IA32 X64 IPF EBC - false - Crc32SectionExtract - - - - DebugLib - - - UefiDriverEntryPoint - - - BaseMemoryLib - - - UefiBootServicesTableLib - - - MemoryAllocationLib - - - - Crc32SectionExtract.c - Crc32SectionExtract.h - GuidedSection.c - GuidedSection.h - Crc32SectionExtract.dxs - - - - - - - gEfiSecurityPolicyProtocolGuid - - - gEfiCrc32GuidedSectionExtractionProtocolGuid - - - - EFI_SPECIFICATION_VERSION 0x00020000 - EDK_RELEASE_VERSION 0x00020000 - - InitializeCrc32GuidedSectionExtractionProtocol - - - -- cgit v1.1