]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
ArmPlatformPkg/NorFlashDxe: Optimise FVB protocol
[mirror_edk2.git] / ArmPlatformPkg / Drivers / NorFlashDxe / NorFlashDxe.c
index a03bf5749e9fc56893525005684fc2cd75774ed4..82b9f3f742b9917e525a5f259be49350c541e827 100644 (file)
@@ -586,6 +586,7 @@ NorFlashWriteSingleBlock (
   UINTN         BuffersInBlock;\r
   UINTN         RemainingWords;\r
   EFI_TPL       OriginalTPL;\r
+  UINTN         Cnt;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -619,13 +620,22 @@ NorFlashWriteSingleBlock (
     BuffersInBlock = (UINTN)(BlockSizeInWords * 4) / P30_MAX_BUFFER_SIZE_IN_BYTES;\r
 \r
     // Then feed each buffer chunk to the NOR Flash\r
+    // If a buffer does not contain any data, don't write it.\r
     for(BufferIndex=0;\r
          BufferIndex < BuffersInBlock;\r
          BufferIndex++, WordAddress += P30_MAX_BUFFER_SIZE_IN_BYTES, DataBuffer += P30_MAX_BUFFER_SIZE_IN_WORDS\r
       ) {\r
-      Status = NorFlashWriteBuffer (Instance, WordAddress, P30_MAX_BUFFER_SIZE_IN_BYTES, DataBuffer);\r
-      if (EFI_ERROR(Status)) {\r
-        goto EXIT;\r
+      // Check the buffer to see if it contains any data (not set all 1s).\r
+      for (Cnt = 0; Cnt < P30_MAX_BUFFER_SIZE_IN_WORDS; Cnt++) {\r
+        if (~DataBuffer[Cnt] != 0 ) {\r
+          // Some data found, write the buffer.\r
+          Status = NorFlashWriteBuffer (Instance, WordAddress, P30_MAX_BUFFER_SIZE_IN_BYTES,\r
+                                        DataBuffer);\r
+          if (EFI_ERROR(Status)) {\r
+            goto EXIT;\r
+          }\r
+          break;\r
+        }\r
       }\r
     }\r
 \r
@@ -784,6 +794,57 @@ NorFlashReadBlocks (
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+NorFlashRead (\r
+  IN NOR_FLASH_INSTANCE   *Instance,\r
+  IN EFI_LBA              Lba,\r
+  IN UINTN                Offset,\r
+  IN UINTN                BufferSizeInBytes,\r
+  OUT VOID                *Buffer\r
+  )\r
+{\r
+  UINT32              NumBlocks;\r
+  UINTN               StartAddress;\r
+\r
+  // The buffer must be valid\r
+  if (Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Return if we have not any byte to read\r
+  if (BufferSizeInBytes == 0) {\r
+    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
+    DEBUG ((EFI_D_ERROR, "NorFlashRead: ERROR - Read will exceed device size.\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Get the address to start reading from\r
+  StartAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress,\r
+                                        Lba,\r
+                                        Instance->Media.BlockSize\r
+                                       );\r
+\r
+  // Put the device into Read Array mode\r
+  SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);\r
+\r
+  // Readout the data\r
+  CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 EFI_STATUS\r
 NorFlashReset (\r
   IN  NOR_FLASH_INSTANCE *Instance\r