Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 - 2010, 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.  
  117. #define __DSWSTATE_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acparser.h"
  122. #include "acdispat.h"
  123. #include "acnamesp.h"
  124.  
  125. #define _COMPONENT          ACPI_DISPATCHER
  126.         ACPI_MODULE_NAME    ("dswstate")
  127.  
  128. /* Local prototypes */
  129.  
  130. static ACPI_STATUS
  131. AcpiDsResultStackPush (
  132.     ACPI_WALK_STATE         *WalkState);
  133.  
  134. static ACPI_STATUS
  135. AcpiDsResultStackPop (
  136.     ACPI_WALK_STATE         *WalkState);
  137.  
  138.  
  139. /*******************************************************************************
  140.  *
  141.  * FUNCTION:    AcpiDsResultPop
  142.  *
  143.  * PARAMETERS:  Object              - Where to return the popped object
  144.  *              WalkState           - Current Walk state
  145.  *
  146.  * RETURN:      Status
  147.  *
  148.  * DESCRIPTION: Pop an object off the top of this walk's result stack
  149.  *
  150.  ******************************************************************************/
  151.  
  152. ACPI_STATUS
  153. AcpiDsResultPop (
  154.     ACPI_OPERAND_OBJECT     **Object,
  155.     ACPI_WALK_STATE         *WalkState)
  156. {
  157.     UINT32                  Index;
  158.     ACPI_GENERIC_STATE      *State;
  159.     ACPI_STATUS             Status;
  160.  
  161.  
  162.     ACPI_FUNCTION_NAME (DsResultPop);
  163.  
  164.  
  165.     State = WalkState->Results;
  166.  
  167.     /* Incorrect state of result stack */
  168.  
  169.     if (State && !WalkState->ResultCount)
  170.     {
  171.         ACPI_ERROR ((AE_INFO, "No results on result stack"));
  172.         return (AE_AML_INTERNAL);
  173.     }
  174.  
  175.     if (!State && WalkState->ResultCount)
  176.     {
  177.         ACPI_ERROR ((AE_INFO, "No result state for result stack"));
  178.         return (AE_AML_INTERNAL);
  179.     }
  180.  
  181.     /* Empty result stack */
  182.  
  183.     if (!State)
  184.     {
  185.         ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState));
  186.         return (AE_AML_NO_RETURN_VALUE);
  187.     }
  188.  
  189.     /* Return object of the top element and clean that top element result stack */
  190.  
  191.     WalkState->ResultCount--;
  192.     Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
  193.  
  194.     *Object = State->Results.ObjDesc [Index];
  195.     if (!*Object)
  196.     {
  197.         ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p",
  198.             WalkState));
  199.         return (AE_AML_NO_RETURN_VALUE);
  200.     }
  201.  
  202.     State->Results.ObjDesc [Index] = NULL;
  203.     if (Index == 0)
  204.     {
  205.         Status = AcpiDsResultStackPop (WalkState);
  206.         if (ACPI_FAILURE (Status))
  207.         {
  208.             return (Status);
  209.         }
  210.     }
  211.  
  212.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  213.         "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object,
  214.         AcpiUtGetObjectTypeName (*Object),
  215.         Index, WalkState, WalkState->ResultCount));
  216.  
  217.     return (AE_OK);
  218. }
  219.  
  220.  
  221. /*******************************************************************************
  222.  *
  223.  * FUNCTION:    AcpiDsResultPush
  224.  *
  225.  * PARAMETERS:  Object              - Where to return the popped object
  226.  *              WalkState           - Current Walk state
  227.  *
  228.  * RETURN:      Status
  229.  *
  230.  * DESCRIPTION: Push an object onto the current result stack
  231.  *
  232.  ******************************************************************************/
  233.  
  234. ACPI_STATUS
  235. AcpiDsResultPush (
  236.     ACPI_OPERAND_OBJECT     *Object,
  237.     ACPI_WALK_STATE         *WalkState)
  238. {
  239.     ACPI_GENERIC_STATE      *State;
  240.     ACPI_STATUS             Status;
  241.     UINT32                  Index;
  242.  
  243.  
  244.     ACPI_FUNCTION_NAME (DsResultPush);
  245.  
  246.  
  247.     if (WalkState->ResultCount > WalkState->ResultSize)
  248.     {
  249.         ACPI_ERROR ((AE_INFO, "Result stack is full"));
  250.         return (AE_AML_INTERNAL);
  251.     }
  252.     else if (WalkState->ResultCount == WalkState->ResultSize)
  253.     {
  254.         /* Extend the result stack */
  255.  
  256.         Status = AcpiDsResultStackPush (WalkState);
  257.         if (ACPI_FAILURE (Status))
  258.         {
  259.             ACPI_ERROR ((AE_INFO, "Failed to extend the result stack"));
  260.             return (Status);
  261.         }
  262.     }
  263.  
  264.     if (!(WalkState->ResultCount < WalkState->ResultSize))
  265.     {
  266.         ACPI_ERROR ((AE_INFO, "No free elements in result stack"));
  267.         return (AE_AML_INTERNAL);
  268.     }
  269.  
  270.     State = WalkState->Results;
  271.     if (!State)
  272.     {
  273.         ACPI_ERROR ((AE_INFO, "No result stack frame during push"));
  274.         return (AE_AML_INTERNAL);
  275.     }
  276.  
  277.     if (!Object)
  278.     {
  279.         ACPI_ERROR ((AE_INFO,
  280.             "Null Object! Obj=%p State=%p Num=%u",
  281.             Object, WalkState, WalkState->ResultCount));
  282.         return (AE_BAD_PARAMETER);
  283.     }
  284.  
  285.     /* Assign the address of object to the top free element of result stack */
  286.  
  287.     Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
  288.     State->Results.ObjDesc [Index] = Object;
  289.     WalkState->ResultCount++;
  290.  
  291.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
  292.         Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
  293.         WalkState, WalkState->ResultCount, WalkState->CurrentResult));
  294.  
  295.     return (AE_OK);
  296. }
  297.  
  298.  
  299. /*******************************************************************************
  300.  *
  301.  * FUNCTION:    AcpiDsResultStackPush
  302.  *
  303.  * PARAMETERS:  WalkState           - Current Walk state
  304.  *
  305.  * RETURN:      Status
  306.  *
  307.  * DESCRIPTION: Push an object onto the WalkState result stack
  308.  *
  309.  ******************************************************************************/
  310.  
  311. static ACPI_STATUS
  312. AcpiDsResultStackPush (
  313.     ACPI_WALK_STATE         *WalkState)
  314. {
  315.     ACPI_GENERIC_STATE      *State;
  316.  
  317.  
  318.     ACPI_FUNCTION_NAME (DsResultStackPush);
  319.  
  320.  
  321.     /* Check for stack overflow */
  322.  
  323.     if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
  324.         ACPI_RESULTS_OBJ_NUM_MAX)
  325.     {
  326.         ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
  327.             WalkState, WalkState->ResultSize));
  328.         return (AE_STACK_OVERFLOW);
  329.     }
  330.  
  331.     State = AcpiUtCreateGenericState ();
  332.     if (!State)
  333.     {
  334.         return (AE_NO_MEMORY);
  335.     }
  336.  
  337.     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT;
  338.     AcpiUtPushGenericState (&WalkState->Results, State);
  339.  
  340.     /* Increase the length of the result stack by the length of frame */
  341.  
  342.     WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM;
  343.  
  344.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
  345.         State, WalkState));
  346.  
  347.     return (AE_OK);
  348. }
  349.  
  350.  
  351. /*******************************************************************************
  352.  *
  353.  * FUNCTION:    AcpiDsResultStackPop
  354.  *
  355.  * PARAMETERS:  WalkState           - Current Walk state
  356.  *
  357.  * RETURN:      Status
  358.  *
  359.  * DESCRIPTION: Pop an object off of the WalkState result stack
  360.  *
  361.  ******************************************************************************/
  362.  
  363. static ACPI_STATUS
  364. AcpiDsResultStackPop (
  365.     ACPI_WALK_STATE         *WalkState)
  366. {
  367.     ACPI_GENERIC_STATE      *State;
  368.  
  369.  
  370.     ACPI_FUNCTION_NAME (DsResultStackPop);
  371.  
  372.  
  373.     /* Check for stack underflow */
  374.  
  375.     if (WalkState->Results == NULL)
  376.     {
  377.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Result stack underflow - State=%p\n",
  378.             WalkState));
  379.         return (AE_AML_NO_OPERAND);
  380.     }
  381.  
  382.     if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM)
  383.     {
  384.         ACPI_ERROR ((AE_INFO, "Insufficient result stack size"));
  385.         return (AE_AML_INTERNAL);
  386.     }
  387.  
  388.     State = AcpiUtPopGenericState (&WalkState->Results);
  389.     AcpiUtDeleteGenericState (State);
  390.  
  391.     /* Decrease the length of result stack by the length of frame */
  392.  
  393.     WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM;
  394.  
  395.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  396.         "Result=%p RemainingResults=%X State=%p\n",
  397.         State, WalkState->ResultCount, WalkState));
  398.  
  399.     return (AE_OK);
  400. }
  401.  
  402.  
  403. /*******************************************************************************
  404.  *
  405.  * FUNCTION:    AcpiDsObjStackPush
  406.  *
  407.  * PARAMETERS:  Object              - Object to push
  408.  *              WalkState           - Current Walk state
  409.  *
  410.  * RETURN:      Status
  411.  *
  412.  * DESCRIPTION: Push an object onto this walk's object/operand stack
  413.  *
  414.  ******************************************************************************/
  415.  
  416. ACPI_STATUS
  417. AcpiDsObjStackPush (
  418.     void                    *Object,
  419.     ACPI_WALK_STATE         *WalkState)
  420. {
  421.     ACPI_FUNCTION_NAME (DsObjStackPush);
  422.  
  423.  
  424.     /* Check for stack overflow */
  425.  
  426.     if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
  427.     {
  428.         ACPI_ERROR ((AE_INFO,
  429.             "Object stack overflow! Obj=%p State=%p #Ops=%u",
  430.             Object, WalkState, WalkState->NumOperands));
  431.         return (AE_STACK_OVERFLOW);
  432.     }
  433.  
  434.     /* Put the object onto the stack */
  435.  
  436.     WalkState->Operands [WalkState->OperandIndex] = Object;
  437.     WalkState->NumOperands++;
  438.  
  439.     /* For the usual order of filling the operand stack */
  440.  
  441.     WalkState->OperandIndex++;
  442.  
  443.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
  444.         Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
  445.         WalkState, WalkState->NumOperands));
  446.  
  447.     return (AE_OK);
  448. }
  449.  
  450.  
  451. /*******************************************************************************
  452.  *
  453.  * FUNCTION:    AcpiDsObjStackPop
  454.  *
  455.  * PARAMETERS:  PopCount            - Number of objects/entries to pop
  456.  *              WalkState           - Current Walk state
  457.  *
  458.  * RETURN:      Status
  459.  *
  460.  * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
  461.  *              deleted by this routine.
  462.  *
  463.  ******************************************************************************/
  464.  
  465. ACPI_STATUS
  466. AcpiDsObjStackPop (
  467.     UINT32                  PopCount,
  468.     ACPI_WALK_STATE         *WalkState)
  469. {
  470.     UINT32                  i;
  471.  
  472.  
  473.     ACPI_FUNCTION_NAME (DsObjStackPop);
  474.  
  475.  
  476.     for (i = 0; i < PopCount; i++)
  477.     {
  478.         /* Check for stack underflow */
  479.  
  480.         if (WalkState->NumOperands == 0)
  481.         {
  482.             ACPI_ERROR ((AE_INFO,
  483.                 "Object stack underflow! Count=%X State=%p #Ops=%u",
  484.                 PopCount, WalkState, WalkState->NumOperands));
  485.             return (AE_STACK_UNDERFLOW);
  486.         }
  487.  
  488.         /* Just set the stack entry to null */
  489.  
  490.         WalkState->NumOperands--;
  491.         WalkState->Operands [WalkState->NumOperands] = NULL;
  492.     }
  493.  
  494.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
  495.         PopCount, WalkState, WalkState->NumOperands));
  496.  
  497.     return (AE_OK);
  498. }
  499.  
  500.  
  501. /*******************************************************************************
  502.  *
  503.  * FUNCTION:    AcpiDsObjStackPopAndDelete
  504.  *
  505.  * PARAMETERS:  PopCount            - Number of objects/entries to pop
  506.  *              WalkState           - Current Walk state
  507.  *
  508.  * RETURN:      Status
  509.  *
  510.  * DESCRIPTION: Pop this walk's object stack and delete each object that is
  511.  *              popped off.
  512.  *
  513.  ******************************************************************************/
  514.  
  515. void
  516. AcpiDsObjStackPopAndDelete (
  517.     UINT32                  PopCount,
  518.     ACPI_WALK_STATE         *WalkState)
  519. {
  520.     INT32                   i;
  521.     ACPI_OPERAND_OBJECT     *ObjDesc;
  522.  
  523.  
  524.     ACPI_FUNCTION_NAME (DsObjStackPopAndDelete);
  525.  
  526.  
  527.     if (PopCount == 0)
  528.     {
  529.         return;
  530.     }
  531.  
  532.     for (i = (INT32) PopCount - 1; i >= 0; i--)
  533.     {
  534.         if (WalkState->NumOperands == 0)
  535.         {
  536.             return;
  537.         }
  538.  
  539.         /* Pop the stack and delete an object if present in this stack entry */
  540.  
  541.         WalkState->NumOperands--;
  542.         ObjDesc = WalkState->Operands [i];
  543.         if (ObjDesc)
  544.         {
  545.             AcpiUtRemoveReference (WalkState->Operands [i]);
  546.             WalkState->Operands [i] = NULL;
  547.         }
  548.     }
  549.  
  550.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
  551.         PopCount, WalkState, WalkState->NumOperands));
  552. }
  553.  
  554.  
  555. /*******************************************************************************
  556.  *
  557.  * FUNCTION:    AcpiDsGetCurrentWalkState
  558.  *
  559.  * PARAMETERS:  Thread          - Get current active state for this Thread
  560.  *
  561.  * RETURN:      Pointer to the current walk state
  562.  *
  563.  * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
  564.  *              walk state.)
  565.  *
  566.  ******************************************************************************/
  567.  
  568. ACPI_WALK_STATE *
  569. AcpiDsGetCurrentWalkState (
  570.     ACPI_THREAD_STATE       *Thread)
  571. {
  572.     ACPI_FUNCTION_NAME (DsGetCurrentWalkState);
  573.  
  574.  
  575.     if (!Thread)
  576.     {
  577.         return (NULL);
  578.     }
  579.  
  580.     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
  581.         Thread->WalkStateList));
  582.  
  583.     return (Thread->WalkStateList);
  584. }
  585.  
  586.  
  587. /*******************************************************************************
  588.  *
  589.  * FUNCTION:    AcpiDsPushWalkState
  590.  *
  591.  * PARAMETERS:  WalkState       - State to push
  592.  *              Thread          - Thread state object
  593.  *
  594.  * RETURN:      None
  595.  *
  596.  * DESCRIPTION: Place the Thread state at the head of the state list
  597.  *
  598.  ******************************************************************************/
  599.  
  600. void
  601. AcpiDsPushWalkState (
  602.     ACPI_WALK_STATE         *WalkState,
  603.     ACPI_THREAD_STATE       *Thread)
  604. {
  605.     ACPI_FUNCTION_TRACE (DsPushWalkState);
  606.  
  607.  
  608.     WalkState->Next = Thread->WalkStateList;
  609.     Thread->WalkStateList = WalkState;
  610.  
  611.     return_VOID;
  612. }
  613.  
  614.  
  615. /*******************************************************************************
  616.  *
  617.  * FUNCTION:    AcpiDsPopWalkState
  618.  *
  619.  * PARAMETERS:  Thread      - Current thread state
  620.  *
  621.  * RETURN:      A WalkState object popped from the thread's stack
  622.  *
  623.  * DESCRIPTION: Remove and return the walkstate object that is at the head of
  624.  *              the walk stack for the given walk list.  NULL indicates that
  625.  *              the list is empty.
  626.  *
  627.  ******************************************************************************/
  628.  
  629. ACPI_WALK_STATE *
  630. AcpiDsPopWalkState (
  631.     ACPI_THREAD_STATE       *Thread)
  632. {
  633.     ACPI_WALK_STATE         *WalkState;
  634.  
  635.  
  636.     ACPI_FUNCTION_TRACE (DsPopWalkState);
  637.  
  638.  
  639.     WalkState = Thread->WalkStateList;
  640.  
  641.     if (WalkState)
  642.     {
  643.         /* Next walk state becomes the current walk state */
  644.  
  645.         Thread->WalkStateList = WalkState->Next;
  646.  
  647.         /*
  648.          * Don't clear the NEXT field, this serves as an indicator
  649.          * that there is a parent WALK STATE
  650.          * Do Not: WalkState->Next = NULL;
  651.          */
  652.     }
  653.  
  654.     return_PTR (WalkState);
  655. }
  656.  
  657.  
  658. /*******************************************************************************
  659.  *
  660.  * FUNCTION:    AcpiDsCreateWalkState
  661.  *
  662.  * PARAMETERS:  OwnerId         - ID for object creation
  663.  *              Origin          - Starting point for this walk
  664.  *              MethodDesc      - Method object
  665.  *              Thread          - Current thread state
  666.  *
  667.  * RETURN:      Pointer to the new walk state.
  668.  *
  669.  * DESCRIPTION: Allocate and initialize a new walk state.  The current walk
  670.  *              state is set to this new state.
  671.  *
  672.  ******************************************************************************/
  673.  
  674. ACPI_WALK_STATE *
  675. AcpiDsCreateWalkState (
  676.     ACPI_OWNER_ID           OwnerId,
  677.     ACPI_PARSE_OBJECT       *Origin,
  678.     ACPI_OPERAND_OBJECT     *MethodDesc,
  679.     ACPI_THREAD_STATE       *Thread)
  680. {
  681.     ACPI_WALK_STATE         *WalkState;
  682.  
  683.  
  684.     ACPI_FUNCTION_TRACE (DsCreateWalkState);
  685.  
  686.  
  687.     WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE));
  688.     if (!WalkState)
  689.     {
  690.         return_PTR (NULL);
  691.     }
  692.  
  693.     WalkState->DescriptorType = ACPI_DESC_TYPE_WALK;
  694.     WalkState->MethodDesc = MethodDesc;
  695.     WalkState->OwnerId = OwnerId;
  696.     WalkState->Origin = Origin;
  697.     WalkState->Thread = Thread;
  698.  
  699.     WalkState->ParserState.StartOp = Origin;
  700.  
  701.     /* Init the method args/local */
  702.  
  703. #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
  704.     AcpiDsMethodDataInit (WalkState);
  705. #endif
  706.  
  707.     /* Put the new state at the head of the walk list */
  708.  
  709.     if (Thread)
  710.     {
  711.         AcpiDsPushWalkState (WalkState, Thread);
  712.     }
  713.  
  714.     return_PTR (WalkState);
  715. }
  716.  
  717.  
  718. /*******************************************************************************
  719.  *
  720.  * FUNCTION:    AcpiDsInitAmlWalk
  721.  *
  722.  * PARAMETERS:  WalkState       - New state to be initialized
  723.  *              Op              - Current parse op
  724.  *              MethodNode      - Control method NS node, if any
  725.  *              AmlStart        - Start of AML
  726.  *              AmlLength       - Length of AML
  727.  *              Info            - Method info block (params, etc.)
  728.  *              PassNumber      - 1, 2, or 3
  729.  *
  730.  * RETURN:      Status
  731.  *
  732.  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
  733.  *
  734.  ******************************************************************************/
  735.  
  736. ACPI_STATUS
  737. AcpiDsInitAmlWalk (
  738.     ACPI_WALK_STATE         *WalkState,
  739.     ACPI_PARSE_OBJECT       *Op,
  740.     ACPI_NAMESPACE_NODE     *MethodNode,
  741.     UINT8                   *AmlStart,
  742.     UINT32                  AmlLength,
  743.     ACPI_EVALUATE_INFO      *Info,
  744.     UINT8                   PassNumber)
  745. {
  746.     ACPI_STATUS             Status;
  747.     ACPI_PARSE_STATE        *ParserState = &WalkState->ParserState;
  748.     ACPI_PARSE_OBJECT       *ExtraOp;
  749.  
  750.  
  751.     ACPI_FUNCTION_TRACE (DsInitAmlWalk);
  752.  
  753.  
  754.     WalkState->ParserState.Aml =
  755.     WalkState->ParserState.AmlStart = AmlStart;
  756.     WalkState->ParserState.AmlEnd =
  757.     WalkState->ParserState.PkgEnd = AmlStart + AmlLength;
  758.  
  759.     /* The NextOp of the NextWalk will be the beginning of the method */
  760.  
  761.     WalkState->NextOp = NULL;
  762.     WalkState->PassNumber = PassNumber;
  763.  
  764.     if (Info)
  765.     {
  766.         WalkState->Params = Info->Parameters;
  767.         WalkState->CallerReturnDesc = &Info->ReturnObject;
  768.     }
  769.  
  770.     Status = AcpiPsInitScope (&WalkState->ParserState, Op);
  771.     if (ACPI_FAILURE (Status))
  772.     {
  773.         return_ACPI_STATUS (Status);
  774.     }
  775.  
  776.     if (MethodNode)
  777.     {
  778.         WalkState->ParserState.StartNode = MethodNode;
  779.         WalkState->WalkType = ACPI_WALK_METHOD;
  780.         WalkState->MethodNode = MethodNode;
  781.         WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode);
  782.  
  783.         /* Push start scope on scope stack and make it current  */
  784.  
  785.         Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState);
  786.         if (ACPI_FAILURE (Status))
  787.         {
  788.             return_ACPI_STATUS (Status);
  789.         }
  790.  
  791.         /* Init the method arguments */
  792.  
  793.         Status = AcpiDsMethodDataInitArgs (WalkState->Params,
  794.                     ACPI_METHOD_NUM_ARGS, WalkState);
  795.         if (ACPI_FAILURE (Status))
  796.         {
  797.             return_ACPI_STATUS (Status);
  798.         }
  799.     }
  800.     else
  801.     {
  802.         /*
  803.          * Setup the current scope.
  804.          * Find a Named Op that has a namespace node associated with it.
  805.          * search upwards from this Op.  Current scope is the first
  806.          * Op with a namespace node.
  807.          */
  808.         ExtraOp = ParserState->StartOp;
  809.         while (ExtraOp && !ExtraOp->Common.Node)
  810.         {
  811.             ExtraOp = ExtraOp->Common.Parent;
  812.         }
  813.  
  814.         if (!ExtraOp)
  815.         {
  816.             ParserState->StartNode = NULL;
  817.         }
  818.         else
  819.         {
  820.             ParserState->StartNode = ExtraOp->Common.Node;
  821.         }
  822.  
  823.         if (ParserState->StartNode)
  824.         {
  825.             /* Push start scope on scope stack and make it current  */
  826.  
  827.             Status = AcpiDsScopeStackPush (ParserState->StartNode,
  828.                             ParserState->StartNode->Type, WalkState);
  829.             if (ACPI_FAILURE (Status))
  830.             {
  831.                 return_ACPI_STATUS (Status);
  832.             }
  833.         }
  834.     }
  835.  
  836.     Status = AcpiDsInitCallbacks (WalkState, PassNumber);
  837.     return_ACPI_STATUS (Status);
  838. }
  839.  
  840.  
  841. /*******************************************************************************
  842.  *
  843.  * FUNCTION:    AcpiDsDeleteWalkState
  844.  *
  845.  * PARAMETERS:  WalkState       - State to delete
  846.  *
  847.  * RETURN:      Status
  848.  *
  849.  * DESCRIPTION: Delete a walk state including all internal data structures
  850.  *
  851.  ******************************************************************************/
  852.  
  853. void
  854. AcpiDsDeleteWalkState (
  855.     ACPI_WALK_STATE         *WalkState)
  856. {
  857.     ACPI_GENERIC_STATE      *State;
  858.  
  859.  
  860.     ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState);
  861.  
  862.  
  863.     if (!WalkState)
  864.     {
  865.         return;
  866.     }
  867.  
  868.     if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK)
  869.     {
  870.         ACPI_ERROR ((AE_INFO, "%p is not a valid walk state",
  871.             WalkState));
  872.         return;
  873.     }
  874.  
  875.     /* There should not be any open scopes */
  876.  
  877.     if (WalkState->ParserState.Scope)
  878.     {
  879.         ACPI_ERROR ((AE_INFO, "%p walk still has a scope list",
  880.             WalkState));
  881.         AcpiPsCleanupScope (&WalkState->ParserState);
  882.     }
  883.  
  884.     /* Always must free any linked control states */
  885.  
  886.     while (WalkState->ControlState)
  887.     {
  888.         State = WalkState->ControlState;
  889.         WalkState->ControlState = State->Common.Next;
  890.  
  891.         AcpiUtDeleteGenericState (State);
  892.     }
  893.  
  894.     /* Always must free any linked parse states */
  895.  
  896.     while (WalkState->ScopeInfo)
  897.     {
  898.         State = WalkState->ScopeInfo;
  899.         WalkState->ScopeInfo = State->Common.Next;
  900.  
  901.         AcpiUtDeleteGenericState (State);
  902.     }
  903.  
  904.     /* Always must free any stacked result states */
  905.  
  906.     while (WalkState->Results)
  907.     {
  908.         State = WalkState->Results;
  909.         WalkState->Results = State->Common.Next;
  910.  
  911.         AcpiUtDeleteGenericState (State);
  912.     }
  913.  
  914.     ACPI_FREE (WalkState);
  915.     return_VOID;
  916. }
  917.  
  918.  
  919.