[ACPICA]
[reactos.git] / reactos / drivers / bus / acpi / acpica / dispatcher / dswstate.c
1 /******************************************************************************
2 *
3 * Module Name: dswstate - Dispatcher parse tree walk management routines
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116 #include "acpi.h"
117 #include "accommon.h"
118 #include "acparser.h"
119 #include "acdispat.h"
120 #include "acnamesp.h"
121
122 #define _COMPONENT ACPI_DISPATCHER
123 ACPI_MODULE_NAME ("dswstate")
124
125 /* Local prototypes */
126
127 static ACPI_STATUS
128 AcpiDsResultStackPush (
129 ACPI_WALK_STATE *WalkState);
130
131 static ACPI_STATUS
132 AcpiDsResultStackPop (
133 ACPI_WALK_STATE *WalkState);
134
135
136 /*******************************************************************************
137 *
138 * FUNCTION: AcpiDsResultPop
139 *
140 * PARAMETERS: Object - Where to return the popped object
141 * WalkState - Current Walk state
142 *
143 * RETURN: Status
144 *
145 * DESCRIPTION: Pop an object off the top of this walk's result stack
146 *
147 ******************************************************************************/
148
149 ACPI_STATUS
150 AcpiDsResultPop (
151 ACPI_OPERAND_OBJECT **Object,
152 ACPI_WALK_STATE *WalkState)
153 {
154 UINT32 Index;
155 ACPI_GENERIC_STATE *State;
156 ACPI_STATUS Status;
157
158
159 ACPI_FUNCTION_NAME (DsResultPop);
160
161
162 State = WalkState->Results;
163
164 /* Incorrect state of result stack */
165
166 if (State && !WalkState->ResultCount)
167 {
168 ACPI_ERROR ((AE_INFO, "No results on result stack"));
169 return (AE_AML_INTERNAL);
170 }
171
172 if (!State && WalkState->ResultCount)
173 {
174 ACPI_ERROR ((AE_INFO, "No result state for result stack"));
175 return (AE_AML_INTERNAL);
176 }
177
178 /* Empty result stack */
179
180 if (!State)
181 {
182 ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState));
183 return (AE_AML_NO_RETURN_VALUE);
184 }
185
186 /* Return object of the top element and clean that top element result stack */
187
188 WalkState->ResultCount--;
189 Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
190
191 *Object = State->Results.ObjDesc [Index];
192 if (!*Object)
193 {
194 ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p",
195 WalkState));
196 return (AE_AML_NO_RETURN_VALUE);
197 }
198
199 State->Results.ObjDesc [Index] = NULL;
200 if (Index == 0)
201 {
202 Status = AcpiDsResultStackPop (WalkState);
203 if (ACPI_FAILURE (Status))
204 {
205 return (Status);
206 }
207 }
208
209 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
210 "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object,
211 AcpiUtGetObjectTypeName (*Object),
212 Index, WalkState, WalkState->ResultCount));
213
214 return (AE_OK);
215 }
216
217
218 /*******************************************************************************
219 *
220 * FUNCTION: AcpiDsResultPush
221 *
222 * PARAMETERS: Object - Where to return the popped object
223 * WalkState - Current Walk state
224 *
225 * RETURN: Status
226 *
227 * DESCRIPTION: Push an object onto the current result stack
228 *
229 ******************************************************************************/
230
231 ACPI_STATUS
232 AcpiDsResultPush (
233 ACPI_OPERAND_OBJECT *Object,
234 ACPI_WALK_STATE *WalkState)
235 {
236 ACPI_GENERIC_STATE *State;
237 ACPI_STATUS Status;
238 UINT32 Index;
239
240
241 ACPI_FUNCTION_NAME (DsResultPush);
242
243
244 if (WalkState->ResultCount > WalkState->ResultSize)
245 {
246 ACPI_ERROR ((AE_INFO, "Result stack is full"));
247 return (AE_AML_INTERNAL);
248 }
249 else if (WalkState->ResultCount == WalkState->ResultSize)
250 {
251 /* Extend the result stack */
252
253 Status = AcpiDsResultStackPush (WalkState);
254 if (ACPI_FAILURE (Status))
255 {
256 ACPI_ERROR ((AE_INFO, "Failed to extend the result stack"));
257 return (Status);
258 }
259 }
260
261 if (!(WalkState->ResultCount < WalkState->ResultSize))
262 {
263 ACPI_ERROR ((AE_INFO, "No free elements in result stack"));
264 return (AE_AML_INTERNAL);
265 }
266
267 State = WalkState->Results;
268 if (!State)
269 {
270 ACPI_ERROR ((AE_INFO, "No result stack frame during push"));
271 return (AE_AML_INTERNAL);
272 }
273
274 if (!Object)
275 {
276 ACPI_ERROR ((AE_INFO,
277 "Null Object! Obj=%p State=%p Num=%u",
278 Object, WalkState, WalkState->ResultCount));
279 return (AE_BAD_PARAMETER);
280 }
281
282 /* Assign the address of object to the top free element of result stack */
283
284 Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
285 State->Results.ObjDesc [Index] = Object;
286 WalkState->ResultCount++;
287
288 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
289 Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
290 WalkState, WalkState->ResultCount, WalkState->CurrentResult));
291
292 return (AE_OK);
293 }
294
295
296 /*******************************************************************************
297 *
298 * FUNCTION: AcpiDsResultStackPush
299 *
300 * PARAMETERS: WalkState - Current Walk state
301 *
302 * RETURN: Status
303 *
304 * DESCRIPTION: Push an object onto the WalkState result stack
305 *
306 ******************************************************************************/
307
308 static ACPI_STATUS
309 AcpiDsResultStackPush (
310 ACPI_WALK_STATE *WalkState)
311 {
312 ACPI_GENERIC_STATE *State;
313
314
315 ACPI_FUNCTION_NAME (DsResultStackPush);
316
317
318 /* Check for stack overflow */
319
320 if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
321 ACPI_RESULTS_OBJ_NUM_MAX)
322 {
323 ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
324 WalkState, WalkState->ResultSize));
325 return (AE_STACK_OVERFLOW);
326 }
327
328 State = AcpiUtCreateGenericState ();
329 if (!State)
330 {
331 return (AE_NO_MEMORY);
332 }
333
334 State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT;
335 AcpiUtPushGenericState (&WalkState->Results, State);
336
337 /* Increase the length of the result stack by the length of frame */
338
339 WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM;
340
341 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
342 State, WalkState));
343
344 return (AE_OK);
345 }
346
347
348 /*******************************************************************************
349 *
350 * FUNCTION: AcpiDsResultStackPop
351 *
352 * PARAMETERS: WalkState - Current Walk state
353 *
354 * RETURN: Status
355 *
356 * DESCRIPTION: Pop an object off of the WalkState result stack
357 *
358 ******************************************************************************/
359
360 static ACPI_STATUS
361 AcpiDsResultStackPop (
362 ACPI_WALK_STATE *WalkState)
363 {
364 ACPI_GENERIC_STATE *State;
365
366
367 ACPI_FUNCTION_NAME (DsResultStackPop);
368
369
370 /* Check for stack underflow */
371
372 if (WalkState->Results == NULL)
373 {
374 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Result stack underflow - State=%p\n",
375 WalkState));
376 return (AE_AML_NO_OPERAND);
377 }
378
379 if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM)
380 {
381 ACPI_ERROR ((AE_INFO, "Insufficient result stack size"));
382 return (AE_AML_INTERNAL);
383 }
384
385 State = AcpiUtPopGenericState (&WalkState->Results);
386 AcpiUtDeleteGenericState (State);
387
388 /* Decrease the length of result stack by the length of frame */
389
390 WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM;
391
392 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
393 "Result=%p RemainingResults=%X State=%p\n",
394 State, WalkState->ResultCount, WalkState));
395
396 return (AE_OK);
397 }
398
399
400 /*******************************************************************************
401 *
402 * FUNCTION: AcpiDsObjStackPush
403 *
404 * PARAMETERS: Object - Object to push
405 * WalkState - Current Walk state
406 *
407 * RETURN: Status
408 *
409 * DESCRIPTION: Push an object onto this walk's object/operand stack
410 *
411 ******************************************************************************/
412
413 ACPI_STATUS
414 AcpiDsObjStackPush (
415 void *Object,
416 ACPI_WALK_STATE *WalkState)
417 {
418 ACPI_FUNCTION_NAME (DsObjStackPush);
419
420
421 /* Check for stack overflow */
422
423 if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
424 {
425 ACPI_ERROR ((AE_INFO,
426 "Object stack overflow! Obj=%p State=%p #Ops=%u",
427 Object, WalkState, WalkState->NumOperands));
428 return (AE_STACK_OVERFLOW);
429 }
430
431 /* Put the object onto the stack */
432
433 WalkState->Operands [WalkState->OperandIndex] = Object;
434 WalkState->NumOperands++;
435
436 /* For the usual order of filling the operand stack */
437
438 WalkState->OperandIndex++;
439
440 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
441 Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
442 WalkState, WalkState->NumOperands));
443
444 return (AE_OK);
445 }
446
447
448 /*******************************************************************************
449 *
450 * FUNCTION: AcpiDsObjStackPop
451 *
452 * PARAMETERS: PopCount - Number of objects/entries to pop
453 * WalkState - Current Walk state
454 *
455 * RETURN: Status
456 *
457 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
458 * deleted by this routine.
459 *
460 ******************************************************************************/
461
462 ACPI_STATUS
463 AcpiDsObjStackPop (
464 UINT32 PopCount,
465 ACPI_WALK_STATE *WalkState)
466 {
467 UINT32 i;
468
469
470 ACPI_FUNCTION_NAME (DsObjStackPop);
471
472
473 for (i = 0; i < PopCount; i++)
474 {
475 /* Check for stack underflow */
476
477 if (WalkState->NumOperands == 0)
478 {
479 ACPI_ERROR ((AE_INFO,
480 "Object stack underflow! Count=%X State=%p #Ops=%u",
481 PopCount, WalkState, WalkState->NumOperands));
482 return (AE_STACK_UNDERFLOW);
483 }
484
485 /* Just set the stack entry to null */
486
487 WalkState->NumOperands--;
488 WalkState->Operands [WalkState->NumOperands] = NULL;
489 }
490
491 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
492 PopCount, WalkState, WalkState->NumOperands));
493
494 return (AE_OK);
495 }
496
497
498 /*******************************************************************************
499 *
500 * FUNCTION: AcpiDsObjStackPopAndDelete
501 *
502 * PARAMETERS: PopCount - Number of objects/entries to pop
503 * WalkState - Current Walk state
504 *
505 * RETURN: Status
506 *
507 * DESCRIPTION: Pop this walk's object stack and delete each object that is
508 * popped off.
509 *
510 ******************************************************************************/
511
512 void
513 AcpiDsObjStackPopAndDelete (
514 UINT32 PopCount,
515 ACPI_WALK_STATE *WalkState)
516 {
517 INT32 i;
518 ACPI_OPERAND_OBJECT *ObjDesc;
519
520
521 ACPI_FUNCTION_NAME (DsObjStackPopAndDelete);
522
523
524 if (PopCount == 0)
525 {
526 return;
527 }
528
529 for (i = (INT32) PopCount - 1; i >= 0; i--)
530 {
531 if (WalkState->NumOperands == 0)
532 {
533 return;
534 }
535
536 /* Pop the stack and delete an object if present in this stack entry */
537
538 WalkState->NumOperands--;
539 ObjDesc = WalkState->Operands [i];
540 if (ObjDesc)
541 {
542 AcpiUtRemoveReference (WalkState->Operands [i]);
543 WalkState->Operands [i] = NULL;
544 }
545 }
546
547 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
548 PopCount, WalkState, WalkState->NumOperands));
549 }
550
551
552 /*******************************************************************************
553 *
554 * FUNCTION: AcpiDsGetCurrentWalkState
555 *
556 * PARAMETERS: Thread - Get current active state for this Thread
557 *
558 * RETURN: Pointer to the current walk state
559 *
560 * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
561 * walk state.)
562 *
563 ******************************************************************************/
564
565 ACPI_WALK_STATE *
566 AcpiDsGetCurrentWalkState (
567 ACPI_THREAD_STATE *Thread)
568 {
569 ACPI_FUNCTION_NAME (DsGetCurrentWalkState);
570
571
572 if (!Thread)
573 {
574 return (NULL);
575 }
576
577 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
578 Thread->WalkStateList));
579
580 return (Thread->WalkStateList);
581 }
582
583
584 /*******************************************************************************
585 *
586 * FUNCTION: AcpiDsPushWalkState
587 *
588 * PARAMETERS: WalkState - State to push
589 * Thread - Thread state object
590 *
591 * RETURN: None
592 *
593 * DESCRIPTION: Place the Thread state at the head of the state list
594 *
595 ******************************************************************************/
596
597 void
598 AcpiDsPushWalkState (
599 ACPI_WALK_STATE *WalkState,
600 ACPI_THREAD_STATE *Thread)
601 {
602 ACPI_FUNCTION_TRACE (DsPushWalkState);
603
604
605 WalkState->Next = Thread->WalkStateList;
606 Thread->WalkStateList = WalkState;
607
608 return_VOID;
609 }
610
611
612 /*******************************************************************************
613 *
614 * FUNCTION: AcpiDsPopWalkState
615 *
616 * PARAMETERS: Thread - Current thread state
617 *
618 * RETURN: A WalkState object popped from the thread's stack
619 *
620 * DESCRIPTION: Remove and return the walkstate object that is at the head of
621 * the walk stack for the given walk list. NULL indicates that
622 * the list is empty.
623 *
624 ******************************************************************************/
625
626 ACPI_WALK_STATE *
627 AcpiDsPopWalkState (
628 ACPI_THREAD_STATE *Thread)
629 {
630 ACPI_WALK_STATE *WalkState;
631
632
633 ACPI_FUNCTION_TRACE (DsPopWalkState);
634
635
636 WalkState = Thread->WalkStateList;
637
638 if (WalkState)
639 {
640 /* Next walk state becomes the current walk state */
641
642 Thread->WalkStateList = WalkState->Next;
643
644 /*
645 * Don't clear the NEXT field, this serves as an indicator
646 * that there is a parent WALK STATE
647 * Do Not: WalkState->Next = NULL;
648 */
649 }
650
651 return_PTR (WalkState);
652 }
653
654
655 /*******************************************************************************
656 *
657 * FUNCTION: AcpiDsCreateWalkState
658 *
659 * PARAMETERS: OwnerId - ID for object creation
660 * Origin - Starting point for this walk
661 * MethodDesc - Method object
662 * Thread - Current thread state
663 *
664 * RETURN: Pointer to the new walk state.
665 *
666 * DESCRIPTION: Allocate and initialize a new walk state. The current walk
667 * state is set to this new state.
668 *
669 ******************************************************************************/
670
671 ACPI_WALK_STATE *
672 AcpiDsCreateWalkState (
673 ACPI_OWNER_ID OwnerId,
674 ACPI_PARSE_OBJECT *Origin,
675 ACPI_OPERAND_OBJECT *MethodDesc,
676 ACPI_THREAD_STATE *Thread)
677 {
678 ACPI_WALK_STATE *WalkState;
679
680
681 ACPI_FUNCTION_TRACE (DsCreateWalkState);
682
683
684 WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE));
685 if (!WalkState)
686 {
687 return_PTR (NULL);
688 }
689
690 WalkState->DescriptorType = ACPI_DESC_TYPE_WALK;
691 WalkState->MethodDesc = MethodDesc;
692 WalkState->OwnerId = OwnerId;
693 WalkState->Origin = Origin;
694 WalkState->Thread = Thread;
695
696 WalkState->ParserState.StartOp = Origin;
697
698 /* Init the method args/local */
699
700 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
701 AcpiDsMethodDataInit (WalkState);
702 #endif
703
704 /* Put the new state at the head of the walk list */
705
706 if (Thread)
707 {
708 AcpiDsPushWalkState (WalkState, Thread);
709 }
710
711 return_PTR (WalkState);
712 }
713
714
715 /*******************************************************************************
716 *
717 * FUNCTION: AcpiDsInitAmlWalk
718 *
719 * PARAMETERS: WalkState - New state to be initialized
720 * Op - Current parse op
721 * MethodNode - Control method NS node, if any
722 * AmlStart - Start of AML
723 * AmlLength - Length of AML
724 * Info - Method info block (params, etc.)
725 * PassNumber - 1, 2, or 3
726 *
727 * RETURN: Status
728 *
729 * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
730 *
731 ******************************************************************************/
732
733 ACPI_STATUS
734 AcpiDsInitAmlWalk (
735 ACPI_WALK_STATE *WalkState,
736 ACPI_PARSE_OBJECT *Op,
737 ACPI_NAMESPACE_NODE *MethodNode,
738 UINT8 *AmlStart,
739 UINT32 AmlLength,
740 ACPI_EVALUATE_INFO *Info,
741 UINT8 PassNumber)
742 {
743 ACPI_STATUS Status;
744 ACPI_PARSE_STATE *ParserState = &WalkState->ParserState;
745 ACPI_PARSE_OBJECT *ExtraOp;
746
747
748 ACPI_FUNCTION_TRACE (DsInitAmlWalk);
749
750
751 WalkState->ParserState.Aml =
752 WalkState->ParserState.AmlStart = AmlStart;
753 WalkState->ParserState.AmlEnd =
754 WalkState->ParserState.PkgEnd = AmlStart + AmlLength;
755
756 /* The NextOp of the NextWalk will be the beginning of the method */
757
758 WalkState->NextOp = NULL;
759 WalkState->PassNumber = PassNumber;
760
761 if (Info)
762 {
763 WalkState->Params = Info->Parameters;
764 WalkState->CallerReturnDesc = &Info->ReturnObject;
765 }
766
767 Status = AcpiPsInitScope (&WalkState->ParserState, Op);
768 if (ACPI_FAILURE (Status))
769 {
770 return_ACPI_STATUS (Status);
771 }
772
773 if (MethodNode)
774 {
775 WalkState->ParserState.StartNode = MethodNode;
776 WalkState->WalkType = ACPI_WALK_METHOD;
777 WalkState->MethodNode = MethodNode;
778 WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode);
779
780 /* Push start scope on scope stack and make it current */
781
782 Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState);
783 if (ACPI_FAILURE (Status))
784 {
785 return_ACPI_STATUS (Status);
786 }
787
788 /* Init the method arguments */
789
790 Status = AcpiDsMethodDataInitArgs (WalkState->Params,
791 ACPI_METHOD_NUM_ARGS, WalkState);
792 if (ACPI_FAILURE (Status))
793 {
794 return_ACPI_STATUS (Status);
795 }
796 }
797 else
798 {
799 /*
800 * Setup the current scope.
801 * Find a Named Op that has a namespace node associated with it.
802 * search upwards from this Op. Current scope is the first
803 * Op with a namespace node.
804 */
805 ExtraOp = ParserState->StartOp;
806 while (ExtraOp && !ExtraOp->Common.Node)
807 {
808 ExtraOp = ExtraOp->Common.Parent;
809 }
810
811 if (!ExtraOp)
812 {
813 ParserState->StartNode = NULL;
814 }
815 else
816 {
817 ParserState->StartNode = ExtraOp->Common.Node;
818 }
819
820 if (ParserState->StartNode)
821 {
822 /* Push start scope on scope stack and make it current */
823
824 Status = AcpiDsScopeStackPush (ParserState->StartNode,
825 ParserState->StartNode->Type, WalkState);
826 if (ACPI_FAILURE (Status))
827 {
828 return_ACPI_STATUS (Status);
829 }
830 }
831 }
832
833 Status = AcpiDsInitCallbacks (WalkState, PassNumber);
834 return_ACPI_STATUS (Status);
835 }
836
837
838 /*******************************************************************************
839 *
840 * FUNCTION: AcpiDsDeleteWalkState
841 *
842 * PARAMETERS: WalkState - State to delete
843 *
844 * RETURN: Status
845 *
846 * DESCRIPTION: Delete a walk state including all internal data structures
847 *
848 ******************************************************************************/
849
850 void
851 AcpiDsDeleteWalkState (
852 ACPI_WALK_STATE *WalkState)
853 {
854 ACPI_GENERIC_STATE *State;
855
856
857 ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState);
858
859
860 if (!WalkState)
861 {
862 return_VOID;
863 }
864
865 if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK)
866 {
867 ACPI_ERROR ((AE_INFO, "%p is not a valid walk state",
868 WalkState));
869 return_VOID;
870 }
871
872 /* There should not be any open scopes */
873
874 if (WalkState->ParserState.Scope)
875 {
876 ACPI_ERROR ((AE_INFO, "%p walk still has a scope list",
877 WalkState));
878 AcpiPsCleanupScope (&WalkState->ParserState);
879 }
880
881 /* Always must free any linked control states */
882
883 while (WalkState->ControlState)
884 {
885 State = WalkState->ControlState;
886 WalkState->ControlState = State->Common.Next;
887
888 AcpiUtDeleteGenericState (State);
889 }
890
891 /* Always must free any linked parse states */
892
893 while (WalkState->ScopeInfo)
894 {
895 State = WalkState->ScopeInfo;
896 WalkState->ScopeInfo = State->Common.Next;
897
898 AcpiUtDeleteGenericState (State);
899 }
900
901 /* Always must free any stacked result states */
902
903 while (WalkState->Results)
904 {
905 State = WalkState->Results;
906 WalkState->Results = State->Common.Next;
907
908 AcpiUtDeleteGenericState (State);
909 }
910
911 ACPI_FREE (WalkState);
912 return_VOID;
913 }