1 /****************************************************************************** 2 * 3 * Module Name: psxface - Parser external interfaces 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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 "acpi.h" 45 #include "accommon.h" 46 #include "acparser.h" 47 #include "acdispat.h" 48 #include "acinterp.h" 49 #include "actables.h" 50 #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 WalkState->MethodPathname = Info->FullPathname; 203 WalkState->MethodIsNested = FALSE; 204 205 if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) 206 { 207 WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL; 208 } 209 210 /* Invoke an internal method if necessary */ 211 212 if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY) 213 { 214 Status = Info->ObjDesc->Method.Dispatch.Implementation (WalkState); 215 Info->ReturnObject = WalkState->ReturnDesc; 216 217 /* Cleanup states */ 218 219 AcpiDsScopeStackClear (WalkState); 220 AcpiPsCleanupScope (&WalkState->ParserState); 221 AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState); 222 AcpiDsDeleteWalkState (WalkState); 223 goto Cleanup; 224 } 225 226 /* 227 * Start method evaluation with an implicit return of zero. 228 * This is done for Windows compatibility. 229 */ 230 if (AcpiGbl_EnableInterpreterSlack) 231 { 232 WalkState->ImplicitReturnObj = 233 AcpiUtCreateIntegerObject ((UINT64) 0); 234 if (!WalkState->ImplicitReturnObj) 235 { 236 Status = AE_NO_MEMORY; 237 AcpiDsDeleteWalkState (WalkState); 238 goto Cleanup; 239 } 240 } 241 242 /* Parse the AML */ 243 244 Status = AcpiPsParseAml (WalkState); 245 246 /* WalkState was deleted by ParseAml */ 247 248 Cleanup: 249 AcpiPsDeleteParseTree (Op); 250 251 /* Take away the extra reference that we gave the parameters above */ 252 253 AcpiPsUpdateParameterList (Info, REF_DECREMENT); 254 255 /* Exit now if error above */ 256 257 if (ACPI_FAILURE (Status)) 258 { 259 return_ACPI_STATUS (Status); 260 } 261 262 /* 263 * If the method has returned an object, signal this to the caller with 264 * a control exception code 265 */ 266 if (Info->ReturnObject) 267 { 268 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n", 269 Info->ReturnObject)); 270 ACPI_DUMP_STACK_ENTRY (Info->ReturnObject); 271 272 Status = AE_CTRL_RETURN_VALUE; 273 } 274 275 return_ACPI_STATUS (Status); 276 } 277 278 279 /******************************************************************************* 280 * 281 * FUNCTION: AcpiPsExecuteTable 282 * 283 * PARAMETERS: Info - Method info block, contains: 284 * Node - Node to where the is entered into the 285 * namespace 286 * ObjDesc - Pseudo method object describing the AML 287 * code of the entire table 288 * PassNumber - Parse or execute pass 289 * 290 * RETURN: Status 291 * 292 * DESCRIPTION: Execute a table 293 * 294 ******************************************************************************/ 295 296 ACPI_STATUS 297 AcpiPsExecuteTable ( 298 ACPI_EVALUATE_INFO *Info) 299 { 300 ACPI_STATUS Status; 301 ACPI_PARSE_OBJECT *Op = NULL; 302 ACPI_WALK_STATE *WalkState = NULL; 303 304 305 ACPI_FUNCTION_TRACE (PsExecuteTable); 306 307 308 /* Create and init a Root Node */ 309 310 Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart); 311 if (!Op) 312 { 313 Status = AE_NO_MEMORY; 314 goto Cleanup; 315 } 316 317 /* Create and initialize a new walk state */ 318 319 WalkState = AcpiDsCreateWalkState ( 320 Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL); 321 if (!WalkState) 322 { 323 Status = AE_NO_MEMORY; 324 goto Cleanup; 325 } 326 327 Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node, 328 Info->ObjDesc->Method.AmlStart, 329 Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber); 330 if (ACPI_FAILURE (Status)) 331 { 332 goto Cleanup; 333 } 334 335 WalkState->MethodPathname = Info->FullPathname; 336 WalkState->MethodIsNested = FALSE; 337 338 if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) 339 { 340 WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL; 341 } 342 343 /* Info->Node is the default location to load the table */ 344 345 if (Info->Node && Info->Node != AcpiGbl_RootNode) 346 { 347 Status = AcpiDsScopeStackPush ( 348 Info->Node, ACPI_TYPE_METHOD, WalkState); 349 if (ACPI_FAILURE (Status)) 350 { 351 goto Cleanup; 352 } 353 } 354 355 /* 356 * Parse the AML, WalkState will be deleted by ParseAml 357 */ 358 AcpiExEnterInterpreter (); 359 Status = AcpiPsParseAml (WalkState); 360 AcpiExExitInterpreter (); 361 WalkState = NULL; 362 363 Cleanup: 364 if (WalkState) 365 { 366 AcpiDsDeleteWalkState (WalkState); 367 } 368 if (Op) 369 { 370 AcpiPsDeleteParseTree (Op); 371 } 372 return_ACPI_STATUS (Status); 373 } 374 375 376 /******************************************************************************* 377 * 378 * FUNCTION: AcpiPsUpdateParameterList 379 * 380 * PARAMETERS: Info - See ACPI_EVALUATE_INFO 381 * (Used: ParameterType and Parameters) 382 * Action - Add or Remove reference 383 * 384 * RETURN: Status 385 * 386 * DESCRIPTION: Update reference count on all method parameter objects 387 * 388 ******************************************************************************/ 389 390 static void 391 AcpiPsUpdateParameterList ( 392 ACPI_EVALUATE_INFO *Info, 393 UINT16 Action) 394 { 395 UINT32 i; 396 397 398 if (Info->Parameters) 399 { 400 /* Update reference count for each parameter */ 401 402 for (i = 0; Info->Parameters[i]; i++) 403 { 404 /* Ignore errors, just do them all */ 405 406 (void) AcpiUtUpdateObjectReference ( 407 Info->Parameters[i], Action); 408 } 409 } 410 } 411