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