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 3FBD781FCC for ; Fri, 27 Jan 2017 03:29:54 -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 D4F7180F9C; Fri, 27 Jan 2017 11:29:54 +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 DD22A2112C0; Fri, 27 Jan 2017 11:29:53 +0000 (UTC) From: Laszlo Ersek To: edk2-devel-01 Cc: Ard Biesheuvel Date: Fri, 27 Jan 2017 12:29:42 +0100 Message-Id: <20170127112942.19212-6-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.27]); Fri, 27 Jan 2017 11:29:54 +0000 (UTC) Subject: [PATCH 5/5] ArmVirtPkg/QemuFwCfgLib: implement QemuFwCfgSkipBytes() API 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:54 -0000 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 Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=359 Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek --- 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