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