示例#1
0
void
AcpiTbUninstallTable (
    ACPI_TABLE_DESC         *TableDesc)
{

    ACPI_FUNCTION_TRACE (TbUninstallTable);


    /* Table must be installed */

    if (!TableDesc->Address)
    {
        return_VOID;
    }

    AcpiTbInvalidateTable (TableDesc);

    if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
        ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL)
    {
        ACPI_FREE (ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
    }

    TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL);
    return_VOID;
}
示例#2
0
ACPI_PHYSICAL_ADDRESS
AcpiOsGetRootPointer (
    void)
{

    return (ACPI_PTR_TO_PHYSADDR (&LocalRSDP));
}
示例#3
0
ACPI_PHYSICAL_ADDRESS
AcpiOsGetRootPointer (
    void)
{

    return (ACPI_PTR_TO_PHYSADDR (RsdpCode));
}
示例#4
0
文件: tbxfload.c 项目: 9elements/fwts
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);
    }

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

    ACPI_INFO (("Host-directed Dynamic ACPI Table Load:"));
    Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table),
        ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, FALSE, &TableIndex);
    return_ACPI_STATUS (Status);
}
示例#5
0
文件: tbutils.c 项目: benevo/acpica
ACPI_TABLE_HEADER *
AcpiTbCopyDsdt (
    UINT32                  TableIndex)
{
    ACPI_TABLE_HEADER       *NewTable;
    ACPI_TABLE_DESC         *TableDesc;


    TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];

    NewTable = ACPI_ALLOCATE (TableDesc->Length);
    if (!NewTable)
    {
        ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
            TableDesc->Length));
        return (NULL);
    }

    memcpy (NewTable, TableDesc->Pointer, TableDesc->Length);
    AcpiTbUninstallTable (TableDesc);

    AcpiTbInitTableDescriptor (
        &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex],
        ACPI_PTR_TO_PHYSADDR (NewTable),
        ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, NewTable);

    ACPI_INFO ((
        "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
        NewTable->Length));

    return (NewTable);
}
示例#6
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_load_table
 *
 * PARAMETERS:  table               - Pointer to a buffer containing the ACPI
 *                                    table to be loaded.
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
 *              be a valid ACPI table with a valid ACPI table header.
 *              Note1: Mainly intended to support hotplug addition of SSDTs.
 *              Note2: Does not copy the incoming table. User is responsible
 *              to ensure that the table is not deleted or unmapped.
 *
 ******************************************************************************/
acpi_status acpi_load_table(struct acpi_table_header *table)
{
	acpi_status status;
	u32 table_index;

	ACPI_FUNCTION_TRACE(acpi_load_table);

	/* Parameter validation */

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

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

	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

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

	ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
						ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
						TRUE, FALSE, &table_index);

	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
	if (ACPI_FAILURE(status)) {
		goto unlock_and_exit;
	}

	/*
	 * Note: Now table is "INSTALLED", it must be validated before
	 * using.
	 */
	status =
	    acpi_tb_validate_table(&acpi_gbl_root_table_list.
				   tables[table_index]);
	if (ACPI_FAILURE(status)) {
		goto unlock_and_exit;
	}

	status = acpi_ns_load_table(table_index, acpi_gbl_root_node);

	/* Invoke table handler if present */

	if (acpi_gbl_table_handler) {
		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
					     acpi_gbl_table_handler_context);
	}

unlock_and_exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
	return_ACPI_STATUS(status);
}
示例#7
0
ACPI_STATUS
AcpiLoadTable (
    ACPI_TABLE_HEADER       *Table)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_DESC         TableDesc;
    UINT32                  TableIndex;


    ACPI_FUNCTION_TRACE (AcpiLoadTable);


    /* Parameter validation */

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

    /* Init local table descriptor */

    ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC));
    TableDesc.Address = ACPI_PTR_TO_PHYSADDR (Table);
    TableDesc.Pointer = Table;
    TableDesc.Length = Table->Length;
    TableDesc.Flags = ACPI_TABLE_ORIGIN_UNKNOWN;

    /* 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 ((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
    Status = AcpiTbAddTable (&TableDesc, &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);
}
示例#8
0
ACPI_STATUS AcpiOsGetPhysicalAddress(
		void *LogicalAddress,
		ACPI_PHYSICAL_ADDRESS *PhysicalAddress) {
	PRINTD("AcpiOsGetPhysicalAddress() called");

	if (!LogicalAddress || !PhysicalAddress) {
		return AE_BAD_PARAMETER;
	}

	*PhysicalAddress = ACPI_PTR_TO_PHYSADDR(LogicalAddress);

	return AE_OK;
}
示例#9
0
acpi_status acpi_load_table(struct acpi_table_header *table)
{
	acpi_status status;
	struct acpi_table_desc table_desc;
	u32 table_index;

	ACPI_FUNCTION_TRACE(acpi_load_table);

	/* Parameter validation */

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

	/* Init local table descriptor */

	ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
	table_desc.address = ACPI_PTR_TO_PHYSADDR(table);
	table_desc.pointer = table;
	table_desc.length = table->length;
	table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN;

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

	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

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

	ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
	status = acpi_tb_add_table(&table_desc, &table_index);
	if (ACPI_FAILURE(status)) {
		goto unlock_and_exit;
	}

	status = acpi_ns_load_table(table_index, acpi_gbl_root_node);

	/* Invoke table handler if present */

	if (acpi_gbl_table_handler) {
		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
					     acpi_gbl_table_handler_context);
	}

      unlock_and_exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
	return_ACPI_STATUS(status);
}
示例#10
0
文件: tbinstal.c 项目: rodero95/sys
ACPI_TABLE_HEADER *
AcpiTbTableOverride (
    ACPI_TABLE_HEADER       *TableHeader,
    ACPI_TABLE_DESC         *TableDesc)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       *NewTable = NULL;
    ACPI_PHYSICAL_ADDRESS   NewAddress = 0;
    UINT32                  NewTableLength = 0;
    UINT8                   NewFlags;
    char                    *OverrideType;


    /* (1) Attempt logical override (returns a logical address) */

    Status = AcpiOsTableOverride (TableHeader, &NewTable);
    if (ACPI_SUCCESS (Status) && NewTable)
    {
        NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
        NewTableLength = NewTable->Length;
        NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
        OverrideType = "Logical";
        goto FinishOverride;
    }

    /* (2) Attempt physical override (returns a physical address) */

    Status = AcpiOsPhysicalTableOverride (TableHeader,
        &NewAddress, &NewTableLength);
    if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
    {
        /* Map the entire new table */

        NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
        if (!NewTable)
        {
            ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
                "%4.4s %p Attempted physical table override failed",
                TableHeader->Signature,
                ACPI_CAST_PTR (void, TableDesc->Address)));
            return (NULL);
        }
示例#11
0
static ACPI_PHYSICAL_ADDRESS
AcpiEfiGetRsdpViaGuid (
    EFI_GUID                *Guid)
{
    ACPI_PHYSICAL_ADDRESS   Address = 0;
    int                     i;


    for (i = 0; i < ST->NumberOfTableEntries; i++)
    {
        if (AcpiEfiCompareGuid (&ST->ConfigurationTable[i].VendorGuid, Guid))
        {
            Address = ACPI_PTR_TO_PHYSADDR (
                    ST->ConfigurationTable[i].VendorTable);
            break;
        }
    }

    return (Address);
}
示例#12
0
struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
						 *table_header,
						 struct acpi_table_desc
						 *table_desc)
{
	acpi_status status;
	struct acpi_table_header *new_table = NULL;
	acpi_physical_address new_address = 0;
	u32 new_table_length = 0;
	u8 new_flags;
	char *override_type;

	/* (1) Attempt logical override (returns a logical address) */

	status = acpi_os_table_override(table_header, &new_table);
	if (ACPI_SUCCESS(status) && new_table) {
		new_address = ACPI_PTR_TO_PHYSADDR(new_table);
		new_table_length = new_table->length;
		new_flags = ACPI_TABLE_ORIGIN_OVERRIDE;
		override_type = "Logical";
		goto finish_override;
	}

	/* (2) Attempt physical override (returns a physical address) */

	status = acpi_os_physical_table_override(table_header,
						 &new_address,
						 &new_table_length);
	if (ACPI_SUCCESS(status) && new_address && new_table_length) {

		/* Map the entire new table */

		new_table = acpi_os_map_memory(new_address, new_table_length);
		if (!new_table) {
			ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
					"%4.4s %p Attempted physical table override failed",
					table_header->signature,
					ACPI_CAST_PTR(void,
						      table_desc->address)));
			return (NULL);
		}
示例#13
0
文件: tbxfload.c 项目: avagin/linux
/*******************************************************************************
 *
 * FUNCTION:    acpi_load_table
 *
 * PARAMETERS:  table               - Pointer to a buffer containing the ACPI
 *                                    table to be loaded.
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
 *              be a valid ACPI table with a valid ACPI table header.
 *              Note1: Mainly intended to support hotplug addition of SSDTs.
 *              Note2: Does not copy the incoming table. User is responsible
 *              to ensure that the table is not deleted or unmapped.
 *
 ******************************************************************************/
acpi_status acpi_load_table(struct acpi_table_header *table)
{
	acpi_status status;
	u32 table_index;

	ACPI_FUNCTION_TRACE(acpi_load_table);

	/* Parameter validation */

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

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

	ACPI_INFO(("Host-directed Dynamic ACPI Table Load:"));
	status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
						ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
						FALSE, &table_index);
	return_ACPI_STATUS(status);
}
示例#14
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);
}
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);
}
acpi_status
acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
	u32 i;
	acpi_status status = AE_OK;
	struct acpi_table_header *override_table = NULL;

	ACPI_FUNCTION_TRACE(tb_add_table);

	if (!table_desc->pointer) {
		status = acpi_tb_verify_table(table_desc);
		if (ACPI_FAILURE(status) || !table_desc->pointer) {
			return_ACPI_STATUS(status);
		}
	}

	/*
	 * Originally, we checked the table signature for "SSDT" or "PSDT" here.
	 * Next, we added support for OEMx tables, signature "OEM".
	 * Valid tables were encountered with a null signature, so we've just
	 * given up on validating the signature, since it seems to be a waste
	 * of code. The original code was removed (05/2008).
	 */

	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	/* Check if table is already registered */

	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
		if (!acpi_gbl_root_table_list.tables[i].pointer) {
			status =
			    acpi_tb_verify_table(&acpi_gbl_root_table_list.
						 tables[i]);
			if (ACPI_FAILURE(status)
			    || !acpi_gbl_root_table_list.tables[i].pointer) {
				continue;
			}
		}

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

		if (ACPI_MEMCMP(table_desc->pointer,
				acpi_gbl_root_table_list.tables[i].pointer,
				acpi_gbl_root_table_list.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.
		 */
		acpi_tb_delete_table(table_desc);
		*table_index = i;

		if (acpi_gbl_root_table_list.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 */

			table_desc->pointer =
			    acpi_gbl_root_table_list.tables[i].pointer;
			table_desc->address =
			    acpi_gbl_root_table_list.tables[i].address;
			status = AE_OK;
			goto print_header;
		}
	}

	/*
	 * ACPI Table Override:
	 * Allow the host to override dynamically loaded tables.
	 */
	status = acpi_os_table_override(table_desc->pointer, &override_table);
	if (ACPI_SUCCESS(status) && override_table) {
		ACPI_INFO((AE_INFO,
			   "%4.4s @ 0x%p Table override, replaced with:",
			   table_desc->pointer->signature,
			   ACPI_CAST_PTR(void, table_desc->address)));

		/* We can delete the table that was passed as a parameter */

		acpi_tb_delete_table(table_desc);

		/* Setup descriptor for the new table */

		table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
		table_desc->pointer = override_table;
		table_desc->length = override_table->length;
		table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
	}
示例#17
0
文件: dsopcode.c 项目: ModeenF/haiku
ACPI_STATUS
AcpiDsEvalTableRegionOperands (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_STATUS             Status;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_OPERAND_OBJECT     **Operand;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_PARSE_OBJECT       *NextOp;
    ACPI_TABLE_HEADER       *Table;
    UINT32                  TableIndex;


    ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);


    /*
     * This is where we evaluate the Signature string, OemId string,
     * and OemTableId string of the Data Table Region declaration
     */
    Node =  Op->Common.Node;

    /* NextOp points to Signature string op */

    NextOp = Op->Common.Value.Arg;

    /*
     * Evaluate/create the Signature string, OemId string,
     * and OemTableId string operands
     */
    Status = AcpiDsCreateOperands (WalkState, NextOp);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Operand = &WalkState->Operands[0];

    /*
     * Resolve the Signature string, OemId string,
     * and OemTableId string operands
     */
    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
                ACPI_WALK_OPERANDS, WalkState);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Find the ACPI table */

    Status = AcpiTbFindTable (
                Operand[0]->String.Pointer,
                Operand[1]->String.Pointer,
                Operand[2]->String.Pointer, &TableIndex);
    if (ACPI_FAILURE (Status))
    {
        if (Status == AE_NOT_FOUND)
        {
            ACPI_ERROR ((AE_INFO,
                "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
                Operand[0]->String.Pointer,
                Operand[1]->String.Pointer,
                Operand[2]->String.Pointer));
        }
        goto Cleanup;
    }

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

    ObjDesc = AcpiNsGetAttachedObject (Node);
    if (!ObjDesc)
    {
        Status = AE_NOT_EXIST;
        goto Cleanup;
    }

    ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table);
    ObjDesc->Region.Length = Table->Length;

    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
        ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
        ObjDesc->Region.Length));

    /* Now the address and length are valid for this opregion */

    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;

Cleanup:
    AcpiUtRemoveReference (Operand[0]);
    AcpiUtRemoveReference (Operand[1]);
    AcpiUtRemoveReference (Operand[2]);

    return_ACPI_STATUS (Status);
}
示例#18
0
ACPI_STATUS
AnBuildLocalTables (
    ACPI_NEW_TABLE_DESC     *TableList)
{
    UINT32                  TableCount = 0;
    ACPI_PHYSICAL_ADDRESS   DsdtAddress = 0;
    UINT32                  XsdtSize;
    ACPI_NEW_TABLE_DESC     *NextTable;
    UINT32                  NextIndex;
    ACPI_TABLE_FADT         *ExternalFadt = NULL;


    /*
     * Update the table count. For the DSDT, it is not put into the XSDT.
     * For the FADT, this table is already accounted for since we usually
     * install a local FADT.
     */
    NextTable = TableList;
    while (NextTable)
    {
        if (!ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) &&
            !ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            TableCount++;
        }

        NextTable = NextTable->Next;
    }

    XsdtSize = BASE_XSDT_SIZE + (TableCount * sizeof (UINT64));

    /* Build an XSDT */

    LocalXSDT = AcpiOsAllocate (XsdtSize);
    if (!LocalXSDT)
    {
        return (AE_NO_MEMORY);
    }

    memset (LocalXSDT, 0, XsdtSize);
    LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);

    /*
     * Install the user tables. The DSDT must be installed in the FADT.
     * All other tables are installed directly into the XSDT.
     *
     * Note: The tables are loaded in reverse order from the incoming
     * input, which makes it match the command line order.
     */
    NextIndex = BASE_XSDT_TABLES;
    NextTable = TableList;
    while (NextTable)
    {
        /*
         * Incoming DSDT or FADT are special cases. All other tables are
         * just immediately installed into the XSDT.
         */
        if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT))
        {
            if (DsdtAddress)
            {
                printf ("Already found a DSDT, only one allowed\n");
                return (AE_ALREADY_EXISTS);
            }

            /* The incoming user table is a DSDT */

            DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            ExternalFadt =
                ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table);
            LocalXSDT->TableOffsetEntry[0] =
                ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else
        {
            /* Install the table in the XSDT */

            LocalXSDT->TableOffsetEntry[TableCount - NextIndex + 1] =
                ACPI_PTR_TO_PHYSADDR (NextTable->Table);
            NextIndex++;
        }

        NextTable = NextTable->Next;
    }

    /* Build an RSDP. Contains a valid XSDT only, no RSDT */

    memset (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
    ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature);
    memcpy (LocalRSDP.OemId, "Intel", 6);

    LocalRSDP.Revision = 2;
    LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT);
    LocalRSDP.Length = sizeof (ACPI_TABLE_XSDT);

    /* Set checksums for both XSDT and RSDP */

    AnInitializeTableHeader ((void *) LocalXSDT, ACPI_SIG_XSDT, XsdtSize);

    LocalRSDP.Checksum = 0;
    LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum (
        (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH);

    if (!DsdtAddress)
    {
        return (AE_SUPPORT);
    }

    /*
     * Build an FADT. There are two options for the FADT:
     * 1) Incoming external FADT specified on the command line
     * 2) A fully featured local FADT
     */
    memset (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT));

    if (ExternalFadt)
    {
        /*
         * Use the external FADT, but we must update the DSDT/FACS
         * addresses as well as the checksum
         */
        ExternalFadt->Dsdt = (UINT32) DsdtAddress;
        ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        /*
         * If there room in the FADT for the XDsdt and XFacs 64-bit
         * pointers, use them.
         */
        if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (
            &ExternalFadt->XDsdt, ExternalFadt))
        {
            ExternalFadt->Dsdt = 0;
            ExternalFadt->Facs = 0;
            ExternalFadt->XDsdt = DsdtAddress;
            ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
        }

        /* Complete the external FADT with the checksum */

        ExternalFadt->Header.Checksum = 0;
        ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) ExternalFadt, ExternalFadt->Header.Length);
    }
    else
    {
        /*
         * Build a local FADT so we can test the hardware/event init
         */
        LocalFADT.Header.Revision = 5;

        /* Setup FADT header and DSDT/FACS addresses */

        LocalFADT.Dsdt = 0;
        LocalFADT.Facs = 0;

        LocalFADT.XDsdt = DsdtAddress;
        LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        /* Miscellaneous FADT fields */

        LocalFADT.Gpe0BlockLength = 16;
        LocalFADT.Gpe0Block = 0x00001234;

        LocalFADT.Gpe1BlockLength = 6;
        LocalFADT.Gpe1Block = 0x00005678;
        LocalFADT.Gpe1Base = 96;

        LocalFADT.Pm1EventLength = 4;
        LocalFADT.Pm1aEventBlock = 0x00001aaa;
        LocalFADT.Pm1bEventBlock = 0x00001bbb;

        LocalFADT.Pm1ControlLength = 2;
        LocalFADT.Pm1aControlBlock = 0xB0;

        LocalFADT.PmTimerLength = 4;
        LocalFADT.PmTimerBlock = 0xA0;

        LocalFADT.Pm2ControlBlock = 0xC0;
        LocalFADT.Pm2ControlLength = 1;

        /* Setup one example X-64 field */

        LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
        LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock;
        LocalFADT.XPm1bEventBlock.BitWidth = (UINT8)
            ACPI_MUL_8 (LocalFADT.Pm1EventLength);
    }

    AnInitializeTableHeader ((void *) &LocalFADT,
        ACPI_SIG_FADT, sizeof (ACPI_TABLE_FADT));

    /* Build a FACS */

    memset (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
    ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS);

    LocalFACS.Length = sizeof (ACPI_TABLE_FACS);
    LocalFACS.GlobalLock = 0x11AA0011;
    return (AE_OK);
}
示例#19
0
void
AcpiTbOverrideTable (
    ACPI_TABLE_DESC         *OldTableDesc)
{
    ACPI_STATUS             Status;
    char                    *OverrideType;
    ACPI_TABLE_DESC         NewTableDesc;
    ACPI_TABLE_HEADER       *Table;
    ACPI_PHYSICAL_ADDRESS   Address;
    UINT32                  Length;


    /* (1) Attempt logical override (returns a logical address) */

    Status = AcpiOsTableOverride (OldTableDesc->Pointer, &Table);
    if (ACPI_SUCCESS (Status) && Table)
    {
        AcpiTbAcquireTempTable (&NewTableDesc, ACPI_PTR_TO_PHYSADDR (Table),
            ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
        OverrideType = "Logical";
        goto FinishOverride;
    }

    /* (2) Attempt physical override (returns a physical address) */

    Status = AcpiOsPhysicalTableOverride (OldTableDesc->Pointer,
        &Address, &Length);
    if (ACPI_SUCCESS (Status) && Address && Length)
    {
        AcpiTbAcquireTempTable (&NewTableDesc, Address,
            ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
        OverrideType = "Physical";
        goto FinishOverride;
    }

    return; /* There was no override */


FinishOverride:

    /* Validate and verify a table before overriding */

    Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL);
    if (ACPI_FAILURE (Status))
    {
        return;
    }

    ACPI_INFO ((AE_INFO, "%4.4s 0x%8.8X%8.8X"
        " %s table override, new table: 0x%8.8X%8.8X",
        OldTableDesc->Signature.Ascii,
        ACPI_FORMAT_UINT64 (OldTableDesc->Address),
        OverrideType, ACPI_FORMAT_UINT64 (NewTableDesc.Address)));

    /* We can now uninstall the original table */

    AcpiTbUninstallTable (OldTableDesc);

    /*
     * Replace the original table descriptor and keep its state as
     * "VALIDATED".
     */
    AcpiTbInitTableDescriptor (OldTableDesc, NewTableDesc.Address,
        NewTableDesc.Flags, NewTableDesc.Pointer);
    AcpiTbValidateTempTable (OldTableDesc);

    /* Release the temporary table descriptor */

    AcpiTbReleaseTempTable (&NewTableDesc);
}
struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
        *table_header,
        struct acpi_table_desc
        *table_desc)
{
    acpi_status status;
    struct acpi_table_header *new_table = NULL;
    acpi_physical_address new_address = 0;
    u32 new_table_length = 0;
    u8 new_flags;
    char *override_type;

    /* (1) Attempt logical override (returns a logical address) */

    status = acpi_os_table_override(table_header, &new_table);
    if (ACPI_SUCCESS(status) && new_table) {
        new_address = ACPI_PTR_TO_PHYSADDR(new_table);
        new_table_length = new_table->length;
        new_flags = ACPI_TABLE_ORIGIN_OVERRIDE;
        override_type = "Logical";
        goto finish_override;
    }

    /* (2) Attempt physical override (returns a physical address) */

    status = acpi_os_physical_table_override(table_header,
             &new_address,
             &new_table_length);
    if (ACPI_SUCCESS(status) && new_address && new_table_length) {

        /* Map the entire new table */

        new_table = acpi_os_map_memory(new_address, new_table_length);
        if (!new_table) {
            ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
                            "%4.4s %p Attempted physical table override failed",
                            table_header->signature,
                            ACPI_PHYSADDR_TO_PTR(table_desc->address)));
            return (NULL);
        }

        override_type = "Physical";
        new_flags = ACPI_TABLE_ORIGIN_MAPPED;
        goto finish_override;
    }

    return (NULL);		/* There was no override */

finish_override:

    ACPI_INFO((AE_INFO,
               "%4.4s %p %s table override, new table: %p",
               table_header->signature,
               ACPI_PHYSADDR_TO_PTR(table_desc->address),
               override_type, new_table));

    /* We can now unmap/delete the original table (if fully mapped) */

    acpi_tb_delete_table(table_desc);

    /* Setup descriptor for the new table */

    table_desc->address = new_address;
    table_desc->pointer = new_table;
    table_desc->length = new_table_length;
    table_desc->flags = new_flags;

    return (new_table);
}
示例#21
0
acpi_status
acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
	u32 i;
	acpi_status status = AE_OK;
	struct acpi_table_header *override_table = NULL;

	ACPI_FUNCTION_TRACE(tb_add_table);

	if (!table_desc->pointer) {
		status = acpi_tb_verify_table(table_desc);
		if (ACPI_FAILURE(status) || !table_desc->pointer) {
			return_ACPI_STATUS(status);
		}
	}

	

	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	

	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
		if (!acpi_gbl_root_table_list.tables[i].pointer) {
			status =
			    acpi_tb_verify_table(&acpi_gbl_root_table_list.
						 tables[i]);
			if (ACPI_FAILURE(status)
			    || !acpi_gbl_root_table_list.tables[i].pointer) {
				continue;
			}
		}

		
		if (table_desc->length !=
		    acpi_gbl_root_table_list.tables[i].length) {
			continue;
		}

		if (ACPI_MEMCMP(table_desc->pointer,
				acpi_gbl_root_table_list.tables[i].pointer,
				acpi_gbl_root_table_list.tables[i].length)) {
			continue;
		}

		

		
		acpi_tb_delete_table(table_desc);
		*table_index = i;

		if (acpi_gbl_root_table_list.tables[i].
		    flags & ACPI_TABLE_IS_LOADED) {

			

			status = AE_ALREADY_EXISTS;
			goto release;
		} else {
			

			table_desc->pointer =
			    acpi_gbl_root_table_list.tables[i].pointer;
			table_desc->address =
			    acpi_gbl_root_table_list.tables[i].address;
			status = AE_OK;
			goto print_header;
		}
	}

	
	status = acpi_os_table_override(table_desc->pointer, &override_table);
	if (ACPI_SUCCESS(status) && override_table) {
		ACPI_INFO((AE_INFO,
			   "%4.4s @ 0x%p Table override, replaced with:",
			   table_desc->pointer->signature,
			   ACPI_CAST_PTR(void, table_desc->address)));

		

		acpi_tb_delete_table(table_desc);

		

		table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
		table_desc->pointer = override_table;
		table_desc->length = override_table->length;
		table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
	}
示例#22
0
ACPI_STATUS
AeBuildLocalTables (
    ACPI_NEW_TABLE_DESC     *ListHead)
{
    UINT32                  TableCount = 1;
    ACPI_PHYSICAL_ADDRESS   DsdtAddress = 0;
    UINT32                  XsdtSize;
    ACPI_NEW_TABLE_DESC     *NextTable;
    UINT32                  NextIndex;
    ACPI_TABLE_FADT         *ExternalFadt = NULL;


    /*
     * Update the table count. For the DSDT, it is not put into the XSDT.
     * For the FADT, this table is already accounted for since we usually
     * install a local FADT.
     */
    NextTable = ListHead;
    while (NextTable)
    {
        if (!ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) &&
            !ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            TableCount++;
        }

        NextTable = NextTable->Next;
    }

    XsdtSize = (((TableCount + 1) * sizeof (UINT64)) +
        sizeof (ACPI_TABLE_HEADER));
    if (AcpiGbl_LoadTestTables)
    {
        XsdtSize += BASE_XSDT_SIZE;
    }

    /* Build an XSDT */

    LocalXSDT = AcpiOsAllocate (XsdtSize);
    if (!LocalXSDT)
    {
        return (AE_NO_MEMORY);
    }

    memset (LocalXSDT, 0, XsdtSize);
    LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);
    NextIndex = 1;

    /*
     * Install the user tables. The DSDT must be installed in the FADT.
     * All other tables are installed directly into the XSDT.
     */
    NextTable = ListHead;
    while (NextTable)
    {
        /*
         * Incoming DSDT or FADT are special cases. All other tables are
         * just immediately installed into the XSDT.
         */
        if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT))
        {
            if (DsdtAddress)
            {
                printf ("Already found a DSDT, only one allowed\n");
                return (AE_ALREADY_EXISTS);
            }

            /* The incoming user table is a DSDT */

            DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
            DsdtToInstallOverride = NextTable->Table;
        }
        else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table);
            LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else
        {
            /* Install the table in the XSDT */

            LocalXSDT->TableOffsetEntry[NextIndex] =
                ACPI_PTR_TO_PHYSADDR (NextTable->Table);
            NextIndex++;
        }

        NextTable = NextTable->Next;
    }

    /* Install the optional extra local tables */

    if (AcpiGbl_LoadTestTables)
    {
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&LocalTEST);
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&LocalBADTABLE);

        /* Install two SSDTs to test multiple table support */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Ssdt1Code);
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Ssdt2Code);

        /* Install the OEM1 table to test LoadTable */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Oem1Code);

        /* Install the OEMx table to test LoadTable */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&OemxCode);

         /* Install the ECDT table to test _REG */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&EcdtCode);

        /* Install two UEFIs to test multiple table support */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Uefi1Code);
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Uefi2Code);
    }

    /* Build an RSDP. Contains a valid XSDT only, no RSDT */

    memset (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
    ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature);
    memcpy (LocalRSDP.OemId, "Intel", 6);

    LocalRSDP.Revision = 2;
    LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT);
    LocalRSDP.Length = sizeof (ACPI_TABLE_RSDP);

    /* Set checksums for both XSDT and RSDP */

    AeInitializeTableHeader ((void *) LocalXSDT, ACPI_SIG_XSDT, XsdtSize);

    LocalRSDP.Checksum = 0;
    LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum (
        (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH);

    if (!DsdtAddress)
    {
        /* Use the local DSDT because incoming table(s) are all SSDT(s) */

        DsdtAddress = ACPI_PTR_TO_PHYSADDR (LocalDsdtCode);
        DsdtToInstallOverride = ACPI_CAST_PTR (ACPI_TABLE_HEADER, LocalDsdtCode);
    }

    /*
     * Build an FADT. There are three options for the FADT:
     * 1) Incoming external FADT specified on the command line
     * 2) A "hardware reduced" local FADT
     * 3) A fully featured local FADT
     */
    memset (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT));

    if (ExternalFadt)
    {
        /*
         * Use the external FADT, but we must update the DSDT/FACS
         * addresses as well as the checksum
         */
        ExternalFadt->Dsdt = (UINT32) DsdtAddress;
        if (!AcpiGbl_ReducedHardware)
        {
            ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
        }

        /*
         * If there room in the FADT for the XDsdt and XFacs 64-bit
         * pointers, use them.
         */
        if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (
            &ExternalFadt->XDsdt, ExternalFadt))
        {
            ExternalFadt->Dsdt = 0;
            ExternalFadt->Facs = 0;

            ExternalFadt->XDsdt = DsdtAddress;
            if (!AcpiGbl_ReducedHardware)
            {
                ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
            }
        }

        /* Complete the external FADT with the checksum */

        ExternalFadt->Header.Checksum = 0;
        ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) ExternalFadt, ExternalFadt->Header.Length);
    }
    else if (AcpiGbl_UseHwReducedFadt)
    {
        memcpy (&LocalFADT, HwReducedFadtCode, ACPI_FADT_V5_SIZE);
        LocalFADT.Dsdt = 0;
        LocalFADT.XDsdt = DsdtAddress;
    }
    else
    {
        /*
         * Build a local FADT so we can test the hardware/event init
         */
        LocalFADT.Header.Revision = 5;

        /* Setup FADT header and DSDT/FACS addresses */

        LocalFADT.Dsdt = 0;
        LocalFADT.Facs = 0;

        LocalFADT.XDsdt = DsdtAddress;
        LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        /* Miscellaneous FADT fields */

        LocalFADT.Gpe0BlockLength = 0x08;
        LocalFADT.Gpe0Block = 0x00001234;

        LocalFADT.Gpe1BlockLength = 0x80;
        LocalFADT.Gpe1Block = 0x00005678;
        LocalFADT.Gpe1Base = 100;

        LocalFADT.Pm1EventLength = 4;
        LocalFADT.Pm1aEventBlock = 0x00001aaa;
        LocalFADT.Pm1bEventBlock = 0x00001bbb;

        LocalFADT.Pm1ControlLength = 2;
        LocalFADT.Pm1aControlBlock = 0xB0;

        LocalFADT.PmTimerLength = 4;
        LocalFADT.PmTimerBlock = 0xA0;

        LocalFADT.Pm2ControlBlock = 0xC0;
        LocalFADT.Pm2ControlLength = 1;

        /* Setup one example X-64 GAS field */

        LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
        LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock;
        LocalFADT.XPm1bEventBlock.BitWidth = (UINT8)
            ACPI_MUL_8 (LocalFADT.Pm1EventLength);
    }

    AeInitializeTableHeader ((void *) &LocalFADT,
        ACPI_SIG_FADT, sizeof (ACPI_TABLE_FADT));

    /* Build a FACS */

    memset (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
    ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS);

    LocalFACS.Length = sizeof (ACPI_TABLE_FACS);
    LocalFACS.GlobalLock = 0x11AA0011;

    /* Build the optional local tables */

    if (AcpiGbl_LoadTestTables)
    {
        /*
         * Build a fake table [TEST] so that we make sure that the
         * ACPICA core ignores it
         */
        memset (&LocalTEST, 0, sizeof (ACPI_TABLE_HEADER));
        ACPI_MOVE_NAME (LocalTEST.Signature, "TEST");

        LocalTEST.Revision = 1;
        LocalTEST.Length = sizeof (ACPI_TABLE_HEADER);

        LocalTEST.Checksum = 0;
        LocalTEST.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) &LocalTEST, LocalTEST.Length);

        /*
         * Build a fake table with a bad signature [BAD!] so that we make
         * sure that the ACPICA core ignores it
         */
        memset (&LocalBADTABLE, 0, sizeof (ACPI_TABLE_HEADER));
        ACPI_MOVE_NAME (LocalBADTABLE.Signature, "BAD!");

        LocalBADTABLE.Revision = 1;
        LocalBADTABLE.Length = sizeof (ACPI_TABLE_HEADER);

        LocalBADTABLE.Checksum = 0;
        LocalBADTABLE.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) &LocalBADTABLE, LocalBADTABLE.Length);
    }

    return (AE_OK);
}
acpi_status
acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
				   union acpi_parse_object *op)
{
	acpi_status status;
	union acpi_operand_object *obj_desc;
	union acpi_operand_object **operand;
	struct acpi_namespace_node *node;
	union acpi_parse_object *next_op;
	u32 table_index;
	struct acpi_table_header *table;

	ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);

	/*
	 * This is where we evaluate the Signature string, oem_id string,
	 * and oem_table_id string of the Data Table Region declaration
	 */
	node = op->common.node;

	/* next_op points to Signature string op */

	next_op = op->common.value.arg;

	/*
	 * Evaluate/create the Signature string, oem_id string,
	 * and oem_table_id string operands
	 */
	status = acpi_ds_create_operands(walk_state, next_op);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Resolve the Signature string, oem_id string,
	 * and oem_table_id string operands
	 */
	status = acpi_ex_resolve_operands(op->common.aml_opcode,
					  ACPI_WALK_OPERANDS, walk_state);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	operand = &walk_state->operands[0];

	/* Find the ACPI table */

	status = acpi_tb_find_table(operand[0]->string.pointer,
				    operand[1]->string.pointer,
				    operand[2]->string.pointer, &table_index);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	acpi_ut_remove_reference(operand[0]);
	acpi_ut_remove_reference(operand[1]);
	acpi_ut_remove_reference(operand[2]);

	status = acpi_get_table_by_index(table_index, &table);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	obj_desc = acpi_ns_get_attached_object(node);
	if (!obj_desc) {
		return_ACPI_STATUS(AE_NOT_EXIST);
	}

	obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
	obj_desc->region.length = table->length;

	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
			  obj_desc,
			  ACPI_FORMAT_UINT64(obj_desc->region.address),
			  obj_desc->region.length));

	/* Now the address and length are valid for this opregion */

	obj_desc->region.flags |= AOPOBJ_DATA_VALID;

	return_ACPI_STATUS(status);
}
示例#24
0
ACPI_STATUS
AcpiTbAddTable (
    ACPI_TABLE_DESC         *TableDesc,
    UINT32                  *TableIndex)
{
    UINT32                  i;
    ACPI_STATUS             Status = AE_OK;
    ACPI_TABLE_HEADER       *OverrideTable = NULL;


    ACPI_FUNCTION_TRACE (TbAddTable);


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

    /*
     * Originally, we checked the table signature for "SSDT" or "PSDT" here.
     * Next, we added support for OEMx tables, signature "OEM".
     * Valid tables were encountered with a null signature, so we've just
     * given up on validating the signature, since it seems to be a waste
     * of code. The original code was removed (05/2008).
     */

    (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.
     */
    Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable);
    if (ACPI_SUCCESS (Status) && OverrideTable)
    {
        ACPI_INFO ((AE_INFO,
            "%4.4s @ 0x%p Table override, replaced with:",
            TableDesc->Pointer->Signature,
            ACPI_CAST_PTR (void, TableDesc->Address)));

        /* 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;
    }
示例#25
0
ACPI_STATUS
AeBuildLocalTables (
    UINT32                  TableCount,
    AE_TABLE_DESC           *TableList)
{
    ACPI_PHYSICAL_ADDRESS   DsdtAddress = 0;
    UINT32                  XsdtSize;
    AE_TABLE_DESC           *NextTable;
    UINT32                  NextIndex;
    ACPI_TABLE_FADT         *ExternalFadt = NULL;


    /*
     * Update the table count. For DSDT, it is not put into the XSDT. For
     * FADT, this is already accounted for since we usually install a
     * local FADT.
     */
    NextTable = TableList;
    while (NextTable)
    {
        if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) ||
            ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            TableCount--;
        }
        NextTable = NextTable->Next;
    }

    XsdtSize = BASE_XSDT_SIZE + (TableCount * sizeof (UINT64));

    /* Build an XSDT */

    LocalXSDT = AcpiOsAllocate (XsdtSize);
    if (!LocalXSDT)
    {
        return (AE_NO_MEMORY);
    }

    ACPI_MEMSET (LocalXSDT, 0, XsdtSize);
    ACPI_MOVE_NAME (LocalXSDT->Header.Signature, ACPI_SIG_XSDT);
    LocalXSDT->Header.Length = XsdtSize;
    LocalXSDT->Header.Revision = 1;

    LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);

    /*
     * Install the user tables. The DSDT must be installed in the FADT.
     * All other tables are installed directly into the XSDT.
     */
    NextIndex = BASE_XSDT_TABLES;
    NextTable = TableList;
    while (NextTable)
    {
        /*
         * Incoming DSDT or FADT are special cases. All other tables are
         * just immediately installed into the XSDT.
         */
        if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT))
        {
            if (DsdtAddress)
            {
                printf ("Already found a DSDT, only one allowed\n");
                return (AE_ALREADY_EXISTS);
            }

            /* The incoming user table is a DSDT */

            DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table);
            LocalXSDT->TableOffsetEntry[2] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else
        {
            /* Install the table in the XSDT */

            LocalXSDT->TableOffsetEntry[NextIndex] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
            NextIndex++;
        }

        NextTable = NextTable->Next;
    }

    /* Build an RSDP */

    ACPI_MEMSET (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
    ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature);
    ACPI_MEMCPY (LocalRSDP.OemId, "I_TEST", 6);
    LocalRSDP.Revision = 2;
    LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT);
    LocalRSDP.Length = sizeof (ACPI_TABLE_XSDT);

    /* Set checksums for both XSDT and RSDP */

    LocalXSDT->Header.Checksum = (UINT8) -AcpiTbChecksum (
        (void *) LocalXSDT, LocalXSDT->Header.Length);
    LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum (
        (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH);

    if (!DsdtAddress)
    {
        return (AE_SUPPORT);
    }

    if (ExternalFadt)
    {
        /*
         * Use the external FADT, but we must update the DSDT/FACS addresses
         * as well as the checksum
         */
        ExternalFadt->Dsdt = DsdtAddress;
        ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (&ExternalFadt->XDsdt, ExternalFadt))
        {
            ExternalFadt->XDsdt = DsdtAddress;
            ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
        }
        /* Complete the FADT with the checksum */

        ExternalFadt->Header.Checksum = 0;
        ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) ExternalFadt, ExternalFadt->Header.Length);
    }
    else
    {
        /*
         * Build a local FADT so we can test the hardware/event init
         */
        ACPI_MEMSET (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT));
        ACPI_MOVE_NAME (LocalFADT.Header.Signature, ACPI_SIG_FADT);

        /* Setup FADT header and DSDT/FACS addresses */

        LocalFADT.Dsdt = 0;
        LocalFADT.Facs = 0;

        LocalFADT.XDsdt = DsdtAddress;
        LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        LocalFADT.Header.Revision = 3;
        LocalFADT.Header.Length = sizeof (ACPI_TABLE_FADT);

        /* Miscellaneous FADT fields */

        LocalFADT.Gpe0BlockLength = 16;
        LocalFADT.Gpe0Block = 0x00001234;

        LocalFADT.Gpe1BlockLength = 6;
        LocalFADT.Gpe1Block = 0x00005678;
        LocalFADT.Gpe1Base = 96;

        LocalFADT.Pm1EventLength = 4;
        LocalFADT.Pm1aEventBlock = 0x00001aaa;
        LocalFADT.Pm1bEventBlock = 0x00001bbb;

        LocalFADT.Pm1ControlLength = 2;
        LocalFADT.Pm1aControlBlock = 0xB0;

        LocalFADT.PmTimerLength = 4;
        LocalFADT.PmTimerBlock = 0xA0;

        LocalFADT.Pm2ControlBlock = 0xC0;
        LocalFADT.Pm2ControlLength = 1;

        /* Setup one example X-64 field */

        LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
        LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock;
        LocalFADT.XPm1bEventBlock.BitWidth = (UINT8) ACPI_MUL_8 (LocalFADT.Pm1EventLength);

        /* Complete the FADT with the checksum */

        LocalFADT.Header.Checksum = 0;
        LocalFADT.Header.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) &LocalFADT, LocalFADT.Header.Length);
    }

    /* Build a FACS */

    ACPI_MEMSET (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
    ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS);

    LocalFACS.Length = sizeof (ACPI_TABLE_FACS);
    LocalFACS.GlobalLock = 0x11AA0011;

    return (AE_OK);
}
示例#26
0
文件: tbxfload.c 项目: alex1818/fwts
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);
}
示例#27
0
ACPI_STATUS
AcpiTbAddTable (
    ACPI_TABLE_DESC         *TableDesc,
    UINT32                  *TableIndex)
{
    UINT32                  i;
    ACPI_STATUS             Status = AE_OK;
    ACPI_TABLE_HEADER       *OverrideTable = NULL;


    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_ERROR ((AE_INFO,
            "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
            AcpiUtValidAcpiName (*(UINT32 *) 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.
     */
    Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable);
    if (ACPI_SUCCESS (Status) && OverrideTable)
    {
        ACPI_INFO ((AE_INFO,
            "%4.4s @ 0x%p Table override, replaced with:",
            TableDesc->Pointer->Signature,
            ACPI_CAST_PTR (void, TableDesc->Address)));

        /* 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;
    }