Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,322 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
==============================================
Dell AWCC WMI interface driver (alienware-wmi)
==============================================
Introduction
============
The WMI device WMAX has been implemented for many Alienware and Dell's G-Series
models. Throughout these models, two implementations have been identified. The
first one, used by older systems, deals with HDMI, brightness, RGB, amplifier
and deep sleep control. The second one used by newer systems deals primarily
with thermal control and overclocking.
It is suspected that the latter is used by Alienware Command Center (AWCC) to
manage manufacturer predefined thermal profiles. The alienware-wmi driver
exposes Thermal_Information and Thermal_Control methods through the Platform
Profile API to mimic AWCC's behavior.
This newer interface, named AWCCMethodFunction has been reverse engineered, as
Dell has not provided any official documentation. We will try to describe to the
best of our ability its discovered inner workings.
.. note::
The following method description may be incomplete and some operations have
different implementations between devices.
WMI interface description
-------------------------
The WMI interface description can be decoded from the embedded binary MOF (bmof)
data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
::
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("WMI Function"), guid("{A70591CE-A997-11DA-B012-B622A1EF5492}")]
class AWCCWmiMethodFunction {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(13), Implemented, read, write, Description("Return Overclocking Report.")] void Return_OverclockingReport([out] uint32 argr);
[WmiMethodId(14), Implemented, read, write, Description("Set OCUIBIOS Control.")] void Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(15), Implemented, read, write, Description("Clear OC FailSafe Flag.")] void Clear_OCFailSafeFlag([out] uint32 argr);
[WmiMethodId(19), Implemented, read, write, Description("Get Fan Sensors.")] void GetFanSensors([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(20), Implemented, read, write, Description("Thermal Information.")] void Thermal_Information([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(21), Implemented, read, write, Description("Thermal Control.")] void Thermal_Control([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(23), Implemented, read, write, Description("MemoryOCControl.")] void MemoryOCControl([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(26), Implemented, read, write, Description("System Information.")] void SystemInformation([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(28), Implemented, read, write, Description("Power Information.")] void PowerInformation([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(32), Implemented, read, write, Description("FW Update GPIO toggle.")] void FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(33), Implemented, read, write, Description("Read Total of GPIOs.")] void ReadTotalofGPIOs([out] uint32 argr);
[WmiMethodId(34), Implemented, read, write, Description("Read GPIO pin Status.")] void ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(35), Implemented, read, write, Description("Read Chassis Color.")] void ReadChassisColor([out] uint32 argr);
[WmiMethodId(36), Implemented, read, write, Description("Read Platform Properties.")] void ReadPlatformProperties([out] uint32 argr);
[WmiMethodId(37), Implemented, read, write, Description("Game Shift Status.")] void GameShiftStatus([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(128), Implemented, read, write, Description("Caldera SW installation.")] void CalderaSWInstallation([out] uint32 argr);
[WmiMethodId(129), Implemented, read, write, Description("Caldera SW is released.")] void CalderaSWReleased([out] uint32 argr);
[WmiMethodId(130), Implemented, read, write, Description("Caldera Connection Status.")] void CalderaConnectionStatus([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(131), Implemented, read, write, Description("Surprise Unplugged Flag Status.")] void SurpriseUnpluggedFlagStatus([out] uint32 argr);
[WmiMethodId(132), Implemented, read, write, Description("Clear Surprise Unplugged Flag.")] void ClearSurpriseUnpluggedFlag([out] uint32 argr);
[WmiMethodId(133), Implemented, read, write, Description("Cancel Undock Request.")] void CancelUndockRequest([out] uint32 argr);
[WmiMethodId(135), Implemented, read, write, Description("Devices in Caldera.")] void DevicesInCaldera([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(136), Implemented, read, write, Description("Notify BIOS for SW ready to disconnect Caldera.")] void NotifyBIOSForSWReadyToDisconnectCaldera([out] uint32 argr);
[WmiMethodId(160), Implemented, read, write, Description("Tobii SW installation.")] void TobiiSWinstallation([out] uint32 argr);
[WmiMethodId(161), Implemented, read, write, Description("Tobii SW Released.")] void TobiiSWReleased([out] uint32 argr);
[WmiMethodId(162), Implemented, read, write, Description("Tobii Camera Power Reset.")] void TobiiCameraPowerReset([out] uint32 argr);
[WmiMethodId(163), Implemented, read, write, Description("Tobii Camera Power On.")] void TobiiCameraPowerOn([out] uint32 argr);
[WmiMethodId(164), Implemented, read, write, Description("Tobii Camera Power Off.")] void TobiiCameraPowerOff([out] uint32 argr);
};
Methods not described in the following document have unknown behavior.
Argument Structure
------------------
All input arguments have type **uint32** and their structure is very similar
between methods. Usually, the first byte corresponds to a specific *operation*
the method performs, and the subsequent bytes correspond to *arguments* passed
to this *operation*. For example, if an operation has code 0x01 and requires an
ID 0xA0, the argument you would pass to the method is 0xA001.
Thermal Methods
===============
WMI method GetFanSensors([in] uint32 arg2, [out] uint32 argr)
-------------------------------------------------------------
+--------------------+------------------------------------+--------------------+
| Operation (Byte 0) | Description | Arguments |
+====================+====================================+====================+
| 0x01 | Get the number of temperature | - Byte 1: Fan ID |
| | sensors related with a fan ID | |
+--------------------+------------------------------------+--------------------+
| 0x02 | Get the temperature sensor IDs | - Byte 1: Fan ID |
| | related to a fan sensor ID | - Byte 2: Index |
+--------------------+------------------------------------+--------------------+
WMI method Thermal_Information([in] uint32 arg2, [out] uint32 argr)
-------------------------------------------------------------------
+--------------------+------------------------------------+--------------------+
| Operation (Byte 0) | Description | Arguments |
+====================+====================================+====================+
| 0x01 | Unknown. | - None |
+--------------------+------------------------------------+--------------------+
| 0x02 | Get system description number with | - None |
| | the following structure: | |
| | | |
| | - Byte 0: Number of fans | |
| | - Byte 1: Number of temperature | |
| | sensors | |
| | - Byte 2: Unknown | |
| | - Byte 3: Number of thermal | |
| | profiles | |
+--------------------+------------------------------------+--------------------+
| 0x03 | List an ID or resource at a given | - Byte 1: Index |
| | index. Fan IDs, temperature IDs, | |
| | unknown IDs and thermal profile | |
| | IDs are listed in that exact | |
| | order. | |
| | | |
| | Operation 0x02 is used to know | |
| | which indexes map to which | |
| | resources. | |
| | | |
| | **Returns:** ID at a given index | |
+--------------------+------------------------------------+--------------------+
| 0x04 | Get the current temperature for a | - Byte 1: Sensor |
| | given temperature sensor. | ID |
+--------------------+------------------------------------+--------------------+
| 0x05 | Get the current RPM for a given | - Byte 1: Fan ID |
| | fan. | |
+--------------------+------------------------------------+--------------------+
| 0x06 | Get fan speed percentage. (not | - Byte 1: Fan ID |
| | implemented in every model) | |
+--------------------+------------------------------------+--------------------+
| 0x07 | Unknown. | - Unknown |
+--------------------+------------------------------------+--------------------+
| 0x08 | Get minimum RPM for a given FAN | - Byte 1: Fan ID |
| | ID. | |
+--------------------+------------------------------------+--------------------+
| 0x09 | Get maximum RPM for a given FAN | - Byte 1: Fan ID |
| | ID. | |
+--------------------+------------------------------------+--------------------+
| 0x0A | Get balanced thermal profile ID. | - None |
+--------------------+------------------------------------+--------------------+
| 0x0B | Get current thermal profile ID. | - None |
+--------------------+------------------------------------+--------------------+
| 0x0C | Get current `boost` value for a | - Byte 1: Fan ID |
| | given fan ID. | |
+--------------------+------------------------------------+--------------------+
WMI method Thermal_Control([in] uint32 arg2, [out] uint32 argr)
---------------------------------------------------------------
+--------------------+------------------------------------+--------------------+
| Operation (Byte 0) | Description | Arguments |
+====================+====================================+====================+
| 0x01 | Activate a given thermal profile. | - Byte 1: Thermal |
| | | profile ID |
+--------------------+------------------------------------+--------------------+
| 0x02 | Set a `boost` value for a given | - Byte 1: Fan ID |
| | fan ID. | - Byte 2: Boost |
+--------------------+------------------------------------+--------------------+
These are the known thermal profile codes:
+------------------------------+----------+------+
| Thermal Profile | Type | ID |
+==============================+==========+======+
| Custom | Special | 0x00 |
+------------------------------+----------+------+
| G-Mode | Special | 0xAB |
+------------------------------+----------+------+
| Quiet | Legacy | 0x96 |
+------------------------------+----------+------+
| Balanced | Legacy | 0x97 |
+------------------------------+----------+------+
| Balanced Performance | Legacy | 0x98 |
+------------------------------+----------+------+
| Performance | Legacy | 0x99 |
+------------------------------+----------+------+
| Balanced | USTT | 0xA0 |
+------------------------------+----------+------+
| Balanced Performance | USTT | 0xA1 |
+------------------------------+----------+------+
| Cool | USTT | 0xA2 |
+------------------------------+----------+------+
| Quiet | USTT | 0xA3 |
+------------------------------+----------+------+
| Performance | USTT | 0xA4 |
+------------------------------+----------+------+
| Low Power | USTT | 0xA5 |
+------------------------------+----------+------+
If a model supports the User Selectable Thermal Tables (USTT) profiles, it will
not support the Legacy profiles and vice-versa.
Every model supports the CUSTOM (0x00) thermal profile. GMODE replaces
PERFORMANCE in G-Series laptops.
WMI method GameShiftStatus([in] uint32 arg2, [out] uint32 argr)
---------------------------------------------------------------
+--------------------+------------------------------------+--------------------+
| Operation (Byte 0) | Description | Arguments |
+====================+====================================+====================+
| 0x01 | Toggle *Game Shift*. | - None |
+--------------------+------------------------------------+--------------------+
| 0x02 | Get *Game Shift* status. | - None |
+--------------------+------------------------------------+--------------------+
Game Shift Status does not change the fan speed profile but it could be some
sort of CPU/GPU power profile. Benchmarks have not been done.
This method is only present on Dell's G-Series laptops and it's implementation
implies GMODE thermal profile is available, even if operation 0x03 of
Thermal_Information does not list it.
G-key on Dell's G-Series laptops also changes Game Shift status, so both are
directly related.
Overclocking Methods
====================
WMI method MemoryOCControl([in] uint32 arg2, [out] uint32 argr)
---------------------------------------------------------------
AWCC supports memory overclocking, but this method is very intricate and has
not been deciphered yet.
GPIO control Methods
====================
Alienware and Dell G Series devices with the AWCC interface usually have an
embedded STM32 RGB lighting controller with USB/HID capabilities. It's vendor ID
is ``187c`` while it's product ID may vary from model to model.
The control of two GPIO pins of this MCU is exposed as WMI methods for debugging
purposes.
+--------------+--------------------------------------------------------------+
| Pin | Description |
+==============+===============================+==============================+
| 0 | Device Firmware Update (DFU) | **HIGH**: Enables DFU mode |
| | mode pin. | on next MCU boot. |
| | +------------------------------+
| | | **LOW**: Disables DFU mode |
| | | on next MCU boot. |
+--------------+-------------------------------+------------------------------+
| 1 | Negative Reset (NRST) pin. | **HIGH**: MCU is ON. |
| | | |
| | +------------------------------+
| | | **LOW**: MCU is OFF. |
| | | |
+--------------+-------------------------------+------------------------------+
See :ref:`acknowledgements` for more information on this MCU.
.. note::
Some GPIO control methods break the usual argument structure and take a
**Pin number** instead of an operation on the first byte.
WMI method FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr)
------------------------------------------------------------------
+--------------------+------------------------------------+--------------------+
| Operation (Byte 0) | Description | Arguments |
+====================+====================================+====================+
| Pin number | Set the pin status | - Byte 1: Pin |
| | | status |
+--------------------+------------------------------------+--------------------+
WMI method ReadTotalofGPIOs([out] uint32 argr)
----------------------------------------------
+--------------------+------------------------------------+--------------------+
| Operation (Byte 0) | Description | Arguments |
+====================+====================================+====================+
| N/A | Get the total number of GPIOs | - None |
+--------------------+------------------------------------+--------------------+
.. note::
Due to how WMI methods are implemented on the firmware level, this method
requires a dummy uint32 input argument when invoked.
WMI method ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr)
------------------------------------------------------------------
+--------------------+------------------------------------+--------------------+
| Operation (Byte 0) | Description | Arguments |
+====================+====================================+====================+
| Pin number | Get the pin status | - None |
+--------------------+------------------------------------+--------------------+
.. note::
There known firmware bug in some laptops where reading the status of a pin
also flips it.
Other information Methods
=========================
WMI method ReadChassisColor([out] uint32 argr)
----------------------------------------------
Returns the chassis color internal ID.
.. _acknowledgements:
Acknowledgements
================
Kudos to
* `AlexIII <https://github.com/AlexIII/tcc-g15>`_
* `T-Troll <https://github.com/T-Troll/alienfx-tools/>`_
* `Gabriel Marcano <https://gabriel.marcanobrady.family/blog/2024/12/16/dell-g5-5505-se-acpi-or-figuring-out-how-to-reset-the-rgb-controller/>`_
for documenting and testing some of this device's functionality, making it
possible to generalize this driver.
@@ -0,0 +1,207 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
========================================
Bitland MIFS driver (bitland-mifs-wmi)
========================================
Introduction
============
EC WMI interface description
============================
The EC WMI interface description can be decoded from the embedded binary MOF (bmof)
data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
::
class WMIEvent : __ExtrinsicEvent {
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT20"), guid("{46c93e13-ee9b-4262-8488-563bca757fef}")]
class HID_EVENT20 : WmiEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT21"), guid("{fa78e245-2c0f-4ca1-91cf-15f34e474850}")]
class HID_EVENT21 : WmiEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT22"), guid("{1dceaf0a-4d63-44bb-bd0c-0d6281bfddc5}")]
class HID_EVENT22 : WmiEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT23"), guid("{3f9e3c26-b077-4f86-91f5-37ff64d8c7ed}")]
class HID_EVENT23 : WmiEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
};
[WMI, Dynamic, provider("WmiProv"), Locale("MS\\0x409"), Description("Class used to operate firmware interface"), guid("{b60bfb48-3e5b-49e4-a0e9-8cffe1b3434b}")]
class MICommonInterface {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(1), Implemented, read, write, Description("Method used to support system functions.")] void MiInterface([in, Description("WMI Interface")] uint8 InData[32], [out] uint8 OutData[30], [out] uint16 Reserved);
};
Reverse-Engineering the EC WMI interface
========================================
The OEM software can be download from `this link <https://iknow.lenovo.com.cn/detail/429447>`_
Nothing is obfuscated, In this case, `ILSpy <https://github.com/icsharpcode/ILSpy>`_ could be helpful.
WMI Methods (MICommonInterface)
========================================
The ``MICommonInterface`` class (GUID: ``{b60bfb48-3e5b-49e4-a0e9-8cffe1b3434b}``)
is the primary control interface. It uses a 32-byte buffer for both input
(``InData``) and output (``OutData``).
Method Structure
----------------
The data packet follows a standardized format:
+----------+------------------------------------------------------------------+
| Byte | Description |
+==========+==================================================================+
| 1 | Method Type: Get (0xFA / 250) or Set (0xFB / 251) |
+----------+------------------------------------------------------------------+
| 3 | Command ID (Method Name) |
+----------+------------------------------------------------------------------+
| 4 - 31 | Arguments (for Set) or Return Data (for Get) |
+----------+------------------------------------------------------------------+
Command IDs
-----------
The following Command IDs are used in the third byte of the buffer:
+----------+-----------------------+------------------------------------------+
| ID | Name | Values / Description |
+==========+=======================+==========================================+
| 8 | SystemPerMode | 0: Balance, 1: Performance, 2: Quiet, |
| | | 3: Full-speed |
+----------+-----------------------+------------------------------------------+
| 9 | GPUMode | 0: Hybrid, 1: Discrete, 2: UMA |
+----------+-----------------------+------------------------------------------+
| 10 | KeyboardType | 0: White, 1: Single RGB, 2: Zone RGB |
+----------+-----------------------+------------------------------------------+
| 11 | FnLock | 0: Off, 1: On |
+----------+-----------------------+------------------------------------------+
| 12 | TPLock | 0: Unlock, 1: Lock (Touchpad) |
+----------+-----------------------+------------------------------------------+
| 13 | CPUGPUSYSFanSpeed | Returns 12 bytes of fan data: |
| | | Bytes 4-5: CPU Fan RPM (Little Endian) |
| | | Bytes 6-7: GPU Fan RPM (Little Endian) |
| | | Bytes 10-11: SYS Fan RPM (Little Endian) |
+----------+-----------------------+------------------------------------------+
| 16 | RGBKeyboardMode | 0: Off, 1: Auto Cyclic, 2: Fixed, |
| | | 3: Custom |
+----------+-----------------------+------------------------------------------+
| 17 | RGBKeyboardColor | Bytes 4, 5, 6: Red, Green, Blue values |
+----------+-----------------------+------------------------------------------+
| 18 | RGBKeyboardBrightness | 0-10: Brightness Levels, 128: Auto |
+----------+-----------------------+------------------------------------------+
| 19 | SystemAcType | 1: Type-C, 2: Circular Hole (DC) |
+----------+-----------------------+------------------------------------------+
| 20 | MaxFanSpeedSwitch | Byte 4: Fan Type (0: CPU/GPU, 1: SYS) |
| | | Byte 5: State (0: Off, 1: On) |
+----------+-----------------------+------------------------------------------+
| 21 | MaxFanSpeed | Sets manual fan speed duty cycle |
+----------+-----------------------+------------------------------------------+
| 22 | CPUThermometer | Returns CPU Temperature |
+----------+-----------------------+------------------------------------------+
WMI Events (HID_EVENT20)
========================
The driver listens for events from the ``HID_EVENT20`` class
(GUID: ``{46c93e13-ee9b-4262-8488-563bca757fef}``). These events are triggered
by hotkeys or system state changes (e.g., plugging in AC power).
Event Structure
---------------
The event data is provided in an 8-byte array (``EventDetail``):
+----------+------------------------------------------------------------------+
| Byte | Description |
+==========+==================================================================+
| 0 | Event Type (Always 0x01 for HotKey/Notification) |
+----------+------------------------------------------------------------------+
| 1 | Event ID (Corresponds to the Command IDs above) |
+----------+------------------------------------------------------------------+
| 2 | Value (The new state or value of the feature) |
+----------+------------------------------------------------------------------+
Common Event IDs:
-----------------
Note: reserved event ids are not listed there
+----------+------------------------------------------------------------------+
| Event Id | Description |
+==========+==================================================================+
| 4 | AirPlane mode change |
+----------+------------------------------------------------------------------+
| 5 | Keyboard brightness change |
+----------+------------------------------------------------------------------+
| 6 | Touchpad state (enabled/disabled) change |
+----------+------------------------------------------------------------------+
| 7 | FnLock state (enabled/disabled) change |
+----------+------------------------------------------------------------------+
| 8 | Keyboard mode change |
+----------+------------------------------------------------------------------+
| 9 | CapsLock state change |
+----------+------------------------------------------------------------------+
| 13 | NumLock state change |
+----------+------------------------------------------------------------------+
| 14 | ScrollLock state change |
+----------+------------------------------------------------------------------+
| 15 | Performance plan change |
+----------+------------------------------------------------------------------+
| 25 | Display refresh rate change |
+----------+------------------------------------------------------------------+
| 33 | Super key lock state (enabled/disabled) change |
+----------+------------------------------------------------------------------+
| 35 | Open control center key |
+----------+------------------------------------------------------------------+
Implementation Details
======================
Performance Modes
-----------------
Changing the performance mode via Command ID 0x08 (SystemPerMode) affects the
power limits (PL1/PL2) and fan curves managed by the Embedded Controller (EC).
Note that the "Full-speed" and "Performance" mode (1, 3) is typically only
available when the system is connected to a DC power source (not USB-C/PD).
In the driver implementation, switch to performance/full-speed mode without
DC power connected will throw the EOPNOTSUPP error.
Graphics Switching
------------------
The ``GPUMode`` (0x09) allows switching between Hybrid (Muxless) and Discrete
(Muxed) graphics. Changing this value usually requires a system reboot to
take effect in the BIOS/Firmware.
Fan Control
-----------
The system supports both automatic EC control and manual overrides. Command ID
0x14 (``MaxFanSpeedSwitch``) is used to toggle manual control, while ID 0x15
sets the actual PWM duty cycle.
@@ -0,0 +1,319 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
============================================
Dell DDV WMI interface driver (dell-wmi-ddv)
============================================
Introduction
============
Many Dell notebooks made after ~2020 support a WMI-based interface for
retrieving various system data like battery temperature, ePPID, diagnostic data
and fan/thermal sensor data.
This interface is likely used by the `Dell Data Vault` software on Windows,
so it was called `DDV`. Currently the ``dell-wmi-ddv`` driver supports
version 2 and 3 of the interface, with support for new interface versions
easily added.
.. warning:: The interface is regarded as internal by Dell, so no vendor
documentation is available. All knowledge was thus obtained by
trial-and-error, please keep that in mind.
Dell ePPID (electronic Piece Part Identification)
=================================================
The Dell ePPID is used to uniquely identify components in Dell machines,
including batteries. It has a form similar to `CC-PPPPPP-MMMMM-YMD-SSSS-FFF`
and contains the following information:
* Country code of origin (CC).
* Part number with the first character being a filling number (PPPPPP).
* Manufacture Identification (MMMMM).
* Manufacturing Year/Month/Date (YMD) in base 36, with Y being the last digit
of the year.
* Manufacture Sequence Number (SSSS).
* Optional Firmware Version/Revision (FFF).
The `eppidtool <https://pypi.org/project/eppidtool>`_ python utility can be used
to decode and display this information.
All information regarding the Dell ePPID was gathered using Dell support
documentation and `this website <https://telcontar.net/KBK/Dell/date_codes>`_.
WMI interface description
=========================
The WMI interface description can be decoded from the embedded binary MOF (bmof)
data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
::
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("WMI Function"), guid("{8A42EA14-4F2A-FD45-6422-0087F7A7E608}")]
class DDVWmiMethodFunction {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(1), Implemented, read, write, Description("Return Battery Design Capacity.")] void BatteryDesignCapacity([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(2), Implemented, read, write, Description("Return Battery Full Charge Capacity.")] void BatteryFullChargeCapacity([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(3), Implemented, read, write, Description("Return Battery Manufacture Name.")] void BatteryManufactureName([in] uint32 arg2, [out] string argr);
[WmiMethodId(4), Implemented, read, write, Description("Return Battery Manufacture Date.")] void BatteryManufactureDate([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(5), Implemented, read, write, Description("Return Battery Serial Number.")] void BatterySerialNumber([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(6), Implemented, read, write, Description("Return Battery Chemistry Value.")] void BatteryChemistryValue([in] uint32 arg2, [out] string argr);
[WmiMethodId(7), Implemented, read, write, Description("Return Battery Temperature.")] void BatteryTemperature([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(8), Implemented, read, write, Description("Return Battery Current.")] void BatteryCurrent([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(9), Implemented, read, write, Description("Return Battery Voltage.")] void BatteryVoltage([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(10), Implemented, read, write, Description("Return Battery Manufacture Access(MA code).")] void BatteryManufactureAceess([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(11), Implemented, read, write, Description("Return Battery Relative State-Of-Charge.")] void BatteryRelativeStateOfCharge([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(12), Implemented, read, write, Description("Return Battery Cycle Count")] void BatteryCycleCount([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(13), Implemented, read, write, Description("Return Battery ePPID")] void BatteryePPID([in] uint32 arg2, [out] string argr);
[WmiMethodId(14), Implemented, read, write, Description("Return Battery Raw Analytics Start")] void BatteryeRawAnalyticsStart([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(15), Implemented, read, write, Description("Return Battery Raw Analytics")] void BatteryeRawAnalytics([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
[WmiMethodId(16), Implemented, read, write, Description("Return Battery Design Voltage.")] void BatteryDesignVoltage([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(17), Implemented, read, write, Description("Return Battery Raw Analytics A Block")] void BatteryeRawAnalyticsABlock([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
[WmiMethodId(18), Implemented, read, write, Description("Return Version.")] void ReturnVersion([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(32), Implemented, read, write, Description("Return Fan Sensor Information")] void FanSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
[WmiMethodId(34), Implemented, read, write, Description("Return Thermal Sensor Information")] void ThermalSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
};
Each WMI method takes an ACPI buffer containing a 32-bit index as input argument,
with the first 8 bit being used to specify the battery when using battery-related
WMI methods. Other WMI methods may ignore this argument or interpret it
differently. The WMI method output format varies:
* if the function has only a single output, then an ACPI object
of the corresponding type is returned
* if the function has multiple outputs, when an ACPI package
containing the outputs in the same order is returned
The format of the output should be thoroughly checked, since many methods can
return malformed data in case of an error.
The data format of many battery-related methods seems to be based on the
`Smart Battery Data Specification`, so unknown battery-related methods are
likely to follow this standard in some way.
WMI method GetBatteryDesignCapacity()
-------------------------------------
Returns the design capacity of the battery in mAh as an u16.
WMI method BatteryFullCharge()
------------------------------
Returns the full charge capacity of the battery in mAh as an u16.
WMI method BatteryManufactureName()
-----------------------------------
Returns the manufacture name of the battery as an ASCII string.
WMI method BatteryManufactureDate()
-----------------------------------
Returns the manufacture date of the battery as an u16.
The date is encoded in the following manner:
- bits 0 to 4 contain the manufacture day.
- bits 5 to 8 contain the manufacture month.
- bits 9 to 15 contain the manufacture year biased by 1980.
WMI method BatterySerialNumber()
--------------------------------
Returns the serial number of the battery as an u16.
WMI method BatteryChemistryValue()
----------------------------------
Returns the chemistry of the battery as an ASCII string.
Known values are:
- "Li-I" for Li-Ion
WMI method BatteryTemperature()
-------------------------------
Returns the temperature of the battery in tenth degree kelvin as an u16.
WMI method BatteryCurrent()
---------------------------
Returns the current flow of the battery in mA as an s16.
Negative values indicate discharging.
WMI method BatteryVoltage()
---------------------------
Returns the voltage flow of the battery in mV as an u16.
WMI method BatteryManufactureAccess()
-------------------------------------
Returns the health status of the battery as a u16.
The health status encoded in the following manner:
- the third nibble contains the general failure mode
- the fourth nibble contains the specific failure code
Valid failure modes are:
- permanent failure (``0x9``)
- overheat failure (``0xa``)
- overcurrent failure (``0xb``)
All other failure modes are to be considered normal.
The following failure codes are valid for a permanent failure:
- fuse blown (``0x0``)
- cell imbalance (``0x1``)
- overvoltage (``0x2``)
- fet failure (``0x3``)
The last two bits of the failure code are to be ignored when the battery
signals a permanent failure.
The following failure codes a valid for a overheat failure:
- overheat at start of charging (``0x5``)
- overheat during charging (``0x7``)
- overheat during discharging (``0x8``)
The following failure codes are valid for a overcurrent failure:
- overcurrent during charging (``0x6``)
- overcurrent during discharging (``0xb``)
WMI method BatteryRelativeStateOfCharge()
-----------------------------------------
Returns the capacity of the battery in percent as an u16.
WMI method BatteryCycleCount()
------------------------------
Returns the cycle count of the battery as an u16.
WMI method BatteryePPID()
-------------------------
Returns the ePPID of the battery as an ASCII string.
WMI method BatteryeRawAnalyticsStart()
--------------------------------------
Performs an analysis of the battery and returns a status code:
- ``0x0``: Success
- ``0x1``: Interface not supported
- ``0xfffffffe``: Error/Timeout
.. note::
The meaning of this method is still largely unknown.
WMI method BatteryeRawAnalytics()
---------------------------------
Returns a buffer usually containing 12 blocks of analytics data.
Those blocks contain:
- a block number starting with 0 (u8)
- 31 bytes of unknown data
.. note::
The meaning of this method is still largely unknown.
WMI method BatteryDesignVoltage()
---------------------------------
Returns the design voltage of the battery in mV as an u16.
WMI method BatteryeRawAnalyticsABlock()
---------------------------------------
Returns a single block of analytics data, with the second byte
of the index being used for selecting the block number.
*Supported since WMI interface version 3!*
.. note::
The meaning of this method is still largely unknown.
WMI method ReturnVersion()
--------------------------
Returns the WMI interface version as an u32.
WMI method FanSensorInformation()
---------------------------------
Returns a buffer containing fan sensor entries, terminated
with a single ``0xff``.
Those entries contain:
- fan type (u8)
- fan speed in RPM (little endian u16)
WMI method ThermalSensorInformation()
-------------------------------------
Returns a buffer containing thermal sensor entries, terminated
with a single ``0xff``.
Those entries contain:
- thermal type (u8)
- current temperature (s8)
- min. temperature (s8)
- max. temperature (s8)
- unknown field (u8)
.. note::
TODO: Find out what the meaning of the last byte is.
ACPI battery matching algorithm
===============================
The algorithm used to match ACPI batteries to indices is based on information
which was found inside the logging messages of the OEM software.
Basically for each new ACPI battery, the serial numbers of the batteries behind
indices 1 till 3 are compared with the serial number of the ACPI battery.
Since the serial number of the ACPI battery can either be encoded as a normal
integer or as a hexadecimal value, both cases need to be checked. The first
index with a matching serial number is then selected.
A serial number of 0 indicates that the corresponding index is not associated
with an actual battery, or that the associated battery is not present.
Some machines like the Dell Inspiron 3505 only support a single battery and thus
ignore the battery index. Because of this the driver depends on the ACPI battery
hook mechanism to discover batteries.
Reverse-Engineering the DDV WMI interface
=========================================
1. Find a supported Dell notebook, usually made after ~2020.
2. Dump the ACPI tables and search for the WMI device (usually called "ADDV").
3. Decode the corresponding bmof data and look at the ASL code.
4. Try to deduce the meaning of a certain WMI method by comparing the control
flow with other ACPI methods (_BIX or _BIF for battery related methods
for example).
5. Use the built-in UEFI diagnostics to view sensor types/values for fan/thermal
related methods (sometimes overwriting static ACPI data fields can be used
to test different sensor type values, since on some machines this data is
not reinitialized upon a warm reset).
Alternatively:
1. Load the ``dell-wmi-ddv`` driver, use the ``force`` module param
if necessary.
2. Use the debugfs interface to access the raw fan/thermal sensor buffer data.
3. Compare the data with the built-in UEFI diagnostics.
In case the DDV WMI interface version available on your Dell notebook is not
supported or you are seeing unknown fan/thermal sensors, please submit a
bugreport on `bugzilla <https://bugzilla.kernel.org>`_ so they can be added
to the ``dell-wmi-ddv`` driver.
See Documentation/admin-guide/reporting-issues.rst for further information.
@@ -0,0 +1,15 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
=============================
Driver-specific Documentation
=============================
This section provides information about various devices supported by
the Linux kernel, their protocols and driver details.
.. toctree::
:maxdepth: 1
:numbered:
:glob:
*
@@ -0,0 +1,202 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
==========================================================
Lenovo WMI Interface Gamezone Driver (lenovo-wmi-gamezone)
==========================================================
Introduction
============
The Lenovo WMI gamezone interface is broken up into multiple GUIDs,
The primary "Gamezone" GUID provides advanced features such as fan
profiles and overclocking. It is paired with multiple event GUIDs
and data block GUIDs that provide context for the various methods.
Gamezone Data
-------------
WMI GUID ``887B54E3-DDDC-4B2C-8B88-68A26A8835D0``
The Gamezone Data WMI interface provides platform-profile and fan curve
settings for devices that fall under the "Gaming Series" of Lenovo devices.
It uses a notifier chain to inform other Lenovo WMI interface drivers of the
current platform profile when it changes. The currently set profile can be
determined by the user on the hardware by looking at the color of the power
or profile LED, depending on the model.
The following platform profiles are supported:
- low-power, blue LED
- balanced, white LED
- performance, red LED
- max-power, purple LED
- custom, purple LED
Extreme Mode
~~~~~~~~~~~~~~~~~~~~
Some newer Lenovo "Gaming Series" laptops have an "Extreme Mode" profile
enabled in their BIOS. When available, this mode will be represented by the
max-power platform profile.
For a subset of these devices the "Extreme Mode" profile is incomplete in
the BIOS and setting it will cause undefined behavior. A BIOS bug quirk table
is provided to ensure these devices cannot set "Extreme Mode" from the driver.
Custom Profile
~~~~~~~~~~~~~~
The custom profile represents a hardware mode on Lenovo devices that enables
user modifications to Package Power Tracking (PPT) and fan curve settings.
When an attribute exposed by the Other Mode WMI interface is to be modified,
the Gamezone driver must first be switched to the "custom" profile manually,
or the setting will have no effect. If another profile is set from the list
of supported profiles, the BIOS will override any user PPT settings when
switching to that profile.
Gamezone Thermal Mode Event
---------------------------
WMI GUID ``D320289E-8FEA-41E0-86F9-911D83151B5F``
The Gamezone Thermal Mode Event interface notifies the system when the platform
profile has changed, either through the hardware event (Fn+Q for laptops or
Legion + Y for Go Series), or through the Gamezone WMI interface. This event is
implemented in the Lenovo WMI Events driver (lenovo-wmi-events).
WMI interface description
=========================
The WMI interface description can be decoded from the embedded binary MOF (bmof)
data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
::
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("LENOVO_GAMEZONE_DATA class"), guid("{887B54E3-DDDC-4B2C-8B88-68A26A8835D0}")]
class LENOVO_GAMEZONE_DATA {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(4), Implemented, Description("Is SupportGpu OverClock")] void IsSupportGpuOC([out, Description("Is SupportGpu OverClock")] uint32 Data);
[WmiMethodId(11), Implemented, Description("Get AslCode Version")] void GetVersion ([out, Description("AslCode version")] UINT32 Data);
[WmiMethodId(12), Implemented, Description("Fan cooling capability")] void IsSupportFanCooling([out, Description("Fan cooling capability")] UINT32 Data);
[WmiMethodId(13), Implemented, Description("Set Fan cooling on/off")] void SetFanCooling ([in, Description("Set Fan cooling on/off")] UINT32 Data);
[WmiMethodId(14), Implemented, Description("cpu oc capability")] void IsSupportCpuOC ([out, Description("cpu oc capability")] UINT32 Data);
[WmiMethodId(15), Implemented, Description("bios has overclock capability")] void IsBIOSSupportOC ([out, Description("bios has overclock capability")] UINT32 Data);
[WmiMethodId(16), Implemented, Description("enable or disable overclock in bios")] void SetBIOSOC ([in, Description("enable or disable overclock in bios")] UINT32 Data);
[WmiMethodId(18), Implemented, Description("Get CPU temperature")] void GetCPUTemp ([out, Description("Get CPU temperature")] UINT32 Data);
[WmiMethodId(19), Implemented, Description("Get GPU temperature")] void GetGPUTemp ([out, Description("Get GPU temperature")] UINT32 Data);
[WmiMethodId(20), Implemented, Description("Get Fan cooling on/off status")] void GetFanCoolingStatus ([out, Description("Get Fan cooling on/off status")] UINT32 Data);
[WmiMethodId(21), Implemented, Description("EC support disable windows key capability")] void IsSupportDisableWinKey ([out, Description("EC support disable windows key capability")] UINT32 Data);
[WmiMethodId(22), Implemented, Description("Set windows key disable/enable")] void SetWinKeyStatus ([in, Description("Set windows key disable/enable")] UINT32 Data);
[WmiMethodId(23), Implemented, Description("Get windows key disable/enable status")] void GetWinKeyStatus ([out, Description("Get windows key disable/enable status")] UINT32 Data);
[WmiMethodId(24), Implemented, Description("EC support disable touchpad capability")] void IsSupportDisableTP ([out, Description("EC support disable touchpad capability")] UINT32 Data);
[WmiMethodId(25), Implemented, Description("Set touchpad disable/enable")] void SetTPStatus ([in, Description("Set touchpad disable/enable")] UINT32 Data);
[WmiMethodId(26), Implemented, Description("Get touchpad disable/enable status")] void GetTPStatus ([out, Description("Get touchpad disable/enable status")] UINT32 Data);
[WmiMethodId(30), Implemented, Description("Get Keyboard feature list")] void GetKeyboardfeaturelist ([out, Description("Get Keyboard feature list")] UINT32 Data);
[WmiMethodId(31), Implemented, Description("Get Memory OC Information")] void GetMemoryOCInfo ([out, Description("Get Memory OC Information")] UINT32 Data);
[WmiMethodId(32), Implemented, Description("Water Cooling feature capability")] void IsSupportWaterCooling ([out, Description("Water Cooling feature capability")] UINT32 Data);
[WmiMethodId(33), Implemented, Description("Set Water Cooling status")] void SetWaterCoolingStatus ([in, Description("Set Water Cooling status")] UINT32 Data);
[WmiMethodId(34), Implemented, Description("Get Water Cooling status")] void GetWaterCoolingStatus ([out, Description("Get Water Cooling status")] UINT32 Data);
[WmiMethodId(35), Implemented, Description("Lighting feature capability")] void IsSupportLightingFeature ([out, Description("Lighting feature capability")] UINT32 Data);
[WmiMethodId(36), Implemented, Description("Set keyboard light off or on to max")] void SetKeyboardLight ([in, Description("keyboard light off or on switch")] UINT32 Data);
[WmiMethodId(37), Implemented, Description("Get keyboard light on/off status")] void GetKeyboardLight ([out, Description("Get keyboard light on/off status")] UINT32 Data);
[WmiMethodId(38), Implemented, Description("Get Macrokey scan code")] void GetMacrokeyScancode ([in, Description("Macrokey index")] UINT32 idx, [out, Description("Scan code")] UINT32 scancode);
[WmiMethodId(39), Implemented, Description("Get Macrokey count")] void GetMacrokeyCount ([out, Description("Macrokey count")] UINT32 Data);
[WmiMethodId(40), Implemented, Description("Support G-Sync feature")] void IsSupportGSync ([out, Description("Support G-Sync feature")] UINT32 Data);
[WmiMethodId(41), Implemented, Description("Get G-Sync Status")] void GetGSyncStatus ([out, Description("Get G-Sync Status")] UINT32 Data);
[WmiMethodId(42), Implemented, Description("Set G-Sync Status")] void SetGSyncStatus ([in, Description("Set G-Sync Status")] UINT32 Data);
[WmiMethodId(43), Implemented, Description("Support Smart Fan feature")] void IsSupportSmartFan ([out, Description("Support Smart Fan feature")] UINT32 Data);
[WmiMethodId(44), Implemented, Description("Set Smart Fan Mode")] void SetSmartFanMode ([in, Description("Set Smart Fan Mode")] UINT32 Data);
[WmiMethodId(45), Implemented, Description("Get Smart Fan Mode")] void GetSmartFanMode ([out, Description("Get Smart Fan Mode")] UINT32 Data);
[WmiMethodId(46), Implemented, Description("Get Smart Fan Setting Mode")] void GetSmartFanSetting ([out, Description("Get Smart Setting Mode")] UINT32 Data);
[WmiMethodId(47), Implemented, Description("Get Power Charge Mode")] void GetPowerChargeMode ([out, Description("Get Power Charge Mode")] UINT32 Data);
[WmiMethodId(48), Implemented, Description("Get Gaming Product Info")] void GetProductInfo ([out, Description("Get Gaming Product Info")] UINT32 Data);
[WmiMethodId(49), Implemented, Description("Over Drive feature capability")] void IsSupportOD ([out, Description("Over Drive feature capability")] UINT32 Data);
[WmiMethodId(50), Implemented, Description("Get Over Drive status")] void GetODStatus ([out, Description("Get Over Drive status")] UINT32 Data);
[WmiMethodId(51), Implemented, Description("Set Over Drive status")] void SetODStatus ([in, Description("Set Over Drive status")] UINT32 Data);
[WmiMethodId(52), Implemented, Description("Set Light Control Owner")] void SetLightControlOwner ([in, Description("Set Light Control Owner")] UINT32 Data);
[WmiMethodId(53), Implemented, Description("Set DDS Control Owner")] void SetDDSControlOwner ([in, Description("Set DDS Control Owner")] UINT32 Data);
[WmiMethodId(54), Implemented, Description("Get the flag of restore OC value")] void IsRestoreOCValue ([in, Description("Clean this flag")] UINT32 idx, [out, Description("Restore oc value flag")] UINT32 Data);
[WmiMethodId(55), Implemented, Description("Get Real Thremal Mode")] void GetThermalMode ([out, Description("Real Thremal Mode")] UINT32 Data);
[WmiMethodId(56), Implemented, Description("Get the OC switch status in BIOS")] void GetBIOSOCMode ([out, Description("OC Mode")] UINT32 Data);
[WmiMethodId(59), Implemented, Description("Get hardware info support version")] void GetHardwareInfoSupportVersion ([out, Description("version")] UINT32 Data);
[WmiMethodId(60), Implemented, Description("Get Cpu core 0 max frequency")] void GetCpuFrequency ([out, Description("frequency")] UINT32 Data);
[WmiMethodId(62), Implemented, Description("Check the Adapter type fit for OC")] void IsACFitForOC ([out, Description("AC check result")] UINT32 Data);
[WmiMethodId(63), Implemented, Description("Is support IGPU mode")] void IsSupportIGPUMode ([out, Description("IGPU modes")] UINT32 Data);
[WmiMethodId(64), Implemented, Description("Get IGPU Mode Status")] void GetIGPUModeStatus([out, Description("IGPU Mode Status")] UINT32 Data);
[WmiMethodId(65), Implemented, Description("Set IGPU Mode")] void SetIGPUModeStatus([in, Description("IGPU Mode")] UINT32 mode, [out, Description("return code")] UINT32 Data);
[WmiMethodId(66), Implemented, Description("Notify DGPU Status")] void NotifyDGPUStatus([in, Description("DGPU status")] UINT32 status, [out, Description("return code")] UINT32 Data);
[WmiMethodId(67), Implemented, Description("Is changed Y log")] void IsChangedYLog([out, Description("Is changed Y Log")] UINT32 Data);
[WmiMethodId(68), Implemented, Description("Get DGPU Hardwawre ID")] void GetDGPUHWId([out, Description("Get DGPU Hardware ID")] string Data);
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Definition of CPU OC parameter list"), guid("{B7F3CA0A-ACDC-42D2-9217-77C6C628FBD2}")]
class LENOVO_GAMEZONE_CPU_OC_DATA {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("OC tune id.")] uint32 Tuneid;
[WmiDataId(2), read, Description("Default value.")] uint32 DefaultValue;
[WmiDataId(3), read, Description("OC Value.")] uint32 OCValue;
[WmiDataId(4), read, Description("Min Value.")] uint32 MinValue;
[WmiDataId(5), read, Description("Max Value.")] uint32 MaxValue;
[WmiDataId(6), read, Description("Scale Value.")] uint32 ScaleValue;
[WmiDataId(7), read, Description("OC Order id.")] uint32 OCOrderid;
[WmiDataId(8), read, Description("NON-OC Order id.")] uint32 NOCOrderid;
[WmiDataId(9), read, Description("Delay time in ms.")] uint32 Interval;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Definition of GPU OC parameter list"), guid("{887B54E2-DDDC-4B2C-8B88-68A26A8835D0}")]
class LENOVO_GAMEZONE_GPU_OC_DATA {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("P-State ID.")] uint32 PStateID;
[WmiDataId(2), read, Description("CLOCK ID.")] uint32 ClockID;
[WmiDataId(3), read, Description("Default value.")] uint32 defaultvalue;
[WmiDataId(4), read, Description("OC Offset freqency.")] uint32 OCOffsetFreq;
[WmiDataId(5), read, Description("OC Min offset value.")] uint32 OCMinOffset;
[WmiDataId(6), read, Description("OC Max offset value.")] uint32 OCMaxOffset;
[WmiDataId(7), read, Description("OC Offset Scale.")] uint32 OCOffsetScale;
[WmiDataId(8), read, Description("OC Order id.")] uint32 OCOrderid;
[WmiDataId(9), read, Description("NON-OC Order id.")] uint32 NOCOrderid;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Fancooling finish event"), guid("{BC72A435-E8C1-4275-B3E2-D8B8074ABA59}")]
class LENOVO_GAMEZONE_FAN_COOLING_EVENT: WMIEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("Fancooling clean finish event")] uint32 EventId;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Smart Fan mode change event"), guid("{D320289E-8FEA-41E0-86F9-611D83151B5F}")]
class LENOVO_GAMEZONE_SMART_FAN_MODE_EVENT: WMIEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("Smart Fan Mode change event")] uint32 mode;
[WmiDataId(2), read, Description("version of FN+Q")] uint32 version;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Smart Fan setting mode change event"), guid("{D320289E-8FEA-41E1-86F9-611D83151B5F}")]
class LENOVO_GAMEZONE_SMART_FAN_SETTING_EVENT: WMIEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("Smart Fan Setting mode change event")] uint32 mode;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("POWER CHARGE MODE Change EVENT"), guid("{D320289E-8FEA-41E0-86F9-711D83151B5F}")]
class LENOVO_GAMEZONE_POWER_CHARGE_MODE_EVENT: WMIEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("POWER CHARGE MODE Change EVENT")] uint32 mode;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Thermal Mode Real Mode change event"), guid("{D320289E-8FEA-41E0-86F9-911D83151B5F}")]
class LENOVO_GAMEZONE_THERMAL_MODE_EVENT: WMIEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("Thermal Mode Real Mode")] uint32 mode;
};
@@ -0,0 +1,167 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
===========================================================
Lenovo WMI Interface Other Mode Driver (lenovo-wmi-other)
===========================================================
Introduction
============
Lenovo WMI Other Mode interface is broken up into multiple GUIDs,
The primary Other Mode interface provides advanced power tuning features
such as Package Power Tracking (PPT). It is paired with multiple data block
GUIDs that provide context for the various methods.
Other Mode
----------
WMI GUID ``DC2A8805-3A8C-41BA-A6F7-092E0089CD3B``
The Other Mode WMI interface uses the firmware_attributes class to expose
various WMI attributes provided by the interface in the sysfs. This enables
CPU and GPU power limit tuning as well as various other attributes for
devices that fall under the "Gaming Series" of Lenovo devices. Each
attribute exposed by the Other Mode interface has corresponding
capability data blocks which allow the driver to probe details about the
attribute. Each attribute has multiple pages, one for each of the platform
profiles managed by the Gamezone interface. Attributes are exposed in sysfs
under the following path:
::
/sys/class/firmware-attributes/lenovo-wmi-other/attributes/<attribute>/
Additionally, this driver also exports attributes to HWMON.
LENOVO_CAPABILITY_DATA_00
-------------------------
WMI GUID ``362A3AFE-3D96-4665-8530-96DAD5BB300E``
The LENOVO_CAPABILITY_DATA_00 interface provides various information that
does not rely on the gamezone thermal mode.
The following HWMON attributes are implemented:
- fanX_div: internal RPM divisor
- fanX_input: current RPM
- fanX_target: target RPM (tunable, 0=auto)
Due to the internal RPM divisor, the current/target RPMs are rounded down to
its nearest multiple. The divisor itself is not necessary to be a power of two.
LENOVO_CAPABILITY_DATA_01
-------------------------
WMI GUID ``7A8F5407-CB67-4D6E-B547-39B3BE018154``
The LENOVO_CAPABILITY_DATA_01 interface provides various information that
relies on the gamezone thermal mode, including power limits of integrated
CPU and GPU components.
Each attribute has the following properties:
- current_value
- default_value
- display_name
- max_value
- min_value
- scalar_increment
- type
The following firmware-attributes are implemented:
- cpu_temp: CPU Thermal Load Limit
- dgpu_boost_clk: Dedicated GPU Boost Clock
- dgpu_didvid: Dedicated GPU Device Identifier and Vendor Identifier
- dgpu_enable: Dedicated GPU Enabled Status
- gpu_mode: GPU Mode by Power Limit
- gpu_nv_ac_offset: Nvidia GPU AC Total Processing Power Baseline Offset
- gpu_nv_bpl: Nvidia GPU Base Power Limit
- gpu_nv_cpu_boost: Nvidia GPU to CPU Dynamic Boost Limit
- gpu_nv_ctgp: Nvidia GPU Configurable Total Graphics Power
- gpu_nv_ppab: Nvidia GPU Power Performance Aware Boost Limit
- gpu_temp: GPU Thermal Load Limit
- ppt_cpu_cl: CPU Cross Loading Power Limit
- ppt_pl1_apu_spl: Platform Profile Tracking APU Sustained Power Limit
- ppt_pl1_spl: Platform Profile Tracking Sustained Power Limit
- ppt_pl1_spl_cl: Platform Profile Tracking Cross Loading Sustained Power Limit
- ppt_pl1_tau: Exceed Duration for Platform Profile Tracking Sustained Power Limit
- ppt_pl2_sppt: Platform Profile Tracking Slow Package Power Tracking
- ppt_pl2_sppt_cl: Platform Profile Tracking Cross Loading Slow Package Tracking
- ppt_pl3_fppt: Platform Profile Tracking Fast Package Power Tracking
- ppt_pl3_fppt_cl: Platform Profile Tracking Cross Loading Fast Package Power Tracking
- ppt_pl4_ipl: Platform Profile Tracking Instantaneous Power Limit
- ppt_pl4_ipl_cl: Platform Profile Tracking Cross Loading Instantaneous Power Limit
LENOVO_FAN_TEST_DATA
-------------------------
WMI GUID ``B642801B-3D21-45DE-90AE-6E86F164FB21``
The LENOVO_FAN_TEST_DATA interface provides reference data for self-test of
cooling fans.
The following HWMON attributes are implemented:
- fanX_max: maximum RPM
- fanX_min: minimum RPM
WMI interface description
=========================
The WMI interface description can be decoded from the embedded binary MOF (bmof)
data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
::
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("LENOVO_OTHER_METHOD class"), guid("{dc2a8805-3a8c-41ba-a6f7-092e0089cd3b}")]
class LENOVO_OTHER_METHOD {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(17), Implemented, Description("Get Feature Value ")] void GetFeatureValue([in] uint32 IDs, [out] uint32 value);
[WmiMethodId(18), Implemented, Description("Set Feature Value ")] void SetFeatureValue([in] uint32 IDs, [in] uint32 value);
[WmiMethodId(19), Implemented, Description("Get Data By Command ")] void GetDataByCommand([in] uint32 IDs, [in] uint32 Command, [out] uint32 DataSize, [out, WmiSizeIs("DataSize")] uint32 Data[]);
[WmiMethodId(99), Implemented, Description("Get Data By Package for TAC")] void GetDataByPackage([in, Max(40)] uint8 Input[], [out] uint32 DataSize, [out, WmiSizeIs("DataSize")] uint8 Data[]);
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("LENOVO CAPABILITY DATA 00"), guid("{362a3afe-3d96-4665-8530-96dad5bb300e}")]
class LENOVO_CAPABILITY_DATA_00 {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description(" IDs.")] uint32 IDs;
[WmiDataId(2), read, Description("Capability.")] uint32 Capability;
[WmiDataId(3), read, Description("Capability Default Value.")] uint32 DefaultValue;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("LENOVO CAPABILITY DATA 01"), guid("{7a8f5407-cb67-4d6e-b547-39b3be018154}")]
class LENOVO_CAPABILITY_DATA_01 {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description(" IDs.")] uint32 IDs;
[WmiDataId(2), read, Description("Capability.")] uint32 Capability;
[WmiDataId(3), read, Description("Default Value.")] uint32 DefaultValue;
[WmiDataId(4), read, Description("Step.")] uint32 Step;
[WmiDataId(5), read, Description("Minimum Value.")] uint32 MinValue;
[WmiDataId(6), read, Description("Maximum Value.")] uint32 MaxValue;
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("LENOVO CAPABILITY DATA 02"), guid("{bbf1f790-6c2f-422b-bc8c-4e7369c7f6ab}")]
class LENOVO_CAPABILITY_DATA_02 {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description(" IDs.")] uint32 IDs;
[WmiDataId(2), read, Description("Capability.")] uint32 Capability;
[WmiDataId(3), read, Description("Data Size.")] uint32 DataSize;
[WmiDataId(4), read, Description("Default Value"), WmiSizeIs("DataSize")] uint8 DefaultValue[];
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Definition of Fan Test Data"), guid("{B642801B-3D21-45DE-90AE-6E86F164FB21}")]
class LENOVO_FAN_TEST_DATA {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, Description("Mode.")] uint32 NumOfFans;
[WmiDataId(2), read, Description("Fan ID."), WmiSizeIs("NumOfFans")] uint32 FanId[];
[WmiDataId(3), read, Description("Maximum Fan Speed."), WmiSizeIs("NumOfFans")] uint32 FanMaxSpeed[];
[WmiDataId(4), read, Description("Minumum Fan Speed."), WmiSizeIs("NumOfFans")] uint32 FanMinSpeed[];
};
@@ -0,0 +1,198 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
===================================================
MSI WMI Platform Features driver (msi-wmi-platform)
===================================================
Introduction
============
Many MSI notebooks support various features like reading fan sensors. This features are controlled
by the embedded controller, with the ACPI firmware exposing a standard ACPI WMI interface on top
of the embedded controller interface.
WMI interface description
=========================
The WMI interface description can be decoded from the embedded binary MOF (bmof)
data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
::
[WMI, Locale("MS\0x409"),
Description("This class contains the definition of the package used in other classes"),
guid("{ABBC0F60-8EA1-11d1-00A0-C90629100000}")]
class Package {
[WmiDataId(1), read, write, Description("16 bytes of data")] uint8 Bytes[16];
};
[WMI, Locale("MS\0x409"),
Description("This class contains the definition of the package used in other classes"),
guid("{ABBC0F63-8EA1-11d1-00A0-C90629100000}")]
class Package_32 {
[WmiDataId(1), read, write, Description("32 bytes of data")] uint8 Bytes[32];
};
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\0x409"),
Description("Class used to operate methods on a package"),
guid("{ABBC0F6E-8EA1-11d1-00A0-C90629100000}")]
class MSI_ACPI {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(1), Implemented, read, write, Description("Return the contents of a package")]
void GetPackage([out, id(0)] Package Data);
[WmiMethodId(2), Implemented, read, write, Description("Set the contents of a package")]
void SetPackage([in, id(0)] Package Data);
[WmiMethodId(3), Implemented, read, write, Description("Return the contents of a package")]
void Get_EC([out, id(0)] Package_32 Data);
[WmiMethodId(4), Implemented, read, write, Description("Set the contents of a package")]
void Set_EC([in, id(0)] Package_32 Data);
[WmiMethodId(5), Implemented, read, write, Description("Return the contents of a package")]
void Get_BIOS([in, out, id(0)] Package_32 Data);
[WmiMethodId(6), Implemented, read, write, Description("Set the contents of a package")]
void Set_BIOS([in, out, id(0)] Package_32 Data);
[WmiMethodId(7), Implemented, read, write, Description("Return the contents of a package")]
void Get_SMBUS([in, out, id(0)] Package_32 Data);
[WmiMethodId(8), Implemented, read, write, Description("Set the contents of a package")]
void Set_SMBUS([in, out, id(0)] Package_32 Data);
[WmiMethodId(9), Implemented, read, write, Description("Return the contents of a package")]
void Get_MasterBattery([in, out, id(0)] Package_32 Data);
[WmiMethodId(10), Implemented, read, write, Description("Set the contents of a package")]
void Set_MasterBattery([in, out, id(0)] Package_32 Data);
[WmiMethodId(11), Implemented, read, write, Description("Return the contents of a package")]
void Get_SlaveBattery([in, out, id(0)] Package_32 Data);
[WmiMethodId(12), Implemented, read, write, Description("Set the contents of a package")]
void Set_SlaveBattery([in, out, id(0)] Package_32 Data);
[WmiMethodId(13), Implemented, read, write, Description("Return the contents of a package")]
void Get_Temperature([in, out, id(0)] Package_32 Data);
[WmiMethodId(14), Implemented, read, write, Description("Set the contents of a package")]
void Set_Temperature([in, out, id(0)] Package_32 Data);
[WmiMethodId(15), Implemented, read, write, Description("Return the contents of a package")]
void Get_Thermal([in, out, id(0)] Package_32 Data);
[WmiMethodId(16), Implemented, read, write, Description("Set the contents of a package")]
void Set_Thermal([in, out, id(0)] Package_32 Data);
[WmiMethodId(17), Implemented, read, write, Description("Return the contents of a package")]
void Get_Fan([in, out, id(0)] Package_32 Data);
[WmiMethodId(18), Implemented, read, write, Description("Set the contents of a package")]
void Set_Fan([in, out, id(0)] Package_32 Data);
[WmiMethodId(19), Implemented, read, write, Description("Return the contents of a package")]
void Get_Device([in, out, id(0)] Package_32 Data);
[WmiMethodId(20), Implemented, read, write, Description("Set the contents of a package")]
void Set_Device([in, out, id(0)] Package_32 Data);
[WmiMethodId(21), Implemented, read, write, Description("Return the contents of a package")]
void Get_Power([in, out, id(0)] Package_32 Data);
[WmiMethodId(22), Implemented, read, write, Description("Set the contents of a package")]
void Set_Power([in, out, id(0)] Package_32 Data);
[WmiMethodId(23), Implemented, read, write, Description("Return the contents of a package")]
void Get_Debug([in, out, id(0)] Package_32 Data);
[WmiMethodId(24), Implemented, read, write, Description("Set the contents of a package")]
void Set_Debug([in, out, id(0)] Package_32 Data);
[WmiMethodId(25), Implemented, read, write, Description("Return the contents of a package")]
void Get_AP([in, out, id(0)] Package_32 Data);
[WmiMethodId(26), Implemented, read, write, Description("Set the contents of a package")]
void Set_AP([in, out, id(0)] Package_32 Data);
[WmiMethodId(27), Implemented, read, write, Description("Return the contents of a package")]
void Get_Data([in, out, id(0)] Package_32 Data);
[WmiMethodId(28), Implemented, read, write, Description("Set the contents of a package")]
void Set_Data([in, out, id(0)] Package_32 Data);
[WmiMethodId(29), Implemented, read, write, Description("Return the contents of a package")]
void Get_WMI([out, id(0)] Package_32 Data);
};
Due to a peculiarity in how Windows handles the ``CreateByteField()`` ACPI operator (errors only
happen when a invalid byte field is ultimately accessed), all methods require a 32 byte input
buffer, even if the Binary MOF says otherwise.
The input buffer contains a single byte to select the subfeature to be accessed and 31 bytes of
input data, the meaning of which depends on the subfeature being accessed.
The output buffer contains a single byte which signals success or failure (``0x00`` on failure)
and 31 bytes of output data, the meaning if which depends on the subfeature being accessed.
.. note::
The ACPI control method responsible for handling the WMI method calls is not thread-safe.
This is a firmware bug that needs to be handled inside the driver itself.
WMI method Get_EC()
-------------------
Returns embedded controller information, the selected subfeature does not matter. The output
data contains a flag byte and a 28 byte controller firmware version string.
The first 4 bits of the flag byte contain the minor version of the embedded controller interface,
with the next 2 bits containing the major version of the embedded controller interface.
The 7th bit signals if the embedded controller page changed (exact meaning is unknown), and the
last bit signals if the platform is a Tigerlake platform.
The MSI software seems to only use this interface when the last bit is set.
WMI method Get_Fan()
--------------------
Fan speed sensors can be accessed by selecting subfeature ``0x00``. The output data contains
up to four 16-bit fan speed readings in big-endian format. Most machines do not support all
four fan speed sensors, so the remaining reading are hardcoded to ``0x0000``.
The fan RPM readings can be calculated with the following formula:
RPM = 480000 / <fan speed reading>
If the fan speed reading is zero, then the fan RPM is zero too.
WMI method Get_WMI()
--------------------
Returns the version of the ACPI WMI interface, the selected subfeature does not matter.
The output data contains two bytes, the first one contains the major version and the last one
contains the minor revision of the ACPI WMI interface.
The MSI software seems to only use this interface when the major version is greater than two.
Reverse-Engineering the MSI WMI Platform interface
==================================================
.. warning:: Randomly poking the embedded controller interface can potentially cause damage
to the machine and other unwanted side effects, please be careful.
The underlying embedded controller interface is used by the ``msi-ec`` driver, and it seems
that many methods just copy a part of the embedded controller memory into the output buffer.
This means that the remaining WMI methods can be reverse-engineered by looking which part of
the embedded controller memory is accessed by the ACPI AML code. The driver also supports a
debugfs interface for directly executing WMI methods. Additionally, any safety checks regarding
unsupported hardware can be disabled by loading the module with ``force=true``.
More information about the MSI embedded controller interface can be found at the
`msi-ec project <https://github.com/BeardOverflow/msi-ec>`_.
Special thanks go to github user `glpnk` for showing how to decode the fan speed readings.
@@ -0,0 +1,198 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
========================================
Uniwill Notebook driver (uniwill-laptop)
========================================
Introduction
============
Many notebooks manufactured by Uniwill (either directly or as ODM) provide a EC interface
for controlling various platform settings like sensors and fan control. This interface is
used by the ``uniwill-laptop`` driver to map those features onto standard kernel interfaces.
EC WMI interface description
============================
The EC WMI interface description can be decoded from the embedded binary MOF (bmof)
data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
::
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"),
Description("Class used to operate methods on a ULong"),
guid("{ABBC0F6F-8EA1-11d1-00A0-C90629100000}")]
class AcpiTest_MULong {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(1), Implemented, read, write, Description("Return the contents of a ULong")]
void GetULong([out, Description("Ulong Data")] uint32 Data);
[WmiMethodId(2), Implemented, read, write, Description("Set the contents of a ULong")]
void SetULong([in, Description("Ulong Data")] uint32 Data);
[WmiMethodId(3), Implemented, read, write,
Description("Generate an event containing ULong data")]
void FireULong([in, Description("WMI requires a parameter")] uint32 Hack);
[WmiMethodId(4), Implemented, read, write, Description("Get and Set the contents of a ULong")]
void GetSetULong([in, Description("Ulong Data")] uint64 Data,
[out, Description("Ulong Data")] uint32 Return);
[WmiMethodId(5), Implemented, read, write,
Description("Get and Set the contents of a ULong for Dollby button")]
void GetButton([in, Description("Ulong Data")] uint64 Data,
[out, Description("Ulong Data")] uint32 Return);
};
Most of the WMI-related code was copied from the Windows driver samples, which unfortunately means
that the WMI-GUID is not unique. This makes the WMI-GUID unusable for autoloading.
WMI method GetULong()
---------------------
This WMI method was copied from the Windows driver samples and has no function.
WMI method SetULong()
---------------------
This WMI method was copied from the Windows driver samples and has no function.
WMI method FireULong()
----------------------
This WMI method allows to inject a WMI event with a 32-bit payload. Its primary purpose seems
to be debugging.
WMI method GetSetULong()
------------------------
This WMI method is used to communicate with the EC. The ``Data`` argument holds the following
information (starting with the least significant byte):
1. 16-bit address
2. 16-bit data (set to ``0x0000`` when reading)
3. 16-bit operation (``0x0100`` for reading and ``0x0000`` for writing)
4. 16-bit reserved (set to ``0x0000``)
The first 8 bits of the ``Return`` value contain the data returned by the EC when reading.
The special value ``0xFEFEFEFE`` is used to indicate a communication failure with the EC.
WMI method GetButton()
----------------------
This WMI method is not implemented on all machines and has an unknown purpose.
Reverse-Engineering the EC WMI interface
========================================
.. warning:: Randomly poking the EC can potentially cause damage to the machine and other unwanted
side effects, please be careful.
The EC behind the ``GetSetULong`` method is used by the OEM software supplied by the manufacturer.
Reverse-engineering of this software is difficult since it uses an obfuscator, however some parts
are not obfuscated. In this case `dnSpy <https://github.com/dnSpy/dnSpy>`_ could also be helpful.
The EC can be accessed under Windows using powershell (requires admin privileges):
::
> $obj = Get-CimInstance -Namespace root/wmi -ClassName AcpiTest_MULong | Select-Object -First 1
> Invoke-CimMethod -InputObject $obj -MethodName GetSetULong -Arguments @{Data = <input>}
WMI event interface description
===============================
The WMI interface description can also be decoded from the embedded binary MOF (bmof)
data:
::
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"),
Description("Class containing event generated ULong data"),
guid("{ABBC0F72-8EA1-11d1-00A0-C90629100000}")]
class AcpiTest_EventULong : WmiEvent {
[key, read] string InstanceName;
[read] boolean Active;
[WmiDataId(1), read, write, Description("ULong Data")] uint32 ULong;
};
Most of the WMI-related code was again copied from the Windows driver samples, causing this WMI
interface to suffer from the same restrictions as the EC WMI interface described above.
WMI event data
--------------
The WMI event data contains a single 32-bit value which is used to indicate various platform events.
Reverse-Engineering the Uniwill WMI event interface
===================================================
The driver logs debug messages when receiving a WMI event. Thus enabling debug messages will be
useful for finding unknown event codes.
EC ACPI interface description
=============================
The ``INOU0000`` ACPI device is a virtual device used to access various hardware registers
available on notebooks manufactured by Uniwill. Reading and writing those registers happens
by calling ACPI control methods. The ``uniwill-laptop`` driver uses this device to communicate
with the EC because the ACPI control methods are faster than the WMI methods described above.
ACPI control methods used for reading registers take a single ACPI integer containing the address
of the register to read and return a ACPI integer containing the data inside said register. ACPI
control methods used for writing registers however take two ACPI integers, with the additional
ACPI integer containing the data to be written into the register. Such ACPI control methods return
nothing.
System memory
-------------
System memory can be accessed with a granularity of either a single byte (``MMRB`` for reading and
``MMWB`` for writing) or four bytes (``MMRD`` for reading and ``MMWD`` for writing). Those ACPI
control methods are unused because they provide no benefit when compared to the native memory
access functions provided by the kernel.
EC RAM
------
The internal RAM of the EC can be accessed with a granularity of a single byte using the ``ECRR``
(read) and ``ECRW`` (write) ACPI control methods, with the maximum register address being ``0xFFF``.
The OEM software waits 6 ms after calling one of those ACPI control methods, likely to avoid
overwhelming the EC when being connected over LPC.
PCI config space
----------------
The PCI config space can be accessed with a granularity of four bytes using the ``PCRD`` (read) and
``PCWD`` (write) ACPI control methods. The exact address format is unknown, and poking random PCI
devices might confuse the PCI subsystem. Because of this those ACPI control methods are not used.
IO ports
--------
IO ports can be accessed with a granularity of four bytes using the ``IORD`` (read) and ``IOWD``
(write) ACPI control methods. Those ACPI control methods are unused because they provide no benefit
when compared to the native IO port access functions provided by the kernel.
CMOS RAM
--------
The CMOS RAM can be accessed with a granularity of a single byte using the ``RCMS`` (read) and
``WCMS`` ACPI control methods. Using those ACPI methods might interfere with the native CMOS RAM
access functions provided by the kernel due to the usage of indexed IO, so they are unused.
Indexed IO
----------
Indexed IO with IO ports with a granularity of a single byte can be performed using the ``RIOP``
(read) and ``WIOP`` (write) ACPI control methods. Those ACPI methods are unused because they
provide no benefit when compared to the native IO port access functions provided by the kernel.
Special thanks go to github user `pobrn` which developed the
`qc71_laptop <https://github.com/pobrn/qc71_laptop>`_ driver on which this driver is partly based.
The same is true for Tuxedo Computers, which developed the
`tuxedo-drivers <https://gitlab.com/tuxedocomputers/development/packages/tuxedo-drivers>`_ package
which also served as a foundation for this driver.
@@ -0,0 +1,25 @@
.. SPDX-License-Identifier: GPL-2.0-only
==============================
WMI embedded Binary MOF driver
==============================
Introduction
============
Many machines embed WMI Binary MOF (Managed Object Format) metadata used to
describe the details of their ACPI WMI interfaces. The data can be decoded
with tools like `bmfdec <https://github.com/pali/bmfdec>`_ to obtain a
human readable WMI interface description, which is useful for developing
new WMI drivers.
The Binary MOF data can be retrieved from the ``bmof`` sysfs attribute of the
associated WMI device. Please note that multiple WMI devices containing Binary
MOF data can exist on a given system.
WMI interface
=============
The Binary MOF WMI device is identified by the WMI GUID ``05901221-D566-11D1-B2F0-00A0C9062910``.
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.