1 | /****************************************************************************** |
2 | * |
3 | * Module Name: exsystem - Interface to OS services |
4 | * |
5 | *****************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, 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 |
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 | Status = AcpiOsWaitSemaphore (Semaphore, 1, Timeout); |
90 | |
91 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, |
92 | "*** Thread awake after blocking, %s\n" , |
93 | AcpiFormatException (Status))); |
94 | |
95 | /* Reacquire the interpreter */ |
96 | |
97 | AcpiExEnterInterpreter (); |
98 | } |
99 | |
100 | return_ACPI_STATUS (Status); |
101 | } |
102 | |
103 | |
104 | /******************************************************************************* |
105 | * |
106 | * FUNCTION: AcpiExSystemWaitMutex |
107 | * |
108 | * PARAMETERS: Mutex - Mutex to wait on |
109 | * Timeout - Max time to wait |
110 | * |
111 | * RETURN: Status |
112 | * |
113 | * DESCRIPTION: Implements a mutex wait with a check to see if the |
114 | * mutex is available immediately. If it is not, the |
115 | * interpreter is released before waiting. |
116 | * |
117 | ******************************************************************************/ |
118 | |
119 | ACPI_STATUS |
120 | AcpiExSystemWaitMutex ( |
121 | ACPI_MUTEX Mutex, |
122 | UINT16 Timeout) |
123 | { |
124 | ACPI_STATUS Status; |
125 | |
126 | |
127 | ACPI_FUNCTION_TRACE (ExSystemWaitMutex); |
128 | |
129 | |
130 | Status = AcpiOsAcquireMutex (Mutex, ACPI_DO_NOT_WAIT); |
131 | if (ACPI_SUCCESS (Status)) |
132 | { |
133 | return_ACPI_STATUS (Status); |
134 | } |
135 | |
136 | if (Status == AE_TIME) |
137 | { |
138 | /* We must wait, so unlock the interpreter */ |
139 | |
140 | AcpiExExitInterpreter (); |
141 | Status = AcpiOsAcquireMutex (Mutex, Timeout); |
142 | |
143 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, |
144 | "*** Thread awake after blocking, %s\n" , |
145 | AcpiFormatException (Status))); |
146 | |
147 | /* Reacquire the interpreter */ |
148 | |
149 | AcpiExEnterInterpreter (); |
150 | } |
151 | |
152 | return_ACPI_STATUS (Status); |
153 | } |
154 | |
155 | |
156 | /******************************************************************************* |
157 | * |
158 | * FUNCTION: AcpiExSystemDoStall |
159 | * |
160 | * PARAMETERS: HowLong - The amount of time to stall, |
161 | * in microseconds |
162 | * |
163 | * RETURN: Status |
164 | * |
165 | * DESCRIPTION: Suspend running thread for specified amount of time. |
166 | * Note: ACPI specification requires that Stall() does not |
167 | * relinquish the processor, and delays longer than 100 usec |
168 | * should use Sleep() instead. We allow stalls up to 255 usec |
169 | * for compatibility with other interpreters and existing BIOSs. |
170 | * |
171 | ******************************************************************************/ |
172 | |
173 | ACPI_STATUS |
174 | AcpiExSystemDoStall ( |
175 | UINT32 HowLong) |
176 | { |
177 | ACPI_STATUS Status = AE_OK; |
178 | |
179 | |
180 | ACPI_FUNCTION_ENTRY (); |
181 | |
182 | |
183 | if (HowLong > 255) /* 255 microseconds */ |
184 | { |
185 | /* |
186 | * Longer than 255 usec, this is an error |
187 | * |
188 | * (ACPI specifies 100 usec as max, but this gives some slack in |
189 | * order to support existing BIOSs) |
190 | */ |
191 | ACPI_ERROR ((AE_INFO, |
192 | "Time parameter is too large (%u)" , HowLong)); |
193 | Status = AE_AML_OPERAND_VALUE; |
194 | } |
195 | else |
196 | { |
197 | AcpiOsStall (HowLong); |
198 | } |
199 | |
200 | return (Status); |
201 | } |
202 | |
203 | |
204 | /******************************************************************************* |
205 | * |
206 | * FUNCTION: AcpiExSystemDoSleep |
207 | * |
208 | * PARAMETERS: HowLong - The amount of time to sleep, |
209 | * in milliseconds |
210 | * |
211 | * RETURN: None |
212 | * |
213 | * DESCRIPTION: Sleep the running thread for specified amount of time. |
214 | * |
215 | ******************************************************************************/ |
216 | |
217 | ACPI_STATUS |
218 | AcpiExSystemDoSleep ( |
219 | UINT64 HowLong) |
220 | { |
221 | ACPI_FUNCTION_ENTRY (); |
222 | |
223 | |
224 | /* Since this thread will sleep, we must release the interpreter */ |
225 | |
226 | AcpiExExitInterpreter (); |
227 | |
228 | /* |
229 | * For compatibility with other ACPI implementations and to prevent |
230 | * accidental deep sleeps, limit the sleep time to something reasonable. |
231 | */ |
232 | if (HowLong > ACPI_MAX_SLEEP) |
233 | { |
234 | HowLong = ACPI_MAX_SLEEP; |
235 | } |
236 | |
237 | AcpiOsSleep (HowLong); |
238 | |
239 | /* And now we must get the interpreter again */ |
240 | |
241 | AcpiExEnterInterpreter (); |
242 | return (AE_OK); |
243 | } |
244 | |
245 | |
246 | /******************************************************************************* |
247 | * |
248 | * FUNCTION: AcpiExSystemSignalEvent |
249 | * |
250 | * PARAMETERS: ObjDesc - The object descriptor for this op |
251 | * |
252 | * RETURN: Status |
253 | * |
254 | * DESCRIPTION: Provides an access point to perform synchronization operations |
255 | * within the AML. |
256 | * |
257 | ******************************************************************************/ |
258 | |
259 | ACPI_STATUS |
260 | AcpiExSystemSignalEvent ( |
261 | ACPI_OPERAND_OBJECT *ObjDesc) |
262 | { |
263 | ACPI_STATUS Status = AE_OK; |
264 | |
265 | |
266 | ACPI_FUNCTION_TRACE (ExSystemSignalEvent); |
267 | |
268 | |
269 | if (ObjDesc) |
270 | { |
271 | Status = AcpiOsSignalSemaphore (ObjDesc->Event.OsSemaphore, 1); |
272 | } |
273 | |
274 | return_ACPI_STATUS (Status); |
275 | } |
276 | |
277 | |
278 | /******************************************************************************* |
279 | * |
280 | * FUNCTION: AcpiExSystemWaitEvent |
281 | * |
282 | * PARAMETERS: TimeDesc - The 'time to delay' object descriptor |
283 | * ObjDesc - The object descriptor for this op |
284 | * |
285 | * RETURN: Status |
286 | * |
287 | * DESCRIPTION: Provides an access point to perform synchronization operations |
288 | * within the AML. This operation is a request to wait for an |
289 | * event. |
290 | * |
291 | ******************************************************************************/ |
292 | |
293 | ACPI_STATUS |
294 | AcpiExSystemWaitEvent ( |
295 | ACPI_OPERAND_OBJECT *TimeDesc, |
296 | ACPI_OPERAND_OBJECT *ObjDesc) |
297 | { |
298 | ACPI_STATUS Status = AE_OK; |
299 | |
300 | |
301 | ACPI_FUNCTION_TRACE (ExSystemWaitEvent); |
302 | |
303 | |
304 | if (ObjDesc) |
305 | { |
306 | Status = AcpiExSystemWaitSemaphore (ObjDesc->Event.OsSemaphore, |
307 | (UINT16) TimeDesc->Integer.Value); |
308 | } |
309 | |
310 | return_ACPI_STATUS (Status); |
311 | } |
312 | |
313 | |
314 | /******************************************************************************* |
315 | * |
316 | * FUNCTION: AcpiExSystemResetEvent |
317 | * |
318 | * PARAMETERS: ObjDesc - The object descriptor for this op |
319 | * |
320 | * RETURN: Status |
321 | * |
322 | * DESCRIPTION: Reset an event to a known state. |
323 | * |
324 | ******************************************************************************/ |
325 | |
326 | ACPI_STATUS |
327 | AcpiExSystemResetEvent ( |
328 | ACPI_OPERAND_OBJECT *ObjDesc) |
329 | { |
330 | ACPI_STATUS Status = AE_OK; |
331 | ACPI_SEMAPHORE TempSemaphore; |
332 | |
333 | |
334 | ACPI_FUNCTION_ENTRY (); |
335 | |
336 | |
337 | /* |
338 | * We are going to simply delete the existing semaphore and |
339 | * create a new one! |
340 | */ |
341 | Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, &TempSemaphore); |
342 | if (ACPI_SUCCESS (Status)) |
343 | { |
344 | (void) AcpiOsDeleteSemaphore (ObjDesc->Event.OsSemaphore); |
345 | ObjDesc->Event.OsSemaphore = TempSemaphore; |
346 | } |
347 | |
348 | return (Status); |
349 | } |
350 | |