xref: /freebsd/sys/contrib/dev/acpica/components/executer/exsystem.c (revision 0b3105a37d7adcadcb720112fed4dc4e8040be99)
1 /******************************************************************************
2  *
3  * Module Name: exsystem - Interface to OS services
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/acinterp.h>
47 
48 #define _COMPONENT          ACPI_EXECUTER
49         ACPI_MODULE_NAME    ("exsystem")
50 
51 
52 /*******************************************************************************
53  *
54  * FUNCTION:    AcpiExSystemWaitSemaphore
55  *
56  * PARAMETERS:  Semaphore       - Semaphore to wait on
57  *              Timeout         - Max time to wait
58  *
59  * RETURN:      Status
60  *
61  * DESCRIPTION: Implements a semaphore wait with a check to see if the
62  *              semaphore is available immediately. If it is not, the
63  *              interpreter is released before waiting.
64  *
65  ******************************************************************************/
66 
67 ACPI_STATUS
68 AcpiExSystemWaitSemaphore (
69     ACPI_SEMAPHORE          Semaphore,
70     UINT16                  Timeout)
71 {
72     ACPI_STATUS             Status;
73 
74 
75     ACPI_FUNCTION_TRACE (ExSystemWaitSemaphore);
76 
77 
78     Status = AcpiOsWaitSemaphore (Semaphore, 1, ACPI_DO_NOT_WAIT);
79     if (ACPI_SUCCESS (Status))
80     {
81         return_ACPI_STATUS (Status);
82     }
83 
84     if (Status == AE_TIME)
85     {
86         /* We must wait, so unlock the interpreter */
87 
88         AcpiExExitInterpreter ();
89 
90         Status = AcpiOsWaitSemaphore (Semaphore, 1, Timeout);
91 
92         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
93             "*** Thread awake after blocking, %s\n",
94             AcpiFormatException (Status)));
95 
96         /* Reacquire the interpreter */
97 
98        AcpiExEnterInterpreter ();
99     }
100 
101     return_ACPI_STATUS (Status);
102 }
103 
104 
105 /*******************************************************************************
106  *
107  * FUNCTION:    AcpiExSystemWaitMutex
108  *
109  * PARAMETERS:  Mutex           - Mutex to wait on
110  *              Timeout         - Max time to wait
111  *
112  * RETURN:      Status
113  *
114  * DESCRIPTION: Implements a mutex wait with a check to see if the
115  *              mutex is available immediately. If it is not, the
116  *              interpreter is released before waiting.
117  *
118  ******************************************************************************/
119 
120 ACPI_STATUS
121 AcpiExSystemWaitMutex (
122     ACPI_MUTEX              Mutex,
123     UINT16                  Timeout)
124 {
125     ACPI_STATUS             Status;
126 
127 
128     ACPI_FUNCTION_TRACE (ExSystemWaitMutex);
129 
130 
131     Status = AcpiOsAcquireMutex (Mutex, ACPI_DO_NOT_WAIT);
132     if (ACPI_SUCCESS (Status))
133     {
134         return_ACPI_STATUS (Status);
135     }
136 
137     if (Status == AE_TIME)
138     {
139         /* We must wait, so unlock the interpreter */
140 
141         AcpiExExitInterpreter ();
142 
143         Status = AcpiOsAcquireMutex (Mutex, Timeout);
144 
145         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
146             "*** Thread awake after blocking, %s\n",
147             AcpiFormatException (Status)));
148 
149         /* Reacquire the interpreter */
150 
151         AcpiExEnterInterpreter ();
152     }
153 
154     return_ACPI_STATUS (Status);
155 }
156 
157 
158 /*******************************************************************************
159  *
160  * FUNCTION:    AcpiExSystemDoStall
161  *
162  * PARAMETERS:  HowLong         - The amount of time to stall,
163  *                                in microseconds
164  *
165  * RETURN:      Status
166  *
167  * DESCRIPTION: Suspend running thread for specified amount of time.
168  *              Note: ACPI specification requires that Stall() does not
169  *              relinquish the processor, and delays longer than 100 usec
170  *              should use Sleep() instead. We allow stalls up to 255 usec
171  *              for compatibility with other interpreters and existing BIOSs.
172  *
173  ******************************************************************************/
174 
175 ACPI_STATUS
176 AcpiExSystemDoStall (
177     UINT32                  HowLong)
178 {
179     ACPI_STATUS             Status = AE_OK;
180 
181 
182     ACPI_FUNCTION_ENTRY ();
183 
184 
185     if (HowLong > 255) /* 255 microseconds */
186     {
187         /*
188          * Longer than 255 usec, this is an error
189          *
190          * (ACPI specifies 100 usec as max, but this gives some slack in
191          * order to support existing BIOSs)
192          */
193         ACPI_ERROR ((AE_INFO, "Time parameter is too large (%u)",
194             HowLong));
195         Status = AE_AML_OPERAND_VALUE;
196     }
197     else
198     {
199         AcpiOsStall (HowLong);
200     }
201 
202     return (Status);
203 }
204 
205 
206 /*******************************************************************************
207  *
208  * FUNCTION:    AcpiExSystemDoSleep
209  *
210  * PARAMETERS:  HowLong         - The amount of time to sleep,
211  *                                in milliseconds
212  *
213  * RETURN:      None
214  *
215  * DESCRIPTION: Sleep the running thread for specified amount of time.
216  *
217  ******************************************************************************/
218 
219 ACPI_STATUS
220 AcpiExSystemDoSleep (
221     UINT64                  HowLong)
222 {
223     ACPI_FUNCTION_ENTRY ();
224 
225 
226     /* Since this thread will sleep, we must release the interpreter */
227 
228     AcpiExExitInterpreter ();
229 
230     /*
231      * For compatibility with other ACPI implementations and to prevent
232      * accidental deep sleeps, limit the sleep time to something reasonable.
233      */
234     if (HowLong > ACPI_MAX_SLEEP)
235     {
236         HowLong = ACPI_MAX_SLEEP;
237     }
238 
239     AcpiOsSleep (HowLong);
240 
241     /* And now we must get the interpreter again */
242 
243     AcpiExEnterInterpreter ();
244     return (AE_OK);
245 }
246 
247 
248 /*******************************************************************************
249  *
250  * FUNCTION:    AcpiExSystemSignalEvent
251  *
252  * PARAMETERS:  ObjDesc         - The object descriptor for this op
253  *
254  * RETURN:      Status
255  *
256  * DESCRIPTION: Provides an access point to perform synchronization operations
257  *              within the AML.
258  *
259  ******************************************************************************/
260 
261 ACPI_STATUS
262 AcpiExSystemSignalEvent (
263     ACPI_OPERAND_OBJECT     *ObjDesc)
264 {
265     ACPI_STATUS             Status = AE_OK;
266 
267 
268     ACPI_FUNCTION_TRACE (ExSystemSignalEvent);
269 
270 
271     if (ObjDesc)
272     {
273         Status = AcpiOsSignalSemaphore (ObjDesc->Event.OsSemaphore, 1);
274     }
275 
276     return_ACPI_STATUS (Status);
277 }
278 
279 
280 /*******************************************************************************
281  *
282  * FUNCTION:    AcpiExSystemWaitEvent
283  *
284  * PARAMETERS:  TimeDesc        - The 'time to delay' object descriptor
285  *              ObjDesc         - The object descriptor for this op
286  *
287  * RETURN:      Status
288  *
289  * DESCRIPTION: Provides an access point to perform synchronization operations
290  *              within the AML. This operation is a request to wait for an
291  *              event.
292  *
293  ******************************************************************************/
294 
295 ACPI_STATUS
296 AcpiExSystemWaitEvent (
297     ACPI_OPERAND_OBJECT     *TimeDesc,
298     ACPI_OPERAND_OBJECT     *ObjDesc)
299 {
300     ACPI_STATUS             Status = AE_OK;
301 
302 
303     ACPI_FUNCTION_TRACE (ExSystemWaitEvent);
304 
305 
306     if (ObjDesc)
307     {
308         Status = AcpiExSystemWaitSemaphore (ObjDesc->Event.OsSemaphore,
309                     (UINT16) TimeDesc->Integer.Value);
310     }
311 
312     return_ACPI_STATUS (Status);
313 }
314 
315 
316 /*******************************************************************************
317  *
318  * FUNCTION:    AcpiExSystemResetEvent
319  *
320  * PARAMETERS:  ObjDesc         - The object descriptor for this op
321  *
322  * RETURN:      Status
323  *
324  * DESCRIPTION: Reset an event to a known state.
325  *
326  ******************************************************************************/
327 
328 ACPI_STATUS
329 AcpiExSystemResetEvent (
330     ACPI_OPERAND_OBJECT     *ObjDesc)
331 {
332     ACPI_STATUS             Status = AE_OK;
333     ACPI_SEMAPHORE          TempSemaphore;
334 
335 
336     ACPI_FUNCTION_ENTRY ();
337 
338 
339     /*
340      * We are going to simply delete the existing semaphore and
341      * create a new one!
342      */
343     Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, &TempSemaphore);
344     if (ACPI_SUCCESS (Status))
345     {
346         (void) AcpiOsDeleteSemaphore (ObjDesc->Event.OsSemaphore);
347         ObjDesc->Event.OsSemaphore = TempSemaphore;
348     }
349 
350     return (Status);
351 }
352