167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dswstate - Dispatcher parse tree walk management routines
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
4967754Smsmith
5077424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5191116Smsmith        ACPI_MODULE_NAME    ("dswstate")
5267754Smsmith
53151937Sjkim/* Local prototypes */
5467754Smsmith
55167802Sjkimstatic ACPI_STATUS
56167802SjkimAcpiDsResultStackPush (
57151937Sjkim    ACPI_WALK_STATE         *WalkState);
5867754Smsmith
59167802Sjkimstatic ACPI_STATUS
60167802SjkimAcpiDsResultStackPop (
61151937Sjkim    ACPI_WALK_STATE         *WalkState);
6267754Smsmith
6377424Smsmith
6467754Smsmith/*******************************************************************************
6567754Smsmith *
66167802Sjkim * FUNCTION:    AcpiDsResultPop
6767754Smsmith *
6867754Smsmith * PARAMETERS:  Object              - Where to return the popped object
6967754Smsmith *              WalkState           - Current Walk state
7067754Smsmith *
7167754Smsmith * RETURN:      Status
7267754Smsmith *
73167802Sjkim * DESCRIPTION: Pop an object off the top of this walk's result stack
7467754Smsmith *
7567754Smsmith ******************************************************************************/
7667754Smsmith
7767754SmsmithACPI_STATUS
78167802SjkimAcpiDsResultPop (
7967754Smsmith    ACPI_OPERAND_OBJECT     **Object,
8067754Smsmith    ACPI_WALK_STATE         *WalkState)
8167754Smsmith{
82193267Sjkim    UINT32                  Index;
8369746Smsmith    ACPI_GENERIC_STATE      *State;
84167802Sjkim    ACPI_STATUS             Status;
8567754Smsmith
8667754Smsmith
87167802Sjkim    ACPI_FUNCTION_NAME (DsResultPop);
8877424Smsmith
8977424Smsmith
9069746Smsmith    State = WalkState->Results;
91167802Sjkim
92167802Sjkim    /* Incorrect state of result stack */
93167802Sjkim
94167802Sjkim    if (State && !WalkState->ResultCount)
9569746Smsmith    {
96167802Sjkim        ACPI_ERROR ((AE_INFO, "No results on result stack"));
97167802Sjkim        return (AE_AML_INTERNAL);
9869746Smsmith    }
9967754Smsmith
100167802Sjkim    if (!State && WalkState->ResultCount)
10167754Smsmith    {
102167802Sjkim        ACPI_ERROR ((AE_INFO, "No result state for result stack"));
103167802Sjkim        return (AE_AML_INTERNAL);
10469746Smsmith    }
10569746Smsmith
106167802Sjkim    /* Empty result stack */
10769746Smsmith
108167802Sjkim    if (!State)
10969746Smsmith    {
110167802Sjkim        ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState));
11171867Smsmith        return (AE_AML_NO_RETURN_VALUE);
11267754Smsmith    }
11367754Smsmith
114167802Sjkim    /* Return object of the top element and clean that top element result stack */
11567754Smsmith
116167802Sjkim    WalkState->ResultCount--;
117193267Sjkim    Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
11867754Smsmith
11969746Smsmith    *Object = State->Results.ObjDesc [Index];
120167802Sjkim    if (!*Object)
12169746Smsmith    {
122167802Sjkim        ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p",
12369746Smsmith            WalkState));
12471867Smsmith        return (AE_AML_NO_RETURN_VALUE);
12569746Smsmith    }
12669746Smsmith
127167802Sjkim    State->Results.ObjDesc [Index] = NULL;
128167802Sjkim    if (Index == 0)
12969746Smsmith    {
130167802Sjkim        Status = AcpiDsResultStackPop (WalkState);
131167802Sjkim        if (ACPI_FAILURE (Status))
13269746Smsmith        {
133167802Sjkim            return (Status);
13469746Smsmith        }
13569746Smsmith    }
13669746Smsmith
137167802Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
138167802Sjkim        "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object,
139167802Sjkim        AcpiUtGetObjectTypeName (*Object),
140193267Sjkim        Index, WalkState, WalkState->ResultCount));
141167802Sjkim
142167802Sjkim    return (AE_OK);
14369746Smsmith}
14469746Smsmith
145123315Snjl
14669746Smsmith/*******************************************************************************
14769746Smsmith *
148167802Sjkim * FUNCTION:    AcpiDsResultPush
14969746Smsmith *
15069746Smsmith * PARAMETERS:  Object              - Where to return the popped object
15169746Smsmith *              WalkState           - Current Walk state
15269746Smsmith *
15369746Smsmith * RETURN:      Status
15469746Smsmith *
155167802Sjkim * DESCRIPTION: Push an object onto the current result stack
15669746Smsmith *
15769746Smsmith ******************************************************************************/
15869746Smsmith
15969746SmsmithACPI_STATUS
160167802SjkimAcpiDsResultPush (
161167802Sjkim    ACPI_OPERAND_OBJECT     *Object,
16269746Smsmith    ACPI_WALK_STATE         *WalkState)
16369746Smsmith{
164167802Sjkim    ACPI_GENERIC_STATE      *State;
165167802Sjkim    ACPI_STATUS             Status;
166193267Sjkim    UINT32                  Index;
16769746Smsmith
16869746Smsmith
169167802Sjkim    ACPI_FUNCTION_NAME (DsResultPush);
17077424Smsmith
17177424Smsmith
172167802Sjkim    if (WalkState->ResultCount > WalkState->ResultSize)
17369746Smsmith    {
174167802Sjkim        ACPI_ERROR ((AE_INFO, "Result stack is full"));
175167802Sjkim        return (AE_AML_INTERNAL);
17669746Smsmith    }
177167802Sjkim    else if (WalkState->ResultCount == WalkState->ResultSize)
17869746Smsmith    {
179167802Sjkim        /* Extend the result stack */
18069746Smsmith
181167802Sjkim        Status = AcpiDsResultStackPush (WalkState);
182167802Sjkim        if (ACPI_FAILURE (Status))
183167802Sjkim        {
184167802Sjkim            ACPI_ERROR ((AE_INFO, "Failed to extend the result stack"));
185167802Sjkim            return (Status);
186167802Sjkim        }
18769746Smsmith    }
18869746Smsmith
189167802Sjkim    if (!(WalkState->ResultCount < WalkState->ResultSize))
19067754Smsmith    {
191167802Sjkim        ACPI_ERROR ((AE_INFO, "No free elements in result stack"));
192167802Sjkim        return (AE_AML_INTERNAL);
19367754Smsmith    }
19467754Smsmith
19569746Smsmith    State = WalkState->Results;
19669746Smsmith    if (!State)
19769746Smsmith    {
198167802Sjkim        ACPI_ERROR ((AE_INFO, "No result stack frame during push"));
19971867Smsmith        return (AE_AML_INTERNAL);
20069746Smsmith    }
20169746Smsmith
20269746Smsmith    if (!Object)
20369746Smsmith    {
204167802Sjkim        ACPI_ERROR ((AE_INFO,
205204773Sjkim            "Null Object! Obj=%p State=%p Num=%u",
206167802Sjkim            Object, WalkState, WalkState->ResultCount));
20769746Smsmith        return (AE_BAD_PARAMETER);
20869746Smsmith    }
20969746Smsmith
210167802Sjkim    /* Assign the address of object to the top free element of result stack */
21169746Smsmith
212193267Sjkim    Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
213167802Sjkim    State->Results.ObjDesc [Index] = Object;
214167802Sjkim    WalkState->ResultCount++;
215167802Sjkim
21682367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
217167802Sjkim        Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
218167802Sjkim        WalkState, WalkState->ResultCount, WalkState->CurrentResult));
21967754Smsmith
22067754Smsmith    return (AE_OK);
22167754Smsmith}
22267754Smsmith
22367754Smsmith
22467754Smsmith/*******************************************************************************
22567754Smsmith *
22669746Smsmith * FUNCTION:    AcpiDsResultStackPush
22769746Smsmith *
228123315Snjl * PARAMETERS:  WalkState           - Current Walk state
22969746Smsmith *
23069746Smsmith * RETURN:      Status
23169746Smsmith *
232167802Sjkim * DESCRIPTION: Push an object onto the WalkState result stack
23369746Smsmith *
23469746Smsmith ******************************************************************************/
23569746Smsmith
236167802Sjkimstatic ACPI_STATUS
23769746SmsmithAcpiDsResultStackPush (
23869746Smsmith    ACPI_WALK_STATE         *WalkState)
23969746Smsmith{
24069746Smsmith    ACPI_GENERIC_STATE      *State;
24169746Smsmith
24270243Smsmith
243167802Sjkim    ACPI_FUNCTION_NAME (DsResultStackPush);
24482367Smsmith
245167802Sjkim
246167802Sjkim    /* Check for stack overflow */
247167802Sjkim
248193267Sjkim    if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
249167802Sjkim        ACPI_RESULTS_OBJ_NUM_MAX)
250167802Sjkim    {
251204773Sjkim        ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
252167802Sjkim            WalkState, WalkState->ResultSize));
253167802Sjkim        return (AE_STACK_OVERFLOW);
254167802Sjkim    }
255167802Sjkim
25677424Smsmith    State = AcpiUtCreateGenericState ();
25769746Smsmith    if (!State)
25869746Smsmith    {
25969746Smsmith        return (AE_NO_MEMORY);
26069746Smsmith    }
26169746Smsmith
262167802Sjkim    State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT;
26377424Smsmith    AcpiUtPushGenericState (&WalkState->Results, State);
26470243Smsmith
265167802Sjkim    /* Increase the length of the result stack by the length of frame */
266167802Sjkim
267167802Sjkim    WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM;
268167802Sjkim
26982367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
27069746Smsmith        State, WalkState));
27169746Smsmith
27269746Smsmith    return (AE_OK);
27369746Smsmith}
27469746Smsmith
27569746Smsmith
27669746Smsmith/*******************************************************************************
27769746Smsmith *
27869746Smsmith * FUNCTION:    AcpiDsResultStackPop
27969746Smsmith *
28069746Smsmith * PARAMETERS:  WalkState           - Current Walk state
28169746Smsmith *
28269746Smsmith * RETURN:      Status
28369746Smsmith *
284167802Sjkim * DESCRIPTION: Pop an object off of the WalkState result stack
28569746Smsmith *
28669746Smsmith ******************************************************************************/
28769746Smsmith
288167802Sjkimstatic ACPI_STATUS
28969746SmsmithAcpiDsResultStackPop (
29069746Smsmith    ACPI_WALK_STATE         *WalkState)
29169746Smsmith{
29269746Smsmith    ACPI_GENERIC_STATE      *State;
29369746Smsmith
29469746Smsmith
295167802Sjkim    ACPI_FUNCTION_NAME (DsResultStackPop);
29682367Smsmith
297167802Sjkim
29869746Smsmith    /* Check for stack underflow */
29969746Smsmith
30069746Smsmith    if (WalkState->Results == NULL)
30169746Smsmith    {
302298714Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
303298714Sjkim            "Result stack underflow - State=%p\n", WalkState));
30469746Smsmith        return (AE_AML_NO_OPERAND);
30569746Smsmith    }
30669746Smsmith
307167802Sjkim    if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM)
308167802Sjkim    {
309167802Sjkim        ACPI_ERROR ((AE_INFO, "Insufficient result stack size"));
310167802Sjkim        return (AE_AML_INTERNAL);
311167802Sjkim    }
312167802Sjkim
31377424Smsmith    State = AcpiUtPopGenericState (&WalkState->Results);
314167802Sjkim    AcpiUtDeleteGenericState (State);
31569746Smsmith
316167802Sjkim    /* Decrease the length of result stack by the length of frame */
317167802Sjkim
318167802Sjkim    WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM;
319167802Sjkim
32082367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
32182367Smsmith        "Result=%p RemainingResults=%X State=%p\n",
322167802Sjkim        State, WalkState->ResultCount, WalkState));
32369746Smsmith
32469746Smsmith    return (AE_OK);
32569746Smsmith}
32669746Smsmith
32769746Smsmith
32869746Smsmith/*******************************************************************************
32969746Smsmith *
33067754Smsmith * FUNCTION:    AcpiDsObjStackPush
33167754Smsmith *
33267754Smsmith * PARAMETERS:  Object              - Object to push
33367754Smsmith *              WalkState           - Current Walk state
33467754Smsmith *
33567754Smsmith * RETURN:      Status
33667754Smsmith *
33767754Smsmith * DESCRIPTION: Push an object onto this walk's object/operand stack
33867754Smsmith *
33967754Smsmith ******************************************************************************/
34067754Smsmith
34167754SmsmithACPI_STATUS
34267754SmsmithAcpiDsObjStackPush (
34367754Smsmith    void                    *Object,
34467754Smsmith    ACPI_WALK_STATE         *WalkState)
34567754Smsmith{
346167802Sjkim    ACPI_FUNCTION_NAME (DsObjStackPush);
34767754Smsmith
34867754Smsmith
34967754Smsmith    /* Check for stack overflow */
35067754Smsmith
351114237Snjl    if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
35267754Smsmith    {
353167802Sjkim        ACPI_ERROR ((AE_INFO,
354204773Sjkim            "Object stack overflow! Obj=%p State=%p #Ops=%u",
35567754Smsmith            Object, WalkState, WalkState->NumOperands));
35667754Smsmith        return (AE_STACK_OVERFLOW);
35767754Smsmith    }
35867754Smsmith
35967754Smsmith    /* Put the object onto the stack */
36067754Smsmith
361167802Sjkim    WalkState->Operands [WalkState->OperandIndex] = Object;
36267754Smsmith    WalkState->NumOperands++;
36367754Smsmith
364167802Sjkim    /* For the usual order of filling the operand stack */
365167802Sjkim
366167802Sjkim    WalkState->OperandIndex++;
367167802Sjkim
36882367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
369167802Sjkim        Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
370167802Sjkim        WalkState, WalkState->NumOperands));
37167754Smsmith
37267754Smsmith    return (AE_OK);
37367754Smsmith}
37467754Smsmith
37567754Smsmith
37667754Smsmith/*******************************************************************************
37767754Smsmith *
37867754Smsmith * FUNCTION:    AcpiDsObjStackPop
37967754Smsmith *
38067754Smsmith * PARAMETERS:  PopCount            - Number of objects/entries to pop
38167754Smsmith *              WalkState           - Current Walk state
38267754Smsmith *
38367754Smsmith * RETURN:      Status
38467754Smsmith *
385241973Sjkim * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
38667754Smsmith *              deleted by this routine.
38767754Smsmith *
38867754Smsmith ******************************************************************************/
38967754Smsmith
39067754SmsmithACPI_STATUS
39167754SmsmithAcpiDsObjStackPop (
39267754Smsmith    UINT32                  PopCount,
39367754Smsmith    ACPI_WALK_STATE         *WalkState)
39467754Smsmith{
39567754Smsmith    UINT32                  i;
39667754Smsmith
39767754Smsmith
398167802Sjkim    ACPI_FUNCTION_NAME (DsObjStackPop);
39982367Smsmith
400167802Sjkim
40167754Smsmith    for (i = 0; i < PopCount; i++)
40267754Smsmith    {
40367754Smsmith        /* Check for stack underflow */
40467754Smsmith
40567754Smsmith        if (WalkState->NumOperands == 0)
40667754Smsmith        {
407167802Sjkim            ACPI_ERROR ((AE_INFO,
408204773Sjkim                "Object stack underflow! Count=%X State=%p #Ops=%u",
40967754Smsmith                PopCount, WalkState, WalkState->NumOperands));
41067754Smsmith            return (AE_STACK_UNDERFLOW);
41167754Smsmith        }
41267754Smsmith
41367754Smsmith        /* Just set the stack entry to null */
41467754Smsmith
41567754Smsmith        WalkState->NumOperands--;
41667754Smsmith        WalkState->Operands [WalkState->NumOperands] = NULL;
41767754Smsmith    }
41867754Smsmith
419204773Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
420167802Sjkim        PopCount, WalkState, WalkState->NumOperands));
42167754Smsmith
42267754Smsmith    return (AE_OK);
42367754Smsmith}
42467754Smsmith
42567754Smsmith
42667754Smsmith/*******************************************************************************
42767754Smsmith *
42867754Smsmith * FUNCTION:    AcpiDsObjStackPopAndDelete
42967754Smsmith *
43067754Smsmith * PARAMETERS:  PopCount            - Number of objects/entries to pop
43167754Smsmith *              WalkState           - Current Walk state
43267754Smsmith *
43367754Smsmith * RETURN:      Status
43467754Smsmith *
43567754Smsmith * DESCRIPTION: Pop this walk's object stack and delete each object that is
43667754Smsmith *              popped off.
43767754Smsmith *
43867754Smsmith ******************************************************************************/
43967754Smsmith
440167802Sjkimvoid
44167754SmsmithAcpiDsObjStackPopAndDelete (
44267754Smsmith    UINT32                  PopCount,
44367754Smsmith    ACPI_WALK_STATE         *WalkState)
44467754Smsmith{
445193267Sjkim    INT32                   i;
44667754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
44767754Smsmith
448123315Snjl
449167802Sjkim    ACPI_FUNCTION_NAME (DsObjStackPopAndDelete);
45067754Smsmith
45182367Smsmith
452167802Sjkim    if (PopCount == 0)
45367754Smsmith    {
454167802Sjkim        return;
455167802Sjkim    }
45667754Smsmith
457193267Sjkim    for (i = (INT32) PopCount - 1; i >= 0; i--)
458167802Sjkim    {
45967754Smsmith        if (WalkState->NumOperands == 0)
46067754Smsmith        {
461167802Sjkim            return;
46267754Smsmith        }
46367754Smsmith
46467754Smsmith        /* Pop the stack and delete an object if present in this stack entry */
46567754Smsmith
46667754Smsmith        WalkState->NumOperands--;
467167802Sjkim        ObjDesc = WalkState->Operands [i];
46867754Smsmith        if (ObjDesc)
46967754Smsmith        {
470167802Sjkim            AcpiUtRemoveReference (WalkState->Operands [i]);
471167802Sjkim            WalkState->Operands [i] = NULL;
47267754Smsmith        }
47367754Smsmith    }
47467754Smsmith
47582367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
476167802Sjkim        PopCount, WalkState, WalkState->NumOperands));
47767754Smsmith}
47867754Smsmith
47967754Smsmith
48067754Smsmith/*******************************************************************************
48167754Smsmith *
48267754Smsmith * FUNCTION:    AcpiDsGetCurrentWalkState
48367754Smsmith *
48487031Smsmith * PARAMETERS:  Thread          - Get current active state for this Thread
48567754Smsmith *
48667754Smsmith * RETURN:      Pointer to the current walk state
48767754Smsmith *
48867754Smsmith * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
48987031Smsmith *              walk state.)
49067754Smsmith *
49167754Smsmith ******************************************************************************/
49267754Smsmith
49367754SmsmithACPI_WALK_STATE *
49467754SmsmithAcpiDsGetCurrentWalkState (
49587031Smsmith    ACPI_THREAD_STATE       *Thread)
49667754Smsmith{
497167802Sjkim    ACPI_FUNCTION_NAME (DsGetCurrentWalkState);
49867754Smsmith
49982367Smsmith
50087031Smsmith    if (!Thread)
50167754Smsmith    {
50267754Smsmith        return (NULL);
50367754Smsmith    }
50467754Smsmith
505114237Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
50687031Smsmith        Thread->WalkStateList));
50787031Smsmith
50887031Smsmith    return (Thread->WalkStateList);
50967754Smsmith}
51067754Smsmith
51167754Smsmith
51267754Smsmith/*******************************************************************************
51367754Smsmith *
51467754Smsmith * FUNCTION:    AcpiDsPushWalkState
51567754Smsmith *
51667754Smsmith * PARAMETERS:  WalkState       - State to push
517151937Sjkim *              Thread          - Thread state object
51867754Smsmith *
51967754Smsmith * RETURN:      None
52067754Smsmith *
521167802Sjkim * DESCRIPTION: Place the Thread state at the head of the state list
52267754Smsmith *
52367754Smsmith ******************************************************************************/
52467754Smsmith
52584491Smsmithvoid
52667754SmsmithAcpiDsPushWalkState (
52767754Smsmith    ACPI_WALK_STATE         *WalkState,
52887031Smsmith    ACPI_THREAD_STATE       *Thread)
52967754Smsmith{
530167802Sjkim    ACPI_FUNCTION_TRACE (DsPushWalkState);
53167754Smsmith
53267754Smsmith
533167802Sjkim    WalkState->Next = Thread->WalkStateList;
53487031Smsmith    Thread->WalkStateList = WalkState;
53567754Smsmith
53667754Smsmith    return_VOID;
53767754Smsmith}
53867754Smsmith
53967754Smsmith
54067754Smsmith/*******************************************************************************
54167754Smsmith *
54267754Smsmith * FUNCTION:    AcpiDsPopWalkState
54367754Smsmith *
544151937Sjkim * PARAMETERS:  Thread      - Current thread state
54567754Smsmith *
546151937Sjkim * RETURN:      A WalkState object popped from the thread's stack
54767754Smsmith *
54867754Smsmith * DESCRIPTION: Remove and return the walkstate object that is at the head of
549241973Sjkim *              the walk stack for the given walk list. NULL indicates that
55067754Smsmith *              the list is empty.
55167754Smsmith *
55267754Smsmith ******************************************************************************/
55367754Smsmith
55467754SmsmithACPI_WALK_STATE *
55567754SmsmithAcpiDsPopWalkState (
55687031Smsmith    ACPI_THREAD_STATE       *Thread)
55767754Smsmith{
55867754Smsmith    ACPI_WALK_STATE         *WalkState;
55967754Smsmith
56067754Smsmith
561167802Sjkim    ACPI_FUNCTION_TRACE (DsPopWalkState);
56267754Smsmith
56367754Smsmith
56487031Smsmith    WalkState = Thread->WalkStateList;
56567754Smsmith
56667754Smsmith    if (WalkState)
56767754Smsmith    {
56867754Smsmith        /* Next walk state becomes the current walk state */
56967754Smsmith
57087031Smsmith        Thread->WalkStateList = WalkState->Next;
57167754Smsmith
57267754Smsmith        /*
57367754Smsmith         * Don't clear the NEXT field, this serves as an indicator
57467754Smsmith         * that there is a parent WALK STATE
575151937Sjkim         * Do Not: WalkState->Next = NULL;
57667754Smsmith         */
57767754Smsmith    }
57867754Smsmith
57967754Smsmith    return_PTR (WalkState);
58067754Smsmith}
58167754Smsmith
58267754Smsmith
58367754Smsmith/*******************************************************************************
58467754Smsmith *
58567754Smsmith * FUNCTION:    AcpiDsCreateWalkState
58667754Smsmith *
587151937Sjkim * PARAMETERS:  OwnerId         - ID for object creation
588151937Sjkim *              Origin          - Starting point for this walk
589167802Sjkim *              MethodDesc      - Method object
59087031Smsmith *              Thread          - Current thread state
59167754Smsmith *
59267754Smsmith * RETURN:      Pointer to the new walk state.
59367754Smsmith *
594241973Sjkim * DESCRIPTION: Allocate and initialize a new walk state. The current walk
59587031Smsmith *              state is set to this new state.
59667754Smsmith *
59767754Smsmith ******************************************************************************/
59867754Smsmith
59967754SmsmithACPI_WALK_STATE *
60067754SmsmithAcpiDsCreateWalkState (
60167754Smsmith    ACPI_OWNER_ID           OwnerId,
60267754Smsmith    ACPI_PARSE_OBJECT       *Origin,
603167802Sjkim    ACPI_OPERAND_OBJECT     *MethodDesc,
60487031Smsmith    ACPI_THREAD_STATE       *Thread)
60567754Smsmith{
60667754Smsmith    ACPI_WALK_STATE         *WalkState;
60767754Smsmith
60867754Smsmith
609167802Sjkim    ACPI_FUNCTION_TRACE (DsCreateWalkState);
61067754Smsmith
61167754Smsmith
612167802Sjkim    WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE));
61382367Smsmith    if (!WalkState)
61467754Smsmith    {
61582367Smsmith        return_PTR (NULL);
61671867Smsmith    }
61767754Smsmith
618167802Sjkim    WalkState->DescriptorType = ACPI_DESC_TYPE_WALK;
619167802Sjkim    WalkState->MethodDesc = MethodDesc;
620167802Sjkim    WalkState->OwnerId = OwnerId;
621167802Sjkim    WalkState->Origin = Origin;
622167802Sjkim    WalkState->Thread = Thread;
62367754Smsmith
624102550Siwasaki    WalkState->ParserState.StartOp = Origin;
625102550Siwasaki
62667754Smsmith    /* Init the method args/local */
62767754Smsmith
628100966Siwasaki#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
62967754Smsmith    AcpiDsMethodDataInit (WalkState);
63069450Smsmith#endif
63167754Smsmith
63267754Smsmith    /* Put the new state at the head of the walk list */
63367754Smsmith
63487031Smsmith    if (Thread)
63584491Smsmith    {
63687031Smsmith        AcpiDsPushWalkState (WalkState, Thread);
63784491Smsmith    }
63867754Smsmith
63967754Smsmith    return_PTR (WalkState);
64067754Smsmith}
64167754Smsmith
64267754Smsmith
64367754Smsmith/*******************************************************************************
64467754Smsmith *
64584491Smsmith * FUNCTION:    AcpiDsInitAmlWalk
64684491Smsmith *
64784491Smsmith * PARAMETERS:  WalkState       - New state to be initialized
648123315Snjl *              Op              - Current parse op
649123315Snjl *              MethodNode      - Control method NS node, if any
650123315Snjl *              AmlStart        - Start of AML
651123315Snjl *              AmlLength       - Length of AML
652151937Sjkim *              Info            - Method info block (params, etc.)
653123315Snjl *              PassNumber      - 1, 2, or 3
65484491Smsmith *
655123315Snjl * RETURN:      Status
65684491Smsmith *
65784491Smsmith * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
65884491Smsmith *
65984491Smsmith ******************************************************************************/
66084491Smsmith
66184491SmsmithACPI_STATUS
66284491SmsmithAcpiDsInitAmlWalk (
66384491Smsmith    ACPI_WALK_STATE         *WalkState,
66484491Smsmith    ACPI_PARSE_OBJECT       *Op,
66584491Smsmith    ACPI_NAMESPACE_NODE     *MethodNode,
66684491Smsmith    UINT8                   *AmlStart,
66784491Smsmith    UINT32                  AmlLength,
668167802Sjkim    ACPI_EVALUATE_INFO      *Info,
669151937Sjkim    UINT8                   PassNumber)
67084491Smsmith{
67184491Smsmith    ACPI_STATUS             Status;
67284491Smsmith    ACPI_PARSE_STATE        *ParserState = &WalkState->ParserState;
673102550Siwasaki    ACPI_PARSE_OBJECT       *ExtraOp;
67484491Smsmith
67584491Smsmith
676167802Sjkim    ACPI_FUNCTION_TRACE (DsInitAmlWalk);
67784491Smsmith
67884491Smsmith
679167802Sjkim    WalkState->ParserState.Aml =
68084491Smsmith    WalkState->ParserState.AmlStart = AmlStart;
681167802Sjkim    WalkState->ParserState.AmlEnd =
682167802Sjkim    WalkState->ParserState.PkgEnd = AmlStart + AmlLength;
68384491Smsmith
68484491Smsmith    /* The NextOp of the NextWalk will be the beginning of the method */
68584491Smsmith
686151937Sjkim    WalkState->NextOp = NULL;
687151937Sjkim    WalkState->PassNumber = PassNumber;
68884491Smsmith
689129684Snjl    if (Info)
690129684Snjl    {
691193267Sjkim        WalkState->Params = Info->Parameters;
692193267Sjkim        WalkState->CallerReturnDesc = &Info->ReturnObject;
693129684Snjl    }
694129684Snjl
69584491Smsmith    Status = AcpiPsInitScope (&WalkState->ParserState, Op);
69684491Smsmith    if (ACPI_FAILURE (Status))
69784491Smsmith    {
69884491Smsmith        return_ACPI_STATUS (Status);
69984491Smsmith    }
70084491Smsmith
70184491Smsmith    if (MethodNode)
70284491Smsmith    {
703123315Snjl        WalkState->ParserState.StartNode = MethodNode;
704167802Sjkim        WalkState->WalkType = ACPI_WALK_METHOD;
705167802Sjkim        WalkState->MethodNode = MethodNode;
706167802Sjkim        WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode);
70784491Smsmith
70884491Smsmith        /* Push start scope on scope stack and make it current  */
70984491Smsmith
710298714Sjkim        Status = AcpiDsScopeStackPush (
711298714Sjkim            MethodNode, ACPI_TYPE_METHOD, WalkState);
71284491Smsmith        if (ACPI_FAILURE (Status))
71384491Smsmith        {
71484491Smsmith            return_ACPI_STATUS (Status);
71584491Smsmith        }
71684491Smsmith
71784491Smsmith        /* Init the method arguments */
71884491Smsmith
719151937Sjkim        Status = AcpiDsMethodDataInitArgs (WalkState->Params,
720151937Sjkim                    ACPI_METHOD_NUM_ARGS, WalkState);
72199679Siwasaki        if (ACPI_FAILURE (Status))
72299679Siwasaki        {
72399679Siwasaki            return_ACPI_STATUS (Status);
72499679Siwasaki        }
72584491Smsmith    }
72684491Smsmith    else
72784491Smsmith    {
728114237Snjl        /*
729102550Siwasaki         * Setup the current scope.
730102550Siwasaki         * Find a Named Op that has a namespace node associated with it.
731241973Sjkim         * search upwards from this Op. Current scope is the first
732102550Siwasaki         * Op with a namespace node.
733102550Siwasaki         */
734102550Siwasaki        ExtraOp = ParserState->StartOp;
735102550Siwasaki        while (ExtraOp && !ExtraOp->Common.Node)
736102550Siwasaki        {
737102550Siwasaki            ExtraOp = ExtraOp->Common.Parent;
738102550Siwasaki        }
739123315Snjl
740102550Siwasaki        if (!ExtraOp)
741102550Siwasaki        {
742102550Siwasaki            ParserState->StartNode = NULL;
743102550Siwasaki        }
744102550Siwasaki        else
745102550Siwasaki        {
746102550Siwasaki            ParserState->StartNode = ExtraOp->Common.Node;
747102550Siwasaki        }
748114237Snjl
74984491Smsmith        if (ParserState->StartNode)
75084491Smsmith        {
75184491Smsmith            /* Push start scope on scope stack and make it current  */
75284491Smsmith
75384491Smsmith            Status = AcpiDsScopeStackPush (ParserState->StartNode,
754298714Sjkim                ParserState->StartNode->Type, WalkState);
75584491Smsmith            if (ACPI_FAILURE (Status))
75684491Smsmith            {
75784491Smsmith                return_ACPI_STATUS (Status);
75884491Smsmith            }
75984491Smsmith        }
76084491Smsmith    }
76184491Smsmith
76299679Siwasaki    Status = AcpiDsInitCallbacks (WalkState, PassNumber);
76399679Siwasaki    return_ACPI_STATUS (Status);
76484491Smsmith}
76584491Smsmith
76684491Smsmith
76784491Smsmith/*******************************************************************************
76884491Smsmith *
76967754Smsmith * FUNCTION:    AcpiDsDeleteWalkState
77067754Smsmith *
77167754Smsmith * PARAMETERS:  WalkState       - State to delete
77267754Smsmith *
77367754Smsmith * RETURN:      Status
77467754Smsmith *
77567754Smsmith * DESCRIPTION: Delete a walk state including all internal data structures
77667754Smsmith *
77767754Smsmith ******************************************************************************/
77867754Smsmith
77967754Smsmithvoid
78067754SmsmithAcpiDsDeleteWalkState (
78167754Smsmith    ACPI_WALK_STATE         *WalkState)
78267754Smsmith{
78367754Smsmith    ACPI_GENERIC_STATE      *State;
78467754Smsmith
78567754Smsmith
786167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState);
78767754Smsmith
78867754Smsmith
78967754Smsmith    if (!WalkState)
79067754Smsmith    {
791241973Sjkim        return_VOID;
79267754Smsmith    }
79367754Smsmith
794167802Sjkim    if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK)
79567754Smsmith    {
796167802Sjkim        ACPI_ERROR ((AE_INFO, "%p is not a valid walk state",
797151937Sjkim            WalkState));
798241973Sjkim        return_VOID;
79967754Smsmith    }
80067754Smsmith
801167802Sjkim    /* There should not be any open scopes */
802167802Sjkim
80384491Smsmith    if (WalkState->ParserState.Scope)
80484491Smsmith    {
805167802Sjkim        ACPI_ERROR ((AE_INFO, "%p walk still has a scope list",
806151937Sjkim            WalkState));
807167802Sjkim        AcpiPsCleanupScope (&WalkState->ParserState);
80884491Smsmith    }
80967754Smsmith
810123315Snjl    /* Always must free any linked control states */
81184491Smsmith
81267754Smsmith    while (WalkState->ControlState)
81367754Smsmith    {
81467754Smsmith        State = WalkState->ControlState;
81567754Smsmith        WalkState->ControlState = State->Common.Next;
81667754Smsmith
81777424Smsmith        AcpiUtDeleteGenericState (State);
81867754Smsmith    }
81967754Smsmith
82067754Smsmith    /* Always must free any linked parse states */
82167754Smsmith
82267754Smsmith    while (WalkState->ScopeInfo)
82367754Smsmith    {
82467754Smsmith        State = WalkState->ScopeInfo;
82567754Smsmith        WalkState->ScopeInfo = State->Common.Next;
82667754Smsmith
82777424Smsmith        AcpiUtDeleteGenericState (State);
82867754Smsmith    }
82967754Smsmith
83069746Smsmith    /* Always must free any stacked result states */
83169746Smsmith
83269746Smsmith    while (WalkState->Results)
83369746Smsmith    {
83469746Smsmith        State = WalkState->Results;
83569746Smsmith        WalkState->Results = State->Common.Next;
83669746Smsmith
83777424Smsmith        AcpiUtDeleteGenericState (State);
83869746Smsmith    }
83969746Smsmith
840167802Sjkim    ACPI_FREE (WalkState);
84167754Smsmith    return_VOID;
84267754Smsmith}
843