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