- 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 <olivier.martin@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15437
6f19259b-4bc3-4df7-8a09-
765794883524
/** @file NorFlashDxe.c\r
\r
/** @file NorFlashDxe.c\r
\r
- Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>\r
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
FvbEraseBlocks, // EraseBlocks\r
NULL, //ParentHandle\r
}, // FvbProtoccol;\r
FvbEraseBlocks, // EraseBlocks\r
NULL, //ParentHandle\r
}, // FvbProtoccol;\r
\r
ASSERT(NorFlashInstance != NULL);\r
\r
\r
ASSERT(NorFlashInstance != NULL);\r
\r
- Instance = AllocateCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate);\r
+ Instance = AllocateRuntimeCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate);\r
if (Instance == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
if (Instance == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
Instance->Media.BlockSize = BlockSize;\r
Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;\r
\r
Instance->Media.BlockSize = BlockSize;\r
Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;\r
\r
- CopyGuid (&Instance->DevicePath.Vendor.Guid,NorFlashGuid);\r
+ CopyGuid (&Instance->DevicePath.Vendor.Guid, NorFlashGuid);\r
\r
if (SupportFvb) {\r
Instance->SupportFvb = TRUE;\r
Instance->Initialize = NorFlashFvbInitialize;\r
\r
if (SupportFvb) {\r
Instance->SupportFvb = TRUE;\r
Instance->Initialize = NorFlashFvbInitialize;\r
+ Instance->FvbBuffer = AllocateRuntimePool (BlockSize);;\r
+ if (Instance->FvbBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Instance->Handle,\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Instance->Handle,\r
NULL\r
);\r
if (EFI_ERROR(Status)) {\r
NULL\r
);\r
if (EFI_ERROR(Status)) {\r
return Status;\r
}\r
} else {\r
return Status;\r
}\r
} else {\r
NULL\r
);\r
if (EFI_ERROR(Status)) {\r
NULL\r
);\r
if (EFI_ERROR(Status)) {\r
UINTN Index;\r
EFI_TPL OriginalTPL;\r
\r
UINTN Index;\r
EFI_TPL OriginalTPL;\r
\r
- // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
- OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ if (!EfiAtRuntime ()) {\r
+ // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ } else {\r
+ // This initialization is only to prevent the compiler to complain about the\r
+ // use of uninitialized variables\r
+ OriginalTPL = TPL_HIGH_LEVEL;\r
+ }\r
\r
Index = 0;\r
// The block erase might fail a first time (SW bug ?). Retry it ...\r
\r
Index = 0;\r
// The block erase might fail a first time (SW bug ?). Retry it ...\r
DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));\r
}\r
\r
DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));\r
}\r
\r
- // Interruptions can resume.\r
- gBS->RestoreTPL (OriginalTPL);\r
+ if (!EfiAtRuntime ()) {\r
+ // Interruptions can resume.\r
+ gBS->RestoreTPL (OriginalTPL);\r
+ }\r
// Start writing from the first address at the start of the block\r
WordAddress = BlockAddress;\r
\r
// Start writing from the first address at the start of the block\r
WordAddress = BlockAddress;\r
\r
- // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
- OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ if (!EfiAtRuntime ()) {\r
+ // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ } else {\r
+ // This initialization is only to prevent the compiler to complain about the\r
+ // use of uninitialized variables\r
+ OriginalTPL = TPL_HIGH_LEVEL;\r
+ }\r
\r
Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);\r
if (EFI_ERROR(Status)) {\r
\r
Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);\r
if (EFI_ERROR(Status)) {\r
- // Interruptions can resume.\r
- gBS->RestoreTPL (OriginalTPL);\r
+ if (!EfiAtRuntime ()) {\r
+ // Interruptions can resume.\r
+ gBS->RestoreTPL (OriginalTPL);\r
+ }\r
\r
if (EFI_ERROR(Status)) {\r
DEBUG((EFI_D_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status));\r
\r
if (EFI_ERROR(Status)) {\r
DEBUG((EFI_D_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status));\r
- mNorFlashInstances = AllocatePool (sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount);\r
+ mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount);\r
\r
for (Index = 0; Index < NorFlashDeviceCount; Index++) {\r
// Check if this NOR Flash device contain the variable storage region\r
\r
for (Index = 0; Index < NorFlashDeviceCount; Index++) {\r
// Check if this NOR Flash device contain the variable storage region\r
/** @file NorFlashDxe.h\r
\r
/** @file NorFlashDxe.h\r
\r
- Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>\r
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
#include <Library/IoLib.h>\r
#include <Library/NorFlashPlatformLib.h>\r
#include <Library/UefiLib.h>\r
#include <Library/IoLib.h>\r
#include <Library/NorFlashPlatformLib.h>\r
#include <Library/UefiLib.h>\r
+#include <Library/UefiRuntimeLib.h>\r
\r
#define NOR_FLASH_ERASE_RETRY 10\r
\r
\r
#define NOR_FLASH_ERASE_RETRY 10\r
\r
\r
BOOLEAN SupportFvb;\r
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;\r
\r
BOOLEAN SupportFvb;\r
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;\r
\r
NOR_FLASH_DEVICE_PATH DevicePath;\r
};\r
\r
NOR_FLASH_DEVICE_PATH DevicePath;\r
};\r
UefiLib\r
UefiDriverEntryPoint\r
UefiBootServicesTableLib\r
UefiLib\r
UefiDriverEntryPoint\r
UefiBootServicesTableLib\r
\r
[Guids]\r
gEfiSystemNvDataFvGuid\r
\r
[Guids]\r
gEfiSystemNvDataFvGuid\r
/*++ @file NorFlashFvbDxe.c\r
\r
/*++ @file NorFlashFvbDxe.c\r
\r
- Copyright (c) 2011-201333, ARM Ltd. All rights reserved.<BR>\r
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
EFI_STATUS Status;\r
EFI_STATUS TempStatus;\r
UINTN BlockSize;\r
EFI_STATUS Status;\r
EFI_STATUS TempStatus;\r
UINTN BlockSize;\r
NOR_FLASH_INSTANCE *Instance;\r
\r
Instance = INSTANCE_FROM_FVB_THIS(This);\r
NOR_FLASH_INSTANCE *Instance;\r
\r
Instance = INSTANCE_FROM_FVB_THIS(This);\r
return EFI_BAD_BUFFER_SIZE;\r
}\r
\r
return EFI_BAD_BUFFER_SIZE;\r
}\r
\r
- // FixMe: Allow an arbitrary number of bytes to be read out, not just a multiple of block size.\r
-\r
- // Allocate runtime memory to read in the NOR Flash data. Variable Services are runtime.\r
- BlockBuffer = AllocateRuntimePool (BlockSize);\r
-\r
- // Check if the memory allocation was successful\r
- if (BlockBuffer == NULL) {\r
- DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Could not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));\r
+ // Check we did get some memory\r
+ if (Instance->FvbBuffer == NULL) {\r
+ DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Buffer not ready\n"));\r
return EFI_DEVICE_ERROR;\r
}\r
\r
// Read NOR Flash data into shadow buffer\r
return EFI_DEVICE_ERROR;\r
}\r
\r
// Read NOR Flash data into shadow buffer\r
- TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);\r
+ TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer);\r
if (EFI_ERROR (TempStatus)) {\r
// Return one of the pre-approved error statuses\r
if (EFI_ERROR (TempStatus)) {\r
// Return one of the pre-approved error statuses\r
- Status = EFI_DEVICE_ERROR;\r
- goto FREE_MEMORY;\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
// Put the data at the appropriate location inside the buffer area\r
}\r
\r
// Put the data at the appropriate location inside the buffer area\r
- DEBUG ((DEBUG_BLKIO, "FvbRead: CopyMem( Dst=0x%08x, Src=0x%08x, Size=0x%x ).\n", Buffer, BlockBuffer + Offset, *NumBytes));\r
+ DEBUG ((DEBUG_BLKIO, "FvbRead: CopyMem( Dst=0x%08x, Src=0x%08x, Size=0x%x ).\n", Buffer, (UINTN)Instance->FvbBuffer + Offset, *NumBytes));\r
- CopyMem(Buffer, BlockBuffer + Offset, *NumBytes);\r
+ CopyMem (Buffer, (VOID*)((UINTN)Instance->FvbBuffer + Offset), *NumBytes);\r
-FREE_MEMORY:\r
- FreePool(BlockBuffer);\r
EFI_STATUS Status;\r
EFI_STATUS TempStatus;\r
UINTN BlockSize;\r
EFI_STATUS Status;\r
EFI_STATUS TempStatus;\r
UINTN BlockSize;\r
NOR_FLASH_INSTANCE *Instance;\r
\r
Instance = INSTANCE_FROM_FVB_THIS(This);\r
NOR_FLASH_INSTANCE *Instance;\r
\r
Instance = INSTANCE_FROM_FVB_THIS(This);\r
return EFI_BAD_BUFFER_SIZE;\r
}\r
\r
return EFI_BAD_BUFFER_SIZE;\r
}\r
\r
- // Allocate runtime memory to read in the NOR Flash data.\r
- // Since the intention is to use this with Variable Services and since these are runtime,\r
- // allocate the memory from the runtime pool.\r
- BlockBuffer = AllocateRuntimePool (BlockSize);\r
-\r
// Check we did get some memory\r
// Check we did get some memory\r
- if( BlockBuffer == NULL ) {\r
- DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Can not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));\r
+ if (Instance->FvbBuffer == NULL) {\r
+ DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));\r
return EFI_DEVICE_ERROR;\r
}\r
\r
// Read NOR Flash data into shadow buffer\r
return EFI_DEVICE_ERROR;\r
}\r
\r
// Read NOR Flash data into shadow buffer\r
- TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);\r
+ TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer);\r
if (EFI_ERROR (TempStatus)) {\r
// Return one of the pre-approved error statuses\r
if (EFI_ERROR (TempStatus)) {\r
// Return one of the pre-approved error statuses\r
- Status = EFI_DEVICE_ERROR;\r
- goto FREE_MEMORY;\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
// Put the data at the appropriate location inside the buffer area\r
}\r
\r
// Put the data at the appropriate location inside the buffer area\r
- CopyMem((BlockBuffer + Offset), Buffer, *NumBytes);\r
+ CopyMem ((VOID*)((UINTN)Instance->FvbBuffer + Offset), Buffer, *NumBytes);\r
\r
// Write the modified buffer back to the NorFlash\r
\r
// Write the modified buffer back to the NorFlash\r
- TempStatus = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);\r
+ TempStatus = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer);\r
if (EFI_ERROR (TempStatus)) {\r
// Return one of the pre-approved error statuses\r
if (EFI_ERROR (TempStatus)) {\r
// Return one of the pre-approved error statuses\r
- Status = EFI_DEVICE_ERROR;\r
- goto FREE_MEMORY;\r
+ return EFI_DEVICE_ERROR;\r
-FREE_MEMORY:\r
- FreePool(BlockBuffer);\r