Пример #1
0
ACPI_STATUS
AdGetLocalTables (
    void)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       TableHeader;
    ACPI_TABLE_HEADER       *NewTable;
    UINT32                  TableIndex;


    /* Get the DSDT via table override */

    ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
    AcpiOsTableOverride (&TableHeader, &NewTable);
    if (!NewTable)
    {
        fprintf (stderr, "Could not obtain DSDT\n");
        return (AE_NO_ACPI_TABLES);
    }

    AdWriteTable (NewTable, NewTable->Length,
                  ACPI_SIG_DSDT, NewTable->OemTableId);

    /* Store DSDT in the Table Manager */

    Status = AcpiTbStoreTable (0, NewTable, NewTable->Length,
                               0, &TableIndex);
    if (ACPI_FAILURE (Status))
    {
        fprintf (stderr, "Could not store DSDT\n");
        return (AE_NO_ACPI_TABLES);
    }

    return (AE_OK);
}
Пример #2
0
ACPI_STATUS
AcpiTbAddTable (
    ACPI_TABLE_DESC         *TableDesc,
    UINT32                  *TableIndex)
{
    UINT32                  i;
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE (TbAddTable);


    if (!TableDesc->Pointer)
    {
        Status = AcpiTbVerifyTable (TableDesc);
        if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
        {
            return_ACPI_STATUS (Status);
        }
    }

    /*
     * Validate the incoming table signature.
     *
     * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
     * 2) We added support for OEMx tables, signature "OEM".
     * 3) Valid tables were encountered with a null signature, so we just
     *    gave up on validating the signature, (05/2008).
     * 4) We encountered non-AML tables such as the MADT, which caused
     *    interpreter errors and kernel faults. So now, we once again allow
     *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
     */
    if ((TableDesc->Pointer->Signature[0] != 0x00) &&
       (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
       (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
    {
        ACPI_BIOS_ERROR ((AE_INFO,
            "Table has invalid signature [%4.4s] (0x%8.8X), "
            "must be SSDT or OEMx",
            AcpiUtValidAcpiName (TableDesc->Pointer->Signature) ?
                TableDesc->Pointer->Signature : "????",
            *(UINT32 *) TableDesc->Pointer->Signature));

        return_ACPI_STATUS (AE_BAD_SIGNATURE);
    }

    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

    /* Check if table is already registered */

    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
    {
        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
        {
            Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
            if (ACPI_FAILURE (Status) ||
                !AcpiGbl_RootTableList.Tables[i].Pointer)
            {
                continue;
            }
        }

        /*
         * Check for a table match on the entire table length,
         * not just the header.
         */
        if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
        {
            continue;
        }

        if (ACPI_MEMCMP (TableDesc->Pointer,
                AcpiGbl_RootTableList.Tables[i].Pointer,
                AcpiGbl_RootTableList.Tables[i].Length))
        {
            continue;
        }

        /*
         * Note: the current mechanism does not unregister a table if it is
         * dynamically unloaded. The related namespace entries are deleted,
         * but the table remains in the root table list.
         *
         * The assumption here is that the number of different tables that
         * will be loaded is actually small, and there is minimal overhead
         * in just keeping the table in case it is needed again.
         *
         * If this assumption changes in the future (perhaps on large
         * machines with many table load/unload operations), tables will
         * need to be unregistered when they are unloaded, and slots in the
         * root table list should be reused when empty.
         */

        /*
         * Table is already registered.
         * We can delete the table that was passed as a parameter.
         */
        AcpiTbDeleteTable (TableDesc);
        *TableIndex = i;

        if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
        {
            /* Table is still loaded, this is an error */

            Status = AE_ALREADY_EXISTS;
            goto Release;
        }
        else
        {
            /* Table was unloaded, allow it to be reloaded */

            TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
            TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
            Status = AE_OK;
            goto PrintHeader;
        }
    }

    /*
     * ACPI Table Override:
     * Allow the host to override dynamically loaded tables.
     * NOTE: the table is fully mapped at this point, and the mapping will
     * be deleted by TbTableOverride if the table is actually overridden.
     */
    (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);

    /* Add the table to the global root table list */

    Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
                TableDesc->Length, TableDesc->Flags, TableIndex);
    if (ACPI_FAILURE (Status))
    {
        goto Release;
    }

PrintHeader:
    AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);

Release:
    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    return_ACPI_STATUS (Status);
}
Пример #3
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);
}
Пример #4
0
ACPI_STATUS
AdGetLocalTables (
    char                    *Filename,
    BOOLEAN                 GetAllTables)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       TableHeader;
    ACPI_TABLE_HEADER       *NewTable;
    UINT32                  NumTables;
    UINT32                  PointerSize;
    UINT32                  TableIndex;


    if (GetAllTables)
    {
        ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT);
        AcpiOsTableOverride (&TableHeader, &NewTable);
        if (!NewTable)
        {
            fprintf (stderr, "Could not obtain RSDT\n");
            return (AE_NO_ACPI_TABLES);
        }
        else
        {
            AdWriteTable (NewTable, NewTable->Length,
                ACPI_SIG_RSDT, NewTable->OemTableId);
        }

        if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT))
        {
            PointerSize = sizeof (UINT32);
        }
        else
        {
            PointerSize = sizeof (UINT64);
        }

        /*
         * Determine the number of tables pointed to by the RSDT/XSDT.
         * This is defined by the ACPI Specification to be the number of
         * pointers contained within the RSDT/XSDT. The size of the pointers
         * is architecture-dependent.
         */
        NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize;
        AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n",
            NumTables, NewTable->Signature);

        /* Get the FADT */

        ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT);
        AcpiOsTableOverride (&TableHeader, &NewTable);
        if (NewTable)
        {
            AdWriteTable (NewTable, NewTable->Length,
                ACPI_SIG_FADT, NewTable->OemTableId);
        }
        AcpiOsPrintf ("\n");

        /* Don't bother with FACS, it is usually all zeros */
    }

    /* Always get the DSDT */

    ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
    AcpiOsTableOverride (&TableHeader, &NewTable);
    if (NewTable)
    {
        AdWriteTable (NewTable, NewTable->Length,
            ACPI_SIG_DSDT, NewTable->OemTableId);

        /* Store DSDT in the Table Manager */

        Status = AcpiTbStoreTable (0, NewTable, NewTable->Length,
                    0, &TableIndex);
        if (ACPI_FAILURE (Status))
        {
            fprintf (stderr, "Could not store DSDT\n");
            return (AE_NO_ACPI_TABLES);
        }
    }
    else
    {
        fprintf (stderr, "Could not obtain DSDT\n");
        return (AE_NO_ACPI_TABLES);
    }

#if 0
    /* TBD: Future implementation */

    AcpiOsPrintf ("\n");

    /* Get all SSDTs */

    ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT);
    do
    {
        NewTable = NULL;
        Status = AcpiOsTableOverride (&TableHeader, &NewTable);

    } while (NewTable);
#endif

    return (AE_OK);
}
Пример #5
0
        /* We can delete the table that was passed as a parameter */

        AcpiTbDeleteTable (TableDesc);

        /* Setup descriptor for the new table */

        TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
        TableDesc->Pointer = OverrideTable;
        TableDesc->Length = OverrideTable->Length;
        TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
    }

    /* Add the table to the global root table list */

    Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
                TableDesc->Length, TableDesc->Flags, TableIndex);
    if (ACPI_FAILURE (Status))
    {
        goto Release;
    }

PrintHeader:
    AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);

Release:
    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    return_ACPI_STATUS (Status);
}


/*******************************************************************************