public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Sami Mujawar <sami.mujawar@arm.com>
To: edk2-devel@lists.01.org
Cc: alexei.fedorov@arm.com, leif.lindholm@linaro.org,
	Matteo.Carlini@arm.com,  Stephanie.Hughes-Fitt@arm.com,
	nd@arm.com
Subject: [PATCH v1 21/22] DynamicTablesPkg: Arm PCI MCFG Table Generator
Date: Fri, 21 Dec 2018 16:57:18 +0000	[thread overview]
Message-ID: <20181221165719.49480-22-sami.mujawar@arm.com> (raw)
In-Reply-To: <20181221165719.49480-1-sami.mujawar@arm.com>

The MCFG generator uses the configuration manager protocol
to obtain the PCI Configuration space information from the
platform configuration manager and builds the MCFG table.

This table data is then used by the Table Manager to install
the MCFG table.

The Table Manager then invokes the generator interface to free
any resources allocated by the MCFG table generator.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
 DynamicTablesPkg/DynamicTables.dsc.inc                              |   1 +
 DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf |  42 +++
 DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c    | 344 ++++++++++++++++++++
 3 files changed, 387 insertions(+)

diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 5ff981619fcd3a579afc50faff41e474a5d604ad..98a37efa5d567942a18163c44961bd4c86552bb6 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -31,6 +31,7 @@ [Components.common]
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
+      NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
   }
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..e491ad6b24faae24e473f0fd501e06a6f3b456b5
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+#  MCFG Table Generator
+#
+#  Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+  INF_VERSION    = 0x00010019
+  BASE_NAME      = AcpiMcfgLibArm
+  FILE_GUID      = 8C9BDCB2-72D4-4F30-A12D-1145C3807FF7
+  VERSION_STRING = 1.0
+  MODULE_TYPE    = DXE_DRIVER
+  LIBRARY_CLASS  = NULL|DXE_DRIVER
+  CONSTRUCTOR    = AcpiMcfgLibConstructor
+  DESTRUCTOR     = AcpiMcfgLibDestructor
+
+[Sources]
+  McfgGenerator.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+  BaseLib
+
+[Pcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..1be27160c12b51b36b90cd5f5c9e01efecd8cc03
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c
@@ -0,0 +1,344 @@
+/** @file
+  MCFG Table Generator
+
+  Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Reference(s):
+  - PCI Firmware Specification - Revision 3.2, January 26, 2015.
+
+**/
+
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** ARM standard MCFG Generator
+
+Requirements:
+  The following Configuration Manager Object(s) are required by
+  this Generator:
+  - EArmObjPciConfigSpaceInfo
+*/
+
+#pragma pack(1)
+
+/** This typedef is used to shorten the name of the MCFG Table
+    header structure.
+*/
+typedef
+  EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER
+  MCFG_TABLE;
+
+/** This typedef is used to shorten the name of the Enhanced
+    Configuration Space address structure.
+*/
+typedef
+  EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE
+  MCFG_CFG_SPACE_ADDR;
+
+#pragma pack()
+
+/** Retrieve the PCI Configuration Space Information.
+*/
+GET_OBJECT_LIST (
+  EObjNameSpaceArm,
+  EArmObjPciConfigSpaceInfo,
+  CM_ARM_PCI_CONFIG_SPACE_INFO
+  );
+
+/** Add the PCI Enhanced Configuration Space Information to the MCFG Table.
+
+  @param [in]  Mcfg                Pointer to MCFG Table.
+  @param [in]  PciCfgSpaceOffset   Offset for the PCI Configuration Space
+                                   Info structure in the MCFG Table.
+  @param [in]  PciCfgSpaceInfoList Pointer to the PCI Configuration Space
+                                   Info List.
+  @param [in]  PciCfgSpaceCount    Count of PCI Configuration Space Info.
+**/
+STATIC
+VOID
+AddPciConfigurationSpaceList (
+  IN       MCFG_TABLE                   * CONST Mcfg,
+  IN CONST UINT32                               PciCfgSpaceOffset,
+  IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *       PciCfgSpaceInfoList,
+  IN       UINT32                               PciCfgSpaceCount
+)
+{
+  MCFG_CFG_SPACE_ADDR  * PciCfgSpace;
+
+  ASSERT (Mcfg != NULL);
+  ASSERT (PciCfgSpaceInfoList != NULL);
+
+  PciCfgSpace = (MCFG_CFG_SPACE_ADDR *)((UINT8*)Mcfg + PciCfgSpaceOffset);
+
+  while (PciCfgSpaceCount-- != 0) {
+    // Add PCI Configuration Space entry
+    PciCfgSpace->BaseAddress = PciCfgSpaceInfoList->BaseAddress;
+    PciCfgSpace->PciSegmentGroupNumber =
+      PciCfgSpaceInfoList->PciSegmentGroupNumber;
+    PciCfgSpace->StartBusNumber = PciCfgSpaceInfoList->StartBusNumber;
+    PciCfgSpace->EndBusNumber = PciCfgSpaceInfoList->EndBusNumber;
+    PciCfgSpace->Reserved = EFI_ACPI_RESERVED_DWORD;
+    PciCfgSpace++;
+    PciCfgSpaceInfoList++;
+  }
+}
+
+/** Construct the MCFG ACPI table.
+
+  This function invokes the Configuration Manager protocol interface
+  to get the required hardware information for generating the ACPI
+  table.
+
+  If this function allocates any resources then they must be freed
+  in the FreeXXXXTableResources function.
+
+  @param [in]  This           Pointer to the table generator.
+  @param [in]  AcpiTableInfo  Pointer to the ACPI Table Info.
+  @param [in]  CfgMgrProtocol Pointer to the Configuration Manager
+                              Protocol Interface.
+  @param [out] Table          Pointer to the constructed ACPI Table.
+
+  @retval EFI_SUCCESS           Table generated successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object was not found.
+  @retval EFI_BAD_BUFFER_SIZE   The size returned by the Configuration
+                                Manager is less than the Object size for the
+                                requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildMcfgTable (
+  IN  CONST ACPI_TABLE_GENERATOR                  * CONST This,
+  IN  CONST CM_STD_OBJ_ACPI_TABLE_INFO            * CONST AcpiTableInfo,
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
+  OUT       EFI_ACPI_DESCRIPTION_HEADER          ** CONST Table
+  )
+{
+  EFI_STATUS                      Status;
+  UINT32                          TableSize;
+  UINT32                          ConfigurationSpaceCount;
+  CM_ARM_PCI_CONFIG_SPACE_INFO  * PciConfigSpaceInfoList;
+  MCFG_TABLE                    * Mcfg;
+
+  ASSERT (This != NULL);
+  ASSERT (AcpiTableInfo != NULL);
+  ASSERT (CfgMgrProtocol != NULL);
+  ASSERT (Table != NULL);
+  ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+  ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+  *Table = NULL;
+  Status = GetEArmObjPciConfigSpaceInfo (
+              CfgMgrProtocol,
+              CM_NULL_TOKEN,
+              &PciConfigSpaceInfoList,
+              &ConfigurationSpaceCount
+              );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "ERROR: MCFG: Failed to get PCI Configuration Space Information." \
+      " Status = %r\n",
+      Status
+      ));
+    goto error_handler;
+  }
+
+  if (ConfigurationSpaceCount == 0) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MCFG: Configuration Space Count = %d\n",
+      ConfigurationSpaceCount
+      ));
+    Status = EFI_INVALID_PARAMETER;
+    ASSERT (ConfigurationSpaceCount != 0);
+    goto error_handler;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "MCFG: Configuration Space Count = %d\n",
+    ConfigurationSpaceCount
+    ));
+
+  // Calculate the MCFG Table Size
+  TableSize = sizeof (MCFG_TABLE) +
+    ((sizeof (MCFG_CFG_SPACE_ADDR) * ConfigurationSpaceCount));
+
+  *Table = (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize);
+  if (*Table == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MCFG: Failed to allocate memory for MCFG Table, Size = %d," \
+      " Status = %r\n",
+      TableSize,
+      Status
+      ));
+    goto error_handler;
+  }
+
+  Mcfg = (MCFG_TABLE*)*Table;
+  DEBUG ((
+    DEBUG_INFO,
+    "MCFG: Mcfg = 0x%p TableSize = 0x%x\n",
+    Mcfg,
+    TableSize
+    ));
+
+  Status = AddAcpiHeader (CfgMgrProtocol, This, &Mcfg->Header, TableSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MCFG: Failed to add ACPI header. Status = %r\n",
+      Status
+      ));
+    goto error_handler;
+  }
+
+  Mcfg->Reserved = EFI_ACPI_RESERVED_QWORD;
+
+  AddPciConfigurationSpaceList (
+    Mcfg,
+    sizeof (MCFG_TABLE),
+    PciConfigSpaceInfoList,
+    ConfigurationSpaceCount
+    );
+
+  return EFI_SUCCESS;
+
+error_handler:
+  if (*Table != NULL) {
+    FreePool (*Table);
+    *Table = NULL;
+  }
+  return Status;
+}
+
+/** Free any resources allocated for constructing the MCFG
+
+  @param [in]      This           Pointer to the table generator.
+  @param [in]      AcpiTableInfo  Pointer to the ACPI Table Info.
+  @param [in]      CfgMgrProtocol Pointer to the Configuration Manager
+                                  Protocol Interface.
+  @param [in, out] Table          Pointer to the ACPI Table.
+
+  @retval EFI_SUCCESS           The resources were freed successfully.
+  @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+FreeMcfgTableResources (
+  IN      CONST ACPI_TABLE_GENERATOR                  * CONST This,
+  IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO            * CONST AcpiTableInfo,
+  IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
+  IN OUT        EFI_ACPI_DESCRIPTION_HEADER          ** CONST Table
+  )
+{
+  ASSERT (This != NULL);
+  ASSERT (AcpiTableInfo != NULL);
+  ASSERT (CfgMgrProtocol != NULL);
+  ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+  ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+  if ((Table == NULL) || (*Table == NULL)) {
+    DEBUG ((DEBUG_ERROR, "ERROR: MCFG: Invalid Table Pointer\n"));
+    ASSERT ((Table != NULL) && (*Table != NULL));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FreePool (*Table);
+  *Table = NULL;
+  return EFI_SUCCESS;
+}
+
+/** This macro defines the MCFG Table Generator revision.
+*/
+#define MCFG_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the MCFG Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR McfgGenerator = {
+  // Generator ID
+  CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_MCFG),
+  // Generator Description
+  L"ACPI.STD.MCFG.GENERATOR",
+  // ACPI Table Signature
+  EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+  // ACPI Table Revision
+  EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+  // Creator ID
+  TABLE_GENERATOR_CREATOR_ID_ARM,
+  // Creator Revision
+  MCFG_GENERATOR_REVISION,
+  // Build Table function
+  BuildMcfgTable,
+  // Free Resource function
+  FreeMcfgTableResources
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+  @param [in]  ImageHandle  The handle to the image.
+  @param [in]  SystemTable  Pointer to the System Table.
+
+  @retval EFI_SUCCESS           The Generator is registered.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_ALREADY_STARTED   The Generator for the Table ID
+                                is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiMcfgLibConstructor (
+  IN CONST EFI_HANDLE                ImageHandle,
+  IN       EFI_SYSTEM_TABLE  * CONST SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  Status = RegisterAcpiTableGenerator (&McfgGenerator);
+  DEBUG ((DEBUG_INFO, "MCFG: Register Generator. Status = %r\n", Status));
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+  @param [in]  ImageHandle  The handle to the image.
+  @param [in]  SystemTable  Pointer to the System Table.
+
+  @retval EFI_SUCCESS           The Generator is deregistered.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiMcfgLibDestructor (
+  IN CONST EFI_HANDLE                ImageHandle,
+  IN       EFI_SYSTEM_TABLE  * CONST SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  Status = DeregisterAcpiTableGenerator (&McfgGenerator);
+  DEBUG ((DEBUG_INFO, "MCFG: Deregister Generator. Status = %r\n", Status));
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'




  parent reply	other threads:[~2018-12-21 17:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
2018-12-21 16:56 ` [PATCH v1 01/22] DynamicTablesPkg: " Sami Mujawar
2018-12-21 16:56 ` [PATCH v1 02/22] DynamicTablesPkg: Table Generator definition Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 03/22] DynamicTablesPkg: Acpi Table Generator Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 04/22] DynamicTablesPkg: SMBIOS " Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 05/22] DynamicTablesPkg: DT " Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 06/22] DynamicTablesPkg: Standard NameSpace Objects Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 07/22] DynamicTablesPkg: Arm " Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 08/22] DynamicTablesPkg: Configuration Manager Objects Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 09/22] DynamicTablesPkg: Configuration Manager Protocol Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 10/22] DynamicTablesPkg: Configuration Manager Helper Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 11/22] DynamicTablesPkg: Table Helper Library Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 12/22] DynamicTablesPkg: Dynamic Table Factory Protocol Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 13/22] DynamicTablesPkg: Dynamic Table Factory Dxe Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 14/22] DynamicTablesPkg: Dynamic Table Manager Dxe Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 15/22] DynamicTablesPkg: Arm Raw/DSDT/SSDT Generator Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 16/22] DynamicTablesPkg: Arm ACPI FADT Generator Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 17/22] DynamicTablesPkg: Arm ACPI MADT Generator Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 18/22] DynamicTablesPkg: Arm ACPI GTDT Generator Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 19/22] DynamicTablesPkg: Arm SPCR Table Generator Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 20/22] DynamicTablesPkg: Arm DBG2 " Sami Mujawar
2018-12-21 16:57 ` Sami Mujawar [this message]
2018-12-21 16:57 ` [PATCH v1 22/22] DynamicTablesPkg: Arm IORT " Sami Mujawar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181221165719.49480-22-sami.mujawar@arm.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox