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