ACPI patching troubleshooting guide for RedmiBook
I am an another happy owner of the Xiaomi’s RedmiBook, and this laptop is really amazing for its’ price. But nothing is perfect in this world, and one of the issues with RedmiBook is deep sleep support (on Linux).
When I discovered problems with energy consumption while laptop is sleeping, I found this article. I am grateful to author for his work, but unfortunately, copy-pasting commands did not solve my issue - there were some errors during decompilation stage, so recompilation stage failed also.
Problem 1. Disassembling DSDT
As you can see, there are some unresolved external control methods in the DSDT. This is preventing successful disassembly, so future patching and recompilation are impossible.
$ sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.aml
$ iasl -d dsdt.aml
Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20200326
Copyright (c) 2000 - 2020 Intel Corporation
File appears to be binary: found 7312 non-ASCII characters, disassembling
Binary file appears to be a valid ACPI table, disassembling
Input file dsdt.aml, Length 0x4FA8 (20392) bytes
ACPI: DSDT 0x0000000000000000 004FA8 (v01 XMCC XMCC1955 00000002 01000013)
Pass 1 parse of [DSDT]
Pass 2 parse of [DSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
Parsing completed
Found 8 external control methods, reparsing with new information
Pass 1 parse of [DSDT]
Pass 2 parse of [DSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
Parsing completed
Disassembly completed
ASL Output: dsdt.dsl - 192773 bytes
iASL Warning: There were 8 external control methods found during
disassembly, but only 0 were resolved (8 unresolved). Additional
ACPI tables may be required to properly disassemble the code. This
resulting disassembler output file may not compile because the
disassembler did not know how many arguments to assign to the
unresolved methods. Note: SSDTs can be dynamically loaded at
runtime and may or may not be available via the host OS.
To specify the tables needed to resolve external control method
references, the -e option can be used to specify the filenames.
Example iASL invocations:
iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml
iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml
iasl -e ssdt*.aml -d dsdt.aml
In addition, the -fe option can be used to specify a file containing
control method external declarations with the associated method
argument counts. Each line of the file must be of the form:
External (<method pathname>, MethodObj, <argument count>)
Invocation:
iasl -fe refs.txt -d dsdt.aml
Fixing disassembly
But we have some example usage of iasl, mentioning additional SSDTs. And I have a lot of them:
$ ls /sys/firmware/acpi/tables/SSDT*
/sys/firmware/acpi/tables/SSDT1 /sys/firmware/acpi/tables/SSDT13 /sys/firmware/acpi/tables/SSDT2 /sys/firmware/acpi/tables/SSDT6
/sys/firmware/acpi/tables/SSDT10 /sys/firmware/acpi/tables/SSDT14 /sys/firmware/acpi/tables/SSDT3 /sys/firmware/acpi/tables/SSDT7
/sys/firmware/acpi/tables/SSDT11 /sys/firmware/acpi/tables/SSDT15 /sys/firmware/acpi/tables/SSDT4 /sys/firmware/acpi/tables/SSDT8
/sys/firmware/acpi/tables/SSDT12 /sys/firmware/acpi/tables/SSDT16 /sys/firmware/acpi/tables/SSDT5 /sys/firmware/acpi/tables/SSDT9
Let’s try to disassemble DSDT including all available SSDTs:
$ sudo iasl -e /sys/firmware/acpi/tables/SSDT* -d dsdt.aml
Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20200326
Copyright (c) 2000 - 2020 Intel Corporation
File appears to be binary: found 7312 non-ASCII characters, disassembling
Binary file appears to be a valid ACPI table, disassembling
Input file dsdt.aml, Length 0x4FA8 (20392) bytes
ACPI: DSDT 0x0000000000000000 004FA8 (v01 XMCC XMCC1955 00000002 01000013)
External object resolution file /sys/firmware/acpi/tables/SSDT9
Input file /sys/firmware/acpi/tables/SSDT9, Length 0xC78 (3192) bytes
ACPI: SSDT 0x0000000000000000 000C78 (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT8
Input file /sys/firmware/acpi/tables/SSDT8, Length 0x1BF4 (7156) bytes
ACPI: SSDT 0x0000000000000000 001BF4 (v01 XMCC XMCC1955 00000001 AMD 00000001)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT7
Input file /sys/firmware/acpi/tables/SSDT7, Length 0xF8 (248) bytes
ACPI: SSDT 0x0000000000000000 0000F8 (v01 XMCC XMCC1955 00001000 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT6
Input file /sys/firmware/acpi/tables/SSDT6, Length 0x80 (128) bytes
ACPI: SSDT 0x0000000000000000 000080 (v01 XMCC XMCC1955 00000002 01000013)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT5
Input file /sys/firmware/acpi/tables/SSDT5, Length 0x47E (1150) bytes
ACPI: SSDT 0x0000000000000000 00047E (v01 XMCC XMCC1955 00001000 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT4
Input file /sys/firmware/acpi/tables/SSDT4, Length 0x792 (1938) bytes
ACPI: SSDT 0x0000000000000000 000792 (v01 XMCC XMCC1955 00003000 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT3
Input file /sys/firmware/acpi/tables/SSDT3, Length 0x228 (552) bytes
ACPI: SSDT 0x0000000000000000 000228 (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT2
Input file /sys/firmware/acpi/tables/SSDT2, Length 0x7216 (29206) bytes
ACPI: SSDT 0x0000000000000000 007216 (v02 XMCC XMCC1955 00000002 MSFT 04000000)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT16
Input file /sys/firmware/acpi/tables/SSDT16, Length 0x517 (1303) bytes
ACPI: SSDT 0x0000000000000000 000517 (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT15
Input file /sys/firmware/acpi/tables/SSDT15, Length 0x7D (125) bytes
ACPI: SSDT 0x0000000000000000 00007D (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT14
Input file /sys/firmware/acpi/tables/SSDT14, Length 0x20A (522) bytes
ACPI: SSDT 0x0000000000000000 00020A (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT13
Input file /sys/firmware/acpi/tables/SSDT13, Length 0x65E (1630) bytes
ACPI: SSDT 0x0000000000000000 00065E (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT12
Input file /sys/firmware/acpi/tables/SSDT12, Length 0x20A (522) bytes
ACPI: SSDT 0x0000000000000000 00020A (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT11
Input file /sys/firmware/acpi/tables/SSDT11, Length 0x30C8 (12488) bytes
ACPI: SSDT 0x0000000000000000 0030C8 (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT10
Input file /sys/firmware/acpi/tables/SSDT10, Length 0x10AC (4268) bytes
ACPI: SSDT 0x0000000000000000 0010AC (v01 XMCC XMCC1955 00000001 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
External object resolution file /sys/firmware/acpi/tables/SSDT1
Input file /sys/firmware/acpi/tables/SSDT1, Length 0x33BB (13243) bytes
ACPI: SSDT 0x0000000000000000 0033BB (v02 XMCC XMCC1955 00000000 INTL 20130117)
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
Pass 1 parse of [DSDT]
Pass 2 parse of [DSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
Parsing completed
Found 8 external control methods, reparsing with new information
Pass 1 parse of [DSDT]
Pass 2 parse of [DSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
Parsing completed
Disassembly completed
ASL Output: dsdt.dsl - 191166 bytes
Everything seems to be OK, and 8 our control methods were resolved successfully.
Problem 2. DSDT errors
Now we are applying patch from original article (be aware that XMCC version could be different). In my case, proper patch looks like this one:
@@ -18,7 +18,7 @@
* Compiler ID " "
* Compiler Version 0x01000013 (16777235)
*/
-DefinitionBlock ("", "DSDT", 1, "XMCC", "XMCC1955", 0x00000002)
+DefinitionBlock ("", "DSDT", 1, "XMCC", "XMCC1955", 0x00000003)
{
External (_SB_.APTS, MethodObj) // 1 Arguments
External (_SB_.AWAK, MethodObj) // 1 Arguments
@@ -733,19 +733,13 @@
Zero,
Zero
})
- If ((CNSB == Zero))
+ Name (_S3, Package (0x04) // _S3_: S3 System State
{
- If ((DAS3 == One))
- {
- Name (_S3, Package (0x04) // _S3_: S3 System State
- {
- 0x03,
- 0x03,
- Zero,
- Zero
- })
- }
- }
+ 0x03,
+ 0x03,
+ Zero,
+ Zero
+ })
Name (_S4, Package (0x04) // _S4_: S4 System State
{
Idea is simple - update version to a higher one (in DefinitionBlock) and remove ‘if’ blocks, that are preventing S3 state.
$ iasl dsdt-sleep.dsl
Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20200326
Copyright (c) 2000 - 2020 Intel Corporation
[redacted: many lines with remarks, warnings and errors were deleted]
ASL Input: dsdt-sleep.dsl - 191027 bytes 2041 keywords 6370 source lines
Compilation failed. 3 Errors, 32 Warnings, 121 Remarks
No AML files were generated due to compiler error(s)
I do not want to do grep for handling multiline errors, so I would simply add
-ve
flag, which will report only errors:
$ iasl -ve dsdt-sleep.dsl
Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20200326
Copyright (c) 2000 - 2020 Intel Corporation
dsdt-sleep.dsl 3567: Return (Zero)
Error 6105 - ^ Invalid object type for reserved name (_CRS: found Integer, Buffer required)
dsdt-sleep.dsl 3580: Return (Zero)
Error 6105 - ^ Invalid object type for reserved name (_CRS: found Integer, Buffer required)
dsdt-sleep.dsl 3593: Return (Zero)
Error 6105 - ^ Invalid object type for reserved name (_CRS: found Integer, Buffer required)
ASL Input: dsdt-sleep.dsl - 191027 bytes 2041 keywords 6370 source lines
Compilation failed. 3 Errors, 32 Warnings, 121 Remarks
No AML files were generated due to compiler error(s)
Fixing DSDT compilation
After some small research, I tried to replace Zero
with _CRS
:
@@ -3564,7 +3564,7 @@
{
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
+ Return (_CRS)
- Return (Zero)
}
}
@@ -3577,7 +3577,7 @@
{
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
+ Return (_CRS)
- Return (Zero)
}
}
@@ -3590,7 +3590,7 @@
{
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
+ Return (_CRS)
- Return (Zero)
}
Device (WLAN)
Recompiling our patch again:
$ iasl -ve dsdt-sleep-buffer-fix.dsl
Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20200326
Copyright (c) 2000 - 2020 Intel Corporation
ASL Input: dsdt-sleep-buffer-fix.dsl - 191027 bytes 2041 keywords 6370 source lines
AML Output: dsdt-sleep-buffer-fix.aml - 20520 bytes 1137 opcodes 904 named objects
Compilation successful. 0 Errors, 32 Warnings, 124 Remarks, 33 Optimizations
Finally, that worked. Now you can follow further instructions to build cpio archive and add image to initrd.