Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: exsystem - Interface to OS services
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acinterp.h"
0013 
0014 #define _COMPONENT          ACPI_EXECUTER
0015 ACPI_MODULE_NAME("exsystem")
0016 
0017 /*******************************************************************************
0018  *
0019  * FUNCTION:    acpi_ex_system_wait_semaphore
0020  *
0021  * PARAMETERS:  semaphore       - Semaphore to wait on
0022  *              timeout         - Max time to wait
0023  *
0024  * RETURN:      Status
0025  *
0026  * DESCRIPTION: Implements a semaphore wait with a check to see if the
0027  *              semaphore is available immediately. If it is not, the
0028  *              interpreter is released before waiting.
0029  *
0030  ******************************************************************************/
0031 acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
0032 {
0033     acpi_status status;
0034 
0035     ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
0036 
0037     status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
0038     if (ACPI_SUCCESS(status)) {
0039         return_ACPI_STATUS(status);
0040     }
0041 
0042     if (status == AE_TIME) {
0043 
0044         /* We must wait, so unlock the interpreter */
0045 
0046         acpi_ex_exit_interpreter();
0047         status = acpi_os_wait_semaphore(semaphore, 1, timeout);
0048 
0049         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0050                   "*** Thread awake after blocking, %s\n",
0051                   acpi_format_exception(status)));
0052 
0053         /* Reacquire the interpreter */
0054 
0055         acpi_ex_enter_interpreter();
0056     }
0057 
0058     return_ACPI_STATUS(status);
0059 }
0060 
0061 /*******************************************************************************
0062  *
0063  * FUNCTION:    acpi_ex_system_wait_mutex
0064  *
0065  * PARAMETERS:  mutex           - Mutex to wait on
0066  *              timeout         - Max time to wait
0067  *
0068  * RETURN:      Status
0069  *
0070  * DESCRIPTION: Implements a mutex wait with a check to see if the
0071  *              mutex is available immediately. If it is not, the
0072  *              interpreter is released before waiting.
0073  *
0074  ******************************************************************************/
0075 
0076 acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
0077 {
0078     acpi_status status;
0079 
0080     ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
0081 
0082     status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT);
0083     if (ACPI_SUCCESS(status)) {
0084         return_ACPI_STATUS(status);
0085     }
0086 
0087     if (status == AE_TIME) {
0088 
0089         /* We must wait, so unlock the interpreter */
0090 
0091         acpi_ex_exit_interpreter();
0092         status = acpi_os_acquire_mutex(mutex, timeout);
0093 
0094         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0095                   "*** Thread awake after blocking, %s\n",
0096                   acpi_format_exception(status)));
0097 
0098         /* Reacquire the interpreter */
0099 
0100         acpi_ex_enter_interpreter();
0101     }
0102 
0103     return_ACPI_STATUS(status);
0104 }
0105 
0106 /*******************************************************************************
0107  *
0108  * FUNCTION:    acpi_ex_system_do_stall
0109  *
0110  * PARAMETERS:  how_long_us     - The amount of time to stall,
0111  *                                in microseconds
0112  *
0113  * RETURN:      Status
0114  *
0115  * DESCRIPTION: Suspend running thread for specified amount of time.
0116  *              Note: ACPI specification requires that Stall() does not
0117  *              relinquish the processor, and delays longer than 100 usec
0118  *              should use Sleep() instead. We allow stalls up to 255 usec
0119  *              for compatibility with other interpreters and existing BIOSs.
0120  *
0121  ******************************************************************************/
0122 
0123 acpi_status acpi_ex_system_do_stall(u32 how_long_us)
0124 {
0125     acpi_status status = AE_OK;
0126 
0127     ACPI_FUNCTION_ENTRY();
0128 
0129     if (how_long_us > 255) {
0130         /*
0131          * Longer than 255 microseconds, this is an error
0132          *
0133          * (ACPI specifies 100 usec as max, but this gives some slack in
0134          * order to support existing BIOSs)
0135          */
0136         ACPI_ERROR((AE_INFO,
0137                 "Time parameter is too large (%u)", how_long_us));
0138         status = AE_AML_OPERAND_VALUE;
0139     } else {
0140         if (how_long_us > 100) {
0141             ACPI_WARNING((AE_INFO,
0142                       "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.",
0143                       how_long_us));
0144         }
0145         acpi_os_stall(how_long_us);
0146     }
0147 
0148     return (status);
0149 }
0150 
0151 /*******************************************************************************
0152  *
0153  * FUNCTION:    acpi_ex_system_do_sleep
0154  *
0155  * PARAMETERS:  how_long_ms     - The amount of time to sleep,
0156  *                                in milliseconds
0157  *
0158  * RETURN:      None
0159  *
0160  * DESCRIPTION: Sleep the running thread for specified amount of time.
0161  *
0162  ******************************************************************************/
0163 
0164 acpi_status acpi_ex_system_do_sleep(u64 how_long_ms)
0165 {
0166     ACPI_FUNCTION_ENTRY();
0167 
0168     /* Since this thread will sleep, we must release the interpreter */
0169 
0170     acpi_ex_exit_interpreter();
0171 
0172     /*
0173      * For compatibility with other ACPI implementations and to prevent
0174      * accidental deep sleeps, limit the sleep time to something reasonable.
0175      */
0176     if (how_long_ms > ACPI_MAX_SLEEP) {
0177         how_long_ms = ACPI_MAX_SLEEP;
0178     }
0179 
0180     acpi_os_sleep(how_long_ms);
0181 
0182     /* And now we must get the interpreter again */
0183 
0184     acpi_ex_enter_interpreter();
0185     return (AE_OK);
0186 }
0187 
0188 /*******************************************************************************
0189  *
0190  * FUNCTION:    acpi_ex_system_signal_event
0191  *
0192  * PARAMETERS:  obj_desc        - The object descriptor for this op
0193  *
0194  * RETURN:      Status
0195  *
0196  * DESCRIPTION: Provides an access point to perform synchronization operations
0197  *              within the AML.
0198  *
0199  ******************************************************************************/
0200 
0201 acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
0202 {
0203     acpi_status status = AE_OK;
0204 
0205     ACPI_FUNCTION_TRACE(ex_system_signal_event);
0206 
0207     if (obj_desc) {
0208         status =
0209             acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
0210     }
0211 
0212     return_ACPI_STATUS(status);
0213 }
0214 
0215 /*******************************************************************************
0216  *
0217  * FUNCTION:    acpi_ex_system_wait_event
0218  *
0219  * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
0220  *              obj_desc        - The object descriptor for this op
0221  *
0222  * RETURN:      Status
0223  *
0224  * DESCRIPTION: Provides an access point to perform synchronization operations
0225  *              within the AML. This operation is a request to wait for an
0226  *              event.
0227  *
0228  ******************************************************************************/
0229 
0230 acpi_status
0231 acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
0232               union acpi_operand_object *obj_desc)
0233 {
0234     acpi_status status = AE_OK;
0235 
0236     ACPI_FUNCTION_TRACE(ex_system_wait_event);
0237 
0238     if (obj_desc) {
0239         status =
0240             acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
0241                           (u16) time_desc->integer.
0242                           value);
0243     }
0244 
0245     return_ACPI_STATUS(status);
0246 }
0247 
0248 /*******************************************************************************
0249  *
0250  * FUNCTION:    acpi_ex_system_reset_event
0251  *
0252  * PARAMETERS:  obj_desc        - The object descriptor for this op
0253  *
0254  * RETURN:      Status
0255  *
0256  * DESCRIPTION: Reset an event to a known state.
0257  *
0258  ******************************************************************************/
0259 
0260 acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
0261 {
0262     acpi_status status = AE_OK;
0263     acpi_semaphore temp_semaphore;
0264 
0265     ACPI_FUNCTION_ENTRY();
0266 
0267     /*
0268      * We are going to simply delete the existing semaphore and
0269      * create a new one!
0270      */
0271     status =
0272         acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
0273     if (ACPI_SUCCESS(status)) {
0274         (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);
0275         obj_desc->event.os_semaphore = temp_semaphore;
0276     }
0277 
0278     return (status);
0279 }