public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files
@ 2017-01-27 11:29 Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 1/5] OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP op Laszlo Ersek
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Laszlo Ersek @ 2017-01-27 11:29 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Ard Biesheuvel, Jordan Justen

This feature will allow OvmfPkg/AcpiPlatformDxe to implement the
QEMU_LOADER_WRITE_POINTER command, which will instruct the firmware to
write the address of a previously allocated/downloaded fw_cfg blob into
another (writeable) fw_cfg file at a specific offset, in order to inform
QEMU about the allocation address. The command will be based on the
QemuFwCfgSkipBytes() and QemuFwCfgWriteBytes() APIs.

Ref:    https://bugzilla.tianocore.org/show_bug.cgi?id=359
Repo:   https://github.com/lersek/edk2.git
Branch: fwcfg_skip

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>

Thanks,
Laszlo

Laszlo Ersek (5):
  OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP
    op
  OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes()
  ArmVirtPkg/QemuFwCfgLib: extract generic DmaTransferBytes() function
  ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if
    available
  ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API

 OvmfPkg/Include/Library/QemuFwCfgLib.h         |  16 ++
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 178 ++++++++++++++++++--
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c    |  75 +++++++--
 3 files changed, 246 insertions(+), 23 deletions(-)

-- 
2.9.3



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/5] OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP op
  2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
@ 2017-01-27 11:29 ` Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 2/5] OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes() Laszlo Ersek
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Laszlo Ersek @ 2017-01-27 11:29 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

The fw_cfg DMA interface provides a simple method to skip over bytes in an
fw_cfg blob before reading or writing more bytes.
InternalQemuFwCfgDmaBytes() can support it easily, we just have to expose
the Control parameter more flexibly than the current "Write" BOOLEAN.

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>
---
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 31 ++++++++++++--------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index a228c029dfb9..6b6b2c7726e1 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -47,32 +47,39 @@ QemuFwCfgSelectItem (
 
 
 /**
-  Transfer an array of bytes using the DMA interface.
+  Transfer an array of bytes, or skip a number of bytes, using the DMA
+  interface.
 
-  @param[in]     Size    Size in bytes to transfer.
-  @param[in,out] Buffer  Buffer to read data into or write data from. May be
-                         NULL if Size is zero.
-  @param[in]     Write   TRUE if writing to fw_cfg from Buffer, FALSE if
-                         reading from fw_cfg into Buffer.
+  @param[in]     Size     Size in bytes to transfer or skip.
+
+  @param[in,out] Buffer   Buffer to read data into or write data from. Ignored,
+                          and may be NULL, if Size is zero, or Control is
+                          FW_CFG_DMA_CTL_SKIP.
+
+  @param[in]     Control  One of the following:
+                          FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
+                          FW_CFG_DMA_CTL_READ  - read from fw_cfg into Buffer.
+                          FW_CFG_DMA_CTL_SKIP  - skip bytes in fw_cfg.
 **/
 VOID
 InternalQemuFwCfgDmaBytes (
   IN     UINT32   Size,
   IN OUT VOID     *Buffer OPTIONAL,
-  IN     BOOLEAN  Write
+  IN     UINT32   Control
   )
 {
   volatile FW_CFG_DMA_ACCESS Access;
   UINT32                     AccessHigh, AccessLow;
   UINT32                     Status;
 
+  ASSERT (Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||
+    Control == FW_CFG_DMA_CTL_SKIP);
+
   if (Size == 0) {
     return;
   }
 
-  Access.Control = SwapBytes32 (
-                    Write ? FW_CFG_DMA_CTL_WRITE : FW_CFG_DMA_CTL_READ
-                    );
+  Access.Control = SwapBytes32 (Control);
   Access.Length  = SwapBytes32 (Size);
   Access.Address = SwapBytes64 ((UINTN)Buffer);
 
@@ -125,7 +132,7 @@ InternalQemuFwCfgReadBytes (
   )
 {
   if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
-    InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FALSE);
+    InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ);
     return;
   }
   IoReadFifo8 (0x511, Size, Buffer);
@@ -177,7 +184,7 @@ QemuFwCfgWriteBytes (
 {
   if (InternalQemuFwCfgIsAvailable ()) {
     if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
-      InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, TRUE);
+      InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRITE);
       return;
     }
     IoWriteFifo8 (0x511, Size, Buffer);
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/5] OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes()
  2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 1/5] OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP op Laszlo Ersek
@ 2017-01-27 11:29 ` Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 3/5] ArmVirtPkg/QemuFwCfgLib: extract generic DmaTransferBytes() function Laszlo Ersek
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Laszlo Ersek @ 2017-01-27 11:29 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

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>
---
 OvmfPkg/Include/Library/QemuFwCfgLib.h      | 16 +++++++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 44 ++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/OvmfPkg/Include/Library/QemuFwCfgLib.h b/OvmfPkg/Include/Library/QemuFwCfgLib.h
index 3e017d53a97e..41c3817470a2 100644
--- a/OvmfPkg/Include/Library/QemuFwCfgLib.h
+++ b/OvmfPkg/Include/Library/QemuFwCfgLib.h
@@ -159,6 +159,22 @@ QemuFwCfgWriteBytes (
 
 
 /**
+  Skip bytes in the firmware configuration item.
+
+  Increase the offset of the firmware configuration item without transferring
+  bytes between the item and a caller-provided buffer. Subsequent read, write
+  or skip operations will commence at the increased offset.
+
+  @param[in] Size  Number of bytes to skip.
+**/
+VOID
+EFIAPI
+QemuFwCfgSkipBytes (
+  IN UINTN                  Size
+  );
+
+
+/**
   Reads a UINT8 firmware configuration value
 
   @return    Value of Firmware Configuration item read
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 6b6b2c7726e1..7744873217fe 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -193,6 +193,50 @@ QemuFwCfgWriteBytes (
 
 
 /**
+  Skip bytes in the firmware configuration item.
+
+  Increase the offset of the firmware configuration item without transferring
+  bytes between the item and a caller-provided buffer. Subsequent read, write
+  or skip operations will commence at the increased offset.
+
+  @param[in] Size  Number of bytes to skip.
+**/
+VOID
+EFIAPI
+QemuFwCfgSkipBytes (
+  IN UINTN                  Size
+  )
+{
+  UINTN ChunkSize;
+  UINT8 SkipBuffer[256];
+
+  if (!InternalQemuFwCfgIsAvailable ()) {
+    return;
+  }
+
+  if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
+    InternalQemuFwCfgDmaBytes ((UINT32)Size, NULL, FW_CFG_DMA_CTL_SKIP);
+    return;
+  }
+
+  //
+  // Emulate the skip by reading data in chunks, and throwing it away. The
+  // implementation below is suitable even for phases where RAM or dynamic
+  // allocation is not available or appropriate. It also doesn't affect the
+  // static data footprint for client modules. Large skips are not expected,
+  // therefore this fallback is not performance critical. The size of
+  // SkipBuffer is thought not to exert a large pressure on the stack in any
+  // phase.
+  //
+  while (Size > 0) {
+    ChunkSize = MIN (Size, sizeof SkipBuffer);
+    IoReadFifo8 (0x511, ChunkSize, SkipBuffer);
+    Size -= ChunkSize;
+  }
+}
+
+
+/**
   Reads a UINT8 firmware configuration value
 
   @return    Value of Firmware Configuration item read
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/5] ArmVirtPkg/QemuFwCfgLib: extract generic DmaTransferBytes() function
  2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 1/5] OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP op Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 2/5] OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes() Laszlo Ersek
@ 2017-01-27 11:29 ` Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 4/5] ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if available Laszlo Ersek
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Laszlo Ersek @ 2017-01-27 11:29 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Ard Biesheuvel

The DmaReadBytes() function that we currently use only for reading --
through the InternalQemuFwCfgReadBytes function pointer, in case the DMA
interface is available -- is suitable with minimal changes for two more
operations provided by the DMA interface, WRITE and SKIP. Expose the
Control parameter in the function prototype, rename the function to
DmaTransferBytes(), and rebase DmaReadBytes() to it.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
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>
---
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 42 +++++++++++++++++---
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 1b19893709fc..bd0f34720eec 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -250,26 +250,41 @@ MmioReadBytes (
 
 
 /**
-  Fast READ_BYTES_FUNCTION.
+  Transfer an array of bytes, or skip a number of bytes, using the DMA
+  interface.
+
+  @param[in]     Size     Size in bytes to transfer or skip.
+
+  @param[in,out] Buffer   Buffer to read data into or write data from. Ignored,
+                          and may be NULL, if Size is zero, or Control is
+                          FW_CFG_DMA_CTL_SKIP.
+
+  @param[in]     Control  One of the following:
+                          FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
+                          FW_CFG_DMA_CTL_READ  - read from fw_cfg into Buffer.
+                          FW_CFG_DMA_CTL_SKIP  - skip bytes in fw_cfg.
 **/
 STATIC
 VOID
-EFIAPI
-DmaReadBytes (
-  IN UINTN Size,
-  IN VOID  *Buffer OPTIONAL
+DmaTransferBytes (
+  IN     UINTN  Size,
+  IN OUT VOID   *Buffer OPTIONAL,
+  IN     UINT32 Control
   )
 {
   volatile FW_CFG_DMA_ACCESS Access;
   UINT32                     Status;
 
+  ASSERT (Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||
+    Control == FW_CFG_DMA_CTL_SKIP);
+
   if (Size == 0) {
     return;
   }
 
   ASSERT (Size <= MAX_UINT32);
 
-  Access.Control = SwapBytes32 (FW_CFG_DMA_CTL_READ);
+  Access.Control = SwapBytes32 (Control);
   Access.Length  = SwapBytes32 ((UINT32)Size);
   Access.Address = SwapBytes64 ((UINT64)(UINTN)Buffer);
 
@@ -305,6 +320,21 @@ DmaReadBytes (
 
 
 /**
+  Fast READ_BYTES_FUNCTION.
+**/
+STATIC
+VOID
+EFIAPI
+DmaReadBytes (
+  IN UINTN Size,
+  IN VOID  *Buffer OPTIONAL
+  )
+{
+  DmaTransferBytes (Size, Buffer, FW_CFG_DMA_CTL_READ);
+}
+
+
+/**
   Reads firmware configuration bytes into a buffer
 
   If called multiple times, then the data read will continue at the offset of
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/5] ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if available
  2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
                   ` (2 preceding siblings ...)
  2017-01-27 11:29 ` [PATCH 3/5] ArmVirtPkg/QemuFwCfgLib: extract generic DmaTransferBytes() function Laszlo Ersek
@ 2017-01-27 11:29 ` Laszlo Ersek
  2017-01-27 11:29 ` [PATCH 5/5] ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API Laszlo Ersek
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Laszlo Ersek @ 2017-01-27 11:29 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Ard Biesheuvel

We use the "InternalQemuFwCfgReadBytes" static function pointer to
dispatch the reading of fw_cfg bytes between MMIO and DMA. This pointer is
initialized to MMIO, and we set it to DMA in the library constructor if
DMA is available.

Unlike the above, we write fw_cfg bytes only with MMIO at the moment.
Extend the write functionality so that it follows the read pattern:
- introduce the new function typedef WRITE_BYTES_FUNCTION,
- extract the current (MMIO-only) write internals from
  QemuFwCfgWriteBytes() to MmioWriteBytes(),
- provide a DMA-based implementation in DmaWriteBytes() -- a thin wrapper
  around DmaTransferBytes(),
- set the new static function pointer "InternalQemuFwCfgWriteBytes"
  according to the DMA feature provided by QEMU,
- In QemuFwCfgWriteBytes(), call the best available method through
  "InternalQemuFwCfgWriteBytes".

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
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>
---
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 60 ++++++++++++++++++--
 1 file changed, 54 insertions(+), 6 deletions(-)

diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index bd0f34720eec..56db908f5c91 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -42,16 +42,32 @@ VOID (EFIAPI READ_BYTES_FUNCTION) (
   IN VOID  *Buffer OPTIONAL
   );
 
+/**
+  Writes bytes from a buffer to firmware configuration
+
+  @param[in] Size    Size in bytes to write
+  @param[in] Buffer  Buffer to transfer data from (OPTIONAL if Size is 0)
+
+**/
+typedef
+VOID (EFIAPI WRITE_BYTES_FUNCTION) (
+  IN UINTN Size,
+  IN VOID  *Buffer OPTIONAL
+  );
+
 //
 // Forward declaration of the two implementations we have.
 //
 STATIC READ_BYTES_FUNCTION MmioReadBytes;
+STATIC WRITE_BYTES_FUNCTION MmioWriteBytes;
 STATIC READ_BYTES_FUNCTION DmaReadBytes;
+STATIC WRITE_BYTES_FUNCTION DmaWriteBytes;
 
 //
-// This points to the one we detect at runtime.
+// These correspond to the implementation we detect at runtime.
 //
 STATIC READ_BYTES_FUNCTION *InternalQemuFwCfgReadBytes = MmioReadBytes;
+STATIC WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes;
 
 
 /**
@@ -166,6 +182,7 @@ QemuFwCfgInitialize (
         if ((Features & FW_CFG_F_DMA) != 0) {
           mFwCfgDmaAddress = FwCfgDmaAddress;
           InternalQemuFwCfgReadBytes = DmaReadBytes;
+          InternalQemuFwCfgWriteBytes = DmaWriteBytes;
         }
       }
     } else {
@@ -358,6 +375,41 @@ QemuFwCfgReadBytes (
   }
 }
 
+
+/**
+  Slow WRITE_BYTES_FUNCTION.
+**/
+STATIC
+VOID
+EFIAPI
+MmioWriteBytes (
+  IN UINTN Size,
+  IN VOID  *Buffer OPTIONAL
+  )
+{
+  UINTN Idx;
+
+  for (Idx = 0; Idx < Size; ++Idx) {
+    MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]);
+  }
+}
+
+
+/**
+  Fast WRITE_BYTES_FUNCTION.
+**/
+STATIC
+VOID
+EFIAPI
+DmaWriteBytes (
+  IN UINTN Size,
+  IN VOID  *Buffer OPTIONAL
+  )
+{
+  DmaTransferBytes (Size, Buffer, FW_CFG_DMA_CTL_WRITE);
+}
+
+
 /**
   Write firmware configuration bytes from a buffer
 
@@ -376,11 +428,7 @@ QemuFwCfgWriteBytes (
   )
 {
   if (QemuFwCfgIsAvailable ()) {
-    UINTN Idx;
-
-    for (Idx = 0; Idx < Size; ++Idx) {
-      MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]);
-    }
+    InternalQemuFwCfgWriteBytes (Size, Buffer);
   }
 }
 
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/5] ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API
  2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
                   ` (3 preceding siblings ...)
  2017-01-27 11:29 ` [PATCH 4/5] ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if available Laszlo Ersek
@ 2017-01-27 11:29 ` Laszlo Ersek
  2017-01-27 18:25 ` [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Ard Biesheuvel
  2017-01-30 23:07 ` Jordan Justen
  6 siblings, 0 replies; 9+ messages in thread
From: Laszlo Ersek @ 2017-01-27 11:29 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Ard Biesheuvel

We are now sufficiently equipped to implement the new QemuFwCfgSkipBytes()
API.

The previous patch and this one enable ArmVirtPkg/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: Ard Biesheuvel <ard.biesheuvel@linaro.org>
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>
---
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 78 ++++++++++++++++++++
 1 file changed, 78 insertions(+)

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



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files
  2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
                   ` (4 preceding siblings ...)
  2017-01-27 11:29 ` [PATCH 5/5] ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API Laszlo Ersek
@ 2017-01-27 18:25 ` Ard Biesheuvel
  2017-01-30 23:07 ` Jordan Justen
  6 siblings, 0 replies; 9+ messages in thread
From: Ard Biesheuvel @ 2017-01-27 18:25 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel-01, Jordan Justen

On 27 January 2017 at 11:29, Laszlo Ersek <lersek@redhat.com> wrote:
> This feature will allow OvmfPkg/AcpiPlatformDxe to implement the
> QEMU_LOADER_WRITE_POINTER command, which will instruct the firmware to
> write the address of a previously allocated/downloaded fw_cfg blob into
> another (writeable) fw_cfg file at a specific offset, in order to inform
> QEMU about the allocation address. The command will be based on the
> QemuFwCfgSkipBytes() and QemuFwCfgWriteBytes() APIs.
>
> Ref:    https://bugzilla.tianocore.org/show_bug.cgi?id=359
> Repo:   https://github.com/lersek/edk2.git
> Branch: fwcfg_skip
>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
>

Looks fine to me, although you're the expert here

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files
  2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
                   ` (5 preceding siblings ...)
  2017-01-27 18:25 ` [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Ard Biesheuvel
@ 2017-01-30 23:07 ` Jordan Justen
  2017-01-30 23:18   ` Laszlo Ersek
  6 siblings, 1 reply; 9+ messages in thread
From: Jordan Justen @ 2017-01-30 23:07 UTC (permalink / raw)
  To: Laszlo Ersek, edk2-devel-01; +Cc: Ard Biesheuvel

Series Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

On 2017-01-27 03:29:37, Laszlo Ersek wrote:
> This feature will allow OvmfPkg/AcpiPlatformDxe to implement the
> QEMU_LOADER_WRITE_POINTER command, which will instruct the firmware to
> write the address of a previously allocated/downloaded fw_cfg blob into
> another (writeable) fw_cfg file at a specific offset, in order to inform
> QEMU about the allocation address. The command will be based on the
> QemuFwCfgSkipBytes() and QemuFwCfgWriteBytes() APIs.
> 
> Ref:    https://bugzilla.tianocore.org/show_bug.cgi?id=359
> Repo:   https://github.com/lersek/edk2.git
> Branch: fwcfg_skip
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> 
> Thanks,
> Laszlo
> 
> Laszlo Ersek (5):
>   OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP
>     op
>   OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes()
>   ArmVirtPkg/QemuFwCfgLib: extract generic DmaTransferBytes() function
>   ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if
>     available
>   ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API
> 
>  OvmfPkg/Include/Library/QemuFwCfgLib.h         |  16 ++
>  ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 178 ++++++++++++++++++--
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c    |  75 +++++++--
>  3 files changed, 246 insertions(+), 23 deletions(-)
> 
> -- 
> 2.9.3
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files
  2017-01-30 23:07 ` Jordan Justen
@ 2017-01-30 23:18   ` Laszlo Ersek
  0 siblings, 0 replies; 9+ messages in thread
From: Laszlo Ersek @ 2017-01-30 23:18 UTC (permalink / raw)
  To: Jordan Justen, Ard Biesheuvel; +Cc: edk2-devel-01

On 01/31/17 00:07, Jordan Justen wrote:
> Series Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

Thank you both for the reviews; commit range: 465663e9f128..7fcb73541299.

Laszlo

> On 2017-01-27 03:29:37, Laszlo Ersek wrote:
>> This feature will allow OvmfPkg/AcpiPlatformDxe to implement the
>> QEMU_LOADER_WRITE_POINTER command, which will instruct the firmware to
>> write the address of a previously allocated/downloaded fw_cfg blob into
>> another (writeable) fw_cfg file at a specific offset, in order to inform
>> QEMU about the allocation address. The command will be based on the
>> QemuFwCfgSkipBytes() and QemuFwCfgWriteBytes() APIs.
>>
>> Ref:    https://bugzilla.tianocore.org/show_bug.cgi?id=359
>> Repo:   https://github.com/lersek/edk2.git
>> Branch: fwcfg_skip
>>
>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>
>> Thanks,
>> Laszlo
>>
>> Laszlo Ersek (5):
>>   OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP
>>     op
>>   OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes()
>>   ArmVirtPkg/QemuFwCfgLib: extract generic DmaTransferBytes() function
>>   ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if
>>     available
>>   ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API
>>
>>  OvmfPkg/Include/Library/QemuFwCfgLib.h         |  16 ++
>>  ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 178 ++++++++++++++++++--
>>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c    |  75 +++++++--
>>  3 files changed, 246 insertions(+), 23 deletions(-)
>>
>> -- 
>> 2.9.3
>>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-01-30 23:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-27 11:29 [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Laszlo Ersek
2017-01-27 11:29 ` [PATCH 1/5] OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP op Laszlo Ersek
2017-01-27 11:29 ` [PATCH 2/5] OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes() Laszlo Ersek
2017-01-27 11:29 ` [PATCH 3/5] ArmVirtPkg/QemuFwCfgLib: extract generic DmaTransferBytes() function Laszlo Ersek
2017-01-27 11:29 ` [PATCH 4/5] ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if available Laszlo Ersek
2017-01-27 11:29 ` [PATCH 5/5] ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API Laszlo Ersek
2017-01-27 18:25 ` [PATCH 0/5] OvmfPkg, ArmVirtPkg: QemuFwCfgLib: partial rewrite of fw_cfg files Ard Biesheuvel
2017-01-30 23:07 ` Jordan Justen
2017-01-30 23:18   ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox