Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43323cb4 authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

ACPICA: Update DSDT copy/detection.



Move initialization of DSDT pointer. Emit address of DSDT
in the dump of both table headers (good/bad DSDT).
Now handles the case where the root table can be reallocated,
which would invalidate the original pointer.

Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 69ec87ef
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -175,7 +175,7 @@ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;

/* DSDT information. Used to check for DSDT corruption */

ACPI_EXTERN struct acpi_table_desc *acpi_gbl_DSDT;
ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT;
ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header;

/*
+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);

void acpi_tb_check_dsdt_header(void);

void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc);
struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index);

void
acpi_tb_install_table(acpi_physical_address address,
+12 −11
Original line number Diff line number Diff line
@@ -366,22 +366,18 @@ void acpi_tb_check_dsdt_header(void)

	/* Compare original length and checksum to current values */

	if (acpi_gbl_original_dsdt_header.length !=
	    acpi_gbl_DSDT->pointer->length
	    || acpi_gbl_original_dsdt_header.checksum !=
	    acpi_gbl_DSDT->pointer->checksum) {
	if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length ||
	    acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {
		ACPI_ERROR((AE_INFO,
			    "The DSDT has been corrupted or replaced - old, new headers below"));
		acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
		acpi_tb_print_table_header(acpi_gbl_DSDT->address,
					   acpi_gbl_DSDT->pointer);
		acpi_tb_print_table_header(0, acpi_gbl_DSDT);

		/* Disable further error messages */

		acpi_gbl_original_dsdt_header.length =
		    acpi_gbl_DSDT->pointer->length;
		acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
		acpi_gbl_original_dsdt_header.checksum =
		    acpi_gbl_DSDT->pointer->checksum;
		    acpi_gbl_DSDT->checksum;
	}
}

@@ -399,15 +395,18 @@ void acpi_tb_check_dsdt_header(void)
 *
 ******************************************************************************/

void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc)
struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
{
	struct acpi_table_header *new_table;
	struct acpi_table_desc *table_desc;

	table_desc = &acpi_gbl_root_table_list.tables[table_index];

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

	ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
@@ -418,6 +417,8 @@ void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc)
	ACPI_INFO((AE_INFO,
		   "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
		   new_table->length));

	return (new_table);
}

/*******************************************************************************
+23 −6
Original line number Diff line number Diff line
@@ -513,24 +513,38 @@ static acpi_status acpi_tb_load_namespace(void)
{
	acpi_status status;
	u32 i;
	struct acpi_table_header *new_dsdt;

	ACPI_FUNCTION_TRACE(tb_load_namespace);

	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	acpi_gbl_DSDT = &acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT];

	/*
	 * Load the namespace. The DSDT is required, but any SSDT and
	 * PSDT tables are optional. Verify the DSDT.
	 */
	if (!acpi_gbl_root_table_list.count ||
	    !ACPI_COMPARE_NAME(&acpi_gbl_DSDT->signature, ACPI_SIG_DSDT) ||
	    ACPI_FAILURE(acpi_tb_verify_table(acpi_gbl_DSDT))) {
	    !ACPI_COMPARE_NAME(&
			       (acpi_gbl_root_table_list.
				tables[ACPI_TABLE_INDEX_DSDT].signature),
			       ACPI_SIG_DSDT)
	    ||
	    ACPI_FAILURE(acpi_tb_verify_table
			 (&acpi_gbl_root_table_list.
			  tables[ACPI_TABLE_INDEX_DSDT]))) {
		status = AE_NO_ACPI_TABLES;
		goto unlock_and_exit;
	}

	/*
	 * 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 acpi_tb_verify_table.
	 */
	acpi_gbl_DSDT =
	    acpi_gbl_root_table_list.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
@@ -538,14 +552,17 @@ static acpi_status acpi_tb_load_namespace(void)
	 * the DSDT.
	 */
	if (acpi_gbl_copy_dsdt_locally) {
		acpi_tb_copy_dsdt(acpi_gbl_DSDT);
		new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT);
		if (new_dsdt) {
			acpi_gbl_DSDT = new_dsdt;
		}
	}

	/*
	 * Save the original DSDT header for detection of table corruption
	 * and/or replacement of the DSDT from outside the OS.
	 */
	ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT->pointer,
	ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,
		    sizeof(struct acpi_table_header));

	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+1 −0
Original line number Diff line number Diff line
@@ -785,6 +785,7 @@ acpi_status acpi_ut_init_globals(void)

	/* Miscellaneous variables */

	acpi_gbl_DSDT = NULL;
	acpi_gbl_cm_single_step = FALSE;
	acpi_gbl_db_terminate_threads = FALSE;
	acpi_gbl_shutdown = FALSE;