public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms/devel-MinPlatform][Patch v2] AdvancedFeaturePkg/AcpiDebug: Add new AcpiDebug modules.
@ 2019-04-08  4:50 Dong, Eric
  2019-04-12  2:03 ` [edk2-devel] " Kubacki, Michael A
  0 siblings, 1 reply; 2+ messages in thread
From: Dong, Eric @ 2019-04-08  4:50 UTC (permalink / raw)
  To: devel; +Cc: Hao Wu, Michael Kubacki

V2 changes:
1. Add error handling code instead of just assert.
2. Correct some comments and copy right.


Add new AcpiDebug modules which provide ACPI Debug feature.
Detail about this feature see the readme.txt in the patch.


Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
---
 .../AcpiDebug/AcpiDebug.asl                   | 109 ++++
 .../AdvancedFeaturePkg/AcpiDebug/AcpiDebug.c  | 528 ++++++++++++++++++
 .../AcpiDebug/AcpiDebugDxe.inf                |  63 +++
 .../AcpiDebug/AcpiDebugSmm.inf                |  65 +++
 .../AdvancedFeaturePkg/AcpiDebug/Readme.txt   |  31 +
 .../AdvancedFeaturePkg/AdvancedFeaturePkg.dec |   8 +-
 .../AdvancedFeaturePkg/AdvancedFeaturePkg.dsc |   4 +-
 7 files changed, 806 insertions(+), 2 deletions(-)
 create mode 100644 Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.asl
 create mode 100644 Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.c
 create mode 100644 Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf
 create mode 100644 Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf
 create mode 100644 Platform/Intel/AdvancedFeaturePkg/AcpiDebug/Readme.txt

diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.asl b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.asl
new file mode 100644
index 0000000..7e05db1
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.asl
@@ -0,0 +1,109 @@
+/** @file
+  Acpi Debug ASL code.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+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.
+
+**/
+
+DefinitionBlock (
+  "AcpiDebug.aml",
+  "SSDT",
+  2,
+  "Intel ",
+  "ADebTabl",
+  0x1000
+  )
+{
+  Scope(\)
+  {
+    //
+    // These pointers are patched during POST.
+    //
+    Name (DPTR, 0x80000000) // Address of Acpi debug memory buffer, fixed up during POST
+    Name (EPTR, 0x80000000) // End of Acpi debug memory buffer, fixed up during POST
+    Name (CPTR, 0x80000000) // Current pointer used as an index into the buffer(starts after the Acpi Debug head), fixed up during POST
+
+    //
+    // Use a Mutex to prevent multiple calls from simutaneously writing to the same memory.
+    //
+    Mutex (MMUT, 0)
+
+    //
+    // Operational region for SMI port access
+    //
+    OperationRegion (ADBP, SystemIO, 0xB2, 2)
+    Field (ADBP, ByteAcc, NoLock, Preserve)
+    {
+        B2PT, 8,
+        B3PT, 8,
+    }
+
+    //
+    // Write a string to a memory buffer
+    //
+    Method (MDBG, 1, Serialized)
+    {
+      OperationRegion (ADHD, SystemMemory, DPTR, 32) // Operation region for Acpi Debug buffer first 0x20 bytes
+      Field (ADHD, ByteAcc, NoLock, Preserve)
+      {
+        Offset (0x0),
+        ASIG, 128,      // 16 bytes is Signature
+        Offset (0x10),
+        ASIZ, 32,       // 4 bytes is buffer size
+        ACHP, 32,       // 4 bytes is current head pointer, normally is DPTR + 0x20,
+                        //   if there's SMM handler to print, then it's the starting of the info hasn't been printed yet.
+        ACTP, 32,       // 4 bytes is current tail pointer, is the same as CPTR
+        SMIN, 8,        // 1 byte of SMI Number for trigger callback
+        WRAP, 8,        // 1 byte of wrap status
+        SMMV, 8,        // 1 byte of SMM version status
+        TRUN, 8         // 1 byte of truncate status
+      }
+
+      Store (Acquire (MMUT, 1000), Local0) // save Acquire result so we can check for Mutex acquired
+      If (LEqual (Local0, Zero)) // check for Mutex acquired
+      {
+        OperationRegion (ABLK, SystemMemory, CPTR, 32) // Operation region to allow writes to ACPI debug buffer
+        Field (ABLK, ByteAcc, NoLock, Preserve)
+        {
+          Offset (0x0),
+          AAAA, 256 // 32 bytes is max size for string or data
+        }
+        ToHexString (Arg0, Local1) // convert argument to Hexadecimal String
+        Store (0, TRUN)
+        If (LGreaterEqual (SizeOf (Local1), 32))
+        {
+          Store (1, TRUN) // the input from ASL >= 32
+        }
+        Mid (Local1, 0, 31, AAAA) // extract the input to current buffer
+
+        Add (CPTR, 32, CPTR) // advance current pointer to next string location in memory buffer
+        If (LGreaterEqual (CPTR, EPTR) ) // check for end of 64kb Acpi debug buffer
+        {
+          Add (DPTR, 32, CPTR) // wrap around to beginning of buffer if the end has been reached
+          Store (1, WRAP)
+        }
+        Store (CPTR, ACTP)
+
+        If (SMMV)
+        {
+          //
+          // Trigger the SMI to print
+          //
+          Store (SMIN, B2PT)
+        }
+        Release (MMUT)
+      }
+
+      Return (Local0) // return error code indicating whether Mutex was acquired
+    }
+
+  } // End Scope
+} // End SSDT
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.c b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.c
new file mode 100644
index 0000000..be3b365
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.c
@@ -0,0 +1,528 @@
+/** @file
+  Acpi Debug driver code.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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.
+
+**/
+
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Protocol/AcpiTable.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmEndOfDxe.h>
+#include <Protocol/SmmSwDispatch2.h>
+
+#define ACPI_DEBUG_STR      "INTEL ACPI DEBUG"
+
+//
+// ASL NAME structure
+//
+#pragma pack(1)
+typedef struct {
+  UINT8  NameOp;            // Byte [0]=0x08:NameOp.
+  UINT32 NameString;        // Byte [4:1]=Name of object.
+  UINT8  DWordPrefix;       // Byte [5]=0x0C:DWord Prefix.
+  UINT32 Value;             // 0 ; Value of named object.
+} NAME_LAYOUT;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct {
+  UINT8  Signature[16];     // "INTEL ACPI DEBUG"
+  UINT32 BufferSize;        // Total size of Acpi Debug buffer including header structure
+  UINT32 Head;              // Current buffer pointer for SMM to print out
+  UINT32 Tail;              // Current buffer pointer for ASL to input
+  UINT8  SmiTrigger;        // Value to trigger the SMI via B2 port
+  UINT8  Wrap;              // If current Tail < Head
+  UINT8  SmmVersion;        // If SMM version
+  UINT8  Truncate;          // If the input from ASL > MAX_BUFFER_SIZE
+} ACPI_DEBUG_HEAD;
+#pragma pack()
+
+#define AD_SIZE             sizeof (ACPI_DEBUG_HEAD) // This is 0x20
+
+#define MAX_BUFFER_SIZE     32
+
+UINT32                      mBufferEnd = 0;
+ACPI_DEBUG_HEAD             *mAcpiDebug = NULL;
+
+EFI_SMM_SYSTEM_TABLE2       *mSmst = NULL;
+
+/**
+  Patch and load ACPI table.
+
+  @param[in] AcpiDebugAddress   Address of Acpi debug memory buffer.
+  @param[in] BufferIndex        Index that starts after the Acpi Debug head.
+  @param[in] BufferEnd          End of Acpi debug memory buffer.
+
+**/
+VOID
+PatchAndLoadAcpiTable (
+  IN ACPI_DEBUG_HEAD            *AcpiDebugAddress,
+  IN UINT32                     BufferIndex,
+  IN UINT32                     BufferEnd
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  UINTN                         Size;
+  EFI_ACPI_DESCRIPTION_HEADER   *TableHeader;
+  UINTN                         TableKey;
+  UINT8                         *CurrPtr;
+  UINT32                        *Signature;
+  NAME_LAYOUT                   *NamePtr;
+  UINT8                         UpdateCounter;
+
+  Status = GetSectionFromFv (
+             &gEfiCallerIdGuid,
+             EFI_SECTION_RAW,
+             0,
+             (VOID **) &TableHeader,
+             &Size
+             );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // This is Acpi Debug SSDT. Acpi Debug should be enabled if we reach here so load the table.
+  //
+  ASSERT (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId == SIGNATURE_64 ('A', 'D', 'e', 'b', 'T', 'a', 'b', 'l'));
+
+  //
+  // Patch some pointers for the ASL code before loading the SSDT.
+  //
+
+  //
+  // Count pointer updates, so we can stop after all three pointers are patched.
+  //
+  UpdateCounter = 1;
+  for (CurrPtr = (UINT8 *) TableHeader; CurrPtr <= ((UINT8 *) TableHeader + TableHeader->Length) && UpdateCounter < 4; CurrPtr++) {
+    Signature = (UINT32 *) (CurrPtr + 1);
+    //
+    // patch DPTR (address of Acpi debug memory buffer)
+    //
+    if ((*CurrPtr == AML_NAME_OP) && *Signature == SIGNATURE_32 ('D', 'P', 'T', 'R')) {
+      NamePtr = (NAME_LAYOUT *) CurrPtr;
+      NamePtr->Value  = (UINT32) (UINTN) AcpiDebugAddress;
+      UpdateCounter++;
+    }
+    //
+    // patch EPTR (end of Acpi debug memory buffer)
+    //
+    if ((*CurrPtr == AML_NAME_OP) && *Signature == SIGNATURE_32 ('E', 'P', 'T', 'R')) {
+      NamePtr = (NAME_LAYOUT *) CurrPtr;
+      NamePtr->Value  = BufferEnd;
+      UpdateCounter++;
+    }
+    //
+    // patch CPTR (used as an index that starts after the Acpi Debug head)
+    //
+    if ((*CurrPtr == AML_NAME_OP) && *Signature == SIGNATURE_32 ('C', 'P', 'T', 'R')) {
+      NamePtr = (NAME_LAYOUT *) CurrPtr;
+      NamePtr->Value  = BufferIndex;
+      UpdateCounter++;
+    }
+  }
+
+  //
+  // Add the table
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  TableKey = 0;
+  Status = AcpiTable->InstallAcpiTable (
+                        AcpiTable,
+                        TableHeader,
+                        Size,
+                        &TableKey
+                        );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+Done:
+  gBS->FreePool (TableHeader);
+  return ;
+}
+
+/**
+  Allocate Acpi Debug memory.
+
+  @param[out] BufferSize    Pointer to Acpi debug memory buffer size.
+
+  @return Address of Acpi debug memory buffer. 0 if PcdAcpiDebugEnable is FALSE.
+
+**/
+EFI_PHYSICAL_ADDRESS
+AllocateAcpiDebugMemory (
+  OUT UINT32           *BufferSize
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PHYSICAL_ADDRESS AcpiDebugAddress;
+  UINTN                PagesNum;
+
+  AcpiDebugAddress = 0;
+  *BufferSize = 0;
+
+  if (PcdGetBool (PcdAcpiDebugEnable)) {
+    //
+    // Reserve memory to store Acpi Debug data.
+    //
+    AcpiDebugAddress = 0xFFFFFFFF;
+    PagesNum = EFI_SIZE_TO_PAGES (PcdGet32 (PcdAcpiDebugBufferSize));
+    Status = gBS->AllocatePages (
+                    AllocateMaxAddress,
+                    EfiReservedMemoryType,
+                    PagesNum,
+                    &AcpiDebugAddress
+                    );
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      return 0;
+    }
+
+    DEBUG ((DEBUG_INFO, "AcpiDebugAddress - 0x%08x\n", AcpiDebugAddress));
+
+    Status = PcdSet32S (PcdAcpiDebugAddress, (UINT32) AcpiDebugAddress);
+    ASSERT_EFI_ERROR (Status);
+
    if (EFI_ERROR (Status)) {
+      gBS->FreePages (AcpiDebugAddress, PagesNum);
+      return 0;
+    }
+
+    *BufferSize = PcdGet32 (PcdAcpiDebugBufferSize);
+  }
+
+  return AcpiDebugAddress;
+}
+
+/**
+  Acpi Debug EndOfDxe notification.
+
+  @param[in] Event      Event whose notification function is being invoked.
+  @param[in] Context    Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+AcpiDebugEndOfDxeNotification (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  UINT32        BufferSize;
+  UINT32        BufferIndex;
+
+  mAcpiDebug = (ACPI_DEBUG_HEAD *) (UINTN) AllocateAcpiDebugMemory (&BufferSize);
+  if (mAcpiDebug != NULL) {
+    //
+    // Init ACPI DEBUG buffer to lower case 'x'.
+    //
+    SetMem ((VOID *) mAcpiDebug, BufferSize, 0x78);
+
+    //
+    // Clear header of AD_SIZE bytes.
+    //
+    ZeroMem ((VOID *) mAcpiDebug, AD_SIZE);
+
+    //
+    // Write a signature to the first line of the buffer, "INTEL ACPI DEBUG".
+    //
+    CopyMem ((VOID *) mAcpiDebug, ACPI_DEBUG_STR, sizeof (ACPI_DEBUG_STR) - 1);
+
+    BufferIndex = (UINT32) (UINTN) mAcpiDebug;
+    mBufferEnd = BufferIndex + BufferSize;
+
+    //
+    // Leave the Index after the Acpi Debug head.
+    //
+    BufferIndex += AD_SIZE;
+
+    //
+    // Patch and Load the SSDT ACPI Tables.
+    //
+    PatchAndLoadAcpiTable (mAcpiDebug, BufferIndex, mBufferEnd);
+
+    mAcpiDebug->Head = BufferIndex;
+    mAcpiDebug->Tail = BufferIndex;
+    mAcpiDebug->BufferSize = BufferSize;
+  }
+
+  //
+  // Close event, so it will not be invoked again.
+  //
+  gBS->CloseEvent (Event);
+
+  return ;
+}
+
+/**
+  Initialize ACPI Debug.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The driver initializes correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeAcpiDebugDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS            Status;
+  EFI_EVENT             EndOfDxeEvent;
+
+  //
+  // Register EndOfDxe notification
+  // that point could ensure the Acpi Debug related PCDs initialized.
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  AcpiDebugEndOfDxeNotification,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Software SMI callback for ACPI Debug which is called from ACPI method.
+
+  @param[in]      DispatchHandle    The unique handle assigned to this handler by SmiHandlerRegister().
+  @param[in]      Context           Points to an optional handler context which was specified when the
+                                    handler was registered.
+  @param[in, out] CommBuffer        A pointer to a collection of data in memory that will
+                                    be conveyed from a non-SMM environment into an SMM environment.
+  @param[in, out] CommBufferSize    The size of the CommBuffer.
+
+  @retval EFI_SUCCESS               The interrupt was handled successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiDebugSmmCallback (
+  IN EFI_HANDLE     DispatchHandle,
+  IN CONST VOID     *Context,
+  IN OUT VOID       *CommBuffer,
+  IN OUT UINTN      *CommBufferSize
+  )
+{
+  UINT8             Buffer[MAX_BUFFER_SIZE];
+
+  //
+  // Validate the fields in mAcpiDebug to ensure there is no harm to SMI handler.
+  // mAcpiDebug is below 4GB and the start address of whole buffer.
+  //
+  if ((mAcpiDebug->BufferSize != (mBufferEnd - (UINT32) (UINTN) mAcpiDebug)) ||
+      (mAcpiDebug->Head < (UINT32) ((UINTN) mAcpiDebug + AD_SIZE)) ||
+      (mAcpiDebug->Head > mBufferEnd) ||
+      (mAcpiDebug->Tail < (UINT32) ((UINTN) mAcpiDebug + AD_SIZE)) ||
+      (mAcpiDebug->Tail > mBufferEnd)) {
+    //
+    // If some fields in mAcpiDebug are invaid, return directly.
+    //
+    return EFI_SUCCESS;
+  }
+
+  if (!(BOOLEAN)mAcpiDebug->Wrap && ((mAcpiDebug->Head >= (UINT32) ((UINTN) mAcpiDebug + AD_SIZE))
+    && (mAcpiDebug->Head < mAcpiDebug->Tail))){
+    //
+    // If curent ----- buffer + 020
+    //                 ...
+    //                 ... Head
+    //                 ... Data for SMM print
+    //                 ... Tail
+    //                 ... Vacant for ASL input
+    //           ----- buffer end
+    //
+    // skip NULL block
+    //
+    while ((*(CHAR8 *) (UINTN) mAcpiDebug->Head == '\0') && (mAcpiDebug->Head < mAcpiDebug->Tail)) {
+      mAcpiDebug->Head ++;
+    }
+
+    if (mAcpiDebug->Head < mAcpiDebug->Tail) {
+      ZeroMem (Buffer, MAX_BUFFER_SIZE);
+      AsciiStrnCpyS ((CHAR8 *) Buffer, MAX_BUFFER_SIZE, (CHAR8 *) (UINTN) mAcpiDebug->Head, MAX_BUFFER_SIZE - 1);
+
+      DEBUG ((DEBUG_INFO | DEBUG_ERROR, "%a%a\n", Buffer, (BOOLEAN) mAcpiDebug->Truncate ? "..." : ""));
+      mAcpiDebug->Head += MAX_BUFFER_SIZE;
+
+      if (mAcpiDebug->Head >= (mAcpiDebug->Tail)) {
+        //
+        // When head == tail, we do nothing in handler.
+        //
+        mAcpiDebug->Head = mAcpiDebug->Tail;
+      }
+    }
+  } else if ((BOOLEAN) mAcpiDebug->Wrap && ((mAcpiDebug->Head > mAcpiDebug->Tail)
+    && (mAcpiDebug->Head < (UINT32) ((UINTN) mAcpiDebug + mAcpiDebug->BufferSize)))){
+    //
+    // If curent ----- buffer + 020
+    //                 ... Tail
+    //                 ... Vacant for ASL input
+    //                 ... Head
+    //                 ... Data for SMM print
+    //           ----- buffer end
+    //
+    while ((*(CHAR8 *) (UINTN) mAcpiDebug->Head == '\0') && (mAcpiDebug->Head < (UINT32) ((UINTN) mAcpiDebug + mAcpiDebug->BufferSize))) {
+      mAcpiDebug->Head ++;
+    }
+    if (mAcpiDebug->Head < (UINT32) ((UINTN) mAcpiDebug + mAcpiDebug->BufferSize)){
+      ZeroMem (Buffer, MAX_BUFFER_SIZE);
+      AsciiStrnCpyS ((CHAR8 *) Buffer, MAX_BUFFER_SIZE, (CHAR8 *) (UINTN) mAcpiDebug->Head, MAX_BUFFER_SIZE - 1);
+      DEBUG ((DEBUG_INFO | DEBUG_ERROR, "%a%a\n", Buffer, (BOOLEAN) mAcpiDebug->Truncate ? "..." : ""));
+      mAcpiDebug->Head += MAX_BUFFER_SIZE;
+
+      if (mAcpiDebug->Head >= (UINT32) ((UINTN) mAcpiDebug + mAcpiDebug->BufferSize)) {
+        //
+        // We met end of buffer.
+        //
+        mAcpiDebug->Wrap = 0;
+        mAcpiDebug->Head = (UINT32) ((UINTN) mAcpiDebug + AD_SIZE);
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Acpi Debug SmmEndOfDxe notification.
+
+  @param[in] Protocol   Points to the protocol's unique identifier.
+  @param[in] Interface  Points to the interface instance.
+  @param[in] Handle     The handle on which the interface was installed.
+
+  @retval EFI_SUCCESS   Notification runs successfully.
+
+ **/
+EFI_STATUS
+EFIAPI
+AcpiDebugSmmEndOfDxeNotification (
+  IN CONST EFI_GUID     *Protocol,
+  IN VOID               *Interface,
+  IN EFI_HANDLE         Handle
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL     *SwDispatch;
+  EFI_SMM_SW_REGISTER_CONTEXT       SwContext;
+  EFI_HANDLE                        SwHandle;
+
+  AcpiDebugEndOfDxeNotification (NULL, NULL);
+
+  if (mAcpiDebug != NULL) {
+    //
+    // Get the Sw dispatch protocol and register SMI callback function.
+    //
+    SwDispatch = NULL;
+    Status = mSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID **) &SwDispatch);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    SwContext.SwSmiInputValue = (UINTN) -1;
+    Status = SwDispatch->Register (SwDispatch, AcpiDebugSmmCallback, &SwContext, &SwHandle);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    mAcpiDebug->SmiTrigger = (UINT8) SwContext.SwSmiInputValue;
+    mAcpiDebug->SmmVersion = 1;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize ACPI Debug.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The driver initializes correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeAcpiDebugSmm (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+  VOID                      *Registration;
+  EFI_SMM_BASE2_PROTOCOL    *SmmBase2;
+  BOOLEAN                   InSmm;
+
+  Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **) &SmmBase2);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  Status = SmmBase2->InSmm (SmmBase2, &InSmm);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (InSmm);

+  if (!InSmm) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = SmmBase2->GetSmstLocation (SmmBase2, &mSmst);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Register SmmEndOfDxe notification
+  // that point could ensure the Acpi Debug related PCDs initialized.
+  //
+  Registration = NULL;
+  Status = mSmst->SmmRegisterProtocolNotify (
+                    &gEfiSmmEndOfDxeProtocolGuid,
+                    AcpiDebugSmmEndOfDxeNotification,
+                    &Registration
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf
new file mode 100644
index 0000000..210fcd8
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf
@@ -0,0 +1,63 @@
+### @file
+# Component description file for Acpi debug module.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# 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                    = 0x00010005
+  BASE_NAME                      = AcpiDebugDxe
+  FILE_GUID                      = EC98FF95-242C-4513-B1BC-69FA24111C58
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeAcpiDebugDxe
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF
+#
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DebugLib
+  PcdLib
+  DxeServicesLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[Pcd]
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable      ## CONSUMES
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize  ## CONSUMES
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress     ## PRODUCES
+
+[Sources]
+  AcpiDebug.c
+  AcpiDebug.asl
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid         ## CONSUMES
+  gEfiSmmBase2ProtocolGuid          ## CONSUMES # only for SMM version
+  gEfiSmmSwDispatch2ProtocolGuid    ## CONSUMES # only for SMM version
+  gEfiSmmEndOfDxeProtocolGuid       ## NOTIFY # only for SMM version
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid        ## CONSUMES ## Event
+
+[Depex]
+  gEfiAcpiTableProtocolGuid
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf
new file mode 100644
index 0000000..8cc0a6c
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf
@@ -0,0 +1,65 @@
+### @file
+# Component description file for Acpi Debug module.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# 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                    = 0x00010005
+  BASE_NAME                      = AcpiDebugSmm
+  FILE_GUID                      = 9069C144-0A7E-41ef-9C07-418BCA9BF939
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = InitializeAcpiDebugSmm
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF
+#
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DebugLib
+  PcdLib
+  DxeServicesLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[Pcd]
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable      ## CONSUMES
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize  ## CONSUMES
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress     ## PRODUCES
+
+[Sources]
+  AcpiDebug.c
+  AcpiDebug.asl
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid         ## CONSUMES
+  gEfiSmmBase2ProtocolGuid          ## CONSUMES
+  gEfiSmmSwDispatch2ProtocolGuid    ## CONSUMES
+  gEfiSmmEndOfDxeProtocolGuid       ## NOTIFY
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid        ## CONSUMES ## Event # only for DXE version
+
+[Depex]
+  gEfiAcpiTableProtocolGuid AND
+  gEfiSmmBase2ProtocolGuid AND
+  gEfiSmmSwDispatch2ProtocolGuid
diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/Readme.txt b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/Readme.txt
new file mode 100644
index 0000000..71284ec
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/Readme.txt
@@ -0,0 +1,31 @@
+ACPI Debug feature - an alternative to Port 80 and WinDBG
+
+How it works:
+  Acpi Debug does this:
+  Opens a 64kb memory buffer during POST.
+  Patches the buffer address in SSDT ASL code.
+  Save the address in gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress for user reference.
+  Write strings or numbers to the buffer from ASL code with the ADBG method.
+
+How to use it:
+  1. Enable it by set gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable to TRUE.
+  2. The ACPI ASL code must be instrumented with the debug method.
+     Strings up to 32 characters (shorter strings will be padded with Zero's, longer strings will be truncated)
+     Examples:
+       ADBG("This is a test.")
+       ADBG(Arg0)
+
+  DXE version: The bios engineer will read the strings from the buffer on the target machine with read/write memory utility.
+  SMM version: Check debug serial that would show debug strings.
+
+  Sample code for ADBG:
+    External (MDBG, MethodObj)
+    Method (ADBG, 1, Serialized)
+    {
+      If (CondRefOf (MDBG)) // Check if ACPI Debug SSDT is loaded
+      {
+        Return (MDBG (Arg0))
+      }
+      Return (0)
+    }
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec
index fb27647..de80ae7 100644
--- a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+++ b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec
@@ -6,7 +6,7 @@
 # INF files to generate AutoGen.c and AutoGen.h files
 # for the build infrastructure.
 #
-# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
 #
 # This program and the accompanying materials are licensed and made available under
 # the terms and conditions of the BSD License which accompanies this distribution.
@@ -146,11 +146,17 @@ gAdvancedFeaturePkgTokenSpaceGuid         =  {0xa8514688, 0x6693, 0x4ab5, {0xaa,
 
 [PcdsFixedAtBuild]
   gAdvancedFeaturePkgTokenSpaceGuid.PcdMaxSOLChannels|0x3|UINT8|0x40000009
+  ## This PCD specifies AcpiDebug feature is enable/disable.
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable|FALSE|BOOLEAN|0x00000012
+  ## This PCD specifies AcpiDebug buffer size.
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize|0x10000|UINT32|0x00000013
 
 [PcdsDynamic, PcdsDynamicEx]
   gAdvancedFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress|0xCA2|UINT16|0x90000022
   gAdvancedFeaturePkgTokenSpaceGuid.PcdFRB2EnabledFlag|TRUE|BOOLEAN|0x10000030
   gAdvancedFeaturePkgTokenSpaceGuid.PcdFRBTimeoutValue|360|UINT16|0x10000040
+  ## This PCD specifies AcpiDebug buffer address
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress|0|UINT32|0x00000014
 
 [PcdsFeatureFlag]
   gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable          |FALSE|BOOLEAN|0xF00000A1
diff --git a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
index 4fcf9ac..df09eb5 100644
--- a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
+++ b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
@@ -1,7 +1,7 @@
 ## @file
 #  Platform description.
 #
-# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
 #
 # This program and the accompanying materials are licensed and made available under
 # the terms and conditions of the BSD License which accompanies this distribution.
@@ -155,3 +155,5 @@
   AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.inf
   AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.inf
 
+  AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf
+  AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf
\ No newline at end of file
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-04-12  2:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-04-08  4:50 [edk2-platforms/devel-MinPlatform][Patch v2] AdvancedFeaturePkg/AcpiDebug: Add new AcpiDebug modules Dong, Eric
2019-04-12  2:03 ` [edk2-devel] " Kubacki, Michael A

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox