#include <Library/UefiLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
\r
#include <Guid/VariableFormat.h>\r
\r
#include "NorFlashDxe.h"\r
\r
+STATIC EFI_EVENT mFvbVirtualAddrChangeEvent;\r
+STATIC UINTN mFlashNvStorageVariableBase;\r
\r
///\r
/// The Firmware Volume Block Protocol is the low-level interface\r
\r
ASSERT(Address != NULL);\r
\r
- *Address = PcdGet32 (PcdFlashNvStorageVariableBase);\r
+ *Address = mFlashNvStorageVariableBase;\r
return EFI_SUCCESS;\r
}\r
\r
return Status;\r
}\r
\r
+/**\r
+ Fixup internal data so that EFI can be call in virtual mode.\r
+ Call the passed in Child Notify event and convert any pointers in\r
+ lib to virtual mode.\r
+\r
+ @param[in] Event The Event that is being processed\r
+ @param[in] Context Event Context\r
+**/\r
+VOID\r
+EFIAPI\r
+FvbVirtualNotifyEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase);\r
+ return;\r
+}\r
+\r
EFI_STATUS\r
EFIAPI\r
NorFlashFvbInitialize (\r
EFI_STATUS Status;\r
UINT32 FvbNumLba;\r
EFI_BOOT_MODE BootMode;\r
+ UINTN RuntimeMmioRegionSize;\r
\r
DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));\r
\r
Instance->Initialized = TRUE;\r
+ mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);\r
\r
// Set the index of the first LBA for the FVB\r
Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;\r
return Status;\r
}\r
}\r
+\r
+ //\r
+ // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME\r
+ //\r
+\r
+ // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;\r
+ // even if we only use the small block region at the top of the NOR Flash.\r
+ // The reason is when the NOR Flash memory is set into program mode, the command\r
+ // is written as the base of the flash region (ie: Instance->DeviceBaseAddress)\r
+ RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;\r
+\r
+ Status = gDS->AddMemorySpace (\r
+ EfiGcdMemoryTypeMemoryMappedIo,\r
+ Instance->DeviceBaseAddress, RuntimeMmioRegionSize,\r
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = gDS->SetMemorySpaceAttributes (\r
+ Instance->DeviceBaseAddress, RuntimeMmioRegionSize,\r
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Register for the virtual address change event\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ FvbVirtualNotifyEvent,\r
+ NULL,\r
+ &gEfiEventVirtualAddressChangeGuid,\r
+ &mFvbVirtualAddrChangeEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
return Status;\r
}\r