osi.txt 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. ACPI _OSI and _REV methods
  2. --------------------------
  3. An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
  4. to find out what the operating system supports. Eg. If BIOS
  5. AML code includes _OSI("XYZ"), the kernel's AML interpreter
  6. can evaluate that method, look to see if it supports 'XYZ'
  7. and answer YES or NO to the BIOS.
  8. The ACPI _REV method returns the "Revision of the ACPI specification
  9. that OSPM supports"
  10. This document explains how and why the BIOS and Linux should use these methods.
  11. It also explains how and why they are widely misused.
  12. How to use _OSI
  13. ---------------
  14. Linux runs on two groups of machines -- those that are tested by the OEM
  15. to be compatible with Linux, and those that were never tested with Linux,
  16. but where Linux was installed to replace the original OS (Windows or OSX).
  17. The larger group is the systems tested to run only Windows. Not only that,
  18. but many were tested to run with just one specific version of Windows.
  19. So even though the BIOS may use _OSI to query what version of Windows is running,
  20. only a single path through the BIOS has actually been tested.
  21. Experience shows that taking untested paths through the BIOS
  22. exposes Linux to an entire category of BIOS bugs.
  23. For this reason, Linux _OSI defaults must continue to claim compatibility
  24. with all versions of Windows.
  25. But Linux isn't actually compatible with Windows, and the Linux community
  26. has also been hurt with regressions when Linux adds the latest version of
  27. Windows to its list of _OSI strings. So it is possible that additional strings
  28. will be more thoroughly vetted before shipping upstream in the future.
  29. But it is likely that they will all eventually be added.
  30. What should an OEM do if they want to support Linux and Windows
  31. using the same BIOS image? Often they need to do something different
  32. for Linux to deal with how Linux is different from Windows.
  33. Here the BIOS should ask exactly what it wants to know:
  34. _OSI("Linux-OEM-my_interface_name")
  35. where 'OEM' is needed if this is an OEM-specific hook,
  36. and 'my_interface_name' describes the hook, which could be a
  37. quirk, a bug, or a bug-fix.
  38. In addition, the OEM should send a patch to upstream Linux
  39. via the linux-acpi@vger.kernel.org mailing list. When that patch
  40. is checked into Linux, the OS will answer "YES" when the BIOS
  41. on the OEM's system uses _OSI to ask if the interface is supported
  42. by the OS. Linux distributors can back-port that patch for Linux
  43. pre-installs, and it will be included by all distributions that
  44. re-base to upstream. If the distribution can not update the kernel binary,
  45. they can also add an acpi_osi=Linux-OEM-my_interface_name
  46. cmdline parameter to the boot loader, as needed.
  47. If the string refers to a feature where the upstream kernel
  48. eventually grows support, a patch should be sent to remove
  49. the string when that support is added to the kernel.
  50. That was easy. Read on, to find out how to do it wrong.
  51. Before _OSI, there was _OS
  52. --------------------------
  53. ACPI 1.0 specified "_OS" as an
  54. "object that evaluates to a string that identifies the operating system."
  55. The ACPI BIOS flow would include an evaluation of _OS, and the AML
  56. interpreter in the kernel would return to it a string identifying the OS:
  57. Windows 98, SE: "Microsoft Windows"
  58. Windows ME: "Microsoft WindowsME:Millenium Edition"
  59. Windows NT: "Microsoft Windows NT"
  60. The idea was on a platform tasked with running multiple OS's,
  61. the BIOS could use _OS to enable devices that an OS
  62. might support, or enable quirks or bug workarounds
  63. necessary to make the platform compatible with that pre-existing OS.
  64. But _OS had fundamental problems. First, the BIOS needed to know the name
  65. of every possible version of the OS that would run on it, and needed to know
  66. all the quirks of those OS's. Certainly it would make more sense
  67. for the BIOS to ask *specific* things of the OS, such
  68. "do you support a specific interface", and thus in ACPI 3.0,
  69. _OSI was born to replace _OS.
  70. _OS was abandoned, though even today, many BIOS look for
  71. _OS "Microsoft Windows NT", though it seems somewhat far-fetched
  72. that anybody would install those old operating systems
  73. over what came with the machine.
  74. Linux answers "Microsoft Windows NT" to please that BIOS idiom.
  75. That is the *only* viable strategy, as that is what modern Windows does,
  76. and so doing otherwise could steer the BIOS down an untested path.
  77. _OSI is born, and immediately misused
  78. --------------------------------------
  79. With _OSI, the *BIOS* provides the string describing an interface,
  80. and asks the OS: "YES/NO, are you compatible with this interface?"
  81. eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how
  82. to deal with the thermal extensions made to the ACPI 3.0 specification.
  83. An old OS that doesn't know about those extensions would answer FALSE,
  84. and a new OS may be able to return TRUE.
  85. For an OS-specific interface, the ACPI spec said that the BIOS and the OS
  86. were to agree on a string of the form such as "Windows-interface_name".
  87. But two bad things happened. First, the Windows ecosystem used _OSI
  88. not as designed, but as a direct replacement for _OS -- identifying
  89. the OS version, rather than an OS supported interface. Indeed, right
  90. from the start, the ACPI 3.0 spec itself codified this misuse
  91. in example code using _OSI("Windows 2001").
  92. This misuse was adopted and continues today.
  93. Linux had no choice but to also return TRUE to _OSI("Windows 2001")
  94. and its successors. To do otherwise would virtually guarantee breaking
  95. a BIOS that has been tested only with that _OSI returning TRUE.
  96. This strategy is problematic, as Linux is never completely compatible with
  97. the latest version of Windows, and sometimes it takes more than a year
  98. to iron out incompatibilities.
  99. Not to be out-done, the Linux community made things worse by returning TRUE
  100. to _OSI("Linux"). Doing so is even worse than the Windows misuse
  101. of _OSI, as "Linux" does not even contain any version information.
  102. _OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's
  103. using it in untested BIOS flows. But some OEM's used _OSI("Linux")
  104. in tested flows to support real Linux features. In 2009, Linux
  105. removed _OSI("Linux"), and added a cmdline parameter to restore it
  106. for legacy systems still needed it. Further a BIOS_BUG warning prints
  107. for all BIOS's that invoke it.
  108. No BIOS should use _OSI("Linux").
  109. The result is a strategy for Linux to maximize compatibility with
  110. ACPI BIOS that are tested on Windows machines. There is a real risk
  111. of over-stating that compatibility; but the alternative has often been
  112. catastrophic failure resulting from the BIOS taking paths that
  113. were never validated under *any* OS.
  114. Do not use _REV
  115. ---------------
  116. Since _OSI("Linux") went away, some BIOS writers used _REV
  117. to support Linux and Windows differences in the same BIOS.
  118. _REV was defined in ACPI 1.0 to return the version of ACPI
  119. supported by the OS and the OS AML interpreter.
  120. Modern Windows returns _REV = 2. Linux used ACPI_CA_SUPPORT_LEVEL,
  121. which would increment, based on the version of the spec supported.
  122. Unfortunately, _REV was also misused. eg. some BIOS would check
  123. for _REV = 3, and do something for Linux, but when Linux returned
  124. _REV = 4, that support broke.
  125. In response to this problem, Linux returns _REV = 2 always,
  126. from mid-2015 onward. The ACPI specification will also be updated
  127. to reflect that _REV is deprecated, and always returns 2.
  128. Apple Mac and _OSI("Darwin")
  129. ----------------------------
  130. On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
  131. to determine if the machine is running Apple OSX.
  132. Like Linux's _OSI("*Windows*") strategy, Linux defaults to
  133. answering YES to _OSI("Darwin") to enable full access
  134. to the hardware and validated BIOS paths seen by OSX.
  135. Just like on Windows-tested platforms, this strategy has risks.
  136. Starting in Linux-3.18, the kernel answered YES to _OSI("Darwin")
  137. for the purpose of enabling Mac Thunderbolt support. Further,
  138. if the kernel noticed _OSI("Darwin") being invoked, it additionally
  139. disabled all _OSI("*Windows*") to keep poorly written Mac BIOS
  140. from going down untested combinations of paths.
  141. The Linux-3.18 change in default caused power regressions on Mac
  142. laptops, and the 3.18 implementation did not allow changing
  143. the default via cmdline "acpi_osi=!Darwin". Linux-4.7 fixed
  144. the ability to use acpi_osi=!Darwin as a workaround, and
  145. we hope to see Mac Thunderbolt power management support in Linux-4.11.