ACPI_STATUS
AcpiNsParseTable (
    UINT32                  TableIndex,
    ACPI_NAMESPACE_NODE     *StartNode)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (NsParseTable);


    /*
     * AML Parse, pass 1
     *
     * In this pass, we load most of the namespace.  Control methods
     * are not parsed until later.  A parse tree is not created.  Instead,
     * each Parser Op subtree is deleted when it is finished.  This saves
     * a great deal of memory, and allows a small cache of parse objects
     * to service the entire parse.  The second pass of the parse then
     * performs another complete parse of the AML.
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n"));
    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS1,
                TableIndex, StartNode);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * AML Parse, pass 2
     *
     * In this pass, we resolve forward references and other things
     * that could not be completed during the first pass.
     * Another complete parse of the AML is performed, but the
     * overhead of this is compensated for by the fact that the
     * parse objects are all cached.
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n"));
    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2,
                TableIndex, StartNode);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    return_ACPI_STATUS (Status);
}
Beispiel #2
0
ACPI_STATUS
AdParseTable (
    ACPI_TABLE_HEADER       *Table,
    ACPI_OWNER_ID           *OwnerId,
    BOOLEAN                 LoadTable,
    BOOLEAN                 External)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_WALK_STATE         *WalkState;
    UINT8                   *AmlStart;
    UINT32                  AmlLength;
    UINT32                  TableIndex;


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

    /* Pass 1:  Parse everything except control method bodies */

    fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);

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

    /* Create the root object */

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

    /* Create and initialize a new walk state */

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

    Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
                NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

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

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

    /* If LoadTable is FALSE, we are parsing the last loaded table */

    TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;

    /* Pass 2 */

    if (LoadTable)
    {
        Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table,
                    Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex);
        if (ACPI_FAILURE (Status))
        {
            return (Status);
        }
        Status = AcpiTbAllocateOwnerId (TableIndex);
        if (ACPI_FAILURE (Status))
        {
            return (Status);
        }
        if (OwnerId)
        {
            Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
            if (ACPI_FAILURE (Status))
            {
                return (Status);
            }
        }
    }

    fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);

    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* No need to parse control methods of external table */

    if (External)
    {
        return (AE_OK);
    }

    /* Pass 3: Parse control methods and link their parse trees into the main parse tree */

    fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
    Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
    fprintf (stderr, "\n");

    /* Process Resource Templates */

    AcpiDmFindResources (AcpiGbl_ParseOpRoot);

    fprintf (stderr, "Parsing completed\n");
    return (AE_OK);
}
Beispiel #3
0
ACPI_STATUS
AcpiNsParseTable (
    UINT32                  TableIndex,
    ACPI_NAMESPACE_NODE     *StartNode)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (NsParseTable);


    if (AcpiGbl_ExecuteTablesAsMethods)
    {
        /*
         * This case executes the AML table as one large control method.
         * The point of this is to execute any module-level code in-place
         * as the table is parsed. Some AML code depends on this behavior.
         *
         * It is a run-time option at this time, but will eventually become
         * the default.
         *
         * Note: This causes the table to only have a single-pass parse.
         * However, this is compatible with other ACPI implementations.
         */
        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
            "%s: **** Start table execution pass\n", ACPI_GET_FUNCTION_NAME));

        Status = AcpiNsExecuteTable (TableIndex, StartNode);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }
    else
    {
        /*
         * AML Parse, pass 1
         *
         * In this pass, we load most of the namespace. Control methods
         * are not parsed until later. A parse tree is not created.
         * Instead, each Parser Op subtree is deleted when it is finished.
         * This saves a great deal of memory, and allows a small cache of
         * parse objects to service the entire parse. The second pass of
         * the parse then performs another complete parse of the AML.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n"));

        Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS1,
            TableIndex, StartNode);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        /*
         * AML Parse, pass 2
         *
         * In this pass, we resolve forward references and other things
         * that could not be completed during the first pass.
         * Another complete parse of the AML is performed, but the
         * overhead of this is compensated for by the fact that the
         * parse objects are all cached.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n"));
        Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2,
            TableIndex, StartNode);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }

    return_ACPI_STATUS (Status);
}