Merge from vendor branch BINUTILS:
[dragonfly.git] / sys / contrib / dev / acpica / dswstate.c
1 /******************************************************************************
2  *
3  * Module Name: dswstate - Dispatcher parse tree walk management routines
4  *              $Revision: 75 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, 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 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/dswstate.c,v 1.1 2003/09/24 03:32:15 drhodus Exp $                                                               */
117
118
119 #define __DSWSTATE_C__
120
121 #include "acpi.h"
122 #include "acparser.h"
123 #include "acdispat.h"
124 #include "acnamesp.h"
125
126 #define _COMPONENT          ACPI_DISPATCHER
127         ACPI_MODULE_NAME    ("dswstate")
128
129
130 /*******************************************************************************
131  *
132  * FUNCTION:    AcpiDsResultInsert
133  *
134  * PARAMETERS:  Object              - Object to push
135  *              WalkState           - Current Walk state
136  *
137  * RETURN:      Status
138  *
139  * DESCRIPTION: Push an object onto this walk's result stack
140  *
141  ******************************************************************************/
142
143 ACPI_STATUS
144 AcpiDsResultInsert (
145     void                    *Object,
146     UINT32                  Index,
147     ACPI_WALK_STATE         *WalkState)
148 {
149     ACPI_GENERIC_STATE      *State;
150
151
152     ACPI_FUNCTION_NAME ("DsResultInsert");
153
154
155     State = WalkState->Results;
156     if (!State)
157     {
158         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
159             WalkState));
160         return (AE_NOT_EXIST);
161     }
162
163     if (Index >= ACPI_OBJ_NUM_OPERANDS)
164     {
165         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
166             "Index out of range: %X Obj=%p State=%p Num=%X\n",
167             Index, Object, WalkState, State->Results.NumResults));
168         return (AE_BAD_PARAMETER);
169     }
170
171     if (!Object)
172     {
173         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
174             "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
175             Index, Object, WalkState, State->Results.NumResults));
176         return (AE_BAD_PARAMETER);
177     }
178
179     State->Results.ObjDesc [Index] = Object;
180     State->Results.NumResults++;
181
182     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
183         "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
184         Object, Object ? AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object) : "NULL",
185         WalkState, State->Results.NumResults, WalkState->CurrentResult));
186
187     return (AE_OK);
188 }
189
190
191 /*******************************************************************************
192  *
193  * FUNCTION:    AcpiDsResultRemove
194  *
195  * PARAMETERS:  Object              - Where to return the popped object
196  *              WalkState           - Current Walk state
197  *
198  * RETURN:      Status
199  *
200  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
201  *              other words, this is a FIFO.
202  *
203  ******************************************************************************/
204
205 ACPI_STATUS
206 AcpiDsResultRemove (
207     ACPI_OPERAND_OBJECT     **Object,
208     UINT32                  Index,
209     ACPI_WALK_STATE         *WalkState)
210 {
211     ACPI_GENERIC_STATE      *State;
212
213
214     ACPI_FUNCTION_NAME ("DsResultRemove");
215
216
217     State = WalkState->Results;
218     if (!State)
219     {
220         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
221             WalkState));
222         return (AE_NOT_EXIST);
223     }
224
225     if (Index >= ACPI_OBJ_MAX_OPERAND)
226     {
227         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
228             "Index out of range: %X State=%p Num=%X\n",
229             Index, WalkState, State->Results.NumResults));
230     }
231
232     /* Check for a valid result object */
233
234     if (!State->Results.ObjDesc [Index])
235     {
236         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
237             "Null operand! State=%p #Ops=%X, Index=%X\n",
238             WalkState, State->Results.NumResults, Index));
239         return (AE_AML_NO_RETURN_VALUE);
240     }
241
242     /* Remove the object */
243
244     State->Results.NumResults--;
245
246     *Object = State->Results.ObjDesc [Index];
247     State->Results.ObjDesc [Index] = NULL;
248
249     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
250         "Obj=%p [%s] Index=%X State=%p Num=%X\n",
251         *Object, (*Object) ? AcpiUtGetObjectTypeName (*Object) : "NULL",
252         Index, WalkState, State->Results.NumResults));
253
254     return (AE_OK);
255 }
256
257
258 /*******************************************************************************
259  *
260  * FUNCTION:    AcpiDsResultPop
261  *
262  * PARAMETERS:  Object              - Where to return the popped object
263  *              WalkState           - Current Walk state
264  *
265  * RETURN:      Status
266  *
267  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
268  *              other words, this is a FIFO.
269  *
270  ******************************************************************************/
271
272 ACPI_STATUS
273 AcpiDsResultPop (
274     ACPI_OPERAND_OBJECT     **Object,
275     ACPI_WALK_STATE         *WalkState)
276 {
277     ACPI_NATIVE_UINT        Index;
278     ACPI_GENERIC_STATE      *State;
279
280
281     ACPI_FUNCTION_NAME ("DsResultPop");
282
283
284     State = WalkState->Results;
285     if (!State)
286     {
287         return (AE_OK);
288     }
289
290     if (!State->Results.NumResults)
291     {
292         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack is empty! State=%p\n",
293             WalkState));
294         return (AE_AML_NO_RETURN_VALUE);
295     }
296
297     /* Remove top element */
298
299     State->Results.NumResults--;
300
301     for (Index = ACPI_OBJ_NUM_OPERANDS; Index; Index--)
302     {
303         /* Check for a valid result object */
304
305         if (State->Results.ObjDesc [Index -1])
306         {
307             *Object = State->Results.ObjDesc [Index -1];
308             State->Results.ObjDesc [Index -1] = NULL;
309
310             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
311                 *Object, (*Object) ? AcpiUtGetObjectTypeName (*Object) : "NULL",
312                 (UINT32) Index -1, WalkState, State->Results.NumResults));
313
314             return (AE_OK);
315         }
316     }
317
318     ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", WalkState));
319     return (AE_AML_NO_RETURN_VALUE);
320 }
321
322 /*******************************************************************************
323  *
324  * FUNCTION:    AcpiDsResultPopFromBottom
325  *
326  * PARAMETERS:  Object              - Where to return the popped object
327  *              WalkState           - Current Walk state
328  *
329  * RETURN:      Status
330  *
331  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
332  *              other words, this is a FIFO.
333  *
334  ******************************************************************************/
335
336 ACPI_STATUS
337 AcpiDsResultPopFromBottom (
338     ACPI_OPERAND_OBJECT     **Object,
339     ACPI_WALK_STATE         *WalkState)
340 {
341     ACPI_NATIVE_UINT        Index;
342     ACPI_GENERIC_STATE      *State;
343
344
345     ACPI_FUNCTION_NAME ("DsResultPopFromBottom");
346
347
348     State = WalkState->Results;
349     if (!State)
350     {
351         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
352             "Warning: No result object pushed! State=%p\n", WalkState));
353         return (AE_NOT_EXIST);
354     }
355
356     if (!State->Results.NumResults)
357     {
358         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", WalkState));
359         return (AE_AML_NO_RETURN_VALUE);
360     }
361
362     /* Remove Bottom element */
363
364     *Object = State->Results.ObjDesc [0];
365
366     /* Push entire stack down one element */
367
368     for (Index = 0; Index < State->Results.NumResults; Index++)
369     {
370         State->Results.ObjDesc [Index] = State->Results.ObjDesc [Index + 1];
371     }
372
373     State->Results.NumResults--;
374
375     /* Check for a valid result object */
376
377     if (!*Object)
378     {
379         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n",
380             WalkState, State->Results.NumResults, (UINT32) Index));
381         return (AE_AML_NO_RETURN_VALUE);
382     }
383
384     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n",
385         *Object, (*Object) ? AcpiUtGetObjectTypeName (*Object) : "NULL",
386         State, WalkState));
387
388
389     return (AE_OK);
390 }
391
392
393 /*******************************************************************************
394  *
395  * FUNCTION:    AcpiDsResultPush
396  *
397  * PARAMETERS:  Object              - Where to return the popped object
398  *              WalkState           - Current Walk state
399  *
400  * RETURN:      Status
401  *
402  * DESCRIPTION: Push an object onto the current result stack
403  *
404  ******************************************************************************/
405
406 ACPI_STATUS
407 AcpiDsResultPush (
408     ACPI_OPERAND_OBJECT     *Object,
409     ACPI_WALK_STATE         *WalkState)
410 {
411     ACPI_GENERIC_STATE      *State;
412
413
414     ACPI_FUNCTION_NAME ("DsResultPush");
415
416
417     State = WalkState->Results;
418     if (!State)
419     {
420         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result stack frame\n"));
421         return (AE_AML_INTERNAL);
422     }
423
424     if (State->Results.NumResults == ACPI_OBJ_NUM_OPERANDS)
425     {
426         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
427             "Result stack overflow: Obj=%p State=%p Num=%X\n",
428             Object, WalkState, State->Results.NumResults));
429         return (AE_STACK_OVERFLOW);
430     }
431
432     if (!Object)
433     {
434         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%X\n",
435             Object, WalkState, State->Results.NumResults));
436         return (AE_BAD_PARAMETER);
437     }
438
439     State->Results.ObjDesc [State->Results.NumResults] = Object;
440     State->Results.NumResults++;
441
442     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
443         Object, Object ? AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object) : "NULL",
444         WalkState, State->Results.NumResults, WalkState->CurrentResult));
445
446     return (AE_OK);
447 }
448
449
450 /*******************************************************************************
451  *
452  * FUNCTION:    AcpiDsResultStackPush
453  *
454  * PARAMETERS:  Object              - Object to push
455  *              WalkState           - Current Walk state
456  *
457  * RETURN:      Status
458  *
459  * DESCRIPTION: Push an object onto the WalkState result stack.
460  *
461  ******************************************************************************/
462
463 ACPI_STATUS
464 AcpiDsResultStackPush (
465     ACPI_WALK_STATE         *WalkState)
466 {
467     ACPI_GENERIC_STATE      *State;
468
469     ACPI_FUNCTION_NAME ("DsResultStackPush");
470
471
472     State = AcpiUtCreateGenericState ();
473     if (!State)
474     {
475         return (AE_NO_MEMORY);
476     }
477
478     State->Common.DataType  = ACPI_DESC_TYPE_STATE_RESULT;
479     AcpiUtPushGenericState (&WalkState->Results, State);
480
481     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
482         State, WalkState));
483
484     return (AE_OK);
485 }
486
487
488 /*******************************************************************************
489  *
490  * FUNCTION:    AcpiDsResultStackPop
491  *
492  * PARAMETERS:  WalkState           - Current Walk state
493  *
494  * RETURN:      Status
495  *
496  * DESCRIPTION: Pop an object off of the WalkState result stack.
497  *
498  ******************************************************************************/
499
500 ACPI_STATUS
501 AcpiDsResultStackPop (
502     ACPI_WALK_STATE         *WalkState)
503 {
504     ACPI_GENERIC_STATE      *State;
505
506     ACPI_FUNCTION_NAME ("DsResultStackPop");
507
508
509     /* Check for stack underflow */
510
511     if (WalkState->Results == NULL)
512     {
513         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%p\n",
514             WalkState));
515         return (AE_AML_NO_OPERAND);
516     }
517
518
519     State = AcpiUtPopGenericState (&WalkState->Results);
520
521     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
522         "Result=%p RemainingResults=%X State=%p\n",
523         State, State->Results.NumResults, WalkState));
524
525     AcpiUtDeleteGenericState (State);
526
527     return (AE_OK);
528 }
529
530
531 /*******************************************************************************
532  *
533  * FUNCTION:    AcpiDsObjStackDeleteAll
534  *
535  * PARAMETERS:  WalkState           - Current Walk state
536  *
537  * RETURN:      Status
538  *
539  * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
540  *              Should be used with great care, if at all!
541  *
542  ******************************************************************************/
543
544 ACPI_STATUS
545 AcpiDsObjStackDeleteAll (
546     ACPI_WALK_STATE         *WalkState)
547 {
548     UINT32                  i;
549
550
551     ACPI_FUNCTION_TRACE_PTR ("DsObjStackDeleteAll", WalkState);
552
553
554     /* The stack size is configurable, but fixed */
555
556     for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++)
557     {
558         if (WalkState->Operands[i])
559         {
560             AcpiUtRemoveReference (WalkState->Operands[i]);
561             WalkState->Operands[i] = NULL;
562         }
563     }
564
565     return_ACPI_STATUS (AE_OK);
566 }
567
568
569 /*******************************************************************************
570  *
571  * FUNCTION:    AcpiDsObjStackPush
572  *
573  * PARAMETERS:  Object              - Object to push
574  *              WalkState           - Current Walk state
575  *
576  * RETURN:      Status
577  *
578  * DESCRIPTION: Push an object onto this walk's object/operand stack
579  *
580  ******************************************************************************/
581
582 ACPI_STATUS
583 AcpiDsObjStackPush (
584     void                    *Object,
585     ACPI_WALK_STATE         *WalkState)
586 {
587     ACPI_FUNCTION_NAME ("DsObjStackPush");
588
589
590     /* Check for stack overflow */
591
592     if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
593     {
594         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
595             "overflow! Obj=%p State=%p #Ops=%X\n",
596             Object, WalkState, WalkState->NumOperands));
597         return (AE_STACK_OVERFLOW);
598     }
599
600     /* Put the object onto the stack */
601
602     WalkState->Operands [WalkState->NumOperands] = Object;
603     WalkState->NumOperands++;
604
605     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
606                     Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
607                     WalkState, WalkState->NumOperands));
608
609     return (AE_OK);
610 }
611
612
613 #if 0
614 /*******************************************************************************
615  *
616  * FUNCTION:    AcpiDsObjStackPopObject
617  *
618  * PARAMETERS:  PopCount            - Number of objects/entries to pop
619  *              WalkState           - Current Walk state
620  *
621  * RETURN:      Status
622  *
623  * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
624  *              deleted by this routine.
625  *
626  ******************************************************************************/
627
628 ACPI_STATUS
629 AcpiDsObjStackPopObject (
630     ACPI_OPERAND_OBJECT     **Object,
631     ACPI_WALK_STATE         *WalkState)
632 {
633     ACPI_FUNCTION_NAME ("DsObjStackPopObject");
634
635
636     /* Check for stack underflow */
637
638     if (WalkState->NumOperands == 0)
639     {
640         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
641             "Missing operand/stack empty! State=%p #Ops=%X\n",
642             WalkState, WalkState->NumOperands));
643         *Object = NULL;
644         return (AE_AML_NO_OPERAND);
645     }
646
647     /* Pop the stack */
648
649     WalkState->NumOperands--;
650
651     /* Check for a valid operand */
652
653     if (!WalkState->Operands [WalkState->NumOperands])
654     {
655         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
656             "Null operand! State=%p #Ops=%X\n",
657             WalkState, WalkState->NumOperands));
658         *Object = NULL;
659         return (AE_AML_NO_OPERAND);
660     }
661
662     /* Get operand and set stack entry to null */
663
664     *Object = WalkState->Operands [WalkState->NumOperands];
665     WalkState->Operands [WalkState->NumOperands] = NULL;
666
667     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
668                     *Object, AcpiUtGetObjectTypeName (*Object),
669                     WalkState, WalkState->NumOperands));
670
671     return (AE_OK);
672 }
673 #endif
674
675 /*******************************************************************************
676  *
677  * FUNCTION:    AcpiDsObjStackPop
678  *
679  * PARAMETERS:  PopCount            - Number of objects/entries to pop
680  *              WalkState           - Current Walk state
681  *
682  * RETURN:      Status
683  *
684  * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
685  *              deleted by this routine.
686  *
687  ******************************************************************************/
688
689 ACPI_STATUS
690 AcpiDsObjStackPop (
691     UINT32                  PopCount,
692     ACPI_WALK_STATE         *WalkState)
693 {
694     UINT32                  i;
695
696     ACPI_FUNCTION_NAME ("DsObjStackPop");
697
698
699     for (i = 0; i < PopCount; i++)
700     {
701         /* Check for stack underflow */
702
703         if (WalkState->NumOperands == 0)
704         {
705             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
706                 "Underflow! Count=%X State=%p #Ops=%X\n",
707                 PopCount, WalkState, WalkState->NumOperands));
708             return (AE_STACK_UNDERFLOW);
709         }
710
711         /* Just set the stack entry to null */
712
713         WalkState->NumOperands--;
714         WalkState->Operands [WalkState->NumOperands] = NULL;
715     }
716
717     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
718                     PopCount, WalkState, WalkState->NumOperands));
719
720     return (AE_OK);
721 }
722
723
724 /*******************************************************************************
725  *
726  * FUNCTION:    AcpiDsObjStackPopAndDelete
727  *
728  * PARAMETERS:  PopCount            - Number of objects/entries to pop
729  *              WalkState           - Current Walk state
730  *
731  * RETURN:      Status
732  *
733  * DESCRIPTION: Pop this walk's object stack and delete each object that is
734  *              popped off.
735  *
736  ******************************************************************************/
737
738 ACPI_STATUS
739 AcpiDsObjStackPopAndDelete (
740     UINT32                  PopCount,
741     ACPI_WALK_STATE         *WalkState)
742 {
743     UINT32                  i;
744     ACPI_OPERAND_OBJECT     *ObjDesc;
745
746     ACPI_FUNCTION_NAME ("DsObjStackPopAndDelete");
747
748
749     for (i = 0; i < PopCount; i++)
750     {
751         /* Check for stack underflow */
752
753         if (WalkState->NumOperands == 0)
754         {
755             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
756                 "Underflow! Count=%X State=%p #Ops=%X\n",
757                 PopCount, WalkState, WalkState->NumOperands));
758             return (AE_STACK_UNDERFLOW);
759         }
760
761         /* Pop the stack and delete an object if present in this stack entry */
762
763         WalkState->NumOperands--;
764         ObjDesc = WalkState->Operands [WalkState->NumOperands];
765         if (ObjDesc)
766         {
767             AcpiUtRemoveReference (WalkState->Operands [WalkState->NumOperands]);
768             WalkState->Operands [WalkState->NumOperands] = NULL;
769         }
770     }
771
772     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
773                     PopCount, WalkState, WalkState->NumOperands));
774
775     return (AE_OK);
776 }
777
778
779 /*******************************************************************************
780  *
781  * FUNCTION:    AcpiDsObjStackGetValue
782  *
783  * PARAMETERS:  Index               - Stack index whose value is desired.  Based
784  *                                    on the top of the stack (index=0 == top)
785  *              WalkState           - Current Walk state
786  *
787  * RETURN:      Status
788  *
789  * DESCRIPTION: Retrieve an object from this walk's object stack.  Index must
790  *              be within the range of the current stack pointer.
791  *
792  ******************************************************************************/
793
794 void *
795 AcpiDsObjStackGetValue (
796     UINT32                  Index,
797     ACPI_WALK_STATE         *WalkState)
798 {
799
800     ACPI_FUNCTION_TRACE_PTR ("DsObjStackGetValue", WalkState);
801
802
803     /* Can't do it if the stack is empty */
804
805     if (WalkState->NumOperands == 0)
806     {
807         return_PTR (NULL);
808     }
809
810     /* or if the index is past the top of the stack */
811
812     if (Index > (WalkState->NumOperands - (UINT32) 1))
813     {
814         return_PTR (NULL);
815     }
816
817     return_PTR (WalkState->Operands[(ACPI_NATIVE_UINT)(WalkState->NumOperands - 1) -
818                     Index]);
819 }
820
821
822 /*******************************************************************************
823  *
824  * FUNCTION:    AcpiDsGetCurrentWalkState
825  *
826  * PARAMETERS:  Thread          - Get current active state for this Thread
827  *
828  * RETURN:      Pointer to the current walk state
829  *
830  * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
831  *              walk state.)
832  *
833  ******************************************************************************/
834
835 ACPI_WALK_STATE *
836 AcpiDsGetCurrentWalkState (
837     ACPI_THREAD_STATE       *Thread)
838
839 {
840     ACPI_FUNCTION_NAME ("DsGetCurrentWalkState");
841
842
843     if (!Thread)
844     {
845         return (NULL);
846     }
847
848     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
849         Thread->WalkStateList));
850
851     return (Thread->WalkStateList);
852 }
853
854
855 /*******************************************************************************
856  *
857  * FUNCTION:    AcpiDsPushWalkState
858  *
859  * PARAMETERS:  WalkState       - State to push
860  *              WalkList        - The list that owns the walk stack
861  *
862  * RETURN:      None
863  *
864  * DESCRIPTION: Place the WalkState at the head of the state list.
865  *
866  ******************************************************************************/
867
868 void
869 AcpiDsPushWalkState (
870     ACPI_WALK_STATE         *WalkState,
871     ACPI_THREAD_STATE       *Thread)
872 {
873     ACPI_FUNCTION_TRACE ("DsPushWalkState");
874
875
876     WalkState->Next       = Thread->WalkStateList;
877     Thread->WalkStateList = WalkState;
878
879     return_VOID;
880 }
881
882
883 /*******************************************************************************
884  *
885  * FUNCTION:    AcpiDsPopWalkState
886  *
887  * PARAMETERS:  WalkList        - The list that owns the walk stack
888  *
889  * RETURN:      A WalkState object popped from the stack
890  *
891  * DESCRIPTION: Remove and return the walkstate object that is at the head of
892  *              the walk stack for the given walk list.  NULL indicates that
893  *              the list is empty.
894  *
895  ******************************************************************************/
896
897 ACPI_WALK_STATE *
898 AcpiDsPopWalkState (
899     ACPI_THREAD_STATE       *Thread)
900 {
901     ACPI_WALK_STATE         *WalkState;
902
903
904     ACPI_FUNCTION_TRACE ("DsPopWalkState");
905
906
907     WalkState = Thread->WalkStateList;
908
909     if (WalkState)
910     {
911         /* Next walk state becomes the current walk state */
912
913         Thread->WalkStateList = WalkState->Next;
914
915         /*
916          * Don't clear the NEXT field, this serves as an indicator
917          * that there is a parent WALK STATE
918          *     NO: WalkState->Next = NULL;
919          */
920     }
921
922     return_PTR (WalkState);
923 }
924
925
926 /*******************************************************************************
927  *
928  * FUNCTION:    AcpiDsCreateWalkState
929  *
930  * PARAMETERS:  Origin          - Starting point for this walk
931  *              Thread          - Current thread state
932  *
933  * RETURN:      Pointer to the new walk state.
934  *
935  * DESCRIPTION: Allocate and initialize a new walk state.  The current walk
936  *              state is set to this new state.
937  *
938  ******************************************************************************/
939
940 ACPI_WALK_STATE *
941 AcpiDsCreateWalkState (
942     ACPI_OWNER_ID           OwnerId,
943     ACPI_PARSE_OBJECT       *Origin,
944     ACPI_OPERAND_OBJECT     *MthDesc,
945     ACPI_THREAD_STATE       *Thread)
946 {
947     ACPI_WALK_STATE         *WalkState;
948     ACPI_STATUS             Status;
949
950
951     ACPI_FUNCTION_TRACE ("DsCreateWalkState");
952
953
954     WalkState = AcpiUtAcquireFromCache (ACPI_MEM_LIST_WALK);
955     if (!WalkState)
956     {
957         return_PTR (NULL);
958     }
959
960     WalkState->DataType         = ACPI_DESC_TYPE_WALK;
961     WalkState->OwnerId          = OwnerId;
962     WalkState->Origin           = Origin;
963     WalkState->MethodDesc       = MthDesc;
964     WalkState->Thread           = Thread;
965
966     WalkState->ParserState.StartOp = Origin;
967
968     /* Init the method args/local */
969
970 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
971     AcpiDsMethodDataInit (WalkState);
972 #endif
973
974     /* Create an initial result stack entry */
975
976     Status = AcpiDsResultStackPush (WalkState);
977     if (ACPI_FAILURE (Status))
978     {
979         return_PTR (NULL);
980     }
981
982     /* Put the new state at the head of the walk list */
983
984     if (Thread)
985     {
986         AcpiDsPushWalkState (WalkState, Thread);
987     }
988
989     return_PTR (WalkState);
990 }
991
992
993 /*******************************************************************************
994  *
995  * FUNCTION:    AcpiDsInitAmlWalk
996  *
997  * PARAMETERS:  WalkState       - New state to be initialized
998  *
999  * RETURN:      None
1000  *
1001  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
1002  *
1003  ******************************************************************************/
1004
1005 ACPI_STATUS
1006 AcpiDsInitAmlWalk (
1007     ACPI_WALK_STATE         *WalkState,
1008     ACPI_PARSE_OBJECT       *Op,
1009     ACPI_NAMESPACE_NODE     *MethodNode,
1010     UINT8                   *AmlStart,
1011     UINT32                  AmlLength,
1012     ACPI_OPERAND_OBJECT     **Params,
1013     ACPI_OPERAND_OBJECT     **ReturnObjDesc,
1014     UINT32                  PassNumber)
1015 {
1016     ACPI_STATUS             Status;
1017     ACPI_PARSE_STATE        *ParserState = &WalkState->ParserState;
1018     ACPI_PARSE_OBJECT       *ExtraOp;
1019
1020
1021     ACPI_FUNCTION_TRACE ("DsInitAmlWalk");
1022
1023
1024     WalkState->ParserState.Aml      =
1025     WalkState->ParserState.AmlStart = AmlStart;
1026     WalkState->ParserState.AmlEnd   =
1027     WalkState->ParserState.PkgEnd   = AmlStart + AmlLength;
1028
1029     /* The NextOp of the NextWalk will be the beginning of the method */
1030
1031     WalkState->NextOp               = NULL;
1032     WalkState->Params               = Params;
1033     WalkState->CallerReturnDesc     = ReturnObjDesc;
1034
1035     Status = AcpiPsInitScope (&WalkState->ParserState, Op);
1036     if (ACPI_FAILURE (Status))
1037     {
1038         return_ACPI_STATUS (Status);
1039     }
1040
1041     if (MethodNode)
1042     {
1043         WalkState->ParserState.StartNode    = MethodNode;
1044         WalkState->WalkType                 = ACPI_WALK_METHOD;
1045         WalkState->MethodNode               = MethodNode;
1046         WalkState->MethodDesc               = AcpiNsGetAttachedObject (MethodNode);
1047
1048         /* Push start scope on scope stack and make it current  */
1049
1050         Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState);
1051         if (ACPI_FAILURE (Status))
1052         {
1053             return_ACPI_STATUS (Status);
1054         }
1055
1056         /* Init the method arguments */
1057
1058         Status = AcpiDsMethodDataInitArgs (Params, ACPI_METHOD_NUM_ARGS, WalkState);
1059         if (ACPI_FAILURE (Status))
1060         {
1061             return_ACPI_STATUS (Status);
1062         }
1063     }
1064     else
1065     {
1066         /*
1067          * Setup the current scope.
1068          * Find a Named Op that has a namespace node associated with it.
1069          * search upwards from this Op.  Current scope is the first
1070          * Op with a namespace node.
1071          */
1072         ExtraOp = ParserState->StartOp;
1073         while (ExtraOp && !ExtraOp->Common.Node)
1074         {
1075             ExtraOp = ExtraOp->Common.Parent;
1076         }
1077         if (!ExtraOp)
1078         {
1079             ParserState->StartNode = NULL;
1080         }
1081         else
1082         {
1083             ParserState->StartNode = ExtraOp->Common.Node;
1084         }
1085
1086         if (ParserState->StartNode)
1087         {
1088             /* Push start scope on scope stack and make it current  */
1089
1090             Status = AcpiDsScopeStackPush (ParserState->StartNode,
1091                             ParserState->StartNode->Type, WalkState);
1092             if (ACPI_FAILURE (Status))
1093             {
1094                 return_ACPI_STATUS (Status);
1095             }
1096         }
1097     }
1098
1099     Status = AcpiDsInitCallbacks (WalkState, PassNumber);
1100     return_ACPI_STATUS (Status);
1101 }
1102
1103
1104 /*******************************************************************************
1105  *
1106  * FUNCTION:    AcpiDsDeleteWalkState
1107  *
1108  * PARAMETERS:  WalkState       - State to delete
1109  *
1110  * RETURN:      Status
1111  *
1112  * DESCRIPTION: Delete a walk state including all internal data structures
1113  *
1114  ******************************************************************************/
1115
1116 void
1117 AcpiDsDeleteWalkState (
1118     ACPI_WALK_STATE         *WalkState)
1119 {
1120     ACPI_GENERIC_STATE      *State;
1121
1122
1123     ACPI_FUNCTION_TRACE_PTR ("DsDeleteWalkState", WalkState);
1124
1125
1126     if (!WalkState)
1127     {
1128         return;
1129     }
1130
1131     if (WalkState->DataType != ACPI_DESC_TYPE_WALK)
1132     {
1133         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n", WalkState));
1134         return;
1135     }
1136
1137     if (WalkState->ParserState.Scope)
1138     {
1139         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", WalkState));
1140     }
1141
1142    /* Always must free any linked control states */
1143
1144     while (WalkState->ControlState)
1145     {
1146         State = WalkState->ControlState;
1147         WalkState->ControlState = State->Common.Next;
1148
1149         AcpiUtDeleteGenericState (State);
1150     }
1151
1152     /* Always must free any linked parse states */
1153
1154     while (WalkState->ScopeInfo)
1155     {
1156         State = WalkState->ScopeInfo;
1157         WalkState->ScopeInfo = State->Common.Next;
1158
1159         AcpiUtDeleteGenericState (State);
1160     }
1161
1162     /* Always must free any stacked result states */
1163
1164     while (WalkState->Results)
1165     {
1166         State = WalkState->Results;
1167         WalkState->Results = State->Common.Next;
1168
1169         AcpiUtDeleteGenericState (State);
1170     }
1171
1172     AcpiUtReleaseToCache (ACPI_MEM_LIST_WALK, WalkState);
1173     return_VOID;
1174 }
1175
1176
1177 /******************************************************************************
1178  *
1179  * FUNCTION:    AcpiDsDeleteWalkStateCache
1180  *
1181  * PARAMETERS:  None
1182  *
1183  * RETURN:      Status
1184  *
1185  * DESCRIPTION: Purge the global state object cache.  Used during subsystem
1186  *              termination.
1187  *
1188  ******************************************************************************/
1189
1190 void
1191 AcpiDsDeleteWalkStateCache (
1192     void)
1193 {
1194     ACPI_FUNCTION_TRACE ("DsDeleteWalkStateCache");
1195
1196
1197     AcpiUtDeleteGenericCache (ACPI_MEM_LIST_WALK);
1198     return_VOID;
1199 }
1200
1201