]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API
[mirror_edk2.git] / ArmVirtPkg / Library / QemuFwCfgLib / QemuFwCfgLib.c
index 56db908f5c91a73a51b14af93b86dd0963b5c0d4..9dd5c911fc5c24d5a88994ea88026591ab743bed 100644 (file)
@@ -55,19 +55,33 @@ VOID (EFIAPI WRITE_BYTES_FUNCTION) (
   IN VOID  *Buffer OPTIONAL\r
   );\r
 \r
+/**\r
+  Skips bytes in firmware configuration\r
+\r
+  @param[in] Size  Size in bytes to skip\r
+\r
+**/\r
+typedef\r
+VOID (EFIAPI SKIP_BYTES_FUNCTION) (\r
+  IN UINTN Size\r
+  );\r
+\r
 //\r
 // Forward declaration of the two implementations we have.\r
 //\r
 STATIC READ_BYTES_FUNCTION MmioReadBytes;\r
 STATIC WRITE_BYTES_FUNCTION MmioWriteBytes;\r
+STATIC SKIP_BYTES_FUNCTION MmioSkipBytes;\r
 STATIC READ_BYTES_FUNCTION DmaReadBytes;\r
 STATIC WRITE_BYTES_FUNCTION DmaWriteBytes;\r
+STATIC SKIP_BYTES_FUNCTION DmaSkipBytes;\r
 \r
 //\r
 // These correspond to the implementation we detect at runtime.\r
 //\r
 STATIC READ_BYTES_FUNCTION *InternalQemuFwCfgReadBytes = MmioReadBytes;\r
 STATIC WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes;\r
+STATIC SKIP_BYTES_FUNCTION *InternalQemuFwCfgSkipBytes = MmioSkipBytes;\r
 \r
 \r
 /**\r
@@ -183,6 +197,7 @@ QemuFwCfgInitialize (
           mFwCfgDmaAddress = FwCfgDmaAddress;\r
           InternalQemuFwCfgReadBytes = DmaReadBytes;\r
           InternalQemuFwCfgWriteBytes = DmaWriteBytes;\r
+          InternalQemuFwCfgSkipBytes = DmaSkipBytes;\r
         }\r
       }\r
     } else {\r
@@ -433,6 +448,69 @@ QemuFwCfgWriteBytes (
 }\r
 \r
 \r
+/**\r
+  Slow SKIP_BYTES_FUNCTION.\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+MmioSkipBytes (\r
+  IN UINTN Size\r
+  )\r
+{\r
+  UINTN ChunkSize;\r
+  UINT8 SkipBuffer[256];\r
+\r
+  //\r
+  // Emulate the skip by reading data in chunks, and throwing it away. The\r
+  // implementation below doesn't affect the static data footprint for client\r
+  // modules. Large skips are not expected, therefore this fallback is not\r
+  // performance critical. The size of SkipBuffer is thought not to exert a\r
+  // large pressure on the stack.\r
+  //\r
+  while (Size > 0) {\r
+    ChunkSize = MIN (Size, sizeof SkipBuffer);\r
+    MmioReadBytes (ChunkSize, SkipBuffer);\r
+    Size -= ChunkSize;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Fast SKIP_BYTES_FUNCTION.\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+DmaSkipBytes (\r
+  IN UINTN Size\r
+  )\r
+{\r
+  DmaTransferBytes (Size, NULL, FW_CFG_DMA_CTL_SKIP);\r
+}\r
+\r
+\r
+/**\r
+  Skip bytes in the firmware configuration item.\r
+\r
+  Increase the offset of the firmware configuration item without transferring\r
+  bytes between the item and a caller-provided buffer. Subsequent read, write\r
+  or skip operations will commence at the increased offset.\r
+\r
+  @param[in] Size  Number of bytes to skip.\r
+**/\r
+VOID\r
+EFIAPI\r
+QemuFwCfgSkipBytes (\r
+  IN UINTN Size\r
+  )\r
+{\r
+  if (QemuFwCfgIsAvailable ()) {\r
+    InternalQemuFwCfgSkipBytes (Size);\r
+  }\r
+}\r
+\r
+\r
 /**\r
   Reads a UINT8 firmware configuration value\r
 \r