| .. SPDX-License-Identifier: GPL-2.0-or-later | |
| ================== | |
| ACPI WMI interface | |
| ================== | |
| The ACPI WMI interface is a proprietary extension of the ACPI specification made | |
| by Microsoft to allow hardware vendors to embed WMI (Windows Management Instrumentation) | |
| objects inside their ACPI firmware. Typical functions implemented over ACPI WMI | |
| are hotkey events on modern notebooks and configuration of BIOS options. | |
| PNP0C14 ACPI device | |
| ------------------- | |
| Discovery of WMI objects is handled by defining ACPI devices with a PNP ID | |
| of ``PNP0C14``. These devices will contain a set of ACPI buffers and methods | |
| used for mapping and execution of WMI methods and/or queries. If there exist | |
| multiple of such devices, then each device is required to have a | |
| unique ACPI UID. | |
| _WDG buffer | |
| ----------- | |
| The ``_WDG`` buffer is used to discover WMI objects and is required to be | |
| static. Its internal structure consists of data blocks with a size of 20 bytes, | |
| containing the following data: | |
| ======= =============== ===================================================== | |
| Offset Size (in bytes) Content | |
| ======= =============== ===================================================== | |
| 0x00 16 128 bit Variant 2 object GUID. | |
| 0x10 2 2 character method ID or single byte notification ID. | |
| 0x12 1 Object instance count. | |
| 0x13 1 Object flags. | |
| ======= =============== ===================================================== | |
| The WMI object flags control whether the method or notification ID is used: | |
| - 0x1: Data block is expensive to collect. | |
| - 0x2: Data block contains WMI methods. | |
| - 0x4: Data block contains ASCIZ string. | |
| - 0x8: Data block describes a WMI event, use notification ID instead | |
| of method ID. | |
| Each WMI object GUID can appear multiple times inside a system. | |
| The method/notification ID is used to construct the ACPI method names used for | |
| interacting with the WMI object. | |
| WQxx ACPI methods | |
| ----------------- | |
| If a data block does not contain WMI methods, then its content can be retrieved | |
| by this required ACPI method. The last two characters of the ACPI method name | |
| are the method ID of the data block to query. Their single parameter is an | |
| integer describing the instance which should be queried. This parameter can be | |
| omitted if the data block contains only a single instance. | |
| WSxx ACPI methods | |
| ----------------- | |
| Similar to the ``WQxx`` ACPI methods, except that it is optional and takes an | |
| additional buffer as its second argument. The instance argument also cannot | |
| be omitted. | |
| WMxx ACPI methods | |
| ----------------- | |
| Used for executing WMI methods associated with a data block. The last two | |
| characters of the ACPI method name are the method ID of the data block | |
| containing the WMI methods. Their first parameter is a integer describing the | |
| instance which methods should be executed. The second parameter is an integer | |
| describing the WMI method ID to execute, and the third parameter is a buffer | |
| containing the WMI method parameters. If the data block is marked as containing | |
| an ASCIZ string, then this buffer should contain an ASCIZ string. The ACPI | |
| method will return the result of the executed WMI method. | |
| WExx ACPI methods | |
| ----------------- | |
| Used for optionally enabling/disabling WMI events, the last two characters of | |
| the ACPI method are the notification ID of the data block describing the WMI | |
| event as hexadecimal value. Their first parameter is an integer with a value | |
| of 0 if the WMI event should be disabled, other values will enable | |
| the WMI event. | |
| Those ACPI methods are always called even for WMI events not registered as | |
| being expensive to collect to match the behavior of the Windows driver. | |
| WCxx ACPI methods | |
| ----------------- | |
| Similar to the ``WExx`` ACPI methods, except that instead of WMI events it controls | |
| data collection of data blocks registered as being expensive to collect. Thus the | |
| last two characters of the ACPI method name are the method ID of the data block | |
| to enable/disable. | |
| Those ACPI methods are also called before setting data blocks to match the | |
| behavior of the Windows driver. | |
| _WED ACPI method | |
| ---------------- | |
| Used to retrieve additional WMI event data, its single parameter is a integer | |
| holding the notification ID of the event. This method should be evaluated every | |
| time an ACPI notification is received, since some ACPI implementations use a | |
| queue to store WMI event data items. This queue will overflow after a couple | |
| of WMI events are received without retrieving the associated WMI event data. | |
| Conversion rules for ACPI data types | |
| ------------------------------------ | |
| Consumers of the ACPI-WMI interface use binary buffers to exchange data with the WMI driver core, | |
| with the internal structure of the buffer being only know to the consumers. The WMI driver core is | |
| thus responsible for converting the data inside the buffer into an appropriate ACPI data type for | |
| consumption by the ACPI firmware. Additionally, any data returned by the various ACPI methods needs | |
| to be converted back into a binary buffer. | |
| The layout of said buffers is defined by the MOF description of the WMI method or data block in | |
| question [1]_: | |
| =============== ======================================================================= ========= | |
| Data Type Layout Alignment | |
| =============== ======================================================================= ========= | |
| ``string`` Starts with an unsigned 16-bit little endian integer specifying 2 bytes | |
| the length of the string data in bytes, followed by the string data | |
| encoded as UTF-16LE with **optional** NULL termination and padding. | |
| Keep in mind that some firmware implementations might depend on the | |
| terminating NULL character to be present. Also the padding should | |
| always be performed with NULL characters. | |
| ``boolean`` Single byte where 0 means ``false`` and nonzero means ``true``. 1 byte | |
| ``sint8`` Signed 8-bit integer. 1 byte | |
| ``uint8`` Unsigned 8-bit integer. 1 byte | |
| ``sint16`` Signed 16-bit little endian integer. 2 bytes | |
| ``uint16`` Unsigned 16-bit little endian integer. 2 bytes | |
| ``sint32`` Signed 32-bit little endian integer. 4 bytes | |
| ``uint32`` Unsigned 32-bit little endian integer. 4 bytes | |
| ``sint64`` Signed 64-bit little endian integer. 8 bytes | |
| ``uint64`` Unsigned 64-bit little endian integer. 8 bytes | |
| ``datetime`` A fixed-length 25-character UTF-16LE string with the format 2 bytes | |
| *yyyymmddhhmmss.mmmmmmsutc* where *yyyy* is the 4-digit year, *mm* is | |
| the 2-digit month, *dd* is the 2-digit day, *hh* is the 2-digit hour | |
| based on a 24-hour clock, *mm* is the 2-digit minute, *ss* is the | |
| 2-digit second, *mmmmmm* is the 6-digit microsecond, *s* is a plus or | |
| minus character depending on whether *utc* is a positive or negative | |
| offset from UTC (or a colon if the date is an interval). Unpopulated | |
| fields should be filled with asterisks. | |
| =============== ======================================================================= ========= | |
| Arrays should be aligned based on the alignment of their base type, while objects should be | |
| aligned based on the largest alignment of an element inside them. | |
| All buffers returned by the WMI driver core are 8-byte aligned. When converting ACPI data types | |
| into such buffers the following conversion rules apply: | |
| =============== ============================================================ | |
| ACPI Data Type Converted into | |
| =============== ============================================================ | |
| Buffer Copied as-is. | |
| Integer Converted into a ``uint32``. | |
| String Converted into a ``string`` with a terminating NULL character | |
| to match the behavior the of the Windows driver. | |
| Package Each element inside the package is converted with alignment | |
| of the resulting data types being respected. Nested packages | |
| are not allowed. | |
| =============== ============================================================ | |
| The Windows driver does attempt to handle nested packages, but this results in internal data | |
| structures (``_ACPI_METHOD_ARGUMENT_V1``) erroneously being copied into the resulting buffer. | |
| ACPI firmware implementations should thus not return nested packages from ACPI methods | |
| associated with the ACPI-WMI interface. | |
| References | |
| ========== | |
| .. [1] https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/driver-defined-wmi-data-items |