1 /******************************************************************************
2 *
3 * Module Name: exsystem - Interface to OS services
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2014, 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 "acpi.h"
45 #include "accommon.h"
46 #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
AcpiExSystemWaitSemaphore(ACPI_SEMAPHORE Semaphore,UINT16 Timeout)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
AcpiExSystemWaitMutex(ACPI_MUTEX Mutex,UINT16 Timeout)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
AcpiExSystemDoStall(UINT32 HowLong)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
AcpiExSystemDoSleep(UINT64 HowLong)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
AcpiExSystemSignalEvent(ACPI_OPERAND_OBJECT * ObjDesc)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
AcpiExSystemWaitEvent(ACPI_OPERAND_OBJECT * TimeDesc,ACPI_OPERAND_OBJECT * ObjDesc)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
AcpiExSystemResetEvent(ACPI_OPERAND_OBJECT * ObjDesc)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