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