Esempio n. 1
0
ACPI_STATUS
AcpiDsAutoSerializeMethod (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_OPERAND_OBJECT     *ObjDesc)
{
    ACPI_STATUS             Status;
    ACPI_PARSE_OBJECT       *Op = NULL;
    ACPI_WALK_STATE         *WalkState;


    ACPI_FUNCTION_TRACE_PTR (DsAutoSerializeMethod, Node);


    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
        "Method auto-serialization parse [%4.4s] %p\n",
        AcpiUtGetNodeName (Node), Node));

    /* Create/Init a root op for the method parse tree */

    Op = AcpiPsAllocOp (AML_METHOD_OP);
    if (!Op)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    AcpiPsSetName (Op, Node->Name.Integer);
    Op->Common.Node = Node;

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (Node->OwnerId, NULL, NULL, NULL);
    if (!WalkState)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, Node, ObjDesc->Method.AmlStart,
                ObjDesc->Method.AmlLength, NULL, 0);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        return_ACPI_STATUS (Status);
    }

    WalkState->DescendingCallback = AcpiDsDetectNamedOpcodes;

    /* Parse the method, scan for creation of named objects */

    Status = AcpiPsParseAml (WalkState);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    AcpiPsDeleteParseTree (Op);
    return_ACPI_STATUS (Status);
}
Esempio n. 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);
}
Esempio n. 3
0
ACPI_STATUS
AcpiNsOneCompleteParse (
    UINT32                  PassNumber,
    ACPI_TABLE_DESC         *TableDesc)
{
    ACPI_PARSE_OBJECT       *ParseRoot;
    ACPI_STATUS             Status;
    ACPI_WALK_STATE         *WalkState;


    ACPI_FUNCTION_TRACE ("NsOneCompleteParse");


    /* Create and init a Root Node */

    ParseRoot = AcpiPsCreateScopeOp ();
    if (!ParseRoot)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }


    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT,
                                    NULL, NULL, NULL);
    if (!WalkState)
    {
        AcpiPsFreeOp (ParseRoot);
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL, TableDesc->AmlStart,
                    TableDesc->AmlLength, NULL, NULL, PassNumber);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        return_ACPI_STATUS (Status);
    }

    /* Parse the AML */

    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", PassNumber));
    Status = AcpiPsParseAml (WalkState);

    AcpiPsDeleteParseTree (ParseRoot);
    return_ACPI_STATUS (Status);
}
Esempio n. 4
0
ACPI_STATUS
AdAmlDisassemble (
    BOOLEAN                 OutToFile,
    char                    *Filename,
    char                    *Prefix,
    char                    **OutFilename,
    BOOLEAN                 GetAllTables)
{
    ACPI_STATUS             Status;
    char                    *DisasmFilename = NULL;
    char                    *ExternalFilename;
    ACPI_EXTERNAL_FILE      *ExternalFileList = AcpiGbl_ExternalFileList;
    FILE                    *File = NULL;
    ACPI_TABLE_HEADER       *Table = NULL;
    ACPI_TABLE_HEADER       *ExternalTable;
    ACPI_OWNER_ID           OwnerId;


    /*
     * Input: AML code from either a file or via GetTables (memory or
     * registry)
     */
    if (Filename)
    {
        Status = AcpiDbGetTableFromFile (Filename, &Table);
        if (ACPI_FAILURE (Status))
        {
            return (Status);
        }

        /*
         * External filenames separated by commas
         * Example: iasl -e file1,file2,file3 -d xxx.aml
         */
        while (ExternalFileList)
        {
            ExternalFilename = ExternalFileList->Path;
            if (!ACPI_STRCMP (ExternalFilename, Filename))
            {
                /* Next external file */

                ExternalFileList = ExternalFileList->Next;
                continue;
            }

            Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable);
            if (ACPI_FAILURE (Status))
            {
                return (Status);
            }

            /* Load external table for symbol resolution */

            if (ExternalTable)
            {
                Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
                if (ACPI_FAILURE (Status))
                {
                    AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
                        AcpiFormatException (Status));
                    return (Status);
                }

                /*
                 * Load namespace from names created within control methods
                 * Set owner id of nodes in external table
                 */
                AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
                    AcpiGbl_RootNode, OwnerId);
                AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
            }

            /* Next external file */

            ExternalFileList = ExternalFileList->Next;
        }

        /* Clear external list generated by Scope in external tables */

        if (AcpiGbl_ExternalFileList)
        {
            AcpiDmClearExternalList ();
        }
    }
    else
    {
        Status = AdGetLocalTables (Filename, GetAllTables);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not get ACPI tables, %s\n",
                AcpiFormatException (Status));
            return (Status);
        }

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

        /* Obtained the local tables, just disassemble the DSDT */

        Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not get DSDT, %s\n",
                AcpiFormatException (Status));
            return (Status);
        }

        AcpiOsPrintf ("\nDisassembly of DSDT\n");
        Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
    }

    /*
     * Output: ASL code. Redirect to a file if requested
     */
    if (OutToFile)
    {
        /* Create/Open a disassembly output file */

        DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
        if (!OutFilename)
        {
            fprintf (stderr, "Could not generate output filename\n");
            Status = AE_ERROR;
            goto Cleanup;
        }

        File = fopen (DisasmFilename, "w+");
        if (!File)
        {
            fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
            Status = AE_ERROR;
            goto Cleanup;
        }

        AcpiOsRedirectOutput (File);
    }

    *OutFilename = DisasmFilename;

    if (!AcpiUtIsAmlTable (Table))
    {
        AdDisassemblerHeader (Filename);
        AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
            Table->Signature);
        AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  "
            "FieldName : FieldValue\n */\n\n");

        AcpiDmDumpDataTable (Table);
        fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
            Table->Signature);
        fprintf (stderr, "Formatted output:  %s - %u bytes\n",
            DisasmFilename, AdGetFileSize (File));
    }
    else
    {
        /* Always parse the tables, only option is what to display */

        Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
                AcpiFormatException (Status));
            goto Cleanup;
        }

        if (AslCompilerdebug)
        {
            AcpiOsPrintf ("/**** Before second load\n");

            NsSetupNamespaceListing (File);
            NsDisplayNamespace ();
            AcpiOsPrintf ("*****/\n");
        }

        /* Load namespace from names created within control methods */

        AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
            AcpiGbl_RootNode, OwnerId);

        /*
         * Cross reference the namespace here, in order to
         * generate External() statements
         */
        AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
            AcpiGbl_RootNode, OwnerId);

        if (AslCompilerdebug)
        {
            AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
        }

        /* Find possible calls to external control methods */

        AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);

        /*
         * If we found any external control methods, we must reparse
         * the entire tree with the new information (namely, the
         * number of arguments per method)
         */
        if (AcpiDmGetExternalMethodCount ())
        {
            fprintf (stderr,
                "\nFound %u external control methods, "
                "reparsing with new information\n",
                AcpiDmGetExternalMethodCount ());

            /* Reparse, rebuild namespace. no need to xref namespace */

            AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
            AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);

            AcpiGbl_RootNode                    = NULL;
            AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
            AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
            AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
            AcpiGbl_RootNodeStruct.Parent       = NULL;
            AcpiGbl_RootNodeStruct.Child        = NULL;
            AcpiGbl_RootNodeStruct.Peer         = NULL;
            AcpiGbl_RootNodeStruct.Object       = NULL;
            AcpiGbl_RootNodeStruct.Flags        = 0;

            Status = AcpiNsRootInitialize ();
            AcpiDmAddExternalsToNamespace ();

            /* Parse the table again. No need to reload it, however */

            Status = AdParseTable (Table, NULL, FALSE, FALSE);
            if (ACPI_FAILURE (Status))
            {
                AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
                    AcpiFormatException (Status));
                goto Cleanup;
            }

            if (AslCompilerdebug)
            {
                AcpiOsPrintf ("/**** After second load and resource conversion\n");
                NsSetupNamespaceListing (File);
                NsDisplayNamespace ();
                AcpiOsPrintf ("*****/\n");

                AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
            }
        }

        /*
         * Now that the namespace is finalized, we can perform namespace
         * transforms.
         *
         * 1) Convert fixed-offset references to resource descriptors
         *    to symbolic references (Note: modifies namespace)
         */
        AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);

        /* Optional displays */

        if (AcpiGbl_DbOpt_disasm)
        {
            /* This is the real disassembly */

            AdDisplayTables (Filename, Table);

            /* Dump hex table if requested (-vt) */

            AcpiDmDumpDataTable (Table);

            fprintf (stderr, "Disassembly completed\n");
            fprintf (stderr, "ASL Output:    %s - %u bytes\n",
                DisasmFilename, AdGetFileSize (File));
        }
    }

Cleanup:

    if (Table && !AcpiUtIsAmlTable (Table))
    {
        ACPI_FREE (Table);
    }

    if (OutToFile && File)
    {
        if (AslCompilerdebug) /* Display final namespace, with transforms */
        {
            NsSetupNamespaceListing (File);
            NsDisplayNamespace ();
        }

        fclose (File);
        AcpiOsRedirectOutput (stdout);
    }

    AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    AcpiGbl_ParseOpRoot = NULL;
    return (Status);
}
Esempio n. 5
0
static ACPI_STATUS
AcpiDsExecuteArguments (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_NAMESPACE_NODE     *ScopeNode,
    UINT32                  AmlLength,
    UINT8                   *AmlStart)
{
    ACPI_STATUS             Status;
    ACPI_PARSE_OBJECT       *Op;
    ACPI_WALK_STATE         *WalkState;


    ACPI_FUNCTION_TRACE (DsExecuteArguments);


    /*
     * Allocate a new parser op to be the root of the parsed tree
     */
    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
    if (!Op)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Save the Node for use in AcpiPsParseAml */

    Op->Common.Node = ScopeNode;

    /* Create and initialize a new parser state */

    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    if (!WalkState)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
                    AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        goto Cleanup;
    }

    /* Mark this parse as a deferred opcode */

    WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
    WalkState->DeferredNode = Node;

    /* Pass1: Parse the entire declaration */

    Status = AcpiPsParseAml (WalkState);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Get and init the Op created above */

    Op->Common.Node = Node;
    AcpiPsDeleteParseTree (Op);

    /* Evaluate the deferred arguments */

    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
    if (!Op)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Op->Common.Node = ScopeNode;

    /* Create and initialize a new parser state */

    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    if (!WalkState)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /* Execute the opcode and arguments */

    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
                    AmlLength, NULL, ACPI_IMODE_EXECUTE);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        goto Cleanup;
    }

    /* Mark this execution as a deferred opcode */

    WalkState->DeferredNode = Node;
    Status = AcpiPsParseAml (WalkState);

Cleanup:
    AcpiPsDeleteParseTree (Op);
    return_ACPI_STATUS (Status);
}
Esempio n. 6
0
ACPI_STATUS
AcpiPsxExecute (
    ACPI_NAMESPACE_NODE     *MethodNode,
    ACPI_OPERAND_OBJECT     **Params,
    ACPI_OPERAND_OBJECT     **ReturnObjDesc)
{
    ACPI_STATUS             Status;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    UINT32                  i;
    ACPI_PARSE_OBJECT       *Op;
    ACPI_WALK_STATE         *WalkState;


    ACPI_FUNCTION_TRACE ("PsxExecute");


    /* Validate the Node and get the attached object */

    if (!MethodNode)
    {
        return_ACPI_STATUS (AE_NULL_ENTRY);
    }

    ObjDesc = AcpiNsGetAttachedObject (MethodNode);
    if (!ObjDesc)
    {
        return_ACPI_STATUS (AE_NULL_OBJECT);
    }

    /* Init for new method, wait on concurrency semaphore */

    Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc, NULL);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    if (Params)
    {
        /*
         * The caller "owns" the parameters, so give each one an extra
         * reference
         */
        for (i = 0; Params[i]; i++)
        {
            AcpiUtAddReference (Params[i]);
        }
    }

    /*
     * 1) Perform the first pass parse of the method to enter any
     * named objects that it creates into the namespace
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
        "**** Begin Method Parse **** Entry=%p obj=%p\n",
        MethodNode, ObjDesc));

    /* Create and init a Root Node */

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

    /*
     * Get a new OwnerId for objects created by this method.  Namespace
     * objects (such as Operation Regions) can be created during the
     * first pass parse.
     */
    ObjDesc->Method.OwningId = AcpiUtAllocateOwnerId (ACPI_OWNER_TYPE_METHOD);

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId,
                                    NULL, NULL, NULL);
    if (!WalkState)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, MethodNode, ObjDesc->Method.AmlStart,
                    ObjDesc->Method.AmlLength, NULL, NULL, 1);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        return_ACPI_STATUS (Status);
    }

    /* Parse the AML */

    Status = AcpiPsParseAml (WalkState);
    AcpiPsDeleteParseTree (Op);

    /*
     * 2) Execute the method.  Performs second pass parse simultaneously
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
        "**** Begin Method Execution **** Entry=%p obj=%p\n",
        MethodNode, ObjDesc));

    /* Create and init a Root Node */

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

    /* Init new op with the method name and pointer back to the NS node */

    AcpiPsSetName (Op, MethodNode->Name.Integer);
    Op->Common.Node = MethodNode;

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL);
    if (!WalkState)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, MethodNode, ObjDesc->Method.AmlStart,
                    ObjDesc->Method.AmlLength, Params, ReturnObjDesc, 3);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        return_ACPI_STATUS (Status);
    }

    /*
     * The walk of the parse tree is where we actually execute the method
     */
    Status = AcpiPsParseAml (WalkState);
    AcpiPsDeleteParseTree (Op);

    if (Params)
    {
        /* Take away the extra reference that we gave the parameters above */

        for (i = 0; Params[i]; i++)
        {
            /* Ignore errors, just do them all */

            (void) AcpiUtUpdateObjectReference (Params[i], REF_DECREMENT);
        }
    }

    /*
     * If the method has returned an object, signal this to the caller with
     * a control exception code
     */
    if (*ReturnObjDesc)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
            *ReturnObjDesc));
        ACPI_DUMP_STACK_ENTRY (*ReturnObjDesc);

        Status = AE_CTRL_RETURN_VALUE;
    }

    return_ACPI_STATUS (Status);
}
Esempio n. 7
0
ACPI_STATUS
AcpiNsOneCompleteParse (
    ACPI_NATIVE_UINT        PassNumber,
    ACPI_NATIVE_UINT        TableIndex,
    ACPI_NAMESPACE_NODE     *StartNode)
{
    ACPI_PARSE_OBJECT       *ParseRoot;
    ACPI_STATUS             Status;
    ACPI_NATIVE_UINT        AmlLength;
    UINT8                   *AmlStart;
    ACPI_WALK_STATE         *WalkState;
    ACPI_TABLE_HEADER       *Table;
    ACPI_OWNER_ID           OwnerId;


    ACPI_FUNCTION_TRACE (NsOneCompleteParse);


    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Create and init a Root Node */

    ParseRoot = AcpiPsCreateScopeOp ();
    if (!ParseRoot)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (OwnerId, NULL, NULL, NULL);
    if (!WalkState)
    {
        AcpiPsFreeOp (ParseRoot);
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiGetTableByIndex (TableIndex, &Table);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        AcpiPsFreeOp (ParseRoot);
        return_ACPI_STATUS (Status);
    }

    /* Table must consist of at least a complete header */

    if (Table->Length < sizeof (ACPI_TABLE_HEADER))
    {
        Status = AE_BAD_HEADER;
    }
    else
    {
        AmlStart = (UINT8 *) Table + sizeof (ACPI_TABLE_HEADER);
        AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
        Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL,
                    AmlStart, (UINT32) AmlLength, NULL, (UINT8) PassNumber);
    }

    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        goto Cleanup;
    }

    /* StartNode is the default location to load the table  */

    if (StartNode && StartNode != AcpiGbl_RootNode)
    {
        Status = AcpiDsScopeStackPush (StartNode, ACPI_TYPE_METHOD, WalkState);
        if (ACPI_FAILURE (Status))
        {
            AcpiDsDeleteWalkState (WalkState);
            goto Cleanup;
        }
    }

    /* Parse the AML */

    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", (UINT32) PassNumber));
    Status = AcpiPsParseAml (WalkState);

Cleanup:
    AcpiPsDeleteParseTree (ParseRoot);
    return_ACPI_STATUS (Status);
}
Esempio n. 8
0
static BOOLEAN
AcpiPsCompleteThisOp (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
#ifndef PARSER_ONLY
    ACPI_PARSE_OBJECT       *Prev;
    ACPI_PARSE_OBJECT       *Next;
    const ACPI_OPCODE_INFO  *OpInfo;
    const ACPI_OPCODE_INFO  *ParentInfo;
    UINT32                  OpcodeClass;
    ACPI_PARSE_OBJECT       *ReplacementOp = NULL;


    FUNCTION_TRACE_PTR ("PsCompleteThisOp", Op);


    OpInfo      = AcpiPsGetOpcodeInfo (Op->Opcode);
    OpcodeClass = ACPI_GET_OP_CLASS (OpInfo);


    /* Delete this op and the subtree below it if asked to */

    if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
        (OpcodeClass != OPTYPE_CONSTANT)        &&
        (OpcodeClass != OPTYPE_LITERAL)         &&
        (OpcodeClass != OPTYPE_LOCAL_VARIABLE)  &&
        (OpcodeClass != OPTYPE_METHOD_ARGUMENT) &&
        (OpcodeClass != OPTYPE_DATA_TERM)       &&
        (Op->Opcode  != AML_INT_NAMEPATH_OP))
    {
        /* Make sure that we only delete this subtree */

        if (Op->Parent)
        {
            /*
             * Check if we need to replace the operator and its subtree
             * with a return value op (placeholder op)
             */
            ParentInfo  = AcpiPsGetOpcodeInfo (Op->Parent->Opcode);

            switch (ACPI_GET_OP_CLASS (ParentInfo))
            {
            case OPTYPE_CONTROL:        /* IF, ELSE, WHILE only */
                break;

            case OPTYPE_NAMED_OBJECT:   /* Scope, method, etc. */

                /*
                 * These opcodes contain TermArg operands.  The current
                 * op must be replace by a placeholder return op
                 */
                if ((Op->Parent->Opcode == AML_REGION_OP)               ||
                    (Op->Parent->Opcode == AML_CREATE_FIELD_OP)         ||
                    (Op->Parent->Opcode == AML_CREATE_BIT_FIELD_OP)     ||
                    (Op->Parent->Opcode == AML_CREATE_BYTE_FIELD_OP)    ||
                    (Op->Parent->Opcode == AML_CREATE_WORD_FIELD_OP)    ||
                    (Op->Parent->Opcode == AML_CREATE_DWORD_FIELD_OP)   ||
                    (Op->Parent->Opcode == AML_CREATE_QWORD_FIELD_OP))
                {
                    ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
                    if (!ReplacementOp)
                    {
                        return_VALUE (FALSE);
                    }
                }

                break;

            default:
                ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
                if (!ReplacementOp)
                {
                    return_VALUE (FALSE);
                }
            }

            /* We must unlink this op from the parent tree */

            Prev = Op->Parent->Value.Arg;
            if (Prev == Op)
            {
                /* This op is the first in the list */

                if (ReplacementOp)
                {
                    ReplacementOp->Parent    = Op->Parent;
                    ReplacementOp->Value.Arg = NULL;
                    Op->Parent->Value.Arg    = ReplacementOp;
                    ReplacementOp->Next      = Op->Next;
                }
                else
                {
                    Op->Parent->Value.Arg    = Op->Next;
                }
            }

            /* Search the parent list */

            else while (Prev)
            {
                /* Traverse all siblings in the parent's argument list */

                Next = Prev->Next;
                if (Next == Op)
                {
                    if (ReplacementOp)
                    {
                        ReplacementOp->Parent = Op->Parent;
                        ReplacementOp->Value.Arg = NULL;
                        Prev->Next = ReplacementOp;
                        ReplacementOp->Next = Op->Next;
                        Next = NULL;
                    }
                    else
                    {
                        Prev->Next = Op->Next;
                        Next = NULL;
                    }
                }

                Prev = Next;
            }

        }

        /* Now we can actually delete the subtree rooted at op */

        AcpiPsDeleteParseTree (Op);

        return_VALUE (TRUE);
    }

    return_VALUE (FALSE);

#else
    return (FALSE);
#endif
}
Esempio n. 9
0
static ACPI_STATUS
AdReparseOneTable (
    ACPI_TABLE_HEADER       *Table,
    FILE                    *File,
    ACPI_OWNER_ID           OwnerId)
{
    ACPI_STATUS             Status;


    fprintf (stderr,
        "\nFound %u external control methods, "
        "reparsing with new information\n",
        AcpiDmGetExternalMethodCount ());

    /* Reparse, rebuild namespace */

    AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    AcpiGbl_ParseOpRoot = NULL;
    AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);

    AcpiGbl_RootNode                    = NULL;
    AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
    AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
    AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
    AcpiGbl_RootNodeStruct.Parent       = NULL;
    AcpiGbl_RootNodeStruct.Child        = NULL;
    AcpiGbl_RootNodeStruct.Peer         = NULL;
    AcpiGbl_RootNodeStruct.Object       = NULL;
    AcpiGbl_RootNodeStruct.Flags        = 0;

    Status = AcpiNsRootInitialize ();
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* New namespace, add the external definitions first */

    AcpiDmAddExternalsToNamespace ();

    /* Parse the table again. No need to reload it, however */

    Status = AdParseTable (Table, NULL, FALSE, FALSE);
    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
            AcpiFormatException (Status));
        return (Status);
    }

    /* Cross reference the namespace again */

    AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
        AcpiGbl_RootNode, OwnerId);

    AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
        AcpiGbl_RootNode, OwnerId);

    /* Debug output - namespace and parse tree */

    if (AslCompilerdebug)
    {
        AcpiOsPrintf ("/**** After second load and resource conversion\n");
        if (File)
        {
            NsSetupNamespaceListing (File);
            NsDisplayNamespace ();
        }

        AcpiOsPrintf ("*****/\n");
        AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
    }

    return (AE_OK);
}
Esempio n. 10
0
ACPI_STATUS
AdAmlDisassemble (
    BOOLEAN                 OutToFile,
    char                    *Filename,
    char                    *Prefix,
    char                    **OutFilename)
{
    ACPI_STATUS             Status;
    char                    *DisasmFilename = NULL;
    FILE                    *File = NULL;
    ACPI_TABLE_HEADER       *Table = NULL;
    ACPI_NEW_TABLE_DESC     *ListHead = NULL;


    /*
     * Input: AML code from either a file or via GetTables (memory or
     * registry)
     */
    if (Filename)
    {
        /* Get the list of all AML tables in the file */

        Status = AcGetAllTablesFromFile (Filename,
            ACPI_GET_ALL_TABLES, &ListHead);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not get ACPI tables from %s, %s\n",
                Filename, AcpiFormatException (Status));
            return (Status);
        }

        /* Process any user-specified files for external objects */

        Status = AdDoExternalFileList (Filename);
        if (ACPI_FAILURE (Status))
        {
            return (Status);
        }
    }
    else
    {
        Status = AdGetLocalTables ();
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not get ACPI tables, %s\n",
                AcpiFormatException (Status));
            return (Status);
        }

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

        /* Obtained the local tables, just disassemble the DSDT */

        Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not get DSDT, %s\n",
                AcpiFormatException (Status));
            return (Status);
        }

        AcpiOsPrintf ("\nDisassembly of DSDT\n");
        Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
    }

    /*
     * Output: ASL code. Redirect to a file if requested
     */
    if (OutToFile)
    {
        /* Create/Open a disassembly output file */

        DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
        if (!DisasmFilename)
        {
            fprintf (stderr, "Could not generate output filename\n");
            Status = AE_ERROR;
            goto Cleanup;
        }

        File = fopen (DisasmFilename, "w+");
        if (!File)
        {
            fprintf (stderr, "Could not open output file %s\n",
                DisasmFilename);
            Status = AE_ERROR;
            goto Cleanup;
        }

        AcpiOsRedirectOutput (File);
    }

    *OutFilename = DisasmFilename;

    /* Disassemble all AML tables within the file */

    while (ListHead)
    {
        Status = AdDisassembleOneTable (ListHead->Table,
            File, Filename, DisasmFilename);
        if (ACPI_FAILURE (Status))
        {
            break;
        }

        ListHead = ListHead->Next;
    }

Cleanup:

    if (Table &&
        !AcpiGbl_ForceAmlDisassembly &&
        !AcpiUtIsAmlTable (Table))
    {
        ACPI_FREE (Table);
    }

    if (File)
    {
        fclose (File);
        AcpiOsRedirectOutput (stdout);
    }

    AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    AcpiGbl_ParseOpRoot = NULL;
    return (Status);
}
Esempio n. 11
0
ACPI_STATUS
AcpiPsExecuteTable (
    ACPI_EVALUATE_INFO      *Info)
{
    ACPI_STATUS             Status;
    ACPI_PARSE_OBJECT       *Op = NULL;
    ACPI_WALK_STATE         *WalkState = NULL;


    ACPI_FUNCTION_TRACE (PsExecuteTable);


    /* Create and init a Root Node */

    Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart);
    if (!Op)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (
        Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL);
    if (!WalkState)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node,
        Info->ObjDesc->Method.AmlStart,
        Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
    {
        WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL;
    }

    /* Info->Node is the default location to load the table  */

    if (Info->Node && Info->Node != AcpiGbl_RootNode)
    {
        Status = AcpiDsScopeStackPush (
            Info->Node, ACPI_TYPE_METHOD, WalkState);
        if (ACPI_FAILURE (Status))
        {
            goto Cleanup;
        }
    }

    /*
     * Parse the AML, WalkState will be deleted by ParseAml
     */
    AcpiExEnterInterpreter ();
    Status = AcpiPsParseAml (WalkState);
    AcpiExExitInterpreter ();
    WalkState = NULL;

Cleanup:
    if (WalkState)
    {
        AcpiDsDeleteWalkState (WalkState);
    }
    if (Op)
    {
        AcpiPsDeleteParseTree (Op);
    }
    return_ACPI_STATUS (Status);
}
Esempio n. 12
0
ACPI_STATUS
AcpiPsExecuteMethod (
    ACPI_EVALUATE_INFO      *Info)
{
    ACPI_STATUS             Status;
    ACPI_PARSE_OBJECT       *Op;
    ACPI_WALK_STATE         *WalkState;


    ACPI_FUNCTION_TRACE (PsExecuteMethod);


    /* Quick validation of DSDT header */

    AcpiTbCheckDsdtHeader ();

    /* Validate the Info and method Node */

    if (!Info || !Info->Node)
    {
        return_ACPI_STATUS (AE_NULL_ENTRY);
    }

    /* Init for new method, wait on concurrency semaphore */

    Status = AcpiDsBeginMethodExecution (Info->Node, Info->ObjDesc, NULL);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * The caller "owns" the parameters, so give each one an extra reference
     */
    AcpiPsUpdateParameterList (Info, REF_INCREMENT);

    /*
     * Execute the method. Performs parse simultaneously
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
        "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
        Info->Node->Name.Ascii, Info->Node, Info->ObjDesc));

    /* Create and init a Root Node */

    Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart);
    if (!Op)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /* Create and initialize a new walk state */

    Info->PassNumber = ACPI_IMODE_EXECUTE;
    WalkState = AcpiDsCreateWalkState (
        Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL);
    if (!WalkState)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node,
        Info->ObjDesc->Method.AmlStart,
        Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        goto Cleanup;
    }

    if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
    {
        WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL;
    }

    /* Invoke an internal method if necessary */

    if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
    {
        Status = Info->ObjDesc->Method.Dispatch.Implementation (WalkState);
        Info->ReturnObject = WalkState->ReturnDesc;

        /* Cleanup states */

        AcpiDsScopeStackClear (WalkState);
        AcpiPsCleanupScope (&WalkState->ParserState);
        AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
        AcpiDsDeleteWalkState (WalkState);
        goto Cleanup;
    }

    /*
     * Start method evaluation with an implicit return of zero.
     * This is done for Windows compatibility.
     */
    if (AcpiGbl_EnableInterpreterSlack)
    {
        WalkState->ImplicitReturnObj =
            AcpiUtCreateIntegerObject ((UINT64) 0);
        if (!WalkState->ImplicitReturnObj)
        {
            Status = AE_NO_MEMORY;
            AcpiDsDeleteWalkState (WalkState);
            goto Cleanup;
        }
    }

    /* Parse the AML */

    Status = AcpiPsParseAml (WalkState);

    /* WalkState was deleted by ParseAml */

Cleanup:
    AcpiPsDeleteParseTree (Op);

    /* Take away the extra reference that we gave the parameters above */

    AcpiPsUpdateParameterList (Info, REF_DECREMENT);

    /* Exit now if error above */

    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * If the method has returned an object, signal this to the caller with
     * a control exception code
     */
    if (Info->ReturnObject)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
            Info->ReturnObject));
        ACPI_DUMP_STACK_ENTRY (Info->ReturnObject);

        Status = AE_CTRL_RETURN_VALUE;
    }

    return_ACPI_STATUS (Status);
}
Esempio n. 13
0
ACPI_STATUS
AcpiNsOneCompleteParse (
    UINT32                  PassNumber,
    UINT32                  TableIndex,
    ACPI_NAMESPACE_NODE     *StartNode)
{
    ACPI_PARSE_OBJECT       *ParseRoot;
    ACPI_STATUS             Status;
    UINT32                  AmlLength;
    UINT8                   *AmlStart;
    ACPI_WALK_STATE         *WalkState;
    ACPI_TABLE_HEADER       *Table;
    ACPI_OWNER_ID           OwnerId;


    ACPI_FUNCTION_TRACE (NsOneCompleteParse);


    Status = AcpiGetTableByIndex (TableIndex, &Table);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Table must consist of at least a complete header */

    if (Table->Length < sizeof (ACPI_TABLE_HEADER))
    {
        return_ACPI_STATUS (AE_BAD_HEADER);
    }

    AmlStart = (UINT8 *) Table + sizeof (ACPI_TABLE_HEADER);
    AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);

    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Create and init a Root Node */

    ParseRoot = AcpiPsCreateScopeOp (AmlStart);
    if (!ParseRoot)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Create and initialize a new walk state */

    WalkState = AcpiDsCreateWalkState (OwnerId, NULL, NULL, NULL);
    if (!WalkState)
    {
        AcpiPsFreeOp (ParseRoot);
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL,
        AmlStart, AmlLength, NULL, (UINT8) PassNumber);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        goto Cleanup;
    }

    /* Found OSDT table, enable the namespace override feature */

    if (ACPI_COMPARE_NAME(Table->Signature, ACPI_SIG_OSDT) &&
        PassNumber == ACPI_IMODE_LOAD_PASS1)
    {
        WalkState->NamespaceOverride = TRUE;
    }

    /* StartNode is the default location to load the table  */

    if (StartNode && StartNode != AcpiGbl_RootNode)
    {
        Status = AcpiDsScopeStackPush (
            StartNode, ACPI_TYPE_METHOD, WalkState);
        if (ACPI_FAILURE (Status))
        {
            AcpiDsDeleteWalkState (WalkState);
            goto Cleanup;
        }
    }

    /* Parse the AML */

    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
        "*PARSE* pass %u parse\n", PassNumber));
    AcpiExEnterInterpreter ();
    Status = AcpiPsParseAml (WalkState);
    AcpiExExitInterpreter ();

Cleanup:
    AcpiPsDeleteParseTree (ParseRoot);
    return_ACPI_STATUS (Status);
}
Esempio n. 14
0
ACPI_STATUS
AcpiPsCompleteThisOp (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *Prev;
    ACPI_PARSE_OBJECT       *Next;
    const ACPI_OPCODE_INFO  *ParentInfo;
    ACPI_PARSE_OBJECT       *ReplacementOp = NULL;
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE_PTR (PsCompleteThisOp, Op);


    /* Check for null Op, can happen if AML code is corrupt */

    if (!Op)
    {
        return_ACPI_STATUS (AE_OK);  /* OK for now */
    }

    AcpiExStopTraceOpcode (Op, WalkState);

    /* Delete this op and the subtree below it if asked to */

    if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
         (WalkState->OpInfo->Class == AML_CLASS_ARGUMENT))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Make sure that we only delete this subtree */

    if (Op->Common.Parent)
    {
        Prev = Op->Common.Parent->Common.Value.Arg;
        if (!Prev)
        {
            /* Nothing more to do */

            goto Cleanup;
        }

        /*
         * Check if we need to replace the operator and its subtree
         * with a return value op (placeholder op)
         */
        ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);

        switch (ParentInfo->Class)
        {
        case AML_CLASS_CONTROL:

            break;

        case AML_CLASS_CREATE:
            /*
             * These opcodes contain TermArg operands. The current
             * op must be replaced by a placeholder return op
             */
            ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP,
                                Op->Common.Aml);
            if (!ReplacementOp)
            {
                Status = AE_NO_MEMORY;
            }
            break;

        case AML_CLASS_NAMED_OBJECT:
            /*
             * These opcodes contain TermArg operands. The current
             * op must be replaced by a placeholder return op
             */
            if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP)       ||
                (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP)  ||
                (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP)       ||
                (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP)      ||
                (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP)   ||
                (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
            {
                ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP,
                                    Op->Common.Aml);
                if (!ReplacementOp)
                {
                    Status = AE_NO_MEMORY;
                }
            }
            else if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
                     (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
            {
                if ((Op->Common.AmlOpcode == AML_BUFFER_OP) ||
                    (Op->Common.AmlOpcode == AML_PACKAGE_OP) ||
                    (Op->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
                {
                    ReplacementOp = AcpiPsAllocOp (Op->Common.AmlOpcode,
                                        Op->Common.Aml);
                    if (!ReplacementOp)
                    {
                        Status = AE_NO_MEMORY;
                    }
                    else
                    {
                        ReplacementOp->Named.Data = Op->Named.Data;
                        ReplacementOp->Named.Length = Op->Named.Length;
                    }
                }
            }
            break;

        default:

            ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP,
                                Op->Common.Aml);
            if (!ReplacementOp)
            {
                Status = AE_NO_MEMORY;
            }
        }

        /* We must unlink this op from the parent tree */

        if (Prev == Op)
        {
            /* This op is the first in the list */

            if (ReplacementOp)
            {
                ReplacementOp->Common.Parent        = Op->Common.Parent;
                ReplacementOp->Common.Value.Arg     = NULL;
                ReplacementOp->Common.Node          = Op->Common.Node;
                Op->Common.Parent->Common.Value.Arg = ReplacementOp;
                ReplacementOp->Common.Next          = Op->Common.Next;
            }
            else
            {
                Op->Common.Parent->Common.Value.Arg = Op->Common.Next;
            }
        }

        /* Search the parent list */

        else while (Prev)
        {
            /* Traverse all siblings in the parent's argument list */

            Next = Prev->Common.Next;
            if (Next == Op)
            {
                if (ReplacementOp)
                {
                    ReplacementOp->Common.Parent    = Op->Common.Parent;
                    ReplacementOp->Common.Value.Arg = NULL;
                    ReplacementOp->Common.Node      = Op->Common.Node;
                    Prev->Common.Next               = ReplacementOp;
                    ReplacementOp->Common.Next      = Op->Common.Next;
                    Next = NULL;
                }
                else
                {
                    Prev->Common.Next = Op->Common.Next;
                    Next = NULL;
                }
            }
            Prev = Next;
        }
    }


Cleanup:

    /* Now we can actually delete the subtree rooted at Op */

    AcpiPsDeleteParseTree (Op);
    return_ACPI_STATUS (Status);
}
Esempio n. 15
0
static ACPI_STATUS
AdDoExternalFileList (
    char                    *Filename)
{
    ACPI_EXTERNAL_FILE      *ExternalFileList;
    char                    *ExternalFilename;
    ACPI_NEW_TABLE_DESC     *ExternalListHead = NULL;
    ACPI_STATUS             Status;
    ACPI_STATUS             GlobalStatus = AE_OK;
    ACPI_OWNER_ID           OwnerId;


    /*
     * External filenames are specified on the command line like this:
     * Example: iasl -e file1,file2,file3 -d xxx.aml
     */
    ExternalFileList = AcpiGbl_ExternalFileList;

    /* Process each external file */

    while (ExternalFileList)
    {
        ExternalFilename = ExternalFileList->Path;
        if (!strcmp (ExternalFilename, Filename))
        {
            /* Next external file */

            ExternalFileList = ExternalFileList->Next;
            continue;
        }

        AcpiOsPrintf ("External object resolution file %16s\n",
            ExternalFilename);

        Status = AcGetAllTablesFromFile (
            ExternalFilename, ACPI_GET_ONLY_AML_TABLES, &ExternalListHead);
        if (ACPI_FAILURE (Status))
        {
            if (Status == AE_TYPE)
            {
                ExternalFileList = ExternalFileList->Next;
                GlobalStatus = AE_TYPE;
                Status = AE_OK;
                continue;
            }

            return (Status);
        }

        /* Load external tables for symbol resolution */

        while (ExternalListHead)
        {
            Status = AdParseTable (
                ExternalListHead->Table, &OwnerId, TRUE, TRUE);
            if (ACPI_FAILURE (Status))
            {
                AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
                    AcpiFormatException (Status));
                return (Status);
            }

            /*
             * Load namespace from names created within control methods
             * Set owner id of nodes in external table
             */
            AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
                AcpiGbl_RootNode, OwnerId);
            AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);

            ExternalListHead = ExternalListHead->Next;
        }

        /* Next external file */

        ExternalFileList = ExternalFileList->Next;
    }

    if (ACPI_FAILURE (GlobalStatus))
    {
        return (GlobalStatus);
    }

    /* Clear external list generated by Scope in external tables */

    if (AcpiGbl_ExternalFileList)
    {
        AcpiDmClearExternalList ();
    }

    /* Load any externals defined in the optional external ref file */

    AcpiDmGetExternalsFromFile ();
    return (AE_OK);
}
Esempio n. 16
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);
}
Esempio n. 17
0
ACPI_STATUS
AcpiDsExecuteArguments (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_NAMESPACE_NODE     *ScopeNode,
    UINT32                  AmlLength,
    UINT8                   *AmlStart)
{
    ACPI_STATUS             Status;
    ACPI_PARSE_OBJECT       *Op;
    ACPI_WALK_STATE         *WalkState;
    ACPI_PARSE_OBJECT       *Arg;


    ACPI_FUNCTION_TRACE ("AcpiDsExecuteArguments");


    /*
     * Allocate a new parser op to be the root of the parsed tree
     */
    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
    if (!Op)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Save the Node for use in AcpiPsParseAml */

    Op->Common.Node = ScopeNode;

    /* Create and initialize a new parser state */

    WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL);
    if (!WalkState)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
                    AmlLength, NULL, NULL, 1);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        return_ACPI_STATUS (Status);
    }

    WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;

    /* Pass1: Parse the entire declaration */

    Status = AcpiPsParseAml (WalkState);
    if (ACPI_FAILURE (Status))
    {
        AcpiPsDeleteParseTree (Op);
        return_ACPI_STATUS (Status);
    }

    /* Get and init the Op created above */

    Arg = Op->Common.Value.Arg;
    Op->Common.Node = Node;
    Arg->Common.Node = Node;
    AcpiPsDeleteParseTree (Op);

    /* Evaluate the address and length arguments for the Buffer Field */

    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
    if (!Op)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Op->Common.Node = ScopeNode;

    /* Create and initialize a new parser state */

    WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL);
    if (!WalkState)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
                    AmlLength, NULL, NULL, 3);
    if (ACPI_FAILURE (Status))
    {
        AcpiDsDeleteWalkState (WalkState);
        return_ACPI_STATUS (Status);
    }

    Status = AcpiPsParseAml (WalkState);
    AcpiPsDeleteParseTree (Op);
    return_ACPI_STATUS (Status);
}