Exemplo n.º 1
0
ACPI_STATUS
AcpiGetTableByIndex (
    UINT32                  TableIndex,
    ACPI_TABLE_HEADER       **Table)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);


    /* Parameter validation */

    if (!Table)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

    /* Validate index */

    if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
    {
        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
    {
        /* Table is not mapped, map it */

        Status = AcpiTbValidateTable (
            &AcpiGbl_RootTableList.Tables[TableIndex]);
        if (ACPI_FAILURE (Status))
        {
            (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
            return_ACPI_STATUS (Status);
        }
    }

    *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    return_ACPI_STATUS (AE_OK);
}
Exemplo n.º 2
0
ACPI_STATUS
AcpiGetTable (
    char                    *Signature,
    UINT32                  Instance,
    ACPI_TABLE_HEADER       **OutTable)
{
    UINT32                  i;
    UINT32                  j;
    ACPI_STATUS             Status;


    /* Parameter validation */

    if (!Signature || !OutTable)
    {
        return (AE_BAD_PARAMETER);
    }

    /* Walk the root table list */

    for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
    {
        if (!ACPI_COMPARE_NAME (
                &(AcpiGbl_RootTableList.Tables[i].Signature), Signature))
        {
            continue;
        }

        if (++j < Instance)
        {
            continue;
        }

        Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
        if (ACPI_SUCCESS (Status))
        {
            *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
        }

        return (Status);
    }

    return (AE_NOT_FOUND);
}
Exemplo n.º 3
0
ACPI_STATUS
AcpiTbValidateTempTable (
    ACPI_TABLE_DESC         *TableDesc)
{

    if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation)
    {
        /*
         * Only validates the header of the table.
         * Note that Length contains the size of the mapping after invoking
         * this work around, this value is required by
         * AcpiTbReleaseTempTable().
         * We can do this because in AcpiInitTableDescriptor(), the Length
         * field of the installed descriptor is filled with the actual
         * table length obtaining from the table header.
         */
        TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
    }

    return (AcpiTbValidateTable (TableDesc));
}
Exemplo n.º 4
0
ACPI_STATUS
AcpiTbGetTable (
    ACPI_TABLE_DESC        *TableDesc,
    ACPI_TABLE_HEADER      **OutTable)
{
    ACPI_STATUS            Status;


    ACPI_FUNCTION_TRACE (AcpiTbGetTable);


    if (TableDesc->ValidationCount == 0)
    {
        /* Table need to be "VALIDATED" */

        Status = AcpiTbValidateTable (TableDesc);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }

    if (TableDesc->ValidationCount < ACPI_MAX_TABLE_VALIDATIONS)
    {
        TableDesc->ValidationCount++;

        /*
         * Detect ValidationCount overflows to ensure that the warning
         * message will only be printed once.
         */
        if (TableDesc->ValidationCount >= ACPI_MAX_TABLE_VALIDATIONS)
        {
            ACPI_WARNING((AE_INFO,
                "Table %p, Validation count overflows\n", TableDesc));
        }
    }

    *OutTable = TableDesc->Pointer;
    return_ACPI_STATUS (AE_OK);
}
Exemplo n.º 5
0
static ACPI_STATUS
AdStoreTable (
    ACPI_TABLE_HEADER       *Table,
    UINT32                  *TableIndex)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_DESC         *TableDesc;


    Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* Initialize added table */

    AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table),
        ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table);
    Status = AcpiTbValidateTable (TableDesc);
    return (Status);
}
Exemplo n.º 6
0
ACPI_STATUS
AcpiTbFindTable (
    char                    *Signature,
    char                    *OemId,
    char                    *OemTableId,
    UINT32                  *TableIndex)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       Header;
    UINT32                  i;


    ACPI_FUNCTION_TRACE (TbFindTable);


    /* Validate the input table signature */

    if (!AcpiIsValidSignature (Signature))
    {
        return_ACPI_STATUS (AE_BAD_SIGNATURE);
    }

    /* Don't allow the OEM strings to be too long */

    if ((strlen (OemId) > ACPI_OEM_ID_SIZE) ||
        (strlen (OemTableId) > ACPI_OEM_TABLE_ID_SIZE))
    {
        return_ACPI_STATUS (AE_AML_STRING_LIMIT);
    }

    /* Normalize the input strings */

    memset (&Header, 0, sizeof (ACPI_TABLE_HEADER));
    ACPI_MOVE_NAME (Header.Signature, Signature);
    strncpy (Header.OemId, OemId, ACPI_OEM_ID_SIZE);
    strncpy (Header.OemTableId, OemTableId, ACPI_OEM_TABLE_ID_SIZE);

    /* Search for the table */

    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
    {
        if (memcmp (&(AcpiGbl_RootTableList.Tables[i].Signature),
            Header.Signature, ACPI_NAME_SIZE))
        {
            /* Not the requested table */

            continue;
        }

        /* Table with matching signature has been found */

        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
        {
            /* Table is not currently mapped, map it */

            Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }

            if (!AcpiGbl_RootTableList.Tables[i].Pointer)
            {
                continue;
            }
        }

        /* Check for table match on all IDs */

        if (!memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->Signature,
                Header.Signature, ACPI_NAME_SIZE) &&
            (!OemId[0] ||
             !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemId,
                 Header.OemId, ACPI_OEM_ID_SIZE)) &&
            (!OemTableId[0] ||
             !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemTableId,
                 Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE)))
        {
            *TableIndex = i;

            ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
                Header.Signature));
            return_ACPI_STATUS (AE_OK);
        }
    }

    return_ACPI_STATUS (AE_NOT_FOUND);
}
ACPI_STATUS
AcpiExLoadOp (
    ACPI_OPERAND_OBJECT     *ObjDesc,
    ACPI_OPERAND_OBJECT     *Target,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_OPERAND_OBJECT     *DdbHandle;
    ACPI_TABLE_HEADER       *TableHeader;
    ACPI_TABLE_HEADER       *Table;
    UINT32                  TableIndex;
    ACPI_STATUS             Status;
    UINT32                  Length;


    ACPI_FUNCTION_TRACE (ExLoadOp);


    /* Source Object can be either an OpRegion or a Buffer/Field */

    switch (ObjDesc->Common.Type)
    {
    case ACPI_TYPE_REGION:

        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
            "Load table from Region %p\n", ObjDesc));

        /* Region must be SystemMemory (from ACPI spec) */

        if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY)
        {
            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
        }

        /*
         * If the Region Address and Length have not been previously evaluated,
         * evaluate them now and save the results.
         */
        if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
        {
            Status = AcpiDsGetRegionArguments (ObjDesc);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }
        }

        /* Get the table header first so we can get the table length */

        TableHeader = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER));
        if (!TableHeader)
        {
            return_ACPI_STATUS (AE_NO_MEMORY);
        }

        Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER),
                    ACPI_CAST_PTR (UINT8, TableHeader));
        Length = TableHeader->Length;
        ACPI_FREE (TableHeader);

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

        /* Must have at least an ACPI table header */

        if (Length < sizeof (ACPI_TABLE_HEADER))
        {
            return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
        }

        /*
         * The original implementation simply mapped the table, with no copy.
         * However, the memory region is not guaranteed to remain stable and
         * we must copy the table to a local buffer. For example, the memory
         * region is corrupted after suspend on some machines. Dynamically
         * loaded tables are usually small, so this overhead is minimal.
         *
         * The latest implementation (5/2009) does not use a mapping at all.
         * We use the low-level operation region interface to read the table
         * instead of the obvious optimization of using a direct mapping.
         * This maintains a consistent use of operation regions across the
         * entire subsystem. This is important if additional processing must
         * be performed in the (possibly user-installed) operation region
         * handler. For example, AcpiExec and ASLTS depend on this.
         */

        /* Allocate a buffer for the table */

        Table = ACPI_ALLOCATE (Length);
        if (!Table)
        {
            return_ACPI_STATUS (AE_NO_MEMORY);
        }

        /* Read the entire table */

        Status = AcpiExRegionRead (ObjDesc, Length,
                    ACPI_CAST_PTR (UINT8, Table));
        if (ACPI_FAILURE (Status))
        {
            ACPI_FREE (Table);
            return_ACPI_STATUS (Status);
        }
        break;

    case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */

        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
            "Load table from Buffer or Field %p\n", ObjDesc));

        /* Must have at least an ACPI table header */

        if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER))
        {
            return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
        }

        /* Get the actual table length from the table header */

        TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer);
        Length = TableHeader->Length;

        /* Table cannot extend beyond the buffer */

        if (Length > ObjDesc->Buffer.Length)
        {
            return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
        }
        if (Length < sizeof (ACPI_TABLE_HEADER))
        {
            return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
        }

        /*
         * Copy the table from the buffer because the buffer could be modified
         * or even deleted in the future
         */
        Table = ACPI_ALLOCATE (Length);
        if (!Table)
        {
            return_ACPI_STATUS (AE_NO_MEMORY);
        }

        ACPI_MEMCPY (Table, TableHeader, Length);
        break;

    default:

        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }

    /* Install the new table into the local data structures */

    ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

    Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table),
                ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, TRUE, TRUE,
                &TableIndex);

    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    if (ACPI_FAILURE (Status))
    {
        /* Delete allocated table buffer */

        ACPI_FREE (Table);
        return_ACPI_STATUS (Status);
    }

    /*
     * Note: Now table is "INSTALLED", it must be validated before
     * loading.
     */
    Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Add the table to the namespace.
     *
     * Note: Load the table objects relative to the root of the namespace.
     * This appears to go against the ACPI specification, but we do it for
     * compatibility with other ACPI implementations.
     */
    Status = AcpiExAddTable (TableIndex, AcpiGbl_RootNode, &DdbHandle);
    if (ACPI_FAILURE (Status))
    {
        /* On error, TablePtr was deallocated above */

        return_ACPI_STATUS (Status);
    }

    /* Store the DdbHandle into the Target operand */

    Status = AcpiExStore (DdbHandle, Target, WalkState);
    if (ACPI_FAILURE (Status))
    {
        (void) AcpiExUnloadTable (DdbHandle);

        /* TablePtr was deallocated above */

        AcpiUtRemoveReference (DdbHandle);
        return_ACPI_STATUS (Status);
    }

    /* Remove the reference by added by AcpiExStore above */

    AcpiUtRemoveReference (DdbHandle);

    /* Invoke table handler if present */

    if (AcpiGbl_TableHandler)
    {
        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
                    AcpiGbl_TableHandlerContext);
    }

    return_ACPI_STATUS (Status);
}
Exemplo n.º 8
0
void
AcpiDbDisplayTableInfo (
    char                    *TableArg)
{
    UINT32                  i;
    ACPI_TABLE_DESC         *TableDesc;
    ACPI_STATUS             Status;


    /* Header */

    AcpiOsPrintf ("Idx ID    Status Type              TableHeader (Sig, Address, Length)\n");

    /* Walk the entire root table list */

    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
    {
        TableDesc = &AcpiGbl_RootTableList.Tables[i];

        /* Index and Table ID */

        AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);

        /* Decode the table flags */

        if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
        {
            AcpiOsPrintf ("NotLoaded ");
        }
        else
        {
            AcpiOsPrintf ("   Loaded ");
        }

        switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
        {
        case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:

            AcpiOsPrintf ("External/virtual  ");
            break;

        case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:

            AcpiOsPrintf ("Internal/physical ");
            break;

        case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:

            AcpiOsPrintf ("Internal/virtual  ");
            break;

        default:

            AcpiOsPrintf ("INVALID TYPE      ");
            break;
        }

        /* Make sure that the table is mapped */

        Status = AcpiTbValidateTable (TableDesc);
        if (ACPI_FAILURE (Status))
        {
            return;
        }

        /* Dump the table header */

        if (TableDesc->Pointer)
        {
            AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
        }
        else
        {
            /* If the pointer is null, the table has been unloaded */

            ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
                TableDesc->Signature.Ascii));
        }
    }
}
Exemplo n.º 9
0
ACPI_STATUS
AcpiLoadTable (
    ACPI_TABLE_HEADER       *Table)
{
    ACPI_STATUS             Status;
    UINT32                  TableIndex;


    ACPI_FUNCTION_TRACE (AcpiLoadTable);


    /* Parameter validation */

    if (!Table)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Must acquire the interpreter lock during this operation */

    Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Install the table and load it into the namespace */

    ACPI_INFO (("Host-directed Dynamic ACPI Table Load:"));
    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

    Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table),
        ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE,
        &TableIndex);

    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    if (ACPI_FAILURE (Status))
    {
        goto UnlockAndExit;
    }

    /*
     * Note: Now table is "INSTALLED", it must be validated before
     * using.
     */
    Status = AcpiTbValidateTable (
        &AcpiGbl_RootTableList.Tables[TableIndex]);
    if (ACPI_FAILURE (Status))
    {
        goto UnlockAndExit;
    }

    Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode);

    /* Invoke table handler if present */

    if (AcpiGbl_TableHandler)
    {
        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
            AcpiGbl_TableHandlerContext);
    }

UnlockAndExit:
    (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
    return_ACPI_STATUS (Status);
}
Exemplo n.º 10
0
ACPI_STATUS
AcpiTbLoadNamespace (
    void)
{
    ACPI_STATUS             Status;
    UINT32                  i;
    ACPI_TABLE_HEADER       *NewDsdt;
    ACPI_TABLE_DESC         *Table;
    UINT32                  TablesLoaded = 0;
    UINT32                  TablesFailed = 0;


    ACPI_FUNCTION_TRACE (TbLoadNamespace);


    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

    /*
     * Load the namespace. The DSDT is required, but any SSDT and
     * PSDT tables are optional. Verify the DSDT.
     */
    Table = &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex];

    if (!AcpiGbl_RootTableList.CurrentTableCount ||
        !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT) ||
         ACPI_FAILURE (AcpiTbValidateTable (Table)))
    {
        Status = AE_NO_ACPI_TABLES;
        goto UnlockAndExit;
    }

    /*
     * Save the DSDT pointer for simple access. This is the mapped memory
     * address. We must take care here because the address of the .Tables
     * array can change dynamically as tables are loaded at run-time. Note:
     * .Pointer field is not validated until after call to AcpiTbValidateTable.
     */
    AcpiGbl_DSDT = Table->Pointer;

    /*
     * Optionally copy the entire DSDT to local memory (instead of simply
     * mapping it.) There are some BIOSs that corrupt or replace the original
     * DSDT, creating the need for this option. Default is FALSE, do not copy
     * the DSDT.
     */
    if (AcpiGbl_CopyDsdtLocally)
    {
        NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex);
        if (NewDsdt)
        {
            AcpiGbl_DSDT = NewDsdt;
        }
    }

    /*
     * Save the original DSDT header for detection of table corruption
     * and/or replacement of the DSDT from outside the OS.
     */
    memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
        sizeof (ACPI_TABLE_HEADER));

    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);

    /* Load and parse tables */

    Status = AcpiNsLoadTable (AcpiGbl_DsdtIndex, AcpiGbl_RootNode);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status, "[DSDT] table load failed"));
        TablesFailed++;
    }
    else
    {
        TablesLoaded++;
    }

    /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */

    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
    {
        Table = &AcpiGbl_RootTableList.Tables[i];

        if (!AcpiGbl_RootTableList.Tables[i].Address ||
            (!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) &&
             !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) &&
             !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) ||
             ACPI_FAILURE (AcpiTbValidateTable (Table)))
        {
            continue;
        }

        /* Ignore errors while loading tables, get as many as possible */

        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
        Status =  AcpiNsLoadTable (i, AcpiGbl_RootNode);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status, "(%4.4s:%8.8s) while loading table",
                Table->Signature.Ascii, Table->Pointer->OemTableId));

            TablesFailed++;

            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
                "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n",
                Table->Signature.Ascii, Table->Pointer->OemTableId));
        }
        else
        {
            TablesLoaded++;
        }

        (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    }

    if (!TablesFailed)
    {
        ACPI_INFO ((
            "%u ACPI AML tables successfully acquired and loaded\n",
            TablesLoaded));
    }
    else
    {
        ACPI_ERROR ((AE_INFO,
            "%u table load failures, %u successful",
            TablesFailed, TablesLoaded));

        /* Indicate at least one failure */

        Status = AE_CTRL_TERMINATE;
    }

UnlockAndExit:
    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    return_ACPI_STATUS (Status);
}
Exemplo n.º 11
0
static ACPI_STATUS
AcpiTbLoadNamespace (
    void)
{
    ACPI_STATUS             Status;
    UINT32                  i;
    ACPI_TABLE_HEADER       *NewDsdt;


    ACPI_FUNCTION_TRACE (TbLoadNamespace);


    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

    /*
     * Load the namespace. The DSDT is required, but any SSDT and
     * PSDT tables are optional. Verify the DSDT.
     */
    if (!AcpiGbl_RootTableList.CurrentTableCount ||
        !ACPI_COMPARE_NAME (
            &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
            ACPI_SIG_DSDT) ||
         ACPI_FAILURE (AcpiTbValidateTable (
            &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
    {
        Status = AE_NO_ACPI_TABLES;
        goto UnlockAndExit;
    }

    /*
     * Save the DSDT pointer for simple access. This is the mapped memory
     * address. We must take care here because the address of the .Tables
     * array can change dynamically as tables are loaded at run-time. Note:
     * .Pointer field is not validated until after call to AcpiTbValidateTable.
     */
    AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;

    /*
     * Optionally copy the entire DSDT to local memory (instead of simply
     * mapping it.) There are some BIOSs that corrupt or replace the original
     * DSDT, creating the need for this option. Default is FALSE, do not copy
     * the DSDT.
     */
    if (AcpiGbl_CopyDsdtLocally)
    {
        NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
        if (NewDsdt)
        {
            AcpiGbl_DSDT = NewDsdt;
        }
    }

    /*
     * Save the original DSDT header for detection of table corruption
     * and/or replacement of the DSDT from outside the OS.
     */
    ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
        sizeof (ACPI_TABLE_HEADER));

    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);

    /* Load and parse tables */

    Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */

    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
    {
        if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
                    ACPI_SIG_SSDT) &&
             !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
                    ACPI_SIG_PSDT)) ||
             ACPI_FAILURE (AcpiTbValidateTable (
                &AcpiGbl_RootTableList.Tables[i])))
        {
            continue;
        }

        /* Ignore errors while loading tables, get as many as possible */

        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
        (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
        (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    }

    ACPI_INFO ((AE_INFO, "All ACPI Tables successfully acquired"));

UnlockAndExit:
    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    return_ACPI_STATUS (Status);
}
Exemplo n.º 12
0
ACPI_STATUS
AcpiTbFindTable (
    char                    *Signature,
    char                    *OemId,
    char                    *OemTableId,
    UINT32                  *TableIndex)
{
    UINT32                  i;
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       Header;


    ACPI_FUNCTION_TRACE (TbFindTable);


    /* Normalize the input strings */

    ACPI_MEMSET (&Header, 0, sizeof (ACPI_TABLE_HEADER));
    ACPI_MOVE_NAME (Header.Signature, Signature);
    ACPI_STRNCPY (Header.OemId, OemId, ACPI_OEM_ID_SIZE);
    ACPI_STRNCPY (Header.OemTableId, OemTableId, ACPI_OEM_TABLE_ID_SIZE);

    /* Search for the table */

    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
    {
        if (ACPI_MEMCMP (&(AcpiGbl_RootTableList.Tables[i].Signature),
                            Header.Signature, ACPI_NAME_SIZE))
        {
            /* Not the requested table */

            continue;
        }

        /* Table with matching signature has been found */

        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
        {
            /* Table is not currently mapped, map it */

            Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }

            if (!AcpiGbl_RootTableList.Tables[i].Pointer)
            {
                continue;
            }
        }

        /* Check for table match on all IDs */

        if (!ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->Signature,
                            Header.Signature, ACPI_NAME_SIZE) &&
            (!OemId[0] ||
             !ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->OemId,
                             Header.OemId, ACPI_OEM_ID_SIZE)) &&
            (!OemTableId[0] ||
             !ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->OemTableId,
                             Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE)))
        {
            *TableIndex = i;

            ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
                Header.Signature));
            return_ACPI_STATUS (AE_OK);
        }
    }

    return_ACPI_STATUS (AE_NOT_FOUND);
}
Exemplo n.º 13
0
ACPI_STATUS
AcpiTbInstallAndLoadTable (
    ACPI_TABLE_HEADER       *Table,
    ACPI_PHYSICAL_ADDRESS   Address,
    UINT8                   Flags,
    BOOLEAN                 Override,
    UINT32                  *TableIndex)
{
    ACPI_STATUS             Status;
    UINT32                  i;
    ACPI_OWNER_ID           OwnerId;


    ACPI_FUNCTION_TRACE (AcpiLoadTable);


    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

    /* Install the table and load it into the namespace */

    Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
        Override, &i);
    if (ACPI_FAILURE (Status))
    {
        goto UnlockAndExit;
    }

    /*
     * Note: Now table is "INSTALLED", it must be validated before
     * using.
     */
    Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
    if (ACPI_FAILURE (Status))
    {
        goto UnlockAndExit;
    }

    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);

    /* Execute any module-level code that was found in the table */

    if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
    {
        AcpiNsExecModuleCodeList ();
    }

    /*
     * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
     * responsible for discovering any new wake GPEs by running _PRW methods
     * that may have been loaded by this table.
     */
    Status = AcpiTbGetOwnerId (i, &OwnerId);
    if (ACPI_SUCCESS (Status))
    {
        AcpiEvUpdateGpes (OwnerId);
    }

    /* Invoke table handler if present */

    if (AcpiGbl_TableHandler)
    {
        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
            AcpiGbl_TableHandlerContext);
    }
    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);

UnlockAndExit:
    *TableIndex = i;
    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    return_ACPI_STATUS (Status);
}