OvmfPkg: Add the way of HOBs in QemuFwCfgLibMmio
Added the HOB methods to load and store the QEMU firmware configure address, data address and DMA address, which are not enabled during the DXE stage. Build-tested only (with "ArmVirtQemu.dsc and RiscVVirtQemu.dsc"). BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4755 Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Sami Mujawar <sami.mujawar@arm.com> Cc: Sunil V L <sunilvl@ventanamicro.com> Cc: Andrei Warkentin <andrei.warkentin@intel.com> Signed-off-by: Chao Li <lichao@loongson.cn>
This commit is contained in:
parent
5e31c5666d
commit
748d57d40f
|
@ -3,15 +3,21 @@
|
||||||
Copyright (C) 2013 - 2014, Red Hat, Inc.
|
Copyright (C) 2013 - 2014, Red Hat, Inc.
|
||||||
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
||||||
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <Base.h>
|
||||||
#include <Uefi.h>
|
#include <Uefi.h>
|
||||||
|
|
||||||
|
#include <Pi/PiBootMode.h>
|
||||||
|
#include <Pi/PiHob.h>
|
||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
#include <Library/IoLib.h>
|
#include <Library/IoLib.h>
|
||||||
#include <Library/QemuFwCfgLib.h>
|
#include <Library/QemuFwCfgLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
@ -27,6 +33,50 @@ READ_BYTES_FUNCTION *InternalQemuFwCfgReadBytes = MmioReadBytes;
|
||||||
WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes;
|
WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes;
|
||||||
SKIP_BYTES_FUNCTION *InternalQemuFwCfgSkipBytes = MmioSkipBytes;
|
SKIP_BYTES_FUNCTION *InternalQemuFwCfgSkipBytes = MmioSkipBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Build firmware configure resource HOB.
|
||||||
|
|
||||||
|
@param[in] FwCfgResource A pointer to firmware configure resource.
|
||||||
|
|
||||||
|
@retval VOID
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
QemuBuildFwCfgResourceHob (
|
||||||
|
IN QEMU_FW_CFG_RESOURCE *FwCfgResource
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BuildGuidDataHob (
|
||||||
|
&gQemuFirmwareResourceHobGuid,
|
||||||
|
(VOID *)FwCfgResource,
|
||||||
|
sizeof (QEMU_FW_CFG_RESOURCE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get firmware configure resource in HOB.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval non-NULL The firmware configure resource in HOB.
|
||||||
|
NULL The firmware configure resource not found.
|
||||||
|
**/
|
||||||
|
QEMU_FW_CFG_RESOURCE *
|
||||||
|
QemuGetFwCfgResourceHob (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_HOB_GUID_TYPE *GuidHob;
|
||||||
|
|
||||||
|
GuidHob = NULL;
|
||||||
|
|
||||||
|
GuidHob = GetFirstGuidHob (&gQemuFirmwareResourceHobGuid);
|
||||||
|
if (GuidHob == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (QEMU_FW_CFG_RESOURCE *)GET_GUID_HOB_DATA (GuidHob);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a boolean indicating if the firmware configuration interface
|
Returns a boolean indicating if the firmware configuration interface
|
||||||
is available or not.
|
is available or not.
|
||||||
|
@ -43,7 +93,7 @@ QemuFwCfgIsAvailable (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return (BOOLEAN)(mFwCfgSelectorAddress != 0 && mFwCfgDataAddress != 0);
|
return (BOOLEAN)(QemuGetFwCfgSelectorAddress () != 0 && QemuGetFwCfgDataAddress () != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +112,7 @@ QemuFwCfgSelectItem (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (QemuFwCfgIsAvailable ()) {
|
if (QemuFwCfgIsAvailable ()) {
|
||||||
MmioWrite16 (mFwCfgSelectorAddress, SwapBytes16 ((UINT16)QemuFwCfgItem));
|
MmioWrite16 (QemuGetFwCfgSelectorAddress (), SwapBytes16 ((UINT16)QemuFwCfgItem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,30 +142,30 @@ MmioReadBytes (
|
||||||
|
|
||||||
#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64)
|
#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64)
|
||||||
while (Ptr < End) {
|
while (Ptr < End) {
|
||||||
*(UINT64 *)Ptr = MmioRead64 (mFwCfgDataAddress);
|
*(UINT64 *)Ptr = MmioRead64 (QemuGetFwCfgDataAddress ());
|
||||||
Ptr += 8;
|
Ptr += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Left & 4) {
|
if (Left & 4) {
|
||||||
*(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress);
|
*(UINT32 *)Ptr = MmioRead32 (QemuGetFwCfgDataAddress ());
|
||||||
Ptr += 4;
|
Ptr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
while (Ptr < End) {
|
while (Ptr < End) {
|
||||||
*(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress);
|
*(UINT32 *)Ptr = MmioRead32 (QemuGetFwCfgDataAddress ());
|
||||||
Ptr += 4;
|
Ptr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Left & 2) {
|
if (Left & 2) {
|
||||||
*(UINT16 *)Ptr = MmioRead16 (mFwCfgDataAddress);
|
*(UINT16 *)Ptr = MmioRead16 (QemuGetFwCfgDataAddress ());
|
||||||
Ptr += 2;
|
Ptr += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Left & 1) {
|
if (Left & 1) {
|
||||||
*Ptr = MmioRead8 (mFwCfgDataAddress);
|
*Ptr = MmioRead8 (QemuGetFwCfgDataAddress ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,9 +218,9 @@ DmaTransferBytes (
|
||||||
// This will fire off the transfer.
|
// This will fire off the transfer.
|
||||||
//
|
//
|
||||||
#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64)
|
#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64)
|
||||||
MmioWrite64 (mFwCfgDmaAddress, SwapBytes64 ((UINT64)&Access));
|
MmioWrite64 (QemuGetFwCfgDmaAddress (), SwapBytes64 ((UINT64)&Access));
|
||||||
#else
|
#else
|
||||||
MmioWrite32 ((UINT32)(mFwCfgDmaAddress + 4), SwapBytes32 ((UINT32)&Access));
|
MmioWrite32 ((UINT32)(QemuGetFwCfgDmaAddress () + 4), SwapBytes32 ((UINT32)&Access));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -239,7 +289,7 @@ MmioWriteBytes (
|
||||||
UINTN Idx;
|
UINTN Idx;
|
||||||
|
|
||||||
for (Idx = 0; Idx < Size; ++Idx) {
|
for (Idx = 0; Idx < Size; ++Idx) {
|
||||||
MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]);
|
MmioWrite8 (QemuGetFwCfgDataAddress (), ((UINT8 *)Buffer)[Idx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2013 - 2014, Red Hat, Inc.
|
# Copyright (C) 2013 - 2014, Red Hat, Inc.
|
||||||
# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
|
@ -39,11 +40,15 @@
|
||||||
BaseLib
|
BaseLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
DebugLib
|
DebugLib
|
||||||
|
HobLib
|
||||||
IoLib
|
IoLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gFdtClientProtocolGuid ## CONSUMES
|
gFdtClientProtocolGuid ## CONSUMES
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gQemuFirmwareResourceHobGuid
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gFdtClientProtocolGuid
|
gFdtClientProtocolGuid
|
||||||
|
|
|
@ -12,9 +12,11 @@
|
||||||
#ifndef QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_
|
#ifndef QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_
|
||||||
#define QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_
|
#define QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_
|
||||||
|
|
||||||
extern UINTN mFwCfgSelectorAddress;
|
typedef struct {
|
||||||
extern UINTN mFwCfgDataAddress;
|
UINTN FwCfgSelectorAddress;
|
||||||
extern UINTN mFwCfgDmaAddress;
|
UINTN FwCfgDataAddress;
|
||||||
|
UINTN FwCfgDmaAddress;
|
||||||
|
} QEMU_FW_CFG_RESOURCE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads firmware configuration bytes into a buffer
|
Reads firmware configuration bytes into a buffer
|
||||||
|
@ -90,6 +92,69 @@ VOID (EFIAPI *InternalQemuFwCfgSkipBytes)(
|
||||||
IN UINTN Size
|
IN UINTN Size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Build firmware configure resource HOB.
|
||||||
|
|
||||||
|
@param[in] FwCfgResource A pointer to firmware configure resource.
|
||||||
|
|
||||||
|
@retval NULL
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
QemuBuildFwCfgResourceHob (
|
||||||
|
IN QEMU_FW_CFG_RESOURCE *FwCfgResource
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get firmware configure resource HOB.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval FwCfgResource The firmware configure resouce in HOB.
|
||||||
|
**/
|
||||||
|
QEMU_FW_CFG_RESOURCE *
|
||||||
|
QemuGetFwCfgResourceHob (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
To get firmware configure selector address.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval firmware configure selector address
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
QemuGetFwCfgSelectorAddress (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
To get firmware configure Data address.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval firmware configure data address
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
QemuGetFwCfgDataAddress (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
To get firmware DMA address.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval firmware DMA address
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
QemuGetFwCfgDmaAddress (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Slow READ_BYTES_FUNCTION.
|
Slow READ_BYTES_FUNCTION.
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
Copyright (C) 2013 - 2014, Red Hat, Inc.
|
Copyright (C) 2013 - 2014, Red Hat, Inc.
|
||||||
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
||||||
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
**/
|
**/
|
||||||
|
@ -20,9 +21,57 @@
|
||||||
|
|
||||||
#include "QemuFwCfgLibMmioInternal.h"
|
#include "QemuFwCfgLibMmioInternal.h"
|
||||||
|
|
||||||
UINTN mFwCfgSelectorAddress;
|
STATIC UINTN mFwCfgSelectorAddress;
|
||||||
UINTN mFwCfgDataAddress;
|
STATIC UINTN mFwCfgDataAddress;
|
||||||
UINTN mFwCfgDmaAddress;
|
STATIC UINTN mFwCfgDmaAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
To get firmware configure selector address.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval firmware configure selector address
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
QemuGetFwCfgSelectorAddress (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return mFwCfgSelectorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
To get firmware configure Data address.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval firmware configure data address
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
QemuGetFwCfgDataAddress (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return mFwCfgDataAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
To get firmware DMA address.
|
||||||
|
|
||||||
|
@param VOID
|
||||||
|
|
||||||
|
@retval firmware DMA address
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
QemuGetFwCfgDmaAddress (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return mFwCfgDmaAddress;
|
||||||
|
}
|
||||||
|
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
|
@ -41,6 +90,26 @@ QemuFwCfgInitialize (
|
||||||
UINT64 FwCfgDataSize;
|
UINT64 FwCfgDataSize;
|
||||||
UINT64 FwCfgDmaAddress;
|
UINT64 FwCfgDmaAddress;
|
||||||
UINT64 FwCfgDmaSize;
|
UINT64 FwCfgDmaSize;
|
||||||
|
QEMU_FW_CFG_RESOURCE *FwCfgResource;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check whether the Qemu firmware configure resources HOB has been created,
|
||||||
|
// if so use the resources in the HOB.
|
||||||
|
//
|
||||||
|
FwCfgResource = QemuGetFwCfgResourceHob ();
|
||||||
|
if (FwCfgResource != NULL) {
|
||||||
|
mFwCfgSelectorAddress = FwCfgResource->FwCfgSelectorAddress;
|
||||||
|
mFwCfgDataAddress = FwCfgResource->FwCfgDataAddress;
|
||||||
|
mFwCfgDmaAddress = FwCfgResource->FwCfgDmaAddress;
|
||||||
|
|
||||||
|
if (mFwCfgDmaAddress != 0) {
|
||||||
|
InternalQemuFwCfgReadBytes = DmaReadBytes;
|
||||||
|
InternalQemuFwCfgWriteBytes = DmaWriteBytes;
|
||||||
|
InternalQemuFwCfgSkipBytes = DmaSkipBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
Status = gBS->LocateProtocol (
|
Status = gBS->LocateProtocol (
|
||||||
&gFdtClientProtocolGuid,
|
&gFdtClientProtocolGuid,
|
||||||
|
|
Loading…
Reference in New Issue