From 0c18794ea4289f03fefc7117b56740414cc0536c Mon Sep 17 00:00:00 2001 From: gdong1 Date: Fri, 2 Sep 2011 07:49:32 +0000 Subject: Add security package to repository. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12261 6f19259b-4bc3-4df7-8a09-765794883524 --- .../VariableAuthenticated/RuntimeDxe/Reclaim.c | 172 +++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c (limited to 'SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c') diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c new file mode 100644 index 0000000000..4f7a41cd09 --- /dev/null +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c @@ -0,0 +1,172 @@ +/** @file + Handles non-volatile variable store garbage collection, using FTW + (Fault Tolerant Write) protocol. + +Copyright (c) 2009 - 2010, 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. + +**/ + +#include "Variable.h" + +/** + Gets LBA of block and offset by given address. + + This function gets the Logical Block Address (LBA) of a firmware + volume block containing the given address, and the offset of the + address on the block. + + @param Address Address which should be contained + by returned FVB handle. + @param Lba Pointer to LBA for output. + @param Offset Pointer to offset for output. + + @retval EFI_SUCCESS LBA and offset successfully returned. + @retval EFI_NOT_FOUND Fail to find FVB handle by address. + @retval EFI_ABORTED Fail to find valid LBA and offset. + +**/ +EFI_STATUS +GetLbaAndOffsetByAddress ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT EFI_LBA *Lba, + OUT UINTN *Offset + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS FvbBaseAddress; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry; + UINT32 LbaIndex; + + *Lba = (EFI_LBA) (-1); + *Offset = 0; + + // + // Get the proper FVB protocol. + // + Status = GetFvbInfoByAddress (Address, NULL, &Fvb); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the Base Address of FV. + // + Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress); + if (EFI_ERROR (Status)) { + return Status; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress); + + // + // Get the (LBA, Offset) of Address. + // + if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) { + // + // BUGBUG: Assume one FV has one type of BlockLength. + // + FvbMapEntry = &FwVolHeader->BlockMap[0]; + for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { + if (Address < (FvbBaseAddress + FvbMapEntry->Length * LbaIndex)) { + // + // Found the (Lba, Offset). + // + *Lba = LbaIndex - 1; + *Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->Length * (LbaIndex - 1))); + return EFI_SUCCESS; + } + } + } + + return EFI_ABORTED; +} + +/** + Writes a buffer to variable storage space, in the working block. + + This function writes a buffer to variable storage space into a firmware + volume block device. The destination is specified by parameter + VariableBase. Fault Tolerant Write protocol is used for writing. + + @param VariableBase Base address of variable to write + @param Buffer Point to the data buffer. + @param BufferSize The number of bytes of the data Buffer. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. + @retval EFI_ABORTED The function could not complete successfully. + +**/ +EFI_STATUS +FtwVariableSpace ( + IN EFI_PHYSICAL_ADDRESS VariableBase, + IN UINT8 *Buffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + EFI_LBA VarLba; + UINTN VarOffset; + UINT8 *FtwBuffer; + UINTN FtwBufferSize; + EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; + + // + // Locate fault tolerant write protocol. + // + Status = GetFtwProtocol((VOID **) &FtwProtocol); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Locate Fvb handle by address. + // + Status = GetFvbInfoByAddress (VariableBase, &FvbHandle, NULL); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get LBA and Offset by address. + // + Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Prepare for the variable data. + // + FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size; + FtwBuffer = AllocatePool (FtwBufferSize); + if (FtwBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff); + CopyMem (FtwBuffer, Buffer, BufferSize); + + // + // FTW write record. + // + Status = FtwProtocol->Write ( + FtwProtocol, + VarLba, // LBA + VarOffset, // Offset + FtwBufferSize, // NumBytes + NULL, // PrivateData NULL + FvbHandle, // Fvb Handle + FtwBuffer // write buffer + ); + + FreePool (FtwBuffer); + return Status; +} -- cgit v1.2.3