xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/dispatcher/dswstate.c (revision 39d6c466d8217dcb3004074f29c27c60f0fa1ac1)
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