[edk2] [PATCH 5/7] OvmfPkg/PciHotPlugInitDxe: generalize RESOURCE_PADDING composition

Laszlo Ersek posted 7 patches 7 years, 3 months ago
[edk2] [PATCH 5/7] OvmfPkg/PciHotPlugInitDxe: generalize RESOURCE_PADDING composition
Posted by Laszlo Ersek 7 years, 3 months ago
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>
---
 OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf |   1 +
 OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c   | 163 ++++++++++++--------
 2 files changed, 99 insertions(+), 65 deletions(-)

diff --git a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
index ea19206219b7..91729ae1ed04 100644
--- a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+++ b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
@@ -28,8 +28,9 @@ [Packages]
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
 
 [LibraryClasses]
+  BaseMemoryLib
   DebugLib
   DevicePathLib
   MemoryAllocationLib
   UefiBootServicesTableLib
diff --git a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c
index 5c98f806def6..b1b2c5cd8ddc 100644
--- a/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c
+++ b/OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c
@@ -14,8 +14,9 @@
 **/
 
 #include <IndustryStandard/Acpi10.h>
 
+#include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
 #include <Library/DevicePathLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiBootServicesTableLib.h>
@@ -41,83 +42,61 @@ 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
-  },
 
-  //
-  // 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
-  },
+/**
+  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);
 
   //
-  // EndDesc
+  // Fill in the Padding fields that don't vary across resource types.
   //
-  {
-    ACPI_END_TAG_DESCRIPTOR, // Desc
-    0                        // Checksum: to be ignored
+  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
+                           )
+                         );
   }
-};
+
+  //
+  // Fill in the End Tag.
+  //
+  ResourcePadding->EndDesc.Desc = ACPI_END_TAG_DESCRIPTOR;
+}
 
 
 /**
   Returns a list of root Hot Plug Controllers (HPCs) that require
@@ -274,8 +253,13 @@ GetResourcePadding (
   OUT VOID                           **Padding,
   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;
 
@@ -294,9 +278,58 @@ GetResourcePadding (
   if (HpcState == NULL || Padding == NULL || Attributes == NULL) {
     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;
   }
 
-- 
2.14.1.3.gb7cf6e02401b


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel