ACPI is a fundamentally new way of discovering devices, managing power usage, and providing standardized access to various hardware previously managed by the BIOS. Progress is being made toward ACPI working on all systems, but bugs in some motherboards' ACPI Machine Language (AML) bytecode, incompleteness in FreeBSD's kernel subsystems, and bugs in the Intel® ACPI-CA interpreter continue to appear.
This section is intended to help users assist the FreeBSD ACPI maintainers in identifying the root cause of problems and in debugging and developing a solution.
Before submitting a problem, ensure the latest BIOS version is installed and, if available, the embedded controller firmware version.
When submitting a problem, send the following information to freebsd-acpi@FreeBSD.org:
Description of the buggy behavior, including system type and model and anything that causes the bug to appear. Note as accurately as possible when the bug began occurring if it is new.
The output of dmesg(8) after running
boot -v
, including any error messages
generated by the bug.
The dmesg(8) output from boot
-v
with ACPI disabled,
if disabling it helps to fix the problem.
Output from sysctl hw.acpi
. This
lists which features the system offers.
The URL to a pasted version of the ACPI Source Language (ASL). Do not send the ASL directly to the list as it can be very large. Generate a copy of the ASL by running this command:
#
acpidump -dt > name
-system
.asl
Substitute the login name for
name
and manufacturer/model for
system
. For example, use
njl-FooCo6000.asl
.
Most FreeBSD developers watch FreeBSD-CURRENT mailing list, but one should submit problems to freebsd-acpi to be sure it is seen. Be patient when waiting for a response. If the bug is not immediately apparent, submit a PR using send-pr(1). When entering a PR, include the same information as requested above. This helps developers to track the problem and resolve it. Do not send a PR without emailing freebsd-acpi first as it is likely that the problem has been reported before.
ACPI is present in all modern computers that conform to the ia32 (x86), ia64 (Itanium), and amd64 (AMD) architectures. The full standard has many features including CPU performance management, power planes control, thermal zones, various battery systems, embedded controllers, and bus enumeration. Most systems implement less than the full standard. For instance, a desktop system usually only implements bus enumeration while a laptop might have cooling and battery management support as well. Laptops also have suspend and resume, with their own associated complexity.
An ACPI-compliant system has various components. The BIOS and chipset vendors provide various fixed tables, such as FADT, in memory that specify things like the APIC map (used for SMP), config registers, and simple configuration values. Additionally, a bytecode table, the Differentiated System Description Table DSDT, specifies a tree-like name space of devices and methods.
The ACPI driver must parse the fixed
tables, implement an interpreter for the bytecode, and modify
device drivers and the kernel to accept information from the
ACPI subsystem. For FreeBSD, Intel® has
provided an interpreter (ACPI-CA) that is
shared with Linux® and NetBSD. The path to the
ACPI-CA source code is src/sys/contrib/dev/acpica
.
The glue code that allows ACPI-CA to work
on FreeBSD is in src/sys/dev/acpica/Osd
.
Finally, drivers that implement various
ACPI devices are found in src/sys/dev/acpica
.
For ACPI to work correctly, all the parts have to work correctly. Here are some common problems, in order of frequency of appearance, and some possible workarounds or fixes.
In some cases, resuming from a suspend operation will
cause the mouse to fail. A known work around is to add
hint.psm.0.flags="0x3000"
to
/boot/loader.conf
. If this does not
work, consider sending a bug report using
send-pr(1).
ACPI has three suspend to
RAM (STR) states,
S1
-S3
, and one suspend
to disk state (STD
), called
S4
. S5
is
“soft off” and is the normal state the system
is in when plugged in but not powered up.
S4
can be implemented in two separate
ways. S4
BIOS is a
BIOS-assisted suspend to disk.
S4
OS is implemented
entirely by the operating system.
Start by checking sysctl hw.acpi
for the suspend-related items. Here are the results for a
Thinkpad:
Use acpiconf -s
to test
S3
,
S4
OS, and
S5
. An s4bios
of one
(1
), indicates
S4
BIOS support instead
of S4
OS.
When testing suspend/resume, start with
S1
, if supported. This state is most
likely to work since it does not require much driver
support. No one has implemented S2
,
which is similar to S1
. Next, try
S3
. This is the deepest
STR state and requires a lot of driver
support to properly reinitialize the hardware. If there are
problems resuming, email freebsd-acpi. However, the
problem may not be resolved quickly since due to the amount
of drivers and hardware that need more testing and
work.
A common problem with suspend/resume is that many device drivers do not save, restore, or reinitialize their firmware, registers, or device memory properly. As a first attempt at debugging the problem, try:
#
sysctl debug.bootverbose=1
#
sysctl debug.acpi.suspend_bounce=1
#
acpiconf -s 3
This test emulates the suspend/resume cycle of all
device drivers without actually going into
S3
state. In some cases, problems such
as losing firmware state, device watchdog time out, and
retrying forever, can be captured with this method. Note
that the system will not really enter S3
state, which means devices may not lose power, and many
will work fine even if suspend/resume methods are totally
missing, unlike real S3
state.
Harder cases require additional hardware, such as a serial port and cable for debugging through a serial console, a Firewire port and cable for using dcons(4), and kernel debugging skills.
To help isolate the problem, remove as many drivers
from the kernel as possible. If it works, narrow down which
driver is the problem by loading drivers until it fails
again. Typically, binary drivers like
nvidia.ko
, display drivers, and
USB will have the most problems while
Ethernet interfaces usually work fine. If drivers can be
properly loaded and unloaded, automate this by putting the
appropriate commands in
/etc/rc.suspend
and
/etc/rc.resume
.
Try setting hw.acpi.reset_video
to
0
if the display is messed up after
resume. Try setting longer or shorter values for
hw.acpi.sleep_delay
to see if that
helps.
Try loading a recent Linux® distribution to see if suspend/resume works on the same hardware. If it works on Linux®, it is likely a FreeBSD driver problem. Narrowing down which driver causes the problem will assist developers in fixing the problem. Since the ACPI maintainers rarely maintain other drivers, such as sound or ATA, any driver problems should also be posted to the freebsd-current list and mailed to the driver maintainer. Advanced users can include debugging printf(3)s in a problematic driver to track down where in its resume function it hangs.
Finally, try disabling ACPI and enabling APM instead. If suspend/resume works with APM, stick with APM, especially on older hardware (pre-2000). It took vendors a while to get ACPI support correct and older hardware is more likely to have BIOS problems with ACPI.
Most system hangs are a result of lost interrupts or an interrupt storm. Chipsets may have problems based on boot, how the BIOS configures interrupts before correctness of the APIC (MADT) table, and routing of the System Control Interrupt (SCI).
Interrupt storms can be distinguished from lost
interrupts by checking the output of
vmstat -i
and looking at the line that
has acpi0
. If the counter is increasing
at more than a couple per second, there is an interrupt
storm. If the system appears hung, try breaking to
DDB (CTRL+ALT+ESC on console) and type
show interrupts
.
When dealing with interrupt problems, try disabling
APIC support with
hint.apic.0.disabled="1"
in
/boot/loader.conf
.
Panics are relatively rare for ACPI
and are the top priority to be fixed. The first step is to
isolate the steps to reproduce the panic, if possible, and
get a backtrace. Follow the advice for enabling
options DDB
and setting up a serial
console in Section 26.6.5.3, “Entering the DDB Debugger from the Serial Line” or setting
up a dump(8) partition. To get a backtrace in
DDB, use tr
. When
handwriting the backtrace, get at least the last five
and the top five lines in the trace.
Then, try to isolate the problem by booting with
ACPI disabled. If that works, isolate
the ACPI subsystem by using various
values of debug.acpi.disable
. See
acpi(4) for some examples.
First, try setting
hw.acpi.disable_on_poweroff="0"
in
loader.conf(5). This keeps ACPI
from disabling various events during the shutdown process.
Some systems need this value set to 1
(the default) for the same reason. This usually fixes the
problem of a system powering up spontaneously after a
suspend or poweroff.
For other problems with ACPI, such as it not working with a docking station or devices not being detected, email a description to freebsd-acpi. Some issues may be related to unfinished parts of the ACPI subsystem which might take a while to be implemented. Be patient and prepared to test patches.
Some BIOS vendors provide incorrect or buggy bytecode. This is usually manifested by kernel console messages like this:
Often, these problems may be resolved by updating the
BIOS to the latest revision. Most console
messages are harmless, but if there are other problems like
the battery status is not working, these messages are a
good place to start looking for problems. The bytecode,
known as AML, is compiled from a source
language called ASL. The
AML is found in the table known as the
DSDT. To get a copy of the system's
ASL, use acpidump(8). Include both
-t
, to show the contents of the fixed tables,
and -d
, to disassemble the
AML. Refer to
Section 12.17.1, “Submitting Debugging Information” for an example
syntax.
The simplest first check is to recompile the ASL to check for errors. Warnings can usually be ignored, but errors are bugs that will usually prevent ACPI from working correctly. To recompile the ASL, issue the following command:
#
iasl your.asl
The goal of FreeBSD is for everyone to have working
ACPI without any user intervention. At
this point, workarounds are still being developed for common
mistakes made by BIOS vendors. The
Microsoft® interpreter (acpi.sys
and
acpiec.sys
) does not strictly check for
adherence to the standard, and thus many
BIOS vendors who only test
ACPI under Windows® never fix their
ASL. FreeBSD developers continue to identify
and document which non-standard behavior is allowed by
Microsoft®'s interpreter and replicate it so that FreeBSD can
work without forcing users to fix the ASL.
As a workaround, and to help identify behavior, fix the
ASL manually. If this works, send a
diff(1) of the old and new ASL so
developers can possibly work around the buggy behavior in
ACPI-CA.
Here is a list of common error messages, their cause, and how to fix them:
Some AML versions assume the user is
running Windows®. To override this, set
hw.acpi.osname=
in
"Windows
2001"
/boot/loader.conf
, using the strings
in the ASL.
Some methods do not explicitly return a value as the
standard requires. While ACPI-CA
does not handle this, FreeBSD has a workaround that allows it
to return the value implicitly. Explicit return statements
can be added where required if the value which should be
returned is known. To force iasl(8) to compile the
ASL, use the -f
flag.
After customizing your.asl
, compile
it with this command:
#
iasl your.asl
Adding the -f
flag forces creation
of the AML, even if there are errors
during compilation. Some errors, such as missing return
statements, are automatically worked around by the
interpreter.
The default output filename for iasl(8) is
DSDT.aml
. Load this file instead of
the BIOS's buggy copy, which is still
present in flash memory, by editing
/boot/loader.conf
as follows:
Be sure to copy DSDT.aml
to
/boot
.
The ACPI driver has a flexible debugging facility. A set of subsystems and the level of verbosity can be specified. The subsystems to debug are specified as “layers” and are broken down into ACPI-CA components (ACPI_ALL_COMPONENTS) and ACPI hardware support (ACPI_ALL_DRIVERS). The verbosity of debugging output is specified as the “level” and ranges from ACPI_LV_ERROR (just report errors) to ACPI_LV_VERBOSE (everything). The “level” is a bitmask so multiple options can be set at once, separated by spaces. In practice, a serial console should be used to log the output so it is not lost as the console message buffer flushes. A full list of the individual layers and levels is found in acpi(4).
Debugging output is not enabled by default. To enable it,
add options ACPI_DEBUG
to the kernel
configuration file if ACPI is compiled into
the kernel. Add ACPI_DEBUG=1
to
/etc/make.conf
to enable it globally.
If it is a module, recompile just the
acpi.ko
module as follows:
#
cd /sys/modules/acpi/acpi
&& make clean &&
make ACPI_DEBUG=1
Install acpi.ko
in /boot/kernel
and add the
desired level and layer to
/boot/loader.conf
. This example enables
debug messages for all ACPI-CA components
and all ACPI hardware drivers such as
(CPU and LID. It only
outputs error messages at the least verbose level.
If the required information is triggered by a specific
event, such as a suspend and then resume, leave out changes to
/boot/loader.conf
and instead use
sysctl(8) to specify the layer and level after booting
and preparing the system for the specific event. The
variables which can be set using sysctl(8) are named
the same as the tunables in
/boot/loader.conf
.
More information about ACPI may be found in the following locations:
The ACPI Mailing List Archives http://lists.freebsd.org/pipermail/freebsd-acpi/
The old ACPI Mailing List Archives http://home.jp.FreeBSD.org/mail-list/acpi-jp/
The ACPI 2.0 Specification http://acpi.info/spec.htm
acpi(4), acpi_thermal(4), acpidump(8), iasl(8), and acpidb(8)
All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.