From a980324709b195dfe3f83741a7319cc9dc7a2efd Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 21 Sep 2017 14:33:56 +0200 Subject: 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 Cc: Marcel Apfelbaum Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek Reviewed-by: Jordan Justen --- OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c | 161 ++++++++++++++++----------- OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf | 1 + 2 files changed, 98 insertions(+), 64 deletions(-) (limited to 'OvmfPkg') diff --git a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c index 5c98f806de..b1b2c5cd8d 100644 --- a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c +++ b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -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 = { - // - // MmioPadding - // - { - 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_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 - }, + +/** + 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); // - // IoPadding + // Fill in the Padding fields that don't vary across resource types. // - { - 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 - }, + 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 + ) + ); + } // - // EndDesc + // Fill in the End Tag. // - { - ACPI_END_TAG_DESCRIPTOR, // Desc - 0 // Checksum: to be ignored - } -}; + 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; } diff --git a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf index ea19206219..91729ae1ed 100644 --- a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf +++ b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf @@ -29,6 +29,7 @@ MdePkg/MdePkg.dec [LibraryClasses] + BaseMemoryLib DebugLib DevicePathLib MemoryAllocationLib -- cgit v1.2.3