Laptop doesn't any reaction on lid close

So, as I said above, this is translated instruction from Chinese forum.

The problem is really related with ACPI.

Firstly make sure, that you have the same error messages when you open or close your lid.

Run:

journalctl -b -f

After that close and open your lid and you will seen in the logs this lines:

ACPI Error: Needed [Buffer/String/Package], found [Integer] 00000000563bf479 (20210105/exresop-557)
ACPI Error: AE_AML_OPERAND_TYPE, While resolving operands for [Index] (20210105/dswexec-431)
ACPI Error: Aborting method \_SB.ALIB due to previous error (AE_AML_OPERAND_TYPE) (20210105/psparse-529)
ACPI Error: Aborting method \_SB.PCI0.LPC0.EC0._Q80 due to previous error (AE_AML_OPERAND_TYPE) (20210105/pspars>

(some numbers may differ, but the most important thing, that is \_SB.PCI0.LPC0.EC0._Q80. It must be in you log)


You need to decompile DSDT:

sudo acpidump > acpidata.dat
acpixtract -sSSDT acpidata.dat
acpixtract -sDSDT acpidata.dat
iasl -e ssdt*.dat -d dsdt.dat

The function _Q80 in dsdt.dsl looks like this:

Method (_Q80, 0, NotSerialized)  // _Qxx: EC Query, xx=0x00-0xFF
{
    If ((LSTE == Zero))
    {
        ALBH (0x06, 0x4E20)
        ALBH (0x07, 0x4E20)
        ALBH (0x05, 0x00051C98)
        ALIB (One, 0x05)
    }
    Else
    {
        STTC ()
    }

    LIDS = ECRD (RefOf (LSTE))
    Notify (LID0, 0x80) // Status Change
}

The problem appears to be the call to ALIB (One, 0x05). Found that the ALIB function is defined in ssdt2.dsl:

Method (ALIB, 2, NotSerialized)
{
    If ((Arg0 == 0x00))
    {
        。。。。。。
    }

    If ((Arg0 == 0x01))
    {
        Local0 = DerefOf (Arg1 [0x02])
        Return (A019 (Local0))
    }

It looks like Arg1 should be an array, not the integer 0x05. This also matches the error in the syslog.

So what should be changed? Searched this ALIB should be provided by AMD. Documentation: Link for AMD Documentation

Instructions for calling ALIB(1, _):

Report AC/DC State - Function 1.
The Platform BIOS should Report AC/DC State to report boot up power source as AC or DC.
This function could be performed from \_SB.PCI0._INI or from \_SB._INI, for example.

Input:
WORD Size
BYTE AC/DC State

Size
The size in bytes, 3.
AC/DC
State Indicate the current power source type.
0 - Current state is AC power.
1 - Current state is DC power.

Output: None.

The current power state should be passed in. I read this code full of four-letter abbreviations, and have no clue. Since the document says: “report boot up power source”, “This function could be performed from \_SB.PCI0._INI or from \_SB._INI”, it is better to assume that it does not need to be called in the closing event at all, delete it:

$ diff -u dsdt.dsl dsdt_patched.dsl
--- dsdt.dsl    2021-07-01 13:36:18.856593034 +0800
+++ dsdt_patched.dsl    2021-07-01 16:01:44.490812829 +0800
@@ -18,7 +18,7 @@
  *     Compiler ID      "ACPI"
  *     Compiler Version 0x00040000 (262144)
  */
-DefinitionBlock ("", "DSDT", 1, "XMCC  ", "XMCC2019", 0x00000002)
+DefinitionBlock ("", "DSDT", 1, "XMCC  ", "XMCC2019", 0x00000009)
 {
     External (_SB_.ALIB, MethodObj)    // 2 Arguments
     External (_SB_.APTS, MethodObj)    // 1 Arguments
@@ -4672,7 +4672,7 @@
                             ALBH (0x06, 0x4E20)
                             ALBH (0x07, 0x4E20)
                             ALBH (0x05, 0x00051C98)
-                            ALIB (One, 0x05)
+                            // ALIB (One, 0x05)
                         }
                         Else
                         {

Note that the version 0x00000002 of the file header needs to be increased, otherwise the original version cannot be overwritten.

According to the instructions of the arch wiki, overwrite the DSDT: (loaded at runtime, it will not overwrite the original version in the BIOS, rest assured):

patch < lid.patch
iasl dsdt.dsl
mkdir -p kernel/firmware/acpi
cp dsdt.aml kernel/firmware/acpi/
find kernel | cpio -H newc --create > acpi_override.img
sudo cp acpi_override.img /boot/

Then in the kernel command line of the bootloader, add initrd=acpi_override.img before initrd=initramfs-%v.img. example:

initrd=amd-ucode.img initrd=acpi_override.img initrd=initramfs-%v.img 

(I did this with adding GRUB_EARLY_INITRD_LINUX_CUSTOM="acpi_override.img" to /etc/default/grub)

After restarting, search for DSDT in the system log:

kernel: ACPI: DSDT ACPI table found in initrd [kernel/firmware/acpi/dsdt_patched.aml][0x6569]
...
kernel: ACPI: DSDT 0x00000000C843E000 006569 (v01 XMCC   XMCC2019 00000009 INTL 20210331)

Note that the version number changed from 02 to 09 which we changed.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.