From: Olivier Martin Date: Tue, 8 Apr 2014 18:03:25 +0000 (+0000) Subject: ArmPlatformPkg/NorFlashDxe: Fixed driver to support UEFI Runtime mode X-Git-Tag: edk2-stable201903~11546 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=1dbbfc176ffe8050d3de554acf246b2e21a6f650 ArmPlatformPkg/NorFlashDxe: Fixed driver to support UEFI Runtime mode - Added the NOR Flash region to the Runtime UEFI Memory Mapped IO - Caught the gEfiEventVirtualAddressChangeGuid event to fixup the NOR Flash pointers Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15438 6f19259b-4bc3-4df7-8a09-765794883524 --- 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 #include +#include + #include #include 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 #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 @@ -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; }