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 CE59E81FC6 for ; Fri, 27 Jan 2017 03:29:52 -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 6B694550B1; Fri, 27 Jan 2017 11:29:53 +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 7356E20E473; Fri, 27 Jan 2017 11:29:52 +0000 (UTC) From: Laszlo Ersek To: edk2-devel-01 Cc: Ard Biesheuvel Date: Fri, 27 Jan 2017 12:29:41 +0100 Message-Id: <20170127112942.19212-5-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.29]); Fri, 27 Jan 2017 11:29:53 +0000 (UTC) Subject: [PATCH 4/5] ArmVirtPkg/QemuFwCfgLib: use DMA for QemuFwCfgWriteBytes() if available 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:52 -0000 We use the "InternalQemuFwCfgReadBytes" static function pointer to dispatch the reading of fw_cfg bytes between MMIO and DMA. This pointer is initialized to MMIO, and we set it to DMA in the library constructor if DMA is available. Unlike the above, we write fw_cfg bytes only with MMIO at the moment. Extend the write functionality so that it follows the read pattern: - introduce the new function typedef WRITE_BYTES_FUNCTION, - extract the current (MMIO-only) write internals from QemuFwCfgWriteBytes() to MmioWriteBytes(), - provide a DMA-based implementation in DmaWriteBytes() -- a thin wrapper around DmaTransferBytes(), - set the new static function pointer "InternalQemuFwCfgWriteBytes" according to the DMA feature provided by QEMU, - In QemuFwCfgWriteBytes(), call the best available method through "InternalQemuFwCfgWriteBytes". 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 | 60 ++++++++++++++++++-- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c index bd0f34720eec..56db908f5c91 100644 --- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c +++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c @@ -42,16 +42,32 @@ VOID (EFIAPI READ_BYTES_FUNCTION) ( IN VOID *Buffer OPTIONAL ); +/** + Writes bytes from a buffer to firmware configuration + + @param[in] Size Size in bytes to write + @param[in] Buffer Buffer to transfer data from (OPTIONAL if Size is 0) + +**/ +typedef +VOID (EFIAPI WRITE_BYTES_FUNCTION) ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + // // Forward declaration of the two implementations we have. // STATIC READ_BYTES_FUNCTION MmioReadBytes; +STATIC WRITE_BYTES_FUNCTION MmioWriteBytes; STATIC READ_BYTES_FUNCTION DmaReadBytes; +STATIC WRITE_BYTES_FUNCTION DmaWriteBytes; // -// This points to the one we detect at runtime. +// These correspond to the implementation we detect at runtime. // STATIC READ_BYTES_FUNCTION *InternalQemuFwCfgReadBytes = MmioReadBytes; +STATIC WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes; /** @@ -166,6 +182,7 @@ QemuFwCfgInitialize ( if ((Features & FW_CFG_F_DMA) != 0) { mFwCfgDmaAddress = FwCfgDmaAddress; InternalQemuFwCfgReadBytes = DmaReadBytes; + InternalQemuFwCfgWriteBytes = DmaWriteBytes; } } } else { @@ -358,6 +375,41 @@ QemuFwCfgReadBytes ( } } + +/** + Slow WRITE_BYTES_FUNCTION. +**/ +STATIC +VOID +EFIAPI +MmioWriteBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ) +{ + UINTN Idx; + + for (Idx = 0; Idx < Size; ++Idx) { + MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]); + } +} + + +/** + Fast WRITE_BYTES_FUNCTION. +**/ +STATIC +VOID +EFIAPI +DmaWriteBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ) +{ + DmaTransferBytes (Size, Buffer, FW_CFG_DMA_CTL_WRITE); +} + + /** Write firmware configuration bytes from a buffer @@ -376,11 +428,7 @@ QemuFwCfgWriteBytes ( ) { if (QemuFwCfgIsAvailable ()) { - UINTN Idx; - - for (Idx = 0; Idx < Size; ++Idx) { - MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]); - } + InternalQemuFwCfgWriteBytes (Size, Buffer); } } -- 2.9.3