From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 1589F81FBE for ; Fri, 27 Jan 2017 03:29:50 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A681C80491; Fri, 27 Jan 2017 11:29:50 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-16.ams2.redhat.com [10.36.116.16]) by smtp.corp.redhat.com (Postfix) with ESMTP id AD47D20E47F; Fri, 27 Jan 2017 11:29:49 +0000 (UTC) From: Laszlo Ersek To: edk2-devel-01 Cc: Jordan Justen Date: Fri, 27 Jan 2017 12:29:39 +0100 Message-Id: <20170127112942.19212-3-lersek@redhat.com> In-Reply-To: <20170127112942.19212-1-lersek@redhat.com> References: <20170127112942.19212-1-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 27 Jan 2017 11:29:50 +0000 (UTC) Subject: [PATCH 2/5] OvmfPkg/QemuFwCfgLib: add QemuFwCfgSkipBytes() X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Jan 2017 11:29:50 -0000 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 Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=359 Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek --- 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