]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
ArmPlatformPkg/NorFlashDxe: prepare for devicepath format change
[mirror_edk2.git] / ArmPlatformPkg / Drivers / NorFlashDxe / NorFlashDxe.c
index 7030a3c866c342dc2a6eb4afbbe3329fb592761c..53753a4721ac980f202e690b596a1ad31e7250c6 100644 (file)
@@ -32,9 +32,6 @@ NOR_FLASH_INSTANCE  mNorFlashInstanceTemplate = {
   NOR_FLASH_SIGNATURE, // Signature\r
   NULL, // Handle ... NEED TO BE FILLED\r
 \r
-  FALSE, // Initialized\r
-  NULL, // Initialize\r
-\r
   0, // DeviceBaseAddress ... NEED TO BE FILLED\r
   0, // RegionBaseAddress ... NEED TO BE FILLED\r
   0, // Size ... NEED TO BE FILLED\r
@@ -69,7 +66,6 @@ NOR_FLASH_INSTANCE  mNorFlashInstanceTemplate = {
     NorFlashDiskIoWriteDisk        // WriteDisk\r
   },\r
 \r
-  FALSE, // SupportFvb ... NEED TO BE FILLED\r
   {\r
     FvbGetAttributes, // GetAttributes\r
     FvbSetAttributes, // SetAttributes\r
@@ -86,16 +82,17 @@ NOR_FLASH_INSTANCE  mNorFlashInstanceTemplate = {
       {\r
         HARDWARE_DEVICE_PATH,\r
         HW_VENDOR_DP,\r
-        (UINT8)( sizeof(VENDOR_DEVICE_PATH)      ),\r
-        (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),\r
+        {\r
+          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)),\r
+          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8)\r
+        }\r
       },\r
-      { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, // GUID ... NEED TO BE FILLED\r
+      { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, // GUID ... NEED TO BE FILLED\r
     },\r
     {\r
       END_DEVICE_PATH_TYPE,\r
       END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-      sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
-      0\r
+      { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }\r
     }\r
     } // DevicePath\r
 };\r
@@ -105,7 +102,7 @@ NorFlashCreateInstance (
   IN UINTN                  NorFlashDeviceBase,\r
   IN UINTN                  NorFlashRegionBase,\r
   IN UINTN                  NorFlashSize,\r
-  IN UINT32                 MediaId,\r
+  IN UINT32                 Index,\r
   IN UINT32                 BlockSize,\r
   IN BOOLEAN                SupportFvb,\r
   IN CONST GUID             *NorFlashGuid,\r
@@ -127,7 +124,7 @@ NorFlashCreateInstance (
   Instance->Size = NorFlashSize;\r
 \r
   Instance->BlockIoProtocol.Media = &Instance->Media;\r
-  Instance->Media.MediaId = MediaId;\r
+  Instance->Media.MediaId = Index;\r
   Instance->Media.BlockSize = BlockSize;\r
   Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;\r
 \r
@@ -139,8 +136,7 @@ NorFlashCreateInstance (
   }\r
 \r
   if (SupportFvb) {\r
-    Instance->SupportFvb = TRUE;\r
-    Instance->Initialize = NorFlashFvbInitialize;\r
+    NorFlashFvbInitialize (Instance);\r
 \r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Instance->Handle,\r
@@ -154,8 +150,6 @@ NorFlashCreateInstance (
       return Status;\r
     }\r
   } else {\r
-    Instance->Initialized = TRUE;\r
-\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
                     &Instance->Handle,\r
                     &gEfiDevicePathProtocolGuid, &Instance->DevicePath,\r
@@ -184,7 +178,7 @@ NorFlashReadStatusRegister (
   return MmioRead32 (Instance->DeviceBaseAddress);\r
 }\r
 \r
-\r
+STATIC\r
 BOOLEAN\r
 NorFlashBlockIsLocked (\r
   IN NOR_FLASH_INSTANCE     *Instance,\r
@@ -192,9 +186,6 @@ NorFlashBlockIsLocked (
   )\r
 {\r
   UINT32                LockStatus;\r
-  BOOLEAN               BlockIsLocked;\r
-\r
-  BlockIsLocked = TRUE;\r
 \r
   // Send command for reading device id\r
   SEND_NOR_COMMAND (BlockAddress, 2, P30_CMD_READ_DEVICE_ID);\r
@@ -209,23 +200,16 @@ NorFlashBlockIsLocked (
     DEBUG((EFI_D_ERROR, "NorFlashBlockIsLocked: WARNING: Block LOCKED DOWN\n"));\r
   }\r
 \r
-  if ((LockStatus & 0x1) == 0) {\r
-    // This means the block is unlocked\r
-    DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: Block 0x%08x unlocked\n", BlockAddress));\r
-    BlockIsLocked = FALSE;\r
-  }\r
-\r
-  return BlockIsLocked;\r
+  return ((LockStatus & 0x1) != 0);\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 NorFlashUnlockSingleBlock (\r
   IN NOR_FLASH_INSTANCE     *Instance,\r
   IN UINTN                  BlockAddress\r
   )\r
 {\r
-  EFI_STATUS            Status = EFI_SUCCESS;\r
   UINT32                LockStatus;\r
 \r
   // Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations\r
@@ -264,19 +248,21 @@ NorFlashUnlockSingleBlock (
   // Put device back into Read Array mode\r
   SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_READ_ARRAY);\r
 \r
-  DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: BlockAddress=0x%08x, Exit Status = \"%r\".\n", BlockAddress, Status));\r
+  DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: BlockAddress=0x%08x\n", BlockAddress));\r
 \r
-  return Status;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 NorFlashUnlockSingleBlockIfNecessary (\r
   IN NOR_FLASH_INSTANCE     *Instance,\r
   IN UINTN                  BlockAddress\r
   )\r
 {\r
-  EFI_STATUS Status = EFI_SUCCESS;\r
+  EFI_STATUS Status;\r
+\r
+  Status = EFI_SUCCESS;\r
 \r
   if (NorFlashBlockIsLocked (Instance, BlockAddress) == TRUE) {\r
     Status = NorFlashUnlockSingleBlock (Instance, BlockAddress);\r
@@ -289,6 +275,7 @@ NorFlashUnlockSingleBlockIfNecessary (
 /**\r
  * The following function presumes that the block has already been unlocked.\r
  **/\r
+STATIC\r
 EFI_STATUS\r
 NorFlashEraseSingleBlock (\r
   IN NOR_FLASH_INSTANCE     *Instance,\r
@@ -342,7 +329,7 @@ NorFlashEraseSingleBlock (
 }\r
 \r
 /**\r
- * The following function presumes that the block has already been unlocked.\r
+ * This function unlock and erase an entire NOR Flash block.\r
  **/\r
 EFI_STATUS\r
 NorFlashUnlockAndEraseSingleBlock (\r
@@ -368,9 +355,10 @@ NorFlashUnlockAndEraseSingleBlock (
   do {\r
     // Unlock the block if we have to\r
     Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);\r
-    if (!EFI_ERROR(Status)) {\r
-      Status = NorFlashEraseSingleBlock (Instance, BlockAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
     }\r
+    Status = NorFlashEraseSingleBlock (Instance, BlockAddress);\r
     Index++;\r
   } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));\r
 \r
@@ -533,7 +521,7 @@ NorFlashWriteBuffer (
 \r
   // Write the data to the NOR Flash, advancing each address by 4 bytes\r
   for(Count=0; Count < BufferSizeInWords; Count++, Data++, Buffer++) {\r
-    *Data = *Buffer;\r
+    MmioWrite32 ((UINTN)Data, *Buffer);\r
   }\r
 \r
   // Issue the Buffered Program Confirm command, to start the programming operation\r
@@ -752,6 +740,65 @@ NorFlashWriteBlocks (
   return Status;\r
 }\r
 \r
+#define BOTH_ALIGNED(a, b, align) ((((UINTN)(a) | (UINTN)(b)) & ((align) - 1)) == 0)\r
+\r
+/**\r
+  Copy Length bytes from Source to Destination, using aligned accesses only.\r
+  Note that this implementation uses memcpy() semantics rather then memmove()\r
+  semantics, i.e., SourceBuffer and DestinationBuffer should not overlap.\r
+\r
+  @param  DestinationBuffer The target of the copy request.\r
+  @param  SourceBuffer      The place to copy from.\r
+  @param  Length            The number of bytes to copy.\r
+\r
+  @return Destination\r
+\r
+**/\r
+STATIC\r
+VOID *\r
+AlignedCopyMem (\r
+  OUT     VOID                      *DestinationBuffer,\r
+  IN      CONST VOID                *SourceBuffer,\r
+  IN      UINTN                     Length\r
+  )\r
+{\r
+  UINT8             *Destination8;\r
+  CONST UINT8       *Source8;\r
+  UINT32            *Destination32;\r
+  CONST UINT32      *Source32;\r
+  UINT64            *Destination64;\r
+  CONST UINT64      *Source64;\r
+\r
+  if (BOTH_ALIGNED(DestinationBuffer, SourceBuffer, 8) && Length >= 8) {\r
+    Destination64 = DestinationBuffer;\r
+    Source64 = SourceBuffer;\r
+    while (Length >= 8) {\r
+      *Destination64++ = *Source64++;\r
+      Length -= 8;\r
+    }\r
+\r
+    Destination8 = (UINT8 *)Destination64;\r
+    Source8 = (CONST UINT8 *)Source64;\r
+  } else if (BOTH_ALIGNED(DestinationBuffer, SourceBuffer, 4) && Length >= 4) {\r
+    Destination32 = DestinationBuffer;\r
+    Source32 = SourceBuffer;\r
+    while (Length >= 4) {\r
+      *Destination32++ = *Source32++;\r
+      Length -= 4;\r
+    }\r
+\r
+    Destination8 = (UINT8 *)Destination32;\r
+    Source8 = (CONST UINT8 *)Source32;\r
+  } else {\r
+    Destination8 = DestinationBuffer;\r
+    Source8 = SourceBuffer;\r
+  }\r
+  while (Length-- != 0) {\r
+    *Destination8++ = *Source8++;\r
+  }\r
+  return DestinationBuffer;\r
+}\r
+\r
 EFI_STATUS\r
 NorFlashReadBlocks (\r
   IN NOR_FLASH_INSTANCE   *Instance,\r
@@ -799,7 +846,7 @@ NorFlashReadBlocks (
   SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);\r
 \r
   // Readout the data\r
-  CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes);\r
+  AlignedCopyMem (Buffer, (VOID *)StartAddress, BufferSizeInBytes);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -813,8 +860,7 @@ NorFlashRead (
   OUT VOID                *Buffer\r
   )\r
 {\r
-  UINT32              NumBlocks;\r
-  UINTN               StartAddress;\r
+  UINTN  StartAddress;\r
 \r
   // The buffer must be valid\r
   if (Buffer == NULL) {\r
@@ -826,15 +872,7 @@ NorFlashRead (
     return EFI_SUCCESS;\r
   }\r
 \r
-  // All blocks must be within the device\r
-  NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize ;\r
-\r
-  if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {\r
-    DEBUG ((EFI_D_ERROR, "NorFlashRead: ERROR - Read will exceed last block\n"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Offset + BufferSizeInBytes >= Instance->Size) {\r
+  if (((Lba * Instance->Media.BlockSize) + Offset + BufferSizeInBytes) > Instance->Size) {\r
     DEBUG ((EFI_D_ERROR, "NorFlashRead: ERROR - Read will exceed device size.\n"));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -849,7 +887,7 @@ NorFlashRead (
   SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);\r
 \r
   // Readout the data\r
-  CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes);\r
+  AlignedCopyMem (Buffer, (VOID *)(StartAddress + Offset), BufferSizeInBytes);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -882,11 +920,7 @@ NorFlashWriteSingleBlock (
 \r
   PrevBlockAddress = 0;\r
 \r
-  if (!Instance->Initialized && Instance->Initialize) {\r
-    Instance->Initialize(Instance);\r
-  }\r
-\r
-  DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Instance->StartLba + Lba, Offset, *NumBytes, Buffer));\r
+  DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));\r
 \r
   // Detect WriteDisabled state\r
   if (Instance->Media.ReadOnly == TRUE) {\r
@@ -928,8 +962,7 @@ NorFlashWriteSingleBlock (
     while (BytesToWrite > 0) {\r
       // Read full word from NOR, splice as required. A word is the smallest\r
       // unit we can write.\r
-      TempStatus = NorFlashRead (Instance, Instance->StartLba + Lba,\r
-                                 CurOffset & ~(0x3), sizeof(Tmp), &Tmp);\r
+      TempStatus = NorFlashRead (Instance, Lba, CurOffset & ~(0x3), sizeof(Tmp), &Tmp);\r
       if (EFI_ERROR (TempStatus)) {\r
         return EFI_DEVICE_ERROR;\r
       }\r
@@ -1042,7 +1075,7 @@ NorFlashWriteSingleBlock (
   }\r
 \r
   // Read NOR Flash data into shadow buffer\r
-  TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->ShadowBuffer);\r
+  TempStatus = NorFlashReadBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);\r
   if (EFI_ERROR (TempStatus)) {\r
     // Return one of the pre-approved error statuses\r
     return EFI_DEVICE_ERROR;\r
@@ -1052,7 +1085,7 @@ NorFlashWriteSingleBlock (
   CopyMem ((VOID*)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumBytes);\r
 \r
   // Write the modified buffer back to the NorFlash\r
-  TempStatus = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->ShadowBuffer);\r
+  TempStatus = NorFlashWriteBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);\r
   if (EFI_ERROR (TempStatus)) {\r
     // Return one of the pre-approved error statuses\r
     return EFI_DEVICE_ERROR;\r