From 2dff0c1ab2be86979ccb99db8b17bd3347b98b59 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Tue, 8 Apr 2014 18:02:32 +0000 Subject: [PATCH] ArmPlatformPkg/NorFlashDxe: Fix coding mistakes that would prevent Runtime mode - No allocation during Runtime mode (post ExitBootServices()) - Allocate all the persistent data into runtime space - Do not access BootServices API during Runtime mode 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@15437 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Drivers/NorFlashDxe/NorFlashDxe.c | 50 +++++++++++++------ .../Drivers/NorFlashDxe/NorFlashDxe.h | 4 +- .../Drivers/NorFlashDxe/NorFlashDxe.inf | 1 + .../Drivers/NorFlashDxe/NorFlashFvbDxe.c | 49 ++++++------------ 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c index 7953b6c9f5..f6551253d1 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c @@ -1,6 +1,6 @@ /** @file NorFlashDxe.c - Copyright (c) 2011-2013, 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 @@ -72,7 +72,7 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = { FvbEraseBlocks, // EraseBlocks NULL, //ParentHandle }, // FvbProtoccol; - + NULL, // FvbBuffer { { { @@ -109,7 +109,7 @@ NorFlashCreateInstance ( ASSERT(NorFlashInstance != NULL); - Instance = AllocateCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate); + Instance = AllocateRuntimeCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate); if (Instance == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -123,11 +123,15 @@ NorFlashCreateInstance ( Instance->Media.BlockSize = BlockSize; Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1; - CopyGuid (&Instance->DevicePath.Vendor.Guid,NorFlashGuid); + CopyGuid (&Instance->DevicePath.Vendor.Guid, NorFlashGuid); if (SupportFvb) { Instance->SupportFvb = TRUE; Instance->Initialize = NorFlashFvbInitialize; + Instance->FvbBuffer = AllocateRuntimePool (BlockSize);; + if (Instance->FvbBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } Status = gBS->InstallMultipleProtocolInterfaces ( &Instance->Handle, @@ -137,7 +141,7 @@ NorFlashCreateInstance ( NULL ); if (EFI_ERROR(Status)) { - FreePool(Instance); + FreePool (Instance); return Status; } } else { @@ -150,7 +154,7 @@ NorFlashCreateInstance ( NULL ); if (EFI_ERROR(Status)) { - FreePool(Instance); + FreePool (Instance); return Status; } } @@ -340,8 +344,14 @@ NorFlashUnlockAndEraseSingleBlock ( UINTN Index; EFI_TPL OriginalTPL; - // Raise TPL to TPL_HIGH to stop anyone from interrupting us. - OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + if (!EfiAtRuntime ()) { + // Raise TPL to TPL_HIGH to stop anyone from interrupting us. + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + } else { + // This initialization is only to prevent the compiler to complain about the + // use of uninitialized variables + OriginalTPL = TPL_HIGH_LEVEL; + } Index = 0; // The block erase might fail a first time (SW bug ?). Retry it ... @@ -358,8 +368,10 @@ NorFlashUnlockAndEraseSingleBlock ( DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index)); } - // Interruptions can resume. - gBS->RestoreTPL (OriginalTPL); + if (!EfiAtRuntime ()) { + // Interruptions can resume. + gBS->RestoreTPL (OriginalTPL); + } return Status; } @@ -581,8 +593,14 @@ NorFlashWriteSingleBlock ( // Start writing from the first address at the start of the block WordAddress = BlockAddress; - // Raise TPL to TPL_HIGH to stop anyone from interrupting us. - OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + if (!EfiAtRuntime ()) { + // Raise TPL to TPL_HIGH to stop anyone from interrupting us. + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + } else { + // This initialization is only to prevent the compiler to complain about the + // use of uninitialized variables + OriginalTPL = TPL_HIGH_LEVEL; + } Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress); if (EFI_ERROR(Status)) { @@ -632,8 +650,10 @@ NorFlashWriteSingleBlock ( } EXIT: - // Interruptions can resume. - gBS->RestoreTPL (OriginalTPL); + if (!EfiAtRuntime ()) { + // Interruptions can resume. + gBS->RestoreTPL (OriginalTPL); + } if (EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status)); @@ -797,7 +817,7 @@ NorFlashInitialise ( return Status; } - mNorFlashInstances = AllocatePool (sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount); + mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount); for (Index = 0; Index < NorFlashDeviceCount; Index++) { // Check if this NOR Flash device contain the variable storage region diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h index 959c0c1905..424d63925b 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h @@ -1,6 +1,6 @@ /** @file NorFlashDxe.h - 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 @@ -26,6 +26,7 @@ #include #include #include +#include #define NOR_FLASH_ERASE_RETRY 10 @@ -141,6 +142,7 @@ struct _NOR_FLASH_INSTANCE { BOOLEAN SupportFvb; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + VOID* FvbBuffer; NOR_FLASH_DEVICE_PATH DevicePath; }; diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf index 83c61b7a3f..dddaa3c0f8 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf @@ -41,6 +41,7 @@ UefiLib UefiDriverEntryPoint UefiBootServicesTableLib + UefiRuntimeLib [Guids] gEfiSystemNvDataFvGuid diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c index 4b56f2a40a..b9230c1ee0 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c @@ -1,6 +1,6 @@ /*++ @file NorFlashFvbDxe.c - Copyright (c) 2011-201333, 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 @@ -417,7 +417,6 @@ FvbRead ( EFI_STATUS Status; EFI_STATUS TempStatus; UINTN BlockSize; - UINT8 *BlockBuffer; NOR_FLASH_INSTANCE *Instance; Instance = INSTANCE_FROM_FVB_THIS(This); @@ -450,32 +449,24 @@ 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)); + // Check we did get some memory + if (Instance->FvbBuffer == NULL) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Buffer not ready\n")); return EFI_DEVICE_ERROR; } // Read NOR Flash data into shadow buffer - TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer); + TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer); if (EFI_ERROR (TempStatus)) { // Return one of the pre-approved error statuses - Status = EFI_DEVICE_ERROR; - goto FREE_MEMORY; + 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)); + DEBUG ((DEBUG_BLKIO, "FvbRead: CopyMem( Dst=0x%08x, Src=0x%08x, Size=0x%x ).\n", Buffer, (UINTN)Instance->FvbBuffer + Offset, *NumBytes)); - CopyMem(Buffer, BlockBuffer + Offset, *NumBytes); + CopyMem (Buffer, (VOID*)((UINTN)Instance->FvbBuffer + Offset), *NumBytes); -FREE_MEMORY: - FreePool(BlockBuffer); return Status; } @@ -546,7 +537,6 @@ FvbWrite ( EFI_STATUS Status; EFI_STATUS TempStatus; UINTN BlockSize; - UINT8 *BlockBuffer; NOR_FLASH_INSTANCE *Instance; Instance = INSTANCE_FROM_FVB_THIS(This); @@ -585,38 +575,29 @@ FvbWrite ( return EFI_BAD_BUFFER_SIZE; } - // 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)); + if (Instance->FvbBuffer == NULL) { + DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Buffer not ready\n")); return EFI_DEVICE_ERROR; } // Read NOR Flash data into shadow buffer - TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer); + TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer); if (EFI_ERROR (TempStatus)) { // Return one of the pre-approved error statuses - Status = EFI_DEVICE_ERROR; - goto FREE_MEMORY; + return EFI_DEVICE_ERROR; } // Put the data at the appropriate location inside the buffer area - CopyMem((BlockBuffer + Offset), Buffer, *NumBytes); + CopyMem ((VOID*)((UINTN)Instance->FvbBuffer + Offset), Buffer, *NumBytes); // Write the modified buffer back to the NorFlash - TempStatus = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer); + TempStatus = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer); if (EFI_ERROR (TempStatus)) { // Return one of the pre-approved error statuses - Status = EFI_DEVICE_ERROR; - goto FREE_MEMORY; + return EFI_DEVICE_ERROR; } -FREE_MEMORY: - FreePool(BlockBuffer); return Status; }