diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/OvmfPkg/Library/QemuFwCfgLib | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/OvmfPkg/Library/QemuFwCfgLib')
10 files changed, 1507 insertions, 0 deletions
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c new file mode 100644 index 000000000..0182c9235 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c @@ -0,0 +1,453 @@ +/** @file
+
+ Stateful and implicitly initialized fw_cfg library implementation.
+
+ Copyright (C) 2013, Red Hat, Inc.
+ Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+
+#include <Protocol/IoMmu.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemEncryptSevLib.h>
+
+#include "QemuFwCfgLibInternal.h"
+
+STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
+STATIC BOOLEAN mQemuFwCfgDmaSupported;
+
+STATIC EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
+
+/**
+ Returns a boolean indicating if the firmware configuration interface
+ is available or not.
+
+ This function may change fw_cfg state.
+
+ @retval TRUE The interface is available
+ @retval FALSE The interface is not available
+
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ return InternalQemuFwCfgIsAvailable ();
+}
+
+
+RETURN_STATUS
+EFIAPI
+QemuFwCfgInitialize (
+ VOID
+ )
+{
+ UINT32 Signature;
+ UINT32 Revision;
+
+ //
+ // Enable the access routines while probing to see if it is supported.
+ // For probing we always use the IO Port (IoReadFifo8()) access method.
+ //
+ mQemuFwCfgSupported = TRUE;
+ mQemuFwCfgDmaSupported = FALSE;
+
+ QemuFwCfgSelectItem (QemuFwCfgItemSignature);
+ Signature = QemuFwCfgRead32 ();
+ DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature));
+ QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
+ Revision = QemuFwCfgRead32 ();
+ DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision));
+ if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
+ (Revision < 1)
+ ) {
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n"));
+ mQemuFwCfgSupported = FALSE;
+ return RETURN_SUCCESS;
+ }
+
+ if ((Revision & FW_CFG_F_DMA) == 0) {
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n"));
+ } else {
+ mQemuFwCfgDmaSupported = TRUE;
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
+ }
+
+ if (mQemuFwCfgDmaSupported && MemEncryptSevIsEnabled ()) {
+ EFI_STATUS Status;
+
+ //
+ // IoMmuDxe driver must have installed the IOMMU protocol. If we are not
+ // able to locate the protocol then something must have gone wrong.
+ //
+ Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL,
+ (VOID **)&mIoMmuProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "QemuFwCfgSevDma %a:%a Failed to locate IOMMU protocol.\n",
+ gEfiCallerBaseName, __FUNCTION__));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Returns a boolean indicating if the firmware configuration interface is
+ available for library-internal purposes.
+
+ This function never changes fw_cfg state.
+
+ @retval TRUE The interface is available internally.
+ @retval FALSE The interface is not available internally.
+**/
+BOOLEAN
+InternalQemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ return mQemuFwCfgSupported;
+}
+
+/**
+ Returns a boolean indicating whether QEMU provides the DMA-like access method
+ for fw_cfg.
+
+ @retval TRUE The DMA-like access method is available.
+ @retval FALSE The DMA-like access method is unavailable.
+**/
+BOOLEAN
+InternalQemuFwCfgDmaIsAvailable (
+ VOID
+ )
+{
+ return mQemuFwCfgDmaSupported;
+}
+
+/**
+ Function is used for allocating a bi-directional FW_CFG_DMA_ACCESS used
+ between Host and device to exchange the information. The buffer must be free'd
+ using FreeFwCfgDmaAccessBuffer ().
+
+**/
+STATIC
+VOID
+AllocFwCfgDmaAccessBuffer (
+ OUT VOID **Access,
+ OUT VOID **MapInfo
+ )
+{
+ UINTN Size;
+ UINTN NumPages;
+ EFI_STATUS Status;
+ VOID *HostAddress;
+ EFI_PHYSICAL_ADDRESS DmaAddress;
+ VOID *Mapping;
+
+ Size = sizeof (FW_CFG_DMA_ACCESS);
+ NumPages = EFI_SIZE_TO_PAGES (Size);
+
+ //
+ // As per UEFI spec, in order to map a host address with
+ // BusMasterCommonBuffer64, the buffer must be allocated using the IOMMU
+ // AllocateBuffer()
+ //
+ Status = mIoMmuProtocol->AllocateBuffer (
+ mIoMmuProtocol,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ NumPages,
+ &HostAddress,
+ EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to allocate FW_CFG_DMA_ACCESS\n", gEfiCallerBaseName,
+ __FUNCTION__));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ //
+ // Avoid exposing stale data even temporarily: zero the area before mapping
+ // it.
+ //
+ ZeroMem (HostAddress, Size);
+
+ //
+ // Map the host buffer with BusMasterCommonBuffer64
+ //
+ Status = mIoMmuProtocol->Map (
+ mIoMmuProtocol,
+ EdkiiIoMmuOperationBusMasterCommonBuffer64,
+ HostAddress,
+ &Size,
+ &DmaAddress,
+ &Mapping
+ );
+ if (EFI_ERROR (Status)) {
+ mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, HostAddress);
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to Map() FW_CFG_DMA_ACCESS\n", gEfiCallerBaseName,
+ __FUNCTION__));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ if (Size < sizeof (FW_CFG_DMA_ACCESS)) {
+ mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
+ mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, HostAddress);
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to Map() - requested 0x%Lx got 0x%Lx\n", gEfiCallerBaseName,
+ __FUNCTION__, (UINT64)sizeof (FW_CFG_DMA_ACCESS), (UINT64)Size));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ *Access = HostAddress;
+ *MapInfo = Mapping;
+}
+
+/**
+ Function is to used for freeing the Access buffer allocated using
+ AllocFwCfgDmaAccessBuffer()
+
+**/
+STATIC
+VOID
+FreeFwCfgDmaAccessBuffer (
+ IN VOID *Access,
+ IN VOID *Mapping
+ )
+{
+ UINTN NumPages;
+ EFI_STATUS Status;
+
+ NumPages = EFI_SIZE_TO_PAGES (sizeof (FW_CFG_DMA_ACCESS));
+
+ Status = mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to UnMap() Mapping 0x%Lx\n", gEfiCallerBaseName,
+ __FUNCTION__, (UINT64)(UINTN)Mapping));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ Status = mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, Access);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to Free() 0x%Lx\n", gEfiCallerBaseName, __FUNCTION__,
+ (UINT64)(UINTN)Access));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+}
+
+/**
+ Function is used for mapping host address to device address. The buffer must
+ be unmapped with UnmapDmaDataBuffer ().
+
+**/
+STATIC
+VOID
+MapFwCfgDmaDataBuffer (
+ IN BOOLEAN IsWrite,
+ IN VOID *HostAddress,
+ IN UINT32 Size,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **MapInfo
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumberOfBytes;
+ VOID *Mapping;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+
+ NumberOfBytes = Size;
+ Status = mIoMmuProtocol->Map (
+ mIoMmuProtocol,
+ (IsWrite ?
+ EdkiiIoMmuOperationBusMasterRead64 :
+ EdkiiIoMmuOperationBusMasterWrite64),
+ HostAddress,
+ &NumberOfBytes,
+ &PhysicalAddress,
+ &Mapping
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to Map() Address 0x%Lx Size 0x%Lx\n", gEfiCallerBaseName,
+ __FUNCTION__, (UINT64)(UINTN)HostAddress, (UINT64)Size));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ if (NumberOfBytes < Size) {
+ mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to Map() - requested 0x%x got 0x%Lx\n", gEfiCallerBaseName,
+ __FUNCTION__, Size, (UINT64)NumberOfBytes));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ *DeviceAddress = PhysicalAddress;
+ *MapInfo = Mapping;
+}
+
+STATIC
+VOID
+UnmapFwCfgDmaDataBuffer (
+ IN VOID *Mapping
+ )
+{
+ EFI_STATUS Status;
+
+ Status = mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to UnMap() Mapping 0x%Lx\n", gEfiCallerBaseName,
+ __FUNCTION__, (UINT64)(UINTN)Mapping));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+}
+
+/**
+ 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
+InternalQemuFwCfgDmaBytes (
+ IN UINT32 Size,
+ IN OUT VOID *Buffer OPTIONAL,
+ IN UINT32 Control
+ )
+{
+ volatile FW_CFG_DMA_ACCESS LocalAccess;
+ volatile FW_CFG_DMA_ACCESS *Access;
+ UINT32 AccessHigh, AccessLow;
+ UINT32 Status;
+ VOID *AccessMapping, *DataMapping;
+ VOID *DataBuffer;
+
+ ASSERT (Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||
+ Control == FW_CFG_DMA_CTL_SKIP);
+
+ if (Size == 0) {
+ return;
+ }
+
+ Access = &LocalAccess;
+ AccessMapping = NULL;
+ DataMapping = NULL;
+ DataBuffer = Buffer;
+
+ //
+ // When SEV is enabled, map Buffer to DMA address before issuing the DMA
+ // request
+ //
+ if (MemEncryptSevIsEnabled ()) {
+ VOID *AccessBuffer;
+ EFI_PHYSICAL_ADDRESS DataBufferAddress;
+
+ //
+ // Allocate DMA Access buffer
+ //
+ AllocFwCfgDmaAccessBuffer (&AccessBuffer, &AccessMapping);
+
+ Access = AccessBuffer;
+
+ //
+ // Map actual data buffer
+ //
+ if (Control != FW_CFG_DMA_CTL_SKIP) {
+ MapFwCfgDmaDataBuffer (
+ Control == FW_CFG_DMA_CTL_WRITE,
+ Buffer,
+ Size,
+ &DataBufferAddress,
+ &DataMapping
+ );
+
+ DataBuffer = (VOID *) (UINTN) DataBufferAddress;
+ }
+ }
+
+ Access->Control = SwapBytes32 (Control);
+ Access->Length = SwapBytes32 (Size);
+ Access->Address = SwapBytes64 ((UINTN)DataBuffer);
+
+ //
+ // Delimit the transfer from (a) modifications to Access, (b) in case of a
+ // write, from writes to Buffer by the caller.
+ //
+ MemoryFence ();
+
+ //
+ // Start the transfer.
+ //
+ AccessHigh = (UINT32)RShiftU64 ((UINTN)Access, 32);
+ AccessLow = (UINT32)(UINTN)Access;
+ IoWrite32 (FW_CFG_IO_DMA_ADDRESS, SwapBytes32 (AccessHigh));
+ IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));
+
+ //
+ // Don't look at Access.Control before starting the transfer.
+ //
+ MemoryFence ();
+
+ //
+ // Wait for the transfer to complete.
+ //
+ do {
+ Status = SwapBytes32 (Access->Control);
+ ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
+ } while (Status != 0);
+
+ //
+ // After a read, the caller will want to use Buffer.
+ //
+ MemoryFence ();
+
+ //
+ // If Access buffer was dynamically allocated then free it.
+ //
+ if (AccessMapping != NULL) {
+ FreeFwCfgDmaAccessBuffer ((VOID *)Access, AccessMapping);
+ }
+
+ //
+ // If DataBuffer was mapped then unmap it.
+ //
+ if (DataMapping != NULL) {
+ UnmapFwCfgDmaDataBuffer (DataMapping);
+ }
+}
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf new file mode 100644 index 000000000..48899ff12 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf @@ -0,0 +1,51 @@ +## @file
+#
+# Stateful, implicitly initialized fw_cfg library.
+#
+# Copyright (C) 2013, Red Hat, Inc.
+# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuFwCfgDxeLib
+ FILE_GUID = 80474090-55e7-4c28-b25c-9f236ba41f28
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER
+
+ CONSTRUCTOR = QemuFwCfgInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ QemuFwCfgLibInternal.h
+ QemuFwCfgLib.c
+ QemuFwCfgDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ MemoryAllocationLib
+ MemEncryptSevLib
+
+[Protocols]
+ gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
+
+[Depex]
+ gEdkiiIoMmuProtocolGuid OR gIoMmuAbsentProtocolGuid
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c new file mode 100644 index 000000000..4ef78b7a8 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c @@ -0,0 +1,292 @@ +/** @file
+
+ Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (C) 2013, Red Hat, Inc.
+ Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Uefi.h"
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include "QemuFwCfgLibInternal.h"
+
+
+/**
+ Selects a firmware configuration item for reading.
+
+ Following this call, any data read from this item will start from
+ the beginning of the configuration item's data.
+
+ @param[in] QemuFwCfgItem - Firmware Configuration item to read
+
+**/
+VOID
+EFIAPI
+QemuFwCfgSelectItem (
+ IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
+ )
+{
+ DEBUG ((DEBUG_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem));
+ IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)(UINTN) QemuFwCfgItem);
+}
+
+/**
+ 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)
+
+**/
+VOID
+EFIAPI
+InternalQemuFwCfgReadBytes (
+ IN UINTN Size,
+ IN VOID *Buffer OPTIONAL
+ )
+{
+ if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
+ InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ);
+ return;
+ }
+ IoReadFifo8 (FW_CFG_IO_DATA, Size, Buffer);
+}
+
+
+/**
+ Reads firmware configuration bytes into a buffer
+
+ If called multiple times, then the data read will
+ continue at the offset of the firmware configuration
+ item where the previous read ended.
+
+ @param[in] Size - Size in bytes to read
+ @param[in] Buffer - Buffer to store data into
+
+**/
+VOID
+EFIAPI
+QemuFwCfgReadBytes (
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ if (InternalQemuFwCfgIsAvailable ()) {
+ InternalQemuFwCfgReadBytes (Size, Buffer);
+ } else {
+ ZeroMem (Buffer, Size);
+ }
+}
+
+/**
+ Write firmware configuration bytes from a buffer
+
+ If called multiple times, then the data written will
+ continue at the offset of the firmware configuration
+ item where the previous write ended.
+
+ @param[in] Size - Size in bytes to write
+ @param[in] Buffer - Buffer to read data from
+
+**/
+VOID
+EFIAPI
+QemuFwCfgWriteBytes (
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ if (InternalQemuFwCfgIsAvailable ()) {
+ if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
+ InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRITE);
+ return;
+ }
+ IoWriteFifo8 (FW_CFG_IO_DATA, Size, Buffer);
+ }
+}
+
+
+/**
+ 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 (FW_CFG_IO_DATA, ChunkSize, SkipBuffer);
+ Size -= ChunkSize;
+ }
+}
+
+
+/**
+ Reads a UINT8 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT8
+EFIAPI
+QemuFwCfgRead8 (
+ VOID
+ )
+{
+ UINT8 Result;
+
+ QemuFwCfgReadBytes (sizeof (Result), &Result);
+
+ return Result;
+}
+
+
+/**
+ Reads a UINT16 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT16
+EFIAPI
+QemuFwCfgRead16 (
+ VOID
+ )
+{
+ UINT16 Result;
+
+ QemuFwCfgReadBytes (sizeof (Result), &Result);
+
+ return Result;
+}
+
+
+/**
+ Reads a UINT32 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT32
+EFIAPI
+QemuFwCfgRead32 (
+ VOID
+ )
+{
+ UINT32 Result;
+
+ QemuFwCfgReadBytes (sizeof (Result), &Result);
+
+ return Result;
+}
+
+
+/**
+ Reads a UINT64 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT64
+EFIAPI
+QemuFwCfgRead64 (
+ VOID
+ )
+{
+ UINT64 Result;
+
+ QemuFwCfgReadBytes (sizeof (Result), &Result);
+
+ return Result;
+}
+
+
+/**
+ Find the configuration item corresponding to the firmware configuration file.
+
+ @param[in] Name - Name of file to look up.
+ @param[out] Item - Configuration item corresponding to the file, to be passed
+ to QemuFwCfgSelectItem ().
+ @param[out] Size - Number of bytes in the file.
+
+ @return RETURN_SUCCESS If file is found.
+ RETURN_NOT_FOUND If file is not found.
+ RETURN_UNSUPPORTED If firmware configuration is unavailable.
+
+**/
+RETURN_STATUS
+EFIAPI
+QemuFwCfgFindFile (
+ IN CONST CHAR8 *Name,
+ OUT FIRMWARE_CONFIG_ITEM *Item,
+ OUT UINTN *Size
+ )
+{
+ UINT32 Count;
+ UINT32 Idx;
+
+ if (!InternalQemuFwCfgIsAvailable ()) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
+ Count = SwapBytes32 (QemuFwCfgRead32 ());
+
+ for (Idx = 0; Idx < Count; ++Idx) {
+ UINT32 FileSize;
+ UINT16 FileSelect;
+ UINT16 FileReserved;
+ CHAR8 FName[QEMU_FW_CFG_FNAME_SIZE];
+
+ FileSize = QemuFwCfgRead32 ();
+ FileSelect = QemuFwCfgRead16 ();
+ FileReserved = QemuFwCfgRead16 ();
+ (VOID) FileReserved; /* Force a do-nothing reference. */
+ InternalQemuFwCfgReadBytes (sizeof (FName), FName);
+
+ if (AsciiStrCmp (Name, FName) == 0) {
+ *Item = SwapBytes16 (FileSelect);
+ *Size = SwapBytes32 (FileSize);
+ return RETURN_SUCCESS;
+ }
+ }
+
+ return RETURN_NOT_FOUND;
+}
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h new file mode 100644 index 000000000..1fa80686e --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h @@ -0,0 +1,63 @@ +/** @file
+ Internal interfaces specific to the QemuFwCfgLib 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_INTERNAL_H__
+#define __QEMU_FW_CFG_LIB_INTERNAL_H__
+
+/**
+ Returns a boolean indicating if the firmware configuration interface is
+ available for library-internal purposes.
+
+ This function never changes fw_cfg state.
+
+ @retval TRUE The interface is available internally.
+ @retval FALSE The interface is not available internally.
+**/
+BOOLEAN
+InternalQemuFwCfgIsAvailable (
+ VOID
+ );
+
+
+/**
+ Returns a boolean indicating whether QEMU provides the DMA-like access method
+ for fw_cfg.
+
+ @retval TRUE The DMA-like access method is available.
+ @retval FALSE The DMA-like access method is unavailable.
+**/
+BOOLEAN
+InternalQemuFwCfgDmaIsAvailable (
+ VOID
+ );
+
+/**
+ 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
+InternalQemuFwCfgDmaBytes (
+ IN UINT32 Size,
+ IN OUT VOID *Buffer OPTIONAL,
+ IN UINT32 Control
+ );
+
+#endif
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibNull.inf b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibNull.inf new file mode 100644 index 000000000..e5715a643 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibNull.inf @@ -0,0 +1,30 @@ +## @file
+#
+# Null implementation of the fw_cfg library.
+#
+# Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>
+# Copyright (C) 2013, Red Hat, Inc.
+# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuFwCfgLibNull
+ FILE_GUID = B9D1A1F2-01E2-4732-982D-C7F9ED51AC6B
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = QemuFwCfgLib
+
+[Sources]
+ QemuFwCfgNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ DebugLib
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgNull.c b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgNull.c new file mode 100644 index 000000000..edd97db49 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgNull.c @@ -0,0 +1,209 @@ +/** @file
+
+ Null implementation of the fw_cfg library.
+
+ Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>
+ Copyright (C) 2013, Red Hat, Inc.
+ Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+/**
+ Returns a boolean indicating if the firmware configuration interface
+ is available or not.
+
+ This function may change fw_cfg state.
+
+ @retval TRUE The interface is available
+ @retval FALSE The interface is not available
+
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+
+/**
+ Selects a firmware configuration item for reading.
+
+ Following this call, any data read from this item will start from
+ the beginning of the configuration item's data.
+
+ @param[in] QemuFwCfgItem - Firmware Configuration item to read
+
+**/
+VOID
+EFIAPI
+QemuFwCfgSelectItem (
+ IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
+ )
+{
+ ASSERT (FALSE);
+}
+
+
+/**
+ Reads firmware configuration bytes into a buffer
+
+ If called multiple times, then the data read will
+ continue at the offset of the firmware configuration
+ item where the previous read ended.
+
+ @param[in] Size - Size in bytes to read
+ @param[in] Buffer - Buffer to store data into
+
+**/
+VOID
+EFIAPI
+QemuFwCfgReadBytes (
+ IN UINTN Size,
+ IN VOID *Buffer OPTIONAL
+ )
+{
+ ASSERT (FALSE);
+}
+
+
+/**
+ Writes firmware configuration bytes from a buffer
+
+ If called multiple times, then the data written will
+ continue at the offset of the firmware configuration
+ item where the previous write ended.
+
+ @param[in] Size - Size in bytes to write
+ @param[in] Buffer - Buffer to read data from
+
+**/
+VOID
+EFIAPI
+QemuFwCfgWriteBytes (
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ ASSERT (FALSE);
+}
+
+
+/**
+ 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
+ )
+{
+ ASSERT (FALSE);
+}
+
+
+/**
+ Reads a UINT8 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT8
+EFIAPI
+QemuFwCfgRead8 (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+
+/**
+ Reads a UINT16 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT16
+EFIAPI
+QemuFwCfgRead16 (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+
+/**
+ Reads a UINT32 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT32
+EFIAPI
+QemuFwCfgRead32 (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+
+/**
+ Reads a UINT64 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT64
+EFIAPI
+QemuFwCfgRead64 (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+
+/**
+ Find the configuration item corresponding to the firmware configuration file.
+
+ @param[in] Name - Name of file to look up.
+ @param[out] Item - Configuration item corresponding to the file, to be passed
+ to QemuFwCfgSelectItem ().
+ @param[out] Size - Number of bytes in the file.
+
+ @return RETURN_SUCCESS If file is found.
+ RETURN_NOT_FOUND If file is not found.
+ RETURN_UNSUPPORTED If firmware configuration is unavailable.
+
+**/
+RETURN_STATUS
+EFIAPI
+QemuFwCfgFindFile (
+ IN CONST CHAR8 *Name,
+ OUT FIRMWARE_CONFIG_ITEM *Item,
+ OUT UINTN *Size
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
+
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c new file mode 100644 index 000000000..ecabd88fa --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c @@ -0,0 +1,201 @@ +/** @file
+
+ Stateful and implicitly initialized fw_cfg library implementation.
+
+ Copyright (C) 2013, Red Hat, Inc.
+ Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/MemEncryptSevLib.h>
+
+#include "QemuFwCfgLibInternal.h"
+
+STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
+STATIC BOOLEAN mQemuFwCfgDmaSupported;
+
+
+/**
+ Returns a boolean indicating if the firmware configuration interface
+ is available or not.
+
+ This function may change fw_cfg state.
+
+ @retval TRUE The interface is available
+ @retval FALSE The interface is not available
+
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ return InternalQemuFwCfgIsAvailable ();
+}
+
+
+RETURN_STATUS
+EFIAPI
+QemuFwCfgInitialize (
+ VOID
+ )
+{
+ UINT32 Signature;
+ UINT32 Revision;
+
+ //
+ // Enable the access routines while probing to see if it is supported.
+ // For probing we always use the IO Port (IoReadFifo8()) access method.
+ //
+ mQemuFwCfgSupported = TRUE;
+ mQemuFwCfgDmaSupported = FALSE;
+
+ QemuFwCfgSelectItem (QemuFwCfgItemSignature);
+ Signature = QemuFwCfgRead32 ();
+ DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature));
+ QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
+ Revision = QemuFwCfgRead32 ();
+ DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision));
+ if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
+ (Revision < 1)
+ ) {
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n"));
+ mQemuFwCfgSupported = FALSE;
+ return RETURN_SUCCESS;
+ }
+
+ if ((Revision & FW_CFG_F_DMA) == 0) {
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n"));
+ } else {
+ //
+ // If SEV is enabled then we do not support DMA operations in PEI phase.
+ // This is mainly because DMA in SEV guest requires using bounce buffer
+ // (which need to allocate dynamic memory and allocating a PAGE size'd
+ // buffer can be challenge in PEI phase)
+ //
+ if (MemEncryptSevIsEnabled ()) {
+ DEBUG ((DEBUG_INFO, "SEV: QemuFwCfg fallback to IO Port interface.\n"));
+ } else {
+ mQemuFwCfgDmaSupported = TRUE;
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
+ }
+ }
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Returns a boolean indicating if the firmware configuration interface is
+ available for library-internal purposes.
+
+ This function never changes fw_cfg state.
+
+ @retval TRUE The interface is available internally.
+ @retval FALSE The interface is not available internally.
+**/
+BOOLEAN
+InternalQemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ return mQemuFwCfgSupported;
+}
+
+/**
+ Returns a boolean indicating whether QEMU provides the DMA-like access method
+ for fw_cfg.
+
+ @retval TRUE The DMA-like access method is available.
+ @retval FALSE The DMA-like access method is unavailable.
+**/
+BOOLEAN
+InternalQemuFwCfgDmaIsAvailable (
+ VOID
+ )
+{
+ return mQemuFwCfgDmaSupported;
+}
+
+/**
+ 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
+InternalQemuFwCfgDmaBytes (
+ IN UINT32 Size,
+ IN OUT VOID *Buffer OPTIONAL,
+ IN UINT32 Control
+ )
+{
+ volatile FW_CFG_DMA_ACCESS Access;
+ UINT32 AccessHigh, AccessLow;
+ UINT32 Status;
+
+ ASSERT (Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||
+ Control == FW_CFG_DMA_CTL_SKIP);
+
+ if (Size == 0) {
+ return;
+ }
+
+ //
+ // SEV does not support DMA operations in PEI stage, we should
+ // not have reached here.
+ //
+ ASSERT (!MemEncryptSevIsEnabled ());
+
+ Access.Control = SwapBytes32 (Control);
+ Access.Length = SwapBytes32 (Size);
+ Access.Address = SwapBytes64 ((UINTN)Buffer);
+
+ //
+ // Delimit the transfer from (a) modifications to Access, (b) in case of a
+ // write, from writes to Buffer by the caller.
+ //
+ MemoryFence ();
+
+ //
+ // Start the transfer.
+ //
+ AccessHigh = (UINT32)RShiftU64 ((UINTN)&Access, 32);
+ AccessLow = (UINT32)(UINTN)&Access;
+ IoWrite32 (FW_CFG_IO_DMA_ADDRESS, SwapBytes32 (AccessHigh));
+ IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));
+
+ //
+ // Don't look at Access.Control before starting the transfer.
+ //
+ MemoryFence ();
+
+ //
+ // Wait for the transfer to complete.
+ //
+ do {
+ Status = SwapBytes32 (Access.Control);
+ ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
+ } while (Status != 0);
+
+ //
+ // After a read, the caller will want to use Buffer.
+ //
+ MemoryFence ();
+}
+
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf new file mode 100644 index 000000000..9f9af7d03 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf @@ -0,0 +1,45 @@ +## @file
+#
+# Stateful, implicitly initialized fw_cfg library.
+#
+# Copyright (C) 2013, Red Hat, Inc.
+# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuFwCfgPeiLib
+ FILE_GUID = ddd4f5f0-5304-42a8-9efa-d14bf11a3533
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = QemuFwCfgLib|PEIM
+
+ CONSTRUCTOR = QemuFwCfgInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ QemuFwCfgLibInternal.h
+ QemuFwCfgLib.c
+ QemuFwCfgPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ MemoryAllocationLib
+ MemEncryptSevLib
+
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c new file mode 100644 index 000000000..94e8e9218 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c @@ -0,0 +1,121 @@ +/** @file
+
+ Stateless fw_cfg library implementation.
+
+ Clients must call QemuFwCfgIsAvailable() first.
+
+ Copyright (C) 2013, Red Hat, Inc.
+ Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+#include "QemuFwCfgLibInternal.h"
+
+/**
+ Returns a boolean indicating if the firmware configuration interface
+ is available or not.
+
+ This function may change fw_cfg state.
+
+ @retval TRUE The interface is available
+ @retval FALSE The interface is not available
+
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ UINT32 Signature;
+ UINT32 Revision;
+
+ QemuFwCfgSelectItem (QemuFwCfgItemSignature);
+ Signature = QemuFwCfgRead32 ();
+ DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature));
+ QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
+ Revision = QemuFwCfgRead32 ();
+ DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision));
+ if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
+ (Revision < 1)
+ ) {
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n"));
+ return FALSE;
+ }
+
+ DEBUG ((DEBUG_INFO, "QemuFwCfg interface is supported.\n"));
+ return TRUE;
+}
+
+
+/**
+ Returns a boolean indicating if the firmware configuration interface is
+ available for library-internal purposes.
+
+ This function never changes fw_cfg state.
+
+ @retval TRUE The interface is available internally.
+ @retval FALSE The interface is not available internally.
+**/
+BOOLEAN
+InternalQemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ //
+ // We always return TRUE, because the consumer of this library ought to have
+ // called QemuFwCfgIsAvailable before making other calls which would hit this
+ // path.
+ //
+ return TRUE;
+}
+
+/**
+ Returns a boolean indicating whether QEMU provides the DMA-like access method
+ for fw_cfg.
+
+ @retval TRUE The DMA-like access method is available.
+ @retval FALSE The DMA-like access method is unavailable.
+**/
+BOOLEAN
+InternalQemuFwCfgDmaIsAvailable (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+/**
+ 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
+InternalQemuFwCfgDmaBytes (
+ IN UINT32 Size,
+ IN OUT VOID *Buffer OPTIONAL,
+ IN UINT32 Control
+ )
+{
+ //
+ // We should never reach here
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
diff --git a/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf new file mode 100644 index 000000000..d34edd6e6 --- /dev/null +++ b/roms/edk2/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf @@ -0,0 +1,42 @@ +## @file
+#
+# Stateless fw_cfg library that must be queried before use.
+#
+# Copyright (C) 2013, Red Hat, Inc.
+# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuFwCfgSecLib
+ FILE_GUID = 60a910e5-7443-413d-9a30-97e57497cd1b
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = QemuFwCfgLib|SEC
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ QemuFwCfgLibInternal.h
+ QemuFwCfgLib.c
+ QemuFwCfgSec.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ MemoryAllocationLib
+
|