Add fw_cfg DMA interface specification in the documentation. Based on Gerd Hoffman's initial implementation.
Signed-off-by: Marc Marí <mar...@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. + +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 -- 2.4.3