1 /****************************************************************************** 2 * 3 * Module Name: psxface - Parser external interfaces 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acparser.h> 47 #include <contrib/dev/acpica/include/acdispat.h> 48 #include <contrib/dev/acpica/include/acinterp.h> 49 #include <contrib/dev/acpica/include/actables.h> 50 #include <contrib/dev/acpica/include/acnamesp.h> 51 52 53 #define _COMPONENT ACPI_PARSER 54 ACPI_MODULE_NAME ("psxface") 55 56 /* Local Prototypes */ 57 58 static void 59 AcpiPsUpdateParameterList ( 60 ACPI_EVALUATE_INFO *Info, 61 UINT16 Action); 62 63 64 /******************************************************************************* 65 * 66 * FUNCTION: AcpiDebugTrace 67 * 68 * PARAMETERS: MethodName - Valid ACPI name string 69 * DebugLevel - Optional level mask. 0 to use default 70 * DebugLayer - Optional layer mask. 0 to use default 71 * Flags - bit 1: one shot(1) or persistent(0) 72 * 73 * RETURN: Status 74 * 75 * DESCRIPTION: External interface to enable debug tracing during control 76 * method execution 77 * 78 ******************************************************************************/ 79 80 ACPI_STATUS 81 AcpiDebugTrace ( 82 const char *Name, 83 UINT32 DebugLevel, 84 UINT32 DebugLayer, 85 UINT32 Flags) 86 { 87 ACPI_STATUS Status; 88 89 90 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 91 if (ACPI_FAILURE (Status)) 92 { 93 return (Status); 94 } 95 96 AcpiGbl_TraceMethodName = Name; 97 AcpiGbl_TraceFlags = Flags; 98 AcpiGbl_TraceDbgLevel = DebugLevel; 99 AcpiGbl_TraceDbgLayer = DebugLayer; 100 Status = AE_OK; 101 102 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 103 return (Status); 104 } 105 106 107 /******************************************************************************* 108 * 109 * FUNCTION: AcpiPsExecuteMethod 110 * 111 * PARAMETERS: Info - Method info block, contains: 112 * Node - Method Node to execute 113 * ObjDesc - Method object 114 * Parameters - List of parameters to pass to the method, 115 * terminated by NULL. Params itself may be 116 * NULL if no parameters are being passed. 117 * ReturnObject - Where to put method's return value (if 118 * any). If NULL, no value is returned. 119 * ParameterType - Type of Parameter list 120 * ReturnObject - Where to put method's return value (if 121 * any). If NULL, no value is returned. 122 * PassNumber - Parse or execute pass 123 * 124 * RETURN: Status 125 * 126 * DESCRIPTION: Execute a control method 127 * 128 ******************************************************************************/ 129 130 ACPI_STATUS 131 AcpiPsExecuteMethod ( 132 ACPI_EVALUATE_INFO *Info) 133 { 134 ACPI_STATUS Status; 135 ACPI_PARSE_OBJECT *Op; 136 ACPI_WALK_STATE *WalkState; 137 138 139 ACPI_FUNCTION_TRACE (PsExecuteMethod); 140 141 142 /* Quick validation of DSDT header */ 143 144 AcpiTbCheckDsdtHeader (); 145 146 /* Validate the Info and method Node */ 147 148 if (!Info || !Info->Node) 149 { 150 return_ACPI_STATUS (AE_NULL_ENTRY); 151 } 152 153 /* Init for new method, wait on concurrency semaphore */ 154 155 Status = AcpiDsBeginMethodExecution (Info->Node, Info->ObjDesc, NULL); 156 if (ACPI_FAILURE (Status)) 157 { 158 return_ACPI_STATUS (Status); 159 } 160 161 /* 162 * The caller "owns" the parameters, so give each one an extra reference 163 */ 164 AcpiPsUpdateParameterList (Info, REF_INCREMENT); 165 166 /* 167 * Execute the method. Performs parse simultaneously 168 */ 169 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 170 "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n", 171 Info->Node->Name.Ascii, Info->Node, Info->ObjDesc)); 172 173 /* Create and init a Root Node */ 174 175 Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart); 176 if (!Op) 177 { 178 Status = AE_NO_MEMORY; 179 goto Cleanup; 180 } 181 182 /* Create and initialize a new walk state */ 183 184 Info->PassNumber = ACPI_IMODE_EXECUTE; 185 WalkState = AcpiDsCreateWalkState ( 186 Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL); 187 if (!WalkState) 188 { 189 Status = AE_NO_MEMORY; 190 goto Cleanup; 191 } 192 193 Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node, 194 Info->ObjDesc->Method.AmlStart, 195 Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber); 196 if (ACPI_FAILURE (Status)) 197 { 198 AcpiDsDeleteWalkState (WalkState); 199 goto Cleanup; 200 } 201 202 if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) 203 { 204 WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL; 205 } 206 207 /* Invoke an internal method if necessary */ 208 209 if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY) 210 { 211 Status = Info->ObjDesc->Method.Dispatch.Implementation (WalkState); 212 Info->ReturnObject = WalkState->ReturnDesc; 213 214 /* Cleanup states */ 215 216 AcpiDsScopeStackClear (WalkState); 217 AcpiPsCleanupScope (&WalkState->ParserState); 218 AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState); 219 AcpiDsDeleteWalkState (WalkState); 220 goto Cleanup; 221 } 222 223 /* 224 * Start method evaluation with an implicit return of zero. 225 * This is done for Windows compatibility. 226 */ 227 if (AcpiGbl_EnableInterpreterSlack) 228 { 229 WalkState->ImplicitReturnObj = 230 AcpiUtCreateIntegerObject ((UINT64) 0); 231 if (!WalkState->ImplicitReturnObj) 232 { 233 Status = AE_NO_MEMORY; 234 AcpiDsDeleteWalkState (WalkState); 235 goto Cleanup; 236 } 237 } 238 239 /* Parse the AML */ 240 241 Status = AcpiPsParseAml (WalkState); 242 243 /* WalkState was deleted by ParseAml */ 244 245 Cleanup: 246 AcpiPsDeleteParseTree (Op); 247 248 /* Take away the extra reference that we gave the parameters above */ 249 250 AcpiPsUpdateParameterList (Info, REF_DECREMENT); 251 252 /* Exit now if error above */ 253 254 if (ACPI_FAILURE (Status)) 255 { 256 return_ACPI_STATUS (Status); 257 } 258 259 /* 260 * If the method has returned an object, signal this to the caller with 261 * a control exception code 262 */ 263 if (Info->ReturnObject) 264 { 265 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n", 266 Info->ReturnObject)); 267 ACPI_DUMP_STACK_ENTRY (Info->ReturnObject); 268 269 Status = AE_CTRL_RETURN_VALUE; 270 } 271 272 return_ACPI_STATUS (Status); 273 } 274 275 276 /******************************************************************************* 277 * 278 * FUNCTION: AcpiPsUpdateParameterList 279 * 280 * PARAMETERS: Info - See ACPI_EVALUATE_INFO 281 * (Used: ParameterType and Parameters) 282 * Action - Add or Remove reference 283 * 284 * RETURN: Status 285 * 286 * DESCRIPTION: Update reference count on all method parameter objects 287 * 288 ******************************************************************************/ 289 290 static void 291 AcpiPsUpdateParameterList ( 292 ACPI_EVALUATE_INFO *Info, 293 UINT16 Action) 294 { 295 UINT32 i; 296 297 298 if (Info->Parameters) 299 { 300 /* Update reference count for each parameter */ 301 302 for (i = 0; Info->Parameters[i]; i++) 303 { 304 /* Ignore errors, just do them all */ 305 306 (void) AcpiUtUpdateObjectReference (Info->Parameters[i], Action); 307 } 308 } 309 } 310