Deleted Added
sdiff udiff text old ( 80062 ) new ( 82367 )
full compact
1/******************************************************************************
2 *
3 * Module Name: dswstate - Dispatcher parse tree walk management routines
4 * $Revision: 46 $
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
144ACPI_STATUS
145AcpiDsResultInsert (
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 DEBUG_PRINTP (ACPI_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 DEBUG_PRINTP (ACPI_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 DEBUG_PRINTP (ACPI_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 DEBUG_PRINTP (TRACE_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
206ACPI_STATUS
207AcpiDsResultRemove (
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 DEBUG_PRINTP (ACPI_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 DEBUG_PRINTP (ACPI_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 DEBUG_PRINTP (ACPI_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 DEBUG_PRINTP (TRACE_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
274ACPI_STATUS
275AcpiDsResultPop (
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
293 if (!State->Results.NumResults)
294 {
295 DEBUG_PRINTP (ACPI_ERROR, ("Result stack is empty! State=%p\n",
296 WalkState));
297 return (AE_AML_NO_RETURN_VALUE);
298 }
299
300 /* Remove top element */
301
302 State->Results.NumResults--;
303
304 for (Index = OBJ_NUM_OPERANDS; Index; Index--)
305 {
306 /* Check for a valid result object */
307
308 if (State->Results.ObjDesc [Index -1])
309 {
310 *Object = State->Results.ObjDesc [Index -1];
311 State->Results.ObjDesc [Index -1] = NULL;
312
313 DEBUG_PRINTP (TRACE_EXEC, ("Obj=%p [%s] Index=%X State=%p Num=%X\n",
314 *Object, (*Object) ? AcpiUtGetTypeName ((*Object)->Common.Type) : "NULL",
315 Index -1, WalkState, State->Results.NumResults));
316
317 return (AE_OK);
318 }
319 }
320
321
322 DEBUG_PRINTP (ACPI_ERROR, ("No result objects! State=%p\n", WalkState));
323 return (AE_AML_NO_RETURN_VALUE);
324}
325
326/*******************************************************************************
327 *
328 * FUNCTION: AcpiDsResultPopFromBottom
329 *
330 * PARAMETERS: Object - Where to return the popped object
331 * WalkState - Current Walk state
332 *
333 * RETURN: Status
334 *
335 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
336 * other words, this is a FIFO.
337 *
338 ******************************************************************************/
339
340ACPI_STATUS
341AcpiDsResultPopFromBottom (
342 ACPI_OPERAND_OBJECT **Object,
343 ACPI_WALK_STATE *WalkState)
344{
345 UINT32 Index;
346 ACPI_GENERIC_STATE *State;
347
348
349 PROC_NAME ("DsResultPopFromBottom");
350
351
352 State = WalkState->Results;
353 if (!State)
354 {
355 DEBUG_PRINTP (ACPI_ERROR,
356 ("Warning: No result object pushed! State=%p\n", WalkState));
357 return (AE_NOT_EXIST);
358 }
359
360
361 if (!State->Results.NumResults)
362 {
363 DEBUG_PRINTP (ACPI_ERROR, ("No result objects! State=%p\n", WalkState));
364 return (AE_AML_NO_RETURN_VALUE);
365 }
366
367 /* Remove Bottom element */
368
369 *Object = State->Results.ObjDesc [0];
370
371
372 /* Push entire stack down one element */
373
374 for (Index = 0; Index < State->Results.NumResults; Index++)
375 {
376 State->Results.ObjDesc [Index] = State->Results.ObjDesc [Index + 1];
377 }
378
379 State->Results.NumResults--;
380
381 /* Check for a valid result object */
382
383 if (!*Object)
384 {
385 DEBUG_PRINTP (ACPI_ERROR, ("Null operand! State=%p #Ops=%X, Index=%X\n",
386 WalkState, State->Results.NumResults, Index));
387 return (AE_AML_NO_RETURN_VALUE);
388 }
389
390 DEBUG_PRINTP (TRACE_EXEC, ("Obj=%p [%s], Results=%p State=%p\n",
391 *Object, (*Object) ? AcpiUtGetTypeName ((*Object)->Common.Type) : "NULL",
392 State, WalkState));
393
394
395 return (AE_OK);
396}
397
398
399/*******************************************************************************
400 *
401 * FUNCTION: AcpiDsResultPush
402 *
403 * PARAMETERS: Object - Where to return the popped object
404 * WalkState - Current Walk state
405 *
406 * RETURN: Status
407 *
408 * DESCRIPTION: Push an object onto the current result stack
409 *
410 ******************************************************************************/
411
412ACPI_STATUS
413AcpiDsResultPush (
414 ACPI_OPERAND_OBJECT *Object,
415 ACPI_WALK_STATE *WalkState)
416{
417 ACPI_GENERIC_STATE *State;
418
419
420 PROC_NAME ("DsResultPush");
421
422
423 State = WalkState->Results;
424 if (!State)
425 {
426 DEBUG_PRINTP (ACPI_ERROR, ("No result stack frame\n"));
427 return (AE_AML_INTERNAL);
428 }
429
430 if (State->Results.NumResults == OBJ_NUM_OPERANDS)
431 {
432 DEBUG_PRINTP (ACPI_ERROR,
433 ("Result stack overflow: Obj=%p State=%p Num=%X\n",
434 Object, WalkState, State->Results.NumResults));
435 return (AE_STACK_OVERFLOW);
436 }
437
438 if (!Object)
439 {
440 DEBUG_PRINTP (ACPI_ERROR, ("Null Object! Obj=%p State=%p Num=%X\n",
441 Object, WalkState, State->Results.NumResults));
442 return (AE_BAD_PARAMETER);
443 }
444
445
446 State->Results.ObjDesc [State->Results.NumResults] = Object;
447 State->Results.NumResults++;
448
449 DEBUG_PRINTP (TRACE_EXEC, ("Obj=%p [%s] State=%p Num=%X Cur=%X\n",
450 Object, Object ? AcpiUtGetTypeName (((ACPI_OPERAND_OBJECT *) Object)->Common.Type) : "NULL",
451 WalkState, State->Results.NumResults, WalkState->CurrentResult));
452
453 return (AE_OK);
454}
455
456
457/*******************************************************************************
458 *
459 * FUNCTION: AcpiDsResultStackPush
460 *
461 * PARAMETERS: Object - Object to push
462 * WalkState - Current Walk state
463 *
464 * RETURN: Status
465 *
466 * DESCRIPTION:
467 *
468 ******************************************************************************/
469
470ACPI_STATUS
471AcpiDsResultStackPush (
472 ACPI_WALK_STATE *WalkState)
473{
474 ACPI_GENERIC_STATE *State;
475
476
477 State = AcpiUtCreateGenericState ();
478 if (!State)
479 {
480 return (AE_NO_MEMORY);
481 }
482
483 AcpiUtPushGenericState (&WalkState->Results, State);
484
485 DEBUG_PRINT (TRACE_EXEC, ("DsResultStackPush: 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
504ACPI_STATUS
505AcpiDsResultStackPop (
506 ACPI_WALK_STATE *WalkState)
507{
508 ACPI_GENERIC_STATE *State;
509
510
511 /* Check for stack underflow */
512
513 if (WalkState->Results == NULL)
514 {
515 DEBUG_PRINT (TRACE_EXEC, ("DsResultStackPop: Underflow - State=%p\n",
516 WalkState));
517 return (AE_AML_NO_OPERAND);
518 }
519
520
521 State = AcpiUtPopGenericState (&WalkState->Results);
522
523 DEBUG_PRINT (TRACE_EXEC,
524 ("DsResultStackPop: Result=%p RemainingResults=%X State=%p\n",
525 State, State->Results.NumResults, WalkState));
526
527 AcpiUtDeleteGenericState (State);
528
529 return (AE_OK);
530}
531
532
533/*******************************************************************************
534 *
535 * FUNCTION: AcpiDsObjStackDeleteAll
536 *
537 * PARAMETERS: WalkState - Current Walk state
538 *
539 * RETURN: Status
540 *
541 * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
542 * Should be used with great care, if at all!
543 *
544 ******************************************************************************/
545
546ACPI_STATUS
547AcpiDsObjStackDeleteAll (
548 ACPI_WALK_STATE *WalkState)
549{
550 UINT32 i;
551
552
553 FUNCTION_TRACE_PTR ("DsObjStackDeleteAll", WalkState);
554
555
556 /* The stack size is configurable, but fixed */
557
558 for (i = 0; i < OBJ_NUM_OPERANDS; i++)
559 {
560 if (WalkState->Operands[i])
561 {
562 AcpiUtRemoveReference (WalkState->Operands[i]);
563 WalkState->Operands[i] = NULL;
564 }
565 }
566
567 return_ACPI_STATUS (AE_OK);
568}
569
570
571/*******************************************************************************
572 *
573 * FUNCTION: AcpiDsObjStackPush
574 *
575 * PARAMETERS: Object - Object to push
576 * WalkState - Current Walk state
577 *
578 * RETURN: Status
579 *
580 * DESCRIPTION: Push an object onto this walk's object/operand stack
581 *
582 ******************************************************************************/
583
584ACPI_STATUS
585AcpiDsObjStackPush (
586 void *Object,
587 ACPI_WALK_STATE *WalkState)
588{
589
590
591 /* Check for stack overflow */
592
593 if (WalkState->NumOperands >= OBJ_NUM_OPERANDS)
594 {
595 DEBUG_PRINT (ACPI_ERROR,
596 ("DsObjStackPush: overflow! Obj=%p State=%p #Ops=%X\n",
597 Object, WalkState, WalkState->NumOperands));
598 return (AE_STACK_OVERFLOW);
599 }
600
601 /* Put the object onto the stack */
602
603 WalkState->Operands [WalkState->NumOperands] = Object;
604 WalkState->NumOperands++;
605
606 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPush: Obj=%p [%s] State=%p #Ops=%X\n",
607 Object, AcpiUtGetTypeName (((ACPI_OPERAND_OBJECT *) Object)->Common.Type),
608 WalkState, WalkState->NumOperands));
609
610 return (AE_OK);
611}
612
613
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
628ACPI_STATUS
629AcpiDsObjStackPopObject (
630 ACPI_OPERAND_OBJECT **Object,
631 ACPI_WALK_STATE *WalkState)
632{
633
634
635 /* Check for stack underflow */
636
637 if (WalkState->NumOperands == 0)
638 {
639 DEBUG_PRINT (ACPI_ERROR,
640 ("DsObjStackPop: 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 DEBUG_PRINT (ACPI_ERROR,
655 ("DsObjStackPop: 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 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPopObject: Obj=%p [%s] State=%p #Ops=%X\n",
667 *Object, AcpiUtGetTypeName ((*Object)->Common.Type),
668 WalkState, WalkState->NumOperands));
669
670 return (AE_OK);
671}
672
673
674/*******************************************************************************
675 *
676 * FUNCTION: AcpiDsObjStackPop
677 *
678 * PARAMETERS: PopCount - Number of objects/entries to pop
679 * WalkState - Current Walk state
680 *
681 * RETURN: Status
682 *
683 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
684 * deleted by this routine.
685 *
686 ******************************************************************************/
687
688ACPI_STATUS
689AcpiDsObjStackPop (
690 UINT32 PopCount,
691 ACPI_WALK_STATE *WalkState)
692{
693 UINT32 i;
694
695
696 for (i = 0; i < PopCount; i++)
697 {
698 /* Check for stack underflow */
699
700 if (WalkState->NumOperands == 0)
701 {
702 DEBUG_PRINT (ACPI_ERROR,
703 ("DsObjStackPop: Underflow! Count=%X State=%p #Ops=%X\n",
704 PopCount, WalkState, WalkState->NumOperands));
705 return (AE_STACK_UNDERFLOW);
706 }
707
708 /* Just set the stack entry to null */
709
710 WalkState->NumOperands--;
711 WalkState->Operands [WalkState->NumOperands] = NULL;
712 }
713
714 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPop: Count=%X State=%p #Ops=%X\n",
715 PopCount, WalkState, WalkState->NumOperands));
716
717 return (AE_OK);
718}
719
720
721/*******************************************************************************
722 *
723 * FUNCTION: AcpiDsObjStackPopAndDelete
724 *
725 * PARAMETERS: PopCount - Number of objects/entries to pop
726 * WalkState - Current Walk state
727 *
728 * RETURN: Status
729 *
730 * DESCRIPTION: Pop this walk's object stack and delete each object that is
731 * popped off.
732 *
733 ******************************************************************************/
734
735ACPI_STATUS
736AcpiDsObjStackPopAndDelete (
737 UINT32 PopCount,
738 ACPI_WALK_STATE *WalkState)
739{
740 UINT32 i;
741 ACPI_OPERAND_OBJECT *ObjDesc;
742
743
744 for (i = 0; i < PopCount; i++)
745 {
746 /* Check for stack underflow */
747
748 if (WalkState->NumOperands == 0)
749 {
750 DEBUG_PRINT (ACPI_ERROR,
751 ("DsObjStackPop: Underflow! Count=%X State=%p #Ops=%X\n",
752 PopCount, WalkState, WalkState->NumOperands));
753 return (AE_STACK_UNDERFLOW);
754 }
755
756 /* Pop the stack and delete an object if present in this stack entry */
757
758 WalkState->NumOperands--;
759 ObjDesc = WalkState->Operands [WalkState->NumOperands];
760 if (ObjDesc)
761 {
762 AcpiUtRemoveReference (WalkState->Operands [WalkState->NumOperands]);
763 WalkState->Operands [WalkState->NumOperands] = NULL;
764 }
765 }
766
767 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPop: Count=%X State=%p #Ops=%X\n",
768 PopCount, WalkState, WalkState->NumOperands));
769
770 return (AE_OK);
771}
772
773
774/*******************************************************************************
775 *
776 * FUNCTION: AcpiDsObjStackGetValue
777 *
778 * PARAMETERS: Index - Stack index whose value is desired. Based
779 * on the top of the stack (index=0 == top)
780 * WalkState - Current Walk state
781 *
782 * RETURN: Status
783 *
784 * DESCRIPTION: Retrieve an object from this walk's object stack. Index must
785 * be within the range of the current stack pointer.
786 *
787 ******************************************************************************/
788
789void *
790AcpiDsObjStackGetValue (
791 UINT32 Index,
792 ACPI_WALK_STATE *WalkState)
793{
794
795 FUNCTION_TRACE_PTR ("DsObjStackGetValue", WalkState);
796
797
798 /* Can't do it if the stack is empty */
799
800 if (WalkState->NumOperands == 0)
801 {
802 return_PTR (NULL);
803 }
804
805 /* or if the index is past the top of the stack */
806
807 if (Index > (WalkState->NumOperands - (UINT32) 1))
808 {
809 return_PTR (NULL);
810 }
811
812
813 return_PTR (WalkState->Operands[(NATIVE_UINT)(WalkState->NumOperands - 1) -
814 Index]);
815}
816
817
818/*******************************************************************************
819 *
820 * FUNCTION: AcpiDsGetCurrentWalkState
821 *
822 * PARAMETERS: WalkList - Get current active state for this walk list
823 *
824 * RETURN: Pointer to the current walk state
825 *
826 * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
827 * walk state.
828 *
829 ******************************************************************************/
830
831ACPI_WALK_STATE *
832AcpiDsGetCurrentWalkState (
833 ACPI_WALK_LIST *WalkList)
834
835{
836
837 DEBUG_PRINT (TRACE_PARSE, ("DsGetCurrentWalkState, =%p\n",
838 WalkList->WalkState));
839
840 if (!WalkList)
841 {
842 return (NULL);
843 }
844
845 return (WalkList->WalkState);
846}
847
848
849/*******************************************************************************
850 *
851 * FUNCTION: AcpiDsPushWalkState
852 *
853 * PARAMETERS: WalkState - State to push
854 * WalkList - The list that owns the walk stack
855 *
856 * RETURN: None
857 *
858 * DESCRIPTION: Place the WalkState at the head of the state list.
859 *
860 ******************************************************************************/
861
862static void
863AcpiDsPushWalkState (
864 ACPI_WALK_STATE *WalkState,
865 ACPI_WALK_LIST *WalkList)
866{
867
868
869 FUNCTION_TRACE ("DsPushWalkState");
870
871
872 WalkState->Next = WalkList->WalkState;
873 WalkList->WalkState = WalkState;
874
875 return_VOID;
876}
877
878
879/*******************************************************************************
880 *
881 * FUNCTION: AcpiDsPopWalkState
882 *
883 * PARAMETERS: WalkList - The list that owns the walk stack
884 *
885 * RETURN: A WalkState object popped from the stack
886 *
887 * DESCRIPTION: Remove and return the walkstate object that is at the head of
888 * the walk stack for the given walk list. NULL indicates that
889 * the list is empty.
890 *
891 ******************************************************************************/
892
893ACPI_WALK_STATE *
894AcpiDsPopWalkState (
895 ACPI_WALK_LIST *WalkList)
896{
897 ACPI_WALK_STATE *WalkState;
898
899
900 FUNCTION_TRACE ("DsPopWalkState");
901
902
903 WalkState = WalkList->WalkState;
904
905 if (WalkState)
906 {
907 /* Next walk state becomes the current walk state */
908
909 WalkList->WalkState = WalkState->Next;
910
911 /*
912 * Don't clear the NEXT field, this serves as an indicator
913 * that there is a parent WALK STATE
914 * WalkState->Next = NULL;
915 */
916 }
917
918 return_PTR (WalkState);
919}
920
921
922/*******************************************************************************
923 *
924 * FUNCTION: AcpiDsCreateWalkState
925 *
926 * PARAMETERS: Origin - Starting point for this walk
927 * WalkList - Owning walk list
928 *
929 * RETURN: Pointer to the new walk state.
930 *
931 * DESCRIPTION: Allocate and initialize a new walk state. The current walk state
932 * is set to this new state.
933 *
934 ******************************************************************************/
935
936ACPI_WALK_STATE *
937AcpiDsCreateWalkState (
938 ACPI_OWNER_ID OwnerId,
939 ACPI_PARSE_OBJECT *Origin,
940 ACPI_OPERAND_OBJECT *MthDesc,
941 ACPI_WALK_LIST *WalkList)
942{
943 ACPI_WALK_STATE *WalkState;
944 ACPI_STATUS Status;
945
946
947 FUNCTION_TRACE ("DsCreateWalkState");
948
949
950 AcpiUtAcquireMutex (ACPI_MTX_CACHES);
951 AcpiGbl_WalkStateCacheRequests++;
952
953 /* Check the cache first */
954
955 if (AcpiGbl_WalkStateCache)
956 {
957 /* There is an object available, use it */
958
959 WalkState = AcpiGbl_WalkStateCache;
960 AcpiGbl_WalkStateCache = WalkState->Next;
961
962 AcpiGbl_WalkStateCacheHits++;
963 AcpiGbl_WalkStateCacheDepth--;
964
965 DEBUG_PRINTP (TRACE_EXEC, ("State %p from cache\n", WalkState));
966
967 AcpiUtReleaseMutex (ACPI_MTX_CACHES);
968 }
969
970 else
971 {
972 /* The cache is empty, create a new object */
973
974 /* Avoid deadlock with ACPI_MEM_CALLOCATE */
975
976 AcpiUtReleaseMutex (ACPI_MTX_CACHES);
977
978 WalkState = ACPI_MEM_CALLOCATE (sizeof (ACPI_WALK_STATE));
979 if (!WalkState)
980 {
981 return_PTR (NULL);
982 }
983 }
984
985 WalkState->DataType = ACPI_DESC_TYPE_WALK;
986 WalkState->OwnerId = OwnerId;
987 WalkState->Origin = Origin;
988 WalkState->MethodDesc = MthDesc;
989 WalkState->WalkList = WalkList;
990
991 /* Init the method args/local */
992
993#ifndef _ACPI_ASL_COMPILER
994 AcpiDsMethodDataInit (WalkState);
995#endif
996
997 /* Create an initial result stack entry */
998
999 Status = AcpiDsResultStackPush (WalkState);
1000 if (ACPI_FAILURE (Status))
1001 {
1002 return_PTR (NULL);
1003 }
1004
1005
1006 /* Put the new state at the head of the walk list */
1007
1008 AcpiDsPushWalkState (WalkState, WalkList);
1009
1010 return_PTR (WalkState);
1011}
1012
1013
1014/*******************************************************************************
1015 *
1016 * FUNCTION: AcpiDsDeleteWalkState
1017 *
1018 * PARAMETERS: WalkState - State to delete
1019 *
1020 * RETURN: Status
1021 *
1022 * DESCRIPTION: Delete a walk state including all internal data structures
1023 *
1024 ******************************************************************************/
1025
1026void
1027AcpiDsDeleteWalkState (
1028 ACPI_WALK_STATE *WalkState)
1029{
1030 ACPI_GENERIC_STATE *State;
1031
1032
1033 FUNCTION_TRACE_PTR ("DsDeleteWalkState", WalkState);
1034
1035
1036 if (!WalkState)
1037 {
1038 return;
1039 }
1040
1041 if (WalkState->DataType != ACPI_DESC_TYPE_WALK)
1042 {
1043 DEBUG_PRINTP (ACPI_ERROR, ("%p is not a valid walk state\n", WalkState));
1044 return;
1045 }
1046
1047
1048 /* Always must free any linked control states */
1049
1050 while (WalkState->ControlState)
1051 {
1052 State = WalkState->ControlState;
1053 WalkState->ControlState = State->Common.Next;
1054
1055 AcpiUtDeleteGenericState (State);
1056 }
1057
1058 /* Always must free any linked parse states */
1059
1060 while (WalkState->ScopeInfo)
1061 {
1062 State = WalkState->ScopeInfo;
1063 WalkState->ScopeInfo = State->Common.Next;
1064
1065 AcpiUtDeleteGenericState (State);
1066 }
1067
1068 /* Always must free any stacked result states */
1069
1070 while (WalkState->Results)
1071 {
1072 State = WalkState->Results;
1073 WalkState->Results = State->Common.Next;
1074
1075 AcpiUtDeleteGenericState (State);
1076 }
1077
1078
1079 /* If walk cache is full, just free this wallkstate object */
1080
1081 if (AcpiGbl_WalkStateCacheDepth >= MAX_WALK_CACHE_DEPTH)
1082 {
1083 ACPI_MEM_FREE (WalkState);
1084 }
1085
1086 /* Otherwise put this object back into the cache */
1087
1088 else
1089 {
1090 AcpiUtAcquireMutex (ACPI_MTX_CACHES);
1091
1092 /* Clear the state */
1093
1094 MEMSET (WalkState, 0, sizeof (ACPI_WALK_STATE));
1095 WalkState->DataType = ACPI_DESC_TYPE_WALK;
1096
1097 /* Put the object at the head of the global cache list */
1098
1099 WalkState->Next = AcpiGbl_WalkStateCache;
1100 AcpiGbl_WalkStateCache = WalkState;
1101 AcpiGbl_WalkStateCacheDepth++;
1102
1103
1104 AcpiUtReleaseMutex (ACPI_MTX_CACHES);
1105 }
1106
1107 return_VOID;
1108}
1109
1110
1111/******************************************************************************
1112 *
1113 * FUNCTION: AcpiDsDeleteWalkStateCache
1114 *
1115 * PARAMETERS: None
1116 *
1117 * RETURN: Status
1118 *
1119 * DESCRIPTION: Purge the global state object cache. Used during subsystem
1120 * termination.
1121 *
1122 ******************************************************************************/
1123
1124void
1125AcpiDsDeleteWalkStateCache (
1126 void)
1127{
1128 ACPI_WALK_STATE *Next;
1129
1130
1131 FUNCTION_TRACE ("DsDeleteWalkStateCache");
1132
1133
1134 /* Traverse the global cache list */
1135
1136 while (AcpiGbl_WalkStateCache)
1137 {
1138 /* Delete one cached state object */
1139
1140 Next = AcpiGbl_WalkStateCache->Next;
1141 ACPI_MEM_FREE (AcpiGbl_WalkStateCache);
1142
1143 AcpiGbl_WalkStateCache = Next;
1144 AcpiGbl_WalkStateCacheDepth--;
1145 }
1146
1147 return_VOID;
1148}
1149
1150