blob: f329b01672bb67f332bb0731bf1056391ff03ecc [file] [log] [blame]
Erik Schmauss95857632018-03-14 16:13:07 -07001// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/******************************************************************************
3 *
4 * Module Name: exsystem - Interface to OS services
5 *
Bob Moore800ba7c2020-01-10 11:31:49 -08006 * Copyright (C) 2000 - 2020, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
Erik Schmauss95857632018-03-14 16:13:07 -07008 *****************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050011#include "accommon.h"
12#include "acinterp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
14#define _COMPONENT ACPI_EXECUTER
Len Brown4be44fc2005-08-05 00:44:28 -040015ACPI_MODULE_NAME("exsystem")
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
17/*******************************************************************************
18 *
19 * FUNCTION: acpi_ex_system_wait_semaphore
20 *
Bob Mooreba494be2012-07-12 09:40:10 +080021 * PARAMETERS: semaphore - Semaphore to wait on
22 * timeout - Max time to wait
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 *
24 * RETURN: Status
25 *
26 * DESCRIPTION: Implements a semaphore wait with a check to see if the
Bob Moore73a30902012-10-31 02:26:55 +000027 * semaphore is available immediately. If it is not, the
Bob Mooref6dd9222006-07-07 20:44:38 -040028 * interpreter is released before waiting.
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 *
30 ******************************************************************************/
Bob Moore967440e32006-06-23 17:04:00 -040031acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
Linus Torvalds1da177e2005-04-16 15:20:36 -070032{
Len Brown4be44fc2005-08-05 00:44:28 -040033 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Bob Mooreb229cf92006-04-21 17:15:00 -040035 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Bob Moore967440e32006-06-23 17:04:00 -040037 status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
Len Brown4be44fc2005-08-05 00:44:28 -040038 if (ACPI_SUCCESS(status)) {
39 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 }
41
42 if (status == AE_TIME) {
Bob Moore52fc0b02006-10-02 00:00:00 -040043
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 /* We must wait, so unlock the interpreter */
45
Lv Zhenge2b8ddc2014-03-24 14:48:45 +080046 acpi_ex_exit_interpreter();
Len Brown4be44fc2005-08-05 00:44:28 -040047 status = acpi_os_wait_semaphore(semaphore, 1, timeout);
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Len Brown4be44fc2005-08-05 00:44:28 -040049 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
50 "*** Thread awake after blocking, %s\n",
51 acpi_format_exception(status)));
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
53 /* Reacquire the interpreter */
54
Lv Zhenge2b8ddc2014-03-24 14:48:45 +080055 acpi_ex_enter_interpreter();
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 }
57
Len Brown4be44fc2005-08-05 00:44:28 -040058 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059}
60
Linus Torvalds1da177e2005-04-16 15:20:36 -070061/*******************************************************************************
62 *
Bob Moore967440e32006-06-23 17:04:00 -040063 * FUNCTION: acpi_ex_system_wait_mutex
64 *
Bob Mooreba494be2012-07-12 09:40:10 +080065 * PARAMETERS: mutex - Mutex to wait on
66 * timeout - Max time to wait
Bob Moore967440e32006-06-23 17:04:00 -040067 *
68 * RETURN: Status
69 *
Bob Mooref6dd9222006-07-07 20:44:38 -040070 * DESCRIPTION: Implements a mutex wait with a check to see if the
Bob Moore73a30902012-10-31 02:26:55 +000071 * mutex is available immediately. If it is not, the
Bob Mooref6dd9222006-07-07 20:44:38 -040072 * interpreter is released before waiting.
Bob Moore967440e32006-06-23 17:04:00 -040073 *
74 ******************************************************************************/
75
76acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
77{
78 acpi_status status;
Bob Moore967440e32006-06-23 17:04:00 -040079
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
Lv Zhenge2b8ddc2014-03-24 14:48:45 +080091 acpi_ex_exit_interpreter();
Bob Moore967440e32006-06-23 17:04:00 -040092 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
Lv Zhenge2b8ddc2014-03-24 14:48:45 +0800100 acpi_ex_enter_interpreter();
Bob Moore967440e32006-06-23 17:04:00 -0400101 }
102
103 return_ACPI_STATUS(status);
104}
105
106/*******************************************************************************
107 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 * FUNCTION: acpi_ex_system_do_stall
109 *
Robert Moore44f6c012005-04-18 22:49:35 -0400110 * PARAMETERS: how_long - The amount of time to stall,
111 * in microseconds
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 *
113 * RETURN: Status
114 *
115 * DESCRIPTION: Suspend running thread for specified amount of time.
116 * Note: ACPI specification requires that Stall() does not
117 * relinquish the processor, and delays longer than 100 usec
Bob Moore73a30902012-10-31 02:26:55 +0000118 * should use Sleep() instead. We allow stalls up to 255 usec
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 * for compatibility with other interpreters and existing BIOSs.
120 *
121 ******************************************************************************/
122
Len Brown4be44fc2005-08-05 00:44:28 -0400123acpi_status acpi_ex_system_do_stall(u32 how_long)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124{
Len Brown4be44fc2005-08-05 00:44:28 -0400125 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Len Brown4be44fc2005-08-05 00:44:28 -0400127 ACPI_FUNCTION_ENTRY();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Len Brown4be44fc2005-08-05 00:44:28 -0400129 if (how_long > 255) { /* 255 microseconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 /*
131 * Longer than 255 usec, this is an error
132 *
133 * (ACPI specifies 100 usec as max, but this gives some slack in
134 * order to support existing BIOSs)
135 */
Bob Moore1fad8732015-12-29 13:54:36 +0800136 ACPI_ERROR((AE_INFO,
137 "Time parameter is too large (%u)", how_long));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 status = AE_AML_OPERAND_VALUE;
Len Brown4be44fc2005-08-05 00:44:28 -0400139 } else {
140 acpi_os_stall(how_long);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 }
142
143 return (status);
144}
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146/*******************************************************************************
147 *
Bob Mooreada241d2010-04-27 11:48:02 +0800148 * FUNCTION: acpi_ex_system_do_sleep
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 *
Bob Mooreada241d2010-04-27 11:48:02 +0800150 * PARAMETERS: how_long - The amount of time to sleep,
Robert Moore44f6c012005-04-18 22:49:35 -0400151 * in milliseconds
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 *
153 * RETURN: None
154 *
Bob Mooreada241d2010-04-27 11:48:02 +0800155 * DESCRIPTION: Sleep the running thread for specified amount of time.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 *
157 ******************************************************************************/
158
Bob Mooreada241d2010-04-27 11:48:02 +0800159acpi_status acpi_ex_system_do_sleep(u64 how_long)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160{
Len Brown4be44fc2005-08-05 00:44:28 -0400161 ACPI_FUNCTION_ENTRY();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162
163 /* Since this thread will sleep, we must release the interpreter */
164
Lv Zhenge2b8ddc2014-03-24 14:48:45 +0800165 acpi_ex_exit_interpreter();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
Bob Moore9cbfa182010-05-26 11:22:41 +0800167 /*
168 * For compatibility with other ACPI implementations and to prevent
169 * accidental deep sleeps, limit the sleep time to something reasonable.
170 */
171 if (how_long > ACPI_MAX_SLEEP) {
172 how_long = ACPI_MAX_SLEEP;
173 }
174
Len Brown4be44fc2005-08-05 00:44:28 -0400175 acpi_os_sleep(how_long);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176
177 /* And now we must get the interpreter again */
178
Lv Zhenge2b8ddc2014-03-24 14:48:45 +0800179 acpi_ex_enter_interpreter();
Len Brown4d2acd92007-05-09 22:56:38 -0400180 return (AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181}
182
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183/*******************************************************************************
184 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 * FUNCTION: acpi_ex_system_signal_event
186 *
Robert Moore44f6c012005-04-18 22:49:35 -0400187 * PARAMETERS: obj_desc - The object descriptor for this op
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 *
Robert Moore44f6c012005-04-18 22:49:35 -0400189 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 *
191 * DESCRIPTION: Provides an access point to perform synchronization operations
192 * within the AML.
193 *
194 ******************************************************************************/
195
Bob Moorec81da662007-02-02 19:48:18 +0300196acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197{
Len Brown4be44fc2005-08-05 00:44:28 -0400198 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
Bob Mooreb229cf92006-04-21 17:15:00 -0400200 ACPI_FUNCTION_TRACE(ex_system_signal_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201
202 if (obj_desc) {
Bob Moore967440e32006-06-23 17:04:00 -0400203 status =
204 acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 }
206
Len Brown4be44fc2005-08-05 00:44:28 -0400207 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208}
209
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210/*******************************************************************************
211 *
212 * FUNCTION: acpi_ex_system_wait_event
213 *
Robert Moore44f6c012005-04-18 22:49:35 -0400214 * PARAMETERS: time_desc - The 'time to delay' object descriptor
215 * obj_desc - The object descriptor for this op
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 *
217 * RETURN: Status
218 *
219 * DESCRIPTION: Provides an access point to perform synchronization operations
Bob Moore73a30902012-10-31 02:26:55 +0000220 * within the AML. This operation is a request to wait for an
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 * event.
222 *
223 ******************************************************************************/
224
225acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400226acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
227 union acpi_operand_object *obj_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228{
Len Brown4be44fc2005-08-05 00:44:28 -0400229 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
Bob Mooreb229cf92006-04-21 17:15:00 -0400231 ACPI_FUNCTION_TRACE(ex_system_wait_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
233 if (obj_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400234 status =
Bob Moore967440e32006-06-23 17:04:00 -0400235 acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
Len Brown4be44fc2005-08-05 00:44:28 -0400236 (u16) time_desc->integer.
237 value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
239
Len Brown4be44fc2005-08-05 00:44:28 -0400240 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241}
242
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243/*******************************************************************************
244 *
245 * FUNCTION: acpi_ex_system_reset_event
246 *
Robert Moore44f6c012005-04-18 22:49:35 -0400247 * PARAMETERS: obj_desc - The object descriptor for this op
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 *
249 * RETURN: Status
250 *
251 * DESCRIPTION: Reset an event to a known state.
252 *
253 ******************************************************************************/
254
Len Brown4be44fc2005-08-05 00:44:28 -0400255acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256{
Len Brown4be44fc2005-08-05 00:44:28 -0400257 acpi_status status = AE_OK;
Bob Moore967440e32006-06-23 17:04:00 -0400258 acpi_semaphore temp_semaphore;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
Len Brown4be44fc2005-08-05 00:44:28 -0400260 ACPI_FUNCTION_ENTRY();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261
262 /*
263 * We are going to simply delete the existing semaphore and
264 * create a new one!
265 */
Len Brown4be44fc2005-08-05 00:44:28 -0400266 status =
267 acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
268 if (ACPI_SUCCESS(status)) {
Bob Moore967440e32006-06-23 17:04:00 -0400269 (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);
270 obj_desc->event.os_semaphore = temp_semaphore;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 }
272
273 return (status);
274}