ArmPlatformPkg/NorFlashDxe: Fix coding mistakes that would prevent Runtime mode
authorOlivier Martin <olivier.martin@arm.com>
Tue, 8 Apr 2014 18:02:32 +0000 (18:02 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 8 Apr 2014 18:02:32 +0000 (18:02 +0000)
- 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

ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c

index 7953b6c..f655125 100644 (file)
@@ -1,6 +1,6 @@
 /** @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
@@ -72,7 +72,7 @@ NOR_FLASH_INSTANCE  mNorFlashInstanceTemplate = {
     FvbEraseBlocks, // EraseBlocks\r
     NULL, //ParentHandle\r
   }, //  FvbProtoccol;\r
-\r
+  NULL, // FvbBuffer\r
   {\r
     {\r
       {\r
@@ -109,7 +109,7 @@ NorFlashCreateInstance (
 \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
@@ -123,11 +123,15 @@ NorFlashCreateInstance (
   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
+    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
@@ -137,7 +141,7 @@ NorFlashCreateInstance (
                   NULL\r
                   );\r
     if (EFI_ERROR(Status)) {\r
-      FreePool(Instance);\r
+      FreePool (Instance);\r
       return Status;\r
     }\r
   } else {\r
@@ -150,7 +154,7 @@ NorFlashCreateInstance (
                     NULL\r
                     );\r
     if (EFI_ERROR(Status)) {\r
-      FreePool(Instance);\r
+      FreePool (Instance);\r
       return Status;\r
     }\r
   }\r
@@ -340,8 +344,14 @@ NorFlashUnlockAndEraseSingleBlock (
   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
@@ -358,8 +368,10 @@ NorFlashUnlockAndEraseSingleBlock (
     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
 \r
   return Status;\r
 }\r
@@ -581,8 +593,14 @@ NorFlashWriteSingleBlock (
   // 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
@@ -632,8 +650,10 @@ NorFlashWriteSingleBlock (
   }\r
 \r
 EXIT:\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
@@ -797,7 +817,7 @@ NorFlashInitialise (
     return Status;\r
   }\r
 \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
index 959c0c1..424d639 100644 (file)
@@ -1,6 +1,6 @@
 /** @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
@@ -26,6 +26,7 @@
 #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
@@ -141,6 +142,7 @@ struct _NOR_FLASH_INSTANCE {
 \r
   BOOLEAN                             SupportFvb;\r
   EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;\r
+  VOID*                               FvbBuffer;\r
 \r
   NOR_FLASH_DEVICE_PATH                      DevicePath;\r
 };\r
index 83c61b7..dddaa3c 100644 (file)
@@ -41,6 +41,7 @@
   UefiLib\r
   UefiDriverEntryPoint\r
   UefiBootServicesTableLib\r
+  UefiRuntimeLib\r
 \r
 [Guids]\r
   gEfiSystemNvDataFvGuid\r
index 4b56f2a..b9230c1 100644 (file)
@@ -1,6 +1,6 @@
 /*++ @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
@@ -417,7 +417,6 @@ FvbRead (
   EFI_STATUS    Status;\r
   EFI_STATUS    TempStatus;\r
   UINTN         BlockSize;\r
-  UINT8         *BlockBuffer;\r
   NOR_FLASH_INSTANCE *Instance;\r
 \r
   Instance = INSTANCE_FROM_FVB_THIS(This);\r
@@ -450,32 +449,24 @@ FvbRead (
     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
-  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
-    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
-  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
 \r
-  CopyMem(Buffer, BlockBuffer + Offset, *NumBytes);\r
+  CopyMem (Buffer, (VOID*)((UINTN)Instance->FvbBuffer + Offset), *NumBytes);\r
 \r
-FREE_MEMORY:\r
-  FreePool(BlockBuffer);\r
   return Status;\r
 }\r
 \r
@@ -546,7 +537,6 @@ FvbWrite (
   EFI_STATUS  Status;\r
   EFI_STATUS  TempStatus;\r
   UINTN       BlockSize;\r
-  UINT8       *BlockBuffer;\r
   NOR_FLASH_INSTANCE *Instance;\r
 \r
   Instance = INSTANCE_FROM_FVB_THIS(This);\r
@@ -585,38 +575,29 @@ FvbWrite (
     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
-  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
-  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
-    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
-  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
-  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
-    Status = EFI_DEVICE_ERROR;\r
-    goto FREE_MEMORY;\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-FREE_MEMORY:\r
-  FreePool(BlockBuffer);\r
   return Status;\r
 }\r
 \r