aboutsummaryrefslogtreecommitdiffstats
path: root/Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c')
-rw-r--r--Drivers/Variable/BlockVariableDxe/BlockVariableDxe.c444
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;
-}