Showing posts with label ACPI. Show all posts
Showing posts with label ACPI. Show all posts

Monday, May 13, 2019

ACPI Debugging (4) -Analyse ACPI Tables in a Text File with FWTS

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 verify 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 from a text file
 $ fwts method --dumpfile=acpidump.log

or

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

where acpidump.log contains ACPI tables' binary in a specific format as depicted below:
  • Table Signature - the 4-byte long ACPI table signature
  • Offset - data start from 0000 and increase 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 following commands generate the 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

This means it is probable to debug remote systems by the following steps: 1) run sudo acpidump > acpidump.log, 2) copy acpidump.log and 3) run fwts with the --dumpfile=acpidump.log.

For developers, using --dumpfile option also means it is possible to test ACPI tables before deploying them on real hardware. The following sections present how to prepare a customized acpidump.log for such purposes.

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 for the method test.

1. Generate a dummy FACP table

FWTS requires a FACP table in an acpidump.log so it can recognize acpidump.log as a valid input file.

  1. iasl -T FACP
  2. iasl facp.asl > /dev/zero
  3. echo "FACP @ 0x0000000000000000" >> acpidump.log
  4. xxd -c 16 -g 1 facp.aml  | sed 's/^0000/    /' >> acpidump.log
  5. echo "" >> acpidump.log
2. Generate a Customized DSDT table

A customized DSDT can be generated by the following commands
  1. Generate a DSDT -  run "iasl -T DSDT"
  2. Customize dsdt.asl - ex. adding an ACPI battery device

3. Compile the DSDT table to binary

Similar to FACP, the DSDT can be compiled and appended to acpidump.log.
  1. iasl dsdt.asl > /dev/zero
  2. echo "DSDT @ 0x0000000000000000" >> acpidump.log
  3. xxd -c 16 -g 1 dsdt.aml  | sed 's/^0000/    /' >> acpidump.log
  4. echo "" >> acpidump.log

3. Run FWTS method with acpidump.log

And finally, run fwts with the generated acpidump.log

  • 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 updates in recent ACPI specs, and Firmware Test Suite includes most, if not all, changes up-to-date; therefore, FWTS is able to detect errors before firmware developers integrate HMAT into their projects, and therefore reduce errors in final products.

Friday, February 1, 2019

ACPI Debugging (3) - Debug ACPI Tables with Firmware Test Suite (FWTS)

Previous two articles, ACPI AML Debugger in Ubuntu 18.04 & Debug AML (DSD & SSDT) with ACPICA Utilities, discuss techniques for AML debugging; however ACPI specification includes many other important tables. Firmware Test Suite (FWTS) can play a big role in debugging ACPI implementation.

While other ACPI tables include fixed fields and lengths, it doesn't mean their contents cannot go wrong. In fact, many systems have many incorrect ACPI tables in their firmware. This can happen when systems are developed by integrating code from various parties without being modified specifically for 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 also mention it is freely available too?) and it is the recommended ACPI SCT by UEFI forum, who is the owner of the specification.

What is Firmware Test Suite (FWTS) ?

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

More information can be found at its official website.

Installing FWTS

Installation for Ubuntu Linux is as below:
  1. Add stable PPA for latest FWTS (optional) - sudo add-apt-repository ppa:firmware-testing-team/ppa-fwts-stable
  2. Install FWTS - sudo apt install fwts
FWTS packages for Other Linux distros can be found here.

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


More test details can be found on its references.

Running Multiple Tests


FWTS can also run multiple tests by appending tests one after another as below:



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...

FWTS is used for real projects. Here are some examples of tests we have run.

Checking FADT


Running fadt includes 6 tests that check whether system firmware/BIOS implements FACP table correctly.

Especially, the sizes of FACP table grow with ACPI specs, but some firmware/BIOS updates the FACP major and minor versions without adding the new fields in later ACPI spec. This can be caught by FWTS with ease. An example is Test 3 in results.log shown below.


 

Checking Table Checksum

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

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


Next Topic...

FWTS can analyze ACPI tables from other systems. This can be done with fwts --dumpfile=acpidump.log. More details will be discussed in the next blog.

Thursday, January 10, 2019

ACPI Debugging (2) - Debug AML (DSDT & SSDT) with ACPICA Utilities

Using acpidbg on Ubuntu 18.04 x64 can be quite handy; however, the Linux kernel with ACPI_DEBUGGER is not always available, such as on Ubuntu for ARM. In such cases, acpica also provides a set of utilities, named acpica-tools, for ACPI debugging.

Installation

The acpica-tools can be installed by
  •  sudo apt install acpica-tool
The latest source code can be downloaded from either of below, and it can be compiled and installed by “make” followed by “sudo make install“.
  • Windows: https://acpica.org/downloads/binary-tools
  • Ubuntu: sudo apt install acpica-tool

ACPICA Tools

The acpica-tools consist of the following utilities: acpibin, acpiexamples, acpihelp, acpisrc, iasl, acpidump, acpiexec, acpinames and acpixtract. This article focuses on how to use iasl, acpidump, acpiexec and acpixtract because they are commonly used in debugging.
  • acpidump - collect ACPI tables from a running system
  • acpixtract - extract ACPI tables from an acpidump file
  • acpiexec - emulate ACPI tables from extracted acpi tables
  • iasl - compile & disassemble ACPI tables

A Case Study - Airplane Mode

The airplane-mode button on laptops is usually implemented by both system BIOS and an OS driver. More specifically, it requires an ACPI device to be “present” in DSDT (or SSDT) table and a corresponding device driver. The figure below demonstrates how to debug if the airplane mode button fails to work.



Each computer brand has its specific implementation(s) and corresponding device driver(s). Some examples are listed below. Similarly, other driver source code can be found in Linux kernel.
  • Acer - acer-wireless
  • ASUS - asus-wireless
  • Dell - dell-rbtn, intel-hid, intel-vbtn
  • HP - hp-wireless
  • Lenovo - idealpad-laptop, thinkpad_acpi
  • Xiaomi - hp-wireless

Let’s use a Dell system as an example but the same technique also applies for others. To understand whether the airplane mode driver is loaded, one can run



As expected, the intel-hid is used on this particular Dell system.

As seen above, the “intel-hid” is used on this particular Dell system.
Let’s assume we know intel-hid is supposed to be used on this Dell system but it is not loaded for now. We can debug BIOS ASL/AML code using ACPICA utilities following the below steps.

Find Out ACPI Device's (intel-hid's) Hardware ID


A quick online search shows intel-hid.c is for an ACPI device with _HID “INT33D5”.

Extract and Disassemble ACPI Tables

  • Get all ACPI tables: sudo acpidump > acpi.log
  • Extract DSDT and SSDT: acpixtract acpi.log
  • Disassemble tables: iasl -d *.dat

Check Whether INT33D5 is "Present"

  • Find INT33D5 in DSDT or SSDT: grep INT33DT *.dsl

Once found, let's use vi to see more details in DSDT such as the device name (HIDD) as below:


  • Check device status, i.e. Method (_STA)
In addition to the device declaration, Linux ACPI device driver is loaded when _STA returns “present”. As in the above ASL code, _STA can be present (return 0x0F) or absent (return Zero). One can continue to trace OIDE() -> OSID() and so on to find out what _STA returns.

Alternatively, using acpiexec is easier for this task.

Evaluate _SB.HIDD._STA with acpiexec


Using acpiexec is the same as acpidbg, but it loads ACPI tables from files and runs AML in emulation mode, i.e. it does not touch hardware registers or actual memory.

  • Load ACPI tables: acpiexec *.dat
  • Find HIDD path: find HIDD
  • Execute HIDD's _STA: execute _SB.HIDD._STA
If _SB.HIDD._STA returns 0xF but intel-hid is not loaded, something is wrong with Linux kernel, ex. intel-hid is not compiled or is blacklisted. In this case, this should be forwarded to a Linux kernel engineer.

If _SB.HIDD._STA returns 0, we can continue to use acpiexec to find out OIDE() returns. In fact, we can use acpiexec to trace _SB._HIDD._STA
  • Trace _SB.HIDD._STA: debug _SB.HIDD._STA
Tutorial of using acpiexec is the same as acpidbg and can be found in the previous blog.

Final Words

ACPICA tools are very useful for debugging ACPI bugs, and using it well can save much time. This tutorial touches surface of what ACPICA tools can do and more documents can be found on acpica.org website.

Tuesday, May 1, 2018

ACPI Debugging (1) - ACPI AML Runtime Debugger in Ubuntu 18.04 (x64)

ACPICA is an open-source project that provides an operating system (OS)-independent reference implementation. It also contains a list of utilities such as ASL compiler (iasl), acpiexec (an AML emulator) and so on. However, debugging AML on Linux in runtime wasn't provided in ACPICA ... not until Linux Kernel 4.13.

Enabling AML Debugging


The aml-debugger.txt, the instruction for enabling AML runtime debugger, is available at Documentation/acpi/ in Linux kernel source code. In short, two things are required for AML runtime debugging
  • Enable AML debugging (CONFIG_ACPI_DEBUGGER=y & CONFIG_ACPI_DEBUGGER_USER=m) when compiling Linux kernel
  • Compile an utility, acpidbg from Linux kernel (I uploaded a copy here)
While compiling a custom-build kernel is nothing new to kernel developers, it is often inconvenient for system firmware / BIOS developers who need to verify ACPI AML implementation in their firmware. Fortunately, Ubuntu 18.04 (x64) and later enable these config by default, and one can simply execute acpidbg on Ubuntu 18.04 - even on Ubuntu Live from USB too!

Running AML Debugging


Executing acpidbg on Ubuntu 18.04 (x64) is straight-forward


and "help" shows a list supported commands



Examples


acpidbg is particularly handy when one needs to evaluate any ACPI AML objects during runtime - especially ones that change under different conditions. This may be explained by some examples below:

Example 1 - To determine AC power status in runtime.
  1. Find _PSR objects
  2. Evaluate _PSR when AC is disconnected
  3. Evaluate _PSR when AC is connected.


acpidbg also works with complex objects such as packages.
Example 2 - To determine battery information and status.
  1. Find _BIF and _BST objects
  2. Evaluate _BIF and _BST objects (note _BST changes dynamically).


acpidbg can decode bit fields and save time on counting bits. Try to run acpidbg to evaluate any _PLD objects and you will see what I mean :).

Wednesday, November 22, 2017

[Presentation] Firmware Test Suite - Uses, Development, Contribution and GPL

I did a presentation of "Firmware Test Suite - Uses, Development, Contribution and GPL" in UEFI Plugfest in Taipei on Nov 1 2017. The presentation is shared @ slideshare and can be viewed below:

Monday, July 10, 2017

Changes of the _OSI object in ACPI spec 6.1a & 6.2 and in Linux

ACPI _OSI is the most controversial object in my opinions. Not only _OSI was not welcomed by Linux kernel but also it has been discussed multiple times in ACPI Spec Work Group (ASWG) meetings. Many spec contributers tried to remove _OSI from ACPI spec, but the impacts were too great to depreciate _OSI...

Until _OSI is now redefined in ACPI 6.1a & ACPI 6.2 as below



Still confused? Let's take a look at "Table 5-163 Predefined Operating System Vendor String Prefixes" in ACPI 6.1a below:

Operating System Vendor String Prefix Description
“FreeBSD” <FeatureGroupString> Free BSD OS features/interfaces
“HP-UX” <FeatureGroupString> HP Unix Operating Environment OS features/interfaces
“Linux” <FeatureGroupString> GNU/Linux Operating system OS features/interfaces
“OpenVMS” <FeatureGroupString> HP OpenVMS Operating Environment OS features/interfaces
“Windows” <FeatureGroupString> Microsoft Windows OS features/interfaces

While <FeatureGroupString> looks like something new, this addition is backward-compatible - it is very common to see "Windows 2009" (Windows 7), "Windows 2013" (Windows 8.1) and "Windows 2015" (Windows 10). 2009, 2013 and 2015 are sets of new features provided by each new Windows OS and is more than a name of each new OS. Does this make sense?

In fact, the main purpose of this _OSI change is to clarify "_OSI is not to be used to detect operating systems but feature sets supported by operating systems" - these aren't my words but the words of spec contributers in ASWG's meetings. In other words, please stop complaining why OSI("Linux") doesn't work - this usage is never the intention of ACPI spec.

While _OSI("Linux") does NOT  work in Linux kernel by default, kernel maintainers now agree Linux isn't always compatible with Windows and using _OSI("Windows xxxx") isn't the best idea. Each OEM can define different "Linux <FeatureGroupString>" in their ACPI BIOS, and OEM can submit patches so new strings will be recognized by Linux kernel.

The string should be in the format "Linux-OEM-my_interface_name" as defined here. I would guess a valid string can be something like "Linux-Dell-SuperVGA" or "Linux-HP-CrystalAudio" (I made them up, and they aren't recognized by Linux kernel). The kernel document discusses the history and the rules, and BIOS engineers should not abuse this mechanism - if you want to a workaround, create a new string for it, ex. "Linux-Dell-VGA-Workaround" and submit a new patch to Linux kernel. DO NOT use unrelated OEM strings for other purposes.

The new _OSI is introduced for very short time and no ACPI BIOS uses new Linux strings yet. It is our hope this can provide better compatibilities between ACPI BIOS and non-Windows OS's. If anyone has any feedbacks or concerns about this new _OSI thing, I am happy to answer or forward to ACPI Work Group for more discussion.

Friday, July 7, 2017

Why cannot ACPI _REV object be used to detect Linux anymore?

Linux community is never a fan of distinguishing Windows & Linux in BIOS (see my 2012's blog Why does Linux Say It Is not Linux in _OSI("Linux")?). However, many BIOS engineers seem to see the needs of to workaround BIOS bugs for Linux regardlessly. After realising _OSI("Linux") cannot be used by default, some creative BIOS engineers figured ACPI's _REV object could be used for this purpose some years ago, based on the following facts:

1. _REV definition in ACPI spec 5.1


2. Windows returns 2 & Linux returns ACPI revision


While it is obvious it was Windows which did not follow ACPI spec, nothing can stop BIOS engineers from mis-using _REV as a mechanism to detect Linux in BIOS ASL codes.

It did not take long when ACPI Spec Work Group (ASWG), the owner and the publisher of ACPI spec, realised that many systems are mis-using _REV objects in their firmware. Eventually a spec contributer submitted a change to _REV object in ACPI 6.0 and later, and the _REV object is now defined as below:



After ACPI 6.0 was published, the corresponding changes are also made to Linux kernel - the evaluation of _REV now returns 2 in kernel 4.1 and later (for example, Ubuntu 15.10 with kernel 4.2).

In order to provide backward compatibility, a new kernel parameter "acpi_rev_override" was introduced for those who still want to use _REV = 5 in their BIOS ASL code, but most of major Linux distributions do not include this kernel parameter by default, and it should be used with cautions.

If you are using one of the systems with _REV in the firmware, you can develop a kernel patch to add your system to the _REV quirk list acpi_rev_dmi_table in drivers/acpi/blacklist.c as below, like the patch I submitted.

static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
        {
         .callback = dmi_enable_rev_override,
         .ident = "DELL XPS 13 (2015)",
         .matches = {
                      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
                      DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
                },
        },
        ...
  • DMI_SYS_VENDOR can be identified by sudo dmidecode -s system-manufacturer 
  • DMI_PRODUCT_NAME can be identified by sudo dmidecode -s system-product-name.

Monday, November 11, 2013

[Presentation] BIOS, Linux and Firmware Test Suite in-between

I was invited to present "BIOS, Linux and Firmware Test Suite in-between" in Debian Taiwan's MiniDeb Conf in Taipei, Taiwan on Nov 9, 2013. The presentation is shared @ slideshare and can be viewed below:



Firmware Test Suite is an ongoing project that targets to automate firmware and hardware related tests. It receives some attentions from various parties including hardware, software and system vendors. (I also presented the similar topic in UEFI Plugfest in Sept, 2013, and the presentation slides are available @ http://uefi.org/learning_center/presentationsandvideos).

Friday, August 30, 2013

Info Session: Improving BIOS Compatibility on Linux

I had a chance to present a BIOS-related topic "Improving BIOS Compatibility on Linux" in workplace, and the presentation is publicly available. Hope it may interest someone. :-)



Tuesday, July 2, 2013

ACPI AC Adapter (2) - How does Linux handle it?

ACPI AC Adapter Implementation in Linux Kernel

ACPI AC Adapter (1) introduced the theory of interfaces between BIOS and an OS, but a real example is always more convincing than anything else.

SysFs Node

In Linux, one can find out whether a laptop PC has AC plugged in by "cat /sys/class/power_supply/online". Linux ACPI AC driver evaluates _PSR and returns 1 for "AC is online" and 0 for "AC is offline". The sysfs node is also used by user-space applications.

Supported Objects

Surprisingly (or not), not all control methods defined in ACPI AC are supported. In fact, only _PSR is evaluated in Linux ACPI AC driver.

As ACPI covers very broad and rich features, kernel developers may find some of them "uninteresting". For example. _PSR is required, in software's perspective, to know whether AC is online, but which parts of a system is powered (i.e. _PCL) may not be that useful for laptop PCs (which AC usually powers everything). In some other cases, few BIOS implements _PIF and there is hardly any reason that someone decides to add _PIF supports to Linux.

AC Events



It is very interesting to see how an driver responds to ACPI events. In the above source code it is obvious that the driver behaves the same for all events equals 0x80, 0x00, 0x01. It also responds the same to all other ACPI events with an additional error message.

For example, it was seen that some BIOSes issue Notify(AC, 0x81) when AC adapter is plugged or plugged. Apparently Linux kernel does not think 0x81 is a valid event (nor can I find any 0x81 for AC in ACPI); however, Linux still behaves as well with Notify(AC, 0x80).

Suspend and Resume



Another interesting part in ACPI AC driver is acpi_ac_resume called when a system resumes from suspend or hiberation. It compares the "before" and "after" _PSR and issues an uEvent if they are different. This implies BIOSes need not to issue a Notify(AC, 0x80) during waking up to save some CPU cycles; however, this may be specific to Linux. As there is no rule in ACPI spec, one may want to verify the behaviors of the target OSes (ex. Windows).

References

Linux kernel source code (3.10): ACPI AC adpater driver in drivers/acpi/ac.c

Sunday, June 23, 2013

ACPI AC Adapter (1) - Introduction

In ACPI Control Method Battery (2), we see how ACPI's definition for control method battery and read the data in Ubuntu Linux. However, battery does not usually go alone - ACPI AC Adapter always goes with it.

AC Adapter Interface

Unlike the complexity of a control method battery, AC adapter is much simpler and three objects are mandatory:
  • _HID (Hardware ID) - needs to be ACPI0003
  • _PSR (Power Source) - indicates whether AC is online
  • _PCL(1) (Power Consumer List) - refers what is powered by AC

Below is a sample for AC adapter that returns whether AC is online from an EC register in _PSR:



Plugging and Unplugging AC Adapter

When AC adapter is plugged or unplugged, BIOS needs to issue a notification event as the example:



It is worth noting that only 0x80 is needed. Some BIOS will also issue Notify(_SB.AC, 0x81) that is not only redundant but also incorrect. Some BIOS also issues Notify(_SB.BAT, 0x80) and Notify(_SB.BAT, 0x81). While OS is smart enough to know that battery status is also changed, one may argument that issuing notification to battery is correct and at least won't break anything.

In my opinions, it is not incorrect to issue Notify(_SB.BAT, 0x80) as Battery State in _BST is definitely changed to discharging, assuming only one AC source and one battery are present in a system; however, issuing Notify(_SB.BAT, 0x81) and asking OS to re-enumerate _BIF/_BIX is only a waste of CPU cycles.

What is ACPI AC Adapter Affecting?

It is definitely not surprising to know the little AC icon in OS's taskbar uses the return value of AC._PSR - that's  the only way that an OS knows whether a system is powered by an AC adapter. But... what else?

It is true that hardware state is different from powered-by-AC to powered-by-battery - at least from the viewpoint of the power circuit; however, this is only small part of the system board and we often see much more difference and affecting the system. When a system is powered by AC source, it is, in most cases, running at performance mode - CPU can spend more time in maximum frequency, power-saving features are less aggressive, fan runs at higher speed, and the panel may be brighter. All of these can be changed when OS finds out AC is offline from AC._PSR.

The implication? If one sees stability issues without AC only, playing around _PSR may help identify whether it is the power circuit or is an OS beahviours, i.e. one device and its driver are too aggressive with its power-saving features. One way to distinguish whether it is always reports 1 in _PSR - if the problem persists, it is the power circuit (hardware) that causes the problem. I have seem a number of times that bad-quality power components that hang the system and many other times that a device or its driver failed the system. This technique always helps a quick and good direction to real problems.

Next...

How does Linux kernel handle ACPI AC adapter?

Note

  1. It seems _PCL is defined but is not used in Linux kernel.

References

  • ACPI Specification 5.0 - Sec. 10.3
  • ACPI Specification 5.0 - Table 5-121
  • Linux kernel source code (3.10)

Thursday, June 20, 2013

ACPI Brightness Control (4) - Workaround for Brightness Problems in Ubuntu Linux

This blog discusses some common errors for brightness control and hotkeys. It will be updated from time to time.

Initial Zero Brightness

Some system BIOS reports zero in _BQC at boot-up, and it causes Linux kernel to dim the screen to minimum. In some cases, the panel is completely black out. This is because Linux's ACPI VGA driver does the following when it starts:

  1. Read _BQC for current brightness level
  2. Set brightness level to maximum - it is to verify whether brightness work
  3. Restore brightness level from 1
Aside from getting BIOS fixes which is usually close to impossible as the product is shipped (but I do encourage people to call customer services to complain!), there are three ways to fix it:

Kernel parameter

Edit /etc/default/grub
Add "video.use_bios_initl_backlight=0" to GRUB_CMDLINE_LINUX_DEFAULT
Run "sudo update-grub"
Reboot

Bootup script

Edit the file /etc/rc.local
Add a line "echo 4 > /sys/class/backlight/acpi_video0/brightness" before "exit 0"
Reboot

Quirk to acpi/video.c

If you are familiar with Linux kernel, you can develop a patch as in https://bugs.launchpad.net/bugs/1184501. If not, it is more than welcomed to file a bug like LP#1184501, run "sudo dmidecode > dmi.log", attach dmi.log and assign the bug to me. I am very happy to develop a patch for it, and you may help many others using Linux!

Brightness Fails to Work

If you are have laptop PC that BIOS fails to adjust brightness via acpi_video, you can try add the kernel parameter "acpi_backlight=vendor".

What the parameter does is to stop using acpi video to adjust the brightness - also skips creating sysfs nodes for acpi_videoX. As a result, a desktop daemon (like GSD) will find other brightness sysfs nodes created by other drivers, such as Intel_backlight, thinkpad_backlight and so on.

A Hotkey Press Changes Two Levels

In Figure 2 of ACPI Brightness Control (3) - Hotkeys in Ubuntu Linux, a solid and a dash line were draw to call to BIOS _BCM. This implies a hotkey can and may change a brightness twice. This is the case with Gnome-Setting-Daemon in Ubuntu.

If seeing this problem, one can add an kernel parameter to workaround it:
  • sudo vi /etc/default/grub
  • add brightness_switch_enabled=N to GRUB_CMDLINE_LINUX_DEFAULT
  • sudo update-grub
  • reboot

This will skip the dashed line call in ACPI Video driver:


References

  • https://wiki.archlinux.org/index.php/Backlight

ACPI Brightness Control (3) - Hotkeys in Ubuntu Linux

In ACPI Brightness Control (1) - Control Methods and ACPI Brightness Control (2) - Hotkeys, we understand how ACPI designs brightness from BIOS's perspectives. In this blog, we will see them in action using Ubuntu as an example.

Brightness Sysfs Nodes in Linux Kernel


When booting up, Linux's ACPI VGA driver (drivers/acpi/video.c) enumerates ACPI AML (DSDT and SSDT) to look for output devices that support brightness control. Once identified, it creates sysfs nodes in /sys/class/backlight/acpi_video0. If more than one output device is found, it creates acpi_video1 and so on.

FIgure 1 - Sysfs Nodes for Brightness
Figure 1 shows files in acpi_video0 directory. Three files are particularly important:

  • actual_brightness - implements _BQC
  • brightness - implements _BCM, and also record current brightness level
  • max_brightness - implements _BCL and converts it to number of levels
For example, the _BCL in this Thinkpad reports 16 brightness levels with Ubuntu 12.04, and therefore "cat max_brightness" returns 15. Current brightness can be read by executing "cat actual_brightness" or "cat brightness". In most cases, both max_brightness and brightness return the same value (this should not be surprising) - they are only different if something breaks in kernel or BIOS - such as _BQC does not change with _BCM.

To change brightness level, one writes a value to brightness, ranged from 0 to max_brightness. In this system, it is from 0 to 15. ACPI VGA driver will convert it to the actual value in _BCL and write to _BCM. 

Hotkey Implementation in Ubuntu Linux


Figure 2 - Overall Process for Brightness Hotkeys
Figure 2 is an expansion of ACPI Brightness Control (2) - Hotkeys. It shows that many tasks are done even with a single hotkey press, and it also shows separation between OS and BIOS is clear - the clean interface makes hotkey development easy and that's exactly what ACPI is for. Let's add more details to OS level as it is in Figure 3.

Figure 3 - Brightness and Desktop Daemon
Ubuntu ships with gnome-setting-daemon (GSD) that listens to keycode events. ACPI VGA driver converts ACPI notification events to keycodes, and GSD changes brightness via sysfs nodes according. GSD is also responsible for reading brightness levels from sysfs nodes to show OSD for users and to create slider for changing brightness. It is also worthy noting that ACPI VGA driver can also calls _BCM to change brightness without interacting with GSD, but no OSD may be shown.

As GSD is designed to listen to keycode, System vendor may design BIOS to generate other none-standard ACPI events, such as WMI events, as long as there is a kernel driver to do the conversion; however, this is not a suggested.

PS. Please note keycodes are not the same as KBC's scancode.

Debugging Brightness (Hotkey) Failures


From Figure 3, it becomes obvious brightness hotkeys can fail for two primary reasons:
  1. BIOS does not generate events
  2. _BCM fails to change brightness
In Linux, it is easy to verify whether ACPI VGA events and keycodes are generated:
  • Run "acpi_listen" to show ACPI standard events
  • Run "sudo showkey" to show keycodes
One can trigger writes to _BCM as in "Brightness Sysfs Nodes in Linux Kernel", if brightness is changed but LCD panel is not, BIOS did not implement _BCM correctly (or graphics drivers do not respond requests from BIOS in some cases).


Saturday, June 15, 2013

ACPI Brightness Control (2) - Hotkeys

Overview of Brightness Hotkeys


When a brightness up or down hotkey is pressed, the screen shows a OSD and panel brightness is changed accordingly. A simple action results a simple output, but what happens underneath is a lot of magic.

Figure 1 - Hotkeys Overview (Software)

Figure 1 shows a overview from software perspectives. When a hotkey is pressed, ACPI events are generates that triggers a series of actions specific to OS which eventually changes panel brightness. More information can be found in "ACPI Brightness Control (1) - Control Methods".

BIOS ASL for Brightness Up and Down


How does BIOS tell OS to change brightness? ACPI Appendix B.6 (Notifications Specific to Output Devices) defines five types of notification; however two of them are most commonly used:
  • Notify(LCD, 0x86) – increase brightness
  • Notify(LCD, 0x87) – decrease brightness
where LCD is a devices with _BCL, _BQC and _BCM as the below example:

Device (_SB.PCI0.GFX0.LCD) {
     ...
     Method (_BCL, 0) {
          ...
     }
     Method (_BQC, 0) {
          ...
     }
     Method (_BCM, 1) {
          ...
     }
}

The below is an ASL example of an EC handing Q events for brightness hotkeys:

Device (_SB.PCI0.LPC.EC) {
     Method (_Q12, 0) {
          Notify (_SB.PCI0.GFX0.LCD, 0x86)
     }

     Method (_Q13, 0) {
          Notify (_SB.PCI0.GFX0.LCD, 0x87)
     }
}

When Hotkeys Fail


Most of them, brightness hotkeys fail for two reasons: 

1) No events are triggered: 
On Ubuntu or many other Linux distro, running "acpi_listen" and pressing hotkeys shows standard ACPI events. If you don't see anything with hotkey presses, the system BIOS fails to issue events

2) _BCM fails to work
As Windows 8 no longer uses, many BIOS engineers never check whether _BCM works (please remember ACPI requires _BCM to present in order to support brightness controls). In Linux, you can and write to /sys/class/backlight/acpi_video0/brightness to verify whether _BCM works.

Friday, June 14, 2013

ACPI Brightness Control (1) - Control Methods

All laptops today come with hotkeys to adjust panel's brightness. This blog aims to discuss how to control brightness from BIOS's perspectives.

ACPI Control Methods


ACPI Appendix B.5 (Output Device-specific Methods) defines three control methods for brightness.
  • _BCL – Query List of Brightness Control Levels Supported
  • _BCM – Set the Brightness Level
  • _BQC – Brightness Query Current level
Figure 1 - Interaction between OS, BIOS and Hardware
As in Figure 1, OS queries the list of supported brightness levels from _BCL when it starts (1). This list can be used in UI or by OS kernel when it intends to adjust the brightness. OS also read current brightness from _BQC (2). Together with (1), OS can display how brightness the LCD is in a slider or in a OSD to users.

When a user want to adjust the brightness via a slider or hotkeys (more in next blog), OS will call _BCM which calls to EC or to VGA that eventually changes the panel brightness. However, it is worthwhile to note whether to call _BCM is OS- and driver-dependent. At the time of writing, Windows 8 does not call _BCM and Windows 7 may or may not call _BCM depending on VGA, while normal Linux distribution always uses _BCM. A separate blog will discuss how Ubuntu Linux controls brightness.

Sample Code and Common Errors


_BCL


Method (_BCL, 0) {
     // List of supported brightness levels
     Return (Package(7){
          80, // level when machine has full power
          50, // level when machine is on batteries
          20, 40, 60, 80, 100 // other supported levels:
          }
}


The above is an example of _BCL in ACPI. One of the most common errors is the first two elements are left-out. Meaning OS no longer knows what brightness levels should be used when the AC adapter is plugged and unplugged.

_BCM


Method (_BCM, 1) {
     Store (Arg0, \_SB.PCI0.LPC.EC.BRLV)
}

The above is a very simple _BCM implementation. It simply passes the brightness level, from OS, to an EC registers (assuming brightness is controlled by EC). Please note Arg0 will be one of the values in _BCL such as 20, 40, 60 and so on in the _BCL example.

Common errors of _BCM are:
  • _BCM is present but it does not control brightness
    • Some Windows VGA drivers do not use _BCM; however, Linux requires _BCM to work correctly.
  • Lowest brightness level blacks out the screen
    • This may or may not be a bug depending on OEMs.

_BQC


Method (_BQC, 0) {
     Return (\_SB.PCI0.LPC.EC.BRLV)
}

The above example simply returns brightness set from _BCM in the above example.

Common errors of _BQC are:
  • _BQC is not implemented in BIOS AML
  • _BQC returns value not in _BCL
    • _BQC needs to report the value of the brightness, the order of the brightness.
  • _BQC returns zero at boot time

Friday, June 7, 2013

Power Management (5):P-state driver for Intel CPU

A recent Linux patch caught my eyes:

commit 93f0822dff5dae2f0a2645f16300c14af41ca777
Author: Dirk Brandewie <dirk.brandewie@gmail.com>
Date:   Wed Feb 6 09:02:13 2013 -0800

    cpufreq/x86: Add P-state driver for sandy bridge.
    
    Add a P-state driver for the Intel Sandy bridge processor. In cpufreq
    terminology this driver implements a  scaling driver with an internal
    governor.
    
    When built into the the kernel this driver will be the preferred
    scaling driver for Sandy bridge processors.
    
    In addition to the interfaces provided by the cpufreq subsystem for
    controlling scaling drivers. The user may control the behavior of the
    driver via three sysfs files located in
    "/sys/devices/system/cpu/intel_pstate".
    
      max_perf_pct: limits the maximum P state that will be requested by
      the driver stated as a percentage of the avail performance.
    
      min_perf_pct: limits the minimum P state that will be  requested by
      the driver stated as a percentage of the avail performance.
    
      no_turbo: limits the driver to selecting P states below the turbo
      frequency range.
    
    Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
    Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Not surprisingly, another Linux patch for IvyBridge was developed:

commit c96d53d600643ee0adfd1cb90814bd9510e62b71
Author: Dirk Brandewie <dirk.j.brandewie@intel.com>
Date:   Fri May 17 16:10:24 2013 +0000

    cpufreq / intel_pstate: Add additional supported CPU ID
    
    Add CPU ID for Ivybrigde processor.
    
    Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

As Haswell is not officially supported by latest Linux kernel today, we put its model id (by running cat /proc/cpuinfo) and measured the power consumption, and it saves 0.5W (4%) with an idle system - that is the same as enabling ASPM of two PCIe devices (more information @ http://alexhungdmz.blogspot.tw/2011/12/power-management-3pcie-aspm.html) - I'd say this is quite a significant improvement.

What interests me is that these P-states are no longer declared in ACPI CPU._PSS but in device driver. Linux with kernel 3.9 and before will not benefit from the latest power-saving features from Intel. It can be also true to older version of Microsoft Windows.

Does this imply ACPI spec is out-dated and x86 hardware can provide more advanced power management features than ACPI can describe? Probably. If this is true, we should be seeing spec updates from ACPI groups soon. Meanwhile, power management becomes more challenging for system vendors as BIOS is no longer sufficient.

Monday, June 4, 2012

Introduction to ACPI Control Method Battery (2)


Control Method Battery Interface



Figure 1 - An ASL Battery Device
To present a control method battery to an OS, BIOS needs to declare an object in DSDT/SSDT table, and it must be with an _HID "PNP0C0A", as shown in Figure 1.

If more than a battery are needed, each battery can be distinguished by an unique _UID.

In addition to _HID and _UID, a number of ASL objects are also mandatory as below.

_STA: Battery Presence

Figure 3 - _STA Object for a Battery Device
_STA object is used to show the state of a device in a system; however, ACPI battery is special in the sense of device presence.

In ACPI, it is specially noted "Unlike most other devices, when a battery is inserted or removed from the system, the device itself (the battery bay) is still considered to be present in the system." The battery presence is therefore determine as Figure 2, and _STA for a control method battery should be written as the sample in Figure 3.
Figure 2 - _STA Bitmap

_PCL: Power Consumer List

Figure 4 - Sample _PCL Object
_PCL object defines what components are powered by this power source (i.e. this battery). It is not certain who uses this information and how it affects system behaviors, but it may be used to manage more complex systems with multiple power sources and allows runtime replacement. In most of cases, a battery powers every components, and it can be written as Figure 4.

_BIF or _BIX: Battery Information

_BIF passes "static" battery information from a battery pack to an operating system, such as design capacity and last full charged capacity previously discussed (as shown in Figure 5). Please refer to ACPI specification for more details.

Figure 5 - _BIF Data Structure

_BIX is a replacement for _BIF since ACPI 4.0. It includes all data in _BIF plus some additions. However, it would be better to include both _BIF and _BIX in BIOS because many all operating systems support _BIX. Please refer to ACPI Spec 4.0/5.0 for details.

Battery Information Update

BIOS notifies OSPM that battery information changes by issuing Notify (Battery, 0x81). This mostly happens when a battery is inserted or removed. However, this is not 100% sufficient according to my experiences - I think Notify (Battery, 0x81) should be issued whenever any field in _BIF/_BIX change.

If we take a clear look at _BIF and _BIF, it is obvious that most of fiends are very much static, i.e. Power Unit, Design Capacity, Model Name and so on; however, some fields can change without changing a battery, such as Last Full Charge Capacity and Cycle Count. EC should also geneate a SCI to BIOS to Notify (Battery, 0x81) in such scenario. This will keep operating system updated with latest information and prevent some bugs from happening. (Do you know what bugs can happen?)

Getting Battery Information in Linux (Ubuntu 12.04)

To get battery information in Ubuntu 12.04 is very easy and it can be done by two approaches.
  • /proc/acpi/battery/[Battery]/info
On my laptop PC, a simple cat /proc/acpi/battery/BAT0/info returns:
present:                 yes
design capacity:         4313 mAh
last full capacity:      4313 mAh
battery technology:      non-rechargeable
design voltage:          12416 mV
design capacity warning: 432 mAh
design capacity low:     216 mAh
cycle count:   0
capacity granularity 1:  100 mAh
capacity granularity 2:  100 mAh
model number:          
serial number:        
battery type:            LiOn
OEM info:                HP

It should noted that Linux kernel assumed the format of _BIX and it returns 0 for unsupported field if only _BIF is present (i.e. cycle count = 0).
    • /sys/class/power_supply/[Battery]/uevent
    On my laptop PC, a simple cat /sys/class/power_supply/BAT0/uevent returns:
    POWER_SUPPLY_NAME=BAT0
    POWER_SUPPLY_STATUS=Full
    POWER_SUPPLY_PRESENT=1
    POWER_SUPPLY_TECHNOLOGY=Li-ion
    POWER_SUPPLY_CYCLE_COUNT=0
    POWER_SUPPLY_VOLTAGE_MIN_DESIGN=12416000
    POWER_SUPPLY_CHARGE_FULL_DESIGN=4313000
    POWER_SUPPLY_CHARGE_FULL=4313000
    POWER_SUPPLY_CHARGE_NOW=4313000
    POWER_SUPPLY_MODEL_NAME=
    POWER_SUPPLY_MANUFACTURER=HP
    POWER_SUPPLY_SERIAL_NUMBER=

    _BST: Battery State

    _BST passes "dynamic battery information from a battery pack to an operating system, including:
    • Battery State - state of charging/discharging and critical low
    • Battery Present Rate - power or current being supplied or accepted through the battery’s  terminals.
    • Battery Remaining Capacity - the estimated remaining battery capacity
    • Battery Present Voltage - the voltage across the battery’s terminals.

    Battery State Update

    BIOS notifies OSPM that battery information changes by issuing Notify (Battery, 0x80). This can happen during run-time when battery is presented in battery bay. Especially, ACPI defines two scenario that this notification should happen: 1. When battery state of battery changes, and 2. When remaining capacity reaches critical low. Failing to do will not introduce critical bugs (reasonable below) but will decrease responsiveness of battery information to users in some use-cases.

    Operating systems like Windows or Linux periodically poll battery states and there is no need for BIOS/EC to issue Notify (Battery, 0x80) periodically; for example, it is known that Windows 7 polls battery state every 15 seconds. This often surprises BIOS or EC engineers (and I wonder why). Issuing extra Notify (Battery, 0x80) will not prevent any bugs but only waste of CPU cycle (and therefore slightly battery life penalty!).

    Getting Battery State in Linux (Ubuntu 12.04)


    Similarly to Battery Information, two approaches can be applied to get battery state in Linux.
    • /proc/acpi/battery/[Battery]/state
    On my laptop PC, cat /proc/acpi/battery/BAT0/state returns:
    present:                 yes
    capacity state:          ok
    charging state:          charged
    present rate:            unknown
    remaining capacity:      4313 mAh
    present voltage:         unknown
    • /sys/class/power_supply/[Battery]/*
    This is a little different. Each field in _BST is declared as a node (file), and getting battery state is done by cat state_node. I will leave details to you.

    Extra Information

    This article focus on BIOS-OS interfaces and explains little on each field. To understand more on how to get information from a battery pack, extra reading on Smart Battery System Specification is highly recommended; however, this is out-of-scope from BIOS or OS perspectives.

    Thursday, May 31, 2012

    Introduction to ACPI Control Method Battery (1)

    All laptop PCs come with a battery. However, how does an operating system get information from a battery pack?

    First of all, it must be understood that a battery pack can power a computer whether an OS is aware of its presence. All information past to an OS and shown to users is reported.

    ACPI defines two types of battery interfaces.
    1. Smart Battery Subsystem Interface
      • Controlled by OS directly through EC
      • Solution is expensive
    2. Control Method Battery Interface
      • Reported by BIOS
      • Solution is inexpensive
    It would not be surprising to see most of laptop PCs use Control Method Battery interface.

    Battery Capacity and Battery Life

    When a battery pack is produced, it has a "design capacity" that is the maximum capacity of the battery pack in theory, and "last full charged capacity" that is the actual maximum capacity. At the initial state, it can be assume that "design capacity" equals "last full charged capacity".
    However, the last full charged capacity ages over time, and therefore the battery life will also be decreased.

    Battery life can be calculated as

    • Remaining Battery Percentage [%] =

    •  Remaining Battery Life [h] = 


    In operating systems, remaining battery percentage is also calculated by (Remaining Capacity / Design Capacity). In this case, it is very soon that you will not see remaining battery percentage equal 100%. Technical speaking, this is not incorrect but often this will be reported as a bug. In my opinions, this depends on interpretation but I prefer (Remaining Capacity / Last Full Charaged Capacity).

    (To be continued...)

    Thursday, May 10, 2012

    How to Dump ACPI Tables in Ubuntu

    Dumping ACPI tables in Ubuntu is as easy as 1, 2, 3 (and 4, 5). Please note you need root privileges for some of the below tasks.

    Install Linux utilities

    sudo apt-get update && sudo apt-get install acpidump iasl

    Dump ACPI tables from memory by acpidump

    sudo acpidump > acpi.log

    Extract tables by acpixtract

    If you are intending to extract the DSDT table, you can use:
    acpixtract -sDSDT acpi.log
    If table type is not specified, acpixtract extracts DSDT and all SSDTs by default:
    acpixtract acpi.log 

    Decode an ACPI table by Intel's disassembler

    iasl -d DSDT.dat

    View result with your favorite text editor

    I use: vi DSDT.dsl

    Monday, February 13, 2012

    Why does Linux Say It Is not Linux in _OSI("Linux")?

    First, let me explain what _OSI is.


    Section 5.7.2 of ACPI specification defines it as below:
    ===================================================
    _OSI (Operating System Interfaces)

    This object provides the platform with the ability to query OSPM to determine the set of ACPI related interfaces, behaviors, or features that the operating system supports.
    ...
    _OSI provides the platform with the ability to support new operating system versions and their associated features when they become available. OSPM can choose to expose new functionality based on the _OSI argument string. That is, OSPM can use the strings passed into _OSI to ensure compatibility between older platforms and newer operating systems by maintaining known compatible behavior for a platform.
    ===================================================

    In theory, BIOS can use _OSI to provide different functionality for different operating systems to a specific platform.

    Now, the answer to the question "Why does Linux Say It Is not Linux in _OSI("Linux")?" is - because Linux kernel wants to provide better quality and user-experiences.

    Why is the differentiation is not desirable for Linux? Linux source code (drivers/acpi/osl.c) gives a history how the design decision was made as below:

    /*
     * The story of _OSI(Linux)
     *
     * From pre-history through Linux-2.6.22,
     * Linux responded TRUE upon a BIOS OSI(Linux) query.
     *
     * Unfortunately, reference BIOS writers got wind of this
     * and put OSI(Linux) in their example code, quickly exposing
     * this string as ill-conceived and opening the door to
     * an un-bounded number of BIOS incompatibilities.
     *
     * For example, OSI(Linux) was used on resume to re-POST a
     * video card on one system, because Linux at that time
     * could not do a speedy restore in its native driver.
     * But then upon gaining quick native restore capability,
     * Linux has no way to tell the BIOS to skip the time-consuming
     * POST -- putting Linux at a permanent performance disadvantage.
     * On another system, the BIOS writer used OSI(Linux)
     * to infer native OS support for IPMI!  On other systems,
     * OSI(Linux) simply got in the way of Linux claiming to
     * be compatible with other operating systems, exposing
     * BIOS issues such as skipped device initialization.
     *
     * So "Linux" turned out to be a really poor chose of
     * OSI string, and from Linux-2.6.23 onward we respond FALSE.
     *
     * BIOS writers should NOT query _OSI(Linux) on future systems.
     * Linux will complain on the console when it sees it, and return FALSE.
     * To get Linux to return TRUE for your system  will require
     * a kernel source update to add a DMI entry,
     * or boot with "acpi_osi=Linux"
     */ 

    ACPICA User Guide and Programmer Reference also has a similar discussion in Section 8.1.7.2 "Why ACPICA responds TRUE to _OSI (Windows)"
    ===================================================
    ACPICA responds TRUE to all known Windows strings because ACPICA attempts to be fully compatible with the Windows implementation of ACPI. On the other hand, ACPICA responds FALSE to other operating system strings (such as “Linux”, “FreeBSD”, or “HP-UX”) because doing so has been seen to often cause serious problems. For example, on many platforms, the only path through the ASL code that has been fully tested by the manufacturer is in fact the path for “Windows”. By responding TRUE to other operating system strings, the ASL may execute paths that have had only limited or even no evaluation.
    ===================================================

    To summarize, returning FALSE in _OSI("Linux") forces better software quality from two perspectives.

    1. Not to "workaround" kernel errors in BIOS code - if Linux bugs are found, it should be updated to Linux kernel developers to have them fixed. 
    2. To ensure Linux kernel executes code path that is well-tested - the same path Windows would execute. 

    In the case of that _OSI("Linux") is really needed, it can be forced with kernel parameter acpi_osi=Linux as in the above comments.

    Some OEM/ODM ship their systems with acpi_osi=Linux in their customized images; however, the solution has a downside. If a particular bug is not fixed in future kernel, or it is not a kernel bug but a hardware compatibility bug and cannot be fixed, a clean Linux installation by an end-user without adding this parameters will expose this bug. 

    Instead, a better solution would be to have a BIOS setup option for workaround. If the bug is fixed, an end-user can  disable the workaround. A clean installation without acpi_osi=Linux will not expose the bug, either.

    _OSI Strings in Ubuntu 

    _OSI does not return true for a specific string.  Instead, it returns true for a list of strings.  As in Windows, _OSI in Linux returns true up to a Windows version.  For example, kernel 3.13 (used in Ubuntu 14.04) would report _OSI = true for Windows 7 (ex. "Windows 2012" and all versions before.  The below table lists Windows versions and their supports in Ubuntu Linux

    _OSI argument Windows version Supported in Ubuntu
    Windows 2000 Windows 2000 Pre-Dapper 6.06 LTS
    Windows 2001 Windows XP Pre-Dapper 6.06 LTS
    Windows 2001 Windows XP SP1 Pre-Dapper 6.06 LTS
    Windows 2001.1 Windows Server 2003 Pre-Dapper 6.06 LTS

    Windows 2001 SP2
    Windows XP SP2 Pre-Dapper 6.06 LTS

    Windows 2001.1 SP1

    Windows 2001.1 SP1

    Hardy 8.04 LTS

    Windows 2006

    Windows Vista

    Hardy 8.04 LTS

    Windows 2006.1

    Windows Server 2008

    Lucid 10.04 LTS

    Windows 2006 SP1

    Windows Vista SP1

    Lucid 10.04 LTS

    Windows 2006 SP2

    Windows Vista SP2

    Natty 11.04

    Windows 2009

    Windows 7 and Server 2008 R2

    Lucid 10.04 LTS

    Windows 2012

    Windows 8 and Server 2012

    Raring 13.04

    Windows 2013

    Windows 8.1 and Server 2012 R2

    Utopic 14.10

    Windows 2015

    Windows 10

    Wily 15.10