⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psparse.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * FUNCTION:    AcpiPsNextParseState * * PARAMETERS:  WalkState           - Current state *              Op                  - Current parse op *              CallbackStatus      - Status from previous operation * * RETURN:      Status * * DESCRIPTION: Update the parser state based upon the return exception from *              the parser callback. * ******************************************************************************/ACPI_STATUSAcpiPsNextParseState (    ACPI_WALK_STATE         *WalkState,    ACPI_PARSE_OBJECT       *Op,    ACPI_STATUS             CallbackStatus){    ACPI_PARSE_STATE        *ParserState = &WalkState->ParserState;    ACPI_STATUS             Status = AE_CTRL_PENDING;    ACPI_FUNCTION_TRACE_PTR (PsNextParseState, Op);    switch (CallbackStatus)    {    case AE_CTRL_TERMINATE:        /*         * A control method was terminated via a RETURN statement.         * The walk of this method is complete.         */        ParserState->Aml = ParserState->AmlEnd;        Status = AE_CTRL_TERMINATE;        break;    case AE_CTRL_BREAK:        ParserState->Aml = WalkState->AmlLastWhile;        WalkState->ControlState->Common.Value = FALSE;        Status = AE_CTRL_BREAK;        break;    case AE_CTRL_CONTINUE:        ParserState->Aml = WalkState->AmlLastWhile;        Status = AE_CTRL_CONTINUE;        break;    case AE_CTRL_PENDING:        ParserState->Aml = WalkState->AmlLastWhile;        break;#if 0    case AE_CTRL_SKIP:        ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;        Status = AE_OK;        break;#endif    case AE_CTRL_TRUE:        /*         * Predicate of an IF was true, and we are at the matching ELSE.         * Just close out this package         */        ParserState->Aml = AcpiPsGetNextPackageEnd (ParserState);        Status = AE_CTRL_PENDING;        break;    case AE_CTRL_FALSE:        /*         * Either an IF/WHILE Predicate was false or we encountered a BREAK         * opcode.  In both cases, we do not execute the rest of the         * package;  We simply close out the parent (finishing the walk of         * this branch of the tree) and continue execution at the parent         * level.         */        ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;        /* In the case of a BREAK, just force a predicate (if any) to FALSE */        WalkState->ControlState->Common.Value = FALSE;        Status = AE_CTRL_END;        break;    case AE_CTRL_TRANSFER:        /* A method call (invocation) -- transfer control */        Status = AE_CTRL_TRANSFER;        WalkState->PrevOp = Op;        WalkState->MethodCallOp = Op;        WalkState->MethodCallNode = (Op->Common.Value.Arg)->Common.Node;        /* Will return value (if any) be used by the caller? */        WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState);        break;    default:        Status = CallbackStatus;        if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL)        {            Status = AE_OK;        }        break;    }    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiPsParseAml * * PARAMETERS:  WalkState       - Current state * * * RETURN:      Status * * DESCRIPTION: Parse raw AML and return a tree of ops * ******************************************************************************/ACPI_STATUSAcpiPsParseAml (    ACPI_WALK_STATE         *WalkState){    ACPI_STATUS             Status;    ACPI_THREAD_STATE       *Thread;    ACPI_THREAD_STATE       *PrevWalkList = AcpiGbl_CurrentWalkList;    ACPI_WALK_STATE         *PreviousWalkState;    ACPI_FUNCTION_TRACE (PsParseAml);    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,        "Entered with WalkState=%p Aml=%p size=%X\n",        WalkState, WalkState->ParserState.Aml,        WalkState->ParserState.AmlSize));    /* Create and initialize a new thread state */    Thread = AcpiUtCreateThreadState ();    if (!Thread)    {        AcpiDsDeleteWalkState (WalkState);        return_ACPI_STATUS (AE_NO_MEMORY);    }    WalkState->Thread = Thread;    /*     * If executing a method, the starting SyncLevel is this method's     * SyncLevel     */    if (WalkState->MethodDesc)    {        WalkState->Thread->CurrentSyncLevel = WalkState->MethodDesc->Method.SyncLevel;    }    AcpiDsPushWalkState (WalkState, Thread);    /*     * This global allows the AML debugger to get a handle to the currently     * executing control method.     */    AcpiGbl_CurrentWalkList = Thread;    /*     * Execute the walk loop as long as there is a valid Walk State.  This     * handles nested control method invocations without recursion.     */    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", WalkState));    Status = AE_OK;    while (WalkState)    {        if (ACPI_SUCCESS (Status))        {            /*             * The ParseLoop executes AML until the method terminates             * or calls another method.             */            Status = AcpiPsParseLoop (WalkState);        }        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,            "Completed one call to walk loop, %s State=%p\n",            AcpiFormatException (Status), WalkState));        if (Status == AE_CTRL_TRANSFER)        {            /*             * A method call was detected.             * Transfer control to the called control method             */            Status = AcpiDsCallControlMethod (Thread, WalkState, NULL);            if (ACPI_FAILURE (Status))            {                Status = AcpiDsMethodError (Status, WalkState);            }            /*             * If the transfer to the new method method call worked, a new walk             * state was created -- get it             */            WalkState = AcpiDsGetCurrentWalkState (Thread);            continue;        }        else if (Status == AE_CTRL_TERMINATE)        {            Status = AE_OK;        }        else if ((Status != AE_OK) && (WalkState->MethodDesc))        {            /* Either the method parse or actual execution failed */            ACPI_ERROR_METHOD ("Method parse/execution failed",                WalkState->MethodNode, NULL, Status);            /* Check for possible multi-thread reentrancy problem */            if ((Status == AE_ALREADY_EXISTS) &&                (!WalkState->MethodDesc->Method.Mutex))            {                ACPI_INFO ((AE_INFO,                    "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",                    WalkState->MethodNode->Name.Ascii));                /*                 * Method tried to create an object twice. The probable cause is                 * that the method cannot handle reentrancy.                 *                 * The method is marked NotSerialized, but it tried to create                 * a named object, causing the second thread entrance to fail.                 * Workaround this problem by marking the method permanently                 * as Serialized.                 */                WalkState->MethodDesc->Method.MethodFlags |= AML_METHOD_SERIALIZED;                WalkState->MethodDesc->Method.SyncLevel = 0;            }        }        /* We are done with this walk, move on to the parent if any */        WalkState = AcpiDsPopWalkState (Thread);        /* Reset the current scope to the beginning of scope stack */        AcpiDsScopeStackClear (WalkState);        /*         * If we just returned from the execution of a control method or if we         * encountered an error during the method parse phase, there's lots of         * cleanup to do         */        if (((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) ||            (ACPI_FAILURE (Status)))        {            AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);        }        /* Delete this walk state and all linked control states */        AcpiPsCleanupScope (&WalkState->ParserState);        PreviousWalkState = WalkState;        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,            "ReturnValue=%p, ImplicitValue=%p State=%p\n",            WalkState->ReturnDesc, WalkState->ImplicitReturnObj, WalkState));        /* Check if we have restarted a preempted walk */        WalkState = AcpiDsGetCurrentWalkState (Thread);        if (WalkState)        {            if (ACPI_SUCCESS (Status))            {                /*                 * There is another walk state, restart it.                 * If the method return value is not used by the parent,                 * The object is deleted                 */                if (!PreviousWalkState->ReturnDesc)                {                    /*                     * In slack mode execution, if there is no return value                     * we should implicitly return zero (0) as a default value.                     */                    if (AcpiGbl_EnableInterpreterSlack &&                        !PreviousWalkState->ImplicitReturnObj)                    {                        PreviousWalkState->ImplicitReturnObj =                            AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);                        if (!PreviousWalkState->ImplicitReturnObj)                        {                            return_ACPI_STATUS (AE_NO_MEMORY);                        }                        PreviousWalkState->ImplicitReturnObj->Integer.Value = 0;                    }                    /* Restart the calling control method */                    Status = AcpiDsRestartControlMethod (WalkState,                                PreviousWalkState->ImplicitReturnObj);                }                else                {                    /*                     * We have a valid return value, delete any implicit                     * return value.                     */                    AcpiDsClearImplicitReturn (PreviousWalkState);                    Status = AcpiDsRestartControlMethod (WalkState,                                PreviousWalkState->ReturnDesc);                }                if (ACPI_SUCCESS (Status))                {                    WalkState->WalkType |= ACPI_WALK_METHOD_RESTART;                }            }            else            {                /* On error, delete any return object */                AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);            }        }        /*         * Just completed a 1st-level method, save the final internal return         * value (if any)         */        else if (PreviousWalkState->CallerReturnDesc)        {            if (PreviousWalkState->ImplicitReturnObj)            {                *(PreviousWalkState->CallerReturnDesc) =                    PreviousWalkState->ImplicitReturnObj;            }            else            {                 /* NULL if no return value */                *(PreviousWalkState->CallerReturnDesc) =                    PreviousWalkState->ReturnDesc;            }        }        else        {            if (PreviousWalkState->ReturnDesc)            {                /* Caller doesn't want it, must delete it */                AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);            }            if (PreviousWalkState->ImplicitReturnObj)            {                /* Caller doesn't want it, must delete it */                AcpiUtRemoveReference (PreviousWalkState->ImplicitReturnObj);            }        }        AcpiDsDeleteWalkState (PreviousWalkState);    }    /* Normal exit */    AcpiExReleaseAllMutexes (Thread);    AcpiUtDeleteGenericState (ACPI_CAST_PTR (ACPI_GENERIC_STATE, Thread));    AcpiGbl_CurrentWalkList = PrevWalkList;    return_ACPI_STATUS (Status);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -