示例#1
0
ACPI_STATUS
acpi_tb_map_acpi_table (
	ACPI_PHYSICAL_ADDRESS   physical_address,
	u32                     *size,
	void                    **logical_address)
{
	ACPI_TABLE_HEADER       *table;
	u32                     table_size = *size;
	ACPI_STATUS             status = AE_OK;


	/* If size is zero, look at the table header to get the actual size */

	if ((*size) == 0) {
		/* Get the table header so we can extract the table length */

		status = acpi_os_map_memory (physical_address, sizeof (ACPI_TABLE_HEADER),
				  (void **) &table);
		if (ACPI_FAILURE (status)) {
			return (status);
		}

		/* Extract the full table length before we delete the mapping */

		table_size = table->length;

		/*
		 * Validate the header and delete the mapping.
		 * We will create a mapping for the full table below.
		 */

		status = acpi_tb_validate_table_header (table);

		/* Always unmap the memory for the header */

		acpi_os_unmap_memory (table, sizeof (ACPI_TABLE_HEADER));

		/* Exit if header invalid */

		if (ACPI_FAILURE (status)) {
			return (status);
		}
	}


	/* Map the physical memory for the correct length */

	status = acpi_os_map_memory (physical_address, table_size, (void **) &table);
	if (ACPI_FAILURE (status)) {
		return (status);
	}

	*size = table_size;
	*logical_address = table;

	return (status);
}
示例#2
0
acpi_status
acpi_tb_recognize_table (
    struct acpi_table_desc          *table_info,
    u8                              search_type)
{
    struct acpi_table_header        *table_header;
    acpi_status                     status;


    ACPI_FUNCTION_TRACE ("tb_recognize_table");


    /* Ensure that we have a valid table pointer */

    table_header = (struct acpi_table_header *) table_info->pointer;
    if (!table_header) {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /*
     * We only "recognize" a limited number of ACPI tables -- namely, the
     * ones that are used by the subsystem (DSDT, FADT, etc.)
     *
     * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized.
     * This can be any one of many valid ACPI tables, it just isn't one of
     * the tables that is consumed by the core subsystem
     */
    status = acpi_tb_match_signature (table_header->signature, table_info, search_type);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    status = acpi_tb_validate_table_header (table_header);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    /* Return the table type and length via the info struct */

    table_info->length = (acpi_size) table_header->length;

    return_ACPI_STATUS (status);
}
示例#3
0
static acpi_status
acpi_ut_read_table(FILE * fp,
		   struct acpi_table_header **table, u32 *table_length)
{
	struct acpi_table_header table_header;
	u32 actual;
	acpi_status status;
	u32 file_size;
	u8 standard_header = TRUE;
	s32 count;

	/* Get the file size */

	file_size = cm_get_file_size(fp);
	if (file_size == ACPI_UINT32_MAX) {
		return (AE_ERROR);
	}

	if (file_size < 4) {
		return (AE_BAD_HEADER);
	}

	/* Read the signature */

	fseek(fp, 0, SEEK_SET);

	count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
	if (count != sizeof(struct acpi_table_header)) {
		acpi_os_printf("Could not read the table header\n");
		return (AE_BAD_HEADER);
	}

	/* The RSDP table does not have standard ACPI header */

	if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) {
		*table_length = file_size;
		standard_header = FALSE;
	} else {

#if 0
		/* Validate the table header/length */

		status = acpi_tb_validate_table_header(&table_header);
		if (ACPI_FAILURE(status)) {
			acpi_os_printf("Table header is invalid!\n");
			return (status);
		}
#endif

		/* File size must be at least as long as the Header-specified length */

		if (table_header.length > file_size) {
			acpi_os_printf
			    ("TableHeader length [0x%X] greater than the input file size [0x%X]\n",
			     table_header.length, file_size);

#ifdef ACPI_ASL_COMPILER
			acpi_os_printf("File is corrupt or is ASCII text -- "
				       "it must be a binary file\n");
#endif
			return (AE_BAD_HEADER);
		}
#ifdef ACPI_OBSOLETE_CODE
		/* We only support a limited number of table types */

		if (!ACPI_COMPARE_NAME
		    ((char *)table_header.signature, ACPI_SIG_DSDT)
		    && !ACPI_COMPARE_NAME((char *)table_header.signature,
					  ACPI_SIG_PSDT)
		    && !ACPI_COMPARE_NAME((char *)table_header.signature,
					  ACPI_SIG_SSDT)) {
			acpi_os_printf
			    ("Table signature [%4.4s] is invalid or not supported\n",
			     (char *)table_header.signature);
			ACPI_DUMP_BUFFER(&table_header,
					 sizeof(struct acpi_table_header));
			return (AE_ERROR);
		}
#endif

		*table_length = table_header.length;
	}

	/* Allocate a buffer for the table */

	*table = acpi_os_allocate((size_t) file_size);
	if (!*table) {
		acpi_os_printf
		    ("Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
		     table_header.signature, *table_length);
		return (AE_NO_MEMORY);
	}

	/* Get the rest of the table */

	fseek(fp, 0, SEEK_SET);
	actual = fread(*table, 1, (size_t) file_size, fp);
	if (actual == file_size) {
		if (standard_header) {

			/* Now validate the checksum */

			status = acpi_tb_verify_checksum((void *)*table,
							 ACPI_CAST_PTR(struct
								       acpi_table_header,
								       *table)->
							 length);

			if (status == AE_BAD_CHECKSUM) {
				status =
				    acpi_ut_check_text_mode_corruption((u8 *)
								       *table,
								       file_size,
								       (*table)->
								       length);
				return (status);
			}
		}
		return (AE_OK);
	}

	if (actual > 0) {
		acpi_os_printf("Warning - reading table, asked for %X got %X\n",
			       file_size, actual);
		return (AE_OK);
	}

	acpi_os_printf("Error - could not read the table file\n");
	acpi_os_free(*table);
	*table = NULL;
	*table_length = 0;
	return (AE_ERROR);
}