From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (EUR05-VI1-obe.outbound.protection.outlook.com [40.107.21.42]) by mx.groups.io with SMTP id smtpd.web10.5595.1591876172206616418 for ; Thu, 11 Jun 2020 04:49:33 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=t1ootAfy; spf=pass (domain: arm.com, ip: 40.107.21.42, mailfrom: tomas.pilar@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=D44z0Aro7IiOhsBCXr9z0K3mWJjfTSwo7NiYMTad6cE=; b=t1ootAfyynJxb2BN1m1Y0pPjSs8vMYN4F5HZbdxA6JgvX8tiFFxAvOyn8mOZF5q9B0DLfCoAurF2vLxt6Oekr9n8RAWFtIOfljchcGrfgUcYtyMMjLmvm2aSRdQ+jVtD5SV0O8isPHTvoh3DGvUW3AN7/FlGxY0JzcEQq/nXG9I= Received: from AM6P192CA0100.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:8d::41) by HE1PR0802MB2251.eurprd08.prod.outlook.com (2603:10a6:3:cc::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3088.18; Thu, 11 Jun 2020 11:49:28 +0000 Received: from AM5EUR03FT051.eop-EUR03.prod.protection.outlook.com (2603:10a6:209:8d:cafe::61) by AM6P192CA0100.outlook.office365.com (2603:10a6:209:8d::41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3088.19 via Frontend Transport; Thu, 11 Jun 2020 11:49:28 +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=bestguesspass 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 AM5EUR03FT051.mail.protection.outlook.com (10.152.16.246) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3088.18 via Frontend Transport; Thu, 11 Jun 2020 11:49:28 +0000 Received: ("Tessian outbound 3e82c366635e:v59"); Thu, 11 Jun 2020 11:49:28 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 7a6a239b9a45f2b0 X-CR-MTA-TID: 64aa7808 Received: from 523d878f1ae8.3 by 64aa7808-outbound-1.mta.getcheckrecipient.com id D1A9E684-133B-4218-BA67-1C4E98A48AA0.1; Thu, 11 Jun 2020 11:49:22 +0000 Received: from EUR01-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 523d878f1ae8.3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 11 Jun 2020 11:49:22 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=K4UWu+yvsHybLcCBhRs0Dx72tXcFSivzJfbA0k12etqdnmhT+A1NarXsNTXmgTU4KZBs4vOlKuFyicTNwteGphZkkhfs1QezHSOVYltXOscmxZhq4H89enFZDN9QeVEs/kEzthzV7R5nwqBxloVEMLmaNU5dxorz6i/3kF51JnBzcSw0LsCLoRW3E/Ynqip3YGrP7kHfqc0gjEAwcBDBPfqgq+D62vRVY5VKZ0iEk+/xY9E7717PdhEL2qtoePeUuwHJQqYKHHRNSL6SKey7cGpedkmHTWMNURTK65qY9e61/EwE0BH1YBQQEWp0aLYU+44km1hhS+yT3MPx5/EsHw== 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=D44z0Aro7IiOhsBCXr9z0K3mWJjfTSwo7NiYMTad6cE=; b=f1Y54SFn6T4eXbrrygBxjydOGlxGkXxS4wGBL834ei/Ac1/UM/g8uLQ7kjZ5jia6bbk74446T5uxypuhBTKLMsrN6WxMp4GBA1P7B7rw4RwdY2PWjgVTmDE2dZwr0gY27kai8ghbM2PuMuWIh7gHSZH5pLzv6sw4KfW+6tDxjIx8WbeNoQv/VePexjLlX3d36mHQmOlHsT07gDKH/rIQoqvUpHkG8/bFpJv7kvTQ2QxmrkgFXUUOmi87xUJbYo5UWEHwSJM/FOyU2iYp1jbjPBU450bJAe1+hMCJ7IeoJp4bmVH7C26C0obmZ1fHk0En4yyB4PPzn4rOvBMpv1nvVg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; 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=D44z0Aro7IiOhsBCXr9z0K3mWJjfTSwo7NiYMTad6cE=; b=t1ootAfyynJxb2BN1m1Y0pPjSs8vMYN4F5HZbdxA6JgvX8tiFFxAvOyn8mOZF5q9B0DLfCoAurF2vLxt6Oekr9n8RAWFtIOfljchcGrfgUcYtyMMjLmvm2aSRdQ+jVtD5SV0O8isPHTvoh3DGvUW3AN7/FlGxY0JzcEQq/nXG9I= Received: from AM5PR0801MB1844.eurprd08.prod.outlook.com (2603:10a6:203:39::22) by AM5PR0801MB1859.eurprd08.prod.outlook.com (2603:10a6:203:49::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3066.20; Thu, 11 Jun 2020 11:49:20 +0000 Received: from AM5PR0801MB1844.eurprd08.prod.outlook.com ([fe80::95cf:8f23:9053:2f60]) by AM5PR0801MB1844.eurprd08.prod.outlook.com ([fe80::95cf:8f23:9053:2f60%10]) with mapi id 15.20.3088.018; Thu, 11 Jun 2020 11:49:20 +0000 From: "Tomas Pilar (tpilar)" To: "devel@edk2.groups.io" , "zhichao.gao@intel.com" , Krzysztof Koch CC: "Ni, Ray" , Sami Mujawar , "Laura.Moretta@arm.comMatteo.Carlini@arm.com" , nd Subject: Re: [edk2-devel] [PATCH v1 1/6] ShellPkg: acpiview: Add interface for data-driven table parsing Thread-Topic: [edk2-devel] [PATCH v1 1/6] ShellPkg: acpiview: Add interface for data-driven table parsing Thread-Index: AQHWIvRytijKk1YTzEGH9N/UHdkbGqjTQeaAgABEc1A= Date: Thu, 11 Jun 2020 11:49:20 +0000 Message-ID: References: <20200505154604.9848-1-krzysztof.koch@arm.com> <20200505154604.9848-2-krzysztof.koch@arm.com> In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: Authentication-Results-Original: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=arm.com; x-originating-ip: [81.111.29.163] x-ms-publictraffictype: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: e6ef4f0a-a177-4ec9-700e-08d80dfd7f30 x-ms-traffictypediagnostic: AM5PR0801MB1859:|HE1PR0802MB2251: x-ms-exchange-transport-forked: True X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true nodisclaimer: true x-ms-oob-tlc-oobclassifiers: OLM:10000;OLM:10000; x-forefront-prvs: 0431F981D8 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: SXaaFTvEng2Ucd4pYI0G5uu50Aqoh4BHFI3mOZQkAP8dZhRRurI5JN0RfSVk9UVMcS5G4aSfiCw3irlYZSHt6Q+aeSb/rIWAWHraVl8khECliejo0skzgP7jVUvmpxNV1mNWtx49fCNo3MX6fEiI4j9WRn66EfvcoHTVHEBWWc0Ho6AizqhdHJ4wKCDqsmx9wJfPb/kMZyAPJcYVztmEJ1s17h5LgYnU+1+JVDqLzPT6U8n1OdxufZpLRPTUaTFcM6X1nnQWYB9RnefCEef9cB3ksNaiZruyFALCXPdo77gs+e0ydYM8znRnT/2sdpH3wgN+SWUw3uqTv5E/ug5+yLmxCerDcs+pd1VQTHUKMVDHCvhKtqGkZ8hAZzat7S4xC3YFJn0GsN8vPjey7klaDQ== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM5PR0801MB1844.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(4636009)(136003)(346002)(366004)(396003)(376002)(39860400002)(33656002)(66446008)(66476007)(30864003)(76116006)(8676002)(86362001)(64756008)(66946007)(5660300002)(8936002)(71200400001)(83380400001)(2906002)(66556008)(52536014)(966005)(26005)(316002)(55016002)(9686003)(7696005)(4326008)(478600001)(110136005)(53546011)(54906003)(6506007)(6636002)(186003)(579004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata: gWUC1gyCYSJ6m2CciV/jRHONECg6wG2n8xy9/CE0Lv9BvWzgLGNOmDmV1flk1oWD5yuO1AZgqnIxPQmrgEGGkHwi4l8CKrTrJbdwi/MnxatCBTmD2tE8boIXqXU/fP0H5W0SIK/4D8lx5pN4pxoIYxB7zBedYL97h6Vavw/o6UrLytdrl9OZftniUOBnVbrflaAI41H1TeAz9LjpYfbXvgse3I1INCJerujrWcqtNf4SktHZP2smjqtxc6XqaCYgpB8Xl/I+B+yZR0jvLqisTrHmCr4DGy+0+ST4G7aJMuZYvqRH/7KO3Pap+anfPhw8v+E12wx35FMopT9keQC6ovBpvs8fnyufnNrwz9lasAIlzvMf/nt8kldOIKVTQFJFzdtap0nLVSrzIAdkM0nyDMsqhXpsEzi5uc1bPfj3bIQcsoe3Tz7dPnokHReuPg9TQ1StZFIcgJVgDfiGQ/keCHCKS/P/KiUGEjHB1+ghpuU= MIME-Version: 1.0 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1859 Original-Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=arm.com; Return-Path: Tomas.Pilar@arm.com X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM5EUR03FT051.eop-EUR03.prod.protection.outlook.com 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;SFTY:;SFS:(4636009)(136003)(346002)(396003)(376002)(39860400002)(46966005)(7696005)(70586007)(70206006)(186003)(53546011)(52536014)(6506007)(336012)(4326008)(5660300002)(966005)(478600001)(2906002)(26005)(6636002)(110136005)(8936002)(82740400003)(82310400002)(316002)(81166007)(55016002)(356005)(9686003)(33656002)(54906003)(86362001)(47076004)(83380400001)(36906005)(8676002)(30864003);DIR:OUT;SFP:1101; X-MS-Office365-Filtering-Correlation-Id-Prvs: a8680d17-922f-4896-cb21-08d80dfd7a54 X-Forefront-PRVS: 0431F981D8 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: j3mcXfglXKymzDfNviARjbST1DDc5U86YhMnCLybOt1Qjj8t/dCe0OBt5aKrFggWMkdjsIlP2DWYBc75sYLtRvINa/oFJvYJOCR1Wz6xWC/74cqktyTUZvze1EJ+8raetuoS/HnzN6vigmom5ax0hA+00qKF6WoLqcplT886hYCbo20WMVcmuJXAAeG2sCJnSZU3AbVx33fV08hWzQMsnS13aIjWhF1qTlxx9PCrf3+MQA3j/a4xANQuUDehtNH6Q7RTf5/3sDL1jLmskWYNUng+Dwh2WCzwHjXx00F6J7OPeB97HKJeeL6BXorYV+Ka4IRLx0p8dtSi4KcaixNiQdODfaq+9PZCxA2Jx56p5nRCM87eUYR3LizNKWzpnlTw2U2F8mvy6I6/x1/XZ9WsAsf2BfsAgYx+/uw2IWrvZLNTp0WpEugeaUKK362wXc+BQX17dFyqrDLqksFpiRxFrcArKeLam6K5oOxwnt0uncM= X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jun 2020 11:49:28.4103 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e6ef4f0a-a177-4ec9-700e-08d80dfd7f30 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-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0802MB2251 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Krzysztof has moved on to other pastures, I'll respin the patches according= ly. Cheers, Tom -----Original Message----- From: devel@edk2.groups.io On Behalf Of Gao, Zhicha= o via groups.io Sent: 11 June 2020 08:43 To: Krzysztof Koch ; devel@edk2.groups.io Cc: Ni, Ray ; Sami Mujawar ; Laura= .Moretta@arm.comMatteo.Carlini@arm.com; nd Subject: Re: [edk2-devel] [PATCH v1 1/6] ShellPkg: acpiview: Add interface= for data-driven table parsing (1) The ASSERT only works with DEBUG build. I think we need add if conditi= on after the ASSERT to return the error code to avoid the null pointer dere= ference. (2) It is suggested to use the const (lower-case) instead of CONST. same t= o static. Others are fine to me. Thanks, Zhichao > -----Original Message----- > From: Krzysztof Koch > Sent: Tuesday, May 5, 2020 11:46 PM > To: devel@edk2.groups.io > Cc: Ni, Ray ; Gao, Zhichao ;=20 > Sami.Mujawar@arm.com; Laura.Moretta@arm.comMatteo.Carlini@arm.com; > nd@arm.com > Subject: [PATCH v1 1/6] ShellPkg: acpiview: Add interface for=20 > data-driven table parsing >=20 > Define and implement an interface to streamline metadata collection=20 > and validation for structures present in each ACPI table. >=20 > Most ACPI tables define substructures which constitute the table. > These substructures are identified by their 'Type' field value. The=20 > range of possible 'Type' values is defined on a per-table basis. >=20 > For more sophisticated ACPI table validation, additional data about=20 > each structure type needs to be maintained. This patch defines a new=20 > ACPI_STRUCT_INFO structure. It stores additional metadata about a=20 > building block of an ACPI table. ACPI_STRUCT_INFO's are organised into= =20 > ACPI_STRUCT_DATABASE's. ACPI_STRUCT_DATABASE is an array of=20 > ACPI_STRUCT_INFO elements which are indexed using structure's type value= . >=20 > For example, in the Multiple APIC Description Table (MADT) all=20 > Interrupt Controller Structure types form a single database. In the=20 > database, the GIC CPU Interface (GICC) structure's metadata is the 11th = entry (i.e. Type =3D 0xB). >=20 > ACPI_STRUCT_INFO structure consists of: > - ASCII name of the structure > - ACPI-defined stucture Type > - bitmask defining the validity of the structure for various > architectures > - instance counter > - a handler for the structure (ACPI_STRUCT_HANDLER) >=20 > The bitmask allows detection of structures in a table which are not=20 > compatible with the target platform. >=20 > For example, the Multiple APIC Description Table (MADT) contains=20 > Interrupt Controller Structure definitions which apply to either the=20 > Advanced Programmable Interrupt Controller (APIC) model or the Generic= =20 > Interrupt Controller (GIC) model. Presence of APIC-related structures=20 > on an Arm-based platform is a bug which is now detected and reported by = acpiview. >=20 > This patch adds support for compatibility checks with the Arm architectu= re only. > However, provisions are made to allow extensions to other architectures. >=20 > ACPI_STRUCT_HANDLER describes how the contents of the structure can be= =20 > parsed. The possible options are: > - An ACPI_PARSER array which can be passed to the ParseAcpi() function > - A dedicated function for parsing the structure > (ACPI_STRUCT_PARSER_FUNC) >=20 > If neither of these options is provided, it is assumed that the=20 > parsing logic is not implemented. >=20 > ACPI_STRUCT_PARSER_FUNC expects the the first two arguments to be the=20 > pointer to the start of the structure to parse and the length of structu= re's buffer. > The remaining two optional arguments are context specific. >=20 > This patch adds methods for: > - Resetting the instance count for all structure types in a table. > - Getting the combined instance count for all types in a table. > - Validating the compatibility of a structure with the target arch. > - Printing structure counts for the types which are compatible with > the target architecture and validating that the non-compatible > structures are not present in the table. > - Parsing the structure according to the information provided by its > handle. >=20 > Finally, define a helper PrintAcpiStructName () function to streamline= =20 > the printing of ACPI structure name together with the structure's curren= t occurrence count. >=20 > References: > - ACPI 6.3, January 2019 >=20 > Signed-off-by: Krzysztof Koch > --- >=20 > Notes: > v1: > - Add interface for data-driven table parsing [Krzysztof] >=20 > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c | 263 > ++++++++++++++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 234 > +++++++++++++++++ > 2 files changed, 497 insertions(+) >=20 > diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c > b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c > index > 3f12a33050a4e4ab3be2187c90ef8dcf0882283d..32566101e2de2eec3ccf44563ee > 79379404bff62 100644 > --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c > +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c > @@ -6,6 +6,8 @@ > **/ >=20 > #include > +#include > +#include > #include > #include > #include "AcpiParser.h" > @@ -466,6 +468,267 @@ PrintFieldName ( > ); > } >=20 > +/** > + Produce a Null-terminated ASCII string with the name and index of=20 > +an > + ACPI structure. > + > + The output string is in the following format: [] > + > + @param [in] Name Structure name. > + @param [in] Index Structure index. > + @param [in] BufferSize The size, in bytes, of the output buffer. > + @param [out] Buffer Buffer for the output string. > + > + @return The number of bytes written to the buffer (not including Nu= ll-byte) > +**/ > +UINTN > +EFIAPI > +PrintAcpiStructName ( > + IN CONST CHAR8* Name, > + IN UINT32 Index, > + IN UINTN BufferSize, > + OUT CHAR8* Buffer > + ) > +{ > + ASSERT (Name !=3D NULL); > + ASSERT (Buffer !=3D NULL); > + > + return AsciiSPrint (Buffer, BufferSize, "%a [%d]", Name , Index); } > + > +/** > + Set all ACPI structure instance counts to 0. > + > + @param [in,out] StructDb ACPI structure database with counts to r= eset. > +**/ > +VOID > +EFIAPI > +ResetAcpiStructCounts ( > + IN OUT ACPI_STRUCT_DATABASE* StructDb > + ) > +{ > + UINT32 Type; > + > + ASSERT (StructDb !=3D NULL); > + ASSERT (StructDb->Entries !=3D NULL); > + > + for (Type =3D 0; Type < StructDb->EntryCount; Type++) { > + StructDb->Entries[Type].Count =3D 0; > + } > +} > + > +/** > + Sum all ACPI structure instance counts. > + > + @param [in] StructDb ACPI structure database with per-type counts= to sum. > + > + @return Total number of structure instances recorded in the databas= e. > +**/ > +UINT32 > +EFIAPI > +SumAcpiStructCounts ( > + IN CONST ACPI_STRUCT_DATABASE* StructDb > + ) > +{ > + UINT32 Type; > + UINT32 Total; > + > + ASSERT (StructDb !=3D NULL); > + ASSERT (StructDb->Entries !=3D NULL); > + > + Total =3D 0; > + > + for (Type =3D 0; Type < StructDb->EntryCount; Type++) { > + Total +=3D StructDb->Entries[Type].Count; } > + > + return Total; > +} > + > +/** > + Validate that a structure with a given type value is defined for=20 > +the given > + ACPI table and target architecture. > + > + The target architecture is evaluated from the firmare build parameter= s. > + > + @param [in] Type ACPI-defined structure type. > + @param [in] StructDb ACPI structure database with architecture > + compatibility info. > + > + @retval TRUE Structure is valid. > + @retval FALSE Structure is not valid. > +**/ > +BOOLEAN > +EFIAPI > +IsAcpiStructTypeValid ( > + IN UINT32 Type, > + IN CONST ACPI_STRUCT_DATABASE* StructDb > + ) > +{ > + UINT32 Compatible; > + > + ASSERT (StructDb !=3D NULL); > + ASSERT (StructDb->Entries !=3D NULL); > + > + if (Type >=3D StructDb->EntryCount) { > + return FALSE; > + } > + > +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) > + Compatible =3D StructDb->Entries[Type].CompatArch & > + (ARCH_COMPAT_ARM | ARCH_COMPAT_AARCH64); #else > + Compatible =3D StructDb->Entries[Type].CompatArch; > +#endif > + > + return (Compatible !=3D 0); > +} > + > +/** > + Print the instance count of each structure in an ACPI table that is > + compatible with the target architecture. > + > + For structures which are not allowed for the target architecture,=20 > + validate that their instance counts are 0. > + > + @param [in] StructDb ACPI structure database with counts to valid= ate. > + > + @retval TRUE All structures are compatible. > + @retval FALSE One or more incompatible structures present. > +**/ > +BOOLEAN > +EFIAPI > +ValidateAcpiStructCounts ( > + IN CONST ACPI_STRUCT_DATABASE* StructDb > + ) > +{ > + BOOLEAN AllValid; > + UINT32 Type; > + > + ASSERT (StructDb !=3D NULL); > + ASSERT (StructDb->Entries !=3D NULL); > + > + AllValid =3D TRUE; > + Print (L"\nTable Breakdown:\n"); > + > + for (Type =3D 0; Type < StructDb->EntryCount; Type++) { > + ASSERT (Type =3D=3D StructDb->Entries[Type].Type); > + > + if (IsAcpiStructTypeValid (Type, StructDb)) { > + Print ( > + L"%*a%-*a : %d\n", > + INSTANCE_COUNT_INDENT, > + "", > + OUTPUT_FIELD_COLUMN_WIDTH - INSTANCE_COUNT_INDENT, > + StructDb->Entries[Type].Name, > + StructDb->Entries[Type].Count > + ); > + } else if (StructDb->Entries[Type].Count > 0) { > + AllValid =3D FALSE; > + IncrementErrorCount (); > + Print ( > + L"ERROR: %a Structure is not valid for the target architecture = " \ > + L"(found %d)\n", > + StructDb->Entries[Type].Name, > + StructDb->Entries[Type].Count > + ); > + } > + } > + > + return AllValid; > +} > + > +/** > + Parse the ACPI structure with the type value given according to=20 > +instructions > + defined in the ACPI structure database. > + > + If the input structure type is defined in the database, increment=20 > + structure's instance count. > + > + If ACPI_PARSER array is used to parse the input structure, the=20 > + index of the structure (instance count for the type before update)=20 > + gets printed alongside the structure name. This helps debugging if=20 > + there are many instances of the type in a table. For=20 > + ACPI_STRUCT_PARSER_FUNC, the printing of the index must be=20 > + implemented > separately. > + > + @param [in] Indent Number of spaces to indent the output. > + @param [in] Ptr Ptr to the start of the structure. > + @param [in,out] StructDb ACPI structure database with instructions o= n how > + parse every structure type. > + @param [in] Offset Structure offset from the start of the tabl= e. > + @param [in] Type ACPI-defined structure type. > + @param [in] Length Length of the structure in bytes. > + @param [in] OptArg0 First optional argument to pass to parser f= unction. > + @param [in] OptArg1 Second optional argument to pass to parser = function. > + > + @retval TRUE ACPI structure parsed successfully. > + @retval FALSE Undefined structure type or insufficient data to pars= e. > +**/ > +BOOLEAN > +EFIAPI > +ParseAcpiStruct ( > + IN UINT32 Indent, > + IN UINT8* Ptr, > + IN OUT ACPI_STRUCT_DATABASE* StructDb, > + IN UINT32 Offset, > + IN UINT32 Type, > + IN UINT32 Length, > + IN CONST VOID* OptArg0 OPTIONAL, > + IN CONST VOID* OptArg1 OPTIONAL > + ) > +{ > + ACPI_STRUCT_PARSER_FUNC ParserFunc; > + CHAR8 Buffer[80]; > + > + ASSERT (Ptr !=3D NULL); > + ASSERT (StructDb !=3D NULL); > + ASSERT (StructDb->Entries !=3D NULL); ASSERT (StructDb->Name !=3D=20 > + NULL); > + > + PrintFieldName (Indent, L"* Offset *"); Print (L"0x%x\n", Offset); > + > + if (Type >=3D StructDb->EntryCount) { > + IncrementErrorCount (); > + Print (L"ERROR: Unknown %a. Type =3D %d\n", StructDb->Name, Type); > + return FALSE; > + } > + > + if (StructDb->Entries[Type].Handler.ParserFunc !=3D NULL) { > + ParserFunc =3D StructDb->Entries[Type].Handler.ParserFunc; > + ParserFunc (Ptr, Length, OptArg0, OptArg1); } else if=20 > + (StructDb->Entries[Type].Handler.ParserArray !=3D NULL) { > + ASSERT (StructDb->Entries[Type].Handler.Elements !=3D 0); > + > + PrintAcpiStructName ( > + StructDb->Entries[Type].Name, > + StructDb->Entries[Type].Count, > + sizeof (Buffer), > + Buffer > + ); > + > + ParseAcpi ( > + TRUE, > + Indent, > + Buffer, > + Ptr, > + Length, > + StructDb->Entries[Type].Handler.ParserArray, > + StructDb->Entries[Type].Handler.Elements > + ); > + } else { > + StructDb->Entries[Type].Count++; > + Print ( > + L"ERROR: Parsing of %a Structure is not implemented\n", > + StructDb->Entries[Type].Name > + ); > + return FALSE; > + } > + > + StructDb->Entries[Type].Count++; > + return TRUE; > +} > + > /** > This function is used to parse an ACPI table buffer. >=20 > diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h > b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h > index > f81ccac7e118378aa185db4b625e5bcd75f78347..70e540b3a76de0ff9ce70bcabed > 8548063bea0ff 100644 > --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h > +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h > @@ -300,6 +300,240 @@ typedef struct AcpiParser { > VOID* Context; > } ACPI_PARSER; >=20 > +/** > + Produce a Null-terminated ASCII string with the name and index of=20 > +an > + ACPI structure. > + > + The output string is in the following format: [] > + > + @param [in] Name Structure name. > + @param [in] Index Structure index. > + @param [in] BufferSize The size, in bytes, of the output buffer. > + @param [out] Buffer Buffer for the output string. > + > + @return The number of bytes written to the buffer (not including Nu= ll-byte) > +**/ > +UINTN > +EFIAPI > +PrintAcpiStructName ( > + IN CONST CHAR8* Name, > + IN UINT32 Index, > + IN UINTN BufferSize, > + OUT CHAR8* Buffer > + ); > + > +/** > + Indentation for printing instance counts for structures in an ACPI ta= ble. > +**/ > +#define INSTANCE_COUNT_INDENT 2 > + > +/** > + Common signature for functions which parse ACPI structures. > + > + @param [in] Ptr Pointer to the start of structure's buffer. > + @param [in] Length Length of the buffer. > + @param [in] OptArg0 First optional argument. > + @param [in] OptArg1 Second optional argument. > +*/ > +typedef VOID (*ACPI_STRUCT_PARSER_FUNC) ( > + IN UINT8* Ptr, > + IN UINT32 Length, > + IN CONST VOID* OptArg0 OPTIONAL, > + IN CONST VOID* OptArg1 OPTIONAL > + ); > + > +/** > + Description of how an ACPI structure should be parsed. > + > + One of ParserFunc or ParserArray should be not NULL. Otherwise, it=20 > +is > + assumed that parsing of an ACPI structure is not supported. If both > + ParserFunc and ParserArray are defined, ParserFunc is used. > +**/ > +typedef struct AcpiStructHandler { > + /// Dedicated function for parsing an ACPI structure > + ACPI_STRUCT_PARSER_FUNC ParserFunc; > + /// Array of instructions on how each structure field should be parse= d > + CONST ACPI_PARSER* ParserArray; > + /// Number of elements in ParserArray if ParserArray is defined > + UINT32 Elements; > +} ACPI_STRUCT_HANDLER; > + > +/** > + ACPI structure compatiblity with various architectures. > + > + Some ACPI tables define structures which are, for example, only=20 > + valid in the X64 or Arm context. For instance, the Multiple APIC=20 > + Description Table > + (MADT) describes both APIC and GIC interrupt models. > + > + These definitions provide means to describe the belonging of a=20 > +structure > + in an ACPI table to a particular architecture. This way,=20 > +incompatible > + structures can be detected. > +**/ > +#define ARCH_COMPAT_IA32 BIT0 > +#define ARCH_COMPAT_X64 BIT1 > +#define ARCH_COMPAT_ARM BIT2 > +#define ARCH_COMPAT_AARCH64 BIT3 > +#define ARCH_COMPAT_RISCV64 BIT4 > + > +/** > + Information about a structure which constitutes an ACPI table **/=20 > +typedef struct AcpiStructInfo { > + /// ACPI-defined structure Name > + CONST CHAR8* Name; > + /// ACPI-defined structure Type > + CONST UINT32 Type; > + /// Architecture(s) for which this structure is valid > + CONST UINT32 CompatArch; > + /// Structure's instance count in a table > + UINT32 Count; > + /// Information on how to handle the structure > + CONST ACPI_STRUCT_HANDLER Handler; > +} ACPI_STRUCT_INFO; > + > +/** > + Macro for defining ACPI structure info when an ACPI_PARSER array=20 > +must > + be used to parse the structure. > +**/ > +#define ADD_ACPI_STRUCT_INFO_ARRAY(Name, Type, Compat, Array) = \ > +{ = \ > + Name, Type, Compat, 0, {NULL, Array, ARRAY_SIZE (Array)} = \ > +} > + > +/** > + Macro for defining ACPI structure info when an=20 > +ACPI_STRUCT_PARSER_FUNC > + must be used to parse the structure. > +**/ > +#define ADD_ACPI_STRUCT_INFO_FUNC(Name, Type, Compat, Func) = \ > +{ = \ > + Name, Type, Compat, 0, {Func, NULL, 0} = \ > +} > + > +/** > + Macro for defining ACPI structure info when the structure is=20 > +defined in > + the ACPI spec but no parsing information is provided. > +**/ > +#define ACPI_STRUCT_INFO_PARSER_NOT_IMPLEMENTED(Name, Type, > Compat) \ > +{ = \ > + Name, Type, Compat, 0, {NULL, NULL, 0} = \ > +} > + > +/** > + Database collating information about every structure type defined=20 > +by > + an ACPI table. > +**/ > +typedef struct AcpiStructDatabase { > + /// ACPI-defined name for the structures being described in the datab= ase > + CONST CHAR8* Name; > + /// Per-structure-type information. The list must be ordered by the= =20 > +types > + /// defined for the table. All entries must be unique and there=20 > +should be > + /// no gaps. > + ACPI_STRUCT_INFO* Entries; > + /// Total number of unique types defined for the table > + CONST UINT32 EntryCount; > +} ACPI_STRUCT_DATABASE; > + > +/** > + Set all ACPI structure instance counts to 0. > + > + @param [in,out] StructDb ACPI structure database with counts to r= eset. > +**/ > +VOID > +EFIAPI > +ResetAcpiStructCounts ( > + IN OUT ACPI_STRUCT_DATABASE* StructDb > + ); > + > +/** > + Sum all ACPI structure instance counts. > + > + @param [in] StructDb ACPI structure database with per-type counts= to sum. > + > + @return Total number of structure instances recorded in the databas= e. > +**/ > +UINT32 > +EFIAPI > +SumAcpiStructCounts ( > + IN CONST ACPI_STRUCT_DATABASE* StructDb > + ); > + > +/** > + Validate that a structure with a given type value is defined for=20 > +the given > + ACPI table and target architecture. > + > + The target architecture is evaluated from the firmare build parameter= s. > + > + @param [in] Type ACPI-defined structure type. > + @param [in] StructDb ACPI structure database with architecture > + compatibility info. > + > + @retval TRUE Structure is valid. > + @retval FALSE Structure is not valid. > +**/ > +BOOLEAN > +EFIAPI > +IsAcpiStructTypeValid ( > + IN UINT32 Type, > + IN CONST ACPI_STRUCT_DATABASE* StructDb > + ); > + > +/** > + Print the instance count of each structure in an ACPI table that is > + compatible with the target architecture. > + > + For structures which are not allowed for the target architecture,=20 > + validate that their instance counts are 0. > + > + @param [in] StructDb ACPI structure database with counts to valid= ate. > + > + @retval TRUE All structures are compatible. > + @retval FALSE One or more incompatible structures present. > +**/ > +BOOLEAN > +EFIAPI > +ValidateAcpiStructCounts ( > + IN CONST ACPI_STRUCT_DATABASE* StructDb > + ); > + > +/** > + Parse the ACPI structure with the type value given according to=20 > +instructions > + defined in the ACPI structure database. > + > + If the input structure type is defined in the database, increment=20 > + structure's instance count. > + > + If ACPI_PARSER array is used to parse the input structure, the=20 > + index of the structure (instance count for the type before update)=20 > + gets printed alongside the structure name. This helps debugging if=20 > + there are many instances of the type in a table. For=20 > + ACPI_STRUCT_PARSER_FUNC, the printing of the index must be=20 > + implemented > separately. > + > + @param [in] Indent Number of spaces to indent the output. > + @param [in] Ptr Ptr to the start of the structure. > + @param [in,out] StructDb ACPI structure database with instructions o= n how > + parse every structure type. > + @param [in] Offset Structure offset from the start of the tabl= e. > + @param [in] Type ACPI-defined structure type. > + @param [in] Length Length of the structure in bytes. > + @param [in] OptArg0 First optional argument to pass to parser f= unction. > + @param [in] OptArg1 Second optional argument to pass to parser = function. > + > + @retval TRUE ACPI structure parsed successfully. > + @retval FALSE Undefined structure type or insufficient data to pars= e. > +**/ > +BOOLEAN > +EFIAPI > +ParseAcpiStruct ( > + IN UINT32 Indent, > + IN UINT8* Ptr, > + IN OUT ACPI_STRUCT_DATABASE* StructDb, > + IN UINT32 Offset, > + IN UINT32 Type, > + IN UINT32 Length, > + IN CONST VOID* OptArg0 OPTIONAL, > + IN CONST VOID* OptArg1 OPTIONAL > + ); > + > /** > A structure used to store the pointers to the members of the > ACPI description header structure that was parsed. > -- > 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'