From: "levi.yun" <yeoreum.yun@arm.com>
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 [thread overview]
Message-ID: <20240510122257.2457623-5-yeoreum.yun@arm.com> (raw)
In-Reply-To: <20240510122257.2457623-1-yeoreum.yun@arm.com>
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 <zhiguang.liu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhichao Gao <zhichao.gao@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: levi.yun <yeoreum.yun@arm.com>
---
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/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
index e62366116cb7d90c9202c6f0fd17b3306efd7800..9c2e2b703d267fb3ed9d631469d907106e7d4278 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.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..b41f110f6aa18f4f6806c849737f0b540a11152f 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -616,6 +616,27 @@ ParseAcpiDsdt (
IN UINT8 AcpiTableRevision
);
+/**
+ 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/EinjParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c
new file mode 100644
index 0000000000000000000000000000000000000000..508b082f908d76dc46e6ce92d9b4aa6c15998f95
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.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 <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+
+#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[] = {
+ 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 = *(UINT8 *)Ptr;
+
+ if (Flags != 0) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Injection Flags must be zero...");
+ }
+}
+
+/**
+ An ACPI_PARSER array describing the ACPI EINJ Table.
+**/
+STATIC CONST ACPI_PARSER EinjParser[] = {
+ PARSE_ACPI_HEADER (&mAcpiHdrInfo),
+ { L"Injection Header Size", 4, 36, L"%d", NULL, (VOID **)&mEinjInjectionHdrSize,
+ 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 **)&mEinjInjectionEntryCnt,
+ 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 = *(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_REVISION) {
+ MaxInjectionAction = EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS;
+ } else {
+ MaxInjectionAction = 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)...", InjectionAction);
+ }
+}
+
+/**
+ 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 = *Ptr;
+
+ if (*mAcpiHdrInfo.Revision <= EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION) {
+ 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 = (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *)Ptr;
+
+ if ((RegisterRegion->AddressSpaceId != EFI_ACPI_6_5_SYSTEM_MEMORY) &&
+ (RegisterRegion->AddressSpaceId != 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 = *Ptr;
+
+ switch (InjectionAction) {
+ case EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION:
+ ActionName = L"BEGIN_INJECTION_OPERATION";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE:
+ ActionName = L"GET_TRIGGER_ERROR_ACTION_TABLE";
+ break;
+ case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE:
+ ActionName = L"SET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_ERROR_TYPE:
+ ActionName = L"GET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_END_OPERATION:
+ ActionName = L"END_OPERATION";
+ break;
+ case EFI_ACPI_6_5_EINJ_EXECUTE_OPERATION:
+ ActionName = L"EXECUTE_OPERATION";
+ break;
+ case EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS:
+ ActionName = L"CHECK_BUSY_STATUS";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS:
+ ActionName = L"GET_COMMAND_STATUS";
+ break;
+ case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS:
+ ActionName = L"SET_ERROR_TYPE_WITH_ADDRESS";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS:
+ ActionName = L"GET_EXECUTE_OPERATION_TIMINGS";
+ break;
+ case EFI_ACPI_6_5_EINJ_EINJV2_SET_ERROR_TYPE:
+ ActionName = L"EINJV2_SET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE:
+ ActionName = L"EINJV2_GET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_TRIGGER_ERROR:
+ ActionName = L"TRIGGER_ERROR";
+ break;
+ default:
+ IncrementErrorCount ();
+ ActionName = 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 = *Ptr;
+
+ if (Inst < ARRAY_SIZE (InstNameTable)) {
+ InstName = InstNameTable[Inst];
+ } else {
+ IncrementErrorCount ();
+ InstName = L"UNKNOWN";
+ }
+
+ Print (L"%s(0x%x)", InstName, Inst);
+}
+
+/**
+ An ACPI_PARSER array describing the EINJ Injection instruction entry.
+**/
+STATIC CONST ACPI_PARSER EinjInjectionInstEntryParser[] = {
+ { 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 = ParseAcpi (
+ TRUE,
+ 0,
+ "EINJ",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (EinjParser)
+ );
+
+ // Validate Error Source Descriptors Count.
+ if ((mEinjInjectionHdrSize == NULL) || (*mEinjInjectionHdrSize != Offset)) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Injection Header...\n");
+ return;
+ }
+
+ if ((mEinjInjectionEntryCnt == NULL) || (*mEinjInjectionEntryCnt == 0)) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Injection Instruction Entry should be presented...\n");
+ return;
+ }
+
+ InjInstEntrySize = sizeof (EFI_ACPI_6_5_EINJ_INJECTION_INSTRUCTION_ENTRY);
+
+ if ((*mEinjInjectionEntryCnt * InjInstEntrySize) != (AcpiTableLength - Offset)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Incorrect count for Injection Instruction Entry.\n" \
+ L" Injection Entry Count= %d.\n" \
+ L" Present Count= %d.\n",
+ *mEinjInjectionEntryCnt,
+ (AcpiTableLength - Offset) / InjInstEntrySize
+ );
+ }
+
+ while (Offset < AcpiTableLength) {
+ InjInstEntryPtr = Ptr + Offset;
+
+ // Get Injection Instruction Entry.
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Injection Instruction Entry",
+ InjInstEntryPtr,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (EinjInjectionInstEntryParser)
+ );
+
+ Offset += InjInstEntrySize;
+ } // while
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index 0bdf068fe07614727e690897d9c76a5686be18b5..4a90372d81ff1eb2caeb3a477d058d08ffc1bdbf 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -54,6 +54,7 @@ ACPI_TABLE_PARSER ParserList[] = {
{ 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]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-05-10 12:23 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-10 12:22 [edk2-devel] [PATCH v1 0/4] Add EINJ table parser levi.yun
2024-05-10 12:22 ` [edk2-devel] [PATCH v1 1/4] MdePkg/Include/IndustryStandard: Update SET_ERROR_TYPE_WITH_ADDRESS Error Injection Actions levi.yun
2024-05-10 12:22 ` [edk2-devel] [PATCH v1 2/4] MdePkg/Include/IndustryStandard: Update GET_EXECUTE_OPERATION_TIMINGS " levi.yun
2024-05-10 12:22 ` [edk2-devel] [PATCH v1 3/4] MdePkg/Include/IndustryStandard: Update EINJ information according to ACPI 6.5 levi.yun
2024-05-10 12:22 ` levi.yun [this message]
2024-05-13 7:41 ` [edk2-devel] [PATCH v1 0/4] Add EINJ table parser PierreGondois
2024-05-23 8:52 ` levi.yun
2024-06-03 6:36 ` levi.yun
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=20240510122257.2457623-5-yeoreum.yun@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