Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: dscontrol - Support for execution control opcodes -
  4.  *                          if/else/while/return
  5.  *
  6.  *****************************************************************************/
  7.  
  8. /******************************************************************************
  9.  *
  10.  * 1. Copyright Notice
  11.  *
  12.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  13.  * All rights reserved.
  14.  *
  15.  * 2. License
  16.  *
  17.  * 2.1. This is your license from Intel Corp. under its intellectual property
  18.  * rights.  You may have additional license terms from the party that provided
  19.  * you this software, covering your right to use that party's intellectual
  20.  * property rights.
  21.  *
  22.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  23.  * copy of the source code appearing in this file ("Covered Code") an
  24.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  25.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  26.  * make derivatives, distribute, use and display any portion of the Covered
  27.  * Code in any form, with the right to sublicense such rights; and
  28.  *
  29.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  30.  * license (with the right to sublicense), under only those claims of Intel
  31.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  32.  * offer to sell, and import the Covered Code and derivative works thereof
  33.  * solely to the minimum extent necessary to exercise the above copyright
  34.  * license, and in no event shall the patent license extend to any additions
  35.  * to or modifications of the Original Intel Code.  No other license or right
  36.  * is granted directly or by implication, estoppel or otherwise;
  37.  *
  38.  * The above copyright and patent license is granted only if the following
  39.  * conditions are met:
  40.  *
  41.  * 3. Conditions
  42.  *
  43.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  44.  * Redistribution of source code of any substantial portion of the Covered
  45.  * Code or modification with rights to further distribute source must include
  46.  * the above Copyright Notice, the above License, this list of Conditions,
  47.  * and the following Disclaimer and Export Compliance provision.  In addition,
  48.  * Licensee must cause all Covered Code to which Licensee contributes to
  49.  * contain a file documenting the changes Licensee made to create that Covered
  50.  * Code and the date of any change.  Licensee must include in that file the
  51.  * documentation of any changes made by any predecessor Licensee.  Licensee
  52.  * must include a prominent statement that the modification is derived,
  53.  * directly or indirectly, from Original Intel Code.
  54.  *
  55.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  56.  * Redistribution of source code of any substantial portion of the Covered
  57.  * Code or modification without rights to further distribute source must
  58.  * include the following Disclaimer and Export Compliance provision in the
  59.  * documentation and/or other materials provided with distribution.  In
  60.  * addition, Licensee may not authorize further sublicense of source of any
  61.  * portion of the Covered Code, and must include terms to the effect that the
  62.  * license from Licensee to its licensee is limited to the intellectual
  63.  * property embodied in the software Licensee provides to its licensee, and
  64.  * not to intellectual property embodied in modifications its licensee may
  65.  * make.
  66.  *
  67.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  68.  * substantial portion of the Covered Code or modification must reproduce the
  69.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  70.  * provision in the documentation and/or other materials provided with the
  71.  * distribution.
  72.  *
  73.  * 3.4. Intel retains all right, title, and interest in and to the Original
  74.  * Intel Code.
  75.  *
  76.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  77.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  78.  * other dealings in products derived from or relating to the Covered Code
  79.  * without prior written authorization from Intel.
  80.  *
  81.  * 4. Disclaimer and Export Compliance
  82.  *
  83.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  84.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  85.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  86.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  87.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  88.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  89.  * PARTICULAR PURPOSE.
  90.  *
  91.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  92.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  93.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  94.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  95.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  96.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  97.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  98.  * LIMITED REMEDY.
  99.  *
  100.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  101.  * software or system incorporating such software without first obtaining any
  102.  * required license or other approval from the U. S. Department of Commerce or
  103.  * any other agency or department of the United States Government.  In the
  104.  * event Licensee exports any such software from the United States or
  105.  * re-exports any such software from a foreign destination, Licensee shall
  106.  * ensure that the distribution and export/re-export of the software is in
  107.  * compliance with all laws, regulations, orders, or other restrictions of the
  108.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  109.  * any of its subsidiaries will export/re-export any technical data, process,
  110.  * software, or service, directly or indirectly, to any country for which the
  111.  * United States government or any agency thereof requires an export license,
  112.  * other governmental approval, or letter of assurance, without first obtaining
  113.  * such license, approval or letter.
  114.  *
  115.  *****************************************************************************/
  116.  
  117. #define __DSCONTROL_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "amlcode.h"
  122. #include "acdispat.h"
  123. #include "acinterp.h"
  124.  
  125. #define _COMPONENT          ACPI_DISPATCHER
  126.         ACPI_MODULE_NAME    ("dscontrol")
  127.  
  128.  
  129. /*******************************************************************************
  130.  *
  131.  * FUNCTION:    AcpiDsExecBeginControlOp
  132.  *
  133.  * PARAMETERS:  WalkList        - The list that owns the walk stack
  134.  *              Op              - The control Op
  135.  *
  136.  * RETURN:      Status
  137.  *
  138.  * DESCRIPTION: Handles all control ops encountered during control method
  139.  *              execution.
  140.  *
  141.  ******************************************************************************/
  142.  
  143. ACPI_STATUS
  144. AcpiDsExecBeginControlOp (
  145.     ACPI_WALK_STATE         *WalkState,
  146.     ACPI_PARSE_OBJECT       *Op)
  147. {
  148.     ACPI_STATUS             Status = AE_OK;
  149.     ACPI_GENERIC_STATE      *ControlState;
  150.  
  151.  
  152.     ACPI_FUNCTION_NAME (DsExecBeginControlOp);
  153.  
  154.  
  155.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
  156.         Op, Op->Common.AmlOpcode, WalkState));
  157.  
  158.     switch (Op->Common.AmlOpcode)
  159.     {
  160.     case AML_WHILE_OP:
  161.  
  162.         /*
  163.          * If this is an additional iteration of a while loop, continue.
  164.          * There is no need to allocate a new control state.
  165.          */
  166.         if (WalkState->ControlState)
  167.         {
  168.             if (WalkState->ControlState->Control.AmlPredicateStart ==
  169.                 (WalkState->ParserState.Aml - 1))
  170.             {
  171.                 /* Reset the state to start-of-loop */
  172.  
  173.                 WalkState->ControlState->Common.State =
  174.                     ACPI_CONTROL_CONDITIONAL_EXECUTING;
  175.                 break;
  176.             }
  177.         }
  178.  
  179.         /*lint -fallthrough */
  180.  
  181.     case AML_IF_OP:
  182.  
  183.         /*
  184.          * IF/WHILE: Create a new control state to manage these
  185.          * constructs. We need to manage these as a stack, in order
  186.          * to handle nesting.
  187.          */
  188.         ControlState = AcpiUtCreateControlState ();
  189.         if (!ControlState)
  190.         {
  191.             Status = AE_NO_MEMORY;
  192.             break;
  193.         }
  194.         /*
  195.          * Save a pointer to the predicate for multiple executions
  196.          * of a loop
  197.          */
  198.         ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
  199.         ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
  200.         ControlState->Control.Opcode = Op->Common.AmlOpcode;
  201.  
  202.  
  203.         /* Push the control state on this walk's control stack */
  204.  
  205.         AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
  206.         break;
  207.  
  208.     case AML_ELSE_OP:
  209.  
  210.         /* Predicate is in the state object */
  211.         /* If predicate is true, the IF was executed, ignore ELSE part */
  212.  
  213.         if (WalkState->LastPredicate)
  214.         {
  215.             Status = AE_CTRL_TRUE;
  216.         }
  217.  
  218.         break;
  219.  
  220.     case AML_RETURN_OP:
  221.  
  222.         break;
  223.  
  224.     default:
  225.         break;
  226.     }
  227.  
  228.     return (Status);
  229. }
  230.  
  231.  
  232. /*******************************************************************************
  233.  *
  234.  * FUNCTION:    AcpiDsExecEndControlOp
  235.  *
  236.  * PARAMETERS:  WalkList        - The list that owns the walk stack
  237.  *              Op              - The control Op
  238.  *
  239.  * RETURN:      Status
  240.  *
  241.  * DESCRIPTION: Handles all control ops encountered during control method
  242.  *              execution.
  243.  *
  244.  ******************************************************************************/
  245.  
  246. ACPI_STATUS
  247. AcpiDsExecEndControlOp (
  248.     ACPI_WALK_STATE         *WalkState,
  249.     ACPI_PARSE_OBJECT       *Op)
  250. {
  251.     ACPI_STATUS             Status = AE_OK;
  252.     ACPI_GENERIC_STATE      *ControlState;
  253.  
  254.  
  255.     ACPI_FUNCTION_NAME (DsExecEndControlOp);
  256.  
  257.  
  258.     switch (Op->Common.AmlOpcode)
  259.     {
  260.     case AML_IF_OP:
  261.  
  262.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
  263.  
  264.         /*
  265.          * Save the result of the predicate in case there is an
  266.          * ELSE to come
  267.          */
  268.         WalkState->LastPredicate =
  269.             (BOOLEAN) WalkState->ControlState->Common.Value;
  270.  
  271.         /*
  272.          * Pop the control state that was created at the start
  273.          * of the IF and free it
  274.          */
  275.         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
  276.         AcpiUtDeleteGenericState (ControlState);
  277.         break;
  278.  
  279.  
  280.     case AML_ELSE_OP:
  281.  
  282.         break;
  283.  
  284.  
  285.     case AML_WHILE_OP:
  286.  
  287.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
  288.  
  289.         ControlState = WalkState->ControlState;
  290.         if (ControlState->Common.Value)
  291.         {
  292.             /* Predicate was true, the body of the loop was just executed */
  293.  
  294.             /*
  295.              * This loop counter mechanism allows the interpreter to escape
  296.              * possibly infinite loops. This can occur in poorly written AML
  297.              * when the hardware does not respond within a while loop and the
  298.              * loop does not implement a timeout.
  299.              */
  300.             ControlState->Control.LoopCount++;
  301.             if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
  302.             {
  303.                 Status = AE_AML_INFINITE_LOOP;
  304.                 break;
  305.             }
  306.  
  307.             /*
  308.              * Go back and evaluate the predicate and maybe execute the loop
  309.              * another time
  310.              */
  311.             Status = AE_CTRL_PENDING;
  312.             WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
  313.             break;
  314.         }
  315.  
  316.         /* Predicate was false, terminate this while loop */
  317.  
  318.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  319.             "[WHILE_OP] termination! Op=%p\n",Op));
  320.  
  321.         /* Pop this control state and free it */
  322.  
  323.         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
  324.         AcpiUtDeleteGenericState (ControlState);
  325.         break;
  326.  
  327.  
  328.     case AML_RETURN_OP:
  329.  
  330.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  331.             "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
  332.  
  333.         /*
  334.          * One optional operand -- the return value
  335.          * It can be either an immediate operand or a result that
  336.          * has been bubbled up the tree
  337.          */
  338.         if (Op->Common.Value.Arg)
  339.         {
  340.             /* Since we have a real Return(), delete any implicit return */
  341.  
  342.             AcpiDsClearImplicitReturn (WalkState);
  343.  
  344.             /* Return statement has an immediate operand */
  345.  
  346.             Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
  347.             if (ACPI_FAILURE (Status))
  348.             {
  349.                 return (Status);
  350.             }
  351.  
  352.             /*
  353.              * If value being returned is a Reference (such as
  354.              * an arg or local), resolve it now because it may
  355.              * cease to exist at the end of the method.
  356.              */
  357.             Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
  358.             if (ACPI_FAILURE (Status))
  359.             {
  360.                 return (Status);
  361.             }
  362.  
  363.             /*
  364.              * Get the return value and save as the last result
  365.              * value.  This is the only place where WalkState->ReturnDesc
  366.              * is set to anything other than zero!
  367.              */
  368.             WalkState->ReturnDesc = WalkState->Operands[0];
  369.         }
  370.         else if (WalkState->ResultCount)
  371.         {
  372.             /* Since we have a real Return(), delete any implicit return */
  373.  
  374.             AcpiDsClearImplicitReturn (WalkState);
  375.  
  376.             /*
  377.              * The return value has come from a previous calculation.
  378.              *
  379.              * If value being returned is a Reference (such as
  380.              * an arg or local), resolve it now because it may
  381.              * cease to exist at the end of the method.
  382.              *
  383.              * Allow references created by the Index operator to return
  384.              * unchanged.
  385.              */
  386.             if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
  387.                 ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
  388.                 ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
  389.             {
  390.                 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
  391.                 if (ACPI_FAILURE (Status))
  392.                 {
  393.                     return (Status);
  394.                 }
  395.             }
  396.  
  397.             WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
  398.         }
  399.         else
  400.         {
  401.             /* No return operand */
  402.  
  403.             if (WalkState->NumOperands)
  404.             {
  405.                 AcpiUtRemoveReference (WalkState->Operands [0]);
  406.             }
  407.  
  408.             WalkState->Operands [0]     = NULL;
  409.             WalkState->NumOperands      = 0;
  410.             WalkState->ReturnDesc       = NULL;
  411.         }
  412.  
  413.  
  414.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  415.             "Completed RETURN_OP State=%p, RetVal=%p\n",
  416.             WalkState, WalkState->ReturnDesc));
  417.  
  418.         /* End the control method execution right now */
  419.  
  420.         Status = AE_CTRL_TERMINATE;
  421.         break;
  422.  
  423.  
  424.     case AML_NOOP_OP:
  425.  
  426.         /* Just do nothing! */
  427.         break;
  428.  
  429.  
  430.     case AML_BREAK_POINT_OP:
  431.  
  432.         /*
  433.          * Set the single-step flag. This will cause the debugger (if present)
  434.          * to break to the console within the AML debugger at the start of the
  435.          * next AML instruction.
  436.          */
  437.         ACPI_DEBUGGER_EXEC (
  438.             AcpiGbl_CmSingleStep = TRUE);
  439.         ACPI_DEBUGGER_EXEC (
  440.             AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
  441.  
  442.         /* Call to the OSL in case OS wants a piece of the action */
  443.  
  444.         Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
  445.                     "Executed AML Breakpoint opcode");
  446.         break;
  447.  
  448.  
  449.     case AML_BREAK_OP:
  450.     case AML_CONTINUE_OP: /* ACPI 2.0 */
  451.  
  452.  
  453.         /* Pop and delete control states until we find a while */
  454.  
  455.         while (WalkState->ControlState &&
  456.                 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
  457.         {
  458.             ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
  459.             AcpiUtDeleteGenericState (ControlState);
  460.         }
  461.  
  462.         /* No while found? */
  463.  
  464.         if (!WalkState->ControlState)
  465.         {
  466.             return (AE_AML_NO_WHILE);
  467.         }
  468.  
  469.         /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
  470.  
  471.         WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
  472.  
  473.         /* Return status depending on opcode */
  474.  
  475.         if (Op->Common.AmlOpcode == AML_BREAK_OP)
  476.         {
  477.             Status = AE_CTRL_BREAK;
  478.         }
  479.         else
  480.         {
  481.             Status = AE_CTRL_CONTINUE;
  482.         }
  483.         break;
  484.  
  485.  
  486.     default:
  487.  
  488.         ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
  489.             Op->Common.AmlOpcode, Op));
  490.  
  491.         Status = AE_AML_BAD_OPCODE;
  492.         break;
  493.     }
  494.  
  495.     return (Status);
  496. }
  497.