예제 #1
0
ACPI_STATUS
AdDisplayTables (
    char                    *Filename,
    ACPI_TABLE_HEADER       *Table)
{


    if (!AcpiGbl_ParseOpRoot)
    {
        return (AE_NOT_EXIST);
    }

    if (!AcpiGbl_DbOpt_verbose)
    {
        AdCreateTableHeader (Filename, Table);
    }

    AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);

    if (AcpiGbl_DbOpt_verbose)
    {
        AcpiOsPrintf ("\n\nTable Header:\n");
        AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
            DB_BYTE_DISPLAY, ACPI_UINT32_MAX);

        AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
        AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
            Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    }

    return (AE_OK);
}
예제 #2
0
ACPI_STATUS
AcpiDbDisassembleMethod (
    char                    *Name)
{
    ACPI_STATUS             Status;
    ACPI_PARSE_OBJECT       *Op;
    ACPI_WALK_STATE         *WalkState;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_NAMESPACE_NODE     *Method;


    Method = AcpiDbConvertToNode (Name);
    if (!Method)
    {
        return (AE_BAD_PARAMETER);
    }

    ObjDesc = Method->Object;

    Op = AcpiPsCreateScopeOp ();
    if (!Op)
    {
        return (AE_NO_MEMORY);
    }

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
    if (!WalkState)
    {
        return (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
                    ObjDesc->Method.AmlStart,
                    ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* Parse the AML */

    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
    Status = AcpiPsParseAml (WalkState);

    AcpiDmDisassemble (NULL, Op, 0);
    AcpiPsDeleteParseTree (Op);
    return (AE_OK);
}
예제 #3
0
void
AcpiDbDisassembleAml (
    char                    *Statements,
    ACPI_PARSE_OBJECT       *Op)
{
    UINT32                  NumStatements = 8;


    if (!Op)
    {
        AcpiOsPrintf ("There is no method currently executing\n");
        return;
    }

    if (Statements)
    {
        NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
    }

    AcpiDmDisassemble (NULL, Op, NumStatements);
}
예제 #4
0
파일: dbmethod.c 프로젝트: fengsi/freebsd
void
AcpiDbDisassembleAml (
    char                    *Statements,
    ACPI_PARSE_OBJECT       *Op)
{
    UINT32                  NumStatements = 8;


    if (!Op)
    {
        AcpiOsPrintf ("There is no method currently executing\n");
        return;
    }

    if (Statements)
    {
        NumStatements = strtoul (Statements, NULL, 0);
    }

#ifdef ACPI_DISASSEMBLER
    AcpiDmDisassemble (NULL, Op, NumStatements);
#endif
}
예제 #5
0
ACPI_STATUS
AcpiDbDisassembleMethod (
    char                    *Name)
{
    ACPI_STATUS             Status;
    ACPI_PARSE_OBJECT       *Op;
    ACPI_WALK_STATE         *WalkState;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_NAMESPACE_NODE     *Method;


    Method = AcpiDbConvertToNode (Name);
    if (!Method)
    {
        return (AE_BAD_PARAMETER);
    }

    if (Method->Type != ACPI_TYPE_METHOD)
    {
        ACPI_ERROR ((AE_INFO, "%s (%s): Object must be a control method",
            Name, AcpiUtGetTypeName (Method->Type)));
        return (AE_BAD_PARAMETER);
    }

    ObjDesc = Method->Object;

    Op = AcpiPsCreateScopeOp ();
    if (!Op)
    {
        return (AE_NO_MEMORY);
    }

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
    if (!WalkState)
    {
        return (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
        ObjDesc->Method.AmlStart,
        ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId);
    WalkState->OwnerId = ObjDesc->Method.OwnerId;

    /* Push start scope on scope stack and make it current */

    Status = AcpiDsScopeStackPush (Method,
        Method->Type, WalkState);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* Parse the entire method AML including deferred operators */

    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;

    Status = AcpiPsParseAml (WalkState);
    (void) AcpiDmParseDeferredOps (Op);

    /* Now we can disassemble the method */

    AcpiGbl_DbOpt_verbose = FALSE;
    AcpiDmDisassemble (NULL, Op, 0);
    AcpiGbl_DbOpt_verbose = TRUE;

    AcpiPsDeleteParseTree (Op);

    /* Method cleanup */

    AcpiNsDeleteNamespaceSubtree (Method);
    AcpiNsDeleteNamespaceByOwner (ObjDesc->Method.OwnerId);
    AcpiUtReleaseOwnerId (&ObjDesc->Method.OwnerId);
    return (AE_OK);
}
예제 #6
0
void
AcpiDmDumpMethodInfo (
    ACPI_STATUS             Status,
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *Next;
    ACPI_THREAD_STATE       *Thread;
    ACPI_WALK_STATE         *NextWalkState;
    ACPI_NAMESPACE_NODE     *PreviousMethod = NULL;


    /* Ignore control codes, they are not errors */

    if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
    {
        return;
    }

    /* We may be executing a deferred opcode */

    if (WalkState->DeferredNode)
    {
        AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
        return;
    }

    /*
     * If there is no Thread, we are not actually executing a method.
     * This can happen when the iASL compiler calls the interpreter
     * to perform constant folding.
     */
    Thread = WalkState->Thread;
    if (!Thread)
    {
        return;
    }

    /* Display exception and method name */

    AcpiOsPrintf ("\n**** Exception %s during execution of method ",
        AcpiFormatException (Status));
    AcpiNsPrintNodePathname (WalkState->MethodNode, NULL);

    /* Display stack of executing methods */

    AcpiOsPrintf ("\n\nMethod Execution Stack:\n");
    NextWalkState = Thread->WalkStateList;

    /* Walk list of linked walk states */

    while (NextWalkState)
    {
        AcpiOsPrintf ("    Method [%4.4s] executing: ",
                AcpiUtGetNodeName (NextWalkState->MethodNode));

        /* First method is the currently executing method */

        if (NextWalkState == WalkState)
        {
            if (Op)
            {
                /* Display currently executing ASL statement */

                Next = Op->Common.Next;
                Op->Common.Next = NULL;

                AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
                Op->Common.Next = Next;
            }
        }
        else
        {
            /*
             * This method has called another method
             * NOTE: the method call parse subtree is already deleted at this
             * point, so we cannot disassemble the method invocation.
             */
            AcpiOsPrintf ("Call to method ");
            AcpiNsPrintNodePathname (PreviousMethod, NULL);
        }

        PreviousMethod = NextWalkState->MethodNode;
        NextWalkState = NextWalkState->Next;
        AcpiOsPrintf ("\n");
    }

    /* Display the method locals and arguments */

    AcpiOsPrintf ("\n");
    AcpiDmDisplayLocals (WalkState);
    AcpiOsPrintf ("\n");
    AcpiDmDisplayArguments (WalkState);
    AcpiOsPrintf ("\n");
}
예제 #7
0
ACPI_STATUS
AcpiDbSingleStep (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  OpcodeClass)
{
    ACPI_PARSE_OBJECT       *Next;
    ACPI_STATUS             Status = AE_OK;
    UINT32                  OriginalDebugLevel;
    ACPI_PARSE_OBJECT       *DisplayOp;
    ACPI_PARSE_OBJECT       *ParentOp;


    ACPI_FUNCTION_ENTRY ();


    /* Check the abort flag */

    if (AcpiGbl_AbortMethod)
    {
        AcpiGbl_AbortMethod = FALSE;
        return (AE_ABORT_METHOD);
    }

    /* Check for single-step breakpoint */

    if (WalkState->MethodBreakpoint &&
            (WalkState->MethodBreakpoint <= Op->Common.AmlOffset))
    {
        /* Check if the breakpoint has been reached or passed */
        /* Hit the breakpoint, resume single step, reset breakpoint */

        AcpiOsPrintf ("***Break*** at AML offset %X\n", Op->Common.AmlOffset);
        AcpiGbl_CmSingleStep = TRUE;
        AcpiGbl_StepToNextCall = FALSE;
        WalkState->MethodBreakpoint = 0;
    }

    /* Check for user breakpoint (Must be on exact Aml offset) */

    else if (WalkState->UserBreakpoint &&
             (WalkState->UserBreakpoint == Op->Common.AmlOffset))
    {
        AcpiOsPrintf ("***UserBreakpoint*** at AML offset %X\n",
                      Op->Common.AmlOffset);
        AcpiGbl_CmSingleStep = TRUE;
        AcpiGbl_StepToNextCall = FALSE;
        WalkState->MethodBreakpoint = 0;
    }

    /*
     * Check if this is an opcode that we are interested in --
     * namely, opcodes that have arguments
     */
    if (Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
    {
        return (AE_OK);
    }

    switch (OpcodeClass)
    {
    case AML_CLASS_UNKNOWN:
    case AML_CLASS_ARGUMENT:    /* constants, literals, etc.  do nothing */
        return (AE_OK);

    default:
        /* All other opcodes -- continue */
        break;
    }

    /*
     * Under certain debug conditions, display this opcode and its operands
     */
    if ((AcpiGbl_DbOutputToFile)            ||
            (AcpiGbl_CmSingleStep)              ||
            (AcpiDbgLevel & ACPI_LV_PARSE))
    {
        if ((AcpiGbl_DbOutputToFile)        ||
                (AcpiDbgLevel & ACPI_LV_PARSE))
        {
            AcpiOsPrintf ("\n[AmlDebug] Next AML Opcode to execute:\n");
        }

        /*
         * Display this op (and only this op - zero out the NEXT field
         * temporarily, and disable parser trace output for the duration of
         * the display because we don't want the extraneous debug output)
         */
        OriginalDebugLevel = AcpiDbgLevel;
        AcpiDbgLevel &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
        Next = Op->Common.Next;
        Op->Common.Next = NULL;


        DisplayOp = Op;
        ParentOp = Op->Common.Parent;
        if (ParentOp)
        {
            if ((WalkState->ControlState) &&
                    (WalkState->ControlState->Common.State ==
                     ACPI_CONTROL_PREDICATE_EXECUTING))
            {
                /*
                 * We are executing the predicate of an IF or WHILE statement
                 * Search upwards for the containing IF or WHILE so that the
                 * entire predicate can be displayed.
                 */
                while (ParentOp)
                {
                    if ((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
                            (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
                    {
                        DisplayOp = ParentOp;
                        break;
                    }
                    ParentOp = ParentOp->Common.Parent;
                }
            }
            else
            {
                while (ParentOp)
                {
                    if ((ParentOp->Common.AmlOpcode == AML_IF_OP)     ||
                            (ParentOp->Common.AmlOpcode == AML_ELSE_OP)   ||
                            (ParentOp->Common.AmlOpcode == AML_SCOPE_OP)  ||
                            (ParentOp->Common.AmlOpcode == AML_METHOD_OP) ||
                            (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
                    {
                        break;
                    }
                    DisplayOp = ParentOp;
                    ParentOp = ParentOp->Common.Parent;
                }
            }
        }

        /* Now we can display it */

#ifdef ACPI_DISASSEMBLER
        AcpiDmDisassemble (WalkState, DisplayOp, ACPI_UINT32_MAX);
#endif

        if ((Op->Common.AmlOpcode == AML_IF_OP) ||
                (Op->Common.AmlOpcode == AML_WHILE_OP))
        {
            if (WalkState->ControlState->Common.Value)
            {
                AcpiOsPrintf ("Predicate = [True], IF block was executed\n");
            }
            else
            {
                AcpiOsPrintf ("Predicate = [False], Skipping IF block\n");
            }
        }
        else if (Op->Common.AmlOpcode == AML_ELSE_OP)
        {
            AcpiOsPrintf ("Predicate = [False], ELSE block was executed\n");
        }

        /* Restore everything */

        Op->Common.Next = Next;
        AcpiOsPrintf ("\n");
        if ((AcpiGbl_DbOutputToFile)        ||
                (AcpiDbgLevel & ACPI_LV_PARSE))
        {
            AcpiOsPrintf ("\n");
        }
        AcpiDbgLevel = OriginalDebugLevel;
    }

    /* If we are not single stepping, just continue executing the method */

    if (!AcpiGbl_CmSingleStep)
    {
        return (AE_OK);
    }

    /*
     * If we are executing a step-to-call command,
     * Check if this is a method call.
     */
    if (AcpiGbl_StepToNextCall)
    {
        if (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP)
        {
            /* Not a method call, just keep executing */

            return (AE_OK);
        }

        /* Found a method call, stop executing */

        AcpiGbl_StepToNextCall = FALSE;
    }

    /*
     * If the next opcode is a method call, we will "step over" it
     * by default.
     */
    if (Op->Common.AmlOpcode == AML_INT_METHODCALL_OP)
    {
        /* Force no more single stepping while executing called method */

        AcpiGbl_CmSingleStep = FALSE;

        /*
         * Set the breakpoint on/before the call, it will stop execution
         * as soon as we return
         */
        WalkState->MethodBreakpoint = 1;  /* Must be non-zero! */
    }


    Status = AcpiDbStartCommand (WalkState, Op);

    /* User commands complete, continue execution of the interrupted method */

    return (Status);
}
예제 #8
0
void
AcpiDmDumpMethodInfo (
    ACPI_STATUS             Status,
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *Next;
    ACPI_THREAD_STATE       *Thread;
    ACPI_WALK_STATE         *NextWalkState;
    ACPI_NAMESPACE_NODE     *PreviousMethod = NULL;


    /* Ignore control codes, they are not errors */

    if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
    {
        return;
    }

    /* Display exception and method name */

    AcpiOsPrintf ("\n**** Exception %s during execution of method ",
        AcpiFormatException (Status));
    AcpiNsPrintNodePathname (WalkState->MethodNode, NULL);

    /* Display stack of executing methods */

    AcpiOsPrintf ("\n\nMethod Execution Stack:\n");
    Thread = WalkState->Thread;
    NextWalkState = Thread->WalkStateList;

    /* Walk list of linked walk states */

    while (NextWalkState)
    {
        AcpiOsPrintf ("    Method [%4.4s] executing: ",
                NextWalkState->MethodNode->Name.Ascii);

        /* First method is the currently executing method */

        if (NextWalkState == WalkState)
        {
            /* Display currently executing ASL statement */

            Next = Op->Common.Next;
            Op->Common.Next = NULL;

            AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
            Op->Common.Next = Next;
        }
        else
        {
            /*
             * This method has called another method
             * NOTE: the method call parse subtree is already deleted at this
             * point, so we cannot disassemble the method invocation.
             */
            AcpiOsPrintf ("Call to method ");
            AcpiNsPrintNodePathname (PreviousMethod, NULL);
        }

        PreviousMethod = NextWalkState->MethodNode;
        NextWalkState = NextWalkState->Next;
        AcpiOsPrintf ("\n");
    }

    /* Display the method locals and arguments */

    AcpiOsPrintf ("\n");
    AcpiDmDisplayLocals (WalkState);
    AcpiOsPrintf ("\n");
    AcpiDmDisplayArguments (WalkState);
    AcpiOsPrintf ("\n");
}