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