|  | .. SPDX-License-Identifier: GPL-2.0 | 
|  |  | 
|  | ================================ | 
|  | Upgrading ACPI tables via initrd | 
|  | ================================ | 
|  |  | 
|  | What is this about | 
|  | ================== | 
|  |  | 
|  | If the ACPI_TABLE_UPGRADE compile option is true, it is possible to | 
|  | upgrade the ACPI execution environment that is defined by the ACPI tables | 
|  | via upgrading the ACPI tables provided by the BIOS with an instrumented, | 
|  | modified, more recent version one, or installing brand new ACPI tables. | 
|  |  | 
|  | When building initrd with kernel in a single image, option | 
|  | ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD should also be true for this | 
|  | feature to work. | 
|  |  | 
|  | For a full list of ACPI tables that can be upgraded/installed, take a look | 
|  | at the char `*table_sigs[MAX_ACPI_SIGNATURE];` definition in | 
|  | drivers/acpi/tables.c. | 
|  |  | 
|  | All ACPI tables iasl (Intel's ACPI compiler and disassembler) knows should | 
|  | be overridable, except: | 
|  |  | 
|  | - ACPI_SIG_RSDP (has a signature of 6 bytes) | 
|  | - ACPI_SIG_FACS (does not have an ordinary ACPI table header) | 
|  |  | 
|  | Both could get implemented as well. | 
|  |  | 
|  |  | 
|  | What is this for | 
|  | ================ | 
|  |  | 
|  | Complain to your platform/BIOS vendor if you find a bug which is so severe | 
|  | that a workaround is not accepted in the Linux kernel. And this facility | 
|  | allows you to upgrade the buggy tables before your platform/BIOS vendor | 
|  | releases an upgraded BIOS binary. | 
|  |  | 
|  | This facility can be used by platform/BIOS vendors to provide a Linux | 
|  | compatible environment without modifying the underlying platform firmware. | 
|  |  | 
|  | This facility also provides a powerful feature to easily debug and test | 
|  | ACPI BIOS table compatibility with the Linux kernel by modifying old | 
|  | platform provided ACPI tables or inserting new ACPI tables. | 
|  |  | 
|  | It can and should be enabled in any kernel because there is no functional | 
|  | change with not instrumented initrds. | 
|  |  | 
|  |  | 
|  | How does it work | 
|  | ================ | 
|  | :: | 
|  |  | 
|  | # Extract the machine's ACPI tables: | 
|  | cd /tmp | 
|  | acpidump >acpidump | 
|  | acpixtract -a acpidump | 
|  | # Disassemble, modify and recompile them: | 
|  | iasl -d *.dat | 
|  | # For example add this statement into a _PRT (PCI Routing Table) function | 
|  | # of the DSDT: | 
|  | Store("HELLO WORLD", debug) | 
|  | # And increase the OEM Revision. For example, before modification: | 
|  | DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000000) | 
|  | # After modification: | 
|  | DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000001) | 
|  | iasl -sa dsdt.dsl | 
|  | # Add the raw ACPI tables to an uncompressed cpio archive. | 
|  | # They must be put into a /kernel/firmware/acpi directory inside the cpio | 
|  | # archive. Note that if the table put here matches a platform table | 
|  | # (similar Table Signature, and similar OEMID, and similar OEM Table ID) | 
|  | # with a more recent OEM Revision, the platform table will be upgraded by | 
|  | # this table. If the table put here doesn't match a platform table | 
|  | # (dissimilar Table Signature, or dissimilar OEMID, or dissimilar OEM Table | 
|  | # ID), this table will be appended. | 
|  | mkdir -p kernel/firmware/acpi | 
|  | cp dsdt.aml kernel/firmware/acpi | 
|  | # A maximum of "NR_ACPI_INITRD_TABLES (64)" tables are currently allowed | 
|  | # (see osl.c): | 
|  | iasl -sa facp.dsl | 
|  | iasl -sa ssdt1.dsl | 
|  | cp facp.aml kernel/firmware/acpi | 
|  | cp ssdt1.aml kernel/firmware/acpi | 
|  | # The uncompressed cpio archive must be the first. Other, typically | 
|  | # compressed cpio archives, must be concatenated on top of the uncompressed | 
|  | # one. Following command creates the uncompressed cpio archive and | 
|  | # concatenates the original initrd on top: | 
|  | find kernel | cpio -H newc --create > /boot/instrumented_initrd | 
|  | cat /boot/initrd >>/boot/instrumented_initrd | 
|  | # reboot with increased acpi debug level, e.g. boot params: | 
|  | acpi.debug_level=0x2 acpi.debug_layer=0xFFFFFFFF | 
|  | # and check your syslog: | 
|  | [    1.268089] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT] | 
|  | [    1.272091] [ACPI Debug]  String [0x0B] "HELLO WORLD" | 
|  |  | 
|  | iasl is able to disassemble and recompile quite a lot different, | 
|  | also static ACPI tables. | 
|  |  | 
|  |  | 
|  | Where to retrieve userspace tools | 
|  | ================================= | 
|  |  | 
|  | iasl and acpixtract are part of Intel's ACPICA project: | 
|  | https://acpica.org/ | 
|  |  | 
|  | and should be packaged by distributions (for example in the acpica package | 
|  | on SUSE). | 
|  |  | 
|  | acpidump can be found in Len Browns pmtools: | 
|  | ftp://kernel.org/pub/linux/kernel/people/lenb/acpi/utils/pmtools/acpidump | 
|  |  | 
|  | This tool is also part of the acpica package on SUSE. | 
|  | Alternatively, used ACPI tables can be retrieved via sysfs in latest kernels: | 
|  | /sys/firmware/acpi/tables |