diff mbox

[2/5] fw_cfg DMA interface documentation

Message ID 1438858878-29450-3-git-send-email-markmb@redhat.com
State New
Headers show

Commit Message

Marc Marí Aug. 6, 2015, 11:01 a.m. UTC
Add fw_cfg DMA interface specification in the documentation.

Based on Gerd Hoffman's initial implementation.

Signed-off-by: Marc Marí <markmb@redhat.com>
---
 docs/specs/fw_cfg.txt | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

Comments

Kevin O'Connor Aug. 6, 2015, 2:20 p.m. UTC | #1
On Thu, Aug 06, 2015 at 01:01:15PM +0200, Marc Marí wrote:
> Add fw_cfg DMA interface specification in the documentation.
> 
> Based on Gerd Hoffman's initial implementation.
> 
> Signed-off-by: Marc Marí <markmb@redhat.com>
> ---
>  docs/specs/fw_cfg.txt | 42 ++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
> index 5bc7b96..dc8051e 100644
> --- a/docs/specs/fw_cfg.txt
> +++ b/docs/specs/fw_cfg.txt
> @@ -76,6 +76,7 @@ increasing address order, similar to memcpy().
>  
>  Selector Register IOport: 0x510
>  Data Register IOport:     0x511
> +DMA Address IOport:       0x512
>  
>  == Firmware Configuration Items ==
>  
> @@ -89,8 +90,9 @@ present, the four bytes read will contain the characters "QEMU".
>  === Revision (Key 0x0001, FW_CFG_ID) ===
>  
>  A 32-bit little-endian unsigned int, this item is used as an interface
> -revision number, and is currently set to 1 by QEMU when fw_cfg is
> -initialized.
> +revision number. If it is set to 1, the interface is the traditional
> +selector / data interface. If it is set to 2, the DMA extension is
> +also present.
>  
>  === File Directory (Key 0x0019, FW_CFG_FILE_DIR) ===
>  
> @@ -132,6 +134,42 @@ Selector Reg.    Range Usage
>  In practice, the number of allowed firmware configuration items is given
>  by the value of FW_CFG_MAX_ENTRY (see fw_cfg.h).
>  
> += Guest-side DMA Interface =
> +
> +For revision value 2, the DMA interface is present. This does not replace
> +the existing fw_cfg interface, it is an add-on.
> +
> +When this interface is enabled the DMA Address register can be used to
> +write the address of a FWCfgDmaAccess structure:
> +
> +typedef struct FWCfgDmaAccess {
> +    uint64_t address;
> +    uint32_t length;
> +    uint32_t control;
> +} FWCfgDmaAccess;
> +
> +If "control" has the bit 1 set (FW_CFG_DMA_CTL_READ), a read operation is
> +performed on the selected entry. "length" bytes of data in that fw_cfg
> +entry are copied to the address specified by "address".
> +
> +If the field "address" has value 0, the read is considered a skip, and
> +the data is not copied anywhere, but the offset is still incremented.

Thanks!

I have a few suggestions on the interface:

- I think it would be better to place the 'control' field first (ie,
  control/length/address instead of address/length/control).  Placing
  the 'control' field first makes potential future extensions easier -
  that is, it would make it easier for future control bits to change
  the layout of the struct.

- It would be good to add a 'select' field to the struct.  I think
  this could be done by using a 'u16 control; u16 select' instead of
  the current 'u32 control'.  It's common for guests to select a
  fw_cfg entry and read its entire contents - with the 'select' field
  in the struct this could be done with a single guest/host fault.  A
  new control bit could be added (eg, FW_CFG_DMA_CTL_SELECT) to
  determine whether or not the select field is used - iff the bit is
  set then the given fw_cfg entry is selected and the read position is
  reset to the start prior to the DMA data copy.

- Instead of using address==0 to check for skip, I think a new control
  bit would be a little more friendly.  That is, one could add a new
  control bit FW_CFG_DMA_CTL_COPY, and iff it is set then do the DMA
  style copy to the 'address' field.  If it is not set, then 'address'
  is ignored and effectively the read position is just incremented.

-Kevin
Marc Marí Aug. 7, 2015, 8:12 a.m. UTC | #2
On Thu, 6 Aug 2015 10:20:38 -0400
"Kevin O'Connor" <kevin@koconnor.net> wrote:

> On Thu, Aug 06, 2015 at 01:01:15PM +0200, Marc Marí wrote:
> > Add fw_cfg DMA interface specification in the documentation.
> > 
> > Based on Gerd Hoffman's initial implementation.
> > 
> > Signed-off-by: Marc Marí <markmb@redhat.com>
> > ---
> >  docs/specs/fw_cfg.txt | 42
> > ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40
> > insertions(+), 2 deletions(-)
> > 
> > diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
> > index 5bc7b96..dc8051e 100644
> > --- a/docs/specs/fw_cfg.txt
> > +++ b/docs/specs/fw_cfg.txt
> > @@ -76,6 +76,7 @@ increasing address order, similar to memcpy().
> >  
> >  Selector Register IOport: 0x510
> >  Data Register IOport:     0x511
> > +DMA Address IOport:       0x512
> >  
> >  == Firmware Configuration Items ==
> >  
> > @@ -89,8 +90,9 @@ present, the four bytes read will contain the
> > characters "QEMU". === Revision (Key 0x0001, FW_CFG_ID) ===
> >  
> >  A 32-bit little-endian unsigned int, this item is used as an
> > interface -revision number, and is currently set to 1 by QEMU when
> > fw_cfg is -initialized.
> > +revision number. If it is set to 1, the interface is the
> > traditional +selector / data interface. If it is set to 2, the DMA
> > extension is +also present.
> >  
> >  === File Directory (Key 0x0019, FW_CFG_FILE_DIR) ===
> >  
> > @@ -132,6 +134,42 @@ Selector Reg.    Range Usage
> >  In practice, the number of allowed firmware configuration items is
> > given by the value of FW_CFG_MAX_ENTRY (see fw_cfg.h).
> >  
> > += Guest-side DMA Interface =
> > +
> > +For revision value 2, the DMA interface is present. This does not
> > replace +the existing fw_cfg interface, it is an add-on.
> > +
> > +When this interface is enabled the DMA Address register can be
> > used to +write the address of a FWCfgDmaAccess structure:
> > +
> > +typedef struct FWCfgDmaAccess {
> > +    uint64_t address;
> > +    uint32_t length;
> > +    uint32_t control;
> > +} FWCfgDmaAccess;
> > +
> > +If "control" has the bit 1 set (FW_CFG_DMA_CTL_READ), a read
> > operation is +performed on the selected entry. "length" bytes of
> > data in that fw_cfg +entry are copied to the address specified by
> > "address". +
> > +If the field "address" has value 0, the read is considered a skip,
> > and +the data is not copied anywhere, but the offset is still
> > incremented.
> 
> Thanks!
> 
> I have a few suggestions on the interface:
> 
> - I think it would be better to place the 'control' field first (ie,
>   control/length/address instead of address/length/control).  Placing
>   the 'control' field first makes potential future extensions easier -
>   that is, it would make it easier for future control bits to change
>   the layout of the struct.
> 
> - It would be good to add a 'select' field to the struct.  I think
>   this could be done by using a 'u16 control; u16 select' instead of
>   the current 'u32 control'.  It's common for guests to select a
>   fw_cfg entry and read its entire contents - with the 'select' field
>   in the struct this could be done with a single guest/host fault.  A
>   new control bit could be added (eg, FW_CFG_DMA_CTL_SELECT) to
>   determine whether or not the select field is used - iff the bit is
>   set then the given fw_cfg entry is selected and the read position is
>   reset to the start prior to the DMA data copy.

(Problems with email, I got this delivered today)

I don't think there's much problem in using the original fw cfg select
field. Adding a new select field will add complexity to the guest (when
use one select field or the other), and the host (how the two select
fields interact with each other). I think this part is good enough as
it is now.

Thanks
Marc
diff mbox

Patch

diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
index 5bc7b96..dc8051e 100644
--- a/docs/specs/fw_cfg.txt
+++ b/docs/specs/fw_cfg.txt
@@ -76,6 +76,7 @@  increasing address order, similar to memcpy().
 
 Selector Register IOport: 0x510
 Data Register IOport:     0x511
+DMA Address IOport:       0x512
 
 == Firmware Configuration Items ==
 
@@ -89,8 +90,9 @@  present, the four bytes read will contain the characters "QEMU".
 === Revision (Key 0x0001, FW_CFG_ID) ===
 
 A 32-bit little-endian unsigned int, this item is used as an interface
-revision number, and is currently set to 1 by QEMU when fw_cfg is
-initialized.
+revision number. If it is set to 1, the interface is the traditional
+selector / data interface. If it is set to 2, the DMA extension is
+also present.
 
 === File Directory (Key 0x0019, FW_CFG_FILE_DIR) ===
 
@@ -132,6 +134,42 @@  Selector Reg.    Range Usage
 In practice, the number of allowed firmware configuration items is given
 by the value of FW_CFG_MAX_ENTRY (see fw_cfg.h).
 
+= Guest-side DMA Interface =
+
+For revision value 2, the DMA interface is present. This does not replace
+the existing fw_cfg interface, it is an add-on.
+
+When this interface is enabled the DMA Address register can be used to
+write the address of a FWCfgDmaAccess structure:
+
+typedef struct FWCfgDmaAccess {
+    uint64_t address;
+    uint32_t length;
+    uint32_t control;
+} FWCfgDmaAccess;
+
+If "control" has the bit 1 set (FW_CFG_DMA_CTL_READ), a read operation is
+performed on the selected entry. "length" bytes of data in that fw_cfg
+entry are copied to the address specified by "address".
+
+If the field "address" has value 0, the read is considered a skip, and
+the data is not copied anywhere, but the offset is still incremented.
+
+To check result, read the control register:
+   error bit set     ->  something went wrong.
+   all bits cleared  ->  transfer finished successfully.
+   otherwise         ->  transfer still in progress (doesn't happen
+                         today due to implementation not being async,
+                         but may in the future).
+
+Target address goes up and transfer length goes down as the transfer
+happens, so after a successful transfer the length register is zero
+and the address register points right after the memory block written.
+
+If a partial transfer happened before an error occured the address and
+length registers indicate how much data has been transfered
+successfully.
+
 = Host-side API =
 
 The following functions are available to the QEMU programmer for adding