OvmfPkg/PciHotPlugInitDxe: generalize RESOURCE_PADDING composition

PciHotPlugInitDxe has a static variable called "mPadding" (of type
RESOURCE_PADDING), which describes two constant resource reservations:

- MmioPadding: 2MB of non-prefetchable (hence 32-bit) MMIO space,

- IoPadding: 512B of IO space.

In the GetResourcePadding() member function of
EFI_PCI_HOT_PLUG_INIT_PROTOCOL, the driver outputs a dynamically allocated
verbatim copy of "mPadding", for PciBusDxe to consume in its
ApplyResourcePadding() function.

In a later patch, we're going to compose the set of resource reservations
dynamically, based on QEMU hints. Generalize the RESOURCE_PADDING
structure so that we may generate (or not generate) each resource type
individually:

- Replace the named "MmioPadding" and "IoPadding" fields in
  RESOURCE_PADDING with an array of descriptors,

- remove "mPadding",

- in GetResourcePadding(), request the same (default) reservations as
  before, as if we attempted and failed to fetch the QEMU hints.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Laszlo Ersek 2017-09-21 14:33:56 +02:00
parent c18ac9fbcc
commit a980324709
2 changed files with 99 additions and 65 deletions

View File

@ -15,6 +15,7 @@
#include <IndustryStandard/Acpi10.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
@ -42,81 +43,59 @@ STATIC EFI_PCI_HOT_PLUG_INIT_PROTOCOL mPciHotPlugInit;
// This structure is interpreted by the ApplyResourcePadding() function in the
// edk2 PCI Bus UEFI_DRIVER.
//
// We can request padding for at most four resource types, each of which is
// optional, independently of the others:
// (a) bus numbers,
// (b) IO space,
// (c) non-prefetchable MMIO space (32-bit only),
// (d) prefetchable MMIO space (either 32-bit or 64-bit, never both).
//
#pragma pack (1)
typedef struct {
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR MmioPadding;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR IoPadding;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR Padding[4];
EFI_ACPI_END_TAG_DESCRIPTOR EndDesc;
} RESOURCE_PADDING;
#pragma pack ()
STATIC CONST RESOURCE_PADDING mPadding = {
/**
Initialize a RESOURCE_PADDING object.
@param[out] ResourcePadding The caller-allocated RESOURCE_PADDING object to
initialize.
**/
STATIC
VOID
InitializeResourcePadding (
OUT RESOURCE_PADDING *ResourcePadding
)
{
UINTN Index;
ZeroMem (ResourcePadding, sizeof *ResourcePadding);
//
// MmioPadding
// Fill in the Padding fields that don't vary across resource types.
//
{
ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc
(UINT16)( // Len
for (Index = 0; Index < ARRAY_SIZE (ResourcePadding->Padding); ++Index) {
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
Descriptor = ResourcePadding->Padding + Index;
Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Descriptor->Len = (UINT16)(
sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -
OFFSET_OF (
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,
ResType
)
),
ACPI_ADDRESS_SPACE_TYPE_MEM, // ResType
0, // GenFlag:
// ignored
0, // SpecificFlag:
// non-prefetchable
32, // AddrSpaceGranularity:
// reserve 32-bit aperture
0, // AddrRangeMin:
// ignored
SIZE_2MB - 1, // AddrRangeMax:
// align at 2MB
0, // AddrTranslationOffset:
// ignored
SIZE_2MB // AddrLen:
// 2MB padding
},
//
// IoPadding
//
{
ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc
(UINT16)( // Len
sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -
OFFSET_OF (
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,
ResType
)
),
ACPI_ADDRESS_SPACE_TYPE_IO,// ResType
0, // GenFlag:
// ignored
0, // SpecificFlag:
// ignored
0, // AddrSpaceGranularity:
// ignored
0, // AddrRangeMin:
// ignored
512 - 1, // AddrRangeMax:
// align at 512 IO ports
0, // AddrTranslationOffset:
// ignored
512 // AddrLen:
// 512 IO ports
},
//
// EndDesc
//
{
ACPI_END_TAG_DESCRIPTOR, // Desc
0 // Checksum: to be ignored
);
}
};
//
// Fill in the End Tag.
//
ResourcePadding->EndDesc.Desc = ACPI_END_TAG_DESCRIPTOR;
}
/**
@ -275,6 +254,11 @@ GetResourcePadding (
OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes
)
{
BOOLEAN DefaultIo;
BOOLEAN DefaultMmio;
RESOURCE_PADDING ReservationRequest;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FirstResource;
DEBUG_CODE (
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *Address;
CHAR16 *DevicePathString;
@ -295,7 +279,56 @@ GetResourcePadding (
return EFI_INVALID_PARAMETER;
}
*Padding = AllocateCopyPool (sizeof mPadding, &mPadding);
DefaultIo = TRUE;
DefaultMmio = TRUE;
//
// Init ReservationRequest, and point FirstResource one past the last
// descriptor entry. We're going to build the entries backwards from
// ReservationRequest.EndDesc.
//
InitializeResourcePadding (&ReservationRequest);
FirstResource = ReservationRequest.Padding +
ARRAY_SIZE (ReservationRequest.Padding);
//
// (b) Reserve IO space.
//
if (DefaultIo) {
//
// Request defaults.
//
--FirstResource;
FirstResource->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
FirstResource->AddrRangeMax = 512 - 1; // align at 512 IO ports
FirstResource->AddrLen = 512; // 512 IO ports
}
//
// (c) Reserve non-prefetchable MMIO space (32-bit only).
//
if (DefaultMmio) {
//
// Request defaults.
//
--FirstResource;
FirstResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
FirstResource->SpecificFlag = 0; // non-prefetchable
FirstResource->AddrSpaceGranularity = 32; // 32-bit aperture
FirstResource->AddrRangeMax = SIZE_2MB - 1; // align at 2MB
FirstResource->AddrLen = SIZE_2MB; // 2MB padding
}
//
// Output a copy of ReservationRequest from the lowest-address populated
// entry until the end of the structure (including
// ReservationRequest.EndDesc). If no reservations are necessary, we'll only
// output the End Tag.
//
*Padding = AllocateCopyPool (
(UINT8 *)(&ReservationRequest + 1) - (UINT8 *)FirstResource,
FirstResource
);
if (*Padding == NULL) {
return EFI_OUT_OF_RESOURCES;
}

View File

@ -29,6 +29,7 @@
MdePkg/MdePkg.dec
[LibraryClasses]
BaseMemoryLib
DebugLib
DevicePathLib
MemoryAllocationLib