From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail04.groups.io (mail04.groups.io [45.79.224.9]) by spool.mail.gandi.net (Postfix) with ESMTPS id 085FF7803DF for ; Wed, 17 Apr 2024 08:13:49 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=NO5AtoTP58UGqOcCAKMYq4tjgA9ZTMYyf5pxNmqcM8k=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1713341628; v=1; b=sTu8NxlExSKNi3a0EBvCY4tGhhhJ6qY8pBDtlQi6Im3hYRHMcx0huRwee6SlZgbd2tlSWqpL 8AlDgxXLIwi54IJSh1rdaudny5XgiS712fbgoQ/xD5VVJ6dJ2CVVmNzksYIP61VaO95/Hk5BCro SCCPYKB5nIlTLXbl2H9ss38n7qC21BBgvBJaKV4zNJbSFZT3YNuXvkGRWfPq/mDUOqrA96D+sx1 GyWZZlbs/HBgHtGvlGsWce0R/MV4yMJ1CFqizUc4QfCOUgxC+4Q0zybIeqq/+Gi47T/rqFdW20q yfq8EeaoqvhCVHqkwWT7cI14Sb5sHvEF4hPCEPshf/lxA== X-Received: by 127.0.0.2 with SMTP id ASG5YY7687511xXZ1nXwX1AE; Wed, 17 Apr 2024 01:13:48 -0700 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.7715.1713341627468341407 for ; Wed, 17 Apr 2024 01:13:48 -0700 X-Received: from loongson.cn (unknown [10.2.9.245]) by gateway (Coremail) with SMTP id _____8AxTbu4hB9mIa8oAA--.11188S3; Wed, 17 Apr 2024 16:13:44 +0800 (CST) X-Received: from code-server.gen (unknown [10.2.9.245]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxmhK2hB9mG899AA--.32816S2; Wed, 17 Apr 2024 16:13:42 +0800 (CST) From: "Chao Li" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Gerd Hoffmann , Leif Lindholm , Sami Mujawar , Sunil V L , Andrei Warkentin Subject: [edk2-devel] [PATCH v1 2/4] OvmfPkg: Separate QemuFwCfgLibMmio.c into two files Date: Wed, 17 Apr 2024 16:13:41 +0800 Message-Id: <20240417081341.3125396-1-lichao@loongson.cn> In-Reply-To: <20240417081256.3125187-1-lichao@loongson.cn> References: <20240417081256.3125187-1-lichao@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxmhK2hB9mG899AA--.32816S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQAKCGYeNusLoQAJsF X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Wed, 17 Apr 2024 01:13:48 -0700 Resent-From: lichao@loongson.cn Reply-To: devel@edk2.groups.io,lichao@loongson.cn List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: FSeOdg5rtuKYzoEksReeXuLhx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=sTu8NxlE; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.9 as permitted sender) smtp.mailfrom=bounce@groups.io Separate QemuFwCfgLibMmio.c into two files named QemuFwCfgLibMmio.c and QemuFwCfgLibMmioDxe.c, added a new header named QemuFwCfgLibMmioInternal.h for MMIO version. Build-tested only (with "ArmVirtQemu.dsc and RiscVVirtQemu.dsc"). BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4755 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Leif Lindholm Cc: Sami Mujawar Cc: Sunil V L Cc: Andrei Warkentin Signed-off-by: Chao Li --- .../Library/QemuFwCfgLib/QemuFwCfgLibMmio.c | 213 ++---------------- .../Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf | 10 +- .../QemuFwCfgLib/QemuFwCfgLibMmioInternal.h | 174 ++++++++++++++ .../Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c | 149 ++++++++++++ 4 files changed, 346 insertions(+), 200 deletions(-) create mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h create mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c index 115a210759..2a07273bed 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c @@ -1,7 +1,5 @@ /** @file - Stateful and implicitly initialized fw_cfg library implementation. - Copyright (C) 2013 - 2014, Red Hat, Inc. Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP
@@ -20,63 +18,7 @@ #include -STATIC UINTN mFwCfgSelectorAddress; -STATIC UINTN mFwCfgDataAddress; -STATIC UINTN mFwCfgDmaAddress; - -/** - Reads firmware configuration bytes into a buffer - - @param[in] Size Size in bytes to read - @param[in] Buffer Buffer to store data into (OPTIONAL if Size is 0) - -**/ -typedef -VOID(EFIAPI READ_BYTES_FUNCTION)( - IN UINTN Size, - 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 - ); - -/** - 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; +#include "QemuFwCfgLibMmioInternal.h" /** Returns a boolean indicating if the firmware configuration interface @@ -94,127 +36,7 @@ QemuFwCfgIsAvailable ( VOID ) { - return (BOOLEAN)(mFwCfgSelectorAddress != 0 && mFwCfgDataAddress != 0); -} - -RETURN_STATUS -EFIAPI -QemuFwCfgInitialize ( - VOID - ) -{ - EFI_STATUS Status; - FDT_CLIENT_PROTOCOL *FdtClient; - CONST UINT64 *Reg; - UINT32 RegSize; - UINTN AddressCells, SizeCells; - UINT64 FwCfgSelectorAddress; - UINT64 FwCfgSelectorSize; - UINT64 FwCfgDataAddress; - UINT64 FwCfgDataSize; - UINT64 FwCfgDmaAddress; - UINT64 FwCfgDmaSize; - - Status = gBS->LocateProtocol ( - &gFdtClientProtocolGuid, - NULL, - (VOID **)&FdtClient - ); - ASSERT_EFI_ERROR (Status); - - Status = FdtClient->FindCompatibleNodeReg ( - FdtClient, - "qemu,fw-cfg-mmio", - (CONST VOID **)&Reg, - &AddressCells, - &SizeCells, - &RegSize - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_WARN, - "%a: No 'qemu,fw-cfg-mmio' compatible DT node found (Status == %r)\n", - __func__, - Status - )); - return EFI_SUCCESS; - } - - ASSERT (AddressCells == 2); - ASSERT (SizeCells == 2); - ASSERT (RegSize == 2 * sizeof (UINT64)); - - FwCfgDataAddress = SwapBytes64 (Reg[0]); - FwCfgDataSize = 8; - FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize; - FwCfgSelectorSize = 2; - - // - // The following ASSERT()s express - // - // Address + Size - 1 <= MAX_UINTN - // - // for both registers, that is, that the last byte in each MMIO range is - // expressible as a MAX_UINTN. The form below is mathematically - // equivalent, and it also prevents any unsigned overflow before the - // comparison. - // - ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1); - ASSERT (FwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1); - - mFwCfgSelectorAddress = FwCfgSelectorAddress; - mFwCfgDataAddress = FwCfgDataAddress; - - DEBUG (( - DEBUG_INFO, - "Found FwCfg @ 0x%Lx/0x%Lx\n", - FwCfgSelectorAddress, - FwCfgDataAddress - )); - - if (SwapBytes64 (Reg[1]) >= 0x18) { - FwCfgDmaAddress = FwCfgDataAddress + 0x10; - FwCfgDmaSize = 0x08; - - // - // See explanation above. - // - ASSERT (FwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1); - - DEBUG ((DEBUG_INFO, "Found FwCfg DMA @ 0x%Lx\n", FwCfgDmaAddress)); - } else { - FwCfgDmaAddress = 0; - } - - if (QemuFwCfgIsAvailable ()) { - UINT32 Signature; - - QemuFwCfgSelectItem (QemuFwCfgItemSignature); - Signature = QemuFwCfgRead32 (); - if (Signature == SIGNATURE_32 ('Q', 'E', 'M', 'U')) { - // - // For DMA support, we require the DTB to advertise the register, and the - // feature bitmap (which we read without DMA) to confirm the feature. - // - if (FwCfgDmaAddress != 0) { - UINT32 Features; - - QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); - Features = QemuFwCfgRead32 (); - if ((Features & FW_CFG_F_DMA) != 0) { - mFwCfgDmaAddress = FwCfgDmaAddress; - InternalQemuFwCfgReadBytes = DmaReadBytes; - InternalQemuFwCfgWriteBytes = DmaWriteBytes; - InternalQemuFwCfgSkipBytes = DmaSkipBytes; - } - } - } else { - mFwCfgSelectorAddress = 0; - mFwCfgDataAddress = 0; - } - } - - return RETURN_SUCCESS; + return (BOOLEAN)(PcdGet64 (PcdFwCfgSelectorAddress) != 0 && PcdGet64 (PcdFwCfgDataAddress) != 0); } /** @@ -233,14 +55,13 @@ QemuFwCfgSelectItem ( ) { if (QemuFwCfgIsAvailable ()) { - MmioWrite16 (mFwCfgSelectorAddress, SwapBytes16 ((UINT16)QemuFwCfgItem)); + MmioWrite16 (PcdGet64 (PcdFwCfgSelectorAddress), SwapBytes16 ((UINT16)QemuFwCfgItem)); } } /** Slow READ_BYTES_FUNCTION. **/ -STATIC VOID EFIAPI MmioReadBytes ( @@ -252,7 +73,7 @@ MmioReadBytes ( UINT8 *Ptr; UINT8 *End; - #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) + #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64) Left = Size & 7; #else Left = Size & 3; @@ -262,32 +83,32 @@ MmioReadBytes ( Ptr = Buffer; End = Ptr + Size; - #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) + #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64) while (Ptr < End) { - *(UINT64 *)Ptr = MmioRead64 (mFwCfgDataAddress); + *(UINT64 *)Ptr = MmioRead64 (PcdGet64 (PcdFwCfgDataAddress)); Ptr += 8; } if (Left & 4) { - *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress); + *(UINT32 *)Ptr = MmioRead32 (PcdGet64 (PcdFwCfgDataAddress)); Ptr += 4; } #else while (Ptr < End) { - *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress); + *(UINT32 *)Ptr = MmioRead32 (PcdGet64 (PcdFwCfgDataAddress)); Ptr += 4; } #endif if (Left & 2) { - *(UINT16 *)Ptr = MmioRead16 (mFwCfgDataAddress); + *(UINT16 *)Ptr = MmioRead16 (PcdGet64 (PcdFwCfgDataAddress)); Ptr += 2; } if (Left & 1) { - *Ptr = MmioRead8 (mFwCfgDataAddress); + *Ptr = MmioRead8 (PcdGet64 (PcdFwCfgDataAddress)); } } @@ -306,7 +127,6 @@ MmioReadBytes ( FW_CFG_DMA_CTL_READ - read from fw_cfg into Buffer. FW_CFG_DMA_CTL_SKIP - skip bytes in fw_cfg. **/ -STATIC VOID DmaTransferBytes ( IN UINTN Size, @@ -340,10 +160,10 @@ DmaTransferBytes ( // // This will fire off the transfer. // - #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) - MmioWrite64 (mFwCfgDmaAddress, SwapBytes64 ((UINT64)&Access)); + #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64) + MmioWrite64 (PcdGet64 (PcdFwCfgDmaAddress), SwapBytes64 ((UINT64)&Access)); #else - MmioWrite32 ((UINT32)(mFwCfgDmaAddress + 4), SwapBytes32 ((UINT32)&Access)); + MmioWrite32 ((UINT32)(PcdGet64 (PcdFwCfgDmaAddress) + 4), SwapBytes32 ((UINT32)&Access)); #endif // @@ -365,7 +185,6 @@ DmaTransferBytes ( /** Fast READ_BYTES_FUNCTION. **/ -STATIC VOID EFIAPI DmaReadBytes ( @@ -403,7 +222,6 @@ QemuFwCfgReadBytes ( /** Slow WRITE_BYTES_FUNCTION. **/ -STATIC VOID EFIAPI MmioWriteBytes ( @@ -414,14 +232,13 @@ MmioWriteBytes ( UINTN Idx; for (Idx = 0; Idx < Size; ++Idx) { - MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]); + MmioWrite8 (PcdGet64 (PcdFwCfgDataAddress), ((UINT8 *)Buffer)[Idx]); } } /** Fast WRITE_BYTES_FUNCTION. **/ -STATIC VOID EFIAPI DmaWriteBytes ( @@ -457,7 +274,6 @@ QemuFwCfgWriteBytes ( /** Slow SKIP_BYTES_FUNCTION. **/ -STATIC VOID EFIAPI MmioSkipBytes ( @@ -484,7 +300,6 @@ MmioSkipBytes ( /** Fast SKIP_BYTES_FUNCTION. **/ -STATIC VOID EFIAPI DmaSkipBytes ( diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf index 4b0dfbcb0d..0e7b488644 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf @@ -4,6 +4,7 @@ # # Copyright (C) 2013 - 2014, Red Hat, Inc. # Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
+# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -23,11 +24,12 @@ [Defines] # The following information is for reference only and not required by the build # tools. # -# VALID_ARCHITECTURES = ARM AARCH64 RISCV64 +# VALID_ARCHITECTURES = ARM AARCH64 RISCV64 LOONGARCH64 # [Sources] QemuFwCfgLibMmio.c + QemuFwCfgMmioDxe.c [Packages] MdePkg/MdePkg.dec @@ -39,10 +41,16 @@ [LibraryClasses] BaseMemoryLib DebugLib IoLib + PcdLib UefiBootServicesTableLib [Protocols] gFdtClientProtocolGuid ## CONSUMES +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdFwCfgSelectorAddress ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdFwCfgDataAddress ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdFwCfgDmaAddress ## CONSUMES + [Depex] gFdtClientProtocolGuid diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h new file mode 100644 index 0000000000..6f637367d8 --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h @@ -0,0 +1,174 @@ +/** @file + Internal interfaces specific to the QemuFwCfgLibMmio instances in OvmfPkg. + + Copyright (C) 2016, Red Hat, Inc. + Copyright (C) 2017, Advanced Micro Devices. All rights reserved + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_ +#define QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_ + +/** + Reads firmware configuration bytes into a buffer + + @param[in] Size Size in bytes to read + @param[in] Buffer Buffer to store data into (OPTIONAL if Size is 0) + +**/ +typedef +VOID(EFIAPI READ_BYTES_FUNCTION)( + IN UINTN Size, + 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 + ); + +/** + Skips bytes in firmware configuration + + @param[in] Size Size in bytes to skip + +**/ +typedef +VOID(EFIAPI SKIP_BYTES_FUNCTION)( + IN UINTN Size + ); + +/** + Reads firmware configuration bytes into a buffer + + @param[in] Size Size in bytes to read + @param[in] Buffer Buffer to store data into (OPTIONAL if Size is 0) + +**/ +extern +VOID +EFIAPI +(*InternalQemuFwCfgReadBytes) ( + IN UINTN Size, + 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) + +**/ +extern +VOID +EFIAPI +(*InternalQemuFwCfgWriteBytes) ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + +/** + Skips bytes in firmware configuration + + @param[in] Size Size in bytes to skip + +**/ +extern +VOID +EFIAPI +(*InternalQemuFwCfgSkipBytes) ( + IN UINTN Size + ); + +/** + Slow READ_BYTES_FUNCTION. +**/ +VOID +EFIAPI +MmioReadBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + +/** + Slow WRITE_BYTES_FUNCTION. +**/ +VOID +EFIAPI +MmioWriteBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + +/** + Slow SKIP_BYTES_FUNCTION. +**/ +VOID +EFIAPI +MmioSkipBytes ( + IN UINTN Size + ); + +/** + Fast READ_BYTES_FUNCTION. +**/ +VOID +EFIAPI +DmaReadBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + +/** + Fast WRITE_BYTES_FUNCTION. +**/ +VOID +EFIAPI +DmaWriteBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + +/** + Fast SKIP_BYTES_FUNCTION. +**/ +VOID +EFIAPI +DmaSkipBytes ( + IN UINTN Size + ); + +/** + Transfer an array of bytes, or skip a number of bytes, using the DMA + interface. + + @param[in] Size Size in bytes to transfer or skip. + + @param[in,out] Buffer Buffer to read data into or write data from. Ignored, + and may be NULL, if Size is zero, or Control is + 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 +DmaTransferBytes ( + IN UINTN Size, + IN OUT VOID *Buffer OPTIONAL, + IN UINT32 Control + ); + +#endif diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c new file mode 100644 index 0000000000..4222695cb5 --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c @@ -0,0 +1,149 @@ +/** @file + + Stateful and implicitly initialized fw_cfg library implementation. + + Copyright (C) 2013 - 2014, Red Hat, Inc. + Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include +#include + +#include + +#include "QemuFwCfgLibMmioInternal.h" + +// +// These correspond to the implementation we detect at runtime. +// +READ_BYTES_FUNCTION *InternalQemuFwCfgReadBytes = MmioReadBytes; +WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes; +SKIP_BYTES_FUNCTION *InternalQemuFwCfgSkipBytes = MmioSkipBytes; + +RETURN_STATUS +EFIAPI +QemuFwCfgInitialize ( + VOID + ) +{ + EFI_STATUS Status; + FDT_CLIENT_PROTOCOL *FdtClient; + CONST UINT64 *Reg; + UINT32 RegSize; + UINTN AddressCells, SizeCells; + UINT64 FwCfgSelectorAddress; + UINT64 FwCfgSelectorSize; + UINT64 FwCfgDataAddress; + UINT64 FwCfgDataSize; + UINT64 FwCfgDmaAddress; + UINT64 FwCfgDmaSize; + + Status = gBS->LocateProtocol ( + &gFdtClientProtocolGuid, + NULL, + (VOID **)&FdtClient + ); + ASSERT_EFI_ERROR (Status); + + Status = FdtClient->FindCompatibleNodeReg ( + FdtClient, + "qemu,fw-cfg-mmio", + (CONST VOID **)&Reg, + &AddressCells, + &SizeCells, + &RegSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_WARN, + "%a: No 'qemu,fw-cfg-mmio' compatible DT node found (Status == %r)\n", + __func__, + Status + )); + return EFI_SUCCESS; + } + + ASSERT (AddressCells == 2); + ASSERT (SizeCells == 2); + ASSERT (RegSize == 2 * sizeof (UINT64)); + + FwCfgDataAddress = SwapBytes64 (Reg[0]); + FwCfgDataSize = 8; + FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize; + FwCfgSelectorSize = 2; + + // + // The following ASSERT()s express + // + // Address + Size - 1 <= MAX_UINTN + // + // for both registers, that is, that the last byte in each MMIO range is + // expressible as a MAX_UINTN. The form below is mathematically + // equivalent, and it also prevents any unsigned overflow before the + // comparison. + // + ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1); + ASSERT (FwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1); + + PcdSet64S (PcdFwCfgSelectorAddress, FwCfgSelectorAddress); + PcdSet64S (PcdFwCfgDataAddress, FwCfgDataAddress); + + DEBUG (( + DEBUG_INFO, + "Found FwCfg @ 0x%Lx/0x%Lx\n", + FwCfgSelectorAddress, + FwCfgDataAddress + )); + + if (SwapBytes64 (Reg[1]) >= 0x18) { + FwCfgDmaAddress = FwCfgDataAddress + 0x10; + FwCfgDmaSize = 0x08; + + // + // See explanation above. + // + ASSERT (FwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1); + + DEBUG ((DEBUG_INFO, "Found FwCfg DMA @ 0x%Lx\n", FwCfgDmaAddress)); + } else { + FwCfgDmaAddress = 0; + } + + if (QemuFwCfgIsAvailable ()) { + UINT32 Signature; + + QemuFwCfgSelectItem (QemuFwCfgItemSignature); + Signature = QemuFwCfgRead32 (); + if (Signature == SIGNATURE_32 ('Q', 'E', 'M', 'U')) { + // + // For DMA support, we require the DTB to advertise the register, and the + // feature bitmap (which we read without DMA) to confirm the feature. + // + if (FwCfgDmaAddress != 0) { + UINT32 Features; + + QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); + Features = QemuFwCfgRead32 (); + if ((Features & FW_CFG_F_DMA) != 0) { + PcdSet64S (PcdFwCfgDmaAddress, FwCfgDmaAddress); + InternalQemuFwCfgReadBytes = DmaReadBytes; + InternalQemuFwCfgWriteBytes = DmaWriteBytes; + InternalQemuFwCfgSkipBytes = DmaSkipBytes; + } + } + } else { + PcdSet64S (PcdFwCfgSelectorAddress, 0x0); + PcdSet64S (PcdFwCfgDataAddress, 0x0); + } + } + + return RETURN_SUCCESS; +} -- 2.27.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117906): https://edk2.groups.io/g/devel/message/117906 Mute This Topic: https://groups.io/mt/105573106/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-