ACPI: \134_SB.AMW0.WQMO: 1 arguments were passed to a non-method ACPI object (Buffer)

The Environment:
Dell Latitude E5420 laptop, from 2011, latest BIOS (A14), 8gb RAM, Intel Core i5-2430M processor
FreeBSD AMD64 RELEASE 14.0-p4, standard kernel.

The Issue:
The following message appears at boot:
Code:
ACPI: \134_SB.AMW0.WQMO: 1 arguments were passed to a non-method ACPI object (Buffer) (20221020/nsarguments-361)
Indicates a (minor) problem parsing the machine ACPI tables at boot, attributable to either a bug in FreeBSD's ACPI parser or (more likely) a bug in the AML code of the machine.

Would like to further diagnose the issue and either fix buggy AML via patch, or submit an issue to ACPI maintainers.

The Research:
Retrieved ACPI bin from hw with
acpidump -d -t > DSDT.dsl

Relevant sections below, cut for length
Code:
    Scope (\_SB)
    {
        Device (AMW0)
        {
            Mutex (WMIX, 0x01)
            Name (_HID, "*pnp0c14")  // _HID: Hardware ID
            Name (_UID, 0x00)  // _UID: Unique ID
            Name (_WDG, Buffer (0x64)
            {
                /* 0000 */  0xBC, 0xDC, 0x9D, 0x8D, 0x97, 0xA9, 0xDA, 0x11,  // ........
                /* 0008 */  0xB0, 0x12, 0xB6, 0x22, 0xA1, 0xEF, 0x54, 0x92,  // ..."..T.
                /* 0010 */  0x41, 0x41, 0x01, 0x00, 0xCE, 0x93, 0x05, 0xA8,  // AA......
                /* 0018 */  0x97, 0xA9, 0xDA, 0x11, 0xB0, 0x12, 0xB6, 0x22,  // ......."
                /* 0020 */  0xA1, 0xEF, 0x54, 0x92, 0x42, 0x41, 0x01, 0x02,  // ..T.BA..
                /* 0028 */  0x94, 0x59, 0xBB, 0x9D, 0x97, 0xA9, 0xDA, 0x11,  // .Y......
                /* 0030 */  0xB0, 0x12, 0xB6, 0x22, 0xA1, 0xEF, 0x54, 0x92,  // ..."..T.
                /* 0038 */  0xD0, 0x00, 0x01, 0x08, 0xE0, 0x6C, 0x77, 0xA3,  // .....lw.
                /* 0040 */  0x88, 0x1E, 0xDB, 0x11, 0xA9, 0x8B, 0x08, 0x00,  // ........
                /* 0048 */  0x20, 0x0C, 0x9A, 0x66, 0x42, 0x43, 0x01, 0x00,  //  ..fBC..
                /* 0050 */  0x21, 0x12, 0x90, 0x05, 0x66, 0xD5, 0xD1, 0x11,  // !...f...
                /* 0058 */  0xB2, 0xF0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0x10,  // ......).
                /* 0060 */  0x4D, 0x4F, 0x01, 0x00                           // MO..
            })
            Name (INFO, Buffer (0x80){})
            Name (ECD0, 0x00)
            Method (WED0, 1, NotSerialized)
            {
                ECD0 = Arg0
                Return (Zero)
            }

...
            Name (WQMO, Buffer (0x04FD)
            {
                /* 0000 */  0x46, 0x4F, 0x4D, 0x42, 0x01, 0x00, 0x00, 0x00,  // FOMB....
                /* 0008 */  0xED, 0x04, 0x00, 0x00, 0xD8, 0x15, 0x00, 0x00,  // ........
                /* 0010 */  0x44, 0x53, 0x00, 0x01, 0x1A, 0x7D, 0xDA, 0x54,  // DS...}.T
                /* 0018 */  0x28, 0xD5, 0x8A, 0x00, 0x01, 0x06, 0x18, 0x42,  // (......B
                /* 0020 */  0x10, 0x0D, 0x10, 0x22, 0x21, 0x04, 0x12, 0x01,  // ..."!...
                /* 0028 */  0xA1, 0xC8, 0x2C, 0x0C, 0x86, 0x10, 0x38, 0x2E,  // ..,...8.
                /* 0030 */  0x84, 0x1C, 0x40, 0x48, 0x1C, 0x14, 0x4A, 0x08,  // ..@H..J.
                /* 0038 */  0x84, 0xFA, 0x13, 0xC8, 0xAF, 0x00, 0x84, 0x0E,  // ........
                /* 0040 */  0x05, 0xC8, 0x14, 0x60, 0x50, 0x80, 0x53, 0x04,  // ...`P.S.
                /* 0048 */  0x11, 0xF4, 0x2A, 0xC0, 0xA6, 0x00, 0x93, 0x02,  // ..*.....

...

            })
        }
    }
Some clues so far:
The obvious issue is that WQMO is being called as a Method w/ one argument, but in ACPI it is a Buffer instead (binary blob). The question is why: is Buffer correct, and if so, why is it being called from elsewhere as though it's a Method?

This portion of ACPI code corresponds to the WMI Interface provided by ACPI, which is a Windows extension to ACPI for laptop hotkeys and some BIOS stuff. _WDG table lists info about the methods and other resources in the section: MO is last, w/ GUID = {05901221-D566-11D1-B2F0-00A0C9062910}.

That GUID corresponds to the "WMI Embedded Binary MOF", a block of metadata that can be retrieved and decoded using special tools.
The Binary MOF can be obtained by doing a WMI data block query. The result is then returned as an ACPI buffer with a variable size.
In this case, "Buffer" seems correct. (Also, some ACPI dumps from other machines also have a BMOF block as Buffer, so either they're also broken or this is all correct)

Given that, I need to find the caller of WQMO, and maybe replace it with a block query instead - but I can't see any direct calls in the rest of ACPI disassembly... So, at this point: I'm stumped.

Next steps:
  • Is there a way I can "trace" the ACPI execution to see the point at which the error occurs?
  • Maybe I try a Linux live USB and see if dmesg reports the same issue there?
  • Does anyone else have any ideas?
 
Update:
Booted an Ubuntu live CD. It does not report this error - however, we do have this:
Code:
WQBC data block query control method not found
Searching Linux kernel source turns up some goodies in wmi.c - note the comments...

C:
    /*
     * Data Block Query Control Method (WQxx by convention) is
     * required per the WMI documentation. If it is not present,
     * we ignore this data block.
     */
    get_acpi_method_name(wblock, 'Q', method);
    result = get_subobj_info(device->handle, method, &info);

    if (result) {
        dev_warn(wmi_bus_dev,
             "%s data block query control method not found\n",
             method);
        return result;
    }

    wblock->dev.dev.type = &wmi_type_data;

    /*
     * The Microsoft documentation specifically states:
     *
     *   Data blocks registered with only a single instance
     *   can ignore the parameter.
     *
     * ACPICA will get mad at us if we call the method with the wrong number
     * of arguments, so check what our method expects.  (On some Dell
     * laptops, WQxx may not be a method at all.)
     */
    if (info->type != ACPI_TYPE_METHOD || info->param_count == 0)
        set_bit(WMI_READ_TAKES_NO_ARGS, &wblock->flags);

    kfree(info);

    get_acpi_method_name(wblock, 'S', method);
    if (acpi_has_method(device->handle, method))
        wblock->dev.setable = true;
Certainly it seems they are aware of the issue. I think I must own one of the "some Dell laptops" where WQxx is not a method!

I believe this is enough info to file a bug report w/ FreeBSD kernel: ideally, I think, the acpi-wmi code should be checking whether WQxx is a method or buffer, and better handling this case... say, retrieving the Embedded MOF "manually" via C code instead of trying to call the Block Query method if one doesn't exist - somewhere around this line, maybe: https://github.com/freebsd/freebsd-src/blob/main/sys/dev/acpi_support/acpi_wmi.c#L280

EDIT: Bug opened! https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=276308
 
Would like to further diagnose the issue and either fix buggy AML via patch, or submit an issue to ACPI maintainers.

Great dig and report, PR to pursue it etc - but I wonder:

Do you know what should or might occur if the machine's AML and/or FreeBSD ACPI code were fixed, in terms of enabled and/or improved functionality that this issue now appears to prevent?

Genuine ignorance; I've not seen or heard of this before.
 
Back
Top