281 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: exsystem - Interface to OS services5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acinterp.h"13 14#define _COMPONENT ACPI_EXECUTER15ACPI_MODULE_NAME("exsystem")16 17/*******************************************************************************18 *19 * FUNCTION: acpi_ex_system_wait_semaphore20 *21 * PARAMETERS: semaphore - Semaphore to wait on22 * timeout - Max time to wait23 *24 * RETURN: Status25 *26 * DESCRIPTION: Implements a semaphore wait with a check to see if the27 * semaphore is available immediately. If it is not, the28 * interpreter is released before waiting.29 *30 ******************************************************************************/31acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)32{33 acpi_status status;34 35 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);36 37 status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);38 if (ACPI_SUCCESS(status)) {39 return_ACPI_STATUS(status);40 }41 42 if (status == AE_TIME) {43 44 /* We must wait, so unlock the interpreter */45 46 acpi_ex_exit_interpreter();47 status = acpi_os_wait_semaphore(semaphore, 1, timeout);48 49 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,50 "*** Thread awake after blocking, %s\n",51 acpi_format_exception(status)));52 53 /* Reacquire the interpreter */54 55 acpi_ex_enter_interpreter();56 }57 58 return_ACPI_STATUS(status);59}60 61/*******************************************************************************62 *63 * FUNCTION: acpi_ex_system_wait_mutex64 *65 * PARAMETERS: mutex - Mutex to wait on66 * timeout - Max time to wait67 *68 * RETURN: Status69 *70 * DESCRIPTION: Implements a mutex wait with a check to see if the71 * mutex is available immediately. If it is not, the72 * interpreter is released before waiting.73 *74 ******************************************************************************/75 76acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)77{78 acpi_status status;79 80 ACPI_FUNCTION_TRACE(ex_system_wait_mutex);81 82 status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT);83 if (ACPI_SUCCESS(status)) {84 return_ACPI_STATUS(status);85 }86 87 if (status == AE_TIME) {88 89 /* We must wait, so unlock the interpreter */90 91 acpi_ex_exit_interpreter();92 status = acpi_os_acquire_mutex(mutex, timeout);93 94 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,95 "*** Thread awake after blocking, %s\n",96 acpi_format_exception(status)));97 98 /* Reacquire the interpreter */99 100 acpi_ex_enter_interpreter();101 }102 103 return_ACPI_STATUS(status);104}105 106/*******************************************************************************107 *108 * FUNCTION: acpi_ex_system_do_stall109 *110 * PARAMETERS: how_long_us - The amount of time to stall,111 * in microseconds112 *113 * RETURN: Status114 *115 * DESCRIPTION: Suspend running thread for specified amount of time.116 * Note: ACPI specification requires that Stall() does not117 * relinquish the processor, and delays longer than 100 usec118 * should use Sleep() instead. We allow stalls up to 255 usec119 * for compatibility with other interpreters and existing BIOSs.120 *121 ******************************************************************************/122 123acpi_status acpi_ex_system_do_stall(u32 how_long_us)124{125 acpi_status status = AE_OK;126 127 ACPI_FUNCTION_ENTRY();128 129 if (how_long_us > 255) {130 /*131 * Longer than 255 microseconds, this is an error132 *133 * (ACPI specifies 100 usec as max, but this gives some slack in134 * order to support existing BIOSs)135 */136 ACPI_ERROR_ONCE((AE_INFO,137 "Time parameter is too large (%u)",138 how_long_us));139 status = AE_AML_OPERAND_VALUE;140 } else {141 if (how_long_us > 100) {142 ACPI_WARNING_ONCE((AE_INFO,143 "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.",144 how_long_us));145 }146 acpi_os_stall(how_long_us);147 }148 149 return (status);150}151 152/*******************************************************************************153 *154 * FUNCTION: acpi_ex_system_do_sleep155 *156 * PARAMETERS: how_long_ms - The amount of time to sleep,157 * in milliseconds158 *159 * RETURN: None160 *161 * DESCRIPTION: Sleep the running thread for specified amount of time.162 *163 ******************************************************************************/164 165acpi_status acpi_ex_system_do_sleep(u64 how_long_ms)166{167 ACPI_FUNCTION_ENTRY();168 169 /* Since this thread will sleep, we must release the interpreter */170 171 acpi_ex_exit_interpreter();172 173 /*174 * For compatibility with other ACPI implementations and to prevent175 * accidental deep sleeps, limit the sleep time to something reasonable.176 */177 if (how_long_ms > ACPI_MAX_SLEEP) {178 how_long_ms = ACPI_MAX_SLEEP;179 }180 181 acpi_os_sleep(how_long_ms);182 183 /* And now we must get the interpreter again */184 185 acpi_ex_enter_interpreter();186 return (AE_OK);187}188 189/*******************************************************************************190 *191 * FUNCTION: acpi_ex_system_signal_event192 *193 * PARAMETERS: obj_desc - The object descriptor for this op194 *195 * RETURN: Status196 *197 * DESCRIPTION: Provides an access point to perform synchronization operations198 * within the AML.199 *200 ******************************************************************************/201 202acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)203{204 acpi_status status = AE_OK;205 206 ACPI_FUNCTION_TRACE(ex_system_signal_event);207 208 if (obj_desc) {209 status =210 acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);211 }212 213 return_ACPI_STATUS(status);214}215 216/*******************************************************************************217 *218 * FUNCTION: acpi_ex_system_wait_event219 *220 * PARAMETERS: time_desc - The 'time to delay' object descriptor221 * obj_desc - The object descriptor for this op222 *223 * RETURN: Status224 *225 * DESCRIPTION: Provides an access point to perform synchronization operations226 * within the AML. This operation is a request to wait for an227 * event.228 *229 ******************************************************************************/230 231acpi_status232acpi_ex_system_wait_event(union acpi_operand_object *time_desc,233 union acpi_operand_object *obj_desc)234{235 acpi_status status = AE_OK;236 237 ACPI_FUNCTION_TRACE(ex_system_wait_event);238 239 if (obj_desc) {240 status =241 acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,242 (u16) time_desc->integer.243 value);244 }245 246 return_ACPI_STATUS(status);247}248 249/*******************************************************************************250 *251 * FUNCTION: acpi_ex_system_reset_event252 *253 * PARAMETERS: obj_desc - The object descriptor for this op254 *255 * RETURN: Status256 *257 * DESCRIPTION: Reset an event to a known state.258 *259 ******************************************************************************/260 261acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)262{263 acpi_status status = AE_OK;264 acpi_semaphore temp_semaphore;265 266 ACPI_FUNCTION_ENTRY();267 268 /*269 * We are going to simply delete the existing semaphore and270 * create a new one!271 */272 status =273 acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);274 if (ACPI_SUCCESS(status)) {275 (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);276 obj_desc->event.os_semaphore = temp_semaphore;277 }278 279 return (status);280}281