dswstate.c revision 193267
167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dswstate - Dispatcher parse tree walk management routines
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
767754Smsmith/******************************************************************************
867754Smsmith *
967754Smsmith * 1. Copyright Notice
1067754Smsmith *
11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
1270243Smsmith * All rights reserved.
1367754Smsmith *
1467754Smsmith * 2. License
1567754Smsmith *
1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1767754Smsmith * rights.  You may have additional license terms from the party that provided
1867754Smsmith * you this software, covering your right to use that party's intellectual
1967754Smsmith * property rights.
2067754Smsmith *
2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2667754Smsmith * Code in any form, with the right to sublicense such rights; and
2767754Smsmith *
2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2967754Smsmith * license (with the right to sublicense), under only those claims of Intel
3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3367754Smsmith * license, and in no event shall the patent license extend to any additions
3467754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3567754Smsmith * is granted directly or by implication, estoppel or otherwise;
3667754Smsmith *
3767754Smsmith * The above copyright and patent license is granted only if the following
3867754Smsmith * conditions are met:
3967754Smsmith *
4067754Smsmith * 3. Conditions
4167754Smsmith *
4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4367754Smsmith * Redistribution of source code of any substantial portion of the Covered
4467754Smsmith * Code or modification with rights to further distribute source must include
4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4667754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered
4967754Smsmith * Code and the date of any change.  Licensee must include in that file the
5067754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5167754Smsmith * must include a prominent statement that the modification is derived,
5267754Smsmith * directly or indirectly, from Original Intel Code.
5367754Smsmith *
5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5567754Smsmith * Redistribution of source code of any substantial portion of the Covered
5667754Smsmith * Code or modification without rights to further distribute source must
5767754Smsmith * include the following Disclaimer and Export Compliance provision in the
5867754Smsmith * documentation and/or other materials provided with distribution.  In
5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6167754Smsmith * license from Licensee to its licensee is limited to the intellectual
6267754Smsmith * property embodied in the software Licensee provides to its licensee, and
6367754Smsmith * not to intellectual property embodied in modifications its licensee may
6467754Smsmith * make.
6567754Smsmith *
6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
6967754Smsmith * provision in the documentation and/or other materials provided with the
7067754Smsmith * distribution.
7167754Smsmith *
7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7367754Smsmith * Intel Code.
7467754Smsmith *
7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7767754Smsmith * other dealings in products derived from or relating to the Covered Code
7867754Smsmith * without prior written authorization from Intel.
7967754Smsmith *
8067754Smsmith * 4. Disclaimer and Export Compliance
8167754Smsmith *
8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8367754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8867754Smsmith * PARTICULAR PURPOSE.
8967754Smsmith *
9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9767754Smsmith * LIMITED REMEDY.
9867754Smsmith *
9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10067754Smsmith * software or system incorporating such software without first obtaining any
10167754Smsmith * required license or other approval from the U. S. Department of Commerce or
10267754Smsmith * any other agency or department of the United States Government.  In the
10367754Smsmith * event Licensee exports any such software from the United States or
10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10567754Smsmith * ensure that the distribution and export/re-export of the software is in
10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
10967754Smsmith * software, or service, directly or indirectly, to any country for which the
11067754Smsmith * United States government or any agency thereof requires an export license,
11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11267754Smsmith * such license, approval or letter.
11367754Smsmith *
11467754Smsmith *****************************************************************************/
11567754Smsmith
11667754Smsmith
11767754Smsmith#define __DSWSTATE_C__
11867754Smsmith
119193251Sjkim#include "acpi.h"
120193267Sjkim#include "accommon.h"
121193251Sjkim#include "acparser.h"
122193251Sjkim#include "acdispat.h"
123193251Sjkim#include "acnamesp.h"
12467754Smsmith
12577424Smsmith#define _COMPONENT          ACPI_DISPATCHER
12691116Smsmith        ACPI_MODULE_NAME    ("dswstate")
12767754Smsmith
128151937Sjkim/* Local prototypes */
12967754Smsmith
130167802Sjkimstatic ACPI_STATUS
131167802SjkimAcpiDsResultStackPush (
132151937Sjkim    ACPI_WALK_STATE         *WalkState);
13367754Smsmith
134167802Sjkimstatic ACPI_STATUS
135167802SjkimAcpiDsResultStackPop (
136151937Sjkim    ACPI_WALK_STATE         *WalkState);
13767754Smsmith
13877424Smsmith
13967754Smsmith/*******************************************************************************
14067754Smsmith *
141167802Sjkim * FUNCTION:    AcpiDsResultPop
14267754Smsmith *
14367754Smsmith * PARAMETERS:  Object              - Where to return the popped object
14467754Smsmith *              WalkState           - Current Walk state
14567754Smsmith *
14667754Smsmith * RETURN:      Status
14767754Smsmith *
148167802Sjkim * DESCRIPTION: Pop an object off the top of this walk's result stack
14967754Smsmith *
15067754Smsmith ******************************************************************************/
15167754Smsmith
15267754SmsmithACPI_STATUS
153167802SjkimAcpiDsResultPop (
15467754Smsmith    ACPI_OPERAND_OBJECT     **Object,
15567754Smsmith    ACPI_WALK_STATE         *WalkState)
15667754Smsmith{
157193267Sjkim    UINT32                  Index;
15869746Smsmith    ACPI_GENERIC_STATE      *State;
159167802Sjkim    ACPI_STATUS             Status;
16067754Smsmith
16167754Smsmith
162167802Sjkim    ACPI_FUNCTION_NAME (DsResultPop);
16377424Smsmith
16477424Smsmith
16569746Smsmith    State = WalkState->Results;
166167802Sjkim
167167802Sjkim    /* Incorrect state of result stack */
168167802Sjkim
169167802Sjkim    if (State && !WalkState->ResultCount)
17069746Smsmith    {
171167802Sjkim        ACPI_ERROR ((AE_INFO, "No results on result stack"));
172167802Sjkim        return (AE_AML_INTERNAL);
17369746Smsmith    }
17467754Smsmith
175167802Sjkim    if (!State && WalkState->ResultCount)
17667754Smsmith    {
177167802Sjkim        ACPI_ERROR ((AE_INFO, "No result state for result stack"));
178167802Sjkim        return (AE_AML_INTERNAL);
17969746Smsmith    }
18069746Smsmith
181167802Sjkim    /* Empty result stack */
18269746Smsmith
183167802Sjkim    if (!State)
18469746Smsmith    {
185167802Sjkim        ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState));
18671867Smsmith        return (AE_AML_NO_RETURN_VALUE);
18767754Smsmith    }
18867754Smsmith
189167802Sjkim    /* Return object of the top element and clean that top element result stack */
19067754Smsmith
191167802Sjkim    WalkState->ResultCount--;
192193267Sjkim    Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
19367754Smsmith
19469746Smsmith    *Object = State->Results.ObjDesc [Index];
195167802Sjkim    if (!*Object)
19669746Smsmith    {
197167802Sjkim        ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p",
19869746Smsmith            WalkState));
19971867Smsmith        return (AE_AML_NO_RETURN_VALUE);
20069746Smsmith    }
20169746Smsmith
202167802Sjkim    State->Results.ObjDesc [Index] = NULL;
203167802Sjkim    if (Index == 0)
20469746Smsmith    {
205167802Sjkim        Status = AcpiDsResultStackPop (WalkState);
206167802Sjkim        if (ACPI_FAILURE (Status))
20769746Smsmith        {
208167802Sjkim            return (Status);
20969746Smsmith        }
21069746Smsmith    }
21169746Smsmith
212167802Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
213167802Sjkim        "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object,
214167802Sjkim        AcpiUtGetObjectTypeName (*Object),
215193267Sjkim        Index, WalkState, WalkState->ResultCount));
216167802Sjkim
217167802Sjkim    return (AE_OK);
21869746Smsmith}
21969746Smsmith
220123315Snjl
22169746Smsmith/*******************************************************************************
22269746Smsmith *
223167802Sjkim * FUNCTION:    AcpiDsResultPush
22469746Smsmith *
22569746Smsmith * PARAMETERS:  Object              - Where to return the popped object
22669746Smsmith *              WalkState           - Current Walk state
22769746Smsmith *
22869746Smsmith * RETURN:      Status
22969746Smsmith *
230167802Sjkim * DESCRIPTION: Push an object onto the current result stack
23169746Smsmith *
23269746Smsmith ******************************************************************************/
23369746Smsmith
23469746SmsmithACPI_STATUS
235167802SjkimAcpiDsResultPush (
236167802Sjkim    ACPI_OPERAND_OBJECT     *Object,
23769746Smsmith    ACPI_WALK_STATE         *WalkState)
23869746Smsmith{
239167802Sjkim    ACPI_GENERIC_STATE      *State;
240167802Sjkim    ACPI_STATUS             Status;
241193267Sjkim    UINT32                  Index;
24269746Smsmith
24369746Smsmith
244167802Sjkim    ACPI_FUNCTION_NAME (DsResultPush);
24577424Smsmith
24677424Smsmith
247167802Sjkim    if (WalkState->ResultCount > WalkState->ResultSize)
24869746Smsmith    {
249167802Sjkim        ACPI_ERROR ((AE_INFO, "Result stack is full"));
250167802Sjkim        return (AE_AML_INTERNAL);
25169746Smsmith    }
252167802Sjkim    else if (WalkState->ResultCount == WalkState->ResultSize)
25369746Smsmith    {
254167802Sjkim        /* Extend the result stack */
25569746Smsmith
256167802Sjkim        Status = AcpiDsResultStackPush (WalkState);
257167802Sjkim        if (ACPI_FAILURE (Status))
258167802Sjkim        {
259167802Sjkim            ACPI_ERROR ((AE_INFO, "Failed to extend the result stack"));
260167802Sjkim            return (Status);
261167802Sjkim        }
26269746Smsmith    }
26369746Smsmith
264167802Sjkim    if (!(WalkState->ResultCount < WalkState->ResultSize))
26567754Smsmith    {
266167802Sjkim        ACPI_ERROR ((AE_INFO, "No free elements in result stack"));
267167802Sjkim        return (AE_AML_INTERNAL);
26867754Smsmith    }
26967754Smsmith
27069746Smsmith    State = WalkState->Results;
27169746Smsmith    if (!State)
27269746Smsmith    {
273167802Sjkim        ACPI_ERROR ((AE_INFO, "No result stack frame during push"));
27471867Smsmith        return (AE_AML_INTERNAL);
27569746Smsmith    }
27669746Smsmith
27769746Smsmith    if (!Object)
27869746Smsmith    {
279167802Sjkim        ACPI_ERROR ((AE_INFO,
280167802Sjkim            "Null Object! Obj=%p State=%p Num=%X",
281167802Sjkim            Object, WalkState, WalkState->ResultCount));
28269746Smsmith        return (AE_BAD_PARAMETER);
28369746Smsmith    }
28469746Smsmith
285167802Sjkim    /* Assign the address of object to the top free element of result stack */
28669746Smsmith
287193267Sjkim    Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
288167802Sjkim    State->Results.ObjDesc [Index] = Object;
289167802Sjkim    WalkState->ResultCount++;
290167802Sjkim
29182367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
292167802Sjkim        Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
293167802Sjkim        WalkState, WalkState->ResultCount, WalkState->CurrentResult));
29467754Smsmith
29567754Smsmith    return (AE_OK);
29667754Smsmith}
29767754Smsmith
29867754Smsmith
29967754Smsmith/*******************************************************************************
30067754Smsmith *
30169746Smsmith * FUNCTION:    AcpiDsResultStackPush
30269746Smsmith *
303123315Snjl * PARAMETERS:  WalkState           - Current Walk state
30469746Smsmith *
30569746Smsmith * RETURN:      Status
30669746Smsmith *
307167802Sjkim * DESCRIPTION: Push an object onto the WalkState result stack
30869746Smsmith *
30969746Smsmith ******************************************************************************/
31069746Smsmith
311167802Sjkimstatic ACPI_STATUS
31269746SmsmithAcpiDsResultStackPush (
31369746Smsmith    ACPI_WALK_STATE         *WalkState)
31469746Smsmith{
31569746Smsmith    ACPI_GENERIC_STATE      *State;
31669746Smsmith
31770243Smsmith
318167802Sjkim    ACPI_FUNCTION_NAME (DsResultStackPush);
31982367Smsmith
320167802Sjkim
321167802Sjkim    /* Check for stack overflow */
322167802Sjkim
323193267Sjkim    if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
324167802Sjkim        ACPI_RESULTS_OBJ_NUM_MAX)
325167802Sjkim    {
326167802Sjkim        ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%X",
327167802Sjkim            WalkState, WalkState->ResultSize));
328167802Sjkim        return (AE_STACK_OVERFLOW);
329167802Sjkim    }
330167802Sjkim
33177424Smsmith    State = AcpiUtCreateGenericState ();
33269746Smsmith    if (!State)
33369746Smsmith    {
33469746Smsmith        return (AE_NO_MEMORY);
33569746Smsmith    }
33669746Smsmith
337167802Sjkim    State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT;
33877424Smsmith    AcpiUtPushGenericState (&WalkState->Results, State);
33970243Smsmith
340167802Sjkim    /* Increase the length of the result stack by the length of frame */
341167802Sjkim
342167802Sjkim    WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM;
343167802Sjkim
34482367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
34569746Smsmith        State, WalkState));
34669746Smsmith
34769746Smsmith    return (AE_OK);
34869746Smsmith}
34969746Smsmith
35069746Smsmith
35169746Smsmith/*******************************************************************************
35269746Smsmith *
35369746Smsmith * FUNCTION:    AcpiDsResultStackPop
35469746Smsmith *
35569746Smsmith * PARAMETERS:  WalkState           - Current Walk state
35669746Smsmith *
35769746Smsmith * RETURN:      Status
35869746Smsmith *
359167802Sjkim * DESCRIPTION: Pop an object off of the WalkState result stack
36069746Smsmith *
36169746Smsmith ******************************************************************************/
36269746Smsmith
363167802Sjkimstatic ACPI_STATUS
36469746SmsmithAcpiDsResultStackPop (
36569746Smsmith    ACPI_WALK_STATE         *WalkState)
36669746Smsmith{
36769746Smsmith    ACPI_GENERIC_STATE      *State;
36869746Smsmith
36969746Smsmith
370167802Sjkim    ACPI_FUNCTION_NAME (DsResultStackPop);
37182367Smsmith
372167802Sjkim
37369746Smsmith    /* Check for stack underflow */
37469746Smsmith
37569746Smsmith    if (WalkState->Results == NULL)
37669746Smsmith    {
377167802Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Result stack underflow - State=%p\n",
37869746Smsmith            WalkState));
37969746Smsmith        return (AE_AML_NO_OPERAND);
38069746Smsmith    }
38169746Smsmith
382167802Sjkim    if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM)
383167802Sjkim    {
384167802Sjkim        ACPI_ERROR ((AE_INFO, "Insufficient result stack size"));
385167802Sjkim        return (AE_AML_INTERNAL);
386167802Sjkim    }
387167802Sjkim
38877424Smsmith    State = AcpiUtPopGenericState (&WalkState->Results);
389167802Sjkim    AcpiUtDeleteGenericState (State);
39069746Smsmith
391167802Sjkim    /* Decrease the length of result stack by the length of frame */
392167802Sjkim
393167802Sjkim    WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM;
394167802Sjkim
39582367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
39682367Smsmith        "Result=%p RemainingResults=%X State=%p\n",
397167802Sjkim        State, WalkState->ResultCount, WalkState));
39869746Smsmith
39969746Smsmith    return (AE_OK);
40069746Smsmith}
40169746Smsmith
40269746Smsmith
40369746Smsmith/*******************************************************************************
40469746Smsmith *
40567754Smsmith * FUNCTION:    AcpiDsObjStackPush
40667754Smsmith *
40767754Smsmith * PARAMETERS:  Object              - Object to push
40867754Smsmith *              WalkState           - Current Walk state
40967754Smsmith *
41067754Smsmith * RETURN:      Status
41167754Smsmith *
41267754Smsmith * DESCRIPTION: Push an object onto this walk's object/operand stack
41367754Smsmith *
41467754Smsmith ******************************************************************************/
41567754Smsmith
41667754SmsmithACPI_STATUS
41767754SmsmithAcpiDsObjStackPush (
41867754Smsmith    void                    *Object,
41967754Smsmith    ACPI_WALK_STATE         *WalkState)
42067754Smsmith{
421167802Sjkim    ACPI_FUNCTION_NAME (DsObjStackPush);
42267754Smsmith
42367754Smsmith
42467754Smsmith    /* Check for stack overflow */
42567754Smsmith
426114237Snjl    if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
42767754Smsmith    {
428167802Sjkim        ACPI_ERROR ((AE_INFO,
429167802Sjkim            "Object stack overflow! Obj=%p State=%p #Ops=%X",
43067754Smsmith            Object, WalkState, WalkState->NumOperands));
43167754Smsmith        return (AE_STACK_OVERFLOW);
43267754Smsmith    }
43367754Smsmith
43467754Smsmith    /* Put the object onto the stack */
43567754Smsmith
436167802Sjkim    WalkState->Operands [WalkState->OperandIndex] = Object;
43767754Smsmith    WalkState->NumOperands++;
43867754Smsmith
439167802Sjkim    /* For the usual order of filling the operand stack */
440167802Sjkim
441167802Sjkim    WalkState->OperandIndex++;
442167802Sjkim
44382367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
444167802Sjkim        Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
445167802Sjkim        WalkState, WalkState->NumOperands));
44667754Smsmith
44767754Smsmith    return (AE_OK);
44867754Smsmith}
44967754Smsmith
45067754Smsmith
45167754Smsmith/*******************************************************************************
45267754Smsmith *
45367754Smsmith * FUNCTION:    AcpiDsObjStackPop
45467754Smsmith *
45567754Smsmith * PARAMETERS:  PopCount            - Number of objects/entries to pop
45667754Smsmith *              WalkState           - Current Walk state
45767754Smsmith *
45867754Smsmith * RETURN:      Status
45967754Smsmith *
46067754Smsmith * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
46167754Smsmith *              deleted by this routine.
46267754Smsmith *
46367754Smsmith ******************************************************************************/
46467754Smsmith
46567754SmsmithACPI_STATUS
46667754SmsmithAcpiDsObjStackPop (
46767754Smsmith    UINT32                  PopCount,
46867754Smsmith    ACPI_WALK_STATE         *WalkState)
46967754Smsmith{
47067754Smsmith    UINT32                  i;
47167754Smsmith
47267754Smsmith
473167802Sjkim    ACPI_FUNCTION_NAME (DsObjStackPop);
47482367Smsmith
475167802Sjkim
47667754Smsmith    for (i = 0; i < PopCount; i++)
47767754Smsmith    {
47867754Smsmith        /* Check for stack underflow */
47967754Smsmith
48067754Smsmith        if (WalkState->NumOperands == 0)
48167754Smsmith        {
482167802Sjkim            ACPI_ERROR ((AE_INFO,
483167802Sjkim                "Object stack underflow! Count=%X State=%p #Ops=%X",
48467754Smsmith                PopCount, WalkState, WalkState->NumOperands));
48567754Smsmith            return (AE_STACK_UNDERFLOW);
48667754Smsmith        }
48767754Smsmith
48867754Smsmith        /* Just set the stack entry to null */
48967754Smsmith
49067754Smsmith        WalkState->NumOperands--;
49167754Smsmith        WalkState->Operands [WalkState->NumOperands] = NULL;
49267754Smsmith    }
49367754Smsmith
49482367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
495167802Sjkim        PopCount, WalkState, WalkState->NumOperands));
49667754Smsmith
49767754Smsmith    return (AE_OK);
49867754Smsmith}
49967754Smsmith
50067754Smsmith
50167754Smsmith/*******************************************************************************
50267754Smsmith *
50367754Smsmith * FUNCTION:    AcpiDsObjStackPopAndDelete
50467754Smsmith *
50567754Smsmith * PARAMETERS:  PopCount            - Number of objects/entries to pop
50667754Smsmith *              WalkState           - Current Walk state
50767754Smsmith *
50867754Smsmith * RETURN:      Status
50967754Smsmith *
51067754Smsmith * DESCRIPTION: Pop this walk's object stack and delete each object that is
51167754Smsmith *              popped off.
51267754Smsmith *
51367754Smsmith ******************************************************************************/
51467754Smsmith
515167802Sjkimvoid
51667754SmsmithAcpiDsObjStackPopAndDelete (
51767754Smsmith    UINT32                  PopCount,
51867754Smsmith    ACPI_WALK_STATE         *WalkState)
51967754Smsmith{
520193267Sjkim    INT32                   i;
52167754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
52267754Smsmith
523123315Snjl
524167802Sjkim    ACPI_FUNCTION_NAME (DsObjStackPopAndDelete);
52567754Smsmith
52682367Smsmith
527167802Sjkim    if (PopCount == 0)
52867754Smsmith    {
529167802Sjkim        return;
530167802Sjkim    }
53167754Smsmith
532193267Sjkim    for (i = (INT32) PopCount - 1; i >= 0; i--)
533167802Sjkim    {
53467754Smsmith        if (WalkState->NumOperands == 0)
53567754Smsmith        {
536167802Sjkim            return;
53767754Smsmith        }
53867754Smsmith
53967754Smsmith        /* Pop the stack and delete an object if present in this stack entry */
54067754Smsmith
54167754Smsmith        WalkState->NumOperands--;
542167802Sjkim        ObjDesc = WalkState->Operands [i];
54367754Smsmith        if (ObjDesc)
54467754Smsmith        {
545167802Sjkim            AcpiUtRemoveReference (WalkState->Operands [i]);
546167802Sjkim            WalkState->Operands [i] = NULL;
54767754Smsmith        }
54867754Smsmith    }
54967754Smsmith
55082367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
551167802Sjkim        PopCount, WalkState, WalkState->NumOperands));
55267754Smsmith}
55367754Smsmith
55467754Smsmith
55567754Smsmith/*******************************************************************************
55667754Smsmith *
55767754Smsmith * FUNCTION:    AcpiDsGetCurrentWalkState
55867754Smsmith *
55987031Smsmith * PARAMETERS:  Thread          - Get current active state for this Thread
56067754Smsmith *
56167754Smsmith * RETURN:      Pointer to the current walk state
56267754Smsmith *
56367754Smsmith * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
56487031Smsmith *              walk state.)
56567754Smsmith *
56667754Smsmith ******************************************************************************/
56767754Smsmith
56867754SmsmithACPI_WALK_STATE *
56967754SmsmithAcpiDsGetCurrentWalkState (
57087031Smsmith    ACPI_THREAD_STATE       *Thread)
57167754Smsmith{
572167802Sjkim    ACPI_FUNCTION_NAME (DsGetCurrentWalkState);
57367754Smsmith
57482367Smsmith
57587031Smsmith    if (!Thread)
57667754Smsmith    {
57767754Smsmith        return (NULL);
57867754Smsmith    }
57967754Smsmith
580114237Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
58187031Smsmith        Thread->WalkStateList));
58287031Smsmith
58387031Smsmith    return (Thread->WalkStateList);
58467754Smsmith}
58567754Smsmith
58667754Smsmith
58767754Smsmith/*******************************************************************************
58867754Smsmith *
58967754Smsmith * FUNCTION:    AcpiDsPushWalkState
59067754Smsmith *
59167754Smsmith * PARAMETERS:  WalkState       - State to push
592151937Sjkim *              Thread          - Thread state object
59367754Smsmith *
59467754Smsmith * RETURN:      None
59567754Smsmith *
596167802Sjkim * DESCRIPTION: Place the Thread state at the head of the state list
59767754Smsmith *
59867754Smsmith ******************************************************************************/
59967754Smsmith
60084491Smsmithvoid
60167754SmsmithAcpiDsPushWalkState (
60267754Smsmith    ACPI_WALK_STATE         *WalkState,
60387031Smsmith    ACPI_THREAD_STATE       *Thread)
60467754Smsmith{
605167802Sjkim    ACPI_FUNCTION_TRACE (DsPushWalkState);
60667754Smsmith
60767754Smsmith
608167802Sjkim    WalkState->Next = Thread->WalkStateList;
60987031Smsmith    Thread->WalkStateList = WalkState;
61067754Smsmith
61167754Smsmith    return_VOID;
61267754Smsmith}
61367754Smsmith
61467754Smsmith
61567754Smsmith/*******************************************************************************
61667754Smsmith *
61767754Smsmith * FUNCTION:    AcpiDsPopWalkState
61867754Smsmith *
619151937Sjkim * PARAMETERS:  Thread      - Current thread state
62067754Smsmith *
621151937Sjkim * RETURN:      A WalkState object popped from the thread's stack
62267754Smsmith *
62367754Smsmith * DESCRIPTION: Remove and return the walkstate object that is at the head of
62467754Smsmith *              the walk stack for the given walk list.  NULL indicates that
62567754Smsmith *              the list is empty.
62667754Smsmith *
62767754Smsmith ******************************************************************************/
62867754Smsmith
62967754SmsmithACPI_WALK_STATE *
63067754SmsmithAcpiDsPopWalkState (
63187031Smsmith    ACPI_THREAD_STATE       *Thread)
63267754Smsmith{
63367754Smsmith    ACPI_WALK_STATE         *WalkState;
63467754Smsmith
63567754Smsmith
636167802Sjkim    ACPI_FUNCTION_TRACE (DsPopWalkState);
63767754Smsmith
63867754Smsmith
63987031Smsmith    WalkState = Thread->WalkStateList;
64067754Smsmith
64167754Smsmith    if (WalkState)
64267754Smsmith    {
64367754Smsmith        /* Next walk state becomes the current walk state */
64467754Smsmith
64587031Smsmith        Thread->WalkStateList = WalkState->Next;
64667754Smsmith
64767754Smsmith        /*
64867754Smsmith         * Don't clear the NEXT field, this serves as an indicator
64967754Smsmith         * that there is a parent WALK STATE
650151937Sjkim         * Do Not: WalkState->Next = NULL;
65167754Smsmith         */
65267754Smsmith    }
65367754Smsmith
65467754Smsmith    return_PTR (WalkState);
65567754Smsmith}
65667754Smsmith
65767754Smsmith
65867754Smsmith/*******************************************************************************
65967754Smsmith *
66067754Smsmith * FUNCTION:    AcpiDsCreateWalkState
66167754Smsmith *
662151937Sjkim * PARAMETERS:  OwnerId         - ID for object creation
663151937Sjkim *              Origin          - Starting point for this walk
664167802Sjkim *              MethodDesc      - Method object
66587031Smsmith *              Thread          - Current thread state
66667754Smsmith *
66767754Smsmith * RETURN:      Pointer to the new walk state.
66867754Smsmith *
66991116Smsmith * DESCRIPTION: Allocate and initialize a new walk state.  The current walk
67087031Smsmith *              state is set to this new state.
67167754Smsmith *
67267754Smsmith ******************************************************************************/
67367754Smsmith
67467754SmsmithACPI_WALK_STATE *
67567754SmsmithAcpiDsCreateWalkState (
67667754Smsmith    ACPI_OWNER_ID           OwnerId,
67767754Smsmith    ACPI_PARSE_OBJECT       *Origin,
678167802Sjkim    ACPI_OPERAND_OBJECT     *MethodDesc,
67987031Smsmith    ACPI_THREAD_STATE       *Thread)
68067754Smsmith{
68167754Smsmith    ACPI_WALK_STATE         *WalkState;
68267754Smsmith
68367754Smsmith
684167802Sjkim    ACPI_FUNCTION_TRACE (DsCreateWalkState);
68567754Smsmith
68667754Smsmith
687167802Sjkim    WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE));
68882367Smsmith    if (!WalkState)
68967754Smsmith    {
69082367Smsmith        return_PTR (NULL);
69171867Smsmith    }
69267754Smsmith
693167802Sjkim    WalkState->DescriptorType = ACPI_DESC_TYPE_WALK;
694167802Sjkim    WalkState->MethodDesc = MethodDesc;
695167802Sjkim    WalkState->OwnerId = OwnerId;
696167802Sjkim    WalkState->Origin = Origin;
697167802Sjkim    WalkState->Thread = Thread;
69867754Smsmith
699102550Siwasaki    WalkState->ParserState.StartOp = Origin;
700102550Siwasaki
70167754Smsmith    /* Init the method args/local */
70267754Smsmith
703100966Siwasaki#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
70467754Smsmith    AcpiDsMethodDataInit (WalkState);
70569450Smsmith#endif
70667754Smsmith
70767754Smsmith    /* Put the new state at the head of the walk list */
70867754Smsmith
70987031Smsmith    if (Thread)
71084491Smsmith    {
71187031Smsmith        AcpiDsPushWalkState (WalkState, Thread);
71284491Smsmith    }
71367754Smsmith
71467754Smsmith    return_PTR (WalkState);
71567754Smsmith}
71667754Smsmith
71767754Smsmith
71867754Smsmith/*******************************************************************************
71967754Smsmith *
72084491Smsmith * FUNCTION:    AcpiDsInitAmlWalk
72184491Smsmith *
72284491Smsmith * PARAMETERS:  WalkState       - New state to be initialized
723123315Snjl *              Op              - Current parse op
724123315Snjl *              MethodNode      - Control method NS node, if any
725123315Snjl *              AmlStart        - Start of AML
726123315Snjl *              AmlLength       - Length of AML
727151937Sjkim *              Info            - Method info block (params, etc.)
728123315Snjl *              PassNumber      - 1, 2, or 3
72984491Smsmith *
730123315Snjl * RETURN:      Status
73184491Smsmith *
73284491Smsmith * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
73384491Smsmith *
73484491Smsmith ******************************************************************************/
73584491Smsmith
73684491SmsmithACPI_STATUS
73784491SmsmithAcpiDsInitAmlWalk (
73884491Smsmith    ACPI_WALK_STATE         *WalkState,
73984491Smsmith    ACPI_PARSE_OBJECT       *Op,
74084491Smsmith    ACPI_NAMESPACE_NODE     *MethodNode,
74184491Smsmith    UINT8                   *AmlStart,
74284491Smsmith    UINT32                  AmlLength,
743167802Sjkim    ACPI_EVALUATE_INFO      *Info,
744151937Sjkim    UINT8                   PassNumber)
74584491Smsmith{
74684491Smsmith    ACPI_STATUS             Status;
74784491Smsmith    ACPI_PARSE_STATE        *ParserState = &WalkState->ParserState;
748102550Siwasaki    ACPI_PARSE_OBJECT       *ExtraOp;
74984491Smsmith
75084491Smsmith
751167802Sjkim    ACPI_FUNCTION_TRACE (DsInitAmlWalk);
75284491Smsmith
75384491Smsmith
754167802Sjkim    WalkState->ParserState.Aml =
75584491Smsmith    WalkState->ParserState.AmlStart = AmlStart;
756167802Sjkim    WalkState->ParserState.AmlEnd =
757167802Sjkim    WalkState->ParserState.PkgEnd = AmlStart + AmlLength;
75884491Smsmith
75984491Smsmith    /* The NextOp of the NextWalk will be the beginning of the method */
76084491Smsmith
761151937Sjkim    WalkState->NextOp = NULL;
762151937Sjkim    WalkState->PassNumber = PassNumber;
76384491Smsmith
764129684Snjl    if (Info)
765129684Snjl    {
766193267Sjkim        WalkState->Params = Info->Parameters;
767193267Sjkim        WalkState->CallerReturnDesc = &Info->ReturnObject;
768129684Snjl    }
769129684Snjl
77084491Smsmith    Status = AcpiPsInitScope (&WalkState->ParserState, Op);
77184491Smsmith    if (ACPI_FAILURE (Status))
77284491Smsmith    {
77384491Smsmith        return_ACPI_STATUS (Status);
77484491Smsmith    }
77584491Smsmith
77684491Smsmith    if (MethodNode)
77784491Smsmith    {
778123315Snjl        WalkState->ParserState.StartNode = MethodNode;
779167802Sjkim        WalkState->WalkType = ACPI_WALK_METHOD;
780167802Sjkim        WalkState->MethodNode = MethodNode;
781167802Sjkim        WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode);
78284491Smsmith
78384491Smsmith        /* Push start scope on scope stack and make it current  */
78484491Smsmith
78584491Smsmith        Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState);
78684491Smsmith        if (ACPI_FAILURE (Status))
78784491Smsmith        {
78884491Smsmith            return_ACPI_STATUS (Status);
78984491Smsmith        }
79084491Smsmith
79184491Smsmith        /* Init the method arguments */
79284491Smsmith
793151937Sjkim        Status = AcpiDsMethodDataInitArgs (WalkState->Params,
794151937Sjkim                    ACPI_METHOD_NUM_ARGS, WalkState);
79599679Siwasaki        if (ACPI_FAILURE (Status))
79699679Siwasaki        {
79799679Siwasaki            return_ACPI_STATUS (Status);
79899679Siwasaki        }
79984491Smsmith    }
80084491Smsmith    else
80184491Smsmith    {
802114237Snjl        /*
803102550Siwasaki         * Setup the current scope.
804102550Siwasaki         * Find a Named Op that has a namespace node associated with it.
805102550Siwasaki         * search upwards from this Op.  Current scope is the first
806102550Siwasaki         * Op with a namespace node.
807102550Siwasaki         */
808102550Siwasaki        ExtraOp = ParserState->StartOp;
809102550Siwasaki        while (ExtraOp && !ExtraOp->Common.Node)
810102550Siwasaki        {
811102550Siwasaki            ExtraOp = ExtraOp->Common.Parent;
812102550Siwasaki        }
813123315Snjl
814102550Siwasaki        if (!ExtraOp)
815102550Siwasaki        {
816102550Siwasaki            ParserState->StartNode = NULL;
817102550Siwasaki        }
818102550Siwasaki        else
819102550Siwasaki        {
820102550Siwasaki            ParserState->StartNode = ExtraOp->Common.Node;
821102550Siwasaki        }
822114237Snjl
82384491Smsmith        if (ParserState->StartNode)
82484491Smsmith        {
82584491Smsmith            /* Push start scope on scope stack and make it current  */
82684491Smsmith
82784491Smsmith            Status = AcpiDsScopeStackPush (ParserState->StartNode,
82884491Smsmith                            ParserState->StartNode->Type, WalkState);
82984491Smsmith            if (ACPI_FAILURE (Status))
83084491Smsmith            {
83184491Smsmith                return_ACPI_STATUS (Status);
83284491Smsmith            }
83384491Smsmith        }
83484491Smsmith    }
83584491Smsmith
83699679Siwasaki    Status = AcpiDsInitCallbacks (WalkState, PassNumber);
83799679Siwasaki    return_ACPI_STATUS (Status);
83884491Smsmith}
83984491Smsmith
84084491Smsmith
84184491Smsmith/*******************************************************************************
84284491Smsmith *
84367754Smsmith * FUNCTION:    AcpiDsDeleteWalkState
84467754Smsmith *
84567754Smsmith * PARAMETERS:  WalkState       - State to delete
84667754Smsmith *
84767754Smsmith * RETURN:      Status
84867754Smsmith *
84967754Smsmith * DESCRIPTION: Delete a walk state including all internal data structures
85067754Smsmith *
85167754Smsmith ******************************************************************************/
85267754Smsmith
85367754Smsmithvoid
85467754SmsmithAcpiDsDeleteWalkState (
85567754Smsmith    ACPI_WALK_STATE         *WalkState)
85667754Smsmith{
85767754Smsmith    ACPI_GENERIC_STATE      *State;
85867754Smsmith
85967754Smsmith
860167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState);
86167754Smsmith
86267754Smsmith
86367754Smsmith    if (!WalkState)
86467754Smsmith    {
86567754Smsmith        return;
86667754Smsmith    }
86767754Smsmith
868167802Sjkim    if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK)
86967754Smsmith    {
870167802Sjkim        ACPI_ERROR ((AE_INFO, "%p is not a valid walk state",
871151937Sjkim            WalkState));
87267754Smsmith        return;
87367754Smsmith    }
87467754Smsmith
875167802Sjkim    /* There should not be any open scopes */
876167802Sjkim
87784491Smsmith    if (WalkState->ParserState.Scope)
87884491Smsmith    {
879167802Sjkim        ACPI_ERROR ((AE_INFO, "%p walk still has a scope list",
880151937Sjkim            WalkState));
881167802Sjkim        AcpiPsCleanupScope (&WalkState->ParserState);
88284491Smsmith    }
88367754Smsmith
884123315Snjl    /* Always must free any linked control states */
88584491Smsmith
88667754Smsmith    while (WalkState->ControlState)
88767754Smsmith    {
88867754Smsmith        State = WalkState->ControlState;
88967754Smsmith        WalkState->ControlState = State->Common.Next;
89067754Smsmith
89177424Smsmith        AcpiUtDeleteGenericState (State);
89267754Smsmith    }
89367754Smsmith
89467754Smsmith    /* Always must free any linked parse states */
89567754Smsmith
89667754Smsmith    while (WalkState->ScopeInfo)
89767754Smsmith    {
89867754Smsmith        State = WalkState->ScopeInfo;
89967754Smsmith        WalkState->ScopeInfo = State->Common.Next;
90067754Smsmith
90177424Smsmith        AcpiUtDeleteGenericState (State);
90267754Smsmith    }
90367754Smsmith
90469746Smsmith    /* Always must free any stacked result states */
90569746Smsmith
90669746Smsmith    while (WalkState->Results)
90769746Smsmith    {
90869746Smsmith        State = WalkState->Results;
90969746Smsmith        WalkState->Results = State->Common.Next;
91069746Smsmith
91177424Smsmith        AcpiUtDeleteGenericState (State);
91269746Smsmith    }
91369746Smsmith
914167802Sjkim    ACPI_FREE (WalkState);
91567754Smsmith    return_VOID;
91667754Smsmith}
91767754Smsmith
91867754Smsmith
919