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