Canonical Voices

Posts tagged with 'acpi'

Alex Hung

I often need to implement tests for new ACPI tables before they become available on real hardware. Fortunately, FWTS provides a framework to read ACPI tables’ binary.

The below technique is especially convenient for ACPI firmware and OS kernel developers. It provides a simple approach to verifying ACPI tables without compiling firmware and deploying it to hardware.

Using acpidump.log as an input for FWTS

The command to read ACPI tables’ binary is

# check ACPI methods in a text file
$ fwts method --dumpfile=acpidump.log

or

# check ACPI FACP table in a text file
$ fwts facp --dumpfile=acpidump.log

where acpidump.log contains ACPI tables’ binary in a specific format as depicted below:

Format of acpidump
  • Table Signature – the 4-byte long ACPI table signature
  • Offset – data starts from 0000 and increases by 16 bytes per line
  • Hex Data- each line has 16 hex integers of the compiled ACPI table
  • ASCII Data – the ASCII presentation of the hex data

This format may look familiar because it is not specific to FWTS. In fact, it is the same format generated by acpidump. In other words, the below two code snippets generate identical results.

# reading ACPI tables from memory
$ sudo fwts method
# dumping ACPI tables and testing it
$ sudo acpidump > acpidump.log
$ fwts method --dumpfile=acpidump.log

For developers, using –dumpfile option means that it is possible to test ACPI tables before deploying them on real hardware. The following sections present how to prepare a customized log file.

Using a customized acpidump.log for FWTS

We can use acpica-tools to generate an acpidump.log. The following is an example of building a customized acpidump.log to test the fwts method command.

Generate a dummy FADT

A Fixed ACPI Description Table (FADT) contains vital information to ACPI OS such as the base addresses for hardware registers. As a result, FWTS requires a FADT in an acpidump.log so it can recognize acpidump.log as a valid input file.

$ iasl -T FACP
$ iasl facp.asl > /dev/zero
$ echo "FACP @ 0x0000000000000000" >> acpidump.log
$ xxd -c 16 -g 1 facp.aml  | sed 's/^0000/    /' >> acpidump.log
$ echo "" >> acpidump.log

Develop a Customized DSDT table

A Differentiated System Description Table (DSDT) is designed to provide OEM’s value-added features. A dummy DSDT can be generated as below, and OEM value-added features, such as ACPI battery or hotkey for airplane mode, can be added to it.

# Generate a DSDT
$ iasl -T DSDT
# Customize dsdt.asl
#  ex. adding an ACPI battery or airplane mode devices

Compile the DSDT table to binary

The customized DSDT can be compiled and appended to acpidump.log.

$ iasl dsdt.asl > /dev/zero
$ echo "DSDT @ 0x0000000000000000" >> acpidump.log
$ xxd -c 16 -g 1 dsdt.aml  | sed 's/^0000/    /' >> acpidump.log
$ echo "" >> acpidump.log

Run method test with acpidump.log

And finally, run the fwts method test.

$ fwts method --dumpfile=acpidump.log

Final Words

While we use DSDT as an example, the same technique applies to all ACPI tables. For instance, HMAT was introduced and frequently updated in recent ACPI specs, and the Firmware Test Suite includes most, if not all, changes up-to-date. As a consequence, FWTS is able to detect errors before firmware developers integrate HMAT into their projects, and therefore reduces errors in final products.

The post Analyze ACPI Tables in a Text File with FWTS appeared first on Ubuntu Blog.

Read more
Alex Hung

Screenshot of the firmware test suite command line interface

In my previous two articles, ACPI AML Debugger in Ubuntu 18.04 & Debug AML (DSD & SSDT) with ACPICA Utilities, I discussed techniques for AML debugging; however the ACPI specification includes many other important tables. Firmware Test Suite (FWTS) is a test suite (as the name indicates) that can play a big role in debugging ACPI implementations.

While other ACPI tables include fixed fields and lengths, it doesn’t mean their their content cannot go wrong. In fact, many systems have many incorrect tables in their firmware. This can happen when systems are developed by integrating code from various parties without being modified specifically for the customised hardware.

A test suite is a good solution to catch errors without involving too many engineering resources as it can identify errors automatically or semi-automatically. In particular, Firmware Test Suite is one of the best test suite (did I mention it is freely available too?) and it is the recommended ACPI SCT by the UEFI forum, who is the owner of the specification.

What is Firmware Test Suite?

Firmware Test Suite (FWTS) is a test suite that performs sanity checks on firmware. It is intended to identify errors within the BIOS, UEFI, ACPI and if appropriate it will try to explain these errors and give advice to produce a workaround or fix firmware bugs.

More information can be found on the Firmware Test Suite website.

Installing Firmware Test Suite

Installation for Ubuntu Linux is as below:

  1. Add stable PPA (optional) – sudo add-apt-
  2. repository ppa:firmware-testing-team/ppa-fwts-stable
  3. Install FWTS – sudo apt install fwts

You can also download Firmware Test Suite for other Linux distros.

Running Firmware Test Suite

FWTS is a command-line tool and its usage is “fwts cmds” (root access is usually required). The below is an example of checking FACP table

~$ sudo fwts fadt
Running 1 tests, results appended to results.log
Test: FADT Fixed ACPI Description Table tests.                              
  ACPI FADT Description Table flag info.     1 info only          
  FADT checksum test.                        1 passed             
  FADT revision test.                        1 warning           
  ACPI FADT Description Table tests.         24 passed, 2 warnings, 2 skipped
  Test FADT SCI_EN bit is enabled.           1 passed
  Test FADT reset register.                  2 passed
~$ sudo fwts mcfg
Running 1 tests, results appended to results.log
Test: MCFG PCI Express* memory mapped config space test.                    
  Validate MCFG table.                       1 passed
  Validate MCFG PCI config space.            1 passed
~$ sudo fwts checksum
Running 1 tests, results appended to results.log
Test: ACPI table checksum test.
  ACPI table checksum test.                  20 passed
~$ sudo fwts acpitables
Running 1 tests, results appended to results.log
Test: ACPI table headers sanity tests.
  Test ACPI headers.                         17 passed, 1 failed

More test details can be found on its references pages.

Running multiple tests

Multiple tests can be run by appending tests one after another as below:

~$ sudo fwts fadt mcfg checksum acpitables
Running 4 tests, results appended to results.log
Test: FADT Fixed ACPI Description Table tests.
  ACPI FADT Description Table flag info.      1 info only
  FADT checksum test.                         1 passed
  FADT revision test.                         1 warning
  ACPI FADT Description Table tests.          24 passed, 2 warnings, 2 skipped
  Test FADT SCI_EN bit is enabled.            1 passed
  Test FADT reset register.                   2 passed
Test: MCFG PCI Express* memory mapped config space test.
  Validate MCFG table.                        1 passed
  Validate MCFG PCI config space.             1 passed
Test: ACPI table checksum test.
  ACPI table checksum test.                   20 passed
Test: ACPI table headers sanity tests.
  Test ACPI headers.                          17 passed, 1 failed

Running All ACPI Tests

FWTS provides a way to execute all tests in a category. For example, sudo fwts –acpitests run all ACPI tests all together. A similar command is sudo fwts –uefitests which will not be discussed in details here.

Let’s see some examples…

Here are some examples of tests we have run.

Checking FACP Table

Running fadt includes 6 tests that check whether the system firmware/BIOS implements the FACP table correctly. An example results.log is as below.

~$ sudo fwts fadt ; cat results.log
Running 1 tests, results appended to results.log
Test: FADT Fixed ACPI Description Table tests.
  ACPI FADT Description Table flag info.        1 info only
  FADT checksum test.                           1 passed
  FADT revision test.                           1 warning
  ACPI FADT Description Table tests.            24 passed, 2 warnings, 2 skipped
  Test FADT SCI_EN bit is enabled.              1 passed
  Test FADT reset register.                     2 passed

// truncated...

Test 3 of 6: FADT revision test.
FADT revision: 5.0
FADT table length: 268
WARNING: Test 3, FADT revision is outdated: 5.0

ADVICE: The most recent revision of the FADT defined in the ACPI specification is 6.2. While older revisions of the FADT can be used, newer ones may enable additional functionality that cannot be used until the FADT is updated.

// truncated...

Test Failure Summary
====================================================

Critical failures: NONE

High failures: NONE

Medium failures: NONE

Low failures: NONE

Other failures: NONE

Test           |Pass |Fail |Abort|Warn |Skip |Info |
---------------+-----+-----+-----+-----+-----+-----+
fadt           |   28|     |     |    3|    2|    1|
---------------+-----+-----+-----+-----+-----+-----+
Total:         |   28|    0|    0|    3|    2|    1|
---------------+-----+-----+-----+-----+-----+-----+

Checking table checksum

Another common error in system firmware/BIOS is comes from the table checksum. When built by the AML compiler, ex. iasl, the table checksum is updated; however, it is common practice that the system firmware/BIOS modifies the tables for hardware customisation during boot time. This can corrupt the table checksum if the firmware/BIOS does not update it accordingly.

Below is an example to verify the checksum fields of all tables.

~$ sudo fwts checksum ; cat results.log
Running 1 tests, results appended to results.log
Test: ACPI table checksum test.
  ACPI table checksum test.                20 passed
Results generated by fwts: Version V19.01.00 (2019-01-16 03:58:48).

Some of this work - Copyright (c) 1999 - 2019, Intel Corp. All rights reserved.
Some of this work - Copyright (c) 2010 - 2019, Canonical.
Some of this work - Copyright (c) 2016 - 2019, IBM.
Some of this work - Copyright (c) 2017 - 2019, ARM Ltd.

This test run on 24/01/19 at 17:23:54 on host Linux earth 4.15.0-43-generic
#46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64.

Command: "fwts checksum".
Running tests: checksum.

checksum: ACPI table checksum test.
----------------------------------------------------
Test 1 of 1: ACPI table checksum test.
FADT X_FIRMWARE_CTRL 64 bit pointer was zero, falling back to using
FIRMWARE_CTRL 32 bit pointer.
PASSED: Test 1, Table RSDP has correct checksum 0x90.
PASSED: Test 1, Table RSDP has correct extended checksum 0x8e.
PASSED: Test 1, Table XSDT has correct checksum 0x21
PASSED: Test 1, Table DSDT has correct checksum 0xfc
PASSED: Test 1, Table FACP has correct checksum 0xc9
PASSED: Test 1, Table APIC has correct checksum 0xbf
PASSED: Test 1, Table FPDT has correct checksum 0x73
PASSED: Test 1, Table SLIC has correct checksum 0x6a
PASSED: Test 1, Table SSDT has correct checksum 0x36
PASSED: Test 1, Table SSDT has correct checksum 0xb7
PASSED: Test 1, Table SSDT has correct checksum 0x3e
PASSED: Test 1, Table HPET has correct checksum 0xa9
PASSED: Test 1, Table SSDT has correct checksum 0x3e
PASSED: Test 1, Table MCFG has correct checksum 0x9c
PASSED: Test 1, Table SSDT has correct checksum 0x31
PASSED: Test 1, Table ASF! has correct checksum 0xb8
PASSED: Test 1, Table BGRT has correct checksum 0x46
PASSED: Test 1, Table DMAR has correct checksum 0x37
PASSED: Test 1, Table RSDT has correct checksum 0xbd
PASSED: Test 1, Table FACP has correct checksum 0xa1

====================================================
20 passed, 0 failed, 0 warning, 0 aborted, 0 skipped, 0 info only.
====================================================


20 passed, 0 failed, 0 warning, 0 aborted, 0 skipped, 0 info only.

Test Failure Summary
====================================================

Critical failures: NONE

High failures: NONE

Medium failures: NONE

Low failures: NONE

Other failures: NONE

Test           |Pass |Fail |Abort|Warn |Skip |Info |
---------------+-----+-----+-----+-----+-----+-----+
checksum       |   20|     |     |     |     |     |
---------------+-----+-----+-----+-----+-----+-----+
Total:         |   20|    0|    0|    0|    0|    0|
---------------+-----+-----+-----+-----+-----+-----+

The post Debug ACPI Tables with Firmware Test Suite (FWTS) appeared first on Ubuntu Blog.

Read more
Colin Ian King

The Firmware Test Suite (FWTS) has an easy to use text based front-end that is primarily used by the FWTS Live-CD image but it can also be used in the Ubuntu terminal.

To install and run the front-end use:

 sudo apt-get install fwts-frontend  
sudo fwts-frontend-text

..and one should see a menu of options:


In this demonstration, the "All Batch Tests" option has been selected:


Tests will be run one by one and a progress bar shows the progress of each test. Some tests run very quickly, others can take several minutes depending on the hardware configuration (such as number of processors).

Once the tests are all complete, the following dialogue box is displayed:


The test has saved several files into the directory /fwts/15052017/1748/ and selecting Yes one can view the results log in a scroll-box:


Exiting this, the FWTS frontend dialog is displayed:


Press enter to exit (note that the Poweroff option is just for the fwts Live-CD image version of fwts-frontend).

The tool dumps various logs, for example, the above run generated:

 ls -alt /fwts/15052017/1748/  
total 1388
drwxr-xr-x 5 root root 4096 May 15 18:09 ..
drwxr-xr-x 2 root root 4096 May 15 17:49 .
-rw-r--r-- 1 root root 358666 May 15 17:49 acpidump.log
-rw-r--r-- 1 root root 3808 May 15 17:49 cpuinfo.log
-rw-r--r-- 1 root root 22238 May 15 17:49 lspci.log
-rw-r--r-- 1 root root 19136 May 15 17:49 dmidecode.log
-rw-r--r-- 1 root root 79323 May 15 17:49 dmesg.log
-rw-r--r-- 1 root root 311 May 15 17:49 README.txt
-rw-r--r-- 1 root root 631370 May 15 17:49 results.html
-rw-r--r-- 1 root root 281371 May 15 17:49 results.log

acpidump.log is a dump of the ACPI tables in format compatible with the ACPICA acpidump tool.  The results.log file is a copy of the results generated by FWTS and results.html is a HTML formatted version of the log.

Read more
Colin Ian King

The Canonical Hardware Enablement Team and myself are continuing the work to add more ACPI table tests to the Firmware Test Suite (fwts).  The latest 15.08.00 release added sanity checks for the following tables:

The release also added a test for the ACPI _CPC revision 2 control method and we updated the ACPICA core to version 20150717.

Our aim is to continue to add support for existing and new ACPI tables to make fwts a comprehensive firmware test tool.  For more information about fwts, please refer to the fwts jump start wiki page.

Read more
Colin Ian King

fwts 13.12.00 released

Version 13.12.00 of the Firmware Test Suite has been released today.  This latest release includes some of the following new features:

  • ACPI method test, add _IPC, _IFT, _SRV tests
  • Update to version 20131115 of ACPICA
  • Check for thermal overrun messages in klog test
  • Test for CPU frequency maximum limits on cpufreq test
  • Add Ivybridge and Haswell CPU specific MSR checks
  • UEFI variable dump:
    • add more subtype support on acpi device path type  
    • handle the End of Hardware Device Path sub-type 0x01
    • add Fibre Channel Ex subtype-21 support on messaging device path type
    • add SATA subtype-18 support on messaging device path type
    • add USB WWID subtype-16 support on messaging device path type
    • add VLAN subtype-20 support on messaging device path type
    • add Device Logical Unit subtype-17 support on messaging device path typ
    • add SAS Ex subtype-22 support on messaging device path type
    • add the iSCSI subtype-19 support on messaging device path type
    • add the NVM Express namespace subtype-23 support on messaging device path type
..and also the usual bug fixes. 

For more details, please consult the release notes
 
The source tarball is available at:  http://fwts.ubuntu.com/release/fwts-V13.12.00.tar.gz and can be cloned from the repository: git://kernel.ubuntu.com/hwe/fwts.git

The fwts 13.12.00 .debs are available in the firmware testing PPA and will soon appear in Ubuntu Trusty 14.04

And thanks to Alex Hung, Ivan Hu, Keng-Yu Lin their contributions and keen eye for reviewing the numerous patches and also to Robert Moore for the on-going work on ACPICA.

Read more
Colin Ian King

The Firmware Test Suite (fwts) is a tool containing a large set of tests to exercise and diagnose firmware related bugs in x86 PC firmware.  So what new shiny features have appeared in the new Ubuntu Raring 13.04 release?

UEFI specific tests to exercise and stress test various UEFI run time services:
 
  * Stress test for miscellaneous run time service interfaces.
  * Test get/set time interfaces.
  * Test get/set wakeup time interfaces.
  * Test get variable interface.
  * Test get next variable name interface.
  * Test set variable interface.
  * Test query variable info interface. 
  * Set variable interface stress test.
  * Query variable info interface stress test.
  * Test Miscellaneous runtime service interfaces.

These use a new kernel driver to allow fwts to access the kernel UEFI run time interfaces.  The driver is built and installed using DKMS.

ACPI specific improvements:

  * Improved ACPI 5.0 support
  * Annotated ACPI _CRS (Current Resource Settings) dumping.

Kernel log scanning (finds and diagnoses errors as reported by the kernel):

  * Improved kernel log scanning with an additional 450 tests.

This release also includes many small bug fixes as well as minor improvements to the layout of the output of some of the tests.

Many thanks to Alex Hung, Ivan Hu, Keng-Yu Lin and Matt Fleming for all the improvements to fwts for this release.

Read more
Colin Ian King

I've now competed the documentation of the Firmware Test Suite and this include documenting each of the 50+ tests (which was a bit of a typing marathon).  Each test has a brief description of what the test covers, example output from the test, how to run the test (possibly with different options) and explanations of test failure messages.

For example of the per-test documentation, check out the the suspend/resume test page and the ACPI tables test page.

I hope this is useful!


Read more
Colin Ian King

The Firmware Test Suite (fwts) is still a relatively new tool and hence this cycle I've still been adding some features and fixing bugs.  I've been running fwts against large data sets to soak test the tool to catch a lot of stupid corner cases (e.g. broken ACPI tables). Also, I am focused on getting some better documentation written (this is still "work in progress").

New tests for the Oneiric 11.10 release are as follows:

mpcheck:
    Sanity check tables against the MultiProcessor Specification (MPS). For more information about MPS, see the wikipedia MPS page.

mpdump:
    Dump annotated MPS tables.

msr:
    Sanity check Model Specific Registers across all CPUs. Does some form of MSR default field sanity checking.

s3power:
    Very simple suspend (S3) power checks.  This puts the machine into suspend and attempts to measure the power consumed while suspended. Generally this test gives more accurate results the longer one suspends the machine.  Your mileage may vary on this test.

ebdadump:
     Hex dump of the Extended BIOS Data Area.

In addition to the above, the fwts "method" test is now expanded to evaluate and exercise over 90 ACPI objects and methods.

One can also join the fwts mailing list by going to the project page and subscribing.


Read more
Colin Ian King

Back in February I wrote about turning off a PC using the Intel I/O Controller Hub and had some example code to do this, and it was a dirty hack.  I've revised this code to be more aligned with how the Linux kernel does this, namely:

1. Cater for the possible existence of PM1b_EVT_BLK and PM1b_CNT_BLK registers.
2. Clear WAKE_STATUS before transitioning to S5
3. Instead of setting SLP_TYP and SLP_EN on, one sets SLP_TYPE and then finally sets SLP using separate writes.

The refined program requires 4 arguments, namely the port address of the PM1a_EVT_BLK, PM1b_EVT_BLK, PM1a_CNT_BLK and PM1b_CNT_BLK.  If the PM1b_* ports are not defined, then these should be 0.

To find these ports run either:

cat /proc/ioports | grep PM1

or do:

sudo fwts acpidump - | grep PM1 | grep Block:

For example, on a Sandybridge laptop, I have PM1a_EVT_BLK = 0x400, PM1a_CNT_BLK = 0x404 and the PM1b_* ports are not defined, so I use:

sudo ./halt 0x400 0 0x404 0

..and this will transition the laptop to the S5 state very quickly. Needless to say, make sure you have sync'd and/or unmounted your filesystems before doing this.

The PM1_* port addresses from /proc/ioport and the fwts acpidump come from the PM1* configuration data from the ACPI FACP, so if this is wrong, then powering down the machine won't work.  So, if you can't shutdown your machine using this example code then it's possible the FACP is wrong. At this point, one should sanity check the port addresses using the appropriate Southbridge data sheet for your machine - generally speaking look for:

PM1_STS—Power Management 1 Status Register (aka PM1a_EVT_BLK)
PM1_CNT—Power Management 1 Control  (aka PM1a_CNT_BLK)

..however these are offsets from PMBASE which are defined in the LPC Interface PCI Register Address Map so you may require a little bit of work to figure out the addresses of these registers on your hardware.


Read more
Colin Ian King

Firmware Test Suite for Ubuntu 11.04

The  Firmware Test Suite (fwts) is a tool I've been working on over the past few months that does automated testing of PC firmware.  The main aim is to check for errors in BIOS code and ACPI tables.  I have put most effort into ACPI testing as my analysis shows that it constitutes over 90% of firmware related errors reported against the kernel in LaunchPad.

Most of the key features for Ubuntu 11.04 are now in the Firmware Test Suite, so now seems an appropriate time to mention them.

Automated ACPI Method Testing.

The ACPI DSDT and SSDT tables contain ACPI Machine Language (AML) bytecode.  This code is executed by the Linux kernel by the ACPI driver and is an abstract interface between the operating system and the underlying machine hardware, such as the embedded controller, the closed proprietary BIOS and various hardware registers.   The AML can describe hardware layout and contains methods that operate in a manner that should conform to the ACPI specification.   For example, there are methods to handle power management,  thermal control, battery status and much more besides.   The main problem we face is when these implementations are buggy and may not conform to the specification.   The kernel can execute the AML code and so if the AML is broken you may get a machine that does not work correctly.

I've added a method test to fwts that will extract the AML byte code from the DSDT and then using the ACPICA execution engine run these in user space and check methods are returning the expected return types and in some cases (where appropriate) check expected return values.  Over 70 standard methods described in version 4.0a of the ACPI specification are sanity checked.  The code also checks mutex acquire/release counts to see if methods are incorrectly not releasing locks.

To run these test using 11.04 fwts, use:


sudo fwts method

..and the results are appended to the file results.log.  (One has to use sudo to be able to read the ACPI tables).

Another way to sanity check the AML code is to extract it, dis-assemble and then re-assemble it using the ACPICA iasl compiler.  A lot of AML is compiled using the Microsoft AML compiler and this appears to be less strict. Hence, recompiling with a more strict compiler can pick up errors.   The syntaxcheck test existed in fwts for Ubuntu 10.10, but I've re-worked this by integrating in the ACPICA core into the tool and then enhancing the error reporting.  For most error messages produced by the compiler fwts now also outputs 8 lines of disassembled code around the error (to provide context) and also outputs extra feedback advice.  This advice is based on looking at all the reasons why this error can be emitted by the compiler and explaining these with more context.

To run this test, use:

sudo fwts syntaxcheck

..again, output is appended to results.log

Since the ACPICA core is integrated in, we can also use this to easily dump out the disassembled AML byte code from all the ACPI tables.  To do so use:

sudo fwts --disassemble-aml

and the AML code for each table is dumped into files DSDT.dsl and SSDTn.dsl (where n is the Nth SSDT).  This is much easier than running acpixtract, acpidump and the iasl -d on the DSDT and SSDT tables.

The final ACPI table test added to fwts in Ubuntu 11.04 performs about 40 sanity checks on configuration data in common ACPI tables.  To run this test use:

sudo fwts acpitables
 
..and this checks various configurations, e.g. of HPET, SCI interrupt, GPE blocks, reset register + reset values, APIC flags, etc.

Although it's strictly not a test, fwts now includes a tool that will dump out the ACPI tables in an annotated form so that one can examine the configuration settings in a more human readable form than just looking at the raw data in a hex editor. To do use:

sudo fwts acpidump

UEFI

The Firmware Test Suite also needs to work on UEFI firmware based machines which are now becoming far more common.  I've re-worked some of the underlying code in fwts to work with UEFI and standard BIOS.  My next step is to extend fwts to add in more UEFI only tests, but this is still "work-in-progress".

Other goodness

As it is an evolving tool, fwts includes a lot more refinements (and bug fixes) compared the first cut that came out in Ubuntu 10.10.   The log format to be less verbose and there is the new "-" option that dumps the log straight to stdout rather than appending it to a log file.

To see all the tests built into fwts, you can use the "--show-tests-full" option, rather than the more terse option "--show-tests".  

Originally fwts ran silently and this caused some confusion as it was not obvious what was happening.  For Ubuntu 11.04  fwts now runs in verbose mode and reports a brief per test progress information.  The silent mode can be enabled using the "-q" or "--quiet" options.

One can also run the tool on dumped ACPI tables from other machines allowing to remotely diagnose bugs just from raw table data.  Dump the tables using:

sudo fwts --dump

..this produces a dump of kernel log, dmidecode, lspci and the ACPI tables. One can read in the ACPI tables into fwts and run appropriate ACPI specific tests on this data, e.g.

fwts --dumpfile=acpidump.log syntaxcheck method acpitables

There are many more refinements and minor new features.  I recommend reading the manual page to get more familiar with the tool.

To install fwts in Ubuntu 11.04 use:

sudo apt-get install fwts

Enjoy!

[ Update ]

I've written a fwts reference guide, available here: https://wiki.ubuntu.com/Kernel/Reference/fwts


Read more
Colin Ian King

Shutting down a PC is normally performed by transitioning the machine into an ACPI S5 state which is achieved by writing some magic value into an ACPI PM control register.  Implementing this is very straight forward once one has navigated a couple of rather information dense documents.

Armed with a copy of an Intel ICH manual one see that section 8.8.3.3 the PM1_CNT (Power Management 1 Control) register is the direct implementation of the ACPI PM1a_CNT_BLK register as described in section 4.7.3.2.1 of version 4.0 of the ACPI specification.


Bits 10:12 control the sleep state type (SLP_TYP), and setting these to 111 selects soft power off. To signal this, one has to set bit 13 to transition into the required sleep state.

On an Intel system, finding the PM1_CNT register is simple, use:

cat /proc/ioports | grep PM1a_CNT_BLK

..on my Dell 1525 this results in:

1004-1005 : ACPI PM1a_CNT_BLK

..so a soft shutdown can be invoked running the following code with root privileges:

#include <unistd.h>
#include <sys/io.h>
#include <stdint.h>
#include <stdio.h>

/* PM1 Sleep types */
#define SLP_ON       0
#define SLP_ST_PCLK  1
#define SLP_S3       5
#define SLP_S5       6
#define SLP_SOFT_OFF 7

int main(int argc, char **argv)
{
        uint16_t val;

        if (ioperm(0x1004, 2, 1) < 0) {
                printf("Cannot access port 0x1004\n");
                exit(0);
        }
        val = inw(0x1004);
        val &= ~(7 << 10); /* Clear SLP_TYPE */
        val |= (SLP_SOFT_OFF << 10); /* Soft power off */
        val |= (1 << 13);  /* Trigger SLP_EN */
        outw(val, 0x1004);
}

..this is akin to the Vulcan death grip, so make sure that one has sync'd and unmounted file systems first! It's quite impressive to see how quickly can shutdown a machine using this method.

Of course, more rugged implementation would be to determine the PM1a_CNT_BLK register from the Fixed ACPI Description Table (FADT), but happily for us Linux reports this register in /proc/ioports, so it's simple to do from user space.


Read more
Colin Ian King

Hacking a custom DSDT into a QEMU BIOS

Today I was trying to reproduce a bunch of weird ACPI errors when executing AML code from a DSDT extracted from a remote machine. For some reason the AML in the 2.6.32 kernel was causing a bunch of warnings, but not in 2.6.35 and I wanted to see when the fix landed. This was a dirty hack so that I could quickly do kernel bisects running the kernel inside QEMU.

Firstly, I got the DSDT from the remote machine and converted into it form that could be included into the seabios BIOS images. I used the following C source:


#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
int data;
int i = 0;

printf("unsigned char AmlCode[] = {");
for (i=0; (data = getchar()) != EOF; i++)
printf("%s%s0x%2.2x", i>0 ? "," : "",
(i & 7) ? "" : "\n\t", data);
printf("\n};\n");

exit(EXIT_SUCCESS);
}
And built it with:

gcc -Wall hexdump.c -o hexdump

Next I generated a C compilable hex dump of the DSDT.dat raw image:

./hexdump < DSDT.dat > acpi-dsdt.hex

Then I got the seabios sources:

git clone git://git.linuxtogo.org/home/kevin/seabios.git

and the copied the acpi-dsdt.hex to seabios/src

..and then cd into seabios and built using make. This creates bios.bin in the directory called out.

Then I copied the current QEMU bios, vgabios and seabios images to my working directory:

cp -R /usr/share/qemu /usr/share/vgabios /usr/share/seabios/ .

and then copied the compiled seabios image into the newly copied seabios directory:

cp seabios/out/bios.bin seabios

Finally, I ran QEMU using new BIOS image as follows:

qemu -L qemu ubuntu.img

Bit of a hack, but it helped when I did not have the hardware to hand.


Read more
Colin Ian King

The FirmWare Test Suite (fwts) is a tool I've been working on to do automatic testing of a PC's firmware. There can be a lot of subtle or vexing Linux Kernel/firmware issues caused when firmware is buggy, so it's useful to have a tool that can automatically check for common BIOS and ACPI errors. Where possible the tool will give some form of advice on how to fix issues or workaround firmware issues.

It's packaged up and in Maverick universe, you can install it using:

sudo apt-get install fwts

To see the tests available in the tool use:

fwts --show-tests

There are over 30 tests and I hope to expand this every time I find new firmware issues which can be diagnosed automatically in a tool.

To run a test use, for example the ACPI AML syntax checking test use:

sudo fwts syntaxcheck

There are categories of tests, for example, by default fwts will run batch mode tests which run without the need of user intervention. Some tests, such as checking the laptop lid works or hotkeys requires user intervention - these are interactive tests and can be invoked using:

sudo fwts --interactive

By default the tool will append the test results into a log file called results.log. This logs the date/time the test was run, the name of the test and the test results and hopefully some useful advice if a test fails.

I suggest checking out the manual page to see some examples how to fully drive this tool.

Quite a lot of the tests have been picked up from the core of linuxfirmwarekit.org, but I've added a bunch more tests, and expanded the types of errors it checks for and the feedback advice it reports. I've targeted fwts to run with the Maverick 2.6.35 kernel but it should work fine on Lucid kernels too. I've written fwts with command line driven test framework to run the tests mainly to allow fwts to easily plug into more powerful test frameworks.

If you want to run the tool from a bootable USB flash key, then one can download a i386 or amd64 image and dd it to a USB flash key.

For example:

wget http://kernel.ubuntu.com/~kernel-ppa/testing/maverick-desktop-i386-fwts.img
sudo dd if=maverick-desktop-i386-fwts.img of=/dev/sdX

where /dev/sdX is the block device of your USB flash key

then boot off this USB flash key and let it run the tests. At the end it will automatically shutdown the PC and you can then remove the key. The key has a FAT formatted partition containing the results of the test in a directory named: fwts/ddmmyyyy/hhmm/results.log, where ddmmyyyy are the digits in the date and hhmm for the time the test was started.

The fwts PPA can be found in the Firmware Testing Team project and the source code is available in a git repository here.

I've also written a short OpenOffice presentation on the tool which also may prove instructive.


Read more
Colin Ian King

Matthew Garrett wrote a particularly insightful explanation of how suspend/resume works in this article at Advogato. It makes an interesting read to see exactly what is going on and why things go wrong!


Read more
Colin Ian King

GPEs, Embedded Contoller and ACPI

I was poking around with a laptop lid problem a week ago and thought it would be helpful to document the way GPEs work with the Embedded controller and ACPI. An OpenOffice presentation can be found here.


Read more
Colin Ian King

Debugging ACPI using acpiexec

The acpiexec tool is an AML emulator that allows one to execute and interactively ACPI AML code from your BIOS.  The tarball can be downloaded from the ACPICA website  and built as follows:

1. Unzip and untar the acica-unix-20100304.tar.gz tarball.
2. cd into tools/acpiexec
3. run make

This should build acpiexec. Now for the fun part - executing your ACPI inside the emulator. To do this grab your ACPI tables and extract them using:

sudo acpidump > acpi.info && acpixtract -a acpi.info

Now load these tables into the emulator and run with verbose mode:

./acpiexec -v *.dat

Inside the emulator you can type help to navigate around the help system.  It may take a little bit of work to get familiar with all the commands available.

As a quick introduction, here is how to execute the battery information _BIF method.

1. Get a list of all the available methods, type:

methods

on my Lenovo laptop the battery information method is labelled \_SB_.PCI0.LPCB.BAT1._BIF, so to execute this method I use:

execute \_SB_.PCI0.LPCB.BAT1._BIF
Executing \_SB_.PCI0.LPCB.BAT1._BIF
Execution of \_SB_.PCI0.LPCB.BAT1._BIF returned object 0x19669d0 Buflen 178
  [Package] Contains 13 Elements:
    [Integer] = 0000000000000001
    [Integer] = 0000000000000FA0
    [Integer] = 0000000000000FA0
    [Integer] = 0000000000000001
    [Integer] = 0000000000002B5C
    [Integer] = 00000000000001A4
    [Integer] = 000000000000009C
    [Integer] = 0000000000000108
    [Integer] = 0000000000000EC4
    [String] Length 08 = PA3465U
    [String] Length 05 = 3658Q
    [String] Length 06 = Li-Ion
    [String] Length 07 = COMPAL

So far so good. I single stepped through the code using the debug command on the method as follows:

debug \_SB_.PCI0.LPCB.BAT1._BIF

at each % prompt, one can press enter to step the next instruction. If the method requires arguments, these can be passed into the method by specifying them after the method name from the debug command.

To see any local variables used during execution, use the locals command. The list command lists the current AML instructions. The set commands allows one to set method data and interact with the debugging processes.

Hopefully this gives one a taste of what the emulator can do. The internal help is enough to get one up and running, and one does generally require the current ACPI specification to figure out what's happening in your ACPI tables.


Read more
Colin Ian King

Simple ACPI monitoring tools

Back to basics - here are a couple of quick-and-easy tools for seeing ACPI activity on linux. The first is acpi_listen (from the acpid package) - this tool simply monitors ACPI events and dumps them to stdout:

$ acpi_listen
button/power PWRF 00000080 00000001
ac_adapter AC0 00000080 00000000

The above shows the events when I hit the power button and suspend a HP mini netbook.  One can specify the number of events to capture before exiting with the -c flag, and also the number of seconds to wait for with the -t flag. As things go, it's a handy sanity checking tool to make sure things like specific button events get handled correctly.

The next tool is acpitail - this periodically dumps out ACPI status about the battery, fan and temperature to stdout. One can specify the update polling intervals for checking state change using various flags.  To install use:

sudo apt-get install acpitail

and to use, simply run:

$ acpitail
Wed Jan 20 20:40:14 2010
BAT1 remaining capacity: 88% (126 minutes)
Adapter AC0: batteries
temperature THRM: 47 (ok)
Wed Jan 20 20:40:19 2010
temperature THRM: 46 (ok)
Wed Jan 20 20:40:29 2010
temperature THRM: 45 (ok)

..again, it's another simple tool to do some ACPI state sanity checking.


Read more
Colin Ian King

Most of the time when I'm looking at BIOS issues I just look at the disassembled ACPI DSDT using the following runes:

$ sudo cat /proc/acpi/dsdt > dstd.dat
$ iasl -d dstd.dat

..and look at the disassembly in dstd.dsl

Some BIOS bugs need a little more examination, and that's where I use acpidump + acpixtract. The simplest way to dump all the ACPI tables is as follows:

$ sudo acpidump > acpi.dat
$ acpixtract -a acpi.dat
Acpi table [DSDT] - 24564 bytes written to DSDT.dat
Acpi table [FACS] - 64 bytes written to FACS.dat
Acpi table [FACP] - 244 bytes written to FACP1.dat
Acpi table [APIC] - 104 bytes written to APIC1.dat
Acpi table [HPET] - 56 bytes written to HPET.dat
Acpi table [MCFG] - 60 bytes written to MCFG.dat
Acpi table [TCPA] - 50 bytes written to TCPA.dat
Acpi table [TMOR] - 38 bytes written to TMOR.dat
Acpi table [SLIC] - 374 bytes written to SLIC.dat
Acpi table [APIC] - 104 bytes written to APIC2.dat
Acpi table [BOOT] - 40 bytes written to BOOT.dat
Acpi table [SSDT] - 685 bytes written to SSDT1.dat
Acpi table [SSDT] - 163 bytes written to SSDT2.dat
Acpi table [SSDT] - 607 bytes written to SSDT3.dat
Acpi table [SSDT] - 166 bytes written to SSDT4.dat
Acpi table [SSDT] - 1254 bytes written to SSDT5.dat
Acpi table [XSDT] - 148 bytes written to XSDT.dat
Acpi table [FACP] - 116 bytes written to FACP2.dat
Acpi table [RSDT] - 88 bytes written to RSDT.dat
Acpi table [RSDP] - 36 bytes written to RSDP.dat

..this dumps out all the tables into files.

One can the disassemble the required file using iasl, e.g.:

$ iasl -d APIC1.dat

or decode the table using madt:

$ madt < ACPI1.dsl
ACPI: APIC (v001 INTEL CRESTLNE 0x06040000 LOHR 0x0000005a) @ 0x(nil)
ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
ACPI: LAPIC (acpi_id[0x01] lapic_id[0x01] enabled)
ACPI: IOAPIC (id[0x01] address[0xfec00000] global_irq_base[0x0])
ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
ACPI: LAPIC_NMI (acpi_id[0x00] high edge lint[0x1])
ACPI: LAPIC_NMI (acpi_id[0x01] high edge lint[0x1])
Length 104 OK
Checksum OK

Or to just get one particular table, I use:

$ sudo acpidump -t SSDT > SSDT.dat
$ acpixtract -a SSDT.dat
$ iasl -d SSDT.dat
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 SSDT.dat
Acpi table [SSDT] successfully installed and loaded
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
.........
Parsing completed
Disassembly completed, written to "SSDT.dsl"

Armed with a copy of the ACPI spec, one can then start digging into why there are weird Linux/BIOS interactions occurring.


Read more