[ANNOUNCE] ACPI BIOS Guideline for Linux

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

while arguing about current _OSI Linux implementation,
I realized this is complex and absolutely undocumented.

I started to write this up properly.
This was the point when I realized adding
some major general ACPI things OEMs should consider on
Linux is urgently missing and should get published.

Many thanks to Andi Kleen and Pavel Machek who already
reviewed an early version some weeks ago. I still changed
a lot since then (also corrected a lot considering your
corrections, thanks it probably was a lot work going through
this that detailed!).

I like to get as much feedback for this as possible.
Be sure I will go through this attentively and add or
modify whatever makes sense.

I mainly try to get feedback from OEMs and BIOS developers,
I am going to and I also like you to point to this. They
are the main audience for this paper.
Currently OEMs start to take care or at least look at Linux
for the future even in the laptop area (this is why every latest
ACPI BIOS checks whether Linux is running...).
This should give them a documentation and an overview for
what they should take care for. Until a BIOS hits the
customer takes a lot time, so they need stability and a
general policy they can count on.

You find the paper here:
ftp://ftp.suse.com/pub/people/trenn/ACPI_BIOS_on_Linux_guide/acpi_guideline_for_vendors.pdf

At the end are the sources of the original document for
better commenting of special parts of the document.

I am looking forward for a lot feedback.

Thanks,

            Thomas


\documentclass[10pt,a4paper]{article}

\usepackage{hyperref}
\usepackage[numbers]{natbib}

\title{ACPI BIOS Guideline for Linux}
\author{Thomas Renninger - Copyright SUSE Linux GmbH, 2008}


\begin{document}
\maketitle

\begin{abstract}
This specification is intended for PC hardware vendors and PC BIOS
developers. It documents and describes ACPI implementations of the
Linux kernel which are important for BIOS developers. Irregularities
to the ACPI specification are discussed. It outlines problems that may
happen on ACPI driven BIOSes on Linux and how to avoid them.
\end{abstract}

\newpage
\tableofcontents
\newpage

\section{Introduction}

Recently a lot PC hardware vendors have been started to offer Linux pre-loaded on
their hardware. Linux fully supports the ACPI specification version 2.0
and partly 3.0. There are still some pits vendors can fall in, which
can be avoided easily. This paper describes problems that could occur
with ACPI implementations on Linux.
It is intended to get input and feedback from vendors and programmers.
If you have any ideas to improve or expand this documentation, please send
suggestions to \href{mailto:trenn@xxxxxxx}{trenn@suse.de} or to the
linux-acpi mailing list [8].

\section{Vendor specific ACPI implementations}

Linux perfectly supports most ACPI specified devices
(e.g. ``battery'', ``battery vs. plugged-in status'', ``lid'',
``cpufreq frequency scaling (P-states)'', ``processor sleep states
(C-states)'' and a lot more).
Vendors often implement devices through ACPI which are not included
in the general ACPI or other specifications. For example buttons like wireless LAN
on/off switches, volume up/down and mute buttons and more.

Vendors provide a proprietary driver for Windows for such vendor
specific devices and in many cases there also is a re-engineered Linux driver
(e.g. asus\_acpi, sony\_acpi, thinkpad\_acpi and more). Those drivers are
often not complete and hard to maintain, so it is possible for example
for parts of the undocumented interface to change from one model to
another or, even worse, through a BIOS update. Vendors should:

\begin{enumerate}
\item
  Use devices described in the ACPI specification whenever
  possible.
\item
  If new devices or functions are introduced, document how to use
  them.
  A short specification or a request for comments (RFC) can be the
  basis of a new standard which is following your needs.
  Also do make use of a unique Hardare ID to describe the device and
  thus make it easy for the corresponding Linux driver to match and
  register for the device.
\item
  Support mainline developers. Open source developers are often not
  bound to a company. Most of the drivers implemented by open source
  developers are made for private use only, many of them do not fit
  other machines or models.
  Incentives like a trip to the next Linux symposium, a machine of
  their favorite hardware vendor or something like that is often a
  quick and cheap option to get the driver into a shape you would
  like to see it.
\item
  Provide an input channel (a mailinglist for example) to get
  feedback. This can be of big help to get informed about
  problems like breakage in upcoming Linux code. ACPI BIOS
  bugs likely affect your supported Microsoft operating system or an
  upcoming version also. It may happen that
  problems are already analyzed and debugged very detailed by open
  source developers. People may
  already point to a specific firmware bug which can ease up the search
  for BIOS developers to identify the problem and can save precious
  time until an update can be provided to the customer.
\end{enumerate}

\section{Avoid the use of the \_OSI function if possible}

\subsection{What is \_OSI and how is it used}
\_OSI is an ACPI method provided by the operating system that can be
invoked by ACPI BIOS code. It is used by BIOS developers
to detect which operating system is running. The method that should be
used (cmp. ACPI spec[1], chapter 5.7.2 and 5.7.3) is \_OS. But to
check for recent operating systems \_OSI is used to identify the
running OS for various reasons.

The intent of the \_OSI function is to identify features provided by
the OS. For example some BIOSes check for Vista which supports and
demands the latest ACPI backlight functions (compare ACPI spec Appendix
B).

But feature identification is an exception. In reality BIOS
developers use the \_OSI functionality to work around operating system
errors. If the
supported OS is a closed source one like Microsoft Windows, vendors
rely on the use of \_OSI to work around possibly upcoming OS specific
errors (for example through a Service Pack) via a BIOS update.

Vendors must not do this on Linux. If bugs in the Linux OS are
identified, vendors must make sure that the cause is fixed in the
Linux kernel. Linux does not have a strict OS versioning. The root cause
might get fixed in the latest upstream kernel and the workaround could
break there. Such fixes are often backported to distributions.
Therefore an identification(as it is common for Windows)
whether the underlying Linux operating system is affected by a
specific bug is not possible.
Here is an example of how a vendor wrongly fixed his ACPI BIOS
implementation and tried to workaround a Linux bug. It then broke
with more recent kernels after the bug got identified and fixed:
\href{http://bugzilla.kernel.org/show\_bug.cgi?id=7787}{http://bugzilla.kernel.org/show\_bug.cgi?id=7787}


\subsection{How \_OSI is implemented on Linux}

Since version 2.6.23 the mainline kernel does not return true for
\_OSI(``Linux'') BIOS invocations anymore.
The intent is to prevent BIOS
providers and kernel developers from a maintenance nightmare.
Linux specific implementations should never be needed.

The second ACPI specification violation is that the Linux kernel
returns true for all known Windows OS \_OSI
strings (compare with drivers/acpi/utilities/uteval.c in the kernel
sources for the recent list):
\begin{itemize}
\item
  ``Windows 2000'',         /* Windows 2000 */
\item
  ``Windows 2001'',         /* Windows XP */
\item
  ``Windows 2001 SP1'',     /* Windows XP SP1 */
\item
  ``Windows 2001 SP2'',     /* Windows XP SP2 */
\item
  ``Windows 2001.1'',       /* Windows Server 2003 */
\item
  ``Windows 2001.1 SP1'',
  
  /* Windows Server 2003 SP1 - Added 03/2006 */
\item
  ``Windows 2006'',         /* Windows Vista - Added 03/2006 */
\end{itemize}
Therefore it is currently not possible for BIOS developers to
identify that the machine is running on Linux.

The idea is to be compatible with the latest Microsoft operating
system. If people report bugs which come out to be operating system
specific bug workarounds, it is currently tried to adopt or better, be
compatible with these bugs of other operating systems.

There are several drawbacks with this implementation:
\begin{itemize}
\item
  Microsoft versions will change and can be fixed in future releases
  (this only applies for \_OSI specific workarounds)
  while the Linux implementation has to be compatible with all bugs
  that ever appeared in any Microsoft ACPI implementation.
\item
  Microsoft does return true for only one specific version string.
  This can lead to undefined code paths being executed on Linux where
  for all known Windows strings true is returned. For example
  the BIOS checks at initialization time for Windows XP and sets a
  specific variable, then it checks for Windows Vista and sets another
  variable.
  Now later ACPI code paths executed on Linux will be unwanted as
  Windows is probably only returning true for either Vista or XP.

  Vendors should check with else if clauses or use the same variable
  to store the results of \_OSI execution at initialisation time.
  Make sure the latest Windows versions are tested in the end and the
  latest Windows version (e.g. ``Windows 2006'', cmp. with above
  strings) returning true is used.
\item
  It is nearly impossible for vendors to follow all kernel versions
  in mainline and in distributions and to check what Windows strings
  are returned in which kernel version.
\item
  Vendors who care about Linux cannot guarantee proper support of
  Linux and Windows with the same BIOS without modifying the kernel
  slightly(see below for details). Especially if they are forced to
  implement Microsoft erratas through BIOS hot-fixes. Whether this is the
  case cannot be proven, but comparing a lot recent ACPI BIOS
  implementations harden the assumption that this is rather common.
\end{itemize}


\subsection{BIOS providers have to take care about \_OSI on Linux}

It is expected that vendors must add \_OSI hooks to workaround bugs in
other operating systems. If this is not the case, the use of \_OSI
should simply be avoided and everything works out fine.

On Linux, vendors must (instead of adding workarounds into the ACPI BIOS)
fix the Linux kernel or at least discuss and help to identify and fix
the problem for the latest mainline kernel. Then the needed necessary code
patches which fix the problem for the latest Linux kernel must be
backported to the kernels of the supported distributions. Like that
vendors can expect support from kernel developers and a quick solution
for the problem and they can make sure they do not run into
unmanageable maintenance problems (which are very likely to happen if
Linux kernel bugs get fixed in the BIOS).

Unfortunately vendors seem to depend on the \_OSI functionality and it
looks like as they have to provide OS specific BIOS hot-fixes to
guarantee support for Microsoft operating systems.
Because the Linux \_OSI implementation is currently
transparent to the Windows one, BIOS developers cannot distinguish
whether their code is running on Linux or on a Microsoft OS.
Hopefully this will change soon, but it needs a testing phase and will
take some time until such a change find its way into distributions.
Goal for Linux is to not return true for Windows OS strings.

The ``Linux'' OSI
keyword as stated in the ACPI specification ([1], cmp. with chapter 5.7.2)
already is and will stay obsolete in the future. It got removed in
kernel version 2.6.23. Vendors should not rely on Linux returning true
for this string.

For now, while Linux still is transparent to Microsoft Windows,
vendors have to patch the kernel of the distribution they claim to
support. (For example ``SLE 11'' string is used for SUSE Linux
Enterprise Server and Desktop version 11).

The above described osi=''Supported Linux Distribution'' string must
only be used to not execute operating system bug workarounds on a
Linux system. If for example a BIOS hotfix is required for Vista SP2, the
Linux kernel currently might also execute this code (depending on
whether the OS string has already been added to the kernel). In this
case add the condition not to execute this BIOS hotfix on your
supported Linux distributions to prevent them from breaking through the BIOS
update.

It is very important that vendors do not mis-use the ability to
distinguish between Linux and Microsoft Windows and workaround Linux
kernel bugs. Once a problem is identified to be a kernel bug, report
the problem on the linux-acpi mailing list (see links at the
end). ACPI kernel developers will provide and commit a fix for the
next mainline kernel. This fix must then eventually be backported to
the kernel of the supported distributions (if not already done).

Vendors must still make sure that their BIOS runs fine, even if
\_OSI(``Windows XY'') calls do not return true.
The problems outlined above show that for long-term, the only maintainable
solution for Linux is to not return true for Windows OS strings. While
such an interface change needs testing and some time to stabilize, BIOS
developers should keep in mind that this change could happen in
the future.


\section{WMI - Windows Management Instrumentation}

WMI is a Microsoft specific service. A small part of it
describes possible ACPI WMI implementations provided by the BIOS.
This is not part of the official ACPI specification and BIOS developers
should avoid using it. The Linux kernel driver supports basic WMI ACPI
functionality (since 2.6.25), but it is marked experimental.
ACPI functionality should not depend on the WMI interface.

\section {Post Video BIOS after Suspend to Ram}

Graphics drivers on Linux are located in userspace.
Therefore they cannot initialize the graphics device in the early
resume phase.
There are efforts to move necessary parts of the graphics device
drivers into the kernel, but this is complex and needs maturity to run
stable on all recent graphics devices.
Therefore the BIOS vendors still have to provide the legacy way of
graphics cards resuming and have to make sure the BIOS does ``post''
the video BIOS when resuming or at least make sure the operating
system can do so (by issuing ``lcall \$0xc000, 3''). Also regular software
interrupt calls (``int  \$0x10'') must work during resume from suspend
to ram.

\section{Check ACPI operation region declarations}

Sanity check ACPI operation region declarations and PNP resources.
ACPI operation region declarations define the IO port, memory and
other resources to control devices in BIOS through the ACPI language.
PNP resource declarations are bind to an ACPI device and reserve
resources to exclusively be used by an operating system driver which
serves and registers for this ACPI device.
Sometimes there exist several region
declarations for the same device or they partly overlap. This must
not happen. Resources must be declared or used exclusively by either
ACPI BIOS parts or system drivers. Neither Operation Region
declarations nor PNP resources nor both may overlap.

It is expected that some hardware vendors do get ACPI BIOS parts from
several external sources. ACPI BIOS templates for specific devcies may
be added to the BIOS. This makes it difficult for vendors to keep an
overview whether a device is addressed through ACPI parts themselves
or whether its resources are already be exported to an external driver
via PNP resources. If both is done, the device may be accessed through two
instances without any access coordination, which can lead to sever and
very hard to identify system instability problems.
The linuxfirmwarekit discussed below should be able
to identify most of such issues soon and could be of great help for
vendors to smoothly glue several ACPI parts together into one
integrated, sanity checked, ACPI aware BIOS.

\section{Miscellaneous}

\subsection{Smart Battery}

The Smart Battery specification should be avoided.
There were some hardware vendors, e.g. Acer, using the more complex
battery specification called ``Smart Battery'' (compare with ACPI
specification 10.1).
Linux provides a driver for it, but because there were not much BIOS
implementations using it, the driver is not well tested.
Instead of the Smart Battery Interface, make use of the ``Control
Method Batteries'' interface (compare with ACPI specification 10.2).

\subsection{Thermal Zones}

Make use of ACPI thermal zones.
Thermal control is important, and linux can do quite a good
job in this area. Provide thermal zones when you can (that will mean
linux can monitor temperatures inside case) and provide reasonable
passive trip points and polling intervals as specified by the ACPI
specification. With properly set up passive trip points, the machine
can continue working even with failed fan. This is very important for
servers.

\subsection{Always return valid values if possible}
Make sure sane figures are returned for all specified values of an
implemented ACPI device. For example the battery voltage is
sometimes wrong or the entity for the current (mAh vs mW) are mixed
up. While other applications may not need these values, Linux
applications could make use of them and show wrong values or even
shutdown or suspend the system wrongly when the remaining battery
capacity is not calculated correctly.

ACPI lacks the possibility to return error values.
This is a general problem for BIOS developers. If an error code path
has to be covered and it does not make sense to return a valid value
to the OS for the invoked function, then there is no possibility to
tell the OS about the error. Hopefully this will change in the future, for
now it is best to ask on the ACPI kernel developers list[6] what value
would be best to return for the specific problem.


\section{Get used to Intel's BIOS tools}

\subsection{ACPICA - ACPI Component Architecture}
\label{acpica}

While Microsoft uses its own proprietary, closed source ACPI compiler,
Linux does make use of Intel's \href{http://acpica.org} {ACPI Component
  Architecture}. The code base is used as ACPI parser and interpreter
inside the kernel, but it also provides a lot of easy-to-use tools for
general ACPI development and stability testing.

Most important for vendors is the iasl binary which can disassemble
and recompile raw ACPI tables provided by the BIOS. It uses the same
code base as the ACPI parser in the kernel. Therefore vendors should
check whether their ACPI implementation sticks to the ACPI
specification and works with the ACPICA tools (for an easy quick test,
see \ref{linuxfirmwarekit} below).

The Intel compiler is more strict.
Warnings often lead to general ACPI BIOS errors that may also affect
Microsoft Windows or other operating systems. Some may just point to
ACPI specification violations which the Microsoft compiler allows. The
Intel parser may also be able to cope with this code, but fixing such
violations is easy in most cases and makes the ACPI BIOS
implementation more robust against future operating system changes.
If in doubt whether a compiler warning is serious and how to fix it,
you may get help if you subscribe and ask on the
\href{http://www.acpica.org/mailman/listinfo/devel} {ACPICA developer
  mailing list}.

\subsection{Linuxfirmwarekit}
\label{linuxfirmwarekit}

Intel provides a tool to check the BIOS for Linux compatibility.
The tool is distribution independent.
A \href{http://www.linuxfirmwarekit.org/download.php#bootcd} {bootable
  CD image} can be downloaded from linuxfirmware.org.
Once the CD image is booted, the BIOS tests are started
automatically. One test is to disassemble the ACPI tables provided by
the BIOS and recompile them again with Intel's iasl ACPI compiler.
It may happen that there are misleading warnings. If in doubt, ask on
the acpica or linuxfirmwarekit mailing list (see chapter \ref{links}).

OpenSuSE and SLES provide the same test application on their
installation media. But the kernel used for booting and starting the
application is the same which is used by the SuSE distribution.
The BIOS test can be
chosen in the boot loader when booting the installation media or
invoked at runtime when the firmwarekit package is installed.

\section{Summary}
This section summerizes above discussed topics and shortly describes
keynotes, vendors should take care for to be able to ensure proper
ACPI Linux support.

\begin{itemize}
\item
  Avoid the use of ACPI WMI implementations.
\item
  Avoid \_OSI workarounds whenever possible.
\item
  If the supported Linux kernel is transparent to Windows, patch it
  so that it returns true for the specific OS the vendor claims to
  support. Only use this hook to not break the supported Linux
  distribution by Microsoft Windows specific bug workarounds.
\item
  Report any Linux bugs to the linux-acpi mailing list. Fix the bug in
  the source code of the supported Linux distribution (ask for help,
  this is open source software), do not fix such bugs in the BIOS or
  you end up in not being able to support future fixed Linux kernels
  with this BIOS.
\item
  Avoid the Smart Battery ACPI interface, use the more common Control
  Method Batteries interface.
\item
  Strictly implement the ACPI specification.
\item
  Use Intel's ACPICA compiler tools to detect ACPI Source Language
  syntax errors.
\item
  Use Intel's linuxfirmwarekit to detect general and already known
  BIOS errors.
\end{itemize}

\section{Useful Links and Mailing Lists}
\label{links}

\subsection{Links}
\begin{itemize}
\item
  [1] ACPI Specification (Used for this paper: version 3.0b, 2006)

      \href{http://www.acpi.info} {http://www.acpi.info}

\item
  [2] ACPI Component Architecture
  
      \href{http://acpica.org} {http://acpica.org}

\item
  [3] Linuxfirmwarekit
  
      \href{http://linuxfirmwarekit.org} {http://linuxfirmwarekit.org}

\item
  [4] Linux bug workaround in BIOS via \_OSI - A fix in the kernel
  broke it
  \href{http://bugzilla.kernel.org/show\_bug.cgi?id=7787}{http://bugzilla.kernel.org/show\_bug.cgi?id=7787}
 
\item
  [5] Kernel bug tracking system - Report problems there if you think you
      hit a kernel bug

  \href{http://bugzilla.kernel.org} {http://bugzilla.kernel.org}
  
\end{itemize}

\subsection{Mailing Lists}
\begin{itemize}
\item
  [6] ACPICA developer list
  
  \href{http://www.acpica.org/mailman/listinfo/devel} {http://www.acpica.org/mailman/listinfo/devel}
\item
  [7] Firmwarekit Developer and Discussion List
  
  \href{http://www.bughost.org/mailman/listinfo/firmwarekit-discuss}
       {http://www.bughost.org/mailman/listinfo/firmwarekit-discuss}
       
\item
   [8] ACPI kernel developer list
       
   \href{mailto:http://vger.kernel.org/majordomo-info.html?Body=Subscribe
     linux-acpi}
        {mailto:http://vger.kernel.org/majordomo-info.html?Body=Subscribe linux-acpi}
\end{itemize}

\Large
Disclaimer:
\normalsize
Trademarks and trade names may be used in this document to refer to
either the entities claiming the marks and names or their
products. The author of this document disclaims any proprietary
interest in trademarks and trade names other than its own.

\end{document}
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux