OvmfPkg/QemuFwCfgLib: generalize InternalQemuFwCfgDmaBytes() to SKIP op

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>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Laszlo Ersek 2017-01-27 05:49:03 +01:00
parent 465663e9f1
commit d055601ea7
1 changed files with 19 additions and 12 deletions

View File

@ -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] Size Size in bytes to transfer or skip.
@param[in,out] Buffer Buffer to read data into or write data from. May be
NULL if Size is zero. @param[in,out] Buffer Buffer to read data into or write data from. Ignored,
@param[in] Write TRUE if writing to fw_cfg from Buffer, FALSE if and may be NULL, if Size is zero, or Control is
reading from fw_cfg into Buffer. 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 VOID
InternalQemuFwCfgDmaBytes ( InternalQemuFwCfgDmaBytes (
IN UINT32 Size, IN UINT32 Size,
IN OUT VOID *Buffer OPTIONAL, IN OUT VOID *Buffer OPTIONAL,
IN BOOLEAN Write IN UINT32 Control
) )
{ {
volatile FW_CFG_DMA_ACCESS Access; volatile FW_CFG_DMA_ACCESS Access;
UINT32 AccessHigh, AccessLow; UINT32 AccessHigh, AccessLow;
UINT32 Status; UINT32 Status;
ASSERT (Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||
Control == FW_CFG_DMA_CTL_SKIP);
if (Size == 0) { if (Size == 0) {
return; return;
} }
Access.Control = SwapBytes32 ( Access.Control = SwapBytes32 (Control);
Write ? FW_CFG_DMA_CTL_WRITE : FW_CFG_DMA_CTL_READ
);
Access.Length = SwapBytes32 (Size); Access.Length = SwapBytes32 (Size);
Access.Address = SwapBytes64 ((UINTN)Buffer); Access.Address = SwapBytes64 ((UINTN)Buffer);
@ -125,7 +132,7 @@ InternalQemuFwCfgReadBytes (
) )
{ {
if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) { if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FALSE); InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ);
return; return;
} }
IoReadFifo8 (0x511, Size, Buffer); IoReadFifo8 (0x511, Size, Buffer);
@ -177,7 +184,7 @@ QemuFwCfgWriteBytes (
{ {
if (InternalQemuFwCfgIsAvailable ()) { if (InternalQemuFwCfgIsAvailable ()) {
if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) { if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, TRUE); InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRITE);
return; return;
} }
IoWriteFifo8 (0x511, Size, Buffer); IoWriteFifo8 (0x511, Size, Buffer);