1 /****************************************************************************** 2 * 3 * Module Name: psxface - Parser external interfaces 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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: AcpiPsExecuteTable 279 * 280 * PARAMETERS: Info - Method info block, contains: 281 * Node - Node to where the is entered into the 282 * namespace 283 * ObjDesc - Pseudo method object describing the AML 284 * code of the entire table 285 * PassNumber - Parse or execute pass 286 * 287 * RETURN: Status 288 * 289 * DESCRIPTION: Execute a table 290 * 291 ******************************************************************************/ 292 293 ACPI_STATUS 294 AcpiPsExecuteTable ( 295 ACPI_EVALUATE_INFO *Info) 296 { 297 ACPI_STATUS Status; 298 ACPI_PARSE_OBJECT *Op = NULL; 299 ACPI_WALK_STATE *WalkState = NULL; 300 301 302 ACPI_FUNCTION_TRACE (PsExecuteTable); 303 304 305 /* Create and init a Root Node */ 306 307 Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart); 308 if (!Op) 309 { 310 Status = AE_NO_MEMORY; 311 goto Cleanup; 312 } 313 314 /* Create and initialize a new walk state */ 315 316 WalkState = AcpiDsCreateWalkState ( 317 Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL); 318 if (!WalkState) 319 { 320 Status = AE_NO_MEMORY; 321 goto Cleanup; 322 } 323 324 Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node, 325 Info->ObjDesc->Method.AmlStart, 326 Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber); 327 if (ACPI_FAILURE (Status)) 328 { 329 goto Cleanup; 330 } 331 332 if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) 333 { 334 WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL; 335 } 336 337 /* Info->Node is the default location to load the table */ 338 339 if (Info->Node && Info->Node != AcpiGbl_RootNode) 340 { 341 Status = AcpiDsScopeStackPush ( 342 Info->Node, ACPI_TYPE_METHOD, WalkState); 343 if (ACPI_FAILURE (Status)) 344 { 345 goto Cleanup; 346 } 347 } 348 349 /* 350 * Parse the AML, WalkState will be deleted by ParseAml 351 */ 352 AcpiExEnterInterpreter (); 353 Status = AcpiPsParseAml (WalkState); 354 AcpiExExitInterpreter (); 355 WalkState = NULL; 356 357 Cleanup: 358 if (WalkState) 359 { 360 AcpiDsDeleteWalkState (WalkState); 361 } 362 if (Op) 363 { 364 AcpiPsDeleteParseTree (Op); 365 } 366 return_ACPI_STATUS (Status); 367 } 368 369 370 /******************************************************************************* 371 * 372 * FUNCTION: AcpiPsUpdateParameterList 373 * 374 * PARAMETERS: Info - See ACPI_EVALUATE_INFO 375 * (Used: ParameterType and Parameters) 376 * Action - Add or Remove reference 377 * 378 * RETURN: Status 379 * 380 * DESCRIPTION: Update reference count on all method parameter objects 381 * 382 ******************************************************************************/ 383 384 static void 385 AcpiPsUpdateParameterList ( 386 ACPI_EVALUATE_INFO *Info, 387 UINT16 Action) 388 { 389 UINT32 i; 390 391 392 if (Info->Parameters) 393 { 394 /* Update reference count for each parameter */ 395 396 for (i = 0; Info->Parameters[i]; i++) 397 { 398 /* Ignore errors, just do them all */ 399 400 (void) AcpiUtUpdateObjectReference ( 401 Info->Parameters[i], Action); 402 } 403 } 404 } 405