From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (EUR04-VI1-obe.outbound.protection.outlook.com [40.107.8.55]) by mx.groups.io with SMTP id smtpd.web12.16974.1597245814871165458 for ; Wed, 12 Aug 2020 08:23:35 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=j59Ja8SD; spf=pass (domain: arm.com, ip: 40.107.8.55, 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=/ES7mQNOnXecVqvlmqz5j+cxs8S6sW9X5adCB4BBW84=; b=j59Ja8SDoUyxbgxCPC4PAvilRCu1Fb3ARGlgd3OT8F1ACywYgX2iOSeZ0TmR+rVRx8iytJ7cSmGSG5L1BaEwE/vXY3Mdlw4RKrd/t8q1H9WS7QNir4Nrs7Fw8MzI8+IJsl85nIl4RgpcIyfRKYOa2xuc+0FbzeHVltWbaGH7Niw= Received: from AM5PR0402CA0002.eurprd04.prod.outlook.com (2603:10a6:203:90::12) by DBBPR08MB4726.eurprd08.prod.outlook.com (2603:10a6:10:f0::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3261.16; Wed, 12 Aug 2020 15:23:30 +0000 Received: from AM5EUR03FT059.eop-EUR03.prod.protection.outlook.com (2603:10a6:203:90:cafe::4) by AM5PR0402CA0002.outlook.office365.com (2603:10a6:203:90::12) 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:30 +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 AM5EUR03FT059.mail.protection.outlook.com (10.152.17.193) 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:30 +0000 Received: ("Tessian outbound e8cdb8c6f386:v64"); Wed, 12 Aug 2020 15:23:30 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 04acb9250c3a939f X-CR-MTA-TID: 64aa7808 Received: from a6d21fb28bac.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id EE45680E-A859-4FA5-88F3-337866ABD8EE.1; Wed, 12 Aug 2020 15:23:25 +0000 Received: from EUR02-AM5-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id a6d21fb28bac.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Wed, 12 Aug 2020 15:23:25 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=awKC5t0bXVQIPjm/zI4nFgZFpR/ZhRWIAcnJe1weKs0mRWnQcgE5BubzrjK4ulWGp4TBv6XPE58gg2baNorWpef8Sw6VSvT1kyf8+cJYIV4eeKrMsFQuNBaZPudBjSlNYVUZL2IDRWDzmoWeYC//c+N/ASyZlrX57HrJtlgiuJ7KzqVTWNWC58oIMXT+gtpkEkok9cgvxGNLVEs1Yi6Nos0gKDMdgZbpuRYrgEHJEag/PN7uIbdRRYBnowBnedcmM7ETiN8tPUbXJC7wzRcbbCtaKXHNKSiKICiW7uKaVx2FY+Qub3/U2nm1EURIen+7KgAP7hEj7ZAPB003nIFtfQ== 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=/ES7mQNOnXecVqvlmqz5j+cxs8S6sW9X5adCB4BBW84=; b=CkPM0CNClSi5uNDXoUdIfFkUYOE6pEnqPLHIAL7rEZQMQ6/T/R0avD3fOGqeaaA98VocN6/8xmfVx8xLjz0JP0WScyYCOQsBnzmyG5qwNzq0023ugBUg0o4ryp7HXaPA/YzN+FqAf6p1UDLCO9S4VNs2cztcp5hzkDcehuS+MSnabPrfuHD09EPO8GHGb22ZaLRe5dIrSAgDm7FZO1FrbHtzlXK7vA4MUnzxM44KVqfQ2VmKh7vd5uVWUkRNKikVq7uAETboGLqEmOBbl4LGUjwKLMjsG4w0bRFFaqC72ydf4GQ+lRX3FejuO6OlVC9iRUsxYqb7ao2ORLYJ6tadww== 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=/ES7mQNOnXecVqvlmqz5j+cxs8S6sW9X5adCB4BBW84=; b=j59Ja8SDoUyxbgxCPC4PAvilRCu1Fb3ARGlgd3OT8F1ACywYgX2iOSeZ0TmR+rVRx8iytJ7cSmGSG5L1BaEwE/vXY3Mdlw4RKrd/t8q1H9WS7QNir4Nrs7Fw8MzI8+IJsl85nIl4RgpcIyfRKYOa2xuc+0FbzeHVltWbaGH7Niw= Received: from DB6P193CA0013.EURP193.PROD.OUTLOOK.COM (2603:10a6:6:29::23) by DBBPR08MB4839.eurprd08.prod.outlook.com (2603:10a6:10:da::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3261.18; Wed, 12 Aug 2020 15:23:22 +0000 Received: from DB5EUR03FT018.eop-EUR03.prod.protection.outlook.com (2603:10a6:6:29:cafe::b) by DB6P193CA0013.outlook.office365.com (2603:10a6:6:29::23) 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:22 +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 DB5EUR03FT018.mail.protection.outlook.com (10.152.20.69) 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:22 +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:19 +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:18 +0000 From: "Sami Mujawar" To: CC: Sami Mujawar , , , , , , Subject: [PATCH v1 11/30] DynamicTablesPkg: AML and ASL string helper Date: Wed, 12 Aug 2020 16:22:17 +0100 Message-ID: <20200812152236.31164-12-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: 90bf6050-6cb7-4b14-5c6d-08d83ed3ab72 X-MS-TrafficTypeDiagnostic: DBBPR08MB4839:|DBBPR08MB4726: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:172;OLM:172; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: EhlMlGsQDIWRHdqKYuxgthLuASVlhegcTvrPOQitloBwqXgEteTX+LEVDCNnN178E+b7N+IDq3XJJTblMN6HofJVqX3LaeLWRD66vB+gbsMFGNdaLri2wWg37PwHBjW8yL4OlN+MbH9rHxDkF7YXM+eKC7GyPN7s5VwgQMScJTE+h/r62JOGn1qH3aksDspCW14wpxdxe0BLQFg1VJzWPLz6Y0/uWX+MyxmMplf/UzaiE+tDOZs/0nAlmTc82eWvlU4dYS5Detaike5IDpv9RN9YIikBpSs0iNWqxlFCrliuq64HgRfElZvK6a/YrCWLFwCFqRheu9y+qGrHZI5a3h7eq1mJYB8kU8jJE81EhabiJNBRLiB/t353359jaFYepBIeRJeVccoS39GmGltaBw== 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;SFTY:;SFS:(4636009)(396003)(39860400002)(376002)(136003)(346002)(46966005)(36756003)(426003)(2616005)(5660300002)(336012)(356005)(44832011)(7696005)(26005)(86362001)(83380400001)(82740400003)(82310400002)(81166007)(47076004)(186003)(1076003)(316002)(2906002)(54906003)(30864003)(478600001)(70206006)(6916009)(8676002)(4326008)(8936002)(70586007)(579004);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBBPR08MB4839 Return-Path: Sami.Mujawar@arm.com X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM5EUR03FT059.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: 63547d22-cb74-438c-732f-08d83ed3a67b X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: i8rtzXV21JN+R+yBcS1bHiFinXfDJeOMgkCECyMkJFqb+HskFidY7f+DqmomoDU0tPdevmGVEynekXRB3SxV8ed4d356h3TwvvT8ktBOTXe7x3RXooQFzsD/PJZaqglhtZmr3I+4X9xS3k66WeeMUcw/LnLwvD2mu2Xe/nIDi1qHpr6svVi/ffmjKDGlJUdCEWCNAGUrMI/MWM2m+mbSX9tYYmawR/d4dhF6YLszGbsYe/as3HOSJ6SsH5V2efPVROyW9h7wVRNSwvzEEYmI6ouQgdkv48/kM2zCIKIcSyAmNErQAr40G+SpyGQ9e+mUkFNV/xWTeaZ+JiwSETwMOqqyubOrjwaSM18tXkQ4lNH5g4CQdvdGROaK4kNXVdAV++N0CQ9Ex6YItgcZYX+s5A== 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)(376002)(346002)(396003)(39860400002)(136003)(46966005)(86362001)(8936002)(8676002)(83380400001)(82310400002)(426003)(2906002)(54906003)(7696005)(36756003)(478600001)(81166007)(336012)(5660300002)(47076004)(70206006)(4326008)(70586007)(44832011)(2616005)(1076003)(82740400003)(316002)(186003)(26005)(36906005)(6916009)(30864003)(579004);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Aug 2020 15:23:30.7635 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 90bf6050-6cb7-4b14-5c6d-08d83ed3ab72 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: AM5EUR03FT059.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBBPR08MB4726 Content-Type: text/plain From: Pierre Gondois Dynamic AML requires encoding/decoding and conversion of AML and ASL strings. A collection of helper functions have been provided for internal use in the AmlLib Library. Signed-off-by: Pierre Gondois Signed-off-by: Sami Mujawar --- DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.c | 1022 ++++++++++++++++++++ DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.h | 401 ++++++++ 2 files changed, 1423 insertions(+) diff --git a/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.c b/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.c new file mode 100644 index 0000000000000000000000000000000000000000..e9d36f4b6c710cc9a22968d234bb4be720523bb4 --- /dev/null +++ b/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.c @@ -0,0 +1,1022 @@ +/** @file + AML String. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include + +/** Check NameString/path information is valid. + + Root, ParentPrefix and SegCount cannot be 0 at the same time. + This function works for ASL and AML name strings. + + @param [in] Root Number of root char. + Must be 0 or 1. + @param [in] ParentPrefix Number of carets char ('^'). + Must be [0-255]. + @param [in] SegCount Number of NameSeg (s). + Must be [0-255]. + + @retval TRUE id the input information is in the right boundaries. + FALSE otherwise. +**/ +BOOLEAN +EFIAPI +AmlIsNameString ( + IN UINT32 Root, + IN UINT32 ParentPrefix, + IN UINT32 SegCount + ) +{ + if (((Root == 0) || (Root == 1)) && + (ParentPrefix <= MAX_UINT8) && + (!((ParentPrefix != 0) && (Root != 0))) && + (SegCount <= MAX_UINT8) && + ((SegCount + Root + ParentPrefix) != 0)) { + return TRUE; + } + return FALSE; +} + +/** Copy bytes from SrcBuffer to DstBuffer and convert to upper case. + Don't copy more than MaxDstBufferSize bytes. + + @param [out] DstBuffer Destination buffer. + @param [in] MaxDstBufferSize Maximum size of DstBuffer. + Must be non-zero. + @param [in] SrcBuffer Source buffer. + @param [in] Count Count of bytes to copy from SrcBuffer. + Return success if 0. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlUpperCaseMemCpyS ( + OUT CHAR8 * DstBuffer, + IN UINT32 MaxDstBufferSize, + IN CONST CHAR8 * SrcBuffer, + IN UINT32 Count + ) +{ + UINT32 Index; + + if ((DstBuffer == NULL) || + (SrcBuffer == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + if (Count == 0) { + return EFI_SUCCESS; + } + + if (Count > MaxDstBufferSize) { + Count = MaxDstBufferSize; + } + + for (Index = 0; Index < Count; Index++) { + if ((SrcBuffer[Index] >= 'a') && (SrcBuffer[Index] <= 'z')) { + DstBuffer[Index] = (CHAR8)((UINT8)SrcBuffer[Index] - ('a' - 'A')); + } else { + DstBuffer[Index] = SrcBuffer[Index]; + } + } + + return EFI_SUCCESS; +} + +/** Check whether Buffer is a root path ('\'). + + This function works for both ASL and AML pathnames. + Buffer must be at least 2 bytes long. + + @param [in] Buffer An ASL/AML path. + + @retval TRUE Buffer is a root path + @retval FALSE Buffer is not a root path. +**/ +BOOLEAN +EFIAPI +AmlIsRootPath ( + IN CONST CHAR8 * Buffer + ) +{ + if (Buffer == NULL) { + return FALSE; + } + + if ((Buffer[0] == AML_ROOT_CHAR) && (Buffer[1] == '\0')) { + return TRUE; + } else { + return FALSE; + } +} + +/** Check whether Ch is an ASL/AML LeadName. + + This function works for both ASL and AML pathnames. + + ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms": + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + + ACPI 6.3 specification, s20.2.2. "Name Objects Encoding": + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + + @param [in] Ch The char to test. + + @retval TRUE Ch is an ASL/AML LeadName. + @retval FALSE Ch is not an ASL/AML LeadName. +**/ +BOOLEAN +EFIAPI +AmlIsLeadNameChar ( + IN CHAR8 Ch + ) +{ + if ((Ch == '_') || (Ch >= 'A' && Ch <= 'Z') || (Ch >= 'a' && Ch <= 'z')) { + return TRUE; + } else { + return FALSE; + } +} + +/** Check whether Ch is an ASL/AML NameChar. + + This function works for both ASL and AML pathnames. + + ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms": + NameChar := DigitChar | LeadNameChar + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + DigitChar := '0'-'9' + + ACPI 6.3 specification, s20.2.2. "Name Objects Encoding": + NameChar := DigitChar | LeadNameChar + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + DigitChar := '0'-'9' + + @param [in] Ch The char to test. + + @retval TRUE Ch is an ASL/AML NameChar. + @retval FALSE Ch is not an ASL/AML NameChar. +**/ +BOOLEAN +EFIAPI +AmlIsNameChar ( + IN CHAR8 Ch + ) +{ + if (AmlIsLeadNameChar (Ch) || (Ch >= '0' && Ch <= '9')) { + return TRUE; + } else { + return FALSE; + } +} + +/** Check whether AslBuffer is an ASL NameSeg. + + This function only works for ASL NameStrings/pathnames. + ASL NameStrings/pathnames are at most 4 chars long. + + @param [in] AslBuffer Pointer in an ASL NameString/pathname. + @param [out] Size Size of the NameSeg. + + @retval TRUE AslBuffer is an ASL NameSeg. + @retval FALSE AslBuffer is not an ASL NameSeg. +**/ +BOOLEAN +EFIAPI +AslIsNameSeg ( + IN CONST CHAR8 * AslBuffer, + OUT UINT32 * Size + ) +{ + UINT32 Index; + + if ((AslBuffer == NULL) || + (Size == NULL)) { + return FALSE; + } + + if (!AmlIsLeadNameChar (AslBuffer[0])) { + return FALSE; + } + + for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) { + if ((AslBuffer[Index] == '.') || + (AslBuffer[Index] == '\0')) { + *Size = Index; + return TRUE; + } else if (!AmlIsNameChar (AslBuffer[Index])) { + return FALSE; + } + } + + *Size = Index; + return TRUE; +} + +/** Check whether AmlBuffer is an AML NameSeg. + + This function only works for AML NameStrings/pathnames. + AML NameStrings/pathnames must be 4 chars long. + + @param [in] AmlBuffer Pointer in an AML NameString/pathname. + + @retval TRUE AmlBuffer is an AML NameSeg. + @retval FALSE AmlBuffer is not an AML NameSeg. +**/ +BOOLEAN +EFIAPI +AmlIsNameSeg ( + IN CONST CHAR8 * AmlBuffer + ) +{ + UINT32 Index; + + if (AmlBuffer == NULL) { + return FALSE; + } + + if (!AmlIsLeadNameChar (AmlBuffer[0])) { + return FALSE; + } + + for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) { + if (!AmlIsNameChar (AmlBuffer[Index])) { + return FALSE; + } + } + + return TRUE; +} + +/** Parse an ASL NameString/path. + + An ASL NameString/path must be NULL terminated. + Information found in the ASL NameString/path is returned via pointers: + Root, ParentPrefix, SegCount. + + @param [in] Buffer ASL NameString/path. + @param [out] Root Pointer holding the number of root char. + Can be 0 or 1. + @param [out] ParentPrefix Pointer holding the number of carets char ('^'). + Can be [0-255]. + @param [out] SegCount Pointer holding the number of NameSeg (s). + Can be [0-255]. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AslParseNameStringInfo ( + IN CONST CHAR8 * Buffer, + OUT UINT32 * Root, + OUT UINT32 * ParentPrefix, + OUT UINT32 * SegCount + ) +{ + UINT32 NameSegSize; + + if ((Buffer == NULL) || + (Root == NULL) || + (ParentPrefix == NULL) || + (SegCount == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + *Root = 0; + *ParentPrefix = 0; + *SegCount = 0; + + // Handle Root and ParentPrefix(s). + if (*Buffer == AML_ROOT_CHAR) { + *Root = 1; + Buffer++; + } else if (*Buffer == AML_PARENT_PREFIX_CHAR) { + do { + Buffer++; + (*ParentPrefix)++; + } while (*Buffer == AML_PARENT_PREFIX_CHAR); + } + + // Handle SegCount(s). + while (AslIsNameSeg (Buffer, &NameSegSize)) { + // Safety checks on NameSegSize. + if ((NameSegSize == 0) || (NameSegSize > AML_NAME_SEG_SIZE)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Increment the NameSeg count. + (*SegCount)++; + Buffer += NameSegSize; + + // Skip the '.' separator if present. + if (*Buffer == '.') { + Buffer++; + } + } // while + + // An ASL NameString/path must be NULL terminated. + if (*Buffer != '\0') { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + if (!AmlIsNameString (*Root, *ParentPrefix, *SegCount)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** Parse an AML NameString/path. + + It is possible to determine the size of an AML NameString/path just + by sight reading it. So no overflow can occur. + Information found in the AML NameString/path is returned via pointers: + Root, ParentPrefix, SegCount. + + @param [in] Buffer AML NameString/path. + @param [out] Root Pointer holding the number of root char. + Can be 0 or 1. + @param [out] ParentPrefix Pointer holding the number of carets char ('^'). + Can be [0-255]. + @param [out] SegCount Pointer holding the number of NameSeg(s). + Can be [0-255]. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlParseNameStringInfo ( + IN CONST CHAR8 * Buffer, + OUT UINT32 * Root, + OUT UINT32 * ParentPrefix, + OUT UINT32 * SegCount + ) +{ + if ((Buffer == NULL) || + (Root == NULL) || + (ParentPrefix == NULL) || + (SegCount == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + *Root = 0; + *ParentPrefix = 0; + *SegCount = 0; + + // Handle Root and ParentPrefix(s). + if (*Buffer == AML_ROOT_CHAR) { + *Root = 1; + Buffer++; + } else if (*Buffer == AML_PARENT_PREFIX_CHAR) { + do { + Buffer++; + (*ParentPrefix)++; + } while (*Buffer == AML_PARENT_PREFIX_CHAR); + } + + // Handle SegCount(s). + if (*Buffer == AML_DUAL_NAME_PREFIX) { + *SegCount = 2; + } else if (*Buffer == AML_MULTI_NAME_PREFIX) { + *SegCount = *((UINT8*)(Buffer + 1)); + } else if (AmlIsNameSeg (Buffer)) { + *SegCount = 1; + } else if (*Buffer == AML_ZERO_OP) { + *SegCount = 0; + } else { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Safety checks on exit. + if (!AmlIsNameString (*Root, *ParentPrefix, *SegCount)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** Compute the ASL NameString/path size from NameString + information (Root, ParentPrefix, SegCount). + + @param [in] Root Number of root char. + Can be 0 or 1. + @param [in] ParentPrefix Number of carets char ('^'). + Can be [0-255]. + @param [in] SegCount Pointer holding the number of NameSeg(s). + Can be [0-255]. + + @return Size of the ASL NameString/path. +**/ +UINT32 +EFIAPI +AslComputeNameStringSize ( + IN UINT32 Root, + IN UINT32 ParentPrefix, + IN UINT32 SegCount + ) +{ + UINT32 TotalSize; + + if (!AmlIsNameString (Root, ParentPrefix, SegCount)) { + ASSERT (0); + return 0; + } + + // Root and ParentPrefix(s). + TotalSize = Root + ParentPrefix; + + // Add size required for NameSeg(s). + TotalSize += (SegCount * AML_NAME_SEG_SIZE); + + // Add size required for '.' separator(s). + TotalSize += (SegCount > 1) ? (SegCount - 1) : 0; + + // Add 1 byte for NULL termination '\0'. + TotalSize += 1; + + return TotalSize; +} + +/** Compute the AML NameString/path size from NameString + information (Root, ParentPrefix, SegCount). + + @param [in] Root Number of root char. + Can be 0 or 1. + @param [in] ParentPrefix Number of carets char ('^'). + Can be [0-255]. + @param [in] SegCount Pointer holding the number of NameSeg(s). + Can be [0-255]. + + @return Size of the AML NameString/path. +**/ +UINT32 +EFIAPI +AmlComputeNameStringSize ( + IN UINT32 Root, + IN UINT32 ParentPrefix, + IN UINT32 SegCount + ) +{ + UINT32 TotalSize; + + if (!AmlIsNameString (Root, ParentPrefix, SegCount)) { + ASSERT (0); + return 0; + } + + // Root and ParentPrefix(s). + TotalSize = Root + ParentPrefix; + + // If SegCount == 0, '\0' must end the AML NameString/path. + TotalSize += (SegCount == 0) ? 1 : (SegCount * AML_NAME_SEG_SIZE); + + // AML prefix. SegCount > 2 = MultiNamePrefix, SegCount = 2 DualNamePrefix. + TotalSize += (SegCount > 2) ? 2 : ((SegCount == 2) ? 1 : 0); + + return TotalSize; +} + +/** Get the ASL NameString/path size. + + @param [in] AslPath An ASL NameString/path. + @param [out] AslPathSizePtr Pointer holding the ASL NameString/path size. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AslGetNameStringSize ( + IN CONST CHAR8 * AslPath, + OUT UINT32 * AslPathSizePtr + ) +{ + if ((AslPath == NULL) || + (AslPathSizePtr == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + *AslPathSizePtr = 0; + do { + (*AslPathSizePtr)++; + AslPath++; + } while (*AslPath != '\0'); + + return EFI_SUCCESS; +} + +/** Get the AML NameString/path size. + + @param [in] AmlPath An AML NameString/path. + @param [out] AmlPathSizePtr Pointer holding the AML NameString/path size. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlGetNameStringSize ( + IN CONST CHAR8 * AmlPath, + OUT UINT32 * AmlPathSizePtr + ) +{ + EFI_STATUS Status; + + UINT32 Root; + UINT32 ParentPrefix; + UINT32 SegCount; + + if ((AmlPath == NULL) || + (AmlPathSizePtr == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Status = AmlParseNameStringInfo ( + AmlPath, + &Root, + &ParentPrefix, + &SegCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + *AmlPathSizePtr = AmlComputeNameStringSize (Root, ParentPrefix, SegCount); + if (*AmlPathSizePtr == 0) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + return Status; +} + +/** Convert an ASL NameString/path to an AML NameString/path. + The caller must free the memory allocated in this function + for AmlPath using FreePool (). + + @param [in] AslPath An ASL NameString/path. + @param [out] OutAmlPath Buffer containing the AML path. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +ConvertAslNameToAmlName ( + IN CONST CHAR8 * AslPath, + OUT CHAR8 ** OutAmlPath + ) +{ + EFI_STATUS Status; + + UINT32 Root; + UINT32 ParentPrefix; + UINT32 SegCount; + UINT32 TotalSize; + UINT32 NameSegSize; + + CONST CHAR8 * AslBuffer; + CHAR8 * AmlBuffer; + CHAR8 * AmlPath; + + if ((AslPath == NULL) || + (OutAmlPath == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // Analyze AslPath. AslPath is checked in the call. + Status = AslParseNameStringInfo (AslPath, &Root, &ParentPrefix, &SegCount); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Compute TotalSize. + TotalSize = AmlComputeNameStringSize (Root, ParentPrefix, SegCount); + if (TotalSize == 0) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Allocate memory. + AmlPath = AllocateZeroPool (TotalSize); + if (AmlPath == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + AmlBuffer = AmlPath; + AslBuffer = AslPath; + + // Handle Root and ParentPrefix(s). + if (Root == 1) { + *AmlBuffer = AML_ROOT_CHAR; + AmlBuffer++; + AslBuffer++; + } else if (ParentPrefix > 0) { + SetMem (AmlBuffer, ParentPrefix, AML_PARENT_PREFIX_CHAR); + AmlBuffer += ParentPrefix; + AslBuffer += ParentPrefix; + } + + // Handle prefix and SegCount(s). + if (SegCount > 2) { + *AmlBuffer = AML_MULTI_NAME_PREFIX; + AmlBuffer++; + *AmlBuffer = (UINT8)SegCount; + AmlBuffer++; + } else if (SegCount == 2) { + *AmlBuffer = AML_DUAL_NAME_PREFIX; + AmlBuffer++; + } + + if (SegCount != 0) { + // Write NameSeg(s). + while (1) { + SegCount--; + + // Get the NameSeg size. + if (!AslIsNameSeg (AslBuffer, &NameSegSize)) { + ASSERT (0); + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + // Convert to Upper case and copy. + Status = AmlUpperCaseMemCpyS ( + AmlBuffer, + TotalSize, + AslBuffer, + NameSegSize + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto error_handler; + } + + // Complete the NameSeg with an underscore ('_') if shorter than 4 bytes. + SetMem ( + AmlBuffer + NameSegSize, + AML_NAME_SEG_SIZE - NameSegSize, + AML_NAME_CHAR__ + ); + + // Go to the next NameSeg. + AmlBuffer += AML_NAME_SEG_SIZE; + AslBuffer += NameSegSize; + + // Skip the '.' separator. + if (SegCount != 0) { + if (*AslBuffer == '.') { + AslBuffer++; + } else { + ASSERT (0); + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + } else { + // (SegCount == 0) + if (*AslBuffer == '\0') { + break; + } else { + ASSERT (0); + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + } + } // while + + } else { + // (SegCount == 0) + // '\0' needs to end the AML NameString/path. + *AmlBuffer = AML_ZERO_OP; + AmlBuffer++; + } + + // Safety checks on exit. + // Check that AmlPath has been filled with TotalSize bytes. + if ((SegCount != 0) || + (*AslBuffer != AML_ZERO_OP) || + (((UINT32)(AmlBuffer - AmlPath)) != TotalSize)) { + ASSERT (0); + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + *OutAmlPath = AmlPath; + return EFI_SUCCESS; + +error_handler: + FreePool (AmlPath); + return Status; +} + +/** Convert an AML NameString/path to an ASL NameString/path. + The caller must free the memory allocated in this function. + using FreePool (). + + @param [in] AmlPath An AML NameString/path. + @param [out] OutAslPath Buffer containing the ASL path. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +ConvertAmlNameToAslName ( + IN CONST CHAR8 * AmlPath, + OUT CHAR8 ** OutAslPath + ) +{ + EFI_STATUS Status; + + UINT32 Root; + UINT32 ParentPrefix; + UINT32 SegCount; + UINT32 TotalSize; + + CONST CHAR8 * AmlBuffer; + CHAR8 * AslBuffer; + CHAR8 * AslPath; + + if ((AmlPath == NULL) || + (OutAslPath == NULL)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Analyze AslPath. AmlPath is checked in the call. + Status = AmlParseNameStringInfo (AmlPath, &Root, &ParentPrefix, &SegCount); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Compute TotalSize. + TotalSize = AslComputeNameStringSize (Root, ParentPrefix, SegCount); + if (TotalSize == 0) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Allocate memory. + AslPath = AllocateZeroPool (TotalSize); + if (AslPath == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + AmlBuffer = AmlPath; + AslBuffer = AslPath; + + // Handle prefix and SegCount(s). + if (Root == 1) { + *AslBuffer = AML_ROOT_CHAR; + AslBuffer++; + AmlBuffer++; + } else if (ParentPrefix > 0) { + SetMem (AslBuffer, ParentPrefix, AML_PARENT_PREFIX_CHAR); + AslBuffer += ParentPrefix; + AmlBuffer += ParentPrefix; + } + + // Handle Root and Parent(s). + // Skip the MultiName or DualName prefix chars. + if (SegCount > 2) { + AmlBuffer += 2; + } else if (SegCount == 2) { + AmlBuffer += 1; + } + + // Write NameSeg(s). + while (SegCount) { + // NameSeg is already in upper case and always 4 bytes long. + CopyMem (AslBuffer, AmlBuffer, AML_NAME_SEG_SIZE); + AslBuffer += AML_NAME_SEG_SIZE; + AmlBuffer += AML_NAME_SEG_SIZE; + + SegCount--; + + // Write the '.' separator if there is another NameSeg following. + if (SegCount != 0) { + *AslBuffer = '.'; + AslBuffer++; + } + } // while + + // NULL terminate the ASL NameString. + *AslBuffer = '\0'; + AslBuffer++; + + // Safety checks on exit. + // Check that AslPath has been filled with TotalSize bytes. + if (((UINT32)(AslBuffer - AslPath)) != TotalSize) { + ASSERT (0); + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + *OutAslPath = AslPath; + return EFI_SUCCESS; + +error_handler: + FreePool (AslPath); + return Status; +} + +/** Compare two ASL NameStrings. + + @param [in] AslName1 First NameString to compare. + @param [in] AslName2 Second NameString to compare. + + @retval TRUE if the two strings are identical. + @retval FALSE otherwise, or if error. +**/ +BOOLEAN +EFIAPI +AslCompareNameString ( + IN CONST CHAR8 * AslName1, + IN CONST CHAR8 * AslName2 + ) +{ + EFI_STATUS Status; + UINT32 AslName1Len; + UINT32 AslName2Len; + + if ((AslName1 == NULL) || + (AslName2 == NULL)) { + ASSERT (0); + return FALSE; + } + + Status = AslGetNameStringSize (AslName1, &AslName1Len); + if (EFI_ERROR (Status)) { + ASSERT (0); + return FALSE; + } + + Status = AslGetNameStringSize (AslName2, &AslName2Len); + if (EFI_ERROR (Status)) { + ASSERT (0); + return FALSE; + } + + // AslName1 and AslName2 don't have the same length + if (AslName1Len != AslName2Len) { + return FALSE; + } + + return (CompareMem (AslName1, AslName2, AslName1Len) == 0); +} + +/** Compare two AML NameStrings. + + @param [in] AmlName1 First NameString to compare. + @param [in] AmlName2 Second NameString to compare. + + @retval TRUE if the two strings are identical. + @retval FALSE otherwise, or if error. +**/ +BOOLEAN +EFIAPI +AmlCompareNameString ( + IN CONST CHAR8 * AmlName1, + IN CONST CHAR8 * AmlName2 + ) +{ + EFI_STATUS Status; + UINT32 AmlName1Len; + UINT32 AmlName2Len; + + if ((AmlName1 == NULL) || + (AmlName2 == NULL)) { + ASSERT (0); + return FALSE; + } + + Status = AmlGetNameStringSize (AmlName1, &AmlName1Len); + if (EFI_ERROR (Status)) { + ASSERT (0); + return FALSE; + } + + Status = AmlGetNameStringSize (AmlName2, &AmlName2Len); + if (EFI_ERROR (Status)) { + ASSERT (0); + return FALSE; + } + + // AmlName1 and AmlName2 don't have the same length + if (AmlName1Len != AmlName2Len) { + return FALSE; + } + + return (CompareMem (AmlName1, AmlName2, AmlName1Len) == 0); +} + +/** Compare an AML NameString and an ASL NameString. + + The ASL NameString is converted to an AML NameString before + being compared with the ASL NameString. This allows to expand + NameSegs shorter than 4 chars. + E.g.: AslName: "DEV" will be expanded to "DEV_" before being + compared. + + @param [in] AmlName1 AML NameString to compare. + @param [in] AslName2 ASL NameString to compare. + + @retval TRUE if the two strings are identical. + @retval FALSE otherwise, or if error. +**/ +BOOLEAN +EFIAPI +CompareAmlWithAslNameString ( + IN CONST CHAR8 * AmlName1, + IN CONST CHAR8 * AslName2 + ) +{ + EFI_STATUS Status; + + CHAR8 * AmlName2; + BOOLEAN RetVal; + + if ((AmlName1 == NULL) || + (AslName2 == NULL)) { + ASSERT (0); + return FALSE; + } + + // Convert the AslName2 to an AmlName2. + // AmlName2 must be freed. + Status = ConvertAmlNameToAslName (AslName2, &AmlName2); + if (EFI_ERROR (Status)) { + ASSERT (0); + return FALSE; + } + + RetVal = AmlCompareNameString (AmlName1, AmlName2); + + // Free AmlName2. + FreePool (AmlName2); + + return RetVal; +} +/** Given an AmlPath, return the address of the first NameSeg. + + It is possible to determine the size of an AML NameString/path just + by sight reading it. So no overflow can occur. + + @param [in] AmlPath The AML pathname. + @param [in] Root The AML pathname starts with a root char. + It is an absolute path. + @param [in] ParentPrefix The AML pathname has ParentPrefix + carets in its name. + + @return Pointer to the first NameSeg of the NameString. + Return NULL if AmlPath is NULL. +**/ +CONST +CHAR8 * +EFIAPI +AmlGetFirstNameSeg ( + IN CONST CHAR8 * AmlPath, + IN UINT32 Root, + IN UINT32 ParentPrefix + ) +{ + if (AmlPath == NULL) { + ASSERT (0); + return NULL; + } + + AmlPath += Root; + AmlPath += ParentPrefix; + AmlPath += ((*AmlPath == AML_MULTI_NAME_PREFIX) ? 2 + : (*AmlPath == AML_DUAL_NAME_PREFIX) ? 1 : 0); + return AmlPath; +} diff --git a/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.h b/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.h new file mode 100644 index 0000000000000000000000000000000000000000..86d9df5f1918d57261c59f8df585d5c80def3d41 --- /dev/null +++ b/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.h @@ -0,0 +1,401 @@ +/** @file + AML String. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef AML_STRING_H_ +#define AML_STRING_H_ + +/* This header file does not include internal Node definition, + i.e. AML_ROOT_NODE, AML_OBJECT_NODE, etc. The node definitions + must be included by the caller file. The function prototypes must + only expose AML_NODE_HANDLE, AML_ROOT_NODE_HANDLE, etc. node + definitions. + This allows to keep the functions defined here both internal and + potentially external. If necessary, any function of this file can + be exposed externally. + The Api folder is internal to the AmlLib, but should only use these + functions. They provide a "safe" way to interact with the AmlLib. +*/ + +#include + +/** Check NameString/path information is valid. + + Root, ParentPrefix and SegCount cannot be 0 at the same time. + This function works for ASL and AML name strings. + + @param [in] Root Number of root char. + Must be 0 or 1. + @param [in] ParentPrefix Number of carets char ('^'). + Must be [0-255]. + @param [in] SegCount Number of NameSeg (s). + Must be [0-255]. + + @retval TRUE id the input information is in the right boundaries. + FALSE otherwise. +**/ +BOOLEAN +EFIAPI +AmlIsNameString ( + IN UINT32 Root, + IN UINT32 ParentPrefix, + IN UINT32 SegCount + ); + +/** Copy bytes from SrcBuffer to DstBuffer and convert to upper case. + Don't copy more than MaxDstBufferSize bytes. + + @param [out] DstBuffer Destination buffer. + @param [in] MaxDstBufferSize Maximum size of DstBuffer. + Must be non-zero. + @param [in] SrcBuffer Source buffer. + @param [in] Count Count of bytes to copy from SrcBuffer. + Return success if 0. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlUpperCaseMemCpyS ( + OUT CHAR8 * DstBuffer, + IN UINT32 MaxDstBufferSize, + IN CONST CHAR8 * SrcBuffer, + IN UINT32 Count + ); + +/** Check whether Buffer is a root path ('\'). + + This function works for both ASL and AML pathnames. + Buffer must be at least 2 bytes long. + + @param [in] Buffer An ASL/AML path. + + @retval TRUE Buffer is a root path + @retval FALSE Buffer is not a root path. +**/ +BOOLEAN +EFIAPI +AmlIsRootPath ( + IN CONST CHAR8 * Buffer + ); + +/** Check whether Ch is an ASL/AML LeadName. + + This function works for both ASL and AML pathnames. + + ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms": + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + + ACPI 6.3 specification, s20.2.2. "Name Objects Encoding": + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + + @param [in] Ch The char to test. + + @retval TRUE Ch is an ASL/AML LeadName. + @retval FALSE Ch is not an ASL/AML LeadName. +**/ +BOOLEAN +EFIAPI +AmlIsLeadNameChar ( + IN CHAR8 Ch + ); + +/** Check whether Ch is an ASL/AML NameChar. + + This function works for both ASL and AML pathnames. + + ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms": + NameChar := DigitChar | LeadNameChar + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + DigitChar := '0'-'9' + + ACPI 6.3 specification, s20.2.2. "Name Objects Encoding": + NameChar := DigitChar | LeadNameChar + LeadNameChar := 'A'-'Z' | 'a'-'z' | '_' + DigitChar := '0'-'9' + + @param [in] Ch The char to test. + + @retval TRUE Ch is an ASL/AML NameChar. + @retval FALSE Ch is not an ASL/AML NameChar. +**/ +BOOLEAN +EFIAPI +AmlIsNameChar ( + IN CHAR8 Ch + ); + +/** Check whether AslBuffer is an ASL NameSeg. + + This function only works for ASL NameStrings/pathnames. + ASL NameStrings/pathnames are at most 4 chars long. + + @param [in] AslBuffer Pointer in an ASL NameString/pathname. + @param [out] Size Size of the NameSeg. + + @retval TRUE AslBuffer is an ASL NameSeg. + @retval FALSE AslBuffer is not an ASL NameSeg. +**/ +BOOLEAN +EFIAPI +AslIsNameSeg ( + IN CONST CHAR8 * AslBuffer, + OUT UINT32 * Size + ); + +/** Check whether AmlBuffer is an AML NameSeg. + + This function only works for AML NameStrings/pathnames. + AML NameStrings/pathnames must be 4 chars long. + + @param [in] AmlBuffer Pointer in an AML NameString/pathname. + + @retval TRUE AmlBuffer is an AML NameSeg. + @retval FALSE AmlBuffer is not an AML NameSeg. +**/ +BOOLEAN +EFIAPI +AmlIsNameSeg ( + IN CONST CHAR8 * AmlBuffer + ); + +/** Parse an ASL NameString/path. + + An ASL NameString/path must be NULL terminated. + Information found in the ASL NameString/path is returned via pointers: + Root, ParentPrefix, SegCount. + + @param [in] Buffer ASL NameString/path. + @param [out] Root Pointer holding the number of root char. + Can be 0 or 1. + @param [out] ParentPrefix Pointer holding the number of carets char ('^'). + Can be [0-255]. + @param [out] SegCount Pointer holding the number of NameSeg (s). + Can be [0-255]. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AslParseNameStringInfo ( + IN CONST CHAR8 * Buffer, + OUT UINT32 * Root, + OUT UINT32 * ParentPrefix, + OUT UINT32 * SegCount + ); + +/** Parse an AML NameString/path. + + It is possible to determine the size of an AML NameString/path just + by sight reading it. So no overflow can occur. + Information found in the AML NameString/path is returned via pointers: + Root, ParentPrefix, SegCount. + + @param [in] Buffer AML NameString/path. + @param [out] Root Pointer holding the number of root char. + Can be 0 or 1. + @param [out] ParentPrefix Pointer holding the number of carets char ('^'). + Can be [0-255]. + @param [out] SegCount Pointer holding the number of NameSeg(s). + Can be [0-255]. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlParseNameStringInfo ( + IN CONST CHAR8 * Buffer, + OUT UINT32 * Root, + OUT UINT32 * ParentPrefix, + OUT UINT32 * SegCount + ); + +/** Compute the ASL NameString/path size from NameString + information (Root, ParentPrefix, SegCount). + + @param [in] Root Number of root char. + Can be 0 or 1. + @param [in] ParentPrefix Number of carets char ('^'). + Can be [0-255]. + @param [in] SegCount Pointer holding the number of NameSeg(s). + Can be [0-255]. + + @return Size of the ASL NameString/path. +**/ +UINT32 +EFIAPI +AslComputeNameStringSize ( + IN UINT32 Root, + IN UINT32 ParentPrefix, + IN UINT32 SegCount + ); + +/** Compute the AML NameString/path size from NameString + information (Root, ParentPrefix, SegCount). + + @param [in] Root Number of root char. + Can be 0 or 1. + @param [in] ParentPrefix Number of carets char ('^'). + Can be [0-255]. + @param [in] SegCount Pointer holding the number of NameSeg(s). + Can be [0-255]. + + @return Size of the AML NameString/path. +**/ +UINT32 +EFIAPI +AmlComputeNameStringSize ( + IN UINT32 Root, + IN UINT32 ParentPrefix, + IN UINT32 SegCount + ); + +/** Get the ASL NameString/path size. + + @param [in] AslPath An ASL NameString/path. + @param [out] AslPathSizePtr Pointer holding the ASL NameString/path size. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AslGetNameStringSize ( + IN CONST CHAR8 * AslPath, + OUT UINT32 * AslPathSizePtr + ); + +/** Get the AML NameString/path size. + + @param [in] AmlPath An AML NameString/path. + @param [out] AmlPathSizePtr Pointer holding the AML NameString/path size. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlGetNameStringSize ( + IN CONST CHAR8 * AmlPath, + OUT UINT32 * AmlPathSizePtr + ); + +/** Convert an ASL NameString/path to an AML NameString/path. + The caller must free the memory allocated in this function + for AmlPath using FreePool (). + + @param [in] AslPath An ASL NameString/path. + @param [out] OutAmlPath Buffer containing the AML path. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +ConvertAslNameToAmlName ( + IN CONST CHAR8 * AslPath, + OUT CHAR8 ** OutAmlPath + ); + +/** Convert an AML NameString/path to an ASL NameString/path. + The caller must free the memory allocated in this function. + using FreePool (). + + @param [in] AmlPath An AML NameString/path. + @param [out] OutAslPath Buffer containing the ASL path. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +ConvertAmlNameToAslName ( + IN CONST CHAR8 * AmlPath, + OUT CHAR8 ** OutAslPath + ); + +/** Compare two ASL NameStrings. + + @param [in] AslName1 First NameString to compare. + @param [in] AslName2 Second NameString to compare. + + @retval TRUE if the two strings are identical. + @retval FALSE otherwise, or if error. +**/ +BOOLEAN +EFIAPI +AslCompareNameString ( + IN CONST CHAR8 * AslName1, + IN CONST CHAR8 * AslName2 + ); + +/** Compare two AML NameStrings. + + @param [in] AmlName1 First NameString to compare. + @param [in] AmlName2 Second NameString to compare. + + @retval TRUE if the two strings are identical. + @retval FALSE otherwise, or if error. +**/ +BOOLEAN +EFIAPI +AmlCompareNameString ( + IN CONST CHAR8 * AmlName1, + IN CONST CHAR8 * AmlName2 + ); + +/** Compare an AML NameString and an ASL NameString. + + The ASL NameString is converted to an AML NameString before + being compared with the ASL NameString. This allows to expand + NameSegs shorter than 4 chars. + E.g.: AslName: "DEV" will be expanded to "DEV_" before being + compared. + + @param [in] AmlName1 AML NameString to compare. + @param [in] AslName2 ASL NameString to compare. + + @retval TRUE if the two strings are identical. + @retval FALSE otherwise, or if error. +**/ +BOOLEAN +EFIAPI +CompareAmlWithAslNameString ( + IN CONST CHAR8 * AmlName1, + IN CONST CHAR8 * AslName2 + ); + +/** Given an AmlPath, return the address of the first NameSeg. + + It is possible to determine the size of an AML NameString/path just + by sight reading it. So no overflow can occur. + + @param [in] AmlPath The AML pathname. + @param [in] Root The AML pathname starts with a root char. + It is an absolute path. + @param [in] ParentPrefix The AML pathname has ParentPrefix + carets in its name. + + @return Pointer to the first NameSeg of the NameString. + Return NULL if AmlPath is NULL. +**/ +CONST +CHAR8 * +EFIAPI +AmlGetFirstNameSeg ( + IN CONST CHAR8 * AmlPath, + IN UINT32 Root, + IN UINT32 ParentPrefix + ); + +#endif // AML_STRING_H_ -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'