From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (EUR04-DB3-obe.outbound.protection.outlook.com [40.107.6.78]) by mx.groups.io with SMTP id smtpd.web11.17184.1597245826361922507 for ; Wed, 12 Aug 2020 08:23:46 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=KX5ek1pn; spf=pass (domain: arm.com, ip: 40.107.6.78, 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=+FUj7411mvbNMA0OnFJTHB68/74neRvxkC3qYnn8KRk=; b=KX5ek1pnmUC35i9Ds/nqnfOQN6xZBvmxl64E6HQzDhSEHeh2sFf7B9chy/2dbKKa2RTCNGB6z/HWLuuEX1CicNQlgZpz1205nNBJsyUo/ILnvk+u6JCfyCRHYF6PHQWmZ2gpEZ3pqoYEArNphgPaNXauUq13auSd6lKlyFX1CYA= Received: from AM5PR0202CA0009.eurprd02.prod.outlook.com (2603:10a6:203:69::19) by DB8PR08MB4025.eurprd08.prod.outlook.com (2603:10a6:10:a9::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3261.22; Wed, 12 Aug 2020 15:23:43 +0000 Received: from VE1EUR03FT014.eop-EUR03.prod.protection.outlook.com (2603:10a6:203:69:cafe::a6) by AM5PR0202CA0009.outlook.office365.com (2603:10a6:203:69::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3283.15 via Frontend Transport; Wed, 12 Aug 2020 15:23:43 +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 VE1EUR03FT014.mail.protection.outlook.com (10.152.19.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3283.16 via Frontend Transport; Wed, 12 Aug 2020 15:23:43 +0000 Received: ("Tessian outbound e8cdb8c6f386:v64"); Wed, 12 Aug 2020 15:23:43 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: e4e423fd4cdf70fc X-CR-MTA-TID: 64aa7808 Received: from 73fb849e2921.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 4778F146-E82F-464A-A4E6-3D98E6DDB186.1; Wed, 12 Aug 2020 15:23:38 +0000 Received: from EUR04-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 73fb849e2921.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Wed, 12 Aug 2020 15:23:38 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=A2UXc21NuRZLZ8KPfVikvFTK1IE87QmvqebIrFJ2RlKXG1xDOhQwF7nB57+M6jp3byY+UNk1v3r2i1/UqSohcQDN91UqXYl6cDF7ZH8vn+CuVUEEgPCxXPwl6PIPE8SgGY5Dmb4/AsiBC7/+vF12v1PQWRS9h4wH5Dzfqcwu2bx/inORspDkCgiX1l6Cugsc854VLqonTfqncuy64Wvy/sfegZsyEm9Dnj3x9RVY1KC8FC3PBx5178xCLpFI+1o6tg/vZcdYs/UvcoQSEeitOdMzB1RHYY8pZiTLZNgI1N2DFNhWUyj3ldqlyxkbQ12jZ6iXtLHA1HF+1VpxTm/Y9w== 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=+FUj7411mvbNMA0OnFJTHB68/74neRvxkC3qYnn8KRk=; b=aXIs+n7Y+plVnnxM2lkSZmQ+OG3emdhN9wpZpubLVNgrHHxQtO3iiSCTrMwwqaESIRrmflIx8UZQDYka03TbOOmEQGANErwMQrZcAT2ShFcMtPexY2djRbBjuZPxu5QCxefOmXbDw/2UDlD4LKOqlSJ8IhctoScV4GjIFXYSnHdjdZZQ7M7QE9mxZYM6oqkpp7kh2vWfzBgfeObIPwwEiZG3iiyM52BUqz0WVT0R9uDm5IYElq42uvHpJbAEfPw2+BwfUHC1h0bgWF0smKnjkmEaTFm2oktQL1uPWjiznzDJ6wrMrK/tfnNPRyt2rGo20Ozr5LV7P3ru6TcAfBjVDQ== 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=bestguesspass 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=+FUj7411mvbNMA0OnFJTHB68/74neRvxkC3qYnn8KRk=; b=KX5ek1pnmUC35i9Ds/nqnfOQN6xZBvmxl64E6HQzDhSEHeh2sFf7B9chy/2dbKKa2RTCNGB6z/HWLuuEX1CicNQlgZpz1205nNBJsyUo/ILnvk+u6JCfyCRHYF6PHQWmZ2gpEZ3pqoYEArNphgPaNXauUq13auSd6lKlyFX1CYA= Received: from DB7PR05CA0001.eurprd05.prod.outlook.com (2603:10a6:10:36::14) by AM6PR08MB3560.eurprd08.prod.outlook.com (2603:10a6:20b:4c::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3283.15; Wed, 12 Aug 2020 15:23:36 +0000 Received: from DB5EUR03FT021.eop-EUR03.prod.protection.outlook.com (2603:10a6:10:36:cafe::8) by DB7PR05CA0001.outlook.office365.com (2603:10a6:10:36::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3283.15 via Frontend Transport; Wed, 12 Aug 2020 15:23:36 +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=bestguesspass 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 DB5EUR03FT021.mail.protection.outlook.com (10.152.20.238) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.3283.16 via Frontend Transport; Wed, 12 Aug 2020 15:23:36 +0000 Received: from AZ-NEU-EX04.Arm.com (10.251.24.32) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Wed, 12 Aug 2020 15:23:34 +0000 Received: from E107187.Arm.com (10.57.41.222) by mail.arm.com (10.251.24.32) with Microsoft SMTP Server id 15.1.2044.4 via Frontend Transport; Wed, 12 Aug 2020 15:23:34 +0000 From: "Sami Mujawar" To: CC: Sami Mujawar , , , , , , Subject: [PATCH v1 20/30] DynamicTablesPkg: AML Field list parser Date: Wed, 12 Aug 2020 16:22:26 +0100 Message-ID: <20200812152236.31164-21-sami.mujawar@arm.com> X-Mailer: git-send-email 2.11.0.windows.3 In-Reply-To: <20200812152236.31164-1-sami.mujawar@arm.com> References: <20200812152236.31164-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: 4a561062-e69d-4f5d-ec6b-08d83ed3b326 X-MS-TrafficTypeDiagnostic: AM6PR08MB3560:|DB8PR08MB4025: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:8273;OLM:8273; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; 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)(396003)(136003)(39860400002)(376002)(346002)(46966005)(81166007)(82310400002)(426003)(4326008)(2616005)(82740400003)(1076003)(356005)(86362001)(36756003)(47076004)(336012)(30864003)(186003)(7696005)(44832011)(70586007)(26005)(5660300002)(8676002)(8936002)(2906002)(83380400001)(6666004)(6916009)(54906003)(70206006)(316002)(478600001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR08MB3560 Return-Path: Sami.Mujawar@arm.com X-MS-Exchange-Transport-CrossTenantHeadersStripped: VE1EUR03FT014.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: d39ee65a-cbf5-4f53-176d-08d83ed3ae9b X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: s+kNhQv9N0xht2A90IhQLLnj9O6hzyz5a2LTadOKaPqkaUCKilrQ6if2klbVPog2PsHURFvLhbijazpn+OqXJZRkOHgjvOkysGl9ZH5PuxgNU3gzdM0wPQy934eLyU7lpp21w6T0YA5gKZTY1srkMEVNTOpP+qCprWGyJmpd3+66sG8IbVQ/DJjOOFfKogEama6TAo4puUNlTtvx3WngpaUJ2JKNjHiNy3dt0+Aozrm9nJIUfSiP0wHSRJOkEqd/2jg+BZBIENSTFNeC5MEagIByVjb37gr0Gs0O5MZ3hi76u5ih2pu8Qm3/f29y1yCQoJYRJTEn0hIq74S9gJKz5jn+ysndJjcwXF75E/R57HruXeuhPCd2/bPvGCMKzAjorqeC1uzCAELOrFrCey4mcQ== 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)(396003)(376002)(346002)(39860400002)(46966005)(478600001)(426003)(54906003)(6916009)(316002)(8936002)(36756003)(83380400001)(8676002)(82310400002)(36906005)(86362001)(2906002)(4326008)(81166007)(47076004)(1076003)(336012)(7696005)(82740400003)(5660300002)(26005)(44832011)(30864003)(2616005)(70586007)(186003)(70206006)(6666004);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Aug 2020 15:23:43.6100 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4a561062-e69d-4f5d-ec6b-08d83ed3b326 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: VE1EUR03FT014.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB8PR08MB4025 Content-Type: text/plain From: Pierre Gondois The AML language allows defining field lists in a Definition Block. Although Dynamic AML does not provide interfaces to modify Field Lists; an AML template code may contain Field lists and the AML parser must be capable of parsing and representing the Field lists in the AML tree. The AML parser creates an Object node that represents the 'Field Node'. The AML Field list parser creates an object node for each field element parsed in the AML byte stream, and adds them to the variable list of arguments of the 'Field Node'. Nodes that can have a field list are referred as 'Field nodes'. They have the AML_HAS_FIELD_LIST attribute set in the AML encoding. According to the ACPI 6.3 specification, s20.2.5.2 "Named Objects Encoding", field elements can be: - NamedField := NameSeg PkgLength; - ReservedField := 0x00 PkgLength; - AccessField := 0x01 AccessType AccessAttrib; - ConnectField := <0x02 NameString> | <0x02 BufferData>; - ExtendedAccessField := 0x03 AccessType ExtendedAccessAttrib AccessLength. A small set of opcodes describes the field elements. They are referred as field opcodes. An AML_BYTE_ENCODING table has been created for field OpCodes. Field elements: - don't have a SubOpCode; - have at most 3 fixed arguments (as opposed to 6 for standard AML objects); - don't have a variable list of arguments; - only the NamedField field element is part of the AML namespace. ConnectField's BufferData is a buffer node containing a single resource data element. NamedField field elements do not have an AML OpCode. NameSeg starts with a Char type and can thus be differentiated from the Opcodes for other fields. A pseudo OpCode has been created to simplify the parser. Following is a representation of a field node in an AML tree: (FieldNode) \ |- [0][1][3] # Fixed Arguments |- {(FldEl0)->(FldEl1)->...)} # Variable Arguments Where FldEl[n] is one of NamedField, ReservedField, AccessField, ConnectField, ExtendedAccessField. Signed-off-by: Pierre Gondois Signed-off-by: Sami Mujawar --- DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.c | 375 ++++++++++++++++++++ DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.h | 77 ++++ 2 files changed, 452 insertions(+) diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.c b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.c new file mode 100644 index 0000000000000000000000000000000000000000..c25ee22dc7c4b22b1448e11cf9bbd4e5e77c4316 --- /dev/null +++ b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.c @@ -0,0 +1,375 @@ +/** @file + AML Field List Parser. + + Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include +#include +#include +#include + +/** Parse a field element. + + The field elements this function can parse are one of: + - ReservedField; + - AccessField; + - ConnectField; + - ExtendedAccessField. + Indeed, the NamedField field element doesn't have an OpCode. Thus it needs + to be parsed differently. + + @param [in] FieldByteEncoding Field byte encoding to parse. + @param [in, out] FieldNode Field node to attach the field + element to. + Must have the AML_HAS_FIELD_LIST + attribute. + @param [in, out] FStream Forward stream pointing to a field + element not being a named field. + The stream must not be at its end. + @param [in, out] NameSpaceRefList List of namespace reference nodes, + allowing to associate an absolute + path to a node in the tree. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_BUFFER_TOO_SMALL No space left in the buffer. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +*/ +STATIC +EFI_STATUS +EFIAPI +AmlParseFieldElement ( + IN CONST AML_BYTE_ENCODING * FieldByteEncoding, + IN OUT AML_OBJECT_NODE * FieldNode, + IN OUT AML_STREAM * FStream, + IN OUT LIST_ENTRY * NameSpaceRefList + ) +{ + EFI_STATUS Status; + + UINT8 * CurrPos; + AML_OBJECT_NODE * NewNode; + + UINT32 PkgLenOffset; + UINT32 PkgLenSize; + + // Check whether the node is an Object Node and has a field list. + // The byte encoding must be a field element. + if ((FieldByteEncoding == NULL) || + ((FieldByteEncoding->Attribute & AML_IS_FIELD_ELEMENT) == 0) || + ((FieldByteEncoding->Attribute & AML_IS_PSEUDO_OPCODE) == + AML_IS_PSEUDO_OPCODE) || + !AmlNodeHasAttribute (FieldNode, AML_HAS_FIELD_LIST) || + !IS_STREAM (FStream) || + IS_END_OF_STREAM (FStream) || + !IS_STREAM_FORWARD (FStream) || + (NameSpaceRefList == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + CurrPos = AmlStreamGetCurrPos (FStream); + if (CurrPos == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Skip the field opcode (1 byte) as it is already in the FieldByteEncoding. + DumpRaw (CurrPos, 1); + Status = AmlStreamProgress (FStream, 1); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + CurrPos = AmlStreamGetCurrPos (FStream); + if (CurrPos == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Parse the PkgLen if available. + PkgLenSize = 0; + if ((FieldByteEncoding->Attribute & AML_HAS_PKG_LENGTH) == + AML_HAS_PKG_LENGTH) { + PkgLenOffset = AmlGetPkgLength (CurrPos, &PkgLenSize); + if (PkgLenOffset == 0) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Move stream forward as the PkgLen has been read. + DumpRaw (CurrPos, PkgLenOffset); + Status = AmlStreamProgress (FStream, PkgLenOffset); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Update the current position as PkgLen has been parsed. + CurrPos = AmlStreamGetCurrPos (FStream); + } + + Status = AmlCreateObjectNode ( + FieldByteEncoding, + PkgLenSize, + &NewNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the FieldElement to the Variable Argument List. + Status = AmlVarListAddTailInternal ( + (AML_NODE_HEADER*)FieldNode, + (AML_NODE_HEADER*)NewNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + // Delete the sub-tree if the insertion failed. + // Otherwise its reference will be lost. + AmlDeleteTree ((AML_NODE_HEADER*)NewNode); + return Status; + } + + // Some field elements do not have fixed arguments. + if (!IS_END_OF_STREAM (FStream)) { + // Parse the fixed arguments of the field element. + Status = AmlParseFixedArguments ( + NewNode, + FStream, + NameSpaceRefList + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + } + } + + return Status; +} + +/** Parse a named field element. + + Indeed, the NamedField field element doesn't have an OpCode. Thus it needs + to be parsed differently. NamedField field element start with a char. + + @param [in] NamedFieldByteEncoding Field byte encoding to parse. + @param [in, out] FieldNode Field node to attach the field + element to. + Must have the AML_HAS_FIELD_LIST + attribute. + @param [in, out] FStream Forward stream pointing to a named + field element. + The stream must not be at its end. + @param [in, out] NameSpaceRefList List of namespace reference nodes, + allowing to associate an absolute + path to a node in the tree. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_BUFFER_TOO_SMALL No space left in the buffer. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +*/ +STATIC +EFI_STATUS +EFIAPI +AmlParseNamedFieldElement ( + IN CONST AML_BYTE_ENCODING * NamedFieldByteEncoding, + IN OUT AML_OBJECT_NODE * FieldNode, + IN OUT AML_STREAM * FStream, + IN OUT LIST_ENTRY * NameSpaceRefList +) +{ + EFI_STATUS Status; + AML_OBJECT_NODE * NewNode; + + // Check whether the node is an Object Node and has a field list. + // The byte encoding must be a char. + if ((NamedFieldByteEncoding == NULL) || + ((NamedFieldByteEncoding->Attribute & AML_IS_NAME_CHAR) == 0) || + !AmlNodeHasAttribute (FieldNode, AML_HAS_FIELD_LIST) || + !IS_STREAM (FStream) || + IS_END_OF_STREAM (FStream) || + !IS_STREAM_FORWARD (FStream) || + (NameSpaceRefList == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Create a NamedField node. + Status = AmlCreateObjectNode ( + AmlGetFieldEncodingByOpCode (AML_FIELD_NAMED_OP, 0), + 0, + &NewNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the NamedField node to the variable argument list. + Status = AmlVarListAddTailInternal ( + (AML_NODE_HEADER*)FieldNode, + (AML_NODE_HEADER*)NewNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + // Delete the sub-tree if the insertion failed. + // Otherwise its reference will be lost. + AmlDeleteTree ((AML_NODE_HEADER*)NewNode); + return Status; + } + + // Parse the fixed arguments: [0]NameSeg, [1]PkgLen. + Status = AmlParseFixedArguments ( + NewNode, + FStream, + NameSpaceRefList + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the NamedField to the namespace reference list. + Status = AmlAddNameSpaceReference ( + NewNode, + NameSpaceRefList + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** Parse the FieldList contained in the stream. + + Create an object node for each field element parsed in the field list + available in the Stream, and add them to the variable list of arguments + of the FieldNode. + + Nodes that can have a field list are referred as field nodes. They have the + AML_HAS_FIELD_LIST attribute. + + According to the ACPI 6.3 specification, s20.2.5.2 "Named Objects Encoding", + field elements can be: + - NamedField := NameSeg PkgLength; + - ReservedField := 0x00 PkgLength; + - AccessField := 0x01 AccessType AccessAttrib; + - ConnectField := <0x02 NameString> | <0x02 BufferData>; + - ExtendedAccessField := 0x03 AccessType ExtendedAccessAttrib AccessLength. + + A small set of opcodes describes the field elements. They are referred as + field opcodes. An AML_BYTE_ENCODING table has been created for field OpCodes. + Field elements: + - don't have a SubOpCode; + - have at most 3 fixed arguments (as opposed to 6 for standard AML objects); + - don't have a variable list of arguments; + - only the NamedField field element is part of the AML namespace. + + ConnectField's BufferData is a buffer node containing a single + resource data element. + NamedField field elements don't have an AML OpCode. NameSeg starts with a + Char type and can thus be differentiated from the Opcodes for other fields. + A pseudo OpCode has been created to simplify the parser. + + The branch created from parsing a field node is as: + (FieldNode) + \ + |- [FixedArg[0]][FixedArg[1]] # Fixed Arguments + |- {(FieldElement[0])->(FieldElement[1])->...)} # Variable Arguments + + With FieldElement[n] being one of NamedField, ReservedField, AccessField, + ConnectField, ExtendedAccessField. + + @param [in] FieldNode Field node. + Must have the AML_HAS_FIELD_LIST + attribute. + @param [in] FStream Forward stream pointing to a field list. + The stream must not be at its end. + @param [in] NameSpaceRefList List of namespace reference nodes, + allowing to associate an absolute + path to a node in the tree. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_BUFFER_TOO_SMALL No space left in the buffer. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +EFI_STATUS +EFIAPI +AmlParseFieldList ( + IN AML_OBJECT_NODE * FieldNode, + IN AML_STREAM * FStream, + IN LIST_ENTRY * NameSpaceRefList + ) +{ + EFI_STATUS Status; + + UINT8 * CurrPos; + CONST AML_BYTE_ENCODING * FieldByteEncoding; + CONST AML_BYTE_ENCODING * NamedFieldByteEncoding; + + // Check whether the node is an Object Node and has a field list. + if (!AmlNodeHasAttribute (FieldNode, AML_HAS_FIELD_LIST) || + !IS_STREAM (FStream) || + IS_END_OF_STREAM (FStream) || + !IS_STREAM_FORWARD (FStream) || + (NameSpaceRefList == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Iterate through the field elements, creating nodes + // and adding them to the variable list of elements of Node. + while (!IS_END_OF_STREAM (FStream)) { + CurrPos = AmlStreamGetCurrPos (FStream); + + // Check for a field opcode. + FieldByteEncoding = AmlGetFieldEncoding (CurrPos); + if (FieldByteEncoding != NULL) { + Status = AmlParseFieldElement ( + FieldByteEncoding, + FieldNode, + FStream, + NameSpaceRefList + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } else { + // Handle the case of Pseudo OpCodes. + // NamedField has a Pseudo OpCode and starts with a NameChar. Therefore, + // call AmlGetByteEncoding() to check that the encoding is NameChar. + NamedFieldByteEncoding = AmlGetByteEncoding (CurrPos); + if ((NamedFieldByteEncoding != NULL) && + (NamedFieldByteEncoding->Attribute & AML_IS_NAME_CHAR)) { + // This is a NamedField field element since it is starting with a char. + Status = AmlParseNamedFieldElement ( + NamedFieldByteEncoding, + FieldNode, + FStream, + NameSpaceRefList + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } else { + // A field opcode or an AML byte encoding is expected. + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + } + } // while + + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.h b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.h new file mode 100644 index 0000000000000000000000000000000000000000..576f6c41d5620468b524b62684f67af1dacee24d --- /dev/null +++ b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlFieldListParser.h @@ -0,0 +1,77 @@ +/** @file + AML Field List. + + Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef AML_FIELD_LIST_PARSER_H_ +#define AML_FIELD_LIST_PARSER_H_ + +#include +#include + +/** Parse the FieldList contained in the stream. + + Create an object node for each field element parsed in the field list + available in the Stream, and add them to the variable list of arguments + of the FieldNode. + + Nodes that can have a field list are referred as field nodes. They have the + AML_HAS_FIELD_LIST attribute. + + According to the ACPI 6.3 specification, s20.2.5.2 "Named Objects Encoding", + field elements can be: + - NamedField := NameSeg PkgLength; + - ReservedField := 0x00 PkgLength; + - AccessField := 0x01 AccessType AccessAttrib; + - ConnectField := <0x02 NameString> | <0x02 BufferData>; + - ExtendedAccessField := 0x03 AccessType ExtendedAccessAttrib AccessLength. + + A small set of opcodes describes the field elements. They are referred as + field opcodes. An AML_BYTE_ENCODING table has been created for field OpCodes. + Field elements: + - don't have a SubOpCode; + - have at most 3 fixed arguments (as opposed to 6 for standard AML objects); + - don't have a variable list of arguments; + - only the NamedField field element is part of the AML namespace. + + ConnectField's BufferData is a buffer node containing a single + resource data element. + NamedField field elements don't have an AML OpCode. NameSeg starts with a + Char type and can thus be differentiated from the Opcodes for other fields. + A pseudo OpCode has been created to simplify the parser. + + The branch created from parsing a field node is as: + (FieldNode) + \ + |- [FixedArg[0]][FixedArg[1]] # Fixed Arguments + |- {(FieldElement[0])->(FieldElement[1])->...)} # Variable Arguments + + With FieldElement[n] being one of NamedField, ReservedField, AccessField, + ConnectField, ExtendedAccessField. + + @param [in] FieldNode Field node. + Must have the AML_HAS_FIELD_LIST + attribute. + @param [in] FStream Forward stream pointing to a field list. + The stream must not be at its end. + @param [in] NameSpaceRefList List of namespace reference nodes, + allowing to associate an absolute + path to a node in the tree. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_BUFFER_TOO_SMALL No space left in the buffer. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +EFI_STATUS +EFIAPI +AmlParseFieldList ( + IN AML_OBJECT_NODE * FieldNode, + IN AML_STREAM * FStream, + IN LIST_ENTRY * NameSpaceRefList + ); + +#endif // AML_FIELD_LIST_PARSER_H_ -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'