From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR02-VE1-obe.outbound.protection.outlook.com (EUR02-VE1-obe.outbound.protection.outlook.com [40.107.2.43]) by mx.groups.io with SMTP id smtpd.web11.14025.1603295780950804717 for ; Wed, 21 Oct 2020 08:56:21 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=GmdIvJC5; spf=pass (domain: arm.com, ip: 40.107.2.43, mailfrom: sami.mujawar@arm.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qZRQL4uEZCQcW303dtiVxR735ajb//Tb1SSGIZVL/m4=; b=GmdIvJC5N8kfye7zwdSnd8vLaMWdwdlT7A3wfnMc1BbqdvB6qiQDyx+Cy3KbDnqfhoIab9HHXwpVTKJmJb6C8h4EL76Sgau+cYofiTTnH216I8W+8DJqDqZtIKJ+TxIO60vYH1K+ysDuy4+d33u7L7jkVNSSdMC810Qy5rRUy8c= Received: from MR2P264CA0178.FRAP264.PROD.OUTLOOK.COM (2603:10a6:501::17) by DB7PR08MB3579.eurprd08.prod.outlook.com (2603:10a6:10:46::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3477.23; Wed, 21 Oct 2020 15:56:17 +0000 Received: from VE1EUR03FT005.eop-EUR03.prod.protection.outlook.com (2603:10a6:501:0:cafe::8b) by MR2P264CA0178.outlook.office365.com (2603:10a6:501::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3499.18 via Frontend Transport; Wed, 21 Oct 2020 15:56:17 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; edk2.groups.io; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;edk2.groups.io; dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by VE1EUR03FT005.mail.protection.outlook.com (10.152.18.172) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3499.18 via Frontend Transport; Wed, 21 Oct 2020 15:56:17 +0000 Received: ("Tessian outbound 68da730eaaba:v64"); Wed, 21 Oct 2020 15:56:16 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 5e2128718eb81812 X-CR-MTA-TID: 64aa7808 Received: from 8d8a1dd95bc3.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 1682A227-4460-49F0-9AD0-F7FB0691D500.1; Wed, 21 Oct 2020 15:56:00 +0000 Received: from EUR05-DB8-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 8d8a1dd95bc3.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Wed, 21 Oct 2020 15:56:00 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DlUfB0EgtHTgXG3D26EyYYGBM/7gJExARvRLAaIvQEYWIQsw8apA3rWlsOjiknNKOE2mrwGpzarAypNzZTwSBsE2ZmpdKZ91ABpvKH/EaM2vfFvDRQkdb1Z0qCoa1cYPgfVI6kNNw3aF+hOAbrTGd0d8sSRcF7yxCbqzxK8etMRPq4sH/+Rf2Ln8MJWi59yxwEfuJo2j/7lFQBrH4zMUiF1I1HR89nuYOKsUTe8jUti0OBhoCkefSSE5uQak+92yQUwz4mQNFFDVYQJYD/a/DvhIIwl6XEgGjP9uLJ6plbQS/OOyn++ETfFO3rxxWFLKGheNtGFBND/POFB8b5yBwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qZRQL4uEZCQcW303dtiVxR735ajb//Tb1SSGIZVL/m4=; b=ndy7Ed4u6n1RfEY6cKeRZmjScumUPPVWZrY7REaB2OMTfK/aNp57Ka8Pt74B6JieYWMiNEw0nt9nUXzi3Iwil/WYo9/lzDlxDqviaQddWS5Zgwhf/R4qzjWBC4h6/oYFS/XRMgm1HPC43X5uNBNjRH0PCBlk+WTZidQzb9g/2Hs6lANPrQgs/NGwVQf+N1IPxnWl6Y2qWoTtT+CBMe9423lad6d0fp4b+wgBPbPKn87MUA2Ndi0cMmneYiwMPHxo7dPthQvtY1JRnXsRqezm9kFhbZUjk8seG5ZRkxuv6fC55qrsZjskGQOK3YSB4sT8OwoI0EzUt06MqjHEsUiGxw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qZRQL4uEZCQcW303dtiVxR735ajb//Tb1SSGIZVL/m4=; b=GmdIvJC5N8kfye7zwdSnd8vLaMWdwdlT7A3wfnMc1BbqdvB6qiQDyx+Cy3KbDnqfhoIab9HHXwpVTKJmJb6C8h4EL76Sgau+cYofiTTnH216I8W+8DJqDqZtIKJ+TxIO60vYH1K+ysDuy4+d33u7L7jkVNSSdMC810Qy5rRUy8c= Received: from AM7PR03CA0005.eurprd03.prod.outlook.com (2603:10a6:20b:130::15) by VI1PR08MB4431.eurprd08.prod.outlook.com (2603:10a6:803:fe::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3477.28; Wed, 21 Oct 2020 15:55:58 +0000 Received: from AM5EUR03FT041.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:130:cafe::59) by AM7PR03CA0005.outlook.office365.com (2603:10a6:20b:130::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3499.18 via Frontend Transport; Wed, 21 Oct 2020 15:55:58 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 40.67.248.234 as permitted sender) receiver=protection.outlook.com; client-ip=40.67.248.234; helo=nebula.arm.com; Received: from nebula.arm.com (40.67.248.234) by AM5EUR03FT041.mail.protection.outlook.com (10.152.17.186) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.3499.18 via Frontend Transport; Wed, 21 Oct 2020 15:55:57 +0000 Received: from AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.2044.4; Wed, 21 Oct 2020 15:55:56 +0000 Received: from AZ-NEU-EX04.Arm.com (10.251.24.32) by AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1779.2; Wed, 21 Oct 2020 15:55:55 +0000 Received: from E107187.Arm.com (10.57.51.42) by mail.arm.com (10.251.24.32) with Microsoft SMTP Server id 15.1.2044.4 via Frontend Transport; Wed, 21 Oct 2020 15:55:54 +0000 From: "Sami Mujawar" To: CC: Sami Mujawar , , , , , Subject: [PATCH v2 2/2] ShellPkg/Acpiview: AEST Parser Date: Wed, 21 Oct 2020 16:55:52 +0100 Message-ID: <20201021155552.28772-3-sami.mujawar@arm.com> X-Mailer: git-send-email 2.11.0.windows.3 In-Reply-To: <20201021155552.28772-1-sami.mujawar@arm.com> References: <20201021155552.28772-1-sami.mujawar@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-Office365-Filtering-HT: Tenant X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a1037c28-b9dd-4247-5cbc-08d875d9d897 X-MS-TrafficTypeDiagnostic: VI1PR08MB4431:|DB7PR08MB3579: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:10000;OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: t5koUfJLQoq1WFywE6BYrBro0heNf1SLKRHyOCwMwTTfydibiS641At50NiU1KdHJ2qcp1FiUE5K2SXx9sLCZkTjPdG+kOc89P/EoeXHyt102uGfwV4pxE/SjPJLb347tBvcZSZwwTZ59uTt+P7abOUKzPn2a/iBLYu1tmXpoqg4Gnj9IAUImxJZSge7S0Ihh3+83z0FeYaCWWqtk8YxmMdOoAKTfVovFKcdNW1GF05+vmyN+5QJCALbzMFdQp40cIEC/TCdjeLQxpprUL52Wn2MtRZ0MY+l40MjVp+NbNS8tXgRbH9SpOd5V0Plz+q5Y4p88gwl+TQ+iyMAXTHue7fh/B1HHfefDnt0ahtwdM92n60vwM/9TAPN/osV3SWSqwrsdmyB8MXRTunVRtkvW/QFQuiw5hZPsk3m5l7HCS/oZPH72SeDb9XHnb51p3G9x6rEE+DJvyZXRnAhnm3dZ4Byu7kAFIhx92P2eRa+BKE= X-Forefront-Antispam-Report-Untrusted: CIP:40.67.248.234;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:nebula.arm.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(4636009)(346002)(396003)(136003)(39860400002)(376002)(46966005)(1076003)(4326008)(70206006)(83380400001)(82310400003)(2906002)(6916009)(356005)(86362001)(44832011)(478600001)(70586007)(36756003)(426003)(7696005)(19627235002)(5660300002)(30864003)(2616005)(186003)(82740400003)(8936002)(26005)(316002)(54906003)(8676002)(47076004)(336012)(81166007);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR08MB4431 Return-Path: Sami.Mujawar@arm.com X-MS-Exchange-Transport-CrossTenantHeadersStripped: VE1EUR03FT005.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: 1be536db-104f-449c-4c84-08d875d9ccce X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: a1dEz2f/ZAazR1dNh5MD7ymtlyfS/8TOWynmFyxR9DdigmA1KoD63SloMSee0D4lijLIFK0YcRXjH89cqNi5S2Am04E2TBn0CzMnHzLgmJs9nFtsWmWsoPCcBeUeUZ6ZnfM6GMDW3RQ3urQWIZ4JUO6nUbgE2+Xy2v2bvwGYpH8uLJe4IQU7ot6j3XlL3IPtWG8I6Fq5c9J11lm3AKdnMap575IVRHEJrNypspGnVWn5YrNNBpguW6z/q9z/UmTUouLGa2AXozAk9b3lXvq5h3EZ1P0xdg0V5tYDQhgzH9DIgttyUeZRiW9yQrdy+xwh6USrvl3D+mPCqfFJM6BT55LwxGz5fg07r7e8KVDa1ly21E96TPLLip19DT1A0L+Xf2kBFQvoJ037ofEhnoIZcoB684KW7vaLyZQ1XPNt68c9fQmbx91fbHgmvhF0mygxkf6LxlUzILcIJ9M/iXul2OQZCHpWomjRI0BXYLWpoP8= X-Forefront-Antispam-Report: CIP:63.35.35.123;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:64aa7808-outbound-1.mta.getcheckrecipient.com;PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com;CAT:NONE;SFS:(4636009)(39860400002)(136003)(346002)(396003)(376002)(46966005)(336012)(8936002)(36756003)(44832011)(83380400001)(316002)(2906002)(5660300002)(81166007)(7696005)(1076003)(30864003)(6916009)(186003)(19627235002)(26005)(82740400003)(426003)(70206006)(86362001)(82310400003)(36906005)(54906003)(2616005)(70586007)(478600001)(4326008)(8676002)(47076004);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2020 15:56:17.3567 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a1037c28-b9dd-4247-5cbc-08d875d9d897 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: VE1EUR03FT005.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB7PR08MB3579 Content-Type: text/plain From: Marc Moisson-Franckhauser Add a new parser for the Arm Error Source Table (AEST) described in the ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, dated 28 September 2020. (https://developer.arm.com/documentation/den0085/0101/) AEST enables kernel-first handling of errors in a system that supports the Armv8 RAS extensions. It covers Armv8.2+ RAS extensions for PEs and the RAS system architecture for non-PE system components. Signed-off-by: Marc Moisson-Franckhauser Signed-off-by: Sami Mujawar --- Notes: v2: - Minor update to include ArmErrorSourceTable.h to obtain [SAMI] the AEST signature macro definition. ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 21 + ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h | 4 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c | 755 ++++++++++++++++++++ ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 4 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf | 3 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni | 3 +- 6 files changed, 785 insertions(+), 5 deletions(-) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index f81ccac7e118378aa185db4b625e5bcd75f78347..41acd77b1890b6f8efea823843d43220dea63f67 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -462,6 +462,27 @@ ParseAcpiHeader ( ); /** + This function parses the ACPI AEST table. + When trace is enabled this function parses the AEST 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 +ParseAcpiAest ( + IN BOOLEAN Trace, + IN UINT8* Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + +/** This function parses the ACPI BGRT table. When trace is enabled this function parses the BGRT table and traces the ACPI table fields. diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h index 4f92596b90a6ee422d8d0959881015ffd3de4da0..0ebf79fb653ae3a8190273aee452723c6213eb58 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h @@ -1,7 +1,7 @@ /** @file Header file for ACPI table parser - Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2020, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -11,7 +11,7 @@ /** The maximum number of ACPI table parsers. */ -#define MAX_ACPI_TABLE_PARSERS 16 +#define MAX_ACPI_TABLE_PARSERS 32 /** An invalid/NULL signature value. */ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c new file mode 100644 index 0000000000000000000000000000000000000000..7aa8c8fd2167822f4f5e0f6e4067195aac510e5c --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c @@ -0,0 +1,755 @@ +/** @file + AEST table parser + + Copyright (c) 2020, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, + dated 28 September 2020. + (https://developer.arm.com/documentation/den0085/0101/) +**/ + +#include +#include +#include +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; +STATIC UINT8* AestNodeType; +STATIC UINT16* AestNodeLength; +STATIC UINT32* NodeDataOffset; +STATIC UINT32* NodeInterfaceOffset; +STATIC UINT32* NodeInterruptArrayOffset; +STATIC UINT32* NodeInterruptCount; +STATIC UINT32* ProcessorId; +STATIC UINT8* ProcessorFlags; +STATIC UINT8* ProcessorResourceType; + +/** + Validate Processor Flags. + + @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 +ValidateProcessorFlags ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + // If the global or shared node flag is set then the ACPI Processor ID + // field must be set to 0 and ignored. + if (((*Ptr & 0x3) != 0) && (*ProcessorId != 0)) { + IncrementErrorCount (); + Print (L"\nERROR: 'ACPI Processor ID' field must be set to 0 for global" + L" or shared nodes."); + } +} + +/** + Validate GIC Interface Type. + + @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 +ValidateGicInterfaceType ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + UINT32 GicInterfaceType; + + GicInterfaceType = *(UINT32*)Ptr; + if (GicInterfaceType > 3) { + IncrementErrorCount (); + Print (L"\nError: Invalid GIC Interface type %d", GicInterfaceType); + } +} + +/** + Validate Interface Type. + + @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 +ValidateInterfaceType ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + if (*Ptr > 1) { + IncrementErrorCount (); + Print (L"\nError: Interface type should be 0 or 1"); + } +} + +/** + Validate Interrupt Type. + + @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 +ValidateInterruptType ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + if (*Ptr > 1) { + IncrementErrorCount (); + Print (L"\nError: Interrupt type should be 0 or 1"); + } +} + +/** + Validate interrupt flags. + + @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 +ValidateInterruptFlags ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + if ((*Ptr & 0xfe) != 0) { + IncrementErrorCount (); + Print (L"\nError: Reserved Flag bits not set to 0"); + } +} + +/** + Dumps 16 bytes of data. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpVendorSpecificData ( + IN CONST CHAR16* Format OPTIONAL, + IN UINT8* Ptr + ) +{ + Print ( + L"%02X %02X %02X %02X %02X %02X %02X %02X\n", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6], + Ptr[7] + ); + + Print ( + L"%*a %02X %02X %02X %02X %02X %02X %02X %02X", + OUTPUT_FIELD_COLUMN_WIDTH, + "", + Ptr[8], + Ptr[9], + Ptr[10], + Ptr[11], + Ptr[12], + Ptr[13], + Ptr[14], + Ptr[15] + ); +} + +/** + An ACPI_PARSER array describing the ACPI AEST Table. +**/ +STATIC CONST ACPI_PARSER AestParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + An ACPI_PARSER array describing the AEST Node Header. +**/ +STATIC CONST ACPI_PARSER AestNodeHeaderParser[] = { + {L"Type", 1, 0, L"%d", NULL, (VOID**)&AestNodeType, NULL, NULL}, + {L"Length", 2, 1, L"%d", NULL, (VOID**)&AestNodeLength, NULL, NULL}, + {L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Node Data Offset", 4, 4, L"%d", NULL, (VOID**)&NodeDataOffset, NULL, NULL}, + {L"Node Interface Offset", 4, 8, L"%d", NULL, + (VOID**)&NodeInterfaceOffset, NULL, NULL}, + {L"Node Interrupt Array Offset", 4, 12, L"%d", NULL, + (VOID**)&NodeInterruptArrayOffset, NULL, NULL}, + {L"Node Interrupt Count", 4, 16, L"%d", NULL, + (VOID**)&NodeInterruptCount, NULL, NULL}, + {L"Timestamp Rate", 8, 20, L"%ld", NULL, NULL, NULL, NULL}, + {L"Reserved1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Error Injection Countdown Rate", 8, 36, L"%ld", NULL, NULL, NULL, NULL} + // Node specific data... + // Node interface... + // Node interrupt array... +}; + +/** + An ACPI_PARSER array describing the Processor error node specific data. +**/ +STATIC CONST ACPI_PARSER AestProcessorStructure[] = { + {L"ACPI Processor ID", 4, 0, L"0x%x", NULL, (VOID**)&ProcessorId, NULL, NULL}, + {L"Resource Type", 1, 4, L"%d", NULL, (VOID**)&ProcessorResourceType, NULL, + NULL}, + {L"Reserved", 1, 5, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Flags", 1, 6, L"0x%x", NULL, (VOID**)&ProcessorFlags, + ValidateProcessorFlags, NULL}, + {L"Revision", 1, 7, L"%d", NULL, NULL, NULL, NULL}, + {L"Processor Affinity Level Indicator", 8, 8, L"0x%lx", NULL, NULL, NULL, + NULL}, + // Resource specific data... +}; + +/** + An ACPI_PARSER array describing the processor cache resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorCacheResourceSubstructure[] = { + {L"Cache reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the processor TLB resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorTlbResourceSubstructure[] = { + {L"TLB reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the processor generic resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorGenericResourceSubstructure[] = { + {L"Vendor-defined data", 4, 0, L"%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the memory controller structure. +**/ +STATIC CONST ACPI_PARSER AestMemoryControllerStructure[] = { + {L"Proximity Domain", 4, 0, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the SMMU structure. +**/ +STATIC CONST ACPI_PARSER AestSmmuStructure[] = { + {L"IORT Node reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"SubComponent reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the vendor-defined structure. +**/ +STATIC CONST ACPI_PARSER AestVendorDefinedStructure[] = { + {L"Hardware ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Unique ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Vendor-specific data", 16, 8, NULL, DumpVendorSpecificData, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the GIC structure. +**/ +STATIC CONST ACPI_PARSER AestGicStructure[] = { + {L"GIC Interface Type", 4, 0, L"0x%x", NULL, NULL, ValidateGicInterfaceType, + NULL}, + {L"GIC Interface reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the node interface. +**/ +STATIC CONST ACPI_PARSER AestNodeInterface[] = { + {L"Interface Type", 1, 0, L"%d", NULL, NULL, ValidateInterfaceType, NULL}, + {L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}, + {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Start Error Record Index", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Number of Error Records", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Error Records Implemented", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Error Records Support", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Addressing mode", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the node interrupts. +**/ +STATIC CONST ACPI_PARSER AestNodeInterrupt[] = { + {L"Interrupt Type", 1, 0, L"%d", NULL, NULL, ValidateInterruptType, NULL}, + {L"Reserved", 2, 1, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Interrupt Flags", 1, 3, L"0x%x", NULL, NULL, ValidateInterruptFlags, NULL}, + {L"Interrupt GSIV", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}, + {L"ID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Reserved1", 3, 9, L"%x %x %x", Dump3Chars, NULL, NULL, NULL} +}; + +/** + Parses the Processor Error Node structure along with its resource + specific data. + + @param [in] Ptr Pointer to the start of the Processor node. + @param [in] Length Maximum length of the Processor node. +**/ +STATIC +VOID +DumpProcessorNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + UINT32 Offset; + + Offset = ParseAcpi ( + TRUE, + 2, + "Processor", + Ptr, + Length, + PARSER_PARAMS (AestProcessorStructure) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((ProcessorId == NULL) || + (ProcessorResourceType == NULL) || + (ProcessorFlags == NULL)) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient Processor Error Node length. Length = %d.\n", + Length + ); + return; + } + + switch (*ProcessorResourceType) { + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE: + ParseAcpi ( + TRUE, + 2, + "Cache Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorCacheResourceSubstructure) + ); + break; + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB: + ParseAcpi ( + TRUE, + 2, + "TLB Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorTlbResourceSubstructure) + ); + break; + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC: + ParseAcpi ( + TRUE, + 2, + "Generic Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorGenericResourceSubstructure) + ); + break; + default: + IncrementErrorCount (); + Print (L"ERROR: Invalid Processor Resource Type."); + return; + } // switch +} + +/** + Parses the Memory Controller node. + + @param [in] Ptr Pointer to the start of the Memory Controller node. + @param [in] Length Maximum length of the Memory Controller node. +**/ +STATIC +VOID +DumpMemoryControllerNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Memory Controller", + Ptr, + Length, + PARSER_PARAMS (AestMemoryControllerStructure) + ); +} + +/** + Parses the SMMU node. + + @param [in] Ptr Pointer to the start of the SMMU node. + @param [in] Length Maximum length of the SMMU node. +**/ +STATIC +VOID +DumpSmmuNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "SMMU", + Ptr, + Length, + PARSER_PARAMS (AestSmmuStructure) + ); +} + +/** + Parses the Vendor-defined structure. + + @param [in] Ptr Pointer to the start of the Vendor-defined node. + @param [in] Length Maximum length of the Vendor-defined node. +**/ +STATIC +VOID +DumpVendorDefinedNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Vendor-defined", + Ptr, + Length, + PARSER_PARAMS (AestVendorDefinedStructure) + ); +} + +/** + Parses the GIC node. + + @param [in] Ptr Pointer to the start of the GIC node. + @param [in] Length Maximum length of the GIC node. +**/ +STATIC +VOID +DumpGicNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "GIC", + Ptr, + Length, + PARSER_PARAMS (AestGicStructure) + ); +} + +/** + Parses the Node Interface structure. + + @param [in] Ptr Pointer to the start of the Node Interface Structure. + @param [in] Length Maximum length of the Node Interface Structure. +**/ +STATIC +VOID +DumpNodeInterface ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Node Interface", + Ptr, + Length, + PARSER_PARAMS (AestNodeInterface) + ); +} + +/** + Parses the Node Interrupts Structure. + + @param [in] Ptr Pointer to the start of the Node Interrupt array. + @param [in] Length Maximum length of the Node Interrupt array. + @param [in] InterruptCount Number if interrupts in the Node Interrupts array. +**/ +STATIC +VOID +DumpNodeInterrupts ( + IN UINT8* Ptr, + IN UINT32 Length, + IN UINT32 InterruptCount + ) +{ + UINT32 Offset; + UINT32 Index; + CHAR8 Buffer[64]; + + if (Length < (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT))) { + IncrementErrorCount (); + Print ( + L"ERROR: Node not long enough for Interrupt Array.\n"\ + L" Length left = %d, Required = %d, Interrupt Count = %d\n", + Length, + (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT)), + InterruptCount + ); + return; + } + + Offset = 0; + for (Index = 0; Index < InterruptCount; Index++) { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "Node Interrupt [%d]", + Index + ); + + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestNodeInterrupt) + ); + } //for +} + +/** + Parses a single AEST Node Structure. + + @param [in] Ptr Pointer to the start of the Node. + @param [in] Length Maximum length of the Node. + @param [in] NodeType AEST node type. + @param [in] DataOffset Offset to the node data. + @param [in] InterfaceOffset Offset to the node interface data. + @param [in] InterruptArrayOffset Offset to the node interrupt array. + @param [in] InterruptCount Number of interrupts. +**/ +STATIC +VOID +DumpAestNodeStructure ( + IN UINT8* Ptr, + IN UINT32 Length, + IN UINT8 NodeType, + IN UINT32 DataOffset, + IN UINT32 InterfaceOffset, + IN UINT32 InterruptArrayOffset, + IN UINT32 InterruptCount + ) +{ + UINT32 Offset; + UINT32 RemainingLength; + UINT8* NodeDataPtr; + + Offset = ParseAcpi ( + TRUE, + 2, + "Node Structure", + Ptr, + Length, + PARSER_PARAMS (AestNodeHeaderParser) + ); + + if ((Offset > DataOffset) || (DataOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Data Offset: %d.\n"\ + L" It should be between %d and %d.\n", + DataOffset, + Offset, + Length + ); + } + + if ((Offset > InterfaceOffset) || (InterfaceOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Interface Offset: %d.\n"\ + L" It should be between %d and %d.\n", + InterfaceOffset, + Offset, + Length + ); + } + + if ((Offset > InterruptArrayOffset) || (InterruptArrayOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Interrupt Array Offset: %d.\n"\ + L" It should be between %d and %d.\n", + InterruptArrayOffset, + Offset, + Length + ); + } + + // Parse Node Data Field. + NodeDataPtr = Ptr + DataOffset; + RemainingLength = Length - DataOffset; + switch (NodeType) { + case EFI_ACPI_AEST_NODE_TYPE_PROCESSOR: + DumpProcessorNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_MEMORY: + DumpMemoryControllerNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_SMMU: + DumpSmmuNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED: + DumpVendorDefinedNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_GIC: + DumpGicNode (NodeDataPtr, RemainingLength); + break; + default: + IncrementErrorCount (); + Print (L"ERROR: Invalid Error Node Type.\n"); + return; + } // switch + + // Parse the Interface Field. + DumpNodeInterface ( + Ptr + InterfaceOffset, + Length - InterfaceOffset + ); + + // Parse the Node Interrupt Array. + DumpNodeInterrupts ( + Ptr + InterruptArrayOffset, + Length - InterruptArrayOffset, + InterruptCount + ); + + return; +} + +/** + This function parses the ACPI AEST table. + When trace is enabled this function parses the AEST 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 +ParseAcpiAest ( + IN BOOLEAN Trace, + IN UINT8* Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8* NodePtr; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "AEST", + Ptr, + AcpiTableLength, + PARSER_PARAMS (AestParser) + ); + + while (Offset < AcpiTableLength) { + NodePtr = Ptr + Offset; + + ParseAcpi ( + FALSE, + 0, + NULL, + NodePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (AestNodeHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((AestNodeType == NULL) || + (AestNodeLength == NULL) || + (NodeDataOffset == NULL) || + (NodeInterfaceOffset == NULL) || + (NodeInterruptArrayOffset == NULL) || + (NodeInterruptCount == NULL)) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient length left for Node Structure.\n"\ + L" Length left = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate AEST Node length + if ((*AestNodeLength == 0) || + ((Offset + (*AestNodeLength)) > AcpiTableLength)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid AEST Node length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *AestNodeLength, + Offset, + AcpiTableLength + ); + return; + } + + DumpAestNodeStructure ( + NodePtr, + *AestNodeLength, + *AestNodeType, + *NodeDataOffset, + *NodeInterfaceOffset, + *NodeInterruptArrayOffset, + *NodeInterruptCount + ); + + Offset += *AestNodeLength; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c index d2f26ff89f12e596702281c38ab0de3729aa68e4..502bdcf30be50579bc5a4de30b71dc8a44fd55ae 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c @@ -1,12 +1,13 @@ /** @file Main file for 'acpiview' Shell command function. - Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include +#include #include #include @@ -46,6 +47,7 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = { STATIC CONST ACPI_TABLE_PARSER ParserList[] = { + {EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiAest}, {EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE, ParseAcpiBgrt}, {EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2}, {EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index 91459f9ec632635ee453c5ef46f67445cd9eee0c..d89cfbba0da833d5c945ebeb0b462fa52504a865 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -1,7 +1,7 @@ ## @file # Provides Shell 'acpiview' command functions # -# Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -27,6 +27,7 @@ [Sources.common] AcpiView.h AcpiViewConfig.c AcpiViewConfig.h + Parsers/Aest/AestParser.c Parsers/Bgrt/BgrtParser.c Parsers/Dbg2/Dbg2Parser.c Parsers/Dsdt/DsdtParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni index 7cd43d0518fd0a23dc547a5cab0d08b62602a113..9dbffcd7c534fa9039668cfbe79f75d3a94c9b28 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni @@ -1,6 +1,6 @@ // /** // -// Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause-Patent // // Module Name: @@ -78,6 +78,7 @@ " other than AcpiTable header. The actual header can refer to the ACPI spec\r\n" " 6.2\r\n" " Extra A. Particular types:\r\n" +" AEST - Arm Error Source Table\r\n" " APIC - Multiple APIC Description Table (MADT)\r\n" " BGRT - Boot Graphics Resource Table\r\n" " DBG2 - Debug Port Table 2\r\n" -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'