]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes()
authorLaszlo Ersek <lersek@redhat.com>
Fri, 27 Jan 2017 05:35:41 +0000 (06:35 +0100)
committerLaszlo Ersek <lersek@redhat.com>
Mon, 30 Jan 2017 23:14:35 +0000 (00:14 +0100)
Introduce the new public API QemuFwCfgSkipBytes(), for advancing over
bytes in the selected firmware configuration item without transferring
data between the item and the caller.

When the DMA interface is available (the common case), the operation is
instantaneous. As a fallback, provide a loop of chunked reads into a small
stack-allocated scratch buffer.

This patch enables OvmfPkg/QemuFwCfgLib to overwrite part of a writeable
fw_cfg file, which will be particularly useful for the upcoming
QEMU_LOADER_WRITE_POINTER command in OvmfPkg/AcpiPlatformDxe.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=359
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
OvmfPkg/Include/Library/QemuFwCfgLib.h
OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c

index 3e017d53a97eacb05db39dae6cf9d73752688831..41c3817470a2633305b98c08687f958abd979dc7 100644 (file)
@@ -158,6 +158,22 @@ QemuFwCfgWriteBytes (
   );\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
+\r
 /**\r
   Reads a UINT8 firmware configuration value\r
 \r
index 6b6b2c7726e161b40a064f375aa5269fe3223ee1..7744873217fe8bbbb8826afa6d696bcb7b87be35 100644 (file)
@@ -192,6 +192,50 @@ QemuFwCfgWriteBytes (
 }\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
+  UINTN ChunkSize;\r
+  UINT8 SkipBuffer[256];\r
+\r
+  if (!InternalQemuFwCfgIsAvailable ()) {\r
+    return;\r
+  }\r
+\r
+  if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {\r
+    InternalQemuFwCfgDmaBytes ((UINT32)Size, NULL, FW_CFG_DMA_CTL_SKIP);\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Emulate the skip by reading data in chunks, and throwing it away. The\r
+  // implementation below is suitable even for phases where RAM or dynamic\r
+  // allocation is not available or appropriate. It also doesn't affect the\r
+  // static data footprint for client modules. Large skips are not expected,\r
+  // therefore this fallback is not performance critical. The size of\r
+  // SkipBuffer is thought not to exert a large pressure on the stack in any\r
+  // phase.\r
+  //\r
+  while (Size > 0) {\r
+    ChunkSize = MIN (Size, sizeof SkipBuffer);\r
+    IoReadFifo8 (0x511, ChunkSize, SkipBuffer);\r
+    Size -= ChunkSize;\r
+  }\r
+}\r
+\r
+\r
 /**\r
   Reads a UINT8 firmware configuration value\r
 \r