1 /****************************************************************************** 2 * 3 * Module Name: dswstate - Dispatcher parse tree walk management routines 4 * $Revision: 1.98 $ 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 118 #define __DSWSTATE_C__ 119 120 #include "acpi.h" 121 #include "acparser.h" 122 #include "acdispat.h" 123 #include "acnamesp.h" 124 125 #define _COMPONENT ACPI_DISPATCHER 126 ACPI_MODULE_NAME ("dswstate") 127 128 /* Local prototypes */ 129 130 #ifdef ACPI_OBSOLETE_FUNCTIONS 131 ACPI_STATUS 132 AcpiDsResultInsert ( 133 void *Object, 134 UINT32 Index, 135 ACPI_WALK_STATE *WalkState); 136 137 ACPI_STATUS 138 AcpiDsObjStackDeleteAll ( 139 ACPI_WALK_STATE *WalkState); 140 141 ACPI_STATUS 142 AcpiDsObjStackPopObject ( 143 ACPI_OPERAND_OBJECT **Object, 144 ACPI_WALK_STATE *WalkState); 145 146 void * 147 AcpiDsObjStackGetValue ( 148 UINT32 Index, 149 ACPI_WALK_STATE *WalkState); 150 #endif 151 152 153 /******************************************************************************* 154 * 155 * FUNCTION: AcpiDsResultRemove 156 * 157 * PARAMETERS: Object - Where to return the popped object 158 * Index - Where to extract the object 159 * WalkState - Current Walk state 160 * 161 * RETURN: Status 162 * 163 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In 164 * other words, this is a FIFO. 165 * 166 ******************************************************************************/ 167 168 ACPI_STATUS 169 AcpiDsResultRemove ( 170 ACPI_OPERAND_OBJECT **Object, 171 UINT32 Index, 172 ACPI_WALK_STATE *WalkState) 173 { 174 ACPI_GENERIC_STATE *State; 175 176 177 ACPI_FUNCTION_NAME (DsResultRemove); 178 179 180 State = WalkState->Results; 181 if (!State) 182 { 183 ACPI_ERROR ((AE_INFO, "No result object pushed! State=%p", 184 WalkState)); 185 return (AE_NOT_EXIST); 186 } 187 188 if (Index >= ACPI_OBJ_MAX_OPERAND) 189 { 190 ACPI_ERROR ((AE_INFO, 191 "Index out of range: %X State=%p Num=%X", 192 Index, WalkState, State->Results.NumResults)); 193 } 194 195 /* Check for a valid result object */ 196 197 if (!State->Results.ObjDesc [Index]) 198 { 199 ACPI_ERROR ((AE_INFO, 200 "Null operand! State=%p #Ops=%X, Index=%X", 201 WalkState, State->Results.NumResults, Index)); 202 return (AE_AML_NO_RETURN_VALUE); 203 } 204 205 /* Remove the object */ 206 207 State->Results.NumResults--; 208 209 *Object = State->Results.ObjDesc [Index]; 210 State->Results.ObjDesc [Index] = NULL; 211 212 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 213 "Obj=%p [%s] Index=%X State=%p Num=%X\n", 214 *Object, (*Object) ? AcpiUtGetObjectTypeName (*Object) : "NULL", 215 Index, WalkState, State->Results.NumResults)); 216 217 return (AE_OK); 218 } 219 220 221 /******************************************************************************* 222 * 223 * FUNCTION: AcpiDsResultPop 224 * 225 * PARAMETERS: Object - Where to return the popped object 226 * WalkState - Current Walk state 227 * 228 * RETURN: Status 229 * 230 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In 231 * other words, this is a FIFO. 232 * 233 ******************************************************************************/ 234 235 ACPI_STATUS 236 AcpiDsResultPop ( 237 ACPI_OPERAND_OBJECT **Object, 238 ACPI_WALK_STATE *WalkState) 239 { 240 ACPI_NATIVE_UINT Index; 241 ACPI_GENERIC_STATE *State; 242 243 244 ACPI_FUNCTION_NAME (DsResultPop); 245 246 247 State = WalkState->Results; 248 if (!State) 249 { 250 return (AE_OK); 251 } 252 253 if (!State->Results.NumResults) 254 { 255 ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", 256 WalkState)); 257 return (AE_AML_NO_RETURN_VALUE); 258 } 259 260 /* Remove top element */ 261 262 State->Results.NumResults--; 263 264 for (Index = ACPI_OBJ_NUM_OPERANDS; Index; Index--) 265 { 266 /* Check for a valid result object */ 267 268 if (State->Results.ObjDesc [Index -1]) 269 { 270 *Object = State->Results.ObjDesc [Index -1]; 271 State->Results.ObjDesc [Index -1] = NULL; 272 273 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 274 "Obj=%p [%s] Index=%X State=%p Num=%X\n", 275 *Object, 276 (*Object) ? AcpiUtGetObjectTypeName (*Object) : "NULL", 277 (UINT32) Index -1, WalkState, State->Results.NumResults)); 278 279 return (AE_OK); 280 } 281 } 282 283 ACPI_ERROR ((AE_INFO, 284 "No result objects! State=%p", WalkState)); 285 return (AE_AML_NO_RETURN_VALUE); 286 } 287 288 289 /******************************************************************************* 290 * 291 * FUNCTION: AcpiDsResultPopFromBottom 292 * 293 * PARAMETERS: Object - Where to return the popped object 294 * WalkState - Current Walk state 295 * 296 * RETURN: Status 297 * 298 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In 299 * other words, this is a FIFO. 300 * 301 ******************************************************************************/ 302 303 ACPI_STATUS 304 AcpiDsResultPopFromBottom ( 305 ACPI_OPERAND_OBJECT **Object, 306 ACPI_WALK_STATE *WalkState) 307 { 308 ACPI_NATIVE_UINT Index; 309 ACPI_GENERIC_STATE *State; 310 311 312 ACPI_FUNCTION_NAME (DsResultPopFromBottom); 313 314 315 State = WalkState->Results; 316 if (!State) 317 { 318 ACPI_ERROR ((AE_INFO, 319 "No result object pushed! State=%p", WalkState)); 320 return (AE_NOT_EXIST); 321 } 322 323 if (!State->Results.NumResults) 324 { 325 ACPI_ERROR ((AE_INFO, "No result objects! State=%p", 326 WalkState)); 327 return (AE_AML_NO_RETURN_VALUE); 328 } 329 330 /* Remove Bottom element */ 331 332 *Object = State->Results.ObjDesc [0]; 333 334 /* Push entire stack down one element */ 335 336 for (Index = 0; Index < State->Results.NumResults; Index++) 337 { 338 State->Results.ObjDesc [Index] = State->Results.ObjDesc [Index + 1]; 339 } 340 341 State->Results.NumResults--; 342 343 /* Check for a valid result object */ 344 345 if (!*Object) 346 { 347 ACPI_ERROR ((AE_INFO, 348 "Null operand! State=%p #Ops=%X Index=%X", 349 WalkState, State->Results.NumResults, (UINT32) Index)); 350 return (AE_AML_NO_RETURN_VALUE); 351 } 352 353 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n", 354 *Object, (*Object) ? AcpiUtGetObjectTypeName (*Object) : "NULL", 355 State, WalkState)); 356 357 return (AE_OK); 358 } 359 360 361 /******************************************************************************* 362 * 363 * FUNCTION: AcpiDsResultPush 364 * 365 * PARAMETERS: Object - Where to return the popped object 366 * WalkState - Current Walk state 367 * 368 * RETURN: Status 369 * 370 * DESCRIPTION: Push an object onto the current result stack 371 * 372 ******************************************************************************/ 373 374 ACPI_STATUS 375 AcpiDsResultPush ( 376 ACPI_OPERAND_OBJECT *Object, 377 ACPI_WALK_STATE *WalkState) 378 { 379 ACPI_GENERIC_STATE *State; 380 381 382 ACPI_FUNCTION_NAME (DsResultPush); 383 384 385 State = WalkState->Results; 386 if (!State) 387 { 388 ACPI_ERROR ((AE_INFO, "No result stack frame during push")); 389 return (AE_AML_INTERNAL); 390 } 391 392 if (State->Results.NumResults == ACPI_OBJ_NUM_OPERANDS) 393 { 394 ACPI_ERROR ((AE_INFO, 395 "Result stack overflow: Obj=%p State=%p Num=%X", 396 Object, WalkState, State->Results.NumResults)); 397 return (AE_STACK_OVERFLOW); 398 } 399 400 if (!Object) 401 { 402 ACPI_ERROR ((AE_INFO, 403 "Null Object! Obj=%p State=%p Num=%X", 404 Object, WalkState, State->Results.NumResults)); 405 return (AE_BAD_PARAMETER); 406 } 407 408 State->Results.ObjDesc [State->Results.NumResults] = Object; 409 State->Results.NumResults++; 410 411 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", 412 Object, Object ? AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object) : "NULL", 413 WalkState, State->Results.NumResults, WalkState->CurrentResult)); 414 415 return (AE_OK); 416 } 417 418 419 /******************************************************************************* 420 * 421 * FUNCTION: AcpiDsResultStackPush 422 * 423 * PARAMETERS: WalkState - Current Walk state 424 * 425 * RETURN: Status 426 * 427 * DESCRIPTION: Push an object onto the WalkState result stack. 428 * 429 ******************************************************************************/ 430 431 ACPI_STATUS 432 AcpiDsResultStackPush ( 433 ACPI_WALK_STATE *WalkState) 434 { 435 ACPI_GENERIC_STATE *State; 436 437 ACPI_FUNCTION_NAME (DsResultStackPush); 438 439 440 State = AcpiUtCreateGenericState (); 441 if (!State) 442 { 443 return (AE_NO_MEMORY); 444 } 445 446 State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT; 447 AcpiUtPushGenericState (&WalkState->Results, State); 448 449 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n", 450 State, WalkState)); 451 452 return (AE_OK); 453 } 454 455 456 /******************************************************************************* 457 * 458 * FUNCTION: AcpiDsResultStackPop 459 * 460 * PARAMETERS: WalkState - Current Walk state 461 * 462 * RETURN: Status 463 * 464 * DESCRIPTION: Pop an object off of the WalkState result stack. 465 * 466 ******************************************************************************/ 467 468 ACPI_STATUS 469 AcpiDsResultStackPop ( 470 ACPI_WALK_STATE *WalkState) 471 { 472 ACPI_GENERIC_STATE *State; 473 474 ACPI_FUNCTION_NAME (DsResultStackPop); 475 476 477 /* Check for stack underflow */ 478 479 if (WalkState->Results == NULL) 480 { 481 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%p\n", 482 WalkState)); 483 return (AE_AML_NO_OPERAND); 484 } 485 486 State = AcpiUtPopGenericState (&WalkState->Results); 487 488 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 489 "Result=%p RemainingResults=%X State=%p\n", 490 State, State->Results.NumResults, WalkState)); 491 492 AcpiUtDeleteGenericState (State); 493 494 return (AE_OK); 495 } 496 497 498 /******************************************************************************* 499 * 500 * FUNCTION: AcpiDsObjStackPush 501 * 502 * PARAMETERS: Object - Object to push 503 * WalkState - Current Walk state 504 * 505 * RETURN: Status 506 * 507 * DESCRIPTION: Push an object onto this walk's object/operand stack 508 * 509 ******************************************************************************/ 510 511 ACPI_STATUS 512 AcpiDsObjStackPush ( 513 void *Object, 514 ACPI_WALK_STATE *WalkState) 515 { 516 ACPI_FUNCTION_NAME (DsObjStackPush); 517 518 519 /* Check for stack overflow */ 520 521 if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS) 522 { 523 ACPI_ERROR ((AE_INFO, 524 "Object stack overflow! Obj=%p State=%p #Ops=%X", 525 Object, WalkState, WalkState->NumOperands)); 526 return (AE_STACK_OVERFLOW); 527 } 528 529 /* Put the object onto the stack */ 530 531 WalkState->Operands [WalkState->NumOperands] = Object; 532 WalkState->NumOperands++; 533 534 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", 535 Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object), 536 WalkState, WalkState->NumOperands)); 537 538 return (AE_OK); 539 } 540 541 542 /******************************************************************************* 543 * 544 * FUNCTION: AcpiDsObjStackPop 545 * 546 * PARAMETERS: PopCount - Number of objects/entries to pop 547 * WalkState - Current Walk state 548 * 549 * RETURN: Status 550 * 551 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT 552 * deleted by this routine. 553 * 554 ******************************************************************************/ 555 556 ACPI_STATUS 557 AcpiDsObjStackPop ( 558 UINT32 PopCount, 559 ACPI_WALK_STATE *WalkState) 560 { 561 UINT32 i; 562 563 ACPI_FUNCTION_NAME (DsObjStackPop); 564 565 566 for (i = 0; i < PopCount; i++) 567 { 568 /* Check for stack underflow */ 569 570 if (WalkState->NumOperands == 0) 571 { 572 ACPI_ERROR ((AE_INFO, 573 "Object stack underflow! Count=%X State=%p #Ops=%X", 574 PopCount, WalkState, WalkState->NumOperands)); 575 return (AE_STACK_UNDERFLOW); 576 } 577 578 /* Just set the stack entry to null */ 579 580 WalkState->NumOperands--; 581 WalkState->Operands [WalkState->NumOperands] = NULL; 582 } 583 584 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", 585 PopCount, WalkState, WalkState->NumOperands)); 586 587 return (AE_OK); 588 } 589 590 591 /******************************************************************************* 592 * 593 * FUNCTION: AcpiDsObjStackPopAndDelete 594 * 595 * PARAMETERS: PopCount - Number of objects/entries to pop 596 * WalkState - Current Walk state 597 * 598 * RETURN: Status 599 * 600 * DESCRIPTION: Pop this walk's object stack and delete each object that is 601 * popped off. 602 * 603 ******************************************************************************/ 604 605 ACPI_STATUS 606 AcpiDsObjStackPopAndDelete ( 607 UINT32 PopCount, 608 ACPI_WALK_STATE *WalkState) 609 { 610 UINT32 i; 611 ACPI_OPERAND_OBJECT *ObjDesc; 612 613 614 ACPI_FUNCTION_NAME (DsObjStackPopAndDelete); 615 616 617 for (i = 0; i < PopCount; i++) 618 { 619 /* Check for stack underflow */ 620 621 if (WalkState->NumOperands == 0) 622 { 623 ACPI_ERROR ((AE_INFO, 624 "Object stack underflow! Count=%X State=%p #Ops=%X", 625 PopCount, WalkState, WalkState->NumOperands)); 626 return (AE_STACK_UNDERFLOW); 627 } 628 629 /* Pop the stack and delete an object if present in this stack entry */ 630 631 WalkState->NumOperands--; 632 ObjDesc = WalkState->Operands [WalkState->NumOperands]; 633 if (ObjDesc) 634 { 635 AcpiUtRemoveReference (WalkState->Operands [WalkState->NumOperands]); 636 WalkState->Operands [WalkState->NumOperands] = NULL; 637 } 638 } 639 640 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", 641 PopCount, WalkState, WalkState->NumOperands)); 642 643 return (AE_OK); 644 } 645 646 647 /******************************************************************************* 648 * 649 * FUNCTION: AcpiDsGetCurrentWalkState 650 * 651 * PARAMETERS: Thread - Get current active state for this Thread 652 * 653 * RETURN: Pointer to the current walk state 654 * 655 * DESCRIPTION: Get the walk state that is at the head of the list (the "current" 656 * walk state.) 657 * 658 ******************************************************************************/ 659 660 ACPI_WALK_STATE * 661 AcpiDsGetCurrentWalkState ( 662 ACPI_THREAD_STATE *Thread) 663 664 { 665 ACPI_FUNCTION_NAME (DsGetCurrentWalkState); 666 667 668 if (!Thread) 669 { 670 return (NULL); 671 } 672 673 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n", 674 Thread->WalkStateList)); 675 676 return (Thread->WalkStateList); 677 } 678 679 680 /******************************************************************************* 681 * 682 * FUNCTION: AcpiDsPushWalkState 683 * 684 * PARAMETERS: WalkState - State to push 685 * Thread - Thread state object 686 * 687 * RETURN: None 688 * 689 * DESCRIPTION: Place the Thread state at the head of the state list. 690 * 691 ******************************************************************************/ 692 693 void 694 AcpiDsPushWalkState ( 695 ACPI_WALK_STATE *WalkState, 696 ACPI_THREAD_STATE *Thread) 697 { 698 ACPI_FUNCTION_TRACE (DsPushWalkState); 699 700 701 WalkState->Next = Thread->WalkStateList; 702 Thread->WalkStateList = WalkState; 703 704 return_VOID; 705 } 706 707 708 /******************************************************************************* 709 * 710 * FUNCTION: AcpiDsPopWalkState 711 * 712 * PARAMETERS: Thread - Current thread state 713 * 714 * RETURN: A WalkState object popped from the thread's stack 715 * 716 * DESCRIPTION: Remove and return the walkstate object that is at the head of 717 * the walk stack for the given walk list. NULL indicates that 718 * the list is empty. 719 * 720 ******************************************************************************/ 721 722 ACPI_WALK_STATE * 723 AcpiDsPopWalkState ( 724 ACPI_THREAD_STATE *Thread) 725 { 726 ACPI_WALK_STATE *WalkState; 727 728 729 ACPI_FUNCTION_TRACE (DsPopWalkState); 730 731 732 WalkState = Thread->WalkStateList; 733 734 if (WalkState) 735 { 736 /* Next walk state becomes the current walk state */ 737 738 Thread->WalkStateList = WalkState->Next; 739 740 /* 741 * Don't clear the NEXT field, this serves as an indicator 742 * that there is a parent WALK STATE 743 * Do Not: WalkState->Next = NULL; 744 */ 745 } 746 747 return_PTR (WalkState); 748 } 749 750 751 /******************************************************************************* 752 * 753 * FUNCTION: AcpiDsCreateWalkState 754 * 755 * PARAMETERS: OwnerId - ID for object creation 756 * Origin - Starting point for this walk 757 * MethodDesc - Method object 758 * Thread - Current thread state 759 * 760 * RETURN: Pointer to the new walk state. 761 * 762 * DESCRIPTION: Allocate and initialize a new walk state. The current walk 763 * state is set to this new state. 764 * 765 ******************************************************************************/ 766 767 ACPI_WALK_STATE * 768 AcpiDsCreateWalkState ( 769 ACPI_OWNER_ID OwnerId, 770 ACPI_PARSE_OBJECT *Origin, 771 ACPI_OPERAND_OBJECT *MethodDesc, 772 ACPI_THREAD_STATE *Thread) 773 { 774 ACPI_WALK_STATE *WalkState; 775 ACPI_STATUS Status; 776 777 778 ACPI_FUNCTION_TRACE (DsCreateWalkState); 779 780 781 WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE)); 782 if (!WalkState) 783 { 784 return_PTR (NULL); 785 } 786 787 WalkState->DescriptorType = ACPI_DESC_TYPE_WALK; 788 WalkState->MethodDesc = MethodDesc; 789 WalkState->OwnerId = OwnerId; 790 WalkState->Origin = Origin; 791 WalkState->Thread = Thread; 792 793 WalkState->ParserState.StartOp = Origin; 794 795 /* Init the method args/local */ 796 797 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) 798 AcpiDsMethodDataInit (WalkState); 799 #endif 800 801 /* Create an initial result stack entry */ 802 803 Status = AcpiDsResultStackPush (WalkState); 804 if (ACPI_FAILURE (Status)) 805 { 806 ACPI_FREE (WalkState); 807 return_PTR (NULL); 808 } 809 810 /* Put the new state at the head of the walk list */ 811 812 if (Thread) 813 { 814 AcpiDsPushWalkState (WalkState, Thread); 815 } 816 817 return_PTR (WalkState); 818 } 819 820 821 /******************************************************************************* 822 * 823 * FUNCTION: AcpiDsInitAmlWalk 824 * 825 * PARAMETERS: WalkState - New state to be initialized 826 * Op - Current parse op 827 * MethodNode - Control method NS node, if any 828 * AmlStart - Start of AML 829 * AmlLength - Length of AML 830 * Info - Method info block (params, etc.) 831 * PassNumber - 1, 2, or 3 832 * 833 * RETURN: Status 834 * 835 * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk 836 * 837 ******************************************************************************/ 838 839 ACPI_STATUS 840 AcpiDsInitAmlWalk ( 841 ACPI_WALK_STATE *WalkState, 842 ACPI_PARSE_OBJECT *Op, 843 ACPI_NAMESPACE_NODE *MethodNode, 844 UINT8 *AmlStart, 845 UINT32 AmlLength, 846 ACPI_EVALUATE_INFO *Info, 847 UINT8 PassNumber) 848 { 849 ACPI_STATUS Status; 850 ACPI_PARSE_STATE *ParserState = &WalkState->ParserState; 851 ACPI_PARSE_OBJECT *ExtraOp; 852 853 854 ACPI_FUNCTION_TRACE (DsInitAmlWalk); 855 856 857 WalkState->ParserState.Aml = 858 WalkState->ParserState.AmlStart = AmlStart; 859 WalkState->ParserState.AmlEnd = 860 WalkState->ParserState.PkgEnd = AmlStart + AmlLength; 861 862 /* The NextOp of the NextWalk will be the beginning of the method */ 863 864 WalkState->NextOp = NULL; 865 WalkState->PassNumber = PassNumber; 866 867 if (Info) 868 { 869 if (Info->ParameterType == ACPI_PARAM_GPE) 870 { 871 WalkState->GpeEventInfo = 872 ACPI_CAST_PTR (ACPI_GPE_EVENT_INFO, Info->Parameters); 873 } 874 else 875 { 876 WalkState->Params = Info->Parameters; 877 WalkState->CallerReturnDesc = &Info->ReturnObject; 878 } 879 } 880 881 Status = AcpiPsInitScope (&WalkState->ParserState, Op); 882 if (ACPI_FAILURE (Status)) 883 { 884 return_ACPI_STATUS (Status); 885 } 886 887 if (MethodNode) 888 { 889 WalkState->ParserState.StartNode = MethodNode; 890 WalkState->WalkType = ACPI_WALK_METHOD; 891 WalkState->MethodNode = MethodNode; 892 WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode); 893 894 /* Push start scope on scope stack and make it current */ 895 896 Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState); 897 if (ACPI_FAILURE (Status)) 898 { 899 return_ACPI_STATUS (Status); 900 } 901 902 /* Init the method arguments */ 903 904 Status = AcpiDsMethodDataInitArgs (WalkState->Params, 905 ACPI_METHOD_NUM_ARGS, WalkState); 906 if (ACPI_FAILURE (Status)) 907 { 908 return_ACPI_STATUS (Status); 909 } 910 } 911 else 912 { 913 /* 914 * Setup the current scope. 915 * Find a Named Op that has a namespace node associated with it. 916 * search upwards from this Op. Current scope is the first 917 * Op with a namespace node. 918 */ 919 ExtraOp = ParserState->StartOp; 920 while (ExtraOp && !ExtraOp->Common.Node) 921 { 922 ExtraOp = ExtraOp->Common.Parent; 923 } 924 925 if (!ExtraOp) 926 { 927 ParserState->StartNode = NULL; 928 } 929 else 930 { 931 ParserState->StartNode = ExtraOp->Common.Node; 932 } 933 934 if (ParserState->StartNode) 935 { 936 /* Push start scope on scope stack and make it current */ 937 938 Status = AcpiDsScopeStackPush (ParserState->StartNode, 939 ParserState->StartNode->Type, WalkState); 940 if (ACPI_FAILURE (Status)) 941 { 942 return_ACPI_STATUS (Status); 943 } 944 } 945 } 946 947 Status = AcpiDsInitCallbacks (WalkState, PassNumber); 948 return_ACPI_STATUS (Status); 949 } 950 951 952 /******************************************************************************* 953 * 954 * FUNCTION: AcpiDsDeleteWalkState 955 * 956 * PARAMETERS: WalkState - State to delete 957 * 958 * RETURN: Status 959 * 960 * DESCRIPTION: Delete a walk state including all internal data structures 961 * 962 ******************************************************************************/ 963 964 void 965 AcpiDsDeleteWalkState ( 966 ACPI_WALK_STATE *WalkState) 967 { 968 ACPI_GENERIC_STATE *State; 969 970 971 ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState); 972 973 974 if (!WalkState) 975 { 976 return; 977 } 978 979 if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK) 980 { 981 ACPI_ERROR ((AE_INFO, "%p is not a valid walk state", 982 WalkState)); 983 return; 984 } 985 986 /* There should not be any open scopes */ 987 988 if (WalkState->ParserState.Scope) 989 { 990 ACPI_ERROR ((AE_INFO, "%p walk still has a scope list", 991 WalkState)); 992 AcpiPsCleanupScope (&WalkState->ParserState); 993 } 994 995 /* Always must free any linked control states */ 996 997 while (WalkState->ControlState) 998 { 999 State = WalkState->ControlState; 1000 WalkState->ControlState = State->Common.Next; 1001 1002 AcpiUtDeleteGenericState (State); 1003 } 1004 1005 /* Always must free any linked parse states */ 1006 1007 while (WalkState->ScopeInfo) 1008 { 1009 State = WalkState->ScopeInfo; 1010 WalkState->ScopeInfo = State->Common.Next; 1011 1012 AcpiUtDeleteGenericState (State); 1013 } 1014 1015 /* Always must free any stacked result states */ 1016 1017 while (WalkState->Results) 1018 { 1019 State = WalkState->Results; 1020 WalkState->Results = State->Common.Next; 1021 1022 AcpiUtDeleteGenericState (State); 1023 } 1024 1025 ACPI_FREE (WalkState); 1026 return_VOID; 1027 } 1028 1029 1030 #ifdef ACPI_OBSOLETE_FUNCTIONS 1031 /******************************************************************************* 1032 * 1033 * FUNCTION: AcpiDsResultInsert 1034 * 1035 * PARAMETERS: Object - Object to push 1036 * Index - Where to insert the object 1037 * WalkState - Current Walk state 1038 * 1039 * RETURN: Status 1040 * 1041 * DESCRIPTION: Insert an object onto this walk's result stack 1042 * 1043 ******************************************************************************/ 1044 1045 ACPI_STATUS 1046 AcpiDsResultInsert ( 1047 void *Object, 1048 UINT32 Index, 1049 ACPI_WALK_STATE *WalkState) 1050 { 1051 ACPI_GENERIC_STATE *State; 1052 1053 1054 ACPI_FUNCTION_NAME (DsResultInsert); 1055 1056 1057 State = WalkState->Results; 1058 if (!State) 1059 { 1060 ACPI_ERROR ((AE_INFO, "No result object pushed! State=%p", 1061 WalkState)); 1062 return (AE_NOT_EXIST); 1063 } 1064 1065 if (Index >= ACPI_OBJ_NUM_OPERANDS) 1066 { 1067 ACPI_ERROR ((AE_INFO, 1068 "Index out of range: %X Obj=%p State=%p Num=%X", 1069 Index, Object, WalkState, State->Results.NumResults)); 1070 return (AE_BAD_PARAMETER); 1071 } 1072 1073 if (!Object) 1074 { 1075 ACPI_ERROR ((AE_INFO, 1076 "Null Object! Index=%X Obj=%p State=%p Num=%X", 1077 Index, Object, WalkState, State->Results.NumResults)); 1078 return (AE_BAD_PARAMETER); 1079 } 1080 1081 State->Results.ObjDesc [Index] = Object; 1082 State->Results.NumResults++; 1083 1084 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 1085 "Obj=%p [%s] State=%p Num=%X Cur=%X\n", 1086 Object, Object ? AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object) : "NULL", 1087 WalkState, State->Results.NumResults, WalkState->CurrentResult)); 1088 1089 return (AE_OK); 1090 } 1091 1092 1093 /******************************************************************************* 1094 * 1095 * FUNCTION: AcpiDsObjStackDeleteAll 1096 * 1097 * PARAMETERS: WalkState - Current Walk state 1098 * 1099 * RETURN: Status 1100 * 1101 * DESCRIPTION: Clear the object stack by deleting all objects that are on it. 1102 * Should be used with great care, if at all! 1103 * 1104 ******************************************************************************/ 1105 1106 ACPI_STATUS 1107 AcpiDsObjStackDeleteAll ( 1108 ACPI_WALK_STATE *WalkState) 1109 { 1110 UINT32 i; 1111 1112 1113 ACPI_FUNCTION_TRACE_PTR (DsObjStackDeleteAll, WalkState); 1114 1115 1116 /* The stack size is configurable, but fixed */ 1117 1118 for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) 1119 { 1120 if (WalkState->Operands[i]) 1121 { 1122 AcpiUtRemoveReference (WalkState->Operands[i]); 1123 WalkState->Operands[i] = NULL; 1124 } 1125 } 1126 1127 return_ACPI_STATUS (AE_OK); 1128 } 1129 1130 1131 /******************************************************************************* 1132 * 1133 * FUNCTION: AcpiDsObjStackPopObject 1134 * 1135 * PARAMETERS: Object - Where to return the popped object 1136 * WalkState - Current Walk state 1137 * 1138 * RETURN: Status 1139 * 1140 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT 1141 * deleted by this routine. 1142 * 1143 ******************************************************************************/ 1144 1145 ACPI_STATUS 1146 AcpiDsObjStackPopObject ( 1147 ACPI_OPERAND_OBJECT **Object, 1148 ACPI_WALK_STATE *WalkState) 1149 { 1150 ACPI_FUNCTION_NAME (DsObjStackPopObject); 1151 1152 1153 /* Check for stack underflow */ 1154 1155 if (WalkState->NumOperands == 0) 1156 { 1157 ACPI_ERROR ((AE_INFO, 1158 "Missing operand/stack empty! State=%p #Ops=%X", 1159 WalkState, WalkState->NumOperands)); 1160 *Object = NULL; 1161 return (AE_AML_NO_OPERAND); 1162 } 1163 1164 /* Pop the stack */ 1165 1166 WalkState->NumOperands--; 1167 1168 /* Check for a valid operand */ 1169 1170 if (!WalkState->Operands [WalkState->NumOperands]) 1171 { 1172 ACPI_ERROR ((AE_INFO, 1173 "Null operand! State=%p #Ops=%X", 1174 WalkState, WalkState->NumOperands)); 1175 *Object = NULL; 1176 return (AE_AML_NO_OPERAND); 1177 } 1178 1179 /* Get operand and set stack entry to null */ 1180 1181 *Object = WalkState->Operands [WalkState->NumOperands]; 1182 WalkState->Operands [WalkState->NumOperands] = NULL; 1183 1184 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", 1185 *Object, AcpiUtGetObjectTypeName (*Object), 1186 WalkState, WalkState->NumOperands)); 1187 1188 return (AE_OK); 1189 } 1190 1191 1192 /******************************************************************************* 1193 * 1194 * FUNCTION: AcpiDsObjStackGetValue 1195 * 1196 * PARAMETERS: Index - Stack index whose value is desired. Based 1197 * on the top of the stack (index=0 == top) 1198 * WalkState - Current Walk state 1199 * 1200 * RETURN: Pointer to the requested operand 1201 * 1202 * DESCRIPTION: Retrieve an object from this walk's operand stack. Index must 1203 * be within the range of the current stack pointer. 1204 * 1205 ******************************************************************************/ 1206 1207 void * 1208 AcpiDsObjStackGetValue ( 1209 UINT32 Index, 1210 ACPI_WALK_STATE *WalkState) 1211 { 1212 1213 ACPI_FUNCTION_TRACE_PTR (DsObjStackGetValue, WalkState); 1214 1215 1216 /* Can't do it if the stack is empty */ 1217 1218 if (WalkState->NumOperands == 0) 1219 { 1220 return_PTR (NULL); 1221 } 1222 1223 /* or if the index is past the top of the stack */ 1224 1225 if (Index > (WalkState->NumOperands - (UINT32) 1)) 1226 { 1227 return_PTR (NULL); 1228 } 1229 1230 return_PTR (WalkState->Operands[(ACPI_NATIVE_UINT)(WalkState->NumOperands - 1) - 1231 Index]); 1232 } 1233 #endif 1234 1235 1236