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