public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Oram, Isaac W" <isaac.w.oram@intel.com>
To: devel@edk2.groups.io
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>,
	Chasel Chiu <chasel.chiu@intel.com>
Subject: [edk2-devel][edk2-platforms][PATCH V1 6/9] WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and SRAT
Date: Thu, 10 Mar 2022 14:41:11 -0800	[thread overview]
Message-ID: <a911074440b7edb1f196c0aef2d3b802d50f0b42.1646951441.git.isaac.w.oram@intel.com> (raw)
In-Reply-To: <cover.1646951441.git.isaac.w.oram@intel.com>

Library for building tables during the boot.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h                 | 111 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c   | 470 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf |  40 ++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                      |   1 +
 4 files changed, 622 insertions(+)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h
new file mode 100644
index 0000000000..99aa1c02f7
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h
@@ -0,0 +1,111 @@
+/** @file
+  Library for building ACPI Tables.
+
+  @copyright
+  Copyright 2016 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BUILD_ACPI_TABLES_LIB_H_
+#define _BUILD_ACPI_TABLES_LIB_H_
+
+#include <IndustryStandard/Acpi.h>
+
+/** Structure of a MADT and SRAT sub-structure header.
+
+  This structure contains the type and length fields, which are common to every
+  sub-structure of the MADT and SRAT tables. A pointer to any structure can be cast as this.
+**/
+typedef struct {
+  UINT8 Type;
+  UINT8 Length;
+} STRUCTURE_HEADER;
+
+/**
+  Initialize the MADT header.
+
+  This function fills in the MADT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in when building
+  the whole table.
+
+  @param[in,out]  MadtHeader    Pointer to the MADT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the MADT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeMadtHeader (
+  IN OUT EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader
+  );
+
+/**
+  Initialize the SRAT header.
+
+  This function fills in the SRAT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in when building
+  the whole table.
+
+  @param[in,out]  SratHeader    Pointer to the SRAT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the SRAT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeSratHeader (
+  IN OUT EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratHeader
+  );
+
+/**
+  Copy an ACPI sub-structure; MADT and SRAT supported
+
+  This function validates the structure type and size of a sub-structure
+  and returns a newly allocated copy of it.
+
+  @param[in]  Header            Pointer to the header of the table.
+  @param[in]  Structure         Pointer to the structure to copy.
+  @param[in]  NewStructure      Newly allocated copy of the structure.
+
+  @retval EFI_SUCCESS           Successfully copied the structure.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Structure type was unknown.
+  @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
+  @retval EFI_UNSUPPORTED       Header passed in is not supported.
+**/
+EFI_STATUS
+CopyStructure (
+  IN  EFI_ACPI_DESCRIPTION_HEADER *Header,
+  IN  STRUCTURE_HEADER *Structure,
+  OUT STRUCTURE_HEADER **NewStructure
+  );
+
+/**
+  Build ACPI Table. MADT and SRAT tables supported.
+
+  This function builds the ACPI table from the header plus the list of sub-structures
+  passed in. The table returned by this function is ready to be installed using
+  the ACPI table protocol's InstallAcpiTable function, which copies it into
+  ACPI memory. After that, the caller should free the memory returned by this
+  function.
+
+  @param[in]  AcpiHeader             Pointer to the header structure.
+  @param[in]  TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures             Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount         Number of structure pointers in the array.
+  @param[out] NewTable               Newly allocated and initialized pointer to the ACPI Table.
+
+  @retval EFI_SUCCESS           Successfully built the ACPI table.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature.
+  @retval EFI_OUT_OF_RESOURCES  Space for the ACPI Table could not be allocated.
+**/
+EFI_STATUS
+BuildAcpiTable (
+  IN  EFI_ACPI_DESCRIPTION_HEADER  *AcpiHeader,
+  IN  UINTN                        TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER             **Structures,
+  IN  UINTN                        StructureCount,
+  OUT UINT8                        **NewTable
+  );
+
+#endif // _BUILD_ACPI_TABLES_LIB_H_
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c
new file mode 100644
index 0000000000..778136311e
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c
@@ -0,0 +1,470 @@
+/** @file
+  Library for building ACPI Tables.
+
+  @copyright
+  Copyright 2016 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Acpi/Madt.h>
+#include <Acpi/Srat.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <UncoreCommonIncludes.h>
+#include <Library/BuildAcpiTablesLib.h> // library class being implemented
+
+STRUCTURE_HEADER mMadtStructureTable[] = {
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC,          sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE)},
+  {EFI_ACPI_6_2_IO_APIC,                       sizeof (EFI_ACPI_6_2_IO_APIC_STRUCTURE)},
+  {EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE,     sizeof (EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE)},
+  {EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_APIC_NMI,                sizeof (EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE,   sizeof (EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE)},
+  {EFI_ACPI_6_2_IO_SAPIC,                      sizeof (EFI_ACPI_6_2_IO_SAPIC_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_SAPIC,                   sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_SAPIC_STRUCTURE)},
+  {EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES,    sizeof (EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES_STRUCTURE)},
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC,        sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_X2APIC_NMI,              sizeof (EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE)}
+};
+
+STRUCTURE_HEADER mSratStructureTable[] = {
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY, sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE)},
+  {EFI_ACPI_6_2_MEMORY_AFFINITY,                     sizeof (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE)},
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY,     sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE)}
+};
+
+/**
+  Get the size of the ACPI table.
+
+  This function calculates the size needed for the ACPI Table based on the number and
+  size of the sub-structures that will compose it.
+
+  @param[in]  TableSpecificHdrLength  Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures              Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount          Number of structure pointers in the array.
+
+  @return     Total size needed for the ACPI table.
+**/
+UINT32
+GetTableSize (
+  IN  UINTN                 TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER      **Structures,
+  IN  UINTN                 StructureCount
+  )
+{
+  UINT32  TableLength;
+  UINT32  Index;
+
+  //
+  // Compute size of the ACPI table; header plus all structures needed.
+  //
+  TableLength = (UINT32) TableSpecificHdrLength;
+
+  for (Index = 0; Index < StructureCount; Index++) {
+    ASSERT (Structures[Index] != NULL);
+    if (Structures[Index] == NULL) {
+      return 0;
+    }
+
+    TableLength += Structures[Index]->Length;
+  }
+
+  return TableLength;
+}
+
+/**
+  Allocate the ACPI Table.
+
+  This function allocates space for the ACPI table based on the number and size of
+  the sub-structures that will compose it.
+
+  @param[in]  TableSpecificHdrLength  Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures  Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount  Number of structure pointers in the array.
+  @param[out] Table            Newly allocated ACPI Table pointer.
+
+  @retval EFI_SUCCESS           Successfully allocated the Table.
+  @retval EFI_OUT_OF_RESOURCES  Space for the Table could not be allocated.
+**/
+EFI_STATUS
+AllocateTable (
+  IN  UINTN                        TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER             **Structures,
+  IN  UINTN                        StructureCount,
+  OUT EFI_ACPI_DESCRIPTION_HEADER  **Table
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      Size;
+  EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+
+  //
+  // Get the size of the ACPI table and allocate memory.
+  //
+  Size = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+  InternalTable = (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size);
+
+  if (InternalTable == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((
+      DEBUG_ERROR,
+      "Failed to allocate %d bytes for ACPI Table\n",
+      Size
+      ));
+  } else {
+    Status = EFI_SUCCESS;
+    *Table = InternalTable;
+  }
+
+  return Status;
+}
+
+/**
+  Initialize the header.
+
+  This function fills in the standard table header with correct values,
+  except for the length and checksum fields, which are filled in later.
+
+  @param[in,out]  Header        Pointer to the header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeHeader (
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER *Header,
+  IN      UINT32                      Signature,
+  IN      UINT8                       Revision,
+  IN      UINT32                      OemRevision
+  )
+{
+  UINT64 AcpiTableOemId;
+
+  if (Header == NULL) {
+    DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Header->Signature  = Signature;
+  Header->Length     = 0; // filled in by Build function
+  Header->Revision   = Revision;
+  Header->Checksum   = 0; // filled in by InstallAcpiTable
+
+  CopyMem (
+    (VOID *) &Header->OemId,
+    PcdGetPtr (PcdAcpiDefaultOemId),
+    sizeof (Header->OemId)
+    );
+
+  AcpiTableOemId = PcdGet64 (PcdAcpiDefaultOemTableId);
+  CopyMem (
+    (VOID *) &Header->OemTableId,
+    (VOID *) &AcpiTableOemId,
+    sizeof (Header->OemTableId)
+    );
+
+  Header->OemRevision     = OemRevision;
+  Header->CreatorId       = EFI_ACPI_CREATOR_ID;
+  Header->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the MADT header.
+
+  This function fills in the MADT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in later.
+
+  @param[in,out]  MadtHeader    Pointer to the MADT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the MADT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeMadtHeader (
+  IN OUT EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader
+  )
+{
+  EFI_STATUS Status;
+
+  if (MadtHeader == NULL) {
+    DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = InitializeHeader (
+    &MadtHeader->Header,
+    EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+    EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+    EFI_ACPI_OEM_MADT_REVISION
+    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MadtHeader->LocalApicAddress       = EFI_ACPI_LOCAL_APIC_ADDRESS;
+  MadtHeader->Flags                  = EFI_ACPI_6_2_MULTIPLE_APIC_FLAGS;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the SRAT header.
+
+  This function fills in the SRAT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in when building
+  the whole table.
+
+  @param[in,out]  SratHeader    Pointer to the SRAT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the SRAT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeSratHeader (
+  IN OUT EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratHeader
+  )
+{
+  EFI_STATUS Status;
+
+  if (SratHeader == NULL) {
+    DEBUG ((DEBUG_ERROR, "SRAT header pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = InitializeHeader (
+    &SratHeader->Header,
+    EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
+    EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
+    EFI_ACPI_OEM_SRAT_REVISION
+    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SratHeader->Reserved1 = EFI_ACPI_SRAT_RESERVED_FOR_BACKWARD_COMPATIBILITY;
+  SratHeader->Reserved2 = EFI_ACPI_RESERVED_QWORD;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Copy an ACPI sub-structure; MADT and SRAT supported
+
+  This function validates the structure type and size of a sub-structure
+  and returns a newly allocated copy of it.
+
+  @param[in]  Header            Pointer to the header of the table.
+  @param[in]  Structure         Pointer to the structure to copy.
+  @param[in]  NewStructure      Newly allocated copy of the structure.
+
+  @retval EFI_SUCCESS           Successfully copied the structure.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Structure type was unknown.
+  @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
+  @retval EFI_UNSUPPORTED       Header passed in is not supported.
+**/
+EFI_STATUS
+CopyStructure (
+  IN  EFI_ACPI_DESCRIPTION_HEADER *Header,
+  IN  STRUCTURE_HEADER *Structure,
+  OUT STRUCTURE_HEADER **NewStructure
+  )
+{
+  STRUCTURE_HEADER      *NewStructureInternal;
+  STRUCTURE_HEADER      *StructureTable;
+  UINTN                 TableNumEntries;
+  BOOLEAN               EntryFound;
+  UINT8                 Index;
+
+  //
+  // Initialize the number of table entries and the table based on the table header passed in.
+  //
+  if (Header->Signature == EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
+    TableNumEntries = sizeof (mMadtStructureTable) / sizeof (STRUCTURE_HEADER);
+    StructureTable = mMadtStructureTable;
+  } else if (Header->Signature == EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) {
+    TableNumEntries = sizeof (mSratStructureTable) / sizeof (STRUCTURE_HEADER);
+    StructureTable = mSratStructureTable;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check the incoming structure against the table of supported structures.
+  //
+  EntryFound = FALSE;
+  for (Index = 0; Index < TableNumEntries; Index++) {
+    if (Structure->Type == StructureTable[Index].Type) {
+      if (Structure->Length == StructureTable[Index].Length) {
+        EntryFound = TRUE;
+      } else {
+        DEBUG ((
+          DEBUG_ERROR,
+          "Invalid length for structure type %d: expected %d, actually %d\n",
+          Structure->Type,
+          StructureTable[Index].Length,
+          Structure->Length
+          ));
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+  }
+
+  //
+  // If no entry in the table matches the structure type and length passed in
+  // then return invalid parameter.
+  //
+  if (!EntryFound) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Unknown structure type: %d\n",
+      Structure->Type
+      ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NewStructureInternal = (STRUCTURE_HEADER *) AllocatePool (Structure->Length);
+  if (NewStructureInternal == NULL) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Failed to allocate %d bytes for type %d structure\n",
+      Structure->Length,
+      Structure->Type
+      ));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (
+    (VOID *) NewStructureInternal,
+    (VOID *) Structure,
+    Structure->Length
+    );
+
+  *NewStructure = NewStructureInternal;
+  return EFI_SUCCESS;
+}
+
+/**
+  Build ACPI Table. MADT and SRAT tables supported.
+
+  This function builds the ACPI table from the header plus the list of sub-structures
+  passed in. The table returned by this function is ready to be installed using
+  the ACPI table protocol's InstallAcpiTable function, which copies it into
+  ACPI memory. After that, the caller should free the memory returned by this
+  function.
+
+  @param[in]  AcpiHeader             Pointer to the header structure.
+  @param[in]  TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures             Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount         Number of structure pointers in the array.
+  @param[out] NewTable               Newly allocated and initialized pointer to the ACPI Table.
+
+  @retval EFI_SUCCESS           Successfully built the ACPI table.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature.
+  @retval EFI_OUT_OF_RESOURCES  Space for the ACPI Table could not be allocated.
+**/
+EFI_STATUS
+BuildAcpiTable (
+  IN  EFI_ACPI_DESCRIPTION_HEADER  *AcpiHeader,
+  IN  UINTN                        TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER             **Structures,
+  IN  UINTN                        StructureCount,
+  OUT UINT8                        **NewTable
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+  UINTN                       Index;
+  UINT8                       *CurrPtr;
+  UINT8                       *EndOfTablePtr;
+
+  if (AcpiHeader == NULL) {
+    DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (AcpiHeader->Signature != EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE &&
+      AcpiHeader->Signature != EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "MADT or SRAT header signature is expected, actually 0x%08x\n",
+      AcpiHeader->Signature
+      ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Structures == NULL) {
+    DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  for (Index = 0; Index < StructureCount; Index++) {
+    if (Structures[Index] == NULL) {
+      DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index));
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Allocate the memory needed for the table.
+  //
+  Status = AllocateTable (
+    TableSpecificHdrLength,
+    Structures,
+    StructureCount,
+    &InternalTable
+    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Copy Header and patch in structure length, checksum is programmed later
+  // after all structures are populated.
+  //
+  CopyMem (
+    (VOID *) InternalTable,
+    (VOID *) AcpiHeader,
+    TableSpecificHdrLength
+    );
+
+  InternalTable->Length = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+
+  //
+  // Copy all the sub structures to the table.
+  //
+  CurrPtr = ((UINT8 *) InternalTable) + TableSpecificHdrLength;
+  EndOfTablePtr = ((UINT8 *) InternalTable) + InternalTable->Length;
+
+  for (Index = 0; Index < StructureCount; Index++) {
+    ASSERT (Structures[Index] != NULL);
+    if (Structures[Index] == NULL) {
+      break;
+    }
+
+    CopyMem (
+      (VOID *) CurrPtr,
+      (VOID *) Structures[Index],
+      Structures[Index]->Length
+      );
+
+    CurrPtr += Structures[Index]->Length;
+    ASSERT (CurrPtr <= EndOfTablePtr);
+    if (CurrPtr > EndOfTablePtr) {
+      break;
+    }
+  }
+
+  //
+  // Update the return pointer.
+  //
+  *NewTable = (UINT8 *) InternalTable;
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
new file mode 100644
index 0000000000..c2bb068fcf
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Library for building ACPI Tables.
+#
+# @copyright
+# Copyright 2016 - 2017 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010019
+  BASE_NAME                      = DxeBuildAcpiTablesLib
+  FILE_GUID                      = E4F78A63-7B78-43CD-A5C4-6CCB785B8854
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BuildAcpiTablesLib|DXE_DRIVER
+
+[Sources]
+  DxeBuildAcpiTablesLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  PcdLib
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+
+[FixedPcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index 2ac4a81e81..39b93d9289 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -620,6 +620,7 @@
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
   CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
   PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
+  BuildAcpiTablesLib|WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
 
 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM]
   FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
-- 
2.27.0.windows.1


  parent reply	other threads:[~2022-03-10 22:41 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 1/9] WhitleyOpenBoardPkg: Add definitions needed for " Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 2/9] WhitleySiliconPkg: Add definitions used in ACPI subsystem Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16 Oram, Isaac W
2022-03-10 23:18   ` Pedro Falcato
2022-03-10 23:34     ` Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 4/9] WhitleyOpenBoardPkg: Add UbaPlatLib Library Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 5/9] WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library Oram, Isaac W
2022-03-10 22:41 ` Oram, Isaac W [this message]
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 7/9] WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 8/9] WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI tables Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 9/9] WhitleyOpenBoardPkg/Build: Remove confusing build options Oram, Isaac W
2022-03-11  1:12 ` [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Nate DeSimone
2022-03-11 18:49   ` Oram, Isaac W

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=a911074440b7edb1f196c0aef2d3b802d50f0b42.1646951441.git.isaac.w.oram@intel.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