From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 721B1941D5E for ; Thu, 21 Sep 2023 16:49:54 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=fDrcfIAB4MgnzG2rs71BRVNmVBoA9dUvhxP+KrP4iXg=; c=relaxed/simple; d=groups.io; h=Received-SPF:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Authentication-Results-Original:Message-ID:Date:User-Agent:Subject:To:Cc:References:From:In-Reply-To:MIME-Version:NoDisclaimer:Original-Authentication-Results:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type; s=20140610; t=1695314993; v=1; b=U6tqc889P2emOoVYp+Ya4P7q4t0/3wDUJf000A1p0hqk258vsWf5SBlxsvOVXkKVWagbwodE djbKNjSoQ6Ld+sZPmEVnGepq1mDCwtHik+bopNGNMAF9IsuFai7XjT8dKd1kJHfidXsl0MQg5p8 +9HruPeKl22lzRJ/i6TA5+T4= X-Received: by 127.0.0.2 with SMTP id jPCIYY7687511xD0lnHlFhHn; Thu, 21 Sep 2023 09:49:53 -0700 X-Received: from EUR03-AM7-obe.outbound.protection.outlook.com (EUR03-AM7-obe.outbound.protection.outlook.com [40.107.105.89]) by mx.groups.io with SMTP id smtpd.web10.495.1695314991331572670 for ; Thu, 21 Sep 2023 09:49:52 -0700 X-Received: from AS9PR06CA0729.eurprd06.prod.outlook.com (2603:10a6:20b:487::24) by DU0PR08MB8730.eurprd08.prod.outlook.com (2603:10a6:10:402::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.20; Thu, 21 Sep 2023 16:49:40 +0000 X-Received: from AM7EUR03FT016.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:487:cafe::b9) by AS9PR06CA0729.outlook.office365.com (2603:10a6:20b:487::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6792.30 via Frontend Transport; Thu, 21 Sep 2023 16:49:39 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C X-Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM7EUR03FT016.mail.protection.outlook.com (100.127.140.106) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.20 via Frontend Transport; Thu, 21 Sep 2023 16:49:39 +0000 X-Received: ("Tessian outbound 5c548696a0e7:v175"); Thu, 21 Sep 2023 16:49:39 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 37d555e84e43d17c X-CR-MTA-TID: 64aa7808 X-Received: from 0f2d33464dea.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id C1433821-3EA7-42E7-A787-2B6F4FCDD30A.1; Thu, 21 Sep 2023 16:49:28 +0000 X-Received: from EUR03-DBA-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 0f2d33464dea.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 21 Sep 2023 16:49:28 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iDbHrQY/Ovtm93T3ajufnyatdYxYXnDQtQh47gQ+W2D9n7JcDb4kjnPCatilyDtUlmVhe/XTc36pb1kzewutJ9u5bFSNRPYzB0L4CQG173WvYrw36rQCUd/noOAwG+B/skFeDARrTDoLz2pYvd/Hqn3kbzwfhbY+XL6lB9gc/MFAIe+x37RuOyNC6X8g9BAOhBKG/8FXWkbz8AOHg0iotjLQcpi239xlGEXbTjbXf6P/foXPXgnNj4+qUnE/ZJI9dzw9YH6SsVfzCXweKDGON9zlu12A7hJeEeCw6IGnPpc2VEmeb8ZOWue/KA7ugxrr7y4NoDQCDYR3pRLJTj24gw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xTm84lKxSEJwGSPgteYNqdKmGc7pK9GpdHkQvqDPyJ4=; b=SKrrpFXK/abZiGI/LTTCUVTNu8PGzqaBQ5qFa5ua4E1GHUV/o0QFCzK/qGSrVy+vc3O7wDEvrfgrA799WI0yM0Zg9Ap51jUDgzwE5rKfz3iQP0g9pUrWgn+gVXI+/xFcq4QU5I2IsDZhV7dEmilnOeP2CHabc3aacXf4/v4rMw4ZUlK/YtuMwWRQKuK3p04Wpw3u7QXyTQsgnJVSL3xlRaoV0iUh1mfHm8+0knK8Z61Cc3bwiFQIrMccttDLXc+FYljWinbnw+BmANtcId/jFVKwybkHf7eAPdAPpXQ2caTmxij0U68w3E/UAGxTrhYZhghBWLhOTgzQYI96U1dJ9w== 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 Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-Received: from AS8PR08MB6806.eurprd08.prod.outlook.com (2603:10a6:20b:39b::12) by AS8PR08MB7322.eurprd08.prod.outlook.com (2603:10a6:20b:441::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6792.27; Thu, 21 Sep 2023 16:49:26 +0000 X-Received: from AS8PR08MB6806.eurprd08.prod.outlook.com ([fe80::ac37:4594:ab86:59ce]) by AS8PR08MB6806.eurprd08.prod.outlook.com ([fe80::ac37:4594:ab86:59ce%4]) with mapi id 15.20.6792.021; Thu, 21 Sep 2023 16:49:25 +0000 Message-ID: <885016b1-c8f3-8951-8473-15a37cd640a2@arm.com> Date: Thu, 21 Sep 2023 17:49:24 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.15.1 Subject: Re: [edk2-devel] [PATCH v4 2/4] DynamicTablesPkg: Add support for simple method invocation. To: Jeff Brasen , devel@edk2.groups.io Cc: pierre.gondois@arm.com, swatisrik@nvidia.com, ashishsingha@nvidia.com, "nd@arm.com" References: <737650480edcab199927322064b2459f647f9f02.1695049337.git.jbrasen@nvidia.com> From: "Sami Mujawar" In-Reply-To: <737650480edcab199927322064b2459f647f9f02.1695049337.git.jbrasen@nvidia.com> X-ClientProxiedBy: LO4P123CA0045.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:152::14) To AS8PR08MB6806.eurprd08.prod.outlook.com (2603:10a6:20b:39b::12) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: AS8PR08MB6806:EE_|AS8PR08MB7322:EE_|AM7EUR03FT016:EE_|DU0PR08MB8730:EE_ X-MS-Office365-Filtering-Correlation-Id: f89542bf-c229-4a8f-7f14-08dbbac2bf43 X-LD-Processed: f34e5979-57d9-4aaa-ad4d-b122a662184d,ExtAddr x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: CUrG3eKH/R0EdqFe0Rqk2C34cWAh7fWroBzLUs49d6Qzi9520iGbDYtoQnI2mKY9naO/YuvTP6r7SkNcJsmBmKEu+PUFtJhEjmPhqlYf+KEoRvmR4fclIPf3MDGEY+tFSUP0enqF2WgUlVnAnkM2X+z/A1iMdUGgDrNaNY7APgv9bmHUh8OjAU0ktr8S0F3NLszlxkoFXx8qId0ltKWUxXS7DgLOnN9lIiBbpZfGCN1mSaWF/NCYmhckv7GrQ2xJxebgKOJsd5Sm4iqhxOjtPSaEhD+29wlc84hB7n4dMgX405RPj6LBNAewdZT1ByAm1Furuvg1ykzislxxjLhL5nqCbjuLZi1O2u/eDhiTHvch6H83GafkHqi06BZQJYHcCrQrIBMDjUBsjZOtpF5FyMdbi8kLM6ovjvmdf99piIqzfhHlNmDqvSb92O0tl86SWnYvqJZS9KKhYwHt3lTrckhnw927s+s/oTZ57f9Xr/RmDMyAgccOGQYHynUav/fz/piYKBnzgz0ZldVfWGzQLZduArMVzhzRQ1s1ftgeL77y38UqhUGWEqKiHcUjOmtMFJBbTP3PoL50K2JLHvBipuo38Y2HpatYUapPe24fzbwAsaC3uj2Xiqtc1OnkMfHbB8Rjl1dn+/rkmDYppt+/yg== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AS8PR08MB6806.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(346002)(136003)(376002)(396003)(366004)(39860400002)(451199024)(186009)(1800799009)(2906002)(44832011)(5660300002)(26005)(66476007)(41300700001)(316002)(66946007)(66556008)(478600001)(30864003)(8676002)(4326008)(31686004)(8936002)(6506007)(33964004)(6486002)(53546011)(6512007)(36756003)(2616005)(38100700002)(31696002)(83380400001)(86362001)(45980500001)(43740500002)(579004);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB7322 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM7EUR03FT016.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 7864d57a-60e4-497b-1cfa-08dbbac2b6c2 X-Microsoft-Antispam-Message-Info: Nz4no+caYJGYhlOzxr0NEo48dcIGBIunCRgcI6ngL+mBm5nUu2OwWNYOX8Kl9amBCrDmQuYBxm1eF8WyPBbyAY1TdOmL2IYpzLguwTa8JNol9pLrzoj5fz1NM2v1e519YVZpS44gKYnr8e5O+4EDoj9B1Oj4KqzHbF6avELGi/YaP7GoSri8zP+IY3nYBzv2LjxSw5a1U2JTV+vieBOaWCiSAuaZK7UsiVI0GMiSxuoj3AM/uCHw/spyUVx6hAatkdCUWPtTbwQNYDlzESCoGz5gzoxdIH3Sd2uX4P7hsbWwrAfAdgh6fge4EjZYMD7I6ndTkEoJ4gm+jWMbvsZYeJ02W2bPp6sF+JV9d7PB23kBk/vVBcOAa8FcfUxMR8H9Ab3WeyaQrQzMrzAP0gZeA3rKsqpkr8MHnIQyDu6OXjpkuv1O5CZItnS/vlRnsJ+SNags1Doe8+eAgOLpQ9YAkJwJCzk/ODaZ+auNK5ZRa4d53CCJaYdwC9dr1S7EvC1P9d6nOJ2SmFtPHQJej3UUaGYhYy0VUHX1Tqs3IpvH0I+FvS8DbL3UvrxsboygADzPZ0cxh1fGP+arVg2wz9GosLTws0p7rS3Al2Gfjv16MXmaXjuW7SNy+9IwsZJIrpky+czLCJu+pz1BGle0DYElKZInfk6mD7Fhp1HyMlbzEe8BjTn+PmbomWZD+UJJgByCqBaCeTRFdBzFjkwKAq37uU/aKkBXSDSwjkJV7qtwHFoXoMny1DWh0todvO+pn9CJ1+w2+Jf5F/h9Hbslqd3aIg== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2023 16:49:39.7569 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f89542bf-c229-4a8f-7f14-08dbbac2bf43 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: AM7EUR03FT016.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB8730 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,sami.mujawar@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: cxFxkZPvJVhnXxCiCQsq37Oix7686176AA= Content-Type: multipart/alternative; boundary="------------kF2jn2sUmUFmLhhACi5tUxFR" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=U6tqc889; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=arm.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io --------------kF2jn2sUmUFmLhhACi5tUxFR Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi Jeff, Thank you for this patch. Please see my response inline marked [SAMI]. Regards, Sami Mujawar On 18/09/2023 04:46 pm, Jeff Brasen wrote: > Add support to add Return objects via AML that pass a single integer > > argument to the named method. > > > > Signed-off-by: Jeff Brasen > > --- > > .../Include/Library/AmlLib/AmlLib.h | 54 ++++ > > .../Common/AmlLib/CodeGen/AmlCodeGen.c | 244 ++++++++++++++++++ > > 2 files changed, 298 insertions(+) > > > > diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h > > index d201ae9499..b82c7a3ce8 100644 > > --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h > > +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h > > @@ -1194,6 +1194,60 @@ AmlCodeGenMethodRetInteger ( > > OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL > > ); > > > > +/** AML code generation for a method returning a NameString that takes an > > + integer argument. > > + > > + AmlCodeGenMethodRetNameStringIntegerArgument ( > > + "MET0", "MET1", 1, TRUE, 3, 5, ParentNode, NewObjectNode > > + ); > > + is equivalent of the following ASL code: > > + Method(MET0, 1, Serialized, 3) { > > + Return (MET1 (5)) > > + } > > + > > + The ASL parameters "ReturnType" and "ParameterTypes" are not asked > > + in this function. They are optional parameters in ASL. > > + > > + @param [in] MethodNameString The new Method's name. > > + Must be a NULL-terminated ASL NameString > > + e.g.: "MET0", "_SB.MET0", etc. > > + The input string is copied. > > + @param [in] ReturnedNameString The name of the object returned by the > > + method. Optional parameter, can be: > > + - NULL (ignored). > > + - A NULL-terminated ASL NameString. > > + e.g.: "MET0", "_SB.MET0", etc. > > + The input string is copied. > > + @param [in] NumArgs Number of arguments. > > + Must be 0 <= NumArgs <= 6. > > + @param [in] IsSerialized TRUE is equivalent to Serialized. > > + FALSE is equivalent to NotSerialized. > > + Default is NotSerialized in ASL spec. > > + @param [in] SyncLevel Synchronization level for the method. > > + Must be 0 <= SyncLevel <= 15. > > + Default is 0 in ASL. > > + @param [in] IntegerArgument Argument to pass to the NameString. > > + @param [in] ParentNode If provided, set ParentNode as the parent > > + of the node created. > > + @param [out] NewObjectNode If success, contains the created node. > > + > > + @retval EFI_SUCCESS Success. > > + @retval EFI_INVALID_PARAMETER Invalid parameter. > > + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +AmlCodeGenMethodRetNameStringIntegerArgument ( > > + IN CONST CHAR8 *MethodNameString, > > + IN CONST CHAR8 *ReturnedNameString OPTIONAL, > > + IN UINT8 NumArgs, > > + IN BOOLEAN IsSerialized, > > + IN UINT8 SyncLevel, > > + IN UINT64 IntegerArgument, > > + IN AML_NODE_HANDLE ParentNode OPTIONAL, > > + OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL > > + ); > > + > > /** Create a _LPI name. > > > > AmlCreateLpiNode ("_LPI", 0, 1, ParentNode, &LpiNode) is > > diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c > > index 88537b7e2d..ea519d1aa8 100644 > > --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c > > +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c > > @@ -1881,6 +1881,138 @@ AmlCodeGenReturnInteger ( > > return Status; > > } > > > > +/** AML code generation for a Return object node, > > + returning the object as an input NameString with a integer argument. > > + > > + AmlCodeGenReturn ("NAM1", 6, ParentNode, NewObjectNode) is > > + equivalent of the following ASL code: > > + Return(NAM1 (6)) > > + > > + The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding" states: > > + DefReturn := ReturnOp ArgObject > > + ReturnOp := 0xA4 > > + ArgObject := TermArg => DataRefObject > > + > > + Thus, the ReturnNode must be evaluated as a DataRefObject. It can > > + be a NameString referencing an object. As this CodeGen Api doesn't > > + do semantic checking, it is strongly advised to check the AML bytecode > > + generated by this function against an ASL compiler. > > + > > + The ReturnNode must be generated inside a Method body scope. > > + > > + @param [in] NameString The object referenced by this NameString > > + is returned by the Return ASL statement. > > + Must be a NULL-terminated ASL NameString > > + e.g.: "NAM1", "_SB.NAM1", etc. > > + The input string is copied. > > + @param [in] Integer Argument to pass to the NameString > > + @param [in] ParentNode If provided, set ParentNode as the parent > > + of the node created. > > + Must be a MethodOp node. > > + @param [out] NewObjectNode If success, contains the created node. > > + > > + @retval EFI_SUCCESS Success. > > + @retval EFI_INVALID_PARAMETER Invalid parameter. > > + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. > > +**/ > > +STATIC > > +EFI_STATUS > > +EFIAPI > > +AmlCodeGenReturnNameStringIntegerArgument ( > > + IN CONST CHAR8 *NameString, > > + IN UINT64 Integer, > > + IN AML_NODE_HEADER *ParentNode OPTIONAL, > > + OUT AML_OBJECT_NODE **NewObjectNode OPTIONAL > > + ) > > +{ > > + EFI_STATUS Status; > > + AML_DATA_NODE *DataNode; > > + AML_OBJECT_NODE *IntNode; > > + CHAR8 *AmlNameString; > > + UINT32 AmlNameStringSize; > > + AML_OBJECT_NODE *ObjectNode; > > + > > + DataNode = NULL; > > + IntNode = NULL; > > + ObjectNode = NULL; > > + > > + Status = ConvertAslNameToAmlName (NameString, &AmlNameString); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + return Status; > > + } > > + > > + Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + goto exit_handler; > > + } > > + > > + Status = AmlCreateDataNode ( > > + EAmlNodeDataTypeNameString, > > + (UINT8 *)AmlNameString, > > + AmlNameStringSize, > > + &DataNode > > + ); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + goto exit_handler; > > + } > > + > > + Status = AmlCodeGenInteger (Integer, &IntNode); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + goto exit_handler; > > + } > > + > > + // AmlCodeGenReturn() deletes DataNode if error. > > + Status = AmlCodeGenReturn ( > > + (AML_NODE_HEADER *)DataNode, > > + ParentNode, > > + &ObjectNode > > + ); > > + > > + // DataNode is either deleted or added to ObjectNode, set to NULL so we don't > > + // delete it again > > + DataNode = NULL; > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + goto exit_handler; > > + } > > + > > + Status = AmlVarListAddTail ( > > + (AML_NODE_HANDLE)ObjectNode, > > + (AML_NODE_HANDLE)IntNode > > + ); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + goto exit_handler; > > + } > > + > > + if (NewObjectNode != 0) { > > + *NewObjectNode = ObjectNode; > > + } > > + > > +exit_handler: > > + if (AmlNameString != NULL) { > > + FreePool (AmlNameString); > > + } > > + > > + if (IntNode != NULL) { > > + AmlDeleteTree ((AML_NODE_HANDLE)IntNode); > > + } > > + > > + if (DataNode != NULL) { > > + AmlDeleteTree ((AML_NODE_HANDLE)DataNode); > > + } > > + > > + if (ObjectNode != NULL) { > > + AmlDeleteTree ((AML_NODE_HANDLE)ObjectNode); > > + } > > + > > + return Status; > > +} [SAMI] I think the error handling in the above function can be simplified as below: ... STATIC EFI_STATUS EFIAPI AmlCodeGenReturnNameStringIntegerArgument ( INCONSTCHAR8            *NameString, IN       UINT64           Integer, IN       AML_NODE_HEADER  *ParentNode OPTIONAL, OUT      AML_OBJECT_NODE  **NewObjectNode OPTIONAL   ) {   EFI_STATUS       Status;   AML_DATA_NODE    *DataNode;   AML_OBJECT_NODE  *IntNode;   CHAR8            *AmlNameString;   UINT32           AmlNameStringSize;   AML_OBJECT_NODE  *ObjectNode;   DataNode   = NULL;   IntNode    = NULL;   ObjectNode = NULL;   Status = ConvertAslNameToAmlName (NameString, &AmlNameString); if(EFI_ERROR (Status)) { ASSERT(0); returnStatus;   }   Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize); if(EFI_ERROR (Status)) { ASSERT(0); gotoexit_handler;   }   Status = AmlCodeGenInteger (Integer, &IntNode); if(EFI_ERROR (Status)) { ASSERT(0); gotoexit_handler;   }   Status = AmlCreateDataNode ( EAmlNodeDataTypeNameString,              (UINT8 *)AmlNameString,              AmlNameStringSize,              &DataNode              ); if(EFI_ERROR (Status)) { ASSERT(0); gotoexit_handler1;   } // AmlCodeGenReturn() deletes DataNode if error.   Status = AmlCodeGenReturn (              (AML_NODE_HEADER *)DataNode,              ParentNode,              &ObjectNode              ); if(EFI_ERROR (Status)) { ASSERT(0); gotoexit_handler1;   }   Status = AmlVarListAddTail (              (AML_NODE_HANDLE)ObjectNode,              (AML_NODE_HANDLE)IntNode              ); if(EFI_ERROR (Status)) { // ObjectNode is already attached to ParentNode in AmlCodeGenReturn(), // so no need to free it here, it will be deleted when deleting the // ParentNode tree ASSERT(0); gotoexit_handler1;   } if(NewObjectNode != 0) {     *NewObjectNode = ObjectNode;   } gotoexit_handler; exit_handler1: if(IntNode != NULL) {     AmlDeleteTree ((AML_NODE_HANDLE)IntNode);   } exit_handler: if(AmlNameString != NULL) {     FreePool (AmlNameString);   } returnStatus; } Please let me know if you agree with this, and I will make this change before merging. [/SAMI] > + > > /** AML code generation for a method returning a NameString. > > > > AmlCodeGenMethodRetNameString ( > > @@ -1989,6 +2121,118 @@ error_handler: > > return Status; > > } > > > > +/** AML code generation for a method returning a NameString that takes an > > + integer argument. > > + > > + AmlCodeGenMethodRetNameStringIntegerArgument ( > > + "MET0", "MET1", 1, TRUE, 3, 5, ParentNode, NewObjectNode > > + ); > > + is equivalent of the following ASL code: > > + Method(MET0, 1, Serialized, 3) { > > + Return (MET1 (5)) > > + } > > + > > + The ASL parameters "ReturnType" and "ParameterTypes" are not asked > > + in this function. They are optional parameters in ASL. > > + > > + @param [in] MethodNameString The new Method's name. > > + Must be a NULL-terminated ASL NameString > > + e.g.: "MET0", "_SB.MET0", etc. > > + The input string is copied. > > + @param [in] ReturnedNameString The name of the object returned by the > > + method. Optional parameter, can be: > > + - NULL (ignored). > > + - A NULL-terminated ASL NameString. > > + e.g.: "MET0", "_SB.MET0", etc. > > + The input string is copied. > > + @param [in] NumArgs Number of arguments. > > + Must be 0 <= NumArgs <= 6. > > + @param [in] IsSerialized TRUE is equivalent to Serialized. > > + FALSE is equivalent to NotSerialized. > > + Default is NotSerialized in ASL spec. > > + @param [in] SyncLevel Synchronization level for the method. > > + Must be 0 <= SyncLevel <= 15. > > + Default is 0 in ASL. > > + @param [in] IntegerArgument Argument to pass to the NameString. > > + @param [in] ParentNode If provided, set ParentNode as the parent > > + of the node created. > > + @param [out] NewObjectNode If success, contains the created node. > > + > > + @retval EFI_SUCCESS Success. > > + @retval EFI_INVALID_PARAMETER Invalid parameter. > > + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +AmlCodeGenMethodRetNameStringIntegerArgument ( > > + IN CONST CHAR8 *MethodNameString, > > + IN CONST CHAR8 *ReturnedNameString OPTIONAL, > > + IN UINT8 NumArgs, > > + IN BOOLEAN IsSerialized, > > + IN UINT8 SyncLevel, > > + IN UINT64 IntegerArgument, > > + IN AML_NODE_HANDLE ParentNode OPTIONAL, > > + OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL > > + ) > > +{ > > + EFI_STATUS Status; > > + AML_OBJECT_NODE_HANDLE MethodNode; > > + > > + if ((MethodNameString == NULL) || > > + ((ParentNode == NULL) && (NewObjectNode == NULL))) > > + { > > + ASSERT (0); > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // Create a Method named MethodNameString. > > + Status = AmlCodeGenMethod ( > > + MethodNameString, > > + NumArgs, > > + IsSerialized, > > + SyncLevel, > > + NULL, > > + &MethodNode > > + ); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + return Status; > > + } > > + > > + // Return ReturnedNameString if provided. > > + if (ReturnedNameString != NULL) { > > + Status = AmlCodeGenReturnNameStringIntegerArgument ( > > + ReturnedNameString, > > + IntegerArgument, > > + (AML_NODE_HANDLE)MethodNode, > > + NULL > > + ); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + goto error_handler; > > + } > > + } > > + > > + Status = LinkNode ( > > + MethodNode, > > + ParentNode, > > + NewObjectNode > > + ); > > + if (EFI_ERROR (Status)) { > > + ASSERT (0); > > + goto error_handler; > > + } > > + > > + return Status; > > + > > +error_handler: > > + if (MethodNode != NULL) { > > + AmlDeleteTree ((AML_NODE_HANDLE)MethodNode); > > + } > > + > > + return Status; > > +} > > + > > /** AML code generation for a method returning an Integer. > > > > AmlCodeGenMethodRetInteger ( > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108955): https://edk2.groups.io/g/devel/message/108955 Mute This Topic: https://groups.io/mt/101436335/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- --------------kF2jn2sUmUFmLhhACi5tUxFR Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

Hi Jeff,

Thank you for this patch.

Please see my response inline marked [SAMI].

Regards,

Sami Mujawar

On 18/09/2023 04:46 pm, Jeff Brasen wrote:
Add support to add Return obje=
cts via AML that pass a single integer

argument to the named method.



Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>

---

 .../Include/Library/AmlLib/AmlLib.h           |  54 ++++

 .../Common/AmlLib/CodeGen/AmlCodeGen.c        | 244 ++++++++++++++++++

 2 files changed, 298 insertions(+)



diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTabl=
esPkg/Include/Library/AmlLib/AmlLib.h

index d201ae9499..b82c7a3ce8 100644

--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h

+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h

@@ -1194,6 +1194,60 @@ AmlCodeGenMethodRetInteger (

   OUT       AML_OBJECT_NODE_HANDLE  *NewObjectNode        OPTIONAL

   );

=20

+/** AML code generation for a method returning a NameString that takes an

+    integer argument.

+

+  AmlCodeGenMethodRetNameStringIntegerArgument (

+    "MET0", "MET1", 1, TRUE, 3, 5, ParentNode, NewObje=
ctNode

+    );

+  is equivalent of the following ASL code:

+    Method(MET0, 1, Serialized, 3) {

+      Return (MET1 (5))

+    }

+

+  The ASL parameters "ReturnType" and "ParameterTypes"=
 are not asked

+  in this function. They are optional parameters in ASL.

+

+  @param [in]  MethodNameString     The new Method's name.

+                                    Must be a NULL-terminated ASL NameStri=
ng

+                                    e.g.: "MET0", "_SB.MET0=
", etc.

+                                    The input string is copied.

+  @param [in]  ReturnedNameString   The name of the object returned by the

+                                    method. Optional parameter, can be:

+                                     - NULL (ignored).

+                                     - A NULL-terminated ASL NameString.

+                                       e.g.: "MET0", "_SB.M=
ET0", etc.

+                                       The input string is copied.

+  @param [in]  NumArgs              Number of arguments.

+                                    Must be 0 <=3D NumArgs <=3D 6.

+  @param [in]  IsSerialized         TRUE is equivalent to Serialized.

+                                    FALSE is equivalent to NotSerialized.

+                                    Default is NotSerialized in ASL spec.

+  @param [in]  SyncLevel            Synchronization level for the method.

+                                    Must be 0 <=3D SyncLevel <=3D 15=
.

+                                    Default is 0 in ASL.

+  @param [in]  IntegerArgument      Argument to pass to the NameString.

+  @param [in]  ParentNode           If provided, set ParentNode as the par=
ent

+                                    of the node created.

+  @param [out] NewObjectNode        If success, contains the created node.

+

+  @retval EFI_SUCCESS             Success.

+  @retval EFI_INVALID_PARAMETER   Invalid parameter.

+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.

+**/

+EFI_STATUS

+EFIAPI

+AmlCodeGenMethodRetNameStringIntegerArgument (

+  IN  CONST CHAR8                   *MethodNameString,

+  IN  CONST CHAR8                   *ReturnedNameString   OPTIONAL,

+  IN        UINT8                   NumArgs,

+  IN        BOOLEAN                 IsSerialized,

+  IN        UINT8                   SyncLevel,

+  IN        UINT64                  IntegerArgument,

+  IN        AML_NODE_HANDLE         ParentNode           OPTIONAL,

+  OUT       AML_OBJECT_NODE_HANDLE  *NewObjectNode        OPTIONAL

+  );

+

 /** Create a _LPI name.

=20

   AmlCreateLpiNode ("_LPI", 0, 1, ParentNode, &LpiNode) is

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/=
DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c

index 88537b7e2d..ea519d1aa8 100644

--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c

+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c

@@ -1881,6 +1881,138 @@ AmlCodeGenReturnInteger (

   return Status;

 }

=20

+/** AML code generation for a Return object node,

+    returning the object as an input NameString with a integer argument.

+

+  AmlCodeGenReturn ("NAM1", 6, ParentNode, NewObjectNode) is

+  equivalent of the following ASL code:

+    Return(NAM1 (6))

+

+  The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding"=
; states:

+    DefReturn :=3D ReturnOp ArgObject

+    ReturnOp :=3D 0xA4

+    ArgObject :=3D TermArg =3D> DataRefObject

+

+  Thus, the ReturnNode must be evaluated as a DataRefObject. It can

+  be a NameString referencing an object. As this CodeGen Api doesn't

+  do semantic checking, it is strongly advised to check the AML bytecode

+  generated by this function against an ASL compiler.

+

+  The ReturnNode must be generated inside a Method body scope.

+

+  @param [in]  NameString     The object referenced by this NameString

+                              is returned by the Return ASL statement.

+                              Must be a NULL-terminated ASL NameString

+                              e.g.: "NAM1", "_SB.NAM1"=
, etc.

+                              The input string is copied.

+  @param [in]  Integer        Argument to pass to the NameString

+  @param [in]  ParentNode     If provided, set ParentNode as the parent

+                              of the node created.

+                              Must be a MethodOp node.

+  @param [out] NewObjectNode  If success, contains the created node.

+

+  @retval EFI_SUCCESS             Success.

+  @retval EFI_INVALID_PARAMETER   Invalid parameter.

+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.

+**/

+STATIC

+EFI_STATUS

+EFIAPI

+AmlCodeGenReturnNameStringIntegerArgument (

+  IN  CONST CHAR8            *NameString,

+  IN        UINT64           Integer,

+  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,

+  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL

+  )

+{

+  EFI_STATUS       Status;

+  AML_DATA_NODE    *DataNode;

+  AML_OBJECT_NODE  *IntNode;

+  CHAR8            *AmlNameString;

+  UINT32           AmlNameStringSize;

+  AML_OBJECT_NODE  *ObjectNode;

+

+  DataNode   =3D NULL;

+  IntNode    =3D NULL;

+  ObjectNode =3D NULL;

+

+  Status =3D ConvertAslNameToAmlName (NameString, &AmlNameString);

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    return Status;

+  }

+

+  Status =3D AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    goto exit_handler;

+  }

+

+  Status =3D AmlCreateDataNode (

+             EAmlNodeDataTypeNameString,

+             (UINT8 *)AmlNameString,

+             AmlNameStringSize,

+             &DataNode

+             );

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    goto exit_handler;

+  }

+

+  Status =3D AmlCodeGenInteger (Integer, &IntNode);

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    goto exit_handler;

+  }

+

+  // AmlCodeGenReturn() deletes DataNode if error.

+  Status =3D AmlCodeGenReturn (

+             (AML_NODE_HEADER *)DataNode,

+             ParentNode,

+             &ObjectNode

+             );

+

+  // DataNode is either deleted or added to ObjectNode, set to NULL so we =
don't

+  // delete it again

+  DataNode =3D NULL;

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    goto exit_handler;

+  }

+

+  Status =3D AmlVarListAddTail (

+             (AML_NODE_HANDLE)ObjectNode,

+             (AML_NODE_HANDLE)IntNode

+             );

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    goto exit_handler;

+  }

+

+  if (NewObjectNode !=3D 0) {

+    *NewObjectNode =3D ObjectNode;

+  }

+

+exit_handler:

+  if (AmlNameString !=3D NULL) {

+    FreePool (AmlNameString);

+  }

+

+  if (IntNode !=3D NULL) {

+    AmlDeleteTree ((AML_NODE_HANDLE)IntNode);

+  }

+

+  if (DataNode !=3D NULL) {

+    AmlDeleteTree ((AML_NODE_HANDLE)DataNode);

+  }

+

+  if (ObjectNode !=3D NULL) {

+    AmlDeleteTree ((AML_NODE_HANDLE)ObjectNode);

+  }

+

+  return Status;

+}

[SAMI] I think the error handling in the above function can be simplified as below:

...

STATIC
EFI_STATUS
EFIAPI
AmlCodeGenReturnNameStringIntegerArgument (
=   IN  CONST CHAR8   &n= bsp;        *NameString,
  IN        UINT64   =         Integer,
  IN        AML_NODE_HEADER  *P= arentNode      OPTION= AL,
  OUT       AML_OBJECT_NODE  *= *NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_DATA_NODE    *DataNode;=
  AML_OBJECT_NODE  *In= tNode;
  CHAR8  =          *AmlNameString;
  UINT32           A= mlNameStringSize;
  A= ML_OBJECT_NODE  *ObjectNode;
  DataNode   =3D NULL;
  IntNode    = =3D NULL;
  Object= Node =3D NULL;
  Status =3D ConvertAslNameToAmlN= ame (NameString, &AmlNameString);
  if (EFI_ERROR (Status)) {
    = ASSERT (0);
    return Status;
  }
  Status =3D AmlGetNameStringSize= (AmlNameString, &AmlNameStringSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
=     goto exit_handler;<= /div>
  }
  Status =3D AmlCodeGenInteger (I= nteger, &IntNode);
&nb= sp; if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }
  Status =3D AmlCreateDataNode (<= /span>
       = ;      EAmlNodeDataTy= peNameString,
             = (UINT8 *)AmlNameString,
&n= bsp;            AmlNameStringSize,
          &= nbsp;  &DataNode
=              );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handl= er1;
  }
  // AmlCodeGenReturn() deletes DataNode if error.
<= span style=3D"color: #000000;">  Status =3D AmlCodeGenReturn (<= /div>
         = ;    (AML_NODE_HEADER *)DataNode,
             ParentNod= e,
      &n= bsp;      &ObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    <= span style=3D"color: #0000ff;">goto = exit_handler1;
  }
  Status =3D AmlVarListAddTail (<= /span>
       = ;      (AML_NODE_HANDLE)ObjectNode,
             (A= ML_NODE_HANDLE)IntNode
&nb= sp;            );
  if (EFI_ERROR (Status)) {
=     // ObjectNode is already attached to ParentNode in AmlCodeGenRetu= rn(),
    // so no need to free it here, it will be = deleted when deleting the
=     // ParentNode tree
    ASSERT (0= );
    goto e= xit_handler1;
  }
  if (NewObjectNode !=3D 0)= {
    *NewObjec= tNode =3D ObjectNode;
&nbs= p; }
  goto exit_handler;
exit_handler1:
  if<= /span> (IntNode !=3D NULL) {
    AmlDeleteTree ((AML_NOD= E_HANDLE)IntNode);
  = }
exit_handler:
  if (AmlNameString !=3D NULL) {=
    FreePool (AmlNameS= tring);
  }
  return Status;
<= div>}


Please let me know if you agree with this, and I will make this change before merging.

[/SAMI]

+

 /** AML code generation for a method returning a NameString.

=20

   AmlCodeGenMethodRetNameString (

@@ -1989,6 +2121,118 @@ error_handler:

   return Status;

 }

=20

+/** AML code generation for a method returning a NameString that takes an

+    integer argument.

+

+  AmlCodeGenMethodRetNameStringIntegerArgument (

+    "MET0", "MET1", 1, TRUE, 3, 5, ParentNode, NewObje=
ctNode

+    );

+  is equivalent of the following ASL code:

+    Method(MET0, 1, Serialized, 3) {

+      Return (MET1 (5))

+    }

+

+  The ASL parameters "ReturnType" and "ParameterTypes"=
 are not asked

+  in this function. They are optional parameters in ASL.

+

+  @param [in]  MethodNameString     The new Method's name.

+                                    Must be a NULL-terminated ASL NameStri=
ng

+                                    e.g.: "MET0", "_SB.MET0=
", etc.

+                                    The input string is copied.

+  @param [in]  ReturnedNameString   The name of the object returned by the

+                                    method. Optional parameter, can be:

+                                     - NULL (ignored).

+                                     - A NULL-terminated ASL NameString.

+                                       e.g.: "MET0", "_SB.M=
ET0", etc.

+                                       The input string is copied.

+  @param [in]  NumArgs              Number of arguments.

+                                    Must be 0 <=3D NumArgs <=3D 6.

+  @param [in]  IsSerialized         TRUE is equivalent to Serialized.

+                                    FALSE is equivalent to NotSerialized.

+                                    Default is NotSerialized in ASL spec.

+  @param [in]  SyncLevel            Synchronization level for the method.

+                                    Must be 0 <=3D SyncLevel <=3D 15=
.

+                                    Default is 0 in ASL.

+  @param [in]  IntegerArgument      Argument to pass to the NameString.

+  @param [in]  ParentNode           If provided, set ParentNode as the par=
ent

+                                    of the node created.

+  @param [out] NewObjectNode        If success, contains the created node.

+

+  @retval EFI_SUCCESS             Success.

+  @retval EFI_INVALID_PARAMETER   Invalid parameter.

+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.

+**/

+EFI_STATUS

+EFIAPI

+AmlCodeGenMethodRetNameStringIntegerArgument (

+  IN  CONST CHAR8                   *MethodNameString,

+  IN  CONST CHAR8                   *ReturnedNameString   OPTIONAL,

+  IN        UINT8                   NumArgs,

+  IN        BOOLEAN                 IsSerialized,

+  IN        UINT8                   SyncLevel,

+  IN        UINT64                  IntegerArgument,

+  IN        AML_NODE_HANDLE         ParentNode           OPTIONAL,

+  OUT       AML_OBJECT_NODE_HANDLE  *NewObjectNode        OPTIONAL

+  )

+{

+  EFI_STATUS              Status;

+  AML_OBJECT_NODE_HANDLE  MethodNode;

+

+  if ((MethodNameString =3D=3D NULL)  ||

+      ((ParentNode =3D=3D NULL) && (NewObjectNode =3D=3D NULL)))

+  {

+    ASSERT (0);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  // Create a Method named MethodNameString.

+  Status =3D AmlCodeGenMethod (

+             MethodNameString,

+             NumArgs,

+             IsSerialized,

+             SyncLevel,

+             NULL,

+             &MethodNode

+             );

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    return Status;

+  }

+

+  // Return ReturnedNameString if provided.

+  if (ReturnedNameString !=3D NULL) {

+    Status =3D AmlCodeGenReturnNameStringIntegerArgument (

+               ReturnedNameString,

+               IntegerArgument,

+               (AML_NODE_HANDLE)MethodNode,

+               NULL

+               );

+    if (EFI_ERROR (Status)) {

+      ASSERT (0);

+      goto error_handler;

+    }

+  }

+

+  Status =3D LinkNode (

+             MethodNode,

+             ParentNode,

+             NewObjectNode

+             );

+  if (EFI_ERROR (Status)) {

+    ASSERT (0);

+    goto error_handler;

+  }

+

+  return Status;

+

+error_handler:

+  if (MethodNode !=3D NULL) {

+    AmlDeleteTree ((AML_NODE_HANDLE)MethodNode);

+  }

+

+  return Status;

+}

+

 /** AML code generation for a method returning an Integer.

=20

   AmlCodeGenMethodRetInteger (

_._,_._,_

Groups.io Links:

=20 You receive all messages sent to this group. =20 =20

View/Reply Online (#108955) | =20 | Mute= This Topic | New Topic
Your Subscriptio= n | Contact Group Owner | Unsubscribe [rebecca@openfw.io]

_._,_._,_
--------------kF2jn2sUmUFmLhhACi5tUxFR--