HardwareEnableWithDSDT

Differences between revisions 6 and 7
Revision 6 as of 2010-02-04 20:09:02
Size: 5862
Editor: unassigned
Comment:
Revision 7 as of 2010-02-04 20:45:09
Size: 6942
Editor: unassigned
Comment:
Deletions are marked like this. Additions are marked like this.
Line 39: Line 39:
user@here:~$ sudo chown ikepanhc:ikepanhc /home/ikepanhc/DSDT.bin user@here:~$ sudo chown user:user /home/user/DSDT.bin
Line 68: Line 68:
    |-- ATK0101:00     |-- HKEY1122:00
Line 75: Line 75:
    | | |-- LEN0013:00     | | |-- ONE0013:00
Line 78: Line 78:
    | | `-- LEN0014:00     | | `-- ONE0014:00
Line 111: Line 111:
In the above example, we will look at ATK0101, LEN0013 and LEN0014 to find out if there is anything we can enable. In the above example, we will look at HKEY1122, ONE0013 and ONE0014 to find out if there is anything we can enable.
Line 132: Line 132:
You can monitor the EC GPE by add a debug printk. You can monitor the EC GPE by adding a debug printk.
Line 147: Line 147:
We assume when we press mute key, the query bit is 0x1A. When this event happen, EC driver will execute its method _Q1A. Then we can seek _Q1A method in the DSDT/SSDT. The scope of this method shall be EC.
{{{
Scope (_SB.PCI0.SBRG.EC0)
{
    ......
    Method (_Q1A, 0, NotSerialized)
    {
        If (HKON)
        {
            Notify (HKDV, 0x09)
        }
    }
    ......
}
}}}
It tells us that when HKON is true, there will be a notify on HKDV and its event number is 0x09. So, we shall know how to let HKON become true by searching HKON in DSDT/SSDT.
{{{
Scope (_SB)
{
    Name (HKON, Zero)
}
}}}
It tells us HKON is a variable at _SB and its default value is zero.
{{{
Scope (_SB)
{
    Device (HKDV)
    {
        Name (_HID, "HKEY1122")
        Method (INIT, 1, NotSerialized)
        {
            Store (One, HKON)
            Return (Zero)
        }
    }
}
}}}
It tells us there is a method \_SB.HKDV.INIT that helps us to let HKON become true, and when HKON is true, there will be an notify with event number 0x09 on \_SB.HKDV<<BR>>

Summary

This page is going to tell how to read DSDT/SSDT table and how it affects your system.

Overview of ACPI

*TBD*

Dump DSDT/SSDT

There are many ways to dump ACPI tables. The most easy way is to select and read out tables file from /sys/firmware/acpi/tables

user@here:~$ tree /sys/firmware/acpi/tables/
/sys/firmware/acpi/tables/
|-- APIC
|-- ATKG
|-- BOOT
|-- DBGP
|-- DSDT
|-- ECDT
|-- FACP
|-- FACS
|-- HPET
|-- MCFG
|-- OEMB
|-- SLIC
|-- SSDT
`-- dynamic
    |-- SSDT2
    |-- SSDT3
    |-- SSDT4
    `-- SSDT5

1 directory, 17 files

You can copy files out with root privilege and use iasl to decompile it

user@here:~$ sudo cp /sys/firmware/acpi/tables/DSDT ~/DSDT.bin
user@here:~$ sudo chown user:user /home/user/DSDT.bin
user@here:~$ iasl -d ~/DSDT.bin 

Intel ACPI Component Architecture
AML Disassembler version 20090521 [Jun 30 2009]
Copyright (C) 2000 - 2009 Intel Corporation
Supports ACPI Specification Revision 3.0a

Loading Acpi table from file /home/user/DSDT.bin
Acpi table [DSDT] successfully installed and loaded
Pass 1 parse of [DSDT]
Pass 2 parse of [DSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Parsing completed
Disassembly completed, written to "/home/user/DSDT.dsl"

Now, you can find your DSDT at /home/user/DSDT.dsl

Information from /sys

There are lots of ACPI devices described in DSDT/SSDT. DSDT/SSDT describes them in a tree form. The following is a simple example for the ACPI device tree.

user@here:~$ tree /sys/devices/LNXSYSTM\:00/
/sys/devices/LNXSYSTM:00/
|-- LNXCPU:00
|-- LNXCPU:01
|-- LNXPWRBN:00
|-- LNXTHERM:00
|   `-- LNXTHERM:01
`-- device:00
    |-- HKEY1122:00
    |-- PNP0A08:00
    |   |-- ACPI0003:00
    |   |-- PNP0C02:00
    |   |-- PNP0C02:05
    |   |-- PNP0C0A:00
    |   |-- device:01
    |   |   |-- ONE0013:00
    |   |   |-- PNP0C04:00
    |   |   `-- PNP0C09:00
    |   |       `-- ONE0014:00
    |   |-- device:02
    |   |   |-- device:03
    |   |   |   |-- device:04
    |   |   |   `-- device:05
    |   |   |-- device:06
    |   |   |   |-- device:07
    |   |   |   `-- device:08
    |   |   |-- device:09
    |   |   |-- device:0a
    |   |   |-- device:0b
    |   |   `-- device:0c
    |   |-- device:0d
    |   |-- device:2f
    |   |   `-- device:30
    |   `-- device:31
    |       |-- device:32
    |       `-- device:33
    |-- PNP0C01:00
    |-- PNP0C0D:00
    |-- PNP0C0E:00
    |-- PNP0C0F:00
    |-- PNP0C0F:01
    |-- PNP0C0F:02
    |-- PNP0C0F:03
    |-- PNP0C0F:04
    |-- PNP0C0F:05
    |-- PNP0C0F:06
    `-- PNP0C0F:07

The folder name starts with "device" means that this device has no HID (Hardware ID). It's hard to bind a driver on it and execute its method, so we will ignore them.

The folder name starts with "PNP" or "ACPI" means that this device is generic ACPI device, not a machine specific device. When we are going to enable some special function, its not necessary to take a look.

The folder name starts with "LNX" mean some root devices, they do not need an HID we know exact what they are. In the above example, LNXSYSTM means \_SB (System Base), LNXPWRBN is the power butten device, LNXCPU is the CPU and LNXTHERM is the thermal zone defined in DSDT.

In the above example, we will look at HKEY1122, ONE0013 and ONE0014 to find out if there is anything we can enable.

Read DSDT/SSDT

*TBD*

ACPI Event

When an ACPI-handled event happened - for example: an ACPI-handled hotkey is pressed, hardware will generate an interrupt of ACPI. You can monitor that and find out there are relation between event and numbers of ACPI Interrupt.

user@here:~$ cat /proc/interrupts | grep acpi
  9:      32288      32006   IO-APIC-fasteoi   acpi

The interrupt will be dispatch to a GPE event, you can find which GPE it is by monitoring /sys/firmware/acpi/interrupts/*

user@here:~$ cat /sys/firmware/acpi/interrupts/gpe1B
   71718        enabled

Usually it belong to EC. You can check /proc/acpi/embedded_controller/EC?/info

user@here:~$ cat /proc/acpi/embedded_controller/EC0/info
gpe:                    0x1b
ports:                  0x66, 0x62
use global lock:        no

You can monitor the EC GPE by adding a debug printk.

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index d6471bb..a76625b 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -528,6 +528,7 @@ static int acpi_ec_sync_query(struct acpi_ec *ec)
        struct acpi_ec_query_handler *handler, *copy;
        if ((status = acpi_ec_query_unlocked(ec, &value)))
                return status;
+       pr_info(">>>>>> [EC GPE] Query bit = %02X\n", value);
        list_for_each_entry(handler, &ec->list, node) {
                if (value == handler->query_bit) {
                        /* have custom handler for this bit */

We assume when we press mute key, the query bit is 0x1A. When this event happen, EC driver will execute its method _Q1A. Then we can seek _Q1A method in the DSDT/SSDT. The scope of this method shall be EC.

Scope (_SB.PCI0.SBRG.EC0)
{
    ......
    Method (_Q1A, 0, NotSerialized)
    {
        If (HKON)
        {
            Notify (HKDV, 0x09)
        }
    }
    ......
}

It tells us that when HKON is true, there will be a notify on HKDV and its event number is 0x09. So, we shall know how to let HKON become true by searching HKON in DSDT/SSDT.

Scope (_SB)
{
    Name (HKON, Zero)
}

It tells us HKON is a variable at _SB and its default value is zero.

Scope (_SB)
{
    Device (HKDV)
    {
        Name (_HID, "HKEY1122")
        Method (INIT, 1, NotSerialized)
        {
            Store (One, HKON)
            Return (Zero)
        }
    }
}

It tells us there is a method \_SB.HKDV.INIT that helps us to let HKON become true, and when HKON is true, there will be an notify with event number 0x09 on \_SB.HKDV

KernelTeam/HardwareEnableWithDSDT (last edited 2016-08-05 18:38:47 by dannf)