X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmPlatformPkg%2FDrivers%2FNorFlashDxe%2FNorFlashFvbDxe.c;h=bf420853b0a173d96cbb37a163f11ae2fac2eec2;hp=0c138a5ab2e7cb15203ed706ea9cbec7de4d11c6;hb=452a9ee1a637baf7894943c9f850175f679f8ce6;hpb=1e57a46299244793beb27e74be171d1540606999
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
index 0c138a5ab2..bf420853b0 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
@@ -1,6 +1,6 @@
/*++ @file NorFlashFvbDxe.c
- Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
@@ -27,6 +28,8 @@
#include "NorFlashDxe.h"
+STATIC EFI_EVENT mFvbVirtualAddrChangeEvent;
+STATIC UINTN mFlashNvStorageVariableBase;
///
/// The Firmware Volume Block Protocol is the low-level interface
@@ -107,7 +110,7 @@ InitializeFvAndVariableStoreHeaders (
//
// VARIABLE_STORE_HEADER
//
- VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINT32)Headers + FirmwareVolumeHeader->HeaderLength);
+ VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength);
CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED;
@@ -172,7 +175,7 @@ ValidateFvHeader (
return EFI_NOT_FOUND;
}
- VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINT32)FwVolHeader + FwVolHeader->HeaderLength);
+ VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FwVolHeader + FwVolHeader->HeaderLength);
// Check the Variable Store Guid
if( CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) == FALSE ) {
@@ -301,7 +304,7 @@ FvbGetPhysicalAddress (
ASSERT(Address != NULL);
- *Address = PcdGet32 (PcdFlashNvStorageVariableBase);
+ *Address = mFlashNvStorageVariableBase;
return EFI_SUCCESS;
}
@@ -414,10 +417,8 @@ FvbRead (
IN OUT UINT8 *Buffer
)
{
- EFI_STATUS Status;
EFI_STATUS TempStatus;
UINTN BlockSize;
- UINT8 *BlockBuffer;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
@@ -428,8 +429,7 @@ FvbRead (
Instance->Initialize(Instance);
}
- Status = EFI_SUCCESS;
- TempStatus = Status;
+ TempStatus = EFI_SUCCESS;
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->Media.BlockSize;
@@ -450,33 +450,21 @@ FvbRead (
return EFI_BAD_BUFFER_SIZE;
}
- // FixMe: Allow an arbitrary number of bytes to be read out, not just a multiple of block size.
-
- // Allocate runtime memory to read in the NOR Flash data. Variable Services are runtime.
- BlockBuffer = AllocateRuntimePool (BlockSize);
-
- // Check if the memory allocation was successful
- if (BlockBuffer == NULL) {
- DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Could not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));
- return EFI_DEVICE_ERROR;
- }
-
- // Read NOR Flash data into shadow buffer
- TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);
- if (EFI_ERROR (TempStatus)) {
- // Return one of the pre-approved error statuses
- Status = EFI_DEVICE_ERROR;
- goto FREE_MEMORY;
+ // Decide if we are doing full block reads or not.
+ if (*NumBytes % BlockSize != 0) {
+ TempStatus = NorFlashRead (Instance, Instance->StartLba + Lba, Offset, *NumBytes, Buffer);
+ if (EFI_ERROR (TempStatus)) {
+ return EFI_DEVICE_ERROR;
+ }
+ } else {
+ // Read NOR Flash data into shadow buffer
+ TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Buffer);
+ if (EFI_ERROR (TempStatus)) {
+ // Return one of the pre-approved error statuses
+ return EFI_DEVICE_ERROR;
+ }
}
-
- // Put the data at the appropriate location inside the buffer area
- DEBUG ((DEBUG_BLKIO, "FvbRead: CopyMem( Dst=0x%08x, Src=0x%08x, Size=0x%x ).\n", Buffer, BlockBuffer + Offset, *NumBytes));
-
- CopyMem(Buffer, BlockBuffer + Offset, *NumBytes);
-
-FREE_MEMORY:
- FreePool(BlockBuffer);
- return Status;
+ return EFI_SUCCESS;
}
/**
@@ -543,81 +531,11 @@ FvbWrite (
IN UINT8 *Buffer
)
{
- EFI_STATUS Status;
- EFI_STATUS TempStatus;
- UINTN BlockSize;
- UINT8 *BlockBuffer;
NOR_FLASH_INSTANCE *Instance;
- Instance = INSTANCE_FROM_FVB_THIS(This);
-
- if (!Instance->Initialized && Instance->Initialize) {
- Instance->Initialize(Instance);
- }
-
- DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Instance->StartLba + Lba, Offset, *NumBytes, Buffer));
-
- Status = EFI_SUCCESS;
- TempStatus = Status;
-
- // Detect WriteDisabled state
- if (Instance->Media.ReadOnly == TRUE) {
- DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Can not write: Device is in WriteDisabled state.\n"));
- // It is in WriteDisabled state, return an error right away
- return EFI_ACCESS_DENIED;
- }
-
- // Cache the block size to avoid de-referencing pointers all the time
- BlockSize = Instance->Media.BlockSize;
-
- // The write must not span block boundaries.
- // We need to check each variable individually because adding two large values together overflows.
- if ( ( Offset >= BlockSize ) ||
- ( *NumBytes > BlockSize ) ||
- ( (Offset + *NumBytes) > BlockSize ) ) {
- DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
- return EFI_BAD_BUFFER_SIZE;
- }
-
- // We must have some bytes to write
- if (*NumBytes == 0) {
- DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
- return EFI_BAD_BUFFER_SIZE;
- }
+ Instance = INSTANCE_FROM_FVB_THIS (This);
- // Allocate runtime memory to read in the NOR Flash data.
- // Since the intention is to use this with Variable Services and since these are runtime,
- // allocate the memory from the runtime pool.
- BlockBuffer = AllocateRuntimePool (BlockSize);
-
- // Check we did get some memory
- if( BlockBuffer == NULL ) {
- DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Can not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));
- return EFI_DEVICE_ERROR;
- }
-
- // Read NOR Flash data into shadow buffer
- TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);
- if (EFI_ERROR (TempStatus)) {
- // Return one of the pre-approved error statuses
- Status = EFI_DEVICE_ERROR;
- goto FREE_MEMORY;
- }
-
- // Put the data at the appropriate location inside the buffer area
- CopyMem((BlockBuffer + Offset), Buffer, *NumBytes);
-
- // Write the modified buffer back to the NorFlash
- Status = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);
- if (EFI_ERROR (TempStatus)) {
- // Return one of the pre-approved error statuses
- Status = EFI_DEVICE_ERROR;
- goto FREE_MEMORY;
- }
-
-FREE_MEMORY:
- FreePool(BlockBuffer);
- return Status;
+ return NorFlashWriteSingleBlock (Instance, Lba, Offset, NumBytes, Buffer);
}
/**
@@ -764,6 +682,25 @@ EXIT:
return Status;
}
+/**
+ Fixup internal data so that EFI can be call in virtual mode.
+ Call the passed in Child Notify event and convert any pointers in
+ lib to virtual mode.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+FvbVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase);
+ return;
+}
+
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
@@ -773,10 +710,12 @@ NorFlashFvbInitialize (
EFI_STATUS Status;
UINT32 FvbNumLba;
EFI_BOOT_MODE BootMode;
+ UINTN RuntimeMmioRegionSize;
DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
Instance->Initialized = TRUE;
+ mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
// Set the index of the first LBA for the FVB
Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;
@@ -808,5 +747,41 @@ NorFlashFvbInitialize (
return Status;
}
}
+
+ //
+ // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
+ //
+
+ // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;
+ // even if we only use the small block region at the top of the NOR Flash.
+ // The reason is when the NOR Flash memory is set into program mode, the command
+ // is written as the base of the flash region (ie: Instance->DeviceBaseAddress)
+ RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;
+
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gDS->SetMemorySpaceAttributes (
+ Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register for the virtual address change event
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ FvbVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mFvbVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
return Status;
}