\r
#include "NorFlashDxe.h"\r
\r
+STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;\r
\r
//\r
// Global variable declarations\r
//\r
NOR_FLASH_INSTANCE **mNorFlashInstances;\r
+UINT32 mNorFlashDeviceCount;\r
\r
NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {\r
NOR_FLASH_SIGNATURE, // Signature\r
return EFI_SUCCESS;\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
+NorFlashVirtualNotifyEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < mNorFlashDeviceCount; Index++) {\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->DeviceBaseAddress);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->RegionBaseAddress);\r
+\r
+ // Convert BlockIo protocol\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.FlushBlocks);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.ReadBlocks);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.Reset);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.WriteBlocks);\r
+\r
+ // Convert Fvb\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.EraseBlocks);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetAttributes);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetBlockSize);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetPhysicalAddress);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.Read);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.SetAttributes);\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.Write);\r
+\r
+ if (mNorFlashInstances[Index]->FvbBuffer != NULL) {\r
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbBuffer);\r
+ }\r
+ }\r
+\r
+ return;\r
+}\r
+\r
EFI_STATUS\r
EFIAPI\r
NorFlashInitialise (\r
EFI_STATUS Status;\r
UINT32 Index;\r
NOR_FLASH_DESCRIPTION* NorFlashDevices;\r
- UINT32 NorFlashDeviceCount;\r
BOOLEAN ContainVariableStorage;\r
\r
Status = NorFlashPlatformInitialization ();\r
return Status;\r
}\r
\r
- Status = NorFlashPlatformGetDevices (&NorFlashDevices,&NorFlashDeviceCount);\r
+ Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);\r
if (EFI_ERROR(Status)) {\r
DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));\r
return Status;\r
}\r
\r
- mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount);\r
+ mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount);\r
\r
- for (Index = 0; Index < NorFlashDeviceCount; Index++) {\r
+ for (Index = 0; Index < mNorFlashDeviceCount; Index++) {\r
// Check if this NOR Flash device contain the variable storage region\r
ContainVariableStorage =\r
(NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) &&\r
}\r
}\r
\r
+ //\r
+ // Register for the virtual address change event\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ NorFlashVirtualNotifyEvent,\r
+ NULL,\r
+ &gEfiEventVirtualAddressChangeGuid,\r
+ &mNorFlashVirtualAddrChangeEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
return Status;\r
}\r
#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