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 <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acinterp.h" 47 48 #define _COMPONENT ACPI_EXECUTER 49 ACPI_MODULE_NAME("exsystem") 50 51 /******************************************************************************* 52 * 53 * FUNCTION: acpi_ex_system_wait_semaphore 54 * 55 * PARAMETERS: semaphore - Semaphore to wait on 56 * timeout - Max time to wait 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: Implements a semaphore wait with a check to see if the 61 * semaphore is available immediately. If it is not, the 62 * interpreter is released before waiting. 63 * 64 ******************************************************************************/ 65 acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) 66 { 67 acpi_status status; 68 69 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); 70 71 status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT); 72 if (ACPI_SUCCESS(status)) { 73 return_ACPI_STATUS(status); 74 } 75 76 if (status == AE_TIME) { 77 78 /* We must wait, so unlock the interpreter */ 79 80 acpi_ex_exit_interpreter(); 81 82 status = acpi_os_wait_semaphore(semaphore, 1, timeout); 83 84 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 85 "*** Thread awake after blocking, %s\n", 86 acpi_format_exception(status))); 87 88 /* Reacquire the interpreter */ 89 90 acpi_ex_enter_interpreter(); 91 } 92 93 return_ACPI_STATUS(status); 94 } 95 96 /******************************************************************************* 97 * 98 * FUNCTION: acpi_ex_system_wait_mutex 99 * 100 * PARAMETERS: mutex - Mutex to wait on 101 * timeout - Max time to wait 102 * 103 * RETURN: Status 104 * 105 * DESCRIPTION: Implements a mutex wait with a check to see if the 106 * mutex is available immediately. If it is not, the 107 * interpreter is released before waiting. 108 * 109 ******************************************************************************/ 110 111 acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) 112 { 113 acpi_status status; 114 115 ACPI_FUNCTION_TRACE(ex_system_wait_mutex); 116 117 status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT); 118 if (ACPI_SUCCESS(status)) { 119 return_ACPI_STATUS(status); 120 } 121 122 if (status == AE_TIME) { 123 124 /* We must wait, so unlock the interpreter */ 125 126 acpi_ex_exit_interpreter(); 127 128 status = acpi_os_acquire_mutex(mutex, timeout); 129 130 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 131 "*** Thread awake after blocking, %s\n", 132 acpi_format_exception(status))); 133 134 /* Reacquire the interpreter */ 135 136 acpi_ex_enter_interpreter(); 137 } 138 139 return_ACPI_STATUS(status); 140 } 141 142 /******************************************************************************* 143 * 144 * FUNCTION: acpi_ex_system_do_stall 145 * 146 * PARAMETERS: how_long - The amount of time to stall, 147 * in microseconds 148 * 149 * RETURN: Status 150 * 151 * DESCRIPTION: Suspend running thread for specified amount of time. 152 * Note: ACPI specification requires that Stall() does not 153 * relinquish the processor, and delays longer than 100 usec 154 * should use Sleep() instead. We allow stalls up to 255 usec 155 * for compatibility with other interpreters and existing BIOSs. 156 * 157 ******************************************************************************/ 158 159 acpi_status acpi_ex_system_do_stall(u32 how_long) 160 { 161 acpi_status status = AE_OK; 162 163 ACPI_FUNCTION_ENTRY(); 164 165 if (how_long > 255) { /* 255 microseconds */ 166 /* 167 * Longer than 255 usec, this is an error 168 * 169 * (ACPI specifies 100 usec as max, but this gives some slack in 170 * order to support existing BIOSs) 171 */ 172 ACPI_ERROR((AE_INFO, "Time parameter is too large (%u)", 173 how_long)); 174 status = AE_AML_OPERAND_VALUE; 175 } else { 176 acpi_os_stall(how_long); 177 } 178 179 return (status); 180 } 181 182 /******************************************************************************* 183 * 184 * FUNCTION: acpi_ex_system_do_sleep 185 * 186 * PARAMETERS: how_long - The amount of time to sleep, 187 * in milliseconds 188 * 189 * RETURN: None 190 * 191 * DESCRIPTION: Sleep the running thread for specified amount of time. 192 * 193 ******************************************************************************/ 194 195 acpi_status acpi_ex_system_do_sleep(u64 how_long) 196 { 197 ACPI_FUNCTION_ENTRY(); 198 199 /* Since this thread will sleep, we must release the interpreter */ 200 201 acpi_ex_exit_interpreter(); 202 203 /* 204 * For compatibility with other ACPI implementations and to prevent 205 * accidental deep sleeps, limit the sleep time to something reasonable. 206 */ 207 if (how_long > ACPI_MAX_SLEEP) { 208 how_long = ACPI_MAX_SLEEP; 209 } 210 211 acpi_os_sleep(how_long); 212 213 /* And now we must get the interpreter again */ 214 215 acpi_ex_enter_interpreter(); 216 return (AE_OK); 217 } 218 219 /******************************************************************************* 220 * 221 * FUNCTION: acpi_ex_system_signal_event 222 * 223 * PARAMETERS: obj_desc - The object descriptor for this op 224 * 225 * RETURN: Status 226 * 227 * DESCRIPTION: Provides an access point to perform synchronization operations 228 * within the AML. 229 * 230 ******************************************************************************/ 231 232 acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) 233 { 234 acpi_status status = AE_OK; 235 236 ACPI_FUNCTION_TRACE(ex_system_signal_event); 237 238 if (obj_desc) { 239 status = 240 acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1); 241 } 242 243 return_ACPI_STATUS(status); 244 } 245 246 /******************************************************************************* 247 * 248 * FUNCTION: acpi_ex_system_wait_event 249 * 250 * PARAMETERS: time_desc - The 'time to delay' object descriptor 251 * obj_desc - The object descriptor for this op 252 * 253 * RETURN: Status 254 * 255 * DESCRIPTION: Provides an access point to perform synchronization operations 256 * within the AML. This operation is a request to wait for an 257 * event. 258 * 259 ******************************************************************************/ 260 261 acpi_status 262 acpi_ex_system_wait_event(union acpi_operand_object *time_desc, 263 union acpi_operand_object *obj_desc) 264 { 265 acpi_status status = AE_OK; 266 267 ACPI_FUNCTION_TRACE(ex_system_wait_event); 268 269 if (obj_desc) { 270 status = 271 acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore, 272 (u16) time_desc->integer. 273 value); 274 } 275 276 return_ACPI_STATUS(status); 277 } 278 279 /******************************************************************************* 280 * 281 * FUNCTION: acpi_ex_system_reset_event 282 * 283 * PARAMETERS: obj_desc - The object descriptor for this op 284 * 285 * RETURN: Status 286 * 287 * DESCRIPTION: Reset an event to a known state. 288 * 289 ******************************************************************************/ 290 291 acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc) 292 { 293 acpi_status status = AE_OK; 294 acpi_semaphore temp_semaphore; 295 296 ACPI_FUNCTION_ENTRY(); 297 298 /* 299 * We are going to simply delete the existing semaphore and 300 * create a new one! 301 */ 302 status = 303 acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore); 304 if (ACPI_SUCCESS(status)) { 305 (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore); 306 obj_desc->event.os_semaphore = temp_semaphore; 307 } 308 309 return (status); 310 } 311