exsystem.c revision 281075
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
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
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
120ACPI_STATUS
121AcpiExSystemWaitMutex (
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
175ACPI_STATUS
176AcpiExSystemDoStall (
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
219ACPI_STATUS
220AcpiExSystemDoSleep (
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
261ACPI_STATUS
262AcpiExSystemSignalEvent (
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
295ACPI_STATUS
296AcpiExSystemWaitEvent (
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
328ACPI_STATUS
329AcpiExSystemResetEvent (
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