diff options
Diffstat (limited to 'Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c')
-rw-r--r-- | Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c | 444 |
1 files changed, 0 insertions, 444 deletions
diff --git a/Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c b/Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c deleted file mode 100644 index cb09566..0000000 --- a/Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c +++ /dev/null @@ -1,444 +0,0 @@ -/** @file - This file implement the Variable Protocol for the block device. - - Copyright (c) 2015-2016, Linaro Limited. All rights reserved. - Copyright (c) 2015-2016, Hisilicon Limited. 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 <Guid/VariableFormat.h> -#include <Guid/SystemNvDataGuid.h> - -#include <Library/BaseMemoryLib.h> -#include <Library/CacheMaintenanceLib.h> -#include <Library/DebugLib.h> -#include <Library/DevicePathLib.h> -#include <Library/IoLib.h> -#include <Library/MemoryAllocationLib.h> -#include <Library/PcdLib.h> -#include <Library/UefiBootServicesTableLib.h> -#include <Library/UefiLib.h> - -#include "BlockVariableDxe.h" - - -STATIC EFI_PHYSICAL_ADDRESS mMapNvStorageVariableBase; - -EFI_STATUS -EFIAPI -FvbGetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_FVB_ATTRIBUTES_2 FvbAttributes; - FvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( - - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') - - ); - FvbAttributes |= EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled - - *Attributes = FvbAttributes; - - DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - *Address = mMapNvStorageVariableBase; - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -FvbGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ) -{ - BLOCK_VARIABLE_INSTANCE *Instance; - - Instance = CR (This, BLOCK_VARIABLE_INSTANCE, FvbProtocol, BLOCK_VARIABLE_SIGNATURE); - *BlockSize = (UINTN) Instance->Media.BlockSize; - *NumberOfBlocks = PcdGet32 (PcdNvStorageVariableBlockCount); - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -FvbRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ) -{ - BLOCK_VARIABLE_INSTANCE *Instance; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_STATUS Status; - UINTN Bytes; - VOID *DataPtr; - - Instance = CR (This, BLOCK_VARIABLE_INSTANCE, FvbProtocol, BLOCK_VARIABLE_SIGNATURE); - BlockIo = Instance->BlockIoProtocol; - Bytes = (Offset + *NumBytes + Instance->Media.BlockSize - 1) / Instance->Media.BlockSize * Instance->Media.BlockSize; - DataPtr = AllocateZeroPool (Bytes); - if (DataPtr == NULL) { - DEBUG ((EFI_D_ERROR, "FvbWrite: failed to allocate buffer.\n")); - return EFI_BUFFER_TOO_SMALL; - } - WriteBackDataCacheRange (DataPtr, Bytes); - InvalidateDataCacheRange (Buffer, *NumBytes); - Status = BlockIo->ReadBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba, - Bytes, DataPtr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FvbRead StartLba:%x, Lba:%x, Offset:%x, Status:%x\n", - Instance->StartLba, Lba, Offset, Status)); - goto exit; - } - CopyMem (Buffer, DataPtr + Offset, *NumBytes); - WriteBackDataCacheRange (Buffer, *NumBytes); -exit: - FreePool (DataPtr); - return Status; -} - -EFI_STATUS -EFIAPI -FvbWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - BLOCK_VARIABLE_INSTANCE *Instance; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_STATUS Status; - UINTN Bytes; - VOID *DataPtr; - - Instance = CR (This, BLOCK_VARIABLE_INSTANCE, FvbProtocol, BLOCK_VARIABLE_SIGNATURE); - BlockIo = Instance->BlockIoProtocol; - Bytes = (Offset + *NumBytes + Instance->Media.BlockSize - 1) / Instance->Media.BlockSize * Instance->Media.BlockSize; - DataPtr = AllocateZeroPool (Bytes); - if (DataPtr == NULL) { - DEBUG ((EFI_D_ERROR, "FvbWrite: failed to allocate buffer.\n")); - return EFI_BUFFER_TOO_SMALL; - } - WriteBackDataCacheRange (DataPtr, Bytes); - Status = BlockIo->ReadBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba, - Bytes, DataPtr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FvbWrite: failed on reading blocks.\n")); - goto exit; - } - CopyMem (DataPtr + Offset, Buffer, *NumBytes); - WriteBackDataCacheRange (DataPtr, Bytes); - Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba, - Bytes, DataPtr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FvbWrite StartLba:%x, Lba:%x, Offset:%x, Status:%x\n", - Instance->StartLba, Lba, Offset, Status)); - } - // Sometimes the variable isn't flushed into block device if it's the last flush operation. - // So flush it again. - Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba, - Bytes, DataPtr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FvbWrite StartLba:%x, Lba:%x, Offset:%x, Status:%x\n", - Instance->StartLba, Lba, Offset, Status)); - } -exit: - FreePool (DataPtr); - return Status; -} - -EFI_STATUS -EFIAPI -FvbEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ) -{ - return EFI_SUCCESS; -} - -STATIC BLOCK_VARIABLE_INSTANCE mBlockVariableInstance = { - .Signature = BLOCK_VARIABLE_SIGNATURE, - .Media = { - .MediaId = 0, - .RemovableMedia = FALSE, - .MediaPresent = TRUE, - .LogicalPartition = TRUE, - .ReadOnly = FALSE, - .WriteCaching = FALSE, - .BlockSize = 0, - .IoAlign = 4, - .LastBlock = 0, - .LowestAlignedLba = 0, - .LogicalBlocksPerPhysicalBlock = 0, - }, - .FvbProtocol = { - .GetAttributes = FvbGetAttributes, - .SetAttributes = FvbSetAttributes, - .GetPhysicalAddress = FvbGetPhysicalAddress, - .GetBlockSize = FvbGetBlockSize, - .Read = FvbRead, - .Write = FvbWrite, - .EraseBlocks = FvbEraseBlocks, - } -}; - -EFI_STATUS -ValidateFvHeader ( - IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader - ) -{ - UINT16 Checksum, TempChecksum; - VARIABLE_STORE_HEADER *VariableStoreHeader; - UINTN VariableStoreLength; - UINTN FvLength; - - FvLength = (UINTN) (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize)); - - // - // Verify the header revision, header signature, length - // Length of FvBlock cannot be 2**64-1 - // HeaderLength cannot be an odd number - // - if ( (FwVolHeader->Revision != EFI_FVH_REVISION) - || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) - || (FwVolHeader->FvLength != FvLength) - ) - { - DEBUG ((EFI_D_ERROR, "ValidateFvHeader: No Firmware Volume header present\n")); - return EFI_NOT_FOUND; - } - - // Check the Firmware Volume Guid - if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { - DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Firmware Volume Guid non-compatible\n")); - return EFI_NOT_FOUND; - } - - // Verify the header checksum - TempChecksum = FwVolHeader->Checksum; - FwVolHeader->Checksum = 0; - Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); - if (Checksum != TempChecksum) { - DEBUG ((EFI_D_ERROR, "ValidateFvHeader: FV checksum is invalid (Checksum:0x%X)\n",Checksum)); - return EFI_NOT_FOUND; - } - FwVolHeader->Checksum = Checksum; - - VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FwVolHeader + FwVolHeader->HeaderLength); - - // Check the Variable Store Guid - if( CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) == FALSE ) { - DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Guid non-compatible\n")); - return EFI_NOT_FOUND; - } - - VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; - if (VariableStoreHeader->Size != VariableStoreLength) { - DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Length does not match\n")); - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -InitNonVolatileVariableStore ( - IN BLOCK_VARIABLE_INSTANCE *Instance, - IN VOID *Headers, - IN UINTN HeadersLength - ) -{ - EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; - EFI_STATUS Status; - VARIABLE_STORE_HEADER *VariableStoreHeader; - - // Check if the size of the area is at least one block size - ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->BlockIoProtocol->Media->BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->BlockIoProtocol->Media->BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->BlockIoProtocol->Media->BlockSize > 0)); - - // - // EFI_FIRMWARE_VOLUME_HEADER - // - FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Headers; - CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); - FirmwareVolumeHeader->FvLength = - PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); - FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; - FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled - ); - FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); - FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; - FirmwareVolumeHeader->BlockMap[0].NumBlocks = PcdGet32 (PcdNvStorageVariableBlockCount); - FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockIoProtocol->Media->BlockSize; - // BlockMap Terminator - FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; - FirmwareVolumeHeader->BlockMap[1].Length = 0; - FirmwareVolumeHeader->Checksum = 0; - FirmwareVolumeHeader->Checksum = CalculateSum16 ((UINT16*)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength); - - // - // VARIABLE_STORE_HEADER - // - VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FirmwareVolumeHeader + FirmwareVolumeHeader->HeaderLength); - CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); - VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; - VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; - VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; - - Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); - return Status; -} - -EFI_STATUS -BlockVariableDxeInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_HANDLE Handle; - EFI_STATUS Status; - BLOCK_VARIABLE_INSTANCE *Instance = &mBlockVariableInstance; - UINT32 Count; - EFI_LBA Lba; - UINTN NvStorageSize; - EFI_DEVICE_PATH_PROTOCOL *NvBlockDevicePath; - UINT8 *NvStorageData; - VOID *Headers; - UINTN HeadersLength; - - Instance->Signature = BLOCK_VARIABLE_SIGNATURE; - - HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); - Headers = AllocateZeroPool(HeadersLength); - if (Headers == NULL) { - DEBUG ((EFI_D_ERROR, "%a: failed to allocate memory of Headers\n", __func__)); - return EFI_OUT_OF_RESOURCES; - } - - Lba = (EFI_LBA) PcdGet32 (PcdNvStorageVariableBlockLba); - Count = PcdGet32 (PcdNvStorageVariableBlockCount); - Instance->Media.BlockSize = PcdGet32 (PcdNvStorageVariableBlockSize); - NvStorageSize = Count * Instance->Media.BlockSize; - Instance->StartLba = Lba; - HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); - if (NvStorageSize < HeadersLength) { - return EFI_BAD_BUFFER_SIZE; - } - NvStorageData = (UINT8 *) (UINTN) PcdGet32(PcdFlashNvStorageVariableBase); - mMapNvStorageVariableBase = PcdGet32(PcdFlashNvStorageVariableBase); - NvBlockDevicePath = &Instance->DevicePath; - NvBlockDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdNvStorageVariableBlockDevicePath)); - Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &NvBlockDevicePath, - &Instance->Handle); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate NVM device (status: %r)\n", Status)); - return EFI_INVALID_PARAMETER; - } - Status = gBS->OpenProtocol ( - Instance->Handle, - &gEfiBlockIoProtocolGuid, - (VOID **) &Instance->BlockIoProtocol, - gImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Warning: Couldn't open NVM device (status: %r)\n", Status)); - return EFI_DEVICE_ERROR; - } - WriteBackDataCacheRange (Instance, sizeof(BLOCK_VARIABLE_INSTANCE)); - - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol, - NULL - ); - if (EFI_ERROR (Status)) { - goto exit; - } - - Status = FvbRead (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = ValidateFvHeader (Headers); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a, Found invalid Fv Header\n", __func__)); - - // Erase all the block device that is reserved for variable storage - Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, Count, EFI_LBA_LIST_TERMINATOR); - if (EFI_ERROR (Status)) { - goto exit; - } - - Status = InitNonVolatileVariableStore (Instance, Headers, HeadersLength); - if (EFI_ERROR (Status)) { - goto exit; - } - } - - if (NvStorageSize > ((EFI_FIRMWARE_VOLUME_HEADER*)Headers)->FvLength) { - NvStorageSize = ((EFI_FIRMWARE_VOLUME_HEADER*)Headers)->FvLength; - NvStorageSize = ((NvStorageSize + Instance->Media.BlockSize - 1) / Instance->Media.BlockSize) * Instance->Media.BlockSize; - } - Status = FvbRead (&Instance->FvbProtocol, 0, 0, &NvStorageSize, NvStorageData); - -exit: - return Status; -} |