diff options
4 files changed, 127 insertions, 5 deletions
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c index f6551253d1..a03bf5749e 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c @@ -20,11 +20,13 @@ #include "NorFlashDxe.h"
+STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;
//
// Global variable declarations
//
NOR_FLASH_INSTANCE **mNorFlashInstances;
+UINT32 mNorFlashDeviceCount;
NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
NOR_FLASH_SIGNATURE, // Signature
@@ -792,6 +794,50 @@ NorFlashReset ( return EFI_SUCCESS;
}
+/**
+ 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
+NorFlashVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->DeviceBaseAddress);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->RegionBaseAddress);
+
+ // Convert BlockIo protocol
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.FlushBlocks);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.ReadBlocks);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.Reset);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.WriteBlocks);
+
+ // Convert Fvb
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.EraseBlocks);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetAttributes);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetBlockSize);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetPhysicalAddress);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.Read);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.SetAttributes);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.Write);
+
+ if (mNorFlashInstances[Index]->FvbBuffer != NULL) {
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbBuffer);
+ }
+ }
+
+ return;
+}
+
EFI_STATUS
EFIAPI
NorFlashInitialise (
@@ -802,7 +848,6 @@ NorFlashInitialise ( EFI_STATUS Status;
UINT32 Index;
NOR_FLASH_DESCRIPTION* NorFlashDevices;
- UINT32 NorFlashDeviceCount;
BOOLEAN ContainVariableStorage;
Status = NorFlashPlatformInitialization ();
@@ -811,15 +856,15 @@ NorFlashInitialise ( return Status;
}
- Status = NorFlashPlatformGetDevices (&NorFlashDevices,&NorFlashDeviceCount);
+ Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));
return Status;
}
- mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount);
+ mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount);
- for (Index = 0; Index < NorFlashDeviceCount; Index++) {
+ for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
// Check if this NOR Flash device contain the variable storage region
ContainVariableStorage =
(NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) &&
@@ -840,5 +885,18 @@ NorFlashInitialise ( }
}
+ //
+ // Register for the virtual address change event
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ NorFlashVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mNorFlashVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
return Status;
}
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h index 424d63925b..e4d767bf94 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h @@ -19,6 +19,8 @@ #include <Base.h>
#include <PiDxe.h>
+#include <Guid/EventGroup.h>
+
#include <Protocol/BlockIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf index dddaa3c0f8..a2eb27e8f6 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf @@ -42,10 +42,12 @@ UefiDriverEntryPoint
UefiBootServicesTableLib
UefiRuntimeLib
+ DxeServicesTableLib
[Guids]
gEfiSystemNvDataFvGuid
gEfiVariableGuid
+ gEfiEventVirtualAddressChangeGuid
[Protocols]
gEfiBlockIoProtocolGuid
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c index b9230c1ee0..84890cbfce 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c @@ -20,6 +20,7 @@ #include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Guid/VariableFormat.h>
@@ -27,6 +28,8 @@ #include "NorFlashDxe.h"
+STATIC EFI_EVENT mFvbVirtualAddrChangeEvent;
+STATIC UINTN mFlashNvStorageVariableBase;
///
/// The Firmware Volume Block Protocol is the low-level interface
@@ -301,7 +304,7 @@ FvbGetPhysicalAddress ( ASSERT(Address != NULL);
- *Address = PcdGet32 (PcdFlashNvStorageVariableBase);
+ *Address = mFlashNvStorageVariableBase;
return EFI_SUCCESS;
}
@@ -745,6 +748,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 (
@@ -754,10 +776,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;
@@ -789,5 +813,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;
}
|