Search code examples
acpiacpica

How to pass a buffer argument to a control method in `acpiexec` prompt?


I defined a buffer object and a control method to iterate the buffer object.

DefinitionBlock ("dsdt.asl", "DSDT", 0x02, "", "", 0x0) 
{ 
    Name (BUF0, Buffer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})

    Method (IDXA, 1) 
    {
        local0 = sizeof(Arg0) 
        local1 = 0 // use this as the index value 
        printf ("The size of the buffer is %o, Arg0 is: %o", local0, Arg0) 
        while (local0 > local1) 
        {
            printf ("inside loop:")
            printf ("%o", DeRefOf(Arg0[local1]))
            local1++ 
        }
    }
} 

It compiles it with iasl:

iasl dsdt.asl

Then I run it with acpiexec:

acpiexec dsdt.aml

In the acpiexec prompt, I tried to call the IDXA method with \BUF0 as arg0:

- eval \IDXA \BUF0  
Evaluating \IDXA
ACPI Debug:  "The size of the buffer is 0000000000000008, Arg0 is: 0000000000000000"
ACPI Debug:  "inside loop:"
ACPI Error: Needed [Buffer/String/Package], found [Integer] 0x555d39f95770 (20190509/exresop-617)
ACPI Error: AE_AML_OPERAND_TYPE, While resolving operands for [Index] (20190509/dswexec-500)
Failed at AML Offset 00056, Opcode 0088: Index (Arg0, Local1)

Initialized Local Variables for Method [IDXA]:
    Local0: 0x555d39f95840 <Obj>             Integer 0000000000000008
    Local1: 0x555d39f956f0 <Obj>             Integer 0000000000000000

Initialized Arguments for Method [IDXA]:  (1 arguments defined for method invocation)
    Arg0:   0x555d39f95770 <Obj>             Integer 0000000000000000

ACPI Error: Aborting method \IDXA due to previous error (AE_AML_OPERAND_TYPE) (20190509/psparse-581)
ACPI Error: AE_AML_OPERAND_TYPE, while executing \IDXA from AML Debugger (20190509/dbexec-226)
Evaluation of \IDXA failed with status AE_AML_OPERAND_TYPE

The error message says "Arg0 is: 0000000000000000".

And it seems it is an integer got passed in instead of a buffer array. So the index operator failed.

I can access the \BUF0 on the acpiexec prompt. But I cannot pass it to the \IDXA method.

- eval \BUF0
Evaluating \BUF0
Evaluation of \BUF0 returned object 0x55b97b465cd0, external buffer length 28
  [Buffer] Length 0A =     0000: 01 02 03 04 05 06 07 00 00 08                    // ..........

How to pass BUF0 to a ACPI control method in acpiexec prompt?


Solution

  • acpiexec has a set of limited capabilities on what it can supply as arguments to the executed methods. Its help in particularly says:

    Control Method Execution:            
      All <NameSeg>                       Evaluate all objects named NameSeg
      Evaluate <Namepath> [Arguments]     Evaluate object or control method
      Execute <Namepath> [Arguments]      Synonym for Evaluate
      Background <Namepath> [Arguments]   Evaluate object/method in a separate thread
      Thread <Threads><Loops><NamePath>   Spawn threads to execute method(s)
      Debug <Namepath> [Arguments]        Single-Step a control method
      [Arguments] formats:                Control method argument formats
         Hex Integer                      Integer
         "Ascii String"                   String
         (Hex Byte List)                  Buffer
             (01 42 7A BF)                Buffer example (4 bytes)
         [Package Element List]           Package
             [0x01 0x1234 "string"]       Package example (3 elements)
    

    that arguments formats supported are: Integer, String, Buffer, and Package. At the end of this part of help the examples are being provided. So, the Buffer may be supplied only in the form of ( XX YY ZZ ). There is nothing telling about references to the existing objects in ACPI namespace.

    The workaround is to do it in a two steps:

    • eval BUF0 and copy the hex dump of the buffer (might require a bit more work if buffer is long enough);
    • type eval IDXA ( ...copy_and_paste_the_buffer_contents_here... )

    These steps will give you the desired result:

    - eval BUF0
    Evaluating \BUF0
    Evaluation of \BUF0 returned object 0x583cfa5a2d60, external buffer length 28
      [Buffer] Length 0A =     0000: 01 02 03 04 05 06 07 08 09 0A                    // ..........
    
    - eval IDXA ( 01 02 03 04 05 06 07 08 09 0A )
    Evaluating \IDXA
    ACPI Debug:  "The size of the buffer is 000000000000000A, Arg0 is: 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000001"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000002"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000003"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000004"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000005"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000006"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000007"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000008"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "0000000000000009"
    ACPI Debug:  "inside loop:"
    ACPI Debug:  "000000000000000A"
    No object was returned from evaluation of \IDXA
    - 
    

    The proper solution is to patch acpiexec in order to add the required functionality. Since ACPICA is an Open Source project hosted on GitHub you can fork it, develop the feature, and send a PR back to the maintainers. Everybody will benefit from this.