public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "PierreGondois" <pierre.gondois@arm.com>
To: "Attar, AbdulLateef (Abdul Lateef)" <AbdulLateef.Attar@amd.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Subject: Re: [edk2-devel] [Resend PATCH v4 4/4] DynamicTablesPkg: AML Code generation to invoke a method
Date: Wed, 20 Dec 2023 08:48:30 +0100	[thread overview]
Message-ID: <40d1fe0b-db99-45cd-b3ae-5e6b5472b45b@arm.com> (raw)
In-Reply-To: <IA1PR12MB6458968883A5E927BB89B2E0E096A@IA1PR12MB6458.namprd12.prod.outlook.com>

Hello Abdul,

On 12/20/23 05:33, Attar, AbdulLateef (Abdul Lateef) wrote:
> [Public]
> 
> Hi Pierre,
>          Regarding the below comment
>> +AmlCodeGenInvokeMethod (
>> +  IN  CONST CHAR8             *MethodNameString,
>> +  IN        UINT8             NumArgs,
>> +  IN        AML_METHOD_PARAM  *Parameters   OPTIONAL,
>> +  IN        AML_NODE_HANDLE   ParentNode
> Maybe it would be worth also having an OUT parameter in case someone doesn't want to attach the method invocation directly (cf. other methods in the file):
>     OUT AML_OBJECT_NODE_HANDLE  *NewObjectNode   OPTIONAL
> 
> I don’t think its possible because MethodInvocation is a stream of objects, and first object is NameString(method name) which is "Data node".
> AML library doesn’t allow adding variable list arguments to the "Data node", only "object node" is supported.

Yes right,

Regards,
Pierre

> 
> I'll address the remaining comments and submit the v5 patch.
> 
> Thanks
> AbduL
> 
> -----Original Message-----
> From: Pierre Gondois <pierre.gondois@arm.com>
> Sent: Tuesday, December 19, 2023 7:41 PM
> To: Attar, AbdulLateef (Abdul Lateef) <AbdulLateef.Attar@amd.com>; devel@edk2.groups.io
> Cc: Attar, AbdulLateef (Abdul Lateef) <AbdulLateef.Attar@amd.com>; Sami Mujawar <sami.mujawar@arm.com>
> Subject: Re: [Resend PATCH v4 4/4] DynamicTablesPkg: AML Code generation to invoke a method
> 
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
> 
> 
> Hello Abdul,
> The new function looks good, there is just one small issue with the tree layout,
> 
> Regards,
> Pierre
> 
> On 12/19/23 04:06, Abdul Lateef Attar wrote:
>> From: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
>>
>> Adds API to generate AML code to invoke/call another method. Also
>> provides ability to pass arguments of type integer, string, ArgObj or
>> LocalObj.
>>
>> Cc: Pierre Gondois <pierre.gondois@arm.com>
>> Cc: Sami Mujawar <sami.mujawar@arm.com>
>> Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
>> ---
>>    .../Include/Library/AmlLib/AmlLib.h           | 112 +++++++++
>>    .../Common/AmlLib/CodeGen/AmlCodeGen.c        | 236 +++++++++++++++++-
>>    2 files changed, 347 insertions(+), 1 deletion(-)
>>
>> diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
>> b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
>> index eb8740692f..fb16637f02 100644
>> --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
>> +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
>> @@ -101,6 +101,56 @@ typedef enum {
>>      AmlAddressRangeMax      = 4
>>    } AML_MEMORY_ATTRIBUTES_MTP;
>>
>> +/** Method parameter types
>> +
>> +  Possible values are:
>> +    0 - AmlMethodParamTypeInteger
>> +    1 - AmlMethodParamTypeString
>> +    2 - AmlMethodParamTypeArg
>> +    3 - AmlMethodParamTypeLocal
>> +
>> +  @par Reference(s)
>> +  - ACPI 6.5, s20.2.5 "Term Objects Encoding"
>> +
>> +**/
>> +typedef enum {
>> +  AmlMethodParamTypeInteger = 0,
>> +  AmlMethodParamTypeString  = 1,
>> +  AmlMethodParamTypeArg     = 2,
>> +  AmlMethodParamTypeLocal   = 3
>> +} AML_METHOD_PARAM_TYPE;
>> +
>> +/** AML Method parameter data
>> +  holds the AML method parameter data.
>> +**/
>> +typedef union {
>> +  UINT8     Arg;
>> +  UINT8     Local;
>> +  UINT64    Integer;
>> +  VOID      *Buffer;
>> +} AML_METHOD_PARAM_DATA;
>> +
>> +/** structure to hold AML method parameter types
>> +  Type  -   Type of parameter
>> +  Data  -   holds data of parameter
>> +            if Type is AmlMethodParamTypeInteger
>> +              then Data is of type Integer to hold integer value.
>> +            if Type is AmlMethodParamTypeString
>> +              then Data contains null terminated string.
>> +            If Type is AmlMethodParamTypeArg
>> +              then Data contains the Argument number,
>> +              0 to 6 are supported value.
>> +            If Type is AmlMethodParamTypeLocal
>> +              then Data contains the Local variable number,
>> +              0 to 7 are supported value.
>> +  DataSize - for future use
>> +**/
>> +typedef struct {
>> +  AML_METHOD_PARAM_TYPE    Type;
>> +  AML_METHOD_PARAM_DATA    Data;
>> +  UINTN                    DataSize;
>> +} AML_METHOD_PARAM;
>> +
>>    /** Parse the definition block.
>>
>>      The function parses the whole AML blob. It starts with the ACPI
>> DSDT/SSDT @@ -1693,4 +1743,66 @@ AmlAddNameStringToNamedPackage (
>>      IN AML_OBJECT_NODE_HANDLE  NamedNode
>>      );
>>
>> +/** AML code generation to invoke/call another method.
>> +
>> +  This method is subset implementation of MethodInvocation  defined
>> + in the ACPI specification 6.5,  section 20.2.5 "Term Objects
>> + Encoding".
>> +  Added integer, string, ArgObj and LocalObj support.
>> +
>> +  Example 1:
>> +    AmlCodeGenInvokeMethod ("MET0", 0, NULL, ParentNode);
>> +    is equivalent of the following ASL code:
>> +      MET0 ();
>> +
>> +  Example 2:
>> +    AML_METHOD_PARAM  Param[4];
>> +    Param[0].Data.Integer = 0x100;
>> +    Param[0].Type = AmlMethodParamTypeInteger;
>> +    Param[1].Data.Buffer = "TEST";
>> +    Param[1].Type = AmlMethodParamTypeString;
>> +    Param[2].Data.Arg = 0;
>> +    Param[2].Type = AmlMethodParamTypeArg;
>> +    Param[3].Data.Local = 2;
>> +    Param[3].Type = AmlMethodParamTypeLocal;
>> +    AmlCodeGenInvokeMethod ("MET0", 4, Param, ParentNode);
>> +
>> +    is equivalent of the following ASL code:
>> +      MET0 (0x100, "TEST", Arg0, Local2);
>> +
>> +  Example 3:
>> +    AML_METHOD_PARAM  Param[2];
>> +    Param[0].Data.Arg = 0;
>> +    Param[0].Type = AmlMethodParamTypeArg;
>> +    Param[1].Data.Integer = 0x100;
>> +    Param[1].Type = AmlMethodParamTypeInteger;
>> +    AmlCodeGenMethodRetNameString ("MET2", NULL, 2, TRUE, 0, ParentNode, &MethodNode);
>> +    AmlCodeGenInvokeMethod ("MET3", 2, Param, MethodNode);
>> +
>> +    is equivalent of the following ASL code:
>> +    Method (MET2, 2, Serialized)
>> +    {
>> +      MET3 (Arg0, 0x0100)
>> +    }
>> +
>> +  @param [in] MethodNameString  Method name to be called/invoked.
>> +  @param [in] NumArgs           Number of arguments to be passed,
>> +                                0 to 7 are permissible values.
>> +  @param [in] Parameters        contains the parameter data.
>> +  @param [in] ParentNode        set ParentNode as the parent> +                                of the node created.
>> +
>> +  @retval EFI_SUCCESS             Success.
>> +  @retval EFI_INVALID_PARAMETER   Invalid parameter.
>> +  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
>> + **/
>> +EFI_STATUS
>> +EFIAPI
>> +AmlCodeGenInvokeMethod (
>> +  IN  CONST CHAR8             *MethodNameString,
>> +  IN        UINT8             NumArgs,
>> +  IN        AML_METHOD_PARAM  *Parameters   OPTIONAL,
>> +  IN        AML_NODE_HANDLE   ParentNode
>> +  );
>> +
>>    #endif // AML_LIB_H_
>> diff --git
>> a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
>> b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
>> index a6db34fb97..688eefdcef 100644
>> --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
>> +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
>> @@ -2,6 +2,7 @@
>>      AML Code Generation.
>>
>>      Copyright (c) 2020 - 2022, Arm Limited. All rights reserved.<BR>
>> +  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights
>> + reserved.<BR>
>>
>>      SPDX-License-Identifier: BSD-2-Clause-Patent
>>    **/
>> @@ -921,7 +922,7 @@ AmlCodeGenNameUnicodeString (
>>      Status = AmlCreateDataNode (
>>                 EAmlNodeDataTypeRaw,
>>                 (CONST UINT8 *)String,
>> -             StrSize (String),
>> +             (UINT32)StrSize (String),
>>                 &DataNode
>>                 );
>>      if (EFI_ERROR (Status)) {
>> @@ -3849,3 +3850,236 @@ exit_handler:
>>
>>      return Status;
>>    }
>> +
>> +/** AML code generation to invoke/call another method.
>> +
>> +  This method is subset implementation of MethodInvocation  defined
>> + in the ACPI specification 6.5,  section 20.2.5 "Term Objects
>> + Encoding".
>> +  Added integer, string, ArgObj and LocalObj support.
>> +
>> +  Example 1:
>> +    AmlCodeGenInvokeMethod ("MET0", 0, NULL, ParentNode);
>> +    is equivalent of the following ASL code:
>> +      MET0 ();
>> +
>> +  Example 2:
>> +    AML_METHOD_PARAM  Param[4];
>> +    Param[0].Data.Integer = 0x100;
>> +    Param[0].Type = AmlMethodParamTypeInteger;
>> +    Param[1].Data.Buffer = "TEST";
>> +    Param[1].Type = AmlMethodParamTypeString;
>> +    Param[2].Data.Arg = 0;
>> +    Param[2].Type = AmlMethodParamTypeArg;
>> +    Param[3].Data.Local = 2;
>> +    Param[3].Type = AmlMethodParamTypeLocal;
>> +    AmlCodeGenInvokeMethod ("MET0", 4, Param, ParentNode);
>> +
>> +    is equivalent of the following ASL code:
>> +      MET0 (0x100, "TEST", Arg0, Local2);
>> +
>> +  Example 3:
>> +    AML_METHOD_PARAM  Param[2];
>> +    Param[0].Data.Arg = 0;
>> +    Param[0].Type = AmlMethodParamTypeArg;
>> +    Param[1].Data.Integer = 0x100;
>> +    Param[1].Type = AmlMethodParamTypeInteger;
>> +    AmlCodeGenMethodRetNameString ("MET2", NULL, 2, TRUE, 0, ParentNode, &MethodNode);
>> +    AmlCodeGenInvokeMethod ("MET3", 2, Param, MethodNode);
>> +
>> +    is equivalent of the following ASL code:
>> +    Method (MET2, 2, Serialized)
>> +    {
>> +      MET3 (Arg0, 0x0100)
>> +    }
>> +
>> +  @param [in] MethodNameString  Method name to be called/invoked.
>> +  @param [in] NumArgs           Number of arguments to be passed,
>> +                                0 to 7 are permissible values.
>> +  @param [in] Parameters        contains the parameter data.
>> +  @param [in] ParentNode        set ParentNode as the parent
> 
> NIT: set->Set
> 
>> +                                of the node created.
>> +
>> +  @retval EFI_SUCCESS             Success.
>> +  @retval EFI_INVALID_PARAMETER   Invalid parameter.
>> +  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
>> + **/
>> +EFI_STATUS
>> +EFIAPI
>> +AmlCodeGenInvokeMethod (
>> +  IN  CONST CHAR8             *MethodNameString,
>> +  IN        UINT8             NumArgs,
>> +  IN        AML_METHOD_PARAM  *Parameters   OPTIONAL,
>> +  IN        AML_NODE_HANDLE   ParentNode
> 
> Maybe it would be worth also having an OUT parameter in case someone doesn't want to attach the method invocation directly (cf. other methods in the file):
>     OUT AML_OBJECT_NODE_HANDLE  *NewObjectNode   OPTIONAL
> 
> 
>> +  )
>> +{
>> +  EFI_STATUS       Status;
>> +  UINT8            Index;
>> +  CHAR8            *AmlNameString;
>> +  UINT32           AmlNameStringSize;
>> +  AML_DATA_NODE    *DataNode;
>> +  AML_OBJECT_NODE  *IntNode;
>> +  AML_NODE_HANDLE  HeadNode;
>> +  AML_NODE_HANDLE  CurrentNode;
>> +  AML_OBJECT_NODE  *ObjectNode;
>> +
>> +  if ((MethodNameString == NULL) || (ParentNode == NULL)) {
>> +    ASSERT (0);
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  if ((NumArgs > 7) ||
>> +      ((Parameters == NULL) && (NumArgs > 0)))  {
>> +    ASSERT (0);
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  if (Parameters != NULL) {
>> +    /// Validate and convert the Parameters to the stream of node
>> +    HeadNode    = NULL;
>> +    CurrentNode = NULL;
>> +    for (Index = 0; Index < NumArgs; Index++) {
>> +      switch (Parameters[Index].Type) {
>> +        case AmlMethodParamTypeInteger:
>> +          IntNode = NULL;
>> +          Status  = AmlCodeGenInteger (Parameters[Index].Data.Integer, &IntNode);
>> +          if (EFI_ERROR (Status)) {
>> +            ASSERT_EFI_ERROR (Status);
>> +            goto exit_handler;
>> +          }
>> +
>> +          CurrentNode = (AML_NODE_HANDLE)IntNode;
>> +          break;
>> +        case AmlMethodParamTypeString:
>> +          ObjectNode = NULL;
>> +          if (Parameters[Index].Data.Buffer == NULL) {
>> +            ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
>> +            Status = EFI_INVALID_PARAMETER;
>> +            goto exit_handler;
>> +          }
>> +
>> +          Status = AmlCodeGenString (Parameters[Index].Data.Buffer, &ObjectNode);
>> +          if (EFI_ERROR (Status)) {
>> +            ASSERT_EFI_ERROR (Status);
>> +            goto exit_handler;
>> +          }
>> +
>> +          CurrentNode = (AML_NODE_HANDLE)ObjectNode;
>> +          break;
>> +        case AmlMethodParamTypeArg:
>> +          ObjectNode = NULL;
>> +          if (Parameters[Index].Data.Arg > (UINT8)(AML_ARG6 - AML_ARG0)) {
>> +            ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
>> +            Status = EFI_INVALID_PARAMETER;
>> +            goto exit_handler;
>> +          }
>> +
>> +          Status = AmlCreateObjectNode (
>> +                     AmlGetByteEncodingByOpCode (AML_ARG0 + Parameters[Index].Data.Arg, 0),
>> +                     0,
>> +                     &ObjectNode
>> +                     );
>> +          if (EFI_ERROR (Status)) {
>> +            ASSERT_EFI_ERROR (Status);
>> +            goto exit_handler;
>> +          }
>> +
>> +          CurrentNode = (AML_NODE_HANDLE)ObjectNode;
>> +          break;
>> +        case AmlMethodParamTypeLocal:
>> +          ObjectNode = NULL;
>> +          if (Parameters[Index].Data.Local > (UINT8)(AML_LOCAL7 - AML_LOCAL0)) {
>> +            ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
>> +            Status = EFI_INVALID_PARAMETER;
>> +            goto exit_handler;
>> +          }
>> +
>> +          Status = AmlCreateObjectNode (
>> +                     AmlGetByteEncodingByOpCode (AML_LOCAL0 + Parameters[Index].Data.Local, 0),
>> +                     0,
>> +                     &ObjectNode
>> +                     );
>> +          if (EFI_ERROR (Status)) {
>> +            ASSERT_EFI_ERROR (Status);
>> +            goto exit_handler;
>> +          }
>> +
>> +          CurrentNode = (AML_NODE_HANDLE)ObjectNode;
>> +          break;
>> +        default:
>> +          ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
>> +          Status = EFI_INVALID_PARAMETER;
>> +          goto exit_handler;
>> +          break;
>> +      }
>> +
>> +      if (HeadNode == NULL) {
>> +        HeadNode = CurrentNode;
> 
> I think there is an issue here. The method arguments should be attached to the variable list of arguments of the parent, not of another argument.
> 
> For instance, the following:
> Scope (_SB) {
>     MET0 (Arg0, Arg1, Arg2)
> }
> 
> Should create a tree as:
> _SB
> \- (Variable list of arguments of _SB)
>     - MET0
>     - Arg0
>     - Arg1
>     - Arg2
> 
> With the present code, the created tree is:
> _SB
> \- (Variable list of arguments of _SB)
>     - MET0
>     - Arg0
>     \- (Variable list of arguments of Arg0)
>       - Arg1
>       - Arg2
> 
> When serializing the tree, the generated binary is identical, but the tree is incorrect.
> 
>> +      } else {
>> +        Status = AmlVarListAddTail (
>> +                   HeadNode,
>> +                   CurrentNode
>> +                   );
>> +        if (EFI_ERROR (Status)) {
>> +          ASSERT_EFI_ERROR (Status);
>> +          goto exit_handler;
>> +        }
>> +      }
>> +    }
>> +  }
>> +
>> +  /// Create called/invoked method name string  Status =
>> + ConvertAslNameToAmlName (MethodNameString, &AmlNameString);  if
>> + (EFI_ERROR (Status)) {
>> +    ASSERT_EFI_ERROR (Status);
>> +    goto exit_handler;
>> +  }
>> +
>> +  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
>> + if (EFI_ERROR (Status)) {
>> +    ASSERT_EFI_ERROR (Status);
>> +    FreePool (AmlNameString);
>> +    goto exit_handler;
>> +  }
>> +
>> +  DataNode = NULL;
>> +  Status   = AmlCreateDataNode (
>> +               EAmlNodeDataTypeNameString,
>> +               (UINT8 *)AmlNameString,
>> +               AmlNameStringSize,
>> +               &DataNode
>> +               );
>> +  FreePool (AmlNameString);
>> +  if (EFI_ERROR (Status)) {
>> +    ASSERT_EFI_ERROR (Status);
>> +    goto exit_handler;
>> +  }
>> +
>> +  Status = AmlVarListAddTail (
>> +             (AML_NODE_HANDLE)ParentNode,
>> +             (AML_NODE_HANDLE)DataNode
>> +             );
>> +  if (EFI_ERROR (Status)) {
> 
> I think DataNode would not be freed if we fail here.
> 
>> +    ASSERT_EFI_ERROR (Status);
>> +    goto exit_handler;
>> +  }
>> +
>> +  Status = AmlVarListAddTail (
>> +             (AML_NODE_HANDLE)ParentNode,
>> +             HeadNode
>> +             );
>> +  if (EFI_ERROR (Status)) {
>> +    ASSERT_EFI_ERROR (Status);
>> +    goto exit_handler;
>> +  }
>> +
>> +  return Status;
>> +
>> +exit_handler:
>> +  if (HeadNode != NULL) {
>> +    AmlDeleteTree (HeadNode);
>> +  }
>> +
>> +  return Status;
>> +}


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#112750): https://edk2.groups.io/g/devel/message/112750
Mute This Topic: https://groups.io/mt/103256864/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



      reply	other threads:[~2023-12-20  7:48 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-19  3:06 [edk2-devel] [Resend PATCH v4 0/4] DynamicTablesPkg: Adds WordIO and method invocation ability Abdul Lateef Attar via groups.io
2023-12-19  3:06 ` [edk2-devel] [Resend PATCH v4 1/4] DynamicTablesPkg: AML Code generation for word I/O ranges Abdul Lateef Attar via groups.io
2023-12-19  3:06 ` [edk2-devel] [Resend PATCH v4 2/4] DynamicTablesPkg: Corrects AmlCodeGenRdWordBusNumber parameters Abdul Lateef Attar via groups.io
2023-12-19  3:06 ` [edk2-devel] [Resend PATCH v4 3/4] DynamicTablesPkg: Corrects function pointer typedef of AML_PARSE_FUNCTION Abdul Lateef Attar via groups.io
2023-12-19  3:06 ` [edk2-devel] [Resend PATCH v4 4/4] DynamicTablesPkg: AML Code generation to invoke a method Abdul Lateef Attar via groups.io
2023-12-19 14:11   ` PierreGondois
2023-12-20  4:33     ` Abdul Lateef Attar via groups.io
2023-12-20  7:48       ` PierreGondois [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40d1fe0b-db99-45cd-b3ae-5e6b5472b45b@arm.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox