Canonical Voices

Posts tagged with 'acpi'

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