1 /****************************************************************************** 2 * 3 * Module Name: dswstate - Dispatcher parse tree walk management routines 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2015, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 #include "acpi.h" 117 #include "accommon.h" 118 #include "acparser.h" 119 #include "acdispat.h" 120 #include "acnamesp.h" 121 122 #define _COMPONENT ACPI_DISPATCHER 123 ACPI_MODULE_NAME ("dswstate") 124 125 /* Local prototypes */ 126 127 static ACPI_STATUS 128 AcpiDsResultStackPush ( 129 ACPI_WALK_STATE *WalkState); 130 131 static ACPI_STATUS 132 AcpiDsResultStackPop ( 133 ACPI_WALK_STATE *WalkState); 134 135 136 /******************************************************************************* 137 * 138 * FUNCTION: AcpiDsResultPop 139 * 140 * PARAMETERS: Object - Where to return the popped object 141 * WalkState - Current Walk state 142 * 143 * RETURN: Status 144 * 145 * DESCRIPTION: Pop an object off the top of this walk's result stack 146 * 147 ******************************************************************************/ 148 149 ACPI_STATUS 150 AcpiDsResultPop ( 151 ACPI_OPERAND_OBJECT **Object, 152 ACPI_WALK_STATE *WalkState) 153 { 154 UINT32 Index; 155 ACPI_GENERIC_STATE *State; 156 ACPI_STATUS Status; 157 158 159 ACPI_FUNCTION_NAME (DsResultPop); 160 161 162 State = WalkState->Results; 163 164 /* Incorrect state of result stack */ 165 166 if (State && !WalkState->ResultCount) 167 { 168 ACPI_ERROR ((AE_INFO, "No results on result stack")); 169 return (AE_AML_INTERNAL); 170 } 171 172 if (!State && WalkState->ResultCount) 173 { 174 ACPI_ERROR ((AE_INFO, "No result state for result stack")); 175 return (AE_AML_INTERNAL); 176 } 177 178 /* Empty result stack */ 179 180 if (!State) 181 { 182 ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState)); 183 return (AE_AML_NO_RETURN_VALUE); 184 } 185 186 /* Return object of the top element and clean that top element result stack */ 187 188 WalkState->ResultCount--; 189 Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM; 190 191 *Object = State->Results.ObjDesc [Index]; 192 if (!*Object) 193 { 194 ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p", 195 WalkState)); 196 return (AE_AML_NO_RETURN_VALUE); 197 } 198 199 State->Results.ObjDesc [Index] = NULL; 200 if (Index == 0) 201 { 202 Status = AcpiDsResultStackPop (WalkState); 203 if (ACPI_FAILURE (Status)) 204 { 205 return (Status); 206 } 207 } 208 209 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 210 "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object, 211 AcpiUtGetObjectTypeName (*Object), 212 Index, WalkState, WalkState->ResultCount)); 213 214 return (AE_OK); 215 } 216 217 218 /******************************************************************************* 219 * 220 * FUNCTION: AcpiDsResultPush 221 * 222 * PARAMETERS: Object - Where to return the popped object 223 * WalkState - Current Walk state 224 * 225 * RETURN: Status 226 * 227 * DESCRIPTION: Push an object onto the current result stack 228 * 229 ******************************************************************************/ 230 231 ACPI_STATUS 232 AcpiDsResultPush ( 233 ACPI_OPERAND_OBJECT *Object, 234 ACPI_WALK_STATE *WalkState) 235 { 236 ACPI_GENERIC_STATE *State; 237 ACPI_STATUS Status; 238 UINT32 Index; 239 240 241 ACPI_FUNCTION_NAME (DsResultPush); 242 243 244 if (WalkState->ResultCount > WalkState->ResultSize) 245 { 246 ACPI_ERROR ((AE_INFO, "Result stack is full")); 247 return (AE_AML_INTERNAL); 248 } 249 else if (WalkState->ResultCount == WalkState->ResultSize) 250 { 251 /* Extend the result stack */ 252 253 Status = AcpiDsResultStackPush (WalkState); 254 if (ACPI_FAILURE (Status)) 255 { 256 ACPI_ERROR ((AE_INFO, "Failed to extend the result stack")); 257 return (Status); 258 } 259 } 260 261 if (!(WalkState->ResultCount < WalkState->ResultSize)) 262 { 263 ACPI_ERROR ((AE_INFO, "No free elements in result stack")); 264 return (AE_AML_INTERNAL); 265 } 266 267 State = WalkState->Results; 268 if (!State) 269 { 270 ACPI_ERROR ((AE_INFO, "No result stack frame during push")); 271 return (AE_AML_INTERNAL); 272 } 273 274 if (!Object) 275 { 276 ACPI_ERROR ((AE_INFO, 277 "Null Object! Obj=%p State=%p Num=%u", 278 Object, WalkState, WalkState->ResultCount)); 279 return (AE_BAD_PARAMETER); 280 } 281 282 /* Assign the address of object to the top free element of result stack */ 283 284 Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM; 285 State->Results.ObjDesc [Index] = Object; 286 WalkState->ResultCount++; 287 288 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", 289 Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object), 290 WalkState, WalkState->ResultCount, WalkState->CurrentResult)); 291 292 return (AE_OK); 293 } 294 295 296 /******************************************************************************* 297 * 298 * FUNCTION: AcpiDsResultStackPush 299 * 300 * PARAMETERS: WalkState - Current Walk state 301 * 302 * RETURN: Status 303 * 304 * DESCRIPTION: Push an object onto the WalkState result stack 305 * 306 ******************************************************************************/ 307 308 static ACPI_STATUS 309 AcpiDsResultStackPush ( 310 ACPI_WALK_STATE *WalkState) 311 { 312 ACPI_GENERIC_STATE *State; 313 314 315 ACPI_FUNCTION_NAME (DsResultStackPush); 316 317 318 /* Check for stack overflow */ 319 320 if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) > 321 ACPI_RESULTS_OBJ_NUM_MAX) 322 { 323 ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u", 324 WalkState, WalkState->ResultSize)); 325 return (AE_STACK_OVERFLOW); 326 } 327 328 State = AcpiUtCreateGenericState (); 329 if (!State) 330 { 331 return (AE_NO_MEMORY); 332 } 333 334 State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT; 335 AcpiUtPushGenericState (&WalkState->Results, State); 336 337 /* Increase the length of the result stack by the length of frame */ 338 339 WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM; 340 341 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n", 342 State, WalkState)); 343 344 return (AE_OK); 345 } 346 347 348 /******************************************************************************* 349 * 350 * FUNCTION: AcpiDsResultStackPop 351 * 352 * PARAMETERS: WalkState - Current Walk state 353 * 354 * RETURN: Status 355 * 356 * DESCRIPTION: Pop an object off of the WalkState result stack 357 * 358 ******************************************************************************/ 359 360 static ACPI_STATUS 361 AcpiDsResultStackPop ( 362 ACPI_WALK_STATE *WalkState) 363 { 364 ACPI_GENERIC_STATE *State; 365 366 367 ACPI_FUNCTION_NAME (DsResultStackPop); 368 369 370 /* Check for stack underflow */ 371 372 if (WalkState->Results == NULL) 373 { 374 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Result stack underflow - State=%p\n", 375 WalkState)); 376 return (AE_AML_NO_OPERAND); 377 } 378 379 if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM) 380 { 381 ACPI_ERROR ((AE_INFO, "Insufficient result stack size")); 382 return (AE_AML_INTERNAL); 383 } 384 385 State = AcpiUtPopGenericState (&WalkState->Results); 386 AcpiUtDeleteGenericState (State); 387 388 /* Decrease the length of result stack by the length of frame */ 389 390 WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM; 391 392 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 393 "Result=%p RemainingResults=%X State=%p\n", 394 State, WalkState->ResultCount, WalkState)); 395 396 return (AE_OK); 397 } 398 399 400 /******************************************************************************* 401 * 402 * FUNCTION: AcpiDsObjStackPush 403 * 404 * PARAMETERS: Object - Object to push 405 * WalkState - Current Walk state 406 * 407 * RETURN: Status 408 * 409 * DESCRIPTION: Push an object onto this walk's object/operand stack 410 * 411 ******************************************************************************/ 412 413 ACPI_STATUS 414 AcpiDsObjStackPush ( 415 void *Object, 416 ACPI_WALK_STATE *WalkState) 417 { 418 ACPI_FUNCTION_NAME (DsObjStackPush); 419 420 421 /* Check for stack overflow */ 422 423 if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS) 424 { 425 ACPI_ERROR ((AE_INFO, 426 "Object stack overflow! Obj=%p State=%p #Ops=%u", 427 Object, WalkState, WalkState->NumOperands)); 428 return (AE_STACK_OVERFLOW); 429 } 430 431 /* Put the object onto the stack */ 432 433 WalkState->Operands [WalkState->OperandIndex] = Object; 434 WalkState->NumOperands++; 435 436 /* For the usual order of filling the operand stack */ 437 438 WalkState->OperandIndex++; 439 440 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", 441 Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object), 442 WalkState, WalkState->NumOperands)); 443 444 return (AE_OK); 445 } 446 447 448 /******************************************************************************* 449 * 450 * FUNCTION: AcpiDsObjStackPop 451 * 452 * PARAMETERS: PopCount - Number of objects/entries to pop 453 * WalkState - Current Walk state 454 * 455 * RETURN: Status 456 * 457 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT 458 * deleted by this routine. 459 * 460 ******************************************************************************/ 461 462 ACPI_STATUS 463 AcpiDsObjStackPop ( 464 UINT32 PopCount, 465 ACPI_WALK_STATE *WalkState) 466 { 467 UINT32 i; 468 469 470 ACPI_FUNCTION_NAME (DsObjStackPop); 471 472 473 for (i = 0; i < PopCount; i++) 474 { 475 /* Check for stack underflow */ 476 477 if (WalkState->NumOperands == 0) 478 { 479 ACPI_ERROR ((AE_INFO, 480 "Object stack underflow! Count=%X State=%p #Ops=%u", 481 PopCount, WalkState, WalkState->NumOperands)); 482 return (AE_STACK_UNDERFLOW); 483 } 484 485 /* Just set the stack entry to null */ 486 487 WalkState->NumOperands--; 488 WalkState->Operands [WalkState->NumOperands] = NULL; 489 } 490 491 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n", 492 PopCount, WalkState, WalkState->NumOperands)); 493 494 return (AE_OK); 495 } 496 497 498 /******************************************************************************* 499 * 500 * FUNCTION: AcpiDsObjStackPopAndDelete 501 * 502 * PARAMETERS: PopCount - Number of objects/entries to pop 503 * WalkState - Current Walk state 504 * 505 * RETURN: Status 506 * 507 * DESCRIPTION: Pop this walk's object stack and delete each object that is 508 * popped off. 509 * 510 ******************************************************************************/ 511 512 void 513 AcpiDsObjStackPopAndDelete ( 514 UINT32 PopCount, 515 ACPI_WALK_STATE *WalkState) 516 { 517 INT32 i; 518 ACPI_OPERAND_OBJECT *ObjDesc; 519 520 521 ACPI_FUNCTION_NAME (DsObjStackPopAndDelete); 522 523 524 if (PopCount == 0) 525 { 526 return; 527 } 528 529 for (i = (INT32) PopCount - 1; i >= 0; i--) 530 { 531 if (WalkState->NumOperands == 0) 532 { 533 return; 534 } 535 536 /* Pop the stack and delete an object if present in this stack entry */ 537 538 WalkState->NumOperands--; 539 ObjDesc = WalkState->Operands [i]; 540 if (ObjDesc) 541 { 542 AcpiUtRemoveReference (WalkState->Operands [i]); 543 WalkState->Operands [i] = NULL; 544 } 545 } 546 547 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", 548 PopCount, WalkState, WalkState->NumOperands)); 549 } 550 551 552 /******************************************************************************* 553 * 554 * FUNCTION: AcpiDsGetCurrentWalkState 555 * 556 * PARAMETERS: Thread - Get current active state for this Thread 557 * 558 * RETURN: Pointer to the current walk state 559 * 560 * DESCRIPTION: Get the walk state that is at the head of the list (the "current" 561 * walk state.) 562 * 563 ******************************************************************************/ 564 565 ACPI_WALK_STATE * 566 AcpiDsGetCurrentWalkState ( 567 ACPI_THREAD_STATE *Thread) 568 { 569 ACPI_FUNCTION_NAME (DsGetCurrentWalkState); 570 571 572 if (!Thread) 573 { 574 return (NULL); 575 } 576 577 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n", 578 Thread->WalkStateList)); 579 580 return (Thread->WalkStateList); 581 } 582 583 584 /******************************************************************************* 585 * 586 * FUNCTION: AcpiDsPushWalkState 587 * 588 * PARAMETERS: WalkState - State to push 589 * Thread - Thread state object 590 * 591 * RETURN: None 592 * 593 * DESCRIPTION: Place the Thread state at the head of the state list 594 * 595 ******************************************************************************/ 596 597 void 598 AcpiDsPushWalkState ( 599 ACPI_WALK_STATE *WalkState, 600 ACPI_THREAD_STATE *Thread) 601 { 602 ACPI_FUNCTION_TRACE (DsPushWalkState); 603 604 605 WalkState->Next = Thread->WalkStateList; 606 Thread->WalkStateList = WalkState; 607 608 return_VOID; 609 } 610 611 612 /******************************************************************************* 613 * 614 * FUNCTION: AcpiDsPopWalkState 615 * 616 * PARAMETERS: Thread - Current thread state 617 * 618 * RETURN: A WalkState object popped from the thread's stack 619 * 620 * DESCRIPTION: Remove and return the walkstate object that is at the head of 621 * the walk stack for the given walk list. NULL indicates that 622 * the list is empty. 623 * 624 ******************************************************************************/ 625 626 ACPI_WALK_STATE * 627 AcpiDsPopWalkState ( 628 ACPI_THREAD_STATE *Thread) 629 { 630 ACPI_WALK_STATE *WalkState; 631 632 633 ACPI_FUNCTION_TRACE (DsPopWalkState); 634 635 636 WalkState = Thread->WalkStateList; 637 638 if (WalkState) 639 { 640 /* Next walk state becomes the current walk state */ 641 642 Thread->WalkStateList = WalkState->Next; 643 644 /* 645 * Don't clear the NEXT field, this serves as an indicator 646 * that there is a parent WALK STATE 647 * Do Not: WalkState->Next = NULL; 648 */ 649 } 650 651 return_PTR (WalkState); 652 } 653 654 655 /******************************************************************************* 656 * 657 * FUNCTION: AcpiDsCreateWalkState 658 * 659 * PARAMETERS: OwnerId - ID for object creation 660 * Origin - Starting point for this walk 661 * MethodDesc - Method object 662 * Thread - Current thread state 663 * 664 * RETURN: Pointer to the new walk state. 665 * 666 * DESCRIPTION: Allocate and initialize a new walk state. The current walk 667 * state is set to this new state. 668 * 669 ******************************************************************************/ 670 671 ACPI_WALK_STATE * 672 AcpiDsCreateWalkState ( 673 ACPI_OWNER_ID OwnerId, 674 ACPI_PARSE_OBJECT *Origin, 675 ACPI_OPERAND_OBJECT *MethodDesc, 676 ACPI_THREAD_STATE *Thread) 677 { 678 ACPI_WALK_STATE *WalkState; 679 680 681 ACPI_FUNCTION_TRACE (DsCreateWalkState); 682 683 684 WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE)); 685 if (!WalkState) 686 { 687 return_PTR (NULL); 688 } 689 690 WalkState->DescriptorType = ACPI_DESC_TYPE_WALK; 691 WalkState->MethodDesc = MethodDesc; 692 WalkState->OwnerId = OwnerId; 693 WalkState->Origin = Origin; 694 WalkState->Thread = Thread; 695 696 WalkState->ParserState.StartOp = Origin; 697 698 /* Init the method args/local */ 699 700 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) 701 AcpiDsMethodDataInit (WalkState); 702 #endif 703 704 /* Put the new state at the head of the walk list */ 705 706 if (Thread) 707 { 708 AcpiDsPushWalkState (WalkState, Thread); 709 } 710 711 return_PTR (WalkState); 712 } 713 714 715 /******************************************************************************* 716 * 717 * FUNCTION: AcpiDsInitAmlWalk 718 * 719 * PARAMETERS: WalkState - New state to be initialized 720 * Op - Current parse op 721 * MethodNode - Control method NS node, if any 722 * AmlStart - Start of AML 723 * AmlLength - Length of AML 724 * Info - Method info block (params, etc.) 725 * PassNumber - 1, 2, or 3 726 * 727 * RETURN: Status 728 * 729 * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk 730 * 731 ******************************************************************************/ 732 733 ACPI_STATUS 734 AcpiDsInitAmlWalk ( 735 ACPI_WALK_STATE *WalkState, 736 ACPI_PARSE_OBJECT *Op, 737 ACPI_NAMESPACE_NODE *MethodNode, 738 UINT8 *AmlStart, 739 UINT32 AmlLength, 740 ACPI_EVALUATE_INFO *Info, 741 UINT8 PassNumber) 742 { 743 ACPI_STATUS Status; 744 ACPI_PARSE_STATE *ParserState = &WalkState->ParserState; 745 ACPI_PARSE_OBJECT *ExtraOp; 746 747 748 ACPI_FUNCTION_TRACE (DsInitAmlWalk); 749 750 751 WalkState->ParserState.Aml = 752 WalkState->ParserState.AmlStart = AmlStart; 753 WalkState->ParserState.AmlEnd = 754 WalkState->ParserState.PkgEnd = AmlStart + AmlLength; 755 756 /* The NextOp of the NextWalk will be the beginning of the method */ 757 758 WalkState->NextOp = NULL; 759 WalkState->PassNumber = PassNumber; 760 761 if (Info) 762 { 763 WalkState->Params = Info->Parameters; 764 WalkState->CallerReturnDesc = &Info->ReturnObject; 765 } 766 767 Status = AcpiPsInitScope (&WalkState->ParserState, Op); 768 if (ACPI_FAILURE (Status)) 769 { 770 return_ACPI_STATUS (Status); 771 } 772 773 if (MethodNode) 774 { 775 WalkState->ParserState.StartNode = MethodNode; 776 WalkState->WalkType = ACPI_WALK_METHOD; 777 WalkState->MethodNode = MethodNode; 778 WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode); 779 780 /* Push start scope on scope stack and make it current */ 781 782 Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState); 783 if (ACPI_FAILURE (Status)) 784 { 785 return_ACPI_STATUS (Status); 786 } 787 788 /* Init the method arguments */ 789 790 Status = AcpiDsMethodDataInitArgs (WalkState->Params, 791 ACPI_METHOD_NUM_ARGS, WalkState); 792 if (ACPI_FAILURE (Status)) 793 { 794 return_ACPI_STATUS (Status); 795 } 796 } 797 else 798 { 799 /* 800 * Setup the current scope. 801 * Find a Named Op that has a namespace node associated with it. 802 * search upwards from this Op. Current scope is the first 803 * Op with a namespace node. 804 */ 805 ExtraOp = ParserState->StartOp; 806 while (ExtraOp && !ExtraOp->Common.Node) 807 { 808 ExtraOp = ExtraOp->Common.Parent; 809 } 810 811 if (!ExtraOp) 812 { 813 ParserState->StartNode = NULL; 814 } 815 else 816 { 817 ParserState->StartNode = ExtraOp->Common.Node; 818 } 819 820 if (ParserState->StartNode) 821 { 822 /* Push start scope on scope stack and make it current */ 823 824 Status = AcpiDsScopeStackPush (ParserState->StartNode, 825 ParserState->StartNode->Type, WalkState); 826 if (ACPI_FAILURE (Status)) 827 { 828 return_ACPI_STATUS (Status); 829 } 830 } 831 } 832 833 Status = AcpiDsInitCallbacks (WalkState, PassNumber); 834 return_ACPI_STATUS (Status); 835 } 836 837 838 /******************************************************************************* 839 * 840 * FUNCTION: AcpiDsDeleteWalkState 841 * 842 * PARAMETERS: WalkState - State to delete 843 * 844 * RETURN: Status 845 * 846 * DESCRIPTION: Delete a walk state including all internal data structures 847 * 848 ******************************************************************************/ 849 850 void 851 AcpiDsDeleteWalkState ( 852 ACPI_WALK_STATE *WalkState) 853 { 854 ACPI_GENERIC_STATE *State; 855 856 857 ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState); 858 859 860 if (!WalkState) 861 { 862 return_VOID; 863 } 864 865 if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK) 866 { 867 ACPI_ERROR ((AE_INFO, "%p is not a valid walk state", 868 WalkState)); 869 return_VOID; 870 } 871 872 /* There should not be any open scopes */ 873 874 if (WalkState->ParserState.Scope) 875 { 876 ACPI_ERROR ((AE_INFO, "%p walk still has a scope list", 877 WalkState)); 878 AcpiPsCleanupScope (&WalkState->ParserState); 879 } 880 881 /* Always must free any linked control states */ 882 883 while (WalkState->ControlState) 884 { 885 State = WalkState->ControlState; 886 WalkState->ControlState = State->Common.Next; 887 888 AcpiUtDeleteGenericState (State); 889 } 890 891 /* Always must free any linked parse states */ 892 893 while (WalkState->ScopeInfo) 894 { 895 State = WalkState->ScopeInfo; 896 WalkState->ScopeInfo = State->Common.Next; 897 898 AcpiUtDeleteGenericState (State); 899 } 900 901 /* Always must free any stacked result states */ 902 903 while (WalkState->Results) 904 { 905 State = WalkState->Results; 906 WalkState->Results = State->Common.Next; 907 908 AcpiUtDeleteGenericState (State); 909 } 910 911 ACPI_FREE (WalkState); 912 return_VOID; 913 } 914