From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id 2C86D740038 for ; Fri, 10 May 2024 12:23:07 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=cyWzta6bX6DdNSumvMOoCSr3gFewb33qx6EYb2cOTxc=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1715343785; v=1; b=Uf7M5K65ZQPKPxGB/yeYpVEGCkhwBcxwKRQe2dqwoA6m4vGDosjGELGWZg/sLPR5wBc3RfWC 1FAARL1PDDVjkzCocoOn3eBFdUc8Y30iI61oA6lea/oGrw9eM2qDaH7uiHCLBJGZC4f2S8vTZA7 t+B2smw5ljcMeNQsjzof8n/RJQM8UhLk6bOMtCI8hxza4i5obvfDvGuNLT+z+qYWzFXiI5felO6 hSz1eB4c11XLW4EOfbQ8EiTFfkwilqKrxLGn6Yap60cqCcI2FiU0j0MwHTnSoOScXIKhqF8q+kq JyJ/LgDjwqILsb7mc/wa0aNgiBVjK4MNHdGvnX1XvodsA== X-Received: by 127.0.0.2 with SMTP id 7tosYY7687511xcaublvU4Cl; Fri, 10 May 2024 05:23:05 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web10.11340.1715343784969588842 for ; Fri, 10 May 2024 05:23:05 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0C2C7106F; Fri, 10 May 2024 05:23:30 -0700 (PDT) X-Received: from e129823.cambridge.arm.com (e129823.arm.com [10.1.197.6]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 841CA3F6A8; Fri, 10 May 2024 05:23:03 -0700 (PDT) From: "levi.yun" To: devel@edk2.groups.io Cc: yeoreum.yun@arm.com, sami.mujawar@arm.com, pierre.gondois@arm.com, zhiguang.liu@intel.com, dandan.bi@intel.com, gaoliming@byosoft.com.cn, zhichao.gao@intel.com, nd@arm.com Subject: [edk2-devel] [PATCH v1 4/4] ShellPkg/Acpiview: Add EINJ Parser Date: Fri, 10 May 2024 13:22:57 +0100 Message-Id: <20240510122257.2457623-5-yeoreum.yun@arm.com> In-Reply-To: <20240510122257.2457623-1-yeoreum.yun@arm.com> References: <20240510122257.2457623-1-yeoreum.yun@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Fri, 10 May 2024 05:23:05 -0700 Resent-From: yeoreum.yun@arm.com Reply-To: devel@edk2.groups.io,yeoreum.yun@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: oNtjXgzcGMwMR5abZI5C69Six7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=Uf7M5K65; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=arm.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io Add a new parser for the Error Injection Table (EINJ). The EINJ table provides machinism through which OSPM can inject hardware errors to the platform without requiring platform specific OSPM software. Cc: Zhiguang Liu Cc: Dandan Bi Cc: Liming Gao Cc: Zhichao Gao Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: levi.yun --- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib= .inf | 1 + ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h = | 21 ++ ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c = | 358 ++++++++++++++++++++ ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib= .c | 1 + 4 files changed, 381 insertions(+) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiVi= ewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShell= AcpiViewCommandLib.inf index e62366116cb7d90c9202c6f0fd17b3306efd7800..9c2e2b703d267fb3ed9d63146= 9d907106e7d4278 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.inf @@ -33,6 +33,7 @@ [Sources.common] Parsers/Bgrt/BgrtParser.c Parsers/Dbg2/Dbg2Parser.c Parsers/Dsdt/DsdtParser.c + Parsers/Einj/EinjParser.c Parsers/Erst/ErstParser.c Parsers/Facs/FacsParser.c Parsers/Fadt/FadtParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/= ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index 6468fe5d8cddf02d67f2d4705369064046c4a9a1..b41f110f6aa18f4f6806c8497= 37f0b540a11152f 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -616,6 +616,27 @@ ParseAcpiDsdt ( IN UINT8 AcpiTableRevision ); =20 +/** + This function parses the EINJ table. + When trace is enabled this function parses the EINJ table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiEinj ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + /** This function parses the ACPI ERST table. When trace is enabled this function parses the ERST table and diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/Ei= njParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/Ei= njParser.c new file mode 100644 index 0000000000000000000000000000000000000000..508b082f908d76dc46e6ce92d= 9b4aa6c15998f95 --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParse= r.c @@ -0,0 +1,358 @@ +/** @file + EINJ table parser + + Copyright (c) 2024, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - ACPI 6.5, Table 18.3.2 ACPI Error Source +**/ + +#include +#include + +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" + +STATIC ACPI_DESCRIPTION_HEADER_INFO mAcpiHdrInfo; +STATIC UINT32 *mEinjInjectionHdrSize; +STATIC UINT32 *mEinjInjectionEntryCnt; + +STATIC CONST CHAR16 *InstNameTable[] =3D { + L"READ_REGISTER", + L"READ_REGISTER_VALUE", + L"WRITE_REGISTER", + L"WRITE_REGISTER_VALUE", + L"NOOP", +}; + +/** + This function validates the flags field in the EINJ injection header. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateInjectionFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 Flags; + + Flags =3D *(UINT8 *)Ptr; + + if (Flags !=3D 0) { + IncrementErrorCount (); + Print (L"\nERROR: Injection Flags must be zero..."); + } +} + +/** + An ACPI_PARSER array describing the ACPI EINJ Table. +**/ +STATIC CONST ACPI_PARSER EinjParser[] =3D { + PARSE_ACPI_HEADER (&mAcpiHdrInfo), + { L"Injection Header Size", 4, 36, L"%d", NULL, (VOID **)&mEi= njInjectionHdrSize, + NULL, NULL }, + { L"Injection Flags", 1, 40, L"0x%x", NULL, NULL, = ValidateInjectionFlags,NULL }, + { L"Reserved", 3, 41, NULL, NULL, NULL, = NULL, NULL }, + { L"Injection Entry Count", 4, 44, L"%d", NULL, (VOID **)&mEi= njInjectionEntryCnt, + NULL, NULL }, + /// Injection Action Table. + /// ... +}; + +/** + This function validates the injection action field in + the EINJ injection instruction entry. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateInjectionAction ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 InjectionAction; + UINT8 MaxInjectionAction; + + InjectionAction =3D *(UINT8 *)Ptr; + + /** + * EFI_ACPI_6_5_EINJ_TRIGGER_ERROR is only used Trigger Action Table + * not used in Injection Action Table in EINJ. + * Cf ACPI 6.5 Table 18.24 - Error Injection Table + * Cf ACPI 6.5 Table 18.36 - Trigger Error Action + */ + if (*mAcpiHdrInfo.Revision < EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISI= ON) { + MaxInjectionAction =3D EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMIN= GS; + } else { + MaxInjectionAction =3D EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE; + } + + if ((InjectionAction < EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION) || + (InjectionAction > MaxInjectionAction)) + { + IncrementErrorCount (); + Print (L"\nERROR: Invalid Injection Action(0x%x)...", InjectionActio= n); + } +} + +/** + This function validates the instruction field in + the EINJ injection instruction entry. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateInstruction ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 Inst; + + Inst =3D *Ptr; + + if (*mAcpiHdrInfo.Revision <=3D EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REV= ISION) { + if (Inst > EFI_ACPI_6_5_EINJ_NOOP) { + IncrementErrorCount (); + Print (L"\nERROR: Invalid Instruction(0x%x)...", Inst); + } + } +} + +/** + This function validates the register region field in + the EINJ injection instruction entry. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateRegisterRegion ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *RegisterRegion; + + RegisterRegion =3D (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *)Ptr; + + if ((RegisterRegion->AddressSpaceId !=3D EFI_ACPI_6_5_SYSTEM_MEMORY) &= & + (RegisterRegion->AddressSpaceId !=3D EFI_ACPI_6_5_SYSTEM_IO)) + { + IncrementErrorCount (); + Print (L"\nERROR: Register Region Must be SYSTEM_MEMORY or SYSTEM_IO= ..."); + } +} + +/** + Dumps the injection action fields in injection instruction entry. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpInjectionInstAction ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + UINT8 InjectionAction; + CONST CHAR16 *ActionName; + + InjectionAction =3D *Ptr; + + switch (InjectionAction) { + case EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION: + ActionName =3D L"BEGIN_INJECTION_OPERATION"; + break; + case EFI_ACPI_6_5_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE: + ActionName =3D L"GET_TRIGGER_ERROR_ACTION_TABLE"; + break; + case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE: + ActionName =3D L"SET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_GET_ERROR_TYPE: + ActionName =3D L"GET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_END_OPERATION: + ActionName =3D L"END_OPERATION"; + break; + case EFI_ACPI_6_5_EINJ_EXECUTE_OPERATION: + ActionName =3D L"EXECUTE_OPERATION"; + break; + case EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS: + ActionName =3D L"CHECK_BUSY_STATUS"; + break; + case EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS: + ActionName =3D L"GET_COMMAND_STATUS"; + break; + case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS: + ActionName =3D L"SET_ERROR_TYPE_WITH_ADDRESS"; + break; + case EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS: + ActionName =3D L"GET_EXECUTE_OPERATION_TIMINGS"; + break; + case EFI_ACPI_6_5_EINJ_EINJV2_SET_ERROR_TYPE: + ActionName =3D L"EINJV2_SET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE: + ActionName =3D L"EINJV2_GET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_TRIGGER_ERROR: + ActionName =3D L"TRIGGER_ERROR"; + break; + default: + IncrementErrorCount (); + ActionName =3D L"UNKNOWN"; + } + + Print (L"%s(0x%x)", ActionName, InjectionAction); +} + +/** + Dumps the instruction fields in injection instruction entry. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpInstruction ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + UINT8 Inst; + CONST CHAR16 *InstName; + + Inst =3D *Ptr; + + if (Inst < ARRAY_SIZE (InstNameTable)) { + InstName =3D InstNameTable[Inst]; + } else { + IncrementErrorCount (); + InstName =3D L"UNKNOWN"; + } + + Print (L"%s(0x%x)", InstName, Inst); +} + +/** + An ACPI_PARSER array describing the EINJ Injection instruction entry. +**/ +STATIC CONST ACPI_PARSER EinjInjectionInstEntryParser[] =3D { + { L"Injection Action", 1, 0, NULL, DumpInjectionInstAction, NULL, + ValidateInjectionAction, NULL }, + { L"Instruction", 1, 1, NULL, DumpInstruction, NULL, + ValidateInstruction, NULL }, + { L"Flags", 1, 2, L"0x%x", NULL, NULL,= NULL, NULL }, + { L"Reserved", 1, 3, NULL, NULL, NULL,= NULL, NULL }, + { L"Register Region", 12, 4, NULL, DumpGas, NULL, + ValidateRegisterRegion, NULL }, + { L"Value", 8, 16, L"0x%x", NULL, NULL,= NULL, NULL }, + { L"Mask", 8, 24, L"0x%x", NULL, NULL,= NULL, NULL }, +}; + +/** + This function parses the EINJ table. + When trace is enabled this function parses the EINJ table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiEinj ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8 *InjInstEntryPtr; + UINT32 InjInstEntrySize; + + if (!Trace) { + return; + } + + Offset =3D ParseAcpi ( + TRUE, + 0, + "EINJ", + Ptr, + AcpiTableLength, + PARSER_PARAMS (EinjParser) + ); + + // Validate Error Source Descriptors Count. + if ((mEinjInjectionHdrSize =3D=3D NULL) || (*mEinjInjectionHdrSize !=3D= Offset)) { + IncrementErrorCount (); + Print (L"ERROR: Invalid Injection Header...\n"); + return; + } + + if ((mEinjInjectionEntryCnt =3D=3D NULL) || (*mEinjInjectionEntryCnt =3D= =3D 0)) { + IncrementErrorCount (); + Print (L"ERROR: Injection Instruction Entry should be presented...\n= "); + return; + } + + InjInstEntrySize =3D sizeof (EFI_ACPI_6_5_EINJ_INJECTION_INSTRUCTION_E= NTRY); + + if ((*mEinjInjectionEntryCnt * InjInstEntrySize) !=3D (AcpiTableLength= - Offset)) { + IncrementErrorCount (); + Print ( + L"ERROR: Incorrect count for Injection Instruction Entry.\n" \ + L" Injection Entry Count=3D %d.\n" \ + L" Present Count=3D %d.\n", + *mEinjInjectionEntryCnt, + (AcpiTableLength - Offset) / InjInstEntrySize + ); + } + + while (Offset < AcpiTableLength) { + InjInstEntryPtr =3D Ptr + Offset; + + // Get Injection Instruction Entry. + ParseAcpi ( + TRUE, + 2, + "Injection Instruction Entry", + InjInstEntryPtr, + AcpiTableLength - Offset, + PARSER_PARAMS (EinjInjectionInstEntryParser) + ); + + Offset +=3D InjInstEntrySize; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiVi= ewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAc= piViewCommandLib.c index 0bdf068fe07614727e690897d9c76a5686be18b5..4a90372d81ff1eb2caeb3a477= d058d08ffc1bdbf 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.c @@ -54,6 +54,7 @@ ACPI_TABLE_PARSER ParserList[] =3D { { EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, = ParseAcpiDbg2 }, { EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiDsdt }, + { EFI_ACPI_6_5_ERROR_INJECTION_TABLE_SIGNATURE, = ParseAcpiEinj }, { EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE, = ParseAcpiErst }, { EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, = ParseAcpiFacs }, { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, = ParseAcpiFadt }, -- Guid("CE165669-3EF3-493F-B85D-6190EE5B9759") -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118818): https://edk2.groups.io/g/devel/message/118818 Mute This Topic: https://groups.io/mt/106019474/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-