diff mbox

[1/1] ACPI: Document _OSI and _REV for Linux BIOS writers

Message ID d122d41c1cc7230ae5283caf2a4c18fd4d0cd93e.1479792558.git.len.brown@intel.com (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Len Brown Nov. 22, 2016, 5:29 a.m. UTC
From: Len Brown <len.brown@intel.com>

Based on a recent session at the Linux Plumber's Conference,
we need to be more clear about how a BIOS should use _OSI
to properly support Linux.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/acpi/osi.txt | 187 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 187 insertions(+)
 create mode 100644 Documentation/acpi/osi.txt

Comments

Lukas Wunner Nov. 22, 2016, 10:02 a.m. UTC | #1
On Tue, Nov 22, 2016 at 12:29:46AM -0500, Len Brown wrote:
> +On a platform tasked with running multiple versions of Windows,
> +the BIOS could use _OS to enable/disable devices that and OS
                                                           ^
							   delete

> +_OSI("Darwin")
> +--------------
> +
> +No description of _OSI would be complete without mentioning _OSI("Darwin").
> +This string is mis-used by Apple on Mac platforms, just as Linux
> +mis-used _OSI("Linux").
> +
> +Linux did not originally return TRUE to _OSI("Darwin"),
> +on the assumption that on Apple hardware, Linux was
> +probably best pretending to be Windows,
> +rather than pretending to be OSX.
> +
> +But _OSI("Darwin") was required to make Thunderbolt work,
> +and so Linux changed to enable it by default.  Making matters worse,
> +that change did not include the ability to disable _OSI("Darwin")
> +on the cmdline with acpi_OSI=!Darwin, and so the resulting
> +regressions had no workaround.
> +
> +The cmdline has since been fixed to enable !Darwin.
> +Today "Darwin" enables Thunderbolt, but significantly
> +hurts battery life, and so the default for _OSI("Darwin")
> +is still under debate.

So first of all, I'm currently upstreaming a series which enables
runtime PM for Thunderbolt on Macs.  Two series with prep work went
into 4.9 and 4.10.  The final bits are slated for 4.11.

IOW the whole "answering affirmative to Darwin hurts battery life"
argument will be nonsensical and moot from 4.11 onwards.

Link to the series:
https://github.com/l1k/linux/commits/thunderbolt_runpm_v3

All patches up to 3890c45 ("mfd: intel-lpss: Avoid resuming
runtime-suspended lpss unnecessarily") are either already in
mainline or queued up for it.


Second, your description is incorrect in that Thunderbolt is only
powered down in the non-Darwin case on Macs introduced before 2015.
That's because they didn't support Thunderbolt on Windows (with
BootCamp) on the older machines, so they powered the controller down
and made it invisible to the OS.

However on Macs introduced 2015+, they now seem to support Thunderbolt
on Windows.  They seem to switch the controller between SMM-managed
versus OS-managed mode based on the _OSI string.  In any case they no
longer just power it down.


Third, Apple uses _OSI("Darwin") not just for Thunderbolt, so the
above description is incomplete.  They use it *generally* to
distinguish between macOS versus Windows code paths in AML.
(These are the only two OSes they care about.)

E.g. on the 12" MacBook, which doesn't even have Thunderbolt, the
_PS0 and _PS3 methods become no-ops in the non-Darwin case.

Usually Apple only supports a subset of the hardware on Windows,
so we have to pretend being Darwin to be afforded full access to
the machine.

One noteworthy issue with _OSI("Darwin") is that we have to respond
negatively to all other vendor strings once it's encountered.
See here for details:  http://mjg59.dreamwidth.org/29954.html

Thanks,

Lukas
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Len Brown Nov. 29, 2016, 6:07 p.m. UTC | #2
On Tue, Nov 22, 2016 at 5:02 AM, Lukas Wunner <lukas@wunner.de> wrote:
> On Tue, Nov 22, 2016 at 12:29:46AM -0500, Len Brown wrote:
>> +On a platform tasked with running multiple versions of Windows,
>> +the BIOS could use _OS to enable/disable devices that and OS
>                                                            ^
>                                                            delete

Here I was trying to describe that the BIOS may enable or disable
devices and quirks based on the OS.  Yes, there are examples
of disabling in addition to enabling -- as sometimes there is a device
that may appear as different specific flavors of device based on the OS.
Are you  pointing out that I should use the word "or" instead of a '/'?

>> +_OSI("Darwin")
>> +--------------
>> +
>> +No description of _OSI would be complete without mentioning _OSI("Darwin").
>> +This string is mis-used by Apple on Mac platforms, just as Linux
>> +mis-used _OSI("Linux").
>> +
>> +Linux did not originally return TRUE to _OSI("Darwin"),
>> +on the assumption that on Apple hardware, Linux was
>> +probably best pretending to be Windows,
>> +rather than pretending to be OSX.
>> +
>> +But _OSI("Darwin") was required to make Thunderbolt work,
>> +and so Linux changed to enable it by default.  Making matters worse,
>> +that change did not include the ability to disable _OSI("Darwin")
>> +on the cmdline with acpi_OSI=!Darwin, and so the resulting
>> +regressions had no workaround.
>> +
>> +The cmdline has since been fixed to enable !Darwin.
>> +Today "Darwin" enables Thunderbolt, but significantly
>> +hurts battery life, and so the default for _OSI("Darwin")
>> +is still under debate.
>
> So first of all, I'm currently upstreaming a series which enables
> runtime PM for Thunderbolt on Macs.  Two series with prep work went
> into 4.9 and 4.10.  The final bits are slated for 4.11.
>
> IOW the whole "answering affirmative to Darwin hurts battery life"
> argument will be nonsensical and moot from 4.11 onwards.
>
> Link to the series:
> https://github.com/l1k/linux/commits/thunderbolt_runpm_v3
>
> All patches up to 3890c45 ("mfd: intel-lpss: Avoid resuming
> runtime-suspended lpss unnecessarily") are either already in
> mainline or queued up for it.

I'm delighted to learn this is in progress, as I'm sure,
is the entire community of users running Linux on Mac.

>
> Second, your description is incorrect in that Thunderbolt is only
> powered down in the non-Darwin case on Macs introduced before 2015.
> That's because they didn't support Thunderbolt on Windows (with
> BootCamp) on the older machines, so they powered the controller down
> and made it invisible to the OS.
>
> However on Macs introduced 2015+, they now seem to support Thunderbolt
> on Windows.  They seem to switch the controller between SMM-managed
> versus OS-managed mode based on the _OSI string.  In any case they no
> longer just power it down.
>
>
> Third, Apple uses _OSI("Darwin") not just for Thunderbolt, so the
> above description is incomplete.  They use it *generally* to
> distinguish between macOS versus Windows code paths in AML.
> (These are the only two OSes they care about.)
>
> E.g. on the 12" MacBook, which doesn't even have Thunderbolt, the
> _PS0 and _PS3 methods become no-ops in the non-Darwin case.
>
> Usually Apple only supports a subset of the hardware on Windows,
> so we have to pretend being Darwin to be afforded full access to
> the machine.
>
> One noteworthy issue with _OSI("Darwin") is that we have to respond
> negatively to all other vendor strings once it's encountered.
> See here for details:  http://mjg59.dreamwidth.org/29954.html
>

Great feedback!
Yes, I did a somewhat superficial job on the Darwin section.
I'll re-write it, incorporating your feedback, and send out an updated patch.

thanks,
Len Brown, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lukas Wunner Nov. 29, 2016, 6:27 p.m. UTC | #3
On Tue, Nov 29, 2016 at 01:07:55PM -0500, Len Brown wrote:
> On Tue, Nov 22, 2016 at 5:02 AM, Lukas Wunner <lukas@wunner.de> wrote:
> > On Tue, Nov 22, 2016 at 12:29:46AM -0500, Len Brown wrote:
> >> +On a platform tasked with running multiple versions of Windows,
> >> +the BIOS could use _OS to enable/disable devices that and OS
> >                                                            ^
> >                                                            delete
> 
> Here I was trying to describe that the BIOS may enable or disable
> devices and quirks based on the OS.  Yes, there are examples
> of disabling in addition to enabling -- as sometimes there is a device
> that may appear as different specific flavors of device based on the OS.
> Are you  pointing out that I should use the word "or" instead of a '/'?

I meant s/and/an/, so "devices that an OS", it looked like a typo to me.
Sorry for not making this clear enough.


> Great feedback!
> Yes, I did a somewhat superficial job on the Darwin section.
> I'll re-write it, incorporating your feedback, and send out an updated patch.

Great, thanks!

Lukas
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/acpi/osi.txt b/Documentation/acpi/osi.txt
new file mode 100644
index 000000000000..f9a0352f1d28
--- /dev/null
+++ b/Documentation/acpi/osi.txt
@@ -0,0 +1,187 @@ 
+ACPI _OSI and _REV methods
+--------------------------
+
+The ACPI _OSI method, "Operating System Interfaces",
+informs the ACPI BIOS about 'interfaces' supported by the Operating System.
+
+The ACPI _REV method returns the "Revision of the ACPI specification
+that OSPM supports"
+
+This document explains how and why the BIOS and Linux should use these methods.
+It also explains how and why they are widely mis-used.
+
+How to use _OSI
+---------------
+
+Linux runs on two groups of machines -- those that are tested by the OEM
+to be compatible with Linux, and those that were never tested with Linux,
+but where Linux was installed to replace the original OS (Windows or OSX).
+
+The larger group is the systems tested to run only Windows.
+Many of those systems were not only tested with just Windows, they were
+tested with just one specific version of Windows.  Even though the BIOS
+uses _OSI to query what version of Windows is running, only a single
+path through the BIOS has every been tested.
+For that reason, Linux must continue to claim compatibility with
+all versions of Windows.  To do otherwise exposes BIOS bugs on this
+large group of machines.
+
+But Linux isn't actually compatible with Windows, and the Linux community
+has also been hurt with regressions when Linux adds the latest version of
+Windows to its list of _OSI strings.  So it is possible that additional strings
+will be more thoroughly vetted before shipping upstream in the future.
+But it is likely that they will all eventually be added.
+
+Then there are systems designed and tested to run Linux.
+Often an OEM's ACPI BIOS team wants to support a unique feature
+in Linux, to do this, the BIOS should ask exactly what it wants to know:
+
+_OSI("Linux-OEM-my_interface_name")
+where 'OEM' is needed if this is an OEM-specific hook,
+and 'my_interface_name' describes the hook, which could be a
+quirk, a bug, or a bug-fix.
+
+For this to work, a patch must be sent to upstream Linux
+via the linux-acpi@vger.kernel.org mailing list.  When that patch
+is checked into Linux, the OS will answer "YES" when the BIOS
+on the OEM's system uses _OSI to ask if the interface is supported
+by the OS.  Linux distributors can back-port that patch for Linux
+pre-installs, and it will be included by all distributions that
+re-base to upstream.  If the distribution can not update the kernel binary,
+they can also add an acpi_osi= cmdline parameter to the boot loader, as needed.
+
+If the string refers to a feature where the upstream kernel
+eventually grows support, a patch should be sent to remove
+the string when that support is added to the kernel.
+
+That was easy.  Read on, to find out how to do it wrong.
+
+Before _OSI, there was _OS
+--------------------------
+
+ACPI 1.0 specified "_OS" as an
+"object that evaluates to a string that identifies the operating system."
+
+The ACPI BIOS flow would include an evaluation of _OS, and the AML
+interpreter in the kernel would return to it a string identifying
+the OS.  _OS returned "Microsoft Windows" on Windows 98 and SE.
+It returned "Microsoft WindowsME:Millenium Edition" for Win-ME,
+and for Windows NT it returned "Microsoft Windows NT".  After that,
+_OS was abandoned, though modern BIOS continue to contain
+an ancient idiom looking for "Microsoft Windows NT" -- just
+in case time travel becomes possible?
+
+On a platform tasked with running multiple versions of Windows,
+the BIOS could use _OS to enable/disable devices that and OS
+might support, or enable/disable quirks or bug work-arounds
+necessary to make the platform compatible with a pre-existing OS.
+
+If a BIOS invokes _OS today, Linux will return
+"Microsoft Windows NT".  That is the *only* possible choice,
+as doing otherwise can steer the BIOS down an un-tested path.
+
+_OS had fundamental problems.  First, the BIOS needed to know the name
+of every version of the OS that would run on it, and needed to know
+all the quirks of those OS's.  Certainly it would make more sense
+for the BIOS to ask *specific* things of the OS, such
+"do you support a specific interface", and thus in ACPI 3.0,
+_OSI was born to replace _OS.
+
+_OSI is born, and immediately mis-used
+--------------------------------------
+
+With _OSI, the *BIOS* provides the string describing an interface,
+and asks the OS: "YES/NO, are you compatible with this interface?"
+
+eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how
+to deal with the thermal extensions made to the ACPI 3.0 specification.
+An old OS that doesn't know about those extensions would answer FALSE,
+and a new OS may be able to return TRUE.
+
+For an OS-specific interface, the BIOS and the OS
+were to agree on a string of the form such as "Windows-interface_name".
+
+But two bad things happened.  First, the Windows ecosystem used _OSI
+not as designed, but as a direct replacement for _OS -- identifying
+the OS version, rather than an OS supported interface.  Indeed, right
+from the start, the ACPI 3.0 spec itself codified this mis-use
+in example code using _OSI("Windows 2001").
+
+The Windows BIOS/OS ecosystem continues to mis-use this method today.
+
+Linux had no choice but to also return TRUE to _OSI("Windows 2001")
+and its successors.  To do otherwise would virtually guarantee breaking
+a BIOS that has been tested only with that _OSI returning TRUE.
+
+This strategy is problematic, as Linux is never completely compatible with
+the latest version of Windows, and sometimes it takes more than a year
+to iron out incompatibilities.
+
+The Linux community made things worse by returning TRUE
+to _OSI("Linux").  Doing so is even worse than the Windows mis-use
+of _OSI, as "Linux" contains no version information.
+_OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's
+using it in un-tested BIOS flows.  But some OEM's used _OSI("Linux")
+in tested flows to support real Linux features.  In 2009, Linux
+removed _OSI("Linux"), and added a cmdline parameter to restore it
+for legacy systems that needed it, and added a BIOS_BUG warning
+for all BIOS's that invoke it.  No BIOS ever should use _OSI("Linux").
+
+The result is a strategy for Linux to maximize compatibility with
+ACPI BIOS that are tested on Windows machines.  There is a real risk
+of over-stating that compatibility; but the alternative has often been
+catastrophic failure resulting from the BIOS taking paths that
+were never validated under *any* OS.
+
+BIOS for Linux and Windows
+--------------------------
+
+For some platforms, a BIOS that wants to properly run Windows
+and Linux needs to know which is running.  This is a valid requirement,
+and it may be, for example, due to specific hardware that is supported by one
+OS is incompatible with the same hardware support in the other OS.
+Examples may be sound or storage devices with different hardware modes.
+The BIOS can handle such quirks, only if it can reliably identify
+what software is running.
+
+Do not use _REV
+---------------
+
+Some BIOS writers decided to use _REV to tell the difference
+between Linux and Windows.  _REV was defined in ACPI 1.0 to return
+the version of ACPI supported by the OS and the OS AML interpreter.
+
+Modern Windows returns _REV = 2.  Linux used ACPI_CA_SUPPORT_LEVEL,
+which would increment, based on the version of the spec supported.
+
+Unfortunately, _REV was also mis-used.  eg. some BIOS would check
+for _REV = 3, and do something for Linux, but when Linux returned
+_REV = 4, that support broke.
+
+In response to this problem, Linux returns _REV = 2 always,
+from mid-2015 onward.  The ACPI specification will also be updated
+to reflect that _REV is deprecated, and always returns 2.
+
+_OSI("Darwin")
+--------------
+
+No description of _OSI would be complete without mentioning _OSI("Darwin").
+This string is mis-used by Apple on Mac platforms, just as Linux
+mis-used _OSI("Linux").
+
+Linux did not originally return TRUE to _OSI("Darwin"),
+on the assumption that on Apple hardware, Linux was
+probably best pretending to be Windows,
+rather than pretending to be OSX.
+
+But _OSI("Darwin") was required to make Thunderbolt work,
+and so Linux changed to enable it by default.  Making matters worse,
+that change did not include the ability to disable _OSI("Darwin")
+on the cmdline with acpi_OSI=!Darwin, and so the resulting
+regressions had no workaround.
+
+The cmdline has since been fixed to enable !Darwin.
+Today "Darwin" enables Thunderbolt, but significantly
+hurts battery life, and so the default for _OSI("Darwin")
+is still under debate.
+