public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Omkar Anand Kulkarni" <omkar.kulkarni@arm.com>
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>,
	Leif Lindholm <leif@nuviainc.com>,
	Sami Mujawar <sami.mujawar@arm.com>,
	Jiewen Yao <jiewen.yao@intel.com>
Subject: [PATCH 1/3] ArmPlatformPkg: Allow dynamic generation of HEST ACPI table
Date: Fri, 30 Oct 2020 14:06:09 +0530	[thread overview]
Message-ID: <20201030083611.8196-2-omkar.kulkarni@arm.com> (raw)
In-Reply-To: <20201030083611.8196-1-omkar.kulkarni@arm.com>

Introduce the HEST table generation protocol that allows platforms to
build the table with multiple error source descriptors and install the
table. The protocols provides two interfaces. The first interface allows
for adding multiple error source descriptors into the HEST table. The
second interface can then be used to dynamically installed the fully
populated HEST table. This allows multiple drivers and/or libraries to
dynamically register error source descriptors into the HEST table.

Co-authored-by: Thomas Abraham <thomas.abraham@arm.com>
Signed-off-by: Omkar Anand Kulkarni <omkar.kulkarni@arm.com>
---
 ArmPlatformPkg/ArmPlatformPkg.dec               |   4 +
 ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.inf |  45 +++
 ArmPlatformPkg/Include/Protocol/HestTable.h     |  66 ++++
 ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.c   | 320 ++++++++++++++++++++
 4 files changed, 435 insertions(+)

diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec
index 696d636aacee..23c5b768f677 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dec
+++ b/ArmPlatformPkg/ArmPlatformPkg.dec
@@ -110,3 +110,7 @@
   gArmPlatformTokenSpaceGuid.PcdPL031RtcPpmAccuracy|300000000|UINT32|0x00000022
 
   gArmPlatformTokenSpaceGuid.PcdWatchdogCount|0x0|UINT32|0x00000033
+
+[Protocols.common]
+  ## Arm Platform HEST table generation protocol
+  gHestTableProtocolGuid = { 0x705bdcd9, 0x8c47, 0x457e, { 0xad, 0x0d, 0xf7, 0x86, 0xf3, 0x4a, 0x0d, 0x63 } }
diff --git a/ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.inf b/ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.inf
new file mode 100644
index 000000000000..670f53476800
--- /dev/null
+++ b/ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.inf
@@ -0,0 +1,45 @@
+## @file
+#  DXE driver that creates and publishes the HEST ACPI table.
+#
+#  Copyright (c) 2018-2020, ARM Limited. All rights reserved.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = HestDxe
+  FILE_GUID                      = 933099a2-ef71-4e00-82aa-a79b1e0a3b38
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = HestInitialize
+
+[Sources.Common]
+  HestDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/SgiPkg/SgiPlatform.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseMemoryLib
+  DebugLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid         ## PROTOCOL ALWAYS_CONSUMED
+  gHestTableProtocolGuid            ## PRODUCES
+
+[FixedPcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+[Depex]
+  gEfiAcpiSdtProtocolGuid
diff --git a/ArmPlatformPkg/Include/Protocol/HestTable.h b/ArmPlatformPkg/Include/Protocol/HestTable.h
new file mode 100644
index 000000000000..3905aab044dc
--- /dev/null
+++ b/ArmPlatformPkg/Include/Protocol/HestTable.h
@@ -0,0 +1,66 @@
+/** @file
+  Provides protocol to create and install the HEST ACPI for the
+  platform.
+
+  Copyright (c) 2020, ARM Limited. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef HEST_TABLE_H_
+#define HEST_TABLE_H_
+
+#define HEST_TABLE_PROTOCOL_GUID \
+  { \
+    0x705bdcd9, 0x8c47, 0x457e, \
+    { 0xad, 0x0d, 0xf7, 0x86, 0xf3, 0x4a, 0x0d, 0x63 } \
+  }
+
+/**
+  Append a list of error source descriptors to the HEST table.
+
+  Allows error source list producer module to append its error source descriptors
+  into the HEST ACPI table being prepared for installation.
+
+  @param[in] ErrorSourceDescriptorList     List of Error Source Descriptors.
+  @param[in] ErrorSourceDescriptorListSize Total Size of the ErrorSourceDescriptorList.
+  @param[in] ErrorSourceDescriptorCount    Total count of error source descriptors in
+                                           ErrorSourceDescriptorList.
+
+  @retval EFI_SUCCESS                      Appending the error source descriptors
+                                           successful.
+  @retval EFI_OUT_OF_RESOURCES             Buffer reallocation failed for the HEST
+                                           table.
+  @retval EFI_INVALID_PARAMETER            Null ErrorSourceDescriptorList param or
+                                           ErrorSourceDescriptorListSize is 0.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *APPEND_ERROR_SOURCE_DESCRIPTOR) (
+  IN CONST VOID *ErrorSourceDescriptorList,
+  IN UINTN      ErrorSourceDescriptorListSize,
+  IN UINTN      ErrorSourceDescriptorCount
+  );
+
+/**
+  Install ACPI HEST table.
+
+  @retval EFI_SUCCESS On ACPI HEST table installation success.
+  @retval Other       On ACPI HEST table installation failure.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *INSTALL_HEST_TABLE) (VOID);
+
+//
+// HEST_TABLE_PROTOCOL enables creation and installation of HEST table
+//
+typedef struct {
+  APPEND_ERROR_SOURCE_DESCRIPTOR AppendErrorSourceDescriptors;
+  INSTALL_HEST_TABLE             InstallHestTable;
+} HEST_TABLE_PROTOCOL;
+
+extern EFI_GUID gHestTableProtocolGuid;
+#endif  // HEST_TABLE_H_
diff --git a/ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.c b/ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.c
new file mode 100644
index 000000000000..35de14aaf05c
--- /dev/null
+++ b/ArmPlatformPkg/Drivers/Apei/HestDxe/HestDxe.c
@@ -0,0 +1,320 @@
+/** @file
+  Builds and installs the HEST ACPI table.
+
+  This driver installs a protocol that can be used to create and install a HEST
+  ACPI table. The protocol allows one or more error source producers to add the
+  error source descriptors into the HEST table. It also allows the resulting HEST
+  ACPI table to be installed.
+
+  Copyright (c) 2020, ARM Limited. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/HestTable.h>
+
+typedef struct {
+  VOID   *HestTable;        /// Pointer to HEST ACPI table.
+  UINT32 CurrentTableSize;  /// Current size of HEST ACPI table.
+} HEST_DXE_DRIVER_DATA;
+
+STATIC EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol = NULL;
+STATIC HEST_DXE_DRIVER_DATA mHestDriverData;
+
+/**
+  Helper function to reallocate memory pool for every new error source descriptor
+  added.
+
+  @param[in]      OldTableSize  Old memory pool size.
+  @param[in]      NewTableSize  Required memory pool size.
+  @param[in, out] OldBuffer     Current memory buffer pointer holding the HEST
+                                table data.
+
+  @retval                       New pointer to reallocated memory pool.
+
+**/
+STATIC
+VOID*
+ReallocateHestTableMemory (
+  IN     UINT32 OldTableSize,
+  IN     UINT32 NewTableSize,
+  IN OUT VOID   *OldBuffer
+  )
+{
+  return ReallocateReservedPool (
+           OldTableSize,
+           NewTableSize,
+           OldBuffer
+           );
+}
+
+/**
+  Allocate memory for the HEST ACPI table header and populate it.
+
+  @retval EFI_SUCCESS           On successful creation of HEST header.
+  @retval EFI_OUT_OF_RESOURCES  If system is out of memory recources.
+
+**/
+STATIC
+EFI_STATUS
+BuildHestHeader (VOID)
+{
+  EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER HestHeader;
+  UINT64                                          TempOemTableId;
+
+  //
+  // Allocate memory for the HEST ACPI table header.
+  //
+  mHestDriverData.HestTable =
+    ReallocateHestTableMemory (
+      0,
+      sizeof (EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER),
+      NULL
+      );
+  if (mHestDriverData.HestTable == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mHestDriverData.CurrentTableSize =
+    sizeof (EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER);
+
+  //
+  // Populate the values of the HEST ACPI table header.
+  //
+  HestHeader.Header.Signature = EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE;
+  HestHeader.Header.Revision = EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_REVISION;
+  CopyMem (
+    &HestHeader.Header.OemId,
+    FixedPcdGetPtr (PcdAcpiDefaultOemId),
+    sizeof (HestHeader.Header.OemId)
+    );
+  TempOemTableId = FixedPcdGet64 (PcdAcpiDefaultOemTableId);
+  CopyMem (
+    &HestHeader.Header.OemTableId,
+    &TempOemTableId,
+    sizeof (HestHeader.Header.OemTableId)
+    );
+  HestHeader.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
+  HestHeader.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
+  HestHeader.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+  HestHeader.ErrorSourceCount = 0;
+  CopyMem (mHestDriverData.HestTable, &HestHeader, sizeof (HestHeader));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Append HEST error source descriptor protocol service.
+
+  @param[in] ErrorSourceDescriptorList     List of Error Source Descriptors.
+  @param[in] ErrorSourceDescriptorListSize Total Size of the ErrorSourceDescriptorList.
+  @param[in] ErrorSourceDescriptorCount    Total count of error source descriptors in
+                                           ErrorSourceDescriptorList.
+
+  @retval EFI_SUCCESS                      Appending the error source descriptors
+                                           successful.
+  @retval EFI_OUT_OF_RESOURCES             Buffer reallocation failed for the HEST
+                                           table.
+  @retval EFI_INVALID_PARAMETER            Null ErrorSourceDescriptorList param or
+                                           ErrorSourceDescriptorListSize is 0.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AppendErrorSourceDescriptor (
+  IN CONST VOID *ErrorSourceDescriptorList,
+  IN UINTN      ErrorSourceDescriptorListSize,
+  IN UINTN      ErrorSourceDescriptorCount
+  )
+{
+  EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER *HestHeaderPtr;
+  EFI_STATUS                                      Status;
+  UINT32                                          NewTableSize;
+  VOID                                            *ErrorDescriptorPtr;
+
+  if ((ErrorSourceDescriptorList == NULL)
+    || (ErrorSourceDescriptorListSize == 0)) {
+     return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Create a HEST table header if not already created.
+  //
+  if (mHestDriverData.HestTable == NULL) {
+    Status = BuildHestHeader ();
+    if (Status == EFI_OUT_OF_RESOURCES) {
+      DEBUG ((DEBUG_ERROR, "HestDxe: Failed to build HEST header, status: %r\n",
+                           Status));
+      return Status;
+    }
+  }
+
+  //
+  // Resize the existing HEST table buffer to accommodate the incoming error source
+  // descriptors.
+  //
+  NewTableSize = mHestDriverData.CurrentTableSize +
+                 ErrorSourceDescriptorListSize;
+  mHestDriverData.HestTable = ReallocateHestTableMemory (
+                                mHestDriverData.CurrentTableSize,
+                                NewTableSize,
+                                mHestDriverData.HestTable
+                                );
+  if (mHestDriverData.HestTable == NULL) {
+    DEBUG ((DEBUG_ERROR, "HestDxe: Failed to reallocate memory for HEST table\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Copy the incoming error source descriptors into HEST table.
+  //
+  ErrorDescriptorPtr = (VOID *)mHestDriverData.HestTable +
+                       mHestDriverData.CurrentTableSize;
+  HestHeaderPtr = (EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER *)
+                  mHestDriverData.HestTable;
+  CopyMem (
+    ErrorDescriptorPtr,
+    ErrorSourceDescriptorList,
+    ErrorSourceDescriptorListSize
+    );
+  mHestDriverData.CurrentTableSize = NewTableSize;
+  HestHeaderPtr->Header.Length = mHestDriverData.CurrentTableSize;
+  HestHeaderPtr->ErrorSourceCount += ErrorSourceDescriptorCount;
+
+  DEBUG ((DEBUG_INFO, "HestDxe: %d Error source descriptor(s) added \n",
+                      ErrorSourceDescriptorCount));
+  return EFI_SUCCESS;
+}
+
+/**
+  Install HEST ACPI table protocol service.
+
+  @retval EFI_SUCCESS ACPI HEST table is installed successfully.
+  @retval EFI_ABORTED HEST table is NULL.
+  @retval Other       Install HEST ACPI table failed.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+InstallHestAcpiTable (VOID)
+{
+  EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER *HestHeader;
+  EFI_STATUS                                      Status;
+  UINTN                                           AcpiTableHandle;
+
+  //
+  // Check if we have valid HEST table data.
+  //
+  if (mHestDriverData.HestTable == NULL) {
+    DEBUG ((DEBUG_ERROR, "HestDxe: No data available to generate HEST table\n"));
+    return EFI_ABORTED;
+  }
+
+  //
+  // Valid data for HEST table found. Update the header checksum and install the
+  // HEST table.
+  //
+  HestHeader = (EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER *)
+               mHestDriverData.HestTable;
+  HestHeader->Header.Checksum = CalculateCheckSum8 (
+                                  (UINT8 *)HestHeader,
+                                  HestHeader->Header.Length
+                                  );
+
+  Status = mAcpiTableProtocol->InstallAcpiTable (
+                                 mAcpiTableProtocol,
+                                 HestHeader,
+                                 HestHeader->Header.Length,
+                                 &AcpiTableHandle
+                                 );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "HestDxe: HEST ACPI table installation failed, status: %r\n",
+                         Status));
+    return Status;
+  }
+
+  //
+  // Free the HEST table buffer.
+  //
+  FreePool (mHestDriverData.HestTable);
+  DEBUG ((DEBUG_INFO, "HestDxe: Installed HEST ACPI table \n"));
+  return EFI_SUCCESS;
+}
+
+//
+// HEST table generation protocol instance.
+//
+STATIC HEST_TABLE_PROTOCOL mHestProtocol = {
+  AppendErrorSourceDescriptor,
+  InstallHestAcpiTable
+};
+
+/**
+  The Entry Point for HEST DXE driver.
+
+  This function installs the HEST table creation and installation protocol
+  services.
+
+  @param[in] ImageHandle Handle to the EFI image.
+  @param[in] SystemTable A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS    On successful installation of protocol services and
+                         location the Acpi table protocol.
+  @retval Other          On Failure to locate ACPI table protocol or install
+                         of HEST table generation protocol.
+
+**/
+EFI_STATUS
+EFIAPI
+HestInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_HANDLE Handle = NULL;
+  EFI_STATUS Status;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&mAcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "HestDxe: Failed to locate ACPI table protocol, status: %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gHestTableProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mHestProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "HestDxe: Failed to install HEST table generation protocol status: %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


  reply	other threads:[~2020-10-30  8:36 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-30  8:36 [PATCH 0/3] ArmPlatformPkg: Introduce dynamic generation of HEST table omkar.kulkarni
2020-10-30  8:36 ` Omkar Anand Kulkarni [this message]
2020-10-30  8:36 ` [PATCH 2/3] ArmPlatformPkg: add definition for MM_HEST_ERROR_SOURCE_DESC_PROTOCOL Omkar Anand Kulkarni
2020-10-30  8:36 ` [PATCH 3/3] ArmPlatformPkg: retreive error source descriptors from MM Omkar Anand Kulkarni

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=20201030083611.8196-2-omkar.kulkarni@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