Why I wanted to explore:
In my previous post about forming a hypothesis about my Laptop's Blank screen issue, I had realized that my bug may not be a software bug, and instead be firmware or BIOS level. So, I went down this rabbit hole.
ACPI - Advanced Configuration and Power Interface Tables
What it is:
- Describe how the OS should configure and control hardware
- allows OS to manage power, devices and system configuration
-
stuff like--
- CPU Power States
- Sleep Modes
- Device enumeration
- Thermal Management
- Interrupt Routing
Defined by BIOS/UEFI
Characteristics:
- Dynamic hardware configuration
- Contains AML byte-code interpreted by OS
- Controls Power Management and device setup
ACPI is mainly used on PC platforms (esp x86 systems) to describe hardware configuration and enable operating system power management.
Other embedded systems (especially ARM-based systems) like phones and embedded boards use Device Trees.
Device Trees are simpler and mostly static hardware descriptions. They are not written in AML like ACPI. Instead they just describe the hardware layout -- devices, memory addresses, interrupts, buses, etc..
The OS reads the Device Tree during boot to figure out what hardware exists and how to access it. The kernel then uses this information to initialize devices and bind the appropriate drivers.
How the OS finds the ACPI table -- RSDP and XSDT
1) Finds RSDP
- RSDP - Root System Description Pointer
- this is the entry point to ACPI
- OS gets it from UEFI config table, or in well known memory locations
- also gets XSDT from here
2) Load XSDT
- XSDT - Extended System Description Table
- Contains list of pointers to other ACPI tables
XSDT
├── FADT
├── DSDT
├── SSDT
├── MADT
├── HPET
└── others
- each entry is a 64 bit address pointing to another ACPI table
3) Parse Important tables
OS loads important tables for hardware initialization
| Table | Purpose |
|---|---|
| DSDT | AML code describing devices |
| SSDT | Additional AML definitions |
| MADT | Interrupt controller (APIC) |
| FADT | Power management |
| HPET | High precision timer |
| SRAT | NUMA topology |
Then it parses AML bytecode, builds an internal device model, initializes power management
Logs from dmesg
observe the RSDP, XSDT, etc detection process shown here
we can clearly see how all tables were detected one by one during boot
[ 0.007866] ACPI: Early table checksum verification disabled
[ 0.007869] ACPI: RSDP 0x000000006D0B0014 000024 (v02 HPQOEM)
[ 0.007872] ACPI: XSDT 0x000000006D0AF728 00010C (v01 HPQOEM SLIC-MPC 01072009 AMI 01000013)
[ 0.007877] ACPI: FACP 0x000000006D0AA000 000114 (v06 HPQOEM SLIC-MPC 01072009 HP 00010013)
[ 0.007881] ACPI: DSDT 0x000000006D056000 05308D (v02 HPQOEM 87FE 01072009 ACPI 20191018)
[ 0.007883] ACPI: FACS 0x000000006D169000 000040
[ 0.007885] ACPI: MCFG 0x000000006D0AE000 00003C (v01 HPQOEM 87FE 01072009 HP 00000097)
[ 0.007887] ACPI: SSDT 0x000000006D0AB000 0025CF (v02 HPQOEM 87FE 00003000 ACPI 20191018)
[ 0.007889] ACPI: FIDT 0x000000006D055000 00009C (v01 HPQOEM 87FE 01072009 HP 00010013)
[ 0.007891] ACPI: MSDM 0x000000006D054000 000055 (v03 HPQOEM SLIC-MPC 00000001 HP 00010013)
[ 0.007892] ACPI: SSDT 0x000000006D050000 0032D3 (v02 HPQOEM 87FE 00001000 ACPI 20191018)
[ 0.007894] ACPI: SSDT 0x000000006D04D000 002B59 (v02 SaSsdt SaSsdt 00003000 INTL 20191018)
[ 0.007896] ACPI: SSDT 0x000000006D049000 003350 (v02 HPQOEM 87FE 00003000 ACPI 20191018)
[ 0.007898] ACPI: HPET 0x000000006D048000 000038 (v01 HPQOEM 87FE 01072009 HP 01000013)
[ 0.007900] ACPI: APIC 0x000000006D047000 00012C (v04 HPQOEM 87FE 01072009 HP 01000013)
[ 0.007902] ACPI: NHLT 0x000000006D046000 000F58 (v00 HPQOEM 87FE 01072009 HP 01000013)
[ 0.007904] ACPI: LPIT 0x000000006D045000 0000CC (v01 HPQOEM 87FE 01072009 HP 01000013)
[ 0.007906] ACPI: SSDT 0x000000006D041000 002720 (v02 HPQOEM 87FE 00001000 ACPI 20191018)
[ 0.007908] ACPI: SSDT 0x000000006D040000 00012A (v02 HPQOEM 87FE 00000000 ACPI 20191018)
[ 0.007910] ACPI: DBGP 0x000000006D03F000 000034 (v01 HPQOEM 87FE 01072009 HP 01000013)
[ 0.007911] ACPI: DBG2 0x000000006D03E000 000054 (v00 HPQOEM 87FE 01072009 HP 01000013)
[ 0.007913] ACPI: SSDT 0x000000006D03D000 000BA3 (v02 HPQOEM 87FE 00001000 ACPI 20191018)
[ 0.007915] ACPI: DMAR 0x000000006D03C000 000088 (v02 HPQOEM 87FE 00000002 HP 01000013)
[ 0.007917] ACPI: SSDT 0x000000006D03B000 000694 (v02 HPQOEM 87FE 00000000 ACPI 20191018)
[ 0.007919] ACPI: SSDT 0x000000006D03A000 000144 (v02 HPQOEM 87FE 00001000 ACPI 20191018)
[ 0.007921] ACPI: SSDT 0x000000006D039000 00009D (v01 HPQOEM 87FE 00000001 ACPI 20191018)
[ 0.007923] ACPI: SSDT 0x000000006D038000 000060 (v01 HPQOEM 87FE 00000001 ACPI 20191018)
[ 0.007925] ACPI: UEFI 0x000000006D0D9000 00063A (v01 HPQOEM 87FE 00000000 HP 00000000)
[ 0.007926] ACPI: UEFI 0x000000006D0D8000 00005C (v01 HPQOEM 87FE 00000000 HP 00000000)
[ 0.007928] ACPI: TPM2 0x000000006D037000 00004C (v04 HPQOEM 87FE 00000001 HP 00000000)
[ 0.007930] ACPI: PTDT 0x000000006D036000 000CFE (v00 HPQOEM 87FE 00000005 HP 0100000D)
[ 0.007932] ACPI: WSMT 0x000000006D044000 000028 (v01 HPQOEM 87FE 01072009 HP 00010013)
[ 0.007934] ACPI: FPDT 0x000000006D035000 000044 (v01 HPQOEM 87FE 01072009 HP 01000013)
[ 0.007936] ACPI: BGRT 0x000000006D034000 000038 (v01 HPQOEM 87FE 01072009 HP 00010013)
Viewing ACPI tables
ACPI tables are stored in /sys/firmware/acpi/tables
root@laptop:# ls /sys/firmware/acpi/tables
APIC DBG2 DSDT FACS HPET MSDM SSDT1 SSDT2 SSDT5 SSDT8 UEFI1
BGRT DBGP dynamic FIDT LPIT NHLT SSDT10 SSDT3 SSDT6 SSDT9 UEFI2
data DMAR FACP FPDT MCFG PTDT SSDT11 SSDT4 SSDT7 TPM2 WSMT
They are all binary AML files, so they are unreadable
Decoding ACPI tables
install acpica tools
sudo apt install acpica-tools
go to your folder where you want to dump the tables and create a directory
then dump the tables
sudo acpidump -b
this extracts ACPI tables into binary files:
root@laptop:/home/anu/anu/programming/systems_progg/acpi_dump# sudo acpidump -b
root@laptop:/home/anu/anu/programming/systems_progg/acpi_dump# ls
apic.dat facp.dat mcfg.dat ssdt12.dat ssdt18.dat ssdt6.dat uefi2.dat
bgrt.dat facs.dat msdm.dat ssdt13.dat ssdt1.dat ssdt7.dat wsmt.dat
dbg2.dat fidt.dat nhlt.dat ssdt14.dat ssdt2.dat ssdt8.dat
dbgp.dat fpdt.dat ptdt.dat ssdt15.dat ssdt3.dat ssdt9.dat
dmar.dat hpet.dat ssdt10.dat ssdt16.dat ssdt4.dat tpm2.dat
dsdt.dat lpit.dat ssdt11.dat ssdt17.dat ssdt5.dat uefi1.dat
Decompile a table
here, I'm reading DSDT table
convert it to readable ACPI code
iasl -d dsdt.dat
this produces dsdt.dsl
and you can open this in a text editor to or using less to see what's in it
SSDT files and what they contain
SSDT: Secondary System Description Table
- additional AML code
Why many SSDT exist instead of 1 big DSDT?
- Modularity: each subsystem -- own ACPI table
- Dynamic loading: some ssdts are loaded only when the hardware exists (like an optional gpu present, etc)
- Vendors can easily update one ssdt instead of big dsdt
The exact purpose of that SSDT depends on firmware
This is how my SSDTs likely look:
| SSDT | Likely purpose |
|---|---|
| SSDT1 | CPU topology |
| SSDT2 | CPU power states |
| SSDT3 | PCI root bridges |
| SSDT4 | USB |
| SSDT5 | GPU |
| SSDT6 | thermal |
| SSDT7+ | vendor specific |
Editing ACPI tables
You can't "edit" ACPI tables, you override the ACPI tables at boot. This is done when firmware has buggy ACPI configurations
Steps:
1) Dump ACPI tables (as mentioned above)
2) Decompile (as mentioned above)
3) Edit the table
open the file with text editor and edit the file as required.
⚠️Warning: Editing must be done carefully. ACPI is firmware level hardware control code. Bad edits can cause boot issues, fans stuck, thermal shutdowns, power issues, etc.
4) Recompile
`iasl -tc dsdt.dsl`
o/p---> dsdt.aml
5) Now you can override your ACPI table via initramfs
5.1. Move aml file to /lib/firmware/acpi/
sudo mkdir -p /lib/firmware/acpi
sudo cp dsdt.aml /lib/firmware/acpi/
5.2. Rebuild initramfs
sudo update-initramfs -u
5.3 Reboot
5.4 Verify
check dmesg
dmesg | grep -i acpi
You should see smth like this ACPI: overriding DSDT
Next step:
- Explore ACPI -- SSDT tables for understanding current C state configuration to check for bug hiding there.
- Figuring out if i915 driver interaction with ACPI power states is related to my bug's location I don't know whether the answer lies there, but I will look.
Top comments (0)