OvmfPkg: move PciEncoding into AcpiPlatformLib
Bhyve supports providing ACPI tables by FwCfg. Therefore, InstallQemuFwCfgTables should be moved to AcpiPlatformLib to reuse the code. As first step, move PciEncoding into AcpiPlatformLib. Signed-off-by: Corvin Köhne <corvink@FreeBSD.org> Acked-by: Peter Grehan <grehan@freebsd.org>
This commit is contained in:
committed by
mergify[bot]
parent
f5d851673d
commit
ea88df6b26
@@ -16,11 +16,18 @@
|
||||
|
||||
[Sources]
|
||||
DxeAcpiPlatformLib.c
|
||||
PciDecoding.c
|
||||
|
||||
[Packages]
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
OvmfPkg/OvmfPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
DebugLib
|
||||
PcdLib
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
|
||||
|
233
OvmfPkg/Library/AcpiPlatformLib/PciDecoding.c
Normal file
233
OvmfPkg/Library/AcpiPlatformLib/PciDecoding.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/** @file
|
||||
Temporarily enable IO and MMIO decoding for all PCI devices while QEMU
|
||||
regenerates the ACPI tables.
|
||||
|
||||
Copyright (C) 2016, Red Hat, Inc.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <Library/AcpiPlatformLib.h>
|
||||
#include <Library/DebugLib.h> // DEBUG()
|
||||
#include <Library/MemoryAllocationLib.h> // AllocatePool()
|
||||
#include <Library/UefiBootServicesTableLib.h> // gBS
|
||||
|
||||
/**
|
||||
Collect all PciIo protocol instances in the system. Save their original
|
||||
attributes, and enable IO and MMIO decoding for each.
|
||||
|
||||
This is a best effort function; it doesn't return status codes. Its
|
||||
caller is supposed to proceed even if this function fails.
|
||||
|
||||
@param[out] OriginalAttributes On output, a dynamically allocated array of
|
||||
ORIGINAL_ATTRIBUTES elements. The array lists
|
||||
the PciIo protocol instances found in the
|
||||
system at the time of the call, plus the
|
||||
original PCI attributes for each.
|
||||
|
||||
Before returning, the function enables IO and
|
||||
MMIO decoding for each PciIo instance it
|
||||
finds.
|
||||
|
||||
On error, or when no such instances are
|
||||
found, OriginalAttributes is set to NULL.
|
||||
|
||||
@param[out] Count On output, the number of elements in
|
||||
OriginalAttributes. On error it is set to
|
||||
zero.
|
||||
**/
|
||||
VOID
|
||||
EnablePciDecoding (
|
||||
OUT ORIGINAL_ATTRIBUTES **OriginalAttributes,
|
||||
OUT UINTN *Count
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN NoHandles;
|
||||
EFI_HANDLE *Handles;
|
||||
ORIGINAL_ATTRIBUTES *OrigAttrs;
|
||||
UINTN Idx;
|
||||
|
||||
*OriginalAttributes = NULL;
|
||||
*Count = 0;
|
||||
|
||||
if (PcdGetBool (PcdPciDisableBusEnumeration)) {
|
||||
//
|
||||
// The platform downloads ACPI tables from QEMU in general, but there are
|
||||
// no root bridges in this execution. We're done.
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
NULL /* SearchKey */,
|
||||
&NoHandles,
|
||||
&Handles
|
||||
);
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
//
|
||||
// No PCI devices were found on either of the root bridges. We're done.
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_WARN,
|
||||
"%a: LocateHandleBuffer(): %r\n",
|
||||
__func__,
|
||||
Status
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
OrigAttrs = AllocatePool (NoHandles * sizeof *OrigAttrs);
|
||||
if (OrigAttrs == NULL) {
|
||||
DEBUG ((
|
||||
DEBUG_WARN,
|
||||
"%a: AllocatePool(): out of resources\n",
|
||||
__func__
|
||||
));
|
||||
goto FreeHandles;
|
||||
}
|
||||
|
||||
for (Idx = 0; Idx < NoHandles; ++Idx) {
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINT64 Attributes;
|
||||
|
||||
//
|
||||
// Look up PciIo on the handle and stash it
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
Handles[Idx],
|
||||
&gEfiPciIoProtocolGuid,
|
||||
(VOID **)&PciIo
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
OrigAttrs[Idx].PciIo = PciIo;
|
||||
|
||||
//
|
||||
// Stash the current attributes
|
||||
//
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationGet,
|
||||
0,
|
||||
&OrigAttrs[Idx].PciAttributes
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_WARN,
|
||||
"%a: EfiPciIoAttributeOperationGet: %r\n",
|
||||
__func__,
|
||||
Status
|
||||
));
|
||||
goto RestoreAttributes;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve supported attributes
|
||||
//
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationSupported,
|
||||
0,
|
||||
&Attributes
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_WARN,
|
||||
"%a: EfiPciIoAttributeOperationSupported: %r\n",
|
||||
__func__,
|
||||
Status
|
||||
));
|
||||
goto RestoreAttributes;
|
||||
}
|
||||
|
||||
//
|
||||
// Enable IO and MMIO decoding
|
||||
//
|
||||
Attributes &= EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY;
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
Attributes,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_WARN,
|
||||
"%a: EfiPciIoAttributeOperationEnable: %r\n",
|
||||
__func__,
|
||||
Status
|
||||
));
|
||||
goto RestoreAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Success
|
||||
//
|
||||
FreePool (Handles);
|
||||
*OriginalAttributes = OrigAttrs;
|
||||
*Count = NoHandles;
|
||||
return;
|
||||
|
||||
RestoreAttributes:
|
||||
while (Idx > 0) {
|
||||
--Idx;
|
||||
OrigAttrs[Idx].PciIo->Attributes (
|
||||
OrigAttrs[Idx].PciIo,
|
||||
EfiPciIoAttributeOperationSet,
|
||||
OrigAttrs[Idx].PciAttributes,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
FreePool (OrigAttrs);
|
||||
|
||||
FreeHandles:
|
||||
FreePool (Handles);
|
||||
}
|
||||
|
||||
/**
|
||||
Restore the original PCI attributes saved with EnablePciDecoding().
|
||||
|
||||
@param[in] OriginalAttributes The array allocated and populated by
|
||||
EnablePciDecoding(). This parameter may be
|
||||
NULL. If OriginalAttributes is NULL, then the
|
||||
function is a no-op; otherwise the PciIo
|
||||
attributes will be restored, and the
|
||||
OriginalAttributes array will be freed.
|
||||
|
||||
@param[in] Count The Count value stored by EnablePciDecoding(),
|
||||
the number of elements in OriginalAttributes.
|
||||
Count may be zero if and only if
|
||||
OriginalAttributes is NULL.
|
||||
**/
|
||||
VOID
|
||||
RestorePciDecoding (
|
||||
IN ORIGINAL_ATTRIBUTES *OriginalAttributes,
|
||||
IN UINTN Count
|
||||
)
|
||||
{
|
||||
UINTN Idx;
|
||||
|
||||
ASSERT ((OriginalAttributes == NULL) == (Count == 0));
|
||||
if (OriginalAttributes == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Idx = 0; Idx < Count; ++Idx) {
|
||||
OriginalAttributes[Idx].PciIo->Attributes (
|
||||
OriginalAttributes[Idx].PciIo,
|
||||
EfiPciIoAttributeOperationSet,
|
||||
OriginalAttributes[Idx].PciAttributes,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
FreePool (OriginalAttributes);
|
||||
}
|
Reference in New Issue
Block a user