1c2c66affSColin Finck /******************************************************************************
2c2c66affSColin Finck *
3c2c66affSColin Finck * Module Name: utosi - Support for the _OSI predefined control method
4c2c66affSColin Finck *
5c2c66affSColin Finck *****************************************************************************/
6c2c66affSColin Finck
7c2c66affSColin Finck /*
8*03b24380SThomas Faber * Copyright (C) 2000 - 2022, Intel Corp.
9c2c66affSColin Finck * All rights reserved.
10c2c66affSColin Finck *
11c2c66affSColin Finck * Redistribution and use in source and binary forms, with or without
12c2c66affSColin Finck * modification, are permitted provided that the following conditions
13c2c66affSColin Finck * are met:
14c2c66affSColin Finck * 1. Redistributions of source code must retain the above copyright
15c2c66affSColin Finck * notice, this list of conditions, and the following disclaimer,
16c2c66affSColin Finck * without modification.
17c2c66affSColin Finck * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18c2c66affSColin Finck * substantially similar to the "NO WARRANTY" disclaimer below
19c2c66affSColin Finck * ("Disclaimer") and any redistribution must be conditioned upon
20c2c66affSColin Finck * including a substantially similar Disclaimer requirement for further
21c2c66affSColin Finck * binary redistribution.
22c2c66affSColin Finck * 3. Neither the names of the above-listed copyright holders nor the names
23c2c66affSColin Finck * of any contributors may be used to endorse or promote products derived
24c2c66affSColin Finck * from this software without specific prior written permission.
25c2c66affSColin Finck *
26c2c66affSColin Finck * Alternatively, this software may be distributed under the terms of the
27c2c66affSColin Finck * GNU General Public License ("GPL") version 2 as published by the Free
28c2c66affSColin Finck * Software Foundation.
29c2c66affSColin Finck *
30c2c66affSColin Finck * NO WARRANTY
31c2c66affSColin Finck * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32c2c66affSColin Finck * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
336eb8cc49SThomas Faber * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34c2c66affSColin Finck * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35c2c66affSColin Finck * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36c2c66affSColin Finck * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37c2c66affSColin Finck * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38c2c66affSColin Finck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39c2c66affSColin Finck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40c2c66affSColin Finck * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41c2c66affSColin Finck * POSSIBILITY OF SUCH DAMAGES.
42c2c66affSColin Finck */
43c2c66affSColin Finck
44c2c66affSColin Finck #include "acpi.h"
45c2c66affSColin Finck #include "accommon.h"
46c2c66affSColin Finck
47c2c66affSColin Finck
48c2c66affSColin Finck #define _COMPONENT ACPI_UTILITIES
49c2c66affSColin Finck ACPI_MODULE_NAME ("utosi")
50c2c66affSColin Finck
51c2c66affSColin Finck
52c2c66affSColin Finck /******************************************************************************
53c2c66affSColin Finck *
54c2c66affSColin Finck * ACPICA policy for new _OSI strings:
55c2c66affSColin Finck *
56c2c66affSColin Finck * It is the stated policy of ACPICA that new _OSI strings will be integrated
57c2c66affSColin Finck * into this module as soon as possible after they are defined. It is strongly
58c2c66affSColin Finck * recommended that all ACPICA hosts mirror this policy and integrate any
59c2c66affSColin Finck * changes to this module as soon as possible. There are several historical
60c2c66affSColin Finck * reasons behind this policy:
61c2c66affSColin Finck *
62c2c66affSColin Finck * 1) New BIOSs tend to test only the case where the host responds TRUE to
63c2c66affSColin Finck * the latest version of Windows, which would respond to the latest/newest
64c2c66affSColin Finck * _OSI string. Not responding TRUE to the latest version of Windows will
65c2c66affSColin Finck * risk executing untested code paths throughout the DSDT and SSDTs.
66c2c66affSColin Finck *
67c2c66affSColin Finck * 2) If a new _OSI string is recognized only after a significant delay, this
68c2c66affSColin Finck * has the potential to cause problems on existing working machines because
69c2c66affSColin Finck * of the possibility that a new and different path through the ASL code
70c2c66affSColin Finck * will be executed.
71c2c66affSColin Finck *
72c2c66affSColin Finck * 3) New _OSI strings are tending to come out about once per year. A delay
73c2c66affSColin Finck * in recognizing a new string for a significant amount of time risks the
74c2c66affSColin Finck * release of another string which only compounds the initial problem.
75c2c66affSColin Finck *
76c2c66affSColin Finck *****************************************************************************/
77c2c66affSColin Finck
78c2c66affSColin Finck
79c2c66affSColin Finck /*
80c2c66affSColin Finck * Strings supported by the _OSI predefined control method (which is
81c2c66affSColin Finck * implemented internally within this module.)
82c2c66affSColin Finck *
83c2c66affSColin Finck * March 2009: Removed "Linux" as this host no longer wants to respond true
84c2c66affSColin Finck * for this string. Basically, the only safe OS strings are windows-related
85c2c66affSColin Finck * and in many or most cases represent the only test path within the
86c2c66affSColin Finck * BIOS-provided ASL code.
87c2c66affSColin Finck *
88c2c66affSColin Finck * The last element of each entry is used to track the newest version of
89c2c66affSColin Finck * Windows that the BIOS has requested.
90c2c66affSColin Finck */
91c2c66affSColin Finck static ACPI_INTERFACE_INFO AcpiDefaultSupportedInterfaces[] =
92c2c66affSColin Finck {
93c2c66affSColin Finck /* Operating System Vendor Strings */
94c2c66affSColin Finck
95c2c66affSColin Finck {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */
96c2c66affSColin Finck {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */
97c2c66affSColin Finck {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
98c2c66affSColin Finck {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
99c2c66affSColin Finck {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
100c2c66affSColin Finck {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
101c2c66affSColin Finck {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
102c2c66affSColin Finck {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
103c2c66affSColin Finck {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
104c2c66affSColin Finck {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
105c2c66affSColin Finck {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
106c2c66affSColin Finck {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */
1075d4f13f6SThomas Faber {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8_1}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */
108c2c66affSColin Finck {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10}, /* Windows 10 - Added 03/2015 */
109ec55f0ebSThomas Faber {"Windows 2016", NULL, 0, ACPI_OSI_WIN_10_RS1}, /* Windows 10 version 1607 - Added 12/2017 */
110ec55f0ebSThomas Faber {"Windows 2017", NULL, 0, ACPI_OSI_WIN_10_RS2}, /* Windows 10 version 1703 - Added 12/2017 */
1116847cc3aSThomas Faber {"Windows 2017.2", NULL, 0, ACPI_OSI_WIN_10_RS3}, /* Windows 10 version 1709 - Added 02/2018 */
112ecbd6353SThomas Faber {"Windows 2018", NULL, 0, ACPI_OSI_WIN_10_RS4}, /* Windows 10 version 1803 - Added 11/2018 */
113ecbd6353SThomas Faber {"Windows 2018.2", NULL, 0, ACPI_OSI_WIN_10_RS5}, /* Windows 10 version 1809 - Added 11/2018 */
1145d4f13f6SThomas Faber {"Windows 2019", NULL, 0, ACPI_OSI_WIN_10_19H1}, /* Windows 10 version 1903 - Added 08/2019 */
1159b247f6aSThomas Faber {"Windows 2020", NULL, 0, ACPI_OSI_WIN_10_20H1}, /* Windows 10 version 2004 - Added 08/2021 */
116*03b24380SThomas Faber {"Windows 2021", NULL, 0, ACPI_OSI_WIN_11}, /* Windows 11 - Added 01/2022 */
117c2c66affSColin Finck
118c2c66affSColin Finck /* Feature Group Strings */
119c2c66affSColin Finck
120c2c66affSColin Finck {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},
121c2c66affSColin Finck
122c2c66affSColin Finck /*
123c2c66affSColin Finck * All "optional" feature group strings (features that are implemented
124c2c66affSColin Finck * by the host) should be dynamically modified to VALID by the host via
125c2c66affSColin Finck * AcpiInstallInterface or AcpiUpdateInterfaces. Such optional feature
126c2c66affSColin Finck * group strings are set as INVALID by default here.
127c2c66affSColin Finck */
128c2c66affSColin Finck
129c2c66affSColin Finck {"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
130c2c66affSColin Finck {"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
131c2c66affSColin Finck {"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
132c2c66affSColin Finck {"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
133c2c66affSColin Finck {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}
134c2c66affSColin Finck };
135c2c66affSColin Finck
136c2c66affSColin Finck
137c2c66affSColin Finck /*******************************************************************************
138c2c66affSColin Finck *
139c2c66affSColin Finck * FUNCTION: AcpiUtInitializeInterfaces
140c2c66affSColin Finck *
141c2c66affSColin Finck * PARAMETERS: None
142c2c66affSColin Finck *
143c2c66affSColin Finck * RETURN: Status
144c2c66affSColin Finck *
145c2c66affSColin Finck * DESCRIPTION: Initialize the global _OSI supported interfaces list
146c2c66affSColin Finck *
147c2c66affSColin Finck ******************************************************************************/
148c2c66affSColin Finck
149c2c66affSColin Finck ACPI_STATUS
AcpiUtInitializeInterfaces(void)150c2c66affSColin Finck AcpiUtInitializeInterfaces (
151c2c66affSColin Finck void)
152c2c66affSColin Finck {
153c2c66affSColin Finck ACPI_STATUS Status;
154c2c66affSColin Finck UINT32 i;
155c2c66affSColin Finck
156c2c66affSColin Finck
157c2c66affSColin Finck Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
158c2c66affSColin Finck if (ACPI_FAILURE (Status))
159c2c66affSColin Finck {
160c2c66affSColin Finck return (Status);
161c2c66affSColin Finck }
162c2c66affSColin Finck
163c2c66affSColin Finck AcpiGbl_SupportedInterfaces = AcpiDefaultSupportedInterfaces;
164c2c66affSColin Finck
165c2c66affSColin Finck /* Link the static list of supported interfaces */
166c2c66affSColin Finck
167c2c66affSColin Finck for (i = 0;
168c2c66affSColin Finck i < (ACPI_ARRAY_LENGTH (AcpiDefaultSupportedInterfaces) - 1);
169c2c66affSColin Finck i++)
170c2c66affSColin Finck {
171c2c66affSColin Finck AcpiDefaultSupportedInterfaces[i].Next =
172c2c66affSColin Finck &AcpiDefaultSupportedInterfaces[(ACPI_SIZE) i + 1];
173c2c66affSColin Finck }
174c2c66affSColin Finck
175c2c66affSColin Finck AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
176c2c66affSColin Finck return (AE_OK);
177c2c66affSColin Finck }
178c2c66affSColin Finck
179c2c66affSColin Finck
180c2c66affSColin Finck /*******************************************************************************
181c2c66affSColin Finck *
182c2c66affSColin Finck * FUNCTION: AcpiUtInterfaceTerminate
183c2c66affSColin Finck *
184c2c66affSColin Finck * PARAMETERS: None
185c2c66affSColin Finck *
186c2c66affSColin Finck * RETURN: Status
187c2c66affSColin Finck *
188c2c66affSColin Finck * DESCRIPTION: Delete all interfaces in the global list. Sets
189c2c66affSColin Finck * AcpiGbl_SupportedInterfaces to NULL.
190c2c66affSColin Finck *
191c2c66affSColin Finck ******************************************************************************/
192c2c66affSColin Finck
193c2c66affSColin Finck ACPI_STATUS
AcpiUtInterfaceTerminate(void)194c2c66affSColin Finck AcpiUtInterfaceTerminate (
195c2c66affSColin Finck void)
196c2c66affSColin Finck {
197c2c66affSColin Finck ACPI_STATUS Status;
198c2c66affSColin Finck ACPI_INTERFACE_INFO *NextInterface;
199c2c66affSColin Finck
200c2c66affSColin Finck
201c2c66affSColin Finck Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
202c2c66affSColin Finck if (ACPI_FAILURE (Status))
203c2c66affSColin Finck {
204c2c66affSColin Finck return (Status);
205c2c66affSColin Finck }
206c2c66affSColin Finck
207c2c66affSColin Finck NextInterface = AcpiGbl_SupportedInterfaces;
208c2c66affSColin Finck while (NextInterface)
209c2c66affSColin Finck {
210c2c66affSColin Finck AcpiGbl_SupportedInterfaces = NextInterface->Next;
211c2c66affSColin Finck
212c2c66affSColin Finck if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
213c2c66affSColin Finck {
214c2c66affSColin Finck /* Only interfaces added at runtime can be freed */
215c2c66affSColin Finck
216c2c66affSColin Finck ACPI_FREE (NextInterface->Name);
217c2c66affSColin Finck ACPI_FREE (NextInterface);
218c2c66affSColin Finck }
219c2c66affSColin Finck else
220c2c66affSColin Finck {
221c2c66affSColin Finck /* Interface is in static list. Reset it to invalid or valid. */
222c2c66affSColin Finck
223c2c66affSColin Finck if (NextInterface->Flags & ACPI_OSI_DEFAULT_INVALID)
224c2c66affSColin Finck {
225c2c66affSColin Finck NextInterface->Flags |= ACPI_OSI_INVALID;
226c2c66affSColin Finck }
227c2c66affSColin Finck else
228c2c66affSColin Finck {
229c2c66affSColin Finck NextInterface->Flags &= ~ACPI_OSI_INVALID;
230c2c66affSColin Finck }
231c2c66affSColin Finck }
232c2c66affSColin Finck
233c2c66affSColin Finck NextInterface = AcpiGbl_SupportedInterfaces;
234c2c66affSColin Finck }
235c2c66affSColin Finck
236c2c66affSColin Finck AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
237c2c66affSColin Finck return (AE_OK);
238c2c66affSColin Finck }
239c2c66affSColin Finck
240c2c66affSColin Finck
241c2c66affSColin Finck /*******************************************************************************
242c2c66affSColin Finck *
243c2c66affSColin Finck * FUNCTION: AcpiUtInstallInterface
244c2c66affSColin Finck *
245c2c66affSColin Finck * PARAMETERS: InterfaceName - The interface to install
246c2c66affSColin Finck *
247c2c66affSColin Finck * RETURN: Status
248c2c66affSColin Finck *
249c2c66affSColin Finck * DESCRIPTION: Install the interface into the global interface list.
250c2c66affSColin Finck * Caller MUST hold AcpiGbl_OsiMutex
251c2c66affSColin Finck *
252c2c66affSColin Finck ******************************************************************************/
253c2c66affSColin Finck
254c2c66affSColin Finck ACPI_STATUS
AcpiUtInstallInterface(ACPI_STRING InterfaceName)255c2c66affSColin Finck AcpiUtInstallInterface (
256c2c66affSColin Finck ACPI_STRING InterfaceName)
257c2c66affSColin Finck {
258c2c66affSColin Finck ACPI_INTERFACE_INFO *InterfaceInfo;
259c2c66affSColin Finck
260c2c66affSColin Finck
261c2c66affSColin Finck /* Allocate info block and space for the name string */
262c2c66affSColin Finck
263c2c66affSColin Finck InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO));
264c2c66affSColin Finck if (!InterfaceInfo)
265c2c66affSColin Finck {
266c2c66affSColin Finck return (AE_NO_MEMORY);
267c2c66affSColin Finck }
268c2c66affSColin Finck
269c2c66affSColin Finck InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (strlen (InterfaceName) + 1);
270c2c66affSColin Finck if (!InterfaceInfo->Name)
271c2c66affSColin Finck {
272c2c66affSColin Finck ACPI_FREE (InterfaceInfo);
273c2c66affSColin Finck return (AE_NO_MEMORY);
274c2c66affSColin Finck }
275c2c66affSColin Finck
276c2c66affSColin Finck /* Initialize new info and insert at the head of the global list */
277c2c66affSColin Finck
278c2c66affSColin Finck strcpy (InterfaceInfo->Name, InterfaceName);
279c2c66affSColin Finck InterfaceInfo->Flags = ACPI_OSI_DYNAMIC;
280c2c66affSColin Finck InterfaceInfo->Next = AcpiGbl_SupportedInterfaces;
281c2c66affSColin Finck
282c2c66affSColin Finck AcpiGbl_SupportedInterfaces = InterfaceInfo;
283c2c66affSColin Finck return (AE_OK);
284c2c66affSColin Finck }
285c2c66affSColin Finck
286c2c66affSColin Finck
287c2c66affSColin Finck /*******************************************************************************
288c2c66affSColin Finck *
289c2c66affSColin Finck * FUNCTION: AcpiUtRemoveInterface
290c2c66affSColin Finck *
291c2c66affSColin Finck * PARAMETERS: InterfaceName - The interface to remove
292c2c66affSColin Finck *
293c2c66affSColin Finck * RETURN: Status
294c2c66affSColin Finck *
295c2c66affSColin Finck * DESCRIPTION: Remove the interface from the global interface list.
296c2c66affSColin Finck * Caller MUST hold AcpiGbl_OsiMutex
297c2c66affSColin Finck *
298c2c66affSColin Finck ******************************************************************************/
299c2c66affSColin Finck
300c2c66affSColin Finck ACPI_STATUS
AcpiUtRemoveInterface(ACPI_STRING InterfaceName)301c2c66affSColin Finck AcpiUtRemoveInterface (
302c2c66affSColin Finck ACPI_STRING InterfaceName)
303c2c66affSColin Finck {
304c2c66affSColin Finck ACPI_INTERFACE_INFO *PreviousInterface;
305c2c66affSColin Finck ACPI_INTERFACE_INFO *NextInterface;
306c2c66affSColin Finck
307c2c66affSColin Finck
308c2c66affSColin Finck PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces;
309c2c66affSColin Finck while (NextInterface)
310c2c66affSColin Finck {
311c2c66affSColin Finck if (!strcmp (InterfaceName, NextInterface->Name))
312c2c66affSColin Finck {
313c2c66affSColin Finck /*
314c2c66affSColin Finck * Found: name is in either the static list
315c2c66affSColin Finck * or was added at runtime
316c2c66affSColin Finck */
317c2c66affSColin Finck if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
318c2c66affSColin Finck {
319c2c66affSColin Finck /* Interface was added dynamically, remove and free it */
320c2c66affSColin Finck
321c2c66affSColin Finck if (PreviousInterface == NextInterface)
322c2c66affSColin Finck {
323c2c66affSColin Finck AcpiGbl_SupportedInterfaces = NextInterface->Next;
324c2c66affSColin Finck }
325c2c66affSColin Finck else
326c2c66affSColin Finck {
327c2c66affSColin Finck PreviousInterface->Next = NextInterface->Next;
328c2c66affSColin Finck }
329c2c66affSColin Finck
330c2c66affSColin Finck ACPI_FREE (NextInterface->Name);
331c2c66affSColin Finck ACPI_FREE (NextInterface);
332c2c66affSColin Finck }
333c2c66affSColin Finck else
334c2c66affSColin Finck {
335c2c66affSColin Finck /*
336c2c66affSColin Finck * Interface is in static list. If marked invalid, then
337c2c66affSColin Finck * it does not actually exist. Else, mark it invalid.
338c2c66affSColin Finck */
339c2c66affSColin Finck if (NextInterface->Flags & ACPI_OSI_INVALID)
340c2c66affSColin Finck {
341c2c66affSColin Finck return (AE_NOT_EXIST);
342c2c66affSColin Finck }
343c2c66affSColin Finck
344c2c66affSColin Finck NextInterface->Flags |= ACPI_OSI_INVALID;
345c2c66affSColin Finck }
346c2c66affSColin Finck
347c2c66affSColin Finck return (AE_OK);
348c2c66affSColin Finck }
349c2c66affSColin Finck
350c2c66affSColin Finck PreviousInterface = NextInterface;
351c2c66affSColin Finck NextInterface = NextInterface->Next;
352c2c66affSColin Finck }
353c2c66affSColin Finck
354c2c66affSColin Finck /* Interface was not found */
355c2c66affSColin Finck
356c2c66affSColin Finck return (AE_NOT_EXIST);
357c2c66affSColin Finck }
358c2c66affSColin Finck
359c2c66affSColin Finck
360c2c66affSColin Finck /*******************************************************************************
361c2c66affSColin Finck *
362c2c66affSColin Finck * FUNCTION: AcpiUtUpdateInterfaces
363c2c66affSColin Finck *
364c2c66affSColin Finck * PARAMETERS: Action - Actions to be performed during the
365c2c66affSColin Finck * update
366c2c66affSColin Finck *
367c2c66affSColin Finck * RETURN: Status
368c2c66affSColin Finck *
369c2c66affSColin Finck * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
370c2c66affSColin Finck * strings or/and feature group strings.
371c2c66affSColin Finck * Caller MUST hold AcpiGbl_OsiMutex
372c2c66affSColin Finck *
373c2c66affSColin Finck ******************************************************************************/
374c2c66affSColin Finck
375c2c66affSColin Finck ACPI_STATUS
AcpiUtUpdateInterfaces(UINT8 Action)376c2c66affSColin Finck AcpiUtUpdateInterfaces (
377c2c66affSColin Finck UINT8 Action)
378c2c66affSColin Finck {
379c2c66affSColin Finck ACPI_INTERFACE_INFO *NextInterface;
380c2c66affSColin Finck
381c2c66affSColin Finck
382c2c66affSColin Finck NextInterface = AcpiGbl_SupportedInterfaces;
383c2c66affSColin Finck while (NextInterface)
384c2c66affSColin Finck {
385c2c66affSColin Finck if (((NextInterface->Flags & ACPI_OSI_FEATURE) &&
386c2c66affSColin Finck (Action & ACPI_FEATURE_STRINGS)) ||
387c2c66affSColin Finck (!(NextInterface->Flags & ACPI_OSI_FEATURE) &&
388c2c66affSColin Finck (Action & ACPI_VENDOR_STRINGS)))
389c2c66affSColin Finck {
390c2c66affSColin Finck if (Action & ACPI_DISABLE_INTERFACES)
391c2c66affSColin Finck {
392c2c66affSColin Finck /* Mark the interfaces as invalid */
393c2c66affSColin Finck
394c2c66affSColin Finck NextInterface->Flags |= ACPI_OSI_INVALID;
395c2c66affSColin Finck }
396c2c66affSColin Finck else
397c2c66affSColin Finck {
398c2c66affSColin Finck /* Mark the interfaces as valid */
399c2c66affSColin Finck
400c2c66affSColin Finck NextInterface->Flags &= ~ACPI_OSI_INVALID;
401c2c66affSColin Finck }
402c2c66affSColin Finck }
403c2c66affSColin Finck
404c2c66affSColin Finck NextInterface = NextInterface->Next;
405c2c66affSColin Finck }
406c2c66affSColin Finck
407c2c66affSColin Finck return (AE_OK);
408c2c66affSColin Finck }
409c2c66affSColin Finck
410c2c66affSColin Finck
411c2c66affSColin Finck /*******************************************************************************
412c2c66affSColin Finck *
413c2c66affSColin Finck * FUNCTION: AcpiUtGetInterface
414c2c66affSColin Finck *
415c2c66affSColin Finck * PARAMETERS: InterfaceName - The interface to find
416c2c66affSColin Finck *
417c2c66affSColin Finck * RETURN: ACPI_INTERFACE_INFO if found. NULL if not found.
418c2c66affSColin Finck *
419c2c66affSColin Finck * DESCRIPTION: Search for the specified interface name in the global list.
420c2c66affSColin Finck * Caller MUST hold AcpiGbl_OsiMutex
421c2c66affSColin Finck *
422c2c66affSColin Finck ******************************************************************************/
423c2c66affSColin Finck
424c2c66affSColin Finck ACPI_INTERFACE_INFO *
AcpiUtGetInterface(ACPI_STRING InterfaceName)425c2c66affSColin Finck AcpiUtGetInterface (
426c2c66affSColin Finck ACPI_STRING InterfaceName)
427c2c66affSColin Finck {
428c2c66affSColin Finck ACPI_INTERFACE_INFO *NextInterface;
429c2c66affSColin Finck
430c2c66affSColin Finck
431c2c66affSColin Finck NextInterface = AcpiGbl_SupportedInterfaces;
432c2c66affSColin Finck while (NextInterface)
433c2c66affSColin Finck {
434c2c66affSColin Finck if (!strcmp (InterfaceName, NextInterface->Name))
435c2c66affSColin Finck {
436c2c66affSColin Finck return (NextInterface);
437c2c66affSColin Finck }
438c2c66affSColin Finck
439c2c66affSColin Finck NextInterface = NextInterface->Next;
440c2c66affSColin Finck }
441c2c66affSColin Finck
442c2c66affSColin Finck return (NULL);
443c2c66affSColin Finck }
444c2c66affSColin Finck
445c2c66affSColin Finck
446c2c66affSColin Finck /*******************************************************************************
447c2c66affSColin Finck *
448c2c66affSColin Finck * FUNCTION: AcpiUtOsiImplementation
449c2c66affSColin Finck *
450c2c66affSColin Finck * PARAMETERS: WalkState - Current walk state
451c2c66affSColin Finck *
452c2c66affSColin Finck * RETURN: Status
453c2c66affSColin Finck * Integer: TRUE (0) if input string is matched
454c2c66affSColin Finck * FALSE (-1) if string is not matched
455c2c66affSColin Finck *
456c2c66affSColin Finck * DESCRIPTION: Implementation of the _OSI predefined control method. When
457c2c66affSColin Finck * an invocation of _OSI is encountered in the system AML,
458c2c66affSColin Finck * control is transferred to this function.
459c2c66affSColin Finck *
460c2c66affSColin Finck * (August 2016)
461c2c66affSColin Finck * Note: _OSI is now defined to return "Ones" to indicate a match, for
462c2c66affSColin Finck * compatibility with other ACPI implementations. On a 32-bit DSDT, Ones
463c2c66affSColin Finck * is 0xFFFFFFFF. On a 64-bit DSDT, Ones is 0xFFFFFFFFFFFFFFFF
464c2c66affSColin Finck * (ACPI_UINT64_MAX).
465c2c66affSColin Finck *
466c2c66affSColin Finck * This function always returns ACPI_UINT64_MAX for TRUE, and later code
467c2c66affSColin Finck * will truncate this to 32 bits if necessary.
468c2c66affSColin Finck *
469c2c66affSColin Finck ******************************************************************************/
470c2c66affSColin Finck
471c2c66affSColin Finck ACPI_STATUS
AcpiUtOsiImplementation(ACPI_WALK_STATE * WalkState)472c2c66affSColin Finck AcpiUtOsiImplementation (
473c2c66affSColin Finck ACPI_WALK_STATE *WalkState)
474c2c66affSColin Finck {
475c2c66affSColin Finck ACPI_OPERAND_OBJECT *StringDesc;
476c2c66affSColin Finck ACPI_OPERAND_OBJECT *ReturnDesc;
477c2c66affSColin Finck ACPI_INTERFACE_INFO *InterfaceInfo;
478c2c66affSColin Finck ACPI_INTERFACE_HANDLER InterfaceHandler;
479c2c66affSColin Finck ACPI_STATUS Status;
480c2c66affSColin Finck UINT64 ReturnValue;
481c2c66affSColin Finck
482c2c66affSColin Finck
483c2c66affSColin Finck ACPI_FUNCTION_TRACE (UtOsiImplementation);
484c2c66affSColin Finck
485c2c66affSColin Finck
486c2c66affSColin Finck /* Validate the string input argument (from the AML caller) */
487c2c66affSColin Finck
488c2c66affSColin Finck StringDesc = WalkState->Arguments[0].Object;
489c2c66affSColin Finck if (!StringDesc ||
490c2c66affSColin Finck (StringDesc->Common.Type != ACPI_TYPE_STRING))
491c2c66affSColin Finck {
492c2c66affSColin Finck return_ACPI_STATUS (AE_TYPE);
493c2c66affSColin Finck }
494c2c66affSColin Finck
495c2c66affSColin Finck /* Create a return object */
496c2c66affSColin Finck
497c2c66affSColin Finck ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
498c2c66affSColin Finck if (!ReturnDesc)
499c2c66affSColin Finck {
500c2c66affSColin Finck return_ACPI_STATUS (AE_NO_MEMORY);
501c2c66affSColin Finck }
502c2c66affSColin Finck
503c2c66affSColin Finck /* Default return value is 0, NOT SUPPORTED */
504c2c66affSColin Finck
505c2c66affSColin Finck ReturnValue = 0;
506c2c66affSColin Finck Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
507c2c66affSColin Finck if (ACPI_FAILURE (Status))
508c2c66affSColin Finck {
509c2c66affSColin Finck AcpiUtRemoveReference (ReturnDesc);
510c2c66affSColin Finck return_ACPI_STATUS (Status);
511c2c66affSColin Finck }
512c2c66affSColin Finck
513c2c66affSColin Finck /* Lookup the interface in the global _OSI list */
514c2c66affSColin Finck
515c2c66affSColin Finck InterfaceInfo = AcpiUtGetInterface (StringDesc->String.Pointer);
516c2c66affSColin Finck if (InterfaceInfo &&
517c2c66affSColin Finck !(InterfaceInfo->Flags & ACPI_OSI_INVALID))
518c2c66affSColin Finck {
519c2c66affSColin Finck /*
520c2c66affSColin Finck * The interface is supported.
521c2c66affSColin Finck * Update the OsiData if necessary. We keep track of the latest
522c2c66affSColin Finck * version of Windows that has been requested by the BIOS.
523c2c66affSColin Finck */
524c2c66affSColin Finck if (InterfaceInfo->Value > AcpiGbl_OsiData)
525c2c66affSColin Finck {
526c2c66affSColin Finck AcpiGbl_OsiData = InterfaceInfo->Value;
527c2c66affSColin Finck }
528c2c66affSColin Finck
529c2c66affSColin Finck ReturnValue = ACPI_UINT64_MAX;
530c2c66affSColin Finck }
531c2c66affSColin Finck
532c2c66affSColin Finck AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
533c2c66affSColin Finck
534c2c66affSColin Finck /*
535c2c66affSColin Finck * Invoke an optional _OSI interface handler. The host OS may wish
536c2c66affSColin Finck * to do some interface-specific handling. For example, warn about
537c2c66affSColin Finck * certain interfaces or override the true/false support value.
538c2c66affSColin Finck */
539c2c66affSColin Finck InterfaceHandler = AcpiGbl_InterfaceHandler;
540c2c66affSColin Finck if (InterfaceHandler)
541c2c66affSColin Finck {
542c2c66affSColin Finck if (InterfaceHandler (
543c2c66affSColin Finck StringDesc->String.Pointer, (UINT32) ReturnValue))
544c2c66affSColin Finck {
545c2c66affSColin Finck ReturnValue = ACPI_UINT64_MAX;
546c2c66affSColin Finck }
547c2c66affSColin Finck }
548c2c66affSColin Finck
549c2c66affSColin Finck ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
550c2c66affSColin Finck "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
551c2c66affSColin Finck StringDesc->String.Pointer, ReturnValue == 0 ? "not " : ""));
552c2c66affSColin Finck
553c2c66affSColin Finck /* Complete the return object */
554c2c66affSColin Finck
555c2c66affSColin Finck ReturnDesc->Integer.Value = ReturnValue;
556c2c66affSColin Finck WalkState->ReturnDesc = ReturnDesc;
557c2c66affSColin Finck return_ACPI_STATUS (AE_OK);
558c2c66affSColin Finck }
559