exsystem.c revision 306536
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 <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
67ACPI_STATUS
68AcpiExSystemWaitSemaphore (
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
119ACPI_STATUS
120AcpiExSystemWaitMutex (
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
173ACPI_STATUS
174AcpiExSystemDoStall (
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
217ACPI_STATUS
218AcpiExSystemDoSleep (
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
259ACPI_STATUS
260AcpiExSystemSignalEvent (
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
293ACPI_STATUS
294AcpiExSystemWaitEvent (
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
326ACPI_STATUS
327AcpiExSystemResetEvent (
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