From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id D69CFAC1221 for ; Thu, 25 Apr 2024 12:58:34 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=BKVLYkOfKN1fmJGq6IXLt1xdl7QZaDCCArxBtZofKic=; c=relaxed/simple; d=groups.io; h=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject:To:Cc:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type; s=20240206; t=1714049913; v=1; b=Ufb9WXmxcnVftamue/jt962z1yFg3VVz5IEYZu59us1Zz4B5/Icct/EGxvG3zfV6HtMqtfCN PaOL93dngtvaPzr6HhdlOUOorMSHD3z2rGJi6vnZNjug1Iiq63Y5uA2fEDSqAEanFziSho90rEm HtTDcjQof3TX0OlvlVcuVniJsCZZ7QPKPEUHXpJo0Xc+wOwT2v7tyRy2gDHrcccNPX3EMmK7VQh cSVW1AaTR00OD51nz8eCE00L0a2FBuOKY27lGRtjz6bpckYdOunH/VonJDRXpdfJ+3duO1iT7WC 579gEWh3T37TuJWmNrRS/HfYyNXu7MxLzPfZYJtJ7cSKA== X-Received: by 127.0.0.2 with SMTP id wnbsYY7687511xysZtKIPiGm; Thu, 25 Apr 2024 05:58:33 -0700 X-Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by mx.groups.io with SMTP id smtpd.web10.16334.1714049912569644997 for ; Thu, 25 Apr 2024 05:58:32 -0700 X-Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id E771361DCD for ; Thu, 25 Apr 2024 12:58:31 +0000 (UTC) X-Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74BA3C2BD11 for ; Thu, 25 Apr 2024 12:58:31 +0000 (UTC) X-Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-516d3a470d5so1113803e87.3 for ; Thu, 25 Apr 2024 05:58:31 -0700 (PDT) X-Gm-Message-State: 3u03C4O5ckQVfYROWrAfoe8tx7686176AA= X-Google-Smtp-Source: AGHT+IH8j8dQnqt1pLxPjnwHnzCK1HZmJgPez2hTb7y1kYp0PK6d9TXUmhaMOzX0g94/EwaIBiuwEGsOQAowV3LerIU= X-Received: by 2002:a05:6512:310d:b0:51a:1f56:f96d with SMTP id n13-20020a056512310d00b0051a1f56f96dmr4801679lfb.51.1714049909728; Thu, 25 Apr 2024 05:58:29 -0700 (PDT) MIME-Version: 1.0 References: <20240425121232.3009016-1-lichao@loongson.cn> <20240425121257.3009757-1-lichao@loongson.cn> In-Reply-To: <20240425121257.3009757-1-lichao@loongson.cn> From: "Ard Biesheuvel" Date: Thu, 25 Apr 2024 14:58:18 +0200 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [edk2-devel] [PATCH v3 1/7] OvmfPkg: Separate QemuFwCfgLibMmio.c into two files To: Chao Li Cc: devel@edk2.groups.io, Ard Biesheuvel , Jiewen Yao , Gerd Hoffmann , Leif Lindholm , Sami Mujawar , Sunil V L , Andrei Warkentin 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: Thu, 25 Apr 2024 05:58:32 -0700 Resent-From: ardb@kernel.org Reply-To: devel@edk2.groups.io,ardb@kernel.org List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Type: text/plain; charset="UTF-8" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=Ufb9WXmx; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=kernel.org (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io On Thu, 25 Apr 2024 at 14:13, Chao Li wrote: > > 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 | 194 +----------------- > .../Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf | 4 +- > .../QemuFwCfgLib/QemuFwCfgLibMmioInternal.h | 179 ++++++++++++++++ > .../Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c | 153 ++++++++++++++ > 4 files changed, 340 insertions(+), 190 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..dc949c8e26 100644 > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c > @@ -1,10 +1,9 @@ > /** @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.
> Please only claim copyright for code that you wrote, not for code that you just moved between files. > SPDX-License-Identifier: BSD-2-Clause-Patent > **/ > @@ -20,63 +19,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 > @@ -97,126 +40,6 @@ QemuFwCfgIsAvailable ( > 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; > -} > - > /** > Selects a firmware configuration item for reading. > > @@ -240,7 +63,6 @@ QemuFwCfgSelectItem ( > /** > Slow READ_BYTES_FUNCTION. > **/ > -STATIC > VOID > EFIAPI > MmioReadBytes ( > @@ -252,7 +74,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,7 +84,7 @@ 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); > Ptr += 8; > @@ -306,7 +128,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,7 +161,7 @@ DmaTransferBytes ( > // > // This will fire off the transfer. > // > - #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) > + #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64) > MmioWrite64 (mFwCfgDmaAddress, SwapBytes64 ((UINT64)&Access)); > #else > MmioWrite32 ((UINT32)(mFwCfgDmaAddress + 4), SwapBytes32 ((UINT32)&Access)); > @@ -365,7 +186,6 @@ DmaTransferBytes ( > /** > Fast READ_BYTES_FUNCTION. > **/ > -STATIC > VOID > EFIAPI > DmaReadBytes ( > @@ -403,7 +223,6 @@ QemuFwCfgReadBytes ( > /** > Slow WRITE_BYTES_FUNCTION. > **/ > -STATIC > VOID > EFIAPI > MmioWriteBytes ( > @@ -421,7 +240,6 @@ MmioWriteBytes ( > /** > Fast WRITE_BYTES_FUNCTION. > **/ > -STATIC > VOID > EFIAPI > DmaWriteBytes ( > @@ -457,7 +275,6 @@ QemuFwCfgWriteBytes ( > /** > Slow SKIP_BYTES_FUNCTION. > **/ > -STATIC > VOID > EFIAPI > MmioSkipBytes ( > @@ -484,7 +301,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..f2596f270e 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 > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h > new file mode 100644 > index 0000000000..d7d645f700 > --- /dev/null > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h > @@ -0,0 +1,179 @@ > +/** @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 > + Copyright (c) 2024 Loongson Technology Corporation Limited. 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_ > + > +extern UINTN mFwCfgSelectorAddress; > +extern UINTN mFwCfgDataAddress; > +extern UINTN mFwCfgDmaAddress; > + These can remain STATIC and live in the DXE version of the library, no? > +/** > + 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..4844a42a36 > --- /dev/null > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c > @@ -0,0 +1,153 @@ > +/** @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" > + > +UINTN mFwCfgSelectorAddress; > +UINTN mFwCfgDataAddress; > +UINTN mFwCfgDmaAddress; > + > +// > +// These correspond to the implementation we detect at runtime. > +// > +READ_BYTES_FUNCTION *InternalQemuFwCfgReadBytes = MmioReadBytes; > +WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes; > +SKIP_BYTES_FUNCTION *InternalQemuFwCfgSkipBytes = MmioSkipBytes; > + These are duplicated later in the PEI version of the library, right? So they can live in the shared .c file > +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; > +} > -- > 2.27.0 > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118299): https://edk2.groups.io/g/devel/message/118299 Mute This Topic: https://groups.io/mt/105728766/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-