167754Smsmith/****************************************************************************** 267754Smsmith * 377424Smsmith * Module Name: exsystem - Interface to OS services 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 4767754Smsmith 4877424Smsmith#define _COMPONENT ACPI_EXECUTER 4991116Smsmith ACPI_MODULE_NAME ("exsystem") 5067754Smsmith 5167754Smsmith 5267754Smsmith/******************************************************************************* 5367754Smsmith * 5477424Smsmith * FUNCTION: AcpiExSystemWaitSemaphore 5567754Smsmith * 56151937Sjkim * PARAMETERS: Semaphore - Semaphore to wait on 57151937Sjkim * Timeout - Max time to wait 5867754Smsmith * 5967754Smsmith * RETURN: Status 6067754Smsmith * 6167754Smsmith * DESCRIPTION: Implements a semaphore wait with a check to see if the 62241973Sjkim * semaphore is available immediately. If it is not, the 63167802Sjkim * interpreter is released before waiting. 6467754Smsmith * 6567754Smsmith ******************************************************************************/ 6667754Smsmith 6767754SmsmithACPI_STATUS 6877424SmsmithAcpiExSystemWaitSemaphore ( 69167802Sjkim ACPI_SEMAPHORE Semaphore, 70107325Siwasaki UINT16 Timeout) 7167754Smsmith{ 7267754Smsmith ACPI_STATUS Status; 7367754Smsmith 7467754Smsmith 75167802Sjkim ACPI_FUNCTION_TRACE (ExSystemWaitSemaphore); 7667754Smsmith 7783174Smsmith 78167802Sjkim Status = AcpiOsWaitSemaphore (Semaphore, 1, ACPI_DO_NOT_WAIT); 7967754Smsmith if (ACPI_SUCCESS (Status)) 8067754Smsmith { 8167754Smsmith return_ACPI_STATUS (Status); 8267754Smsmith } 8367754Smsmith 8467754Smsmith if (Status == AE_TIME) 8567754Smsmith { 8667754Smsmith /* We must wait, so unlock the interpreter */ 8767754Smsmith 88281075Sdim AcpiExExitInterpreter (); 8967754Smsmith Status = AcpiOsWaitSemaphore (Semaphore, 1, Timeout); 9067754Smsmith 91151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 92151937Sjkim "*** Thread awake after blocking, %s\n", 9380062Smsmith AcpiFormatException (Status))); 9477424Smsmith 9567754Smsmith /* Reacquire the interpreter */ 9667754Smsmith 97306536Sjkim AcpiExEnterInterpreter (); 98167802Sjkim } 9967754Smsmith 100167802Sjkim return_ACPI_STATUS (Status); 101167802Sjkim} 102167802Sjkim 103167802Sjkim 104167802Sjkim/******************************************************************************* 105167802Sjkim * 106167802Sjkim * FUNCTION: AcpiExSystemWaitMutex 107167802Sjkim * 108167802Sjkim * PARAMETERS: Mutex - Mutex to wait on 109167802Sjkim * Timeout - Max time to wait 110167802Sjkim * 111167802Sjkim * RETURN: Status 112167802Sjkim * 113167802Sjkim * DESCRIPTION: Implements a mutex wait with a check to see if the 114241973Sjkim * mutex is available immediately. If it is not, the 115167802Sjkim * interpreter is released before waiting. 116167802Sjkim * 117167802Sjkim ******************************************************************************/ 118167802Sjkim 119167802SjkimACPI_STATUS 120167802SjkimAcpiExSystemWaitMutex ( 121167802Sjkim ACPI_MUTEX Mutex, 122167802Sjkim UINT16 Timeout) 123167802Sjkim{ 124167802Sjkim ACPI_STATUS Status; 125167802Sjkim 126167802Sjkim 127167802Sjkim ACPI_FUNCTION_TRACE (ExSystemWaitMutex); 128167802Sjkim 129167802Sjkim 130167802Sjkim Status = AcpiOsAcquireMutex (Mutex, ACPI_DO_NOT_WAIT); 131167802Sjkim if (ACPI_SUCCESS (Status)) 132167802Sjkim { 133167802Sjkim return_ACPI_STATUS (Status); 13467754Smsmith } 13567754Smsmith 136167802Sjkim if (Status == AE_TIME) 137167802Sjkim { 138167802Sjkim /* We must wait, so unlock the interpreter */ 139167802Sjkim 140281075Sdim AcpiExExitInterpreter (); 141167802Sjkim Status = AcpiOsAcquireMutex (Mutex, Timeout); 142167802Sjkim 143167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 144167802Sjkim "*** Thread awake after blocking, %s\n", 145167802Sjkim AcpiFormatException (Status))); 146167802Sjkim 147167802Sjkim /* Reacquire the interpreter */ 148167802Sjkim 149281075Sdim AcpiExEnterInterpreter (); 150167802Sjkim } 151167802Sjkim 15267754Smsmith return_ACPI_STATUS (Status); 15367754Smsmith} 15467754Smsmith 15567754Smsmith 15667754Smsmith/******************************************************************************* 15767754Smsmith * 15877424Smsmith * FUNCTION: AcpiExSystemDoStall 15967754Smsmith * 160151937Sjkim * PARAMETERS: HowLong - The amount of time to stall, 161151937Sjkim * in microseconds 16267754Smsmith * 16391116Smsmith * RETURN: Status 16467754Smsmith * 16567754Smsmith * DESCRIPTION: Suspend running thread for specified amount of time. 166123315Snjl * Note: ACPI specification requires that Stall() does not 167123315Snjl * relinquish the processor, and delays longer than 100 usec 168241973Sjkim * should use Sleep() instead. We allow stalls up to 255 usec 169123315Snjl * for compatibility with other interpreters and existing BIOSs. 17067754Smsmith * 17167754Smsmith ******************************************************************************/ 17267754Smsmith 17391116SmsmithACPI_STATUS 17477424SmsmithAcpiExSystemDoStall ( 17567754Smsmith UINT32 HowLong) 17667754Smsmith{ 17791116Smsmith ACPI_STATUS Status = AE_OK; 17867754Smsmith 17983174Smsmith 18091116Smsmith ACPI_FUNCTION_ENTRY (); 18191116Smsmith 18291116Smsmith 183123315Snjl if (HowLong > 255) /* 255 microseconds */ 18467754Smsmith { 185123315Snjl /* 186123315Snjl * Longer than 255 usec, this is an error 187123315Snjl * 188123315Snjl * (ACPI specifies 100 usec as max, but this gives some slack in 189123315Snjl * order to support existing BIOSs) 190123315Snjl */ 191306536Sjkim ACPI_ERROR ((AE_INFO, 192306536Sjkim "Time parameter is too large (%u)", HowLong)); 193123315Snjl Status = AE_AML_OPERAND_VALUE; 19467754Smsmith } 19567754Smsmith else 19667754Smsmith { 197117521Snjl AcpiOsStall (HowLong); 19867754Smsmith } 19991116Smsmith 20091116Smsmith return (Status); 20167754Smsmith} 20267754Smsmith 20367754Smsmith 20467754Smsmith/******************************************************************************* 20567754Smsmith * 206207344Sjkim * FUNCTION: AcpiExSystemDoSleep 20767754Smsmith * 208207344Sjkim * PARAMETERS: HowLong - The amount of time to sleep, 209151937Sjkim * in milliseconds 21067754Smsmith * 21167754Smsmith * RETURN: None 21267754Smsmith * 213207344Sjkim * DESCRIPTION: Sleep the running thread for specified amount of time. 21467754Smsmith * 21567754Smsmith ******************************************************************************/ 21667754Smsmith 21791116SmsmithACPI_STATUS 218207344SjkimAcpiExSystemDoSleep ( 219202771Sjkim UINT64 HowLong) 22067754Smsmith{ 22191116Smsmith ACPI_FUNCTION_ENTRY (); 22283174Smsmith 22391116Smsmith 22467754Smsmith /* Since this thread will sleep, we must release the interpreter */ 22567754Smsmith 226281075Sdim AcpiExExitInterpreter (); 22767754Smsmith 228209746Sjkim /* 229209746Sjkim * For compatibility with other ACPI implementations and to prevent 230209746Sjkim * accidental deep sleeps, limit the sleep time to something reasonable. 231209746Sjkim */ 232209746Sjkim if (HowLong > ACPI_MAX_SLEEP) 233209746Sjkim { 234209746Sjkim HowLong = ACPI_MAX_SLEEP; 235209746Sjkim } 236209746Sjkim 237138287Smarks AcpiOsSleep (HowLong); 23867754Smsmith 23967754Smsmith /* And now we must get the interpreter again */ 24067754Smsmith 241281075Sdim AcpiExEnterInterpreter (); 242167802Sjkim return (AE_OK); 24367754Smsmith} 24467754Smsmith 24567754Smsmith 24667754Smsmith/******************************************************************************* 24767754Smsmith * 24877424Smsmith * FUNCTION: AcpiExSystemSignalEvent 24967754Smsmith * 250151937Sjkim * PARAMETERS: ObjDesc - The object descriptor for this op 25167754Smsmith * 252151937Sjkim * RETURN: Status 25367754Smsmith * 25467754Smsmith * DESCRIPTION: Provides an access point to perform synchronization operations 25567754Smsmith * within the AML. 25667754Smsmith * 25767754Smsmith ******************************************************************************/ 25867754Smsmith 25967754SmsmithACPI_STATUS 26077424SmsmithAcpiExSystemSignalEvent ( 26167754Smsmith ACPI_OPERAND_OBJECT *ObjDesc) 26267754Smsmith{ 26367754Smsmith ACPI_STATUS Status = AE_OK; 26467754Smsmith 26567754Smsmith 266167802Sjkim ACPI_FUNCTION_TRACE (ExSystemSignalEvent); 26767754Smsmith 26867754Smsmith 26967754Smsmith if (ObjDesc) 27067754Smsmith { 271167802Sjkim Status = AcpiOsSignalSemaphore (ObjDesc->Event.OsSemaphore, 1); 27267754Smsmith } 27367754Smsmith 27467754Smsmith return_ACPI_STATUS (Status); 27567754Smsmith} 27667754Smsmith 27767754Smsmith 27867754Smsmith/******************************************************************************* 27967754Smsmith * 28077424Smsmith * FUNCTION: AcpiExSystemWaitEvent 28167754Smsmith * 282151937Sjkim * PARAMETERS: TimeDesc - The 'time to delay' object descriptor 283151937Sjkim * ObjDesc - The object descriptor for this op 28467754Smsmith * 28567754Smsmith * RETURN: Status 28667754Smsmith * 28767754Smsmith * DESCRIPTION: Provides an access point to perform synchronization operations 288241973Sjkim * within the AML. This operation is a request to wait for an 28967754Smsmith * event. 29067754Smsmith * 29167754Smsmith ******************************************************************************/ 29267754Smsmith 29367754SmsmithACPI_STATUS 29477424SmsmithAcpiExSystemWaitEvent ( 29567754Smsmith ACPI_OPERAND_OBJECT *TimeDesc, 29667754Smsmith ACPI_OPERAND_OBJECT *ObjDesc) 29767754Smsmith{ 29867754Smsmith ACPI_STATUS Status = AE_OK; 29967754Smsmith 30067754Smsmith 301167802Sjkim ACPI_FUNCTION_TRACE (ExSystemWaitEvent); 30267754Smsmith 30367754Smsmith 30467754Smsmith if (ObjDesc) 30567754Smsmith { 306167802Sjkim Status = AcpiExSystemWaitSemaphore (ObjDesc->Event.OsSemaphore, 307306536Sjkim (UINT16) TimeDesc->Integer.Value); 30867754Smsmith } 30967754Smsmith 31067754Smsmith return_ACPI_STATUS (Status); 31167754Smsmith} 31267754Smsmith 31367754Smsmith 31467754Smsmith/******************************************************************************* 31567754Smsmith * 31677424Smsmith * FUNCTION: AcpiExSystemResetEvent 31767754Smsmith * 318151937Sjkim * PARAMETERS: ObjDesc - The object descriptor for this op 31967754Smsmith * 32067754Smsmith * RETURN: Status 32167754Smsmith * 32277424Smsmith * DESCRIPTION: Reset an event to a known state. 32367754Smsmith * 32467754Smsmith ******************************************************************************/ 32567754Smsmith 32667754SmsmithACPI_STATUS 32777424SmsmithAcpiExSystemResetEvent ( 32867754Smsmith ACPI_OPERAND_OBJECT *ObjDesc) 32967754Smsmith{ 33067754Smsmith ACPI_STATUS Status = AE_OK; 331167802Sjkim ACPI_SEMAPHORE TempSemaphore; 33267754Smsmith 33367754Smsmith 33491116Smsmith ACPI_FUNCTION_ENTRY (); 33583174Smsmith 33683174Smsmith 33767754Smsmith /* 33867754Smsmith * We are going to simply delete the existing semaphore and 33967754Smsmith * create a new one! 34067754Smsmith */ 34167754Smsmith Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, &TempSemaphore); 34267754Smsmith if (ACPI_SUCCESS (Status)) 34367754Smsmith { 344167802Sjkim (void) AcpiOsDeleteSemaphore (ObjDesc->Event.OsSemaphore); 345167802Sjkim ObjDesc->Event.OsSemaphore = TempSemaphore; 34667754Smsmith } 34767754Smsmith 34867754Smsmith return (Status); 34967754Smsmith} 350