]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/PciHotPlugInitDxe: generalize RESOURCE_PADDING composition
authorLaszlo Ersek <lersek@redhat.com>
Thu, 21 Sep 2017 12:33:56 +0000 (14:33 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Tue, 3 Oct 2017 14:07:35 +0000 (16:07 +0200)
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>
OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c
OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf

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