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); }
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); }
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); }