]> git.proxmox.com Git - mirror_edk2.git/commitdiff
DynamicTablesPkg: AcpiSsdtPcieLibArm: Added function to reserve ECAM space
authorKun Qin <kuqin12@gmail.com>
Wed, 20 Jul 2022 17:39:27 +0000 (10:39 -0700)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 1 Sep 2022 10:27:02 +0000 (10:27 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3998

Certain OSes will complain if the ECAM config space is not reserved in
the ACPI namespace.

This change adds a function to reserve PNP motherboard resources for a
given PCI node.

Co-authored-by: Joe Lopez <joelopez@microsoft.com>
Signed-off-by: Kun Qin <kuqin12@gmail.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
Tested-by: Sami Mujawar <sami.mujawar@arm.com>
DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c

index ceffe2838c03fd989101c3adf790e1a2885c3b0b..dd75fc27e60e92919804dc195143aed99d9336bf 100644 (file)
@@ -34,6 +34,9 @@
 \r
 #include "SsdtPcieGenerator.h"\r
 \r
+#define PCI_MAX_DEVICE_COUNT_PER_BUS       32\r
+#define PCI_MAX_FUNCTION_COUNT_PER_DEVICE  8\r
+\r
 /** ARM standard SSDT Pcie Table Generator.\r
 \r
 Requirements:\r
@@ -616,6 +619,130 @@ GeneratePciCrs (
   return Status;\r
 }\r
 \r
+/** Generate a RES0 device node to reserve PNP motherboard resources\r
+  for a given PCI node.\r
+\r
+  @param [in]   PciNode       Parent PCI node handle of the generated\r
+                              resource object.\r
+  @param [out]  CrsNode       CRS node of the AML tree to populate.\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid input parameter.\r
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+GenerateMotherboardDevice (\r
+  IN  AML_OBJECT_NODE_HANDLE  PciNode,\r
+  OUT AML_OBJECT_NODE_HANDLE  *CrsNode\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  UINT32                  EisaId;\r
+  AML_OBJECT_NODE_HANDLE  ResNode;\r
+\r
+  if (CrsNode == NULL) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // ASL: Device (RES0) {}\r
+  Status = AmlCodeGenDevice ("RES0", PciNode, &ResNode);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  // ASL: Name (_HID, EISAID ("PNP0C02"))\r
+  Status = AmlGetEisaIdFromString ("PNP0C02", &EisaId); /* PNP Motherboard Resources */\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  Status = AmlCodeGenNameInteger ("_HID", EisaId, ResNode, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  // ASL: Name (_CRS, ResourceTemplate () {})\r
+  Status = AmlCodeGenNameResourceTemplate ("_CRS", ResNode, CrsNode);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/** Reserves ECAM space for PCI config space\r
+\r
+  @param [in]       Generator       The SSDT Pci generator.\r
+  @param [in]       CfgMgrProtocol  Pointer to the Configuration Manager\r
+                                    Protocol interface.\r
+  @param [in]       PciInfo         Pci device information.\r
+  @param [in, out]  PciNode         RootNode of the AML tree to populate.\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ReserveEcamSpace (\r
+  IN            ACPI_PCI_GENERATOR                            *Generator,\r
+  IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol,\r
+  IN      CONST CM_ARM_PCI_CONFIG_SPACE_INFO                  *PciInfo,\r
+  IN  OUT       AML_OBJECT_NODE_HANDLE                        PciNode\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  AML_OBJECT_NODE_HANDLE  CrsNode;\r
+  UINT64                  AddressMinimum;\r
+  UINT64                  AddressMaximum;\r
+\r
+  Status = GenerateMotherboardDevice (PciNode, &CrsNode);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  AddressMinimum = PciInfo->BaseAddress + (PciInfo->StartBusNumber *\r
+                                           PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB);\r
+  AddressMaximum = PciInfo->BaseAddress + ((PciInfo->EndBusNumber + 1) *\r
+                                           PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB) - 1;\r
+\r
+  Status = AmlCodeGenRdQWordMemory (\r
+             FALSE,\r
+             TRUE,\r
+             TRUE,\r
+             TRUE,\r
+             FALSE,  // non-cacheable\r
+             TRUE,\r
+             0,\r
+             AddressMinimum,\r
+             AddressMaximum,\r
+             0,  // no translation\r
+             AddressMaximum - AddressMinimum + 1,\r
+             0,\r
+             NULL,\r
+             0,\r
+             TRUE,\r
+             CrsNode,\r
+             NULL\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
 /** Generate a Pci device.\r
 \r
   @param [in]       Generator       The SSDT Pci generator.\r
@@ -702,9 +829,17 @@ GeneratePciDevice (
     return Status;\r
   }\r
 \r
+  // Add the PNP Motherboard Resources Device to reserve ECAM space\r
+  Status = ReserveEcamSpace (Generator, CfgMgrProtocol, PciInfo, PciNode);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
   // Add the template _OSC method.\r
   Status = AddOscMethod (PciInfo, PciNode);\r
   ASSERT_EFI_ERROR (Status);\r
+\r
   return Status;\r
 }\r
 \r