From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: eric.dong@intel.com) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by groups.io with SMTP; Sun, 07 Apr 2019 21:50:29 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Apr 2019 21:50:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,324,1549958400"; d="scan'208";a="133843079" Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.133]) by orsmga006.jf.intel.com with ESMTP; 07 Apr 2019 21:50:27 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Cc: Hao Wu , Michael Kubacki Subject: [edk2-platforms/devel-MinPlatform][Patch v2] AdvancedFeaturePkg/AcpiDebug: Add new AcpiDebug modules. Date: Mon, 8 Apr 2019 12:50:25 +0800 Message-Id: <20190408045025.13580-1-eric.dong@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 Cc: Michael Kubacki Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Eric Dong --- .../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.
+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.
+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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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.
+# +# 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.
+# +# 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.
+# Copyright (c) 2017 - 2019, Intel Corporation. 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. @@ -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.
+# Copyright (c) 2017 - 2019, Intel Corporation. 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. @@ -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