void acpi_tb_print_table_header(acpi_physical_address address, struct acpi_table_header *header) { struct acpi_table_header local_header; if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { /* FACS only has signature and length fields */ ACPI_INFO((AE_INFO, "%-4.4s 0x%8.8X%8.8X %06X", header->signature, ACPI_FORMAT_UINT64(address), header->length)); } else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) { /* RSDP has no common fields */ ACPI_MEMCPY(local_header.oem_id, ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id, ACPI_OEM_ID_SIZE); acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); ACPI_INFO((AE_INFO, "RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)", ACPI_FORMAT_UINT64(address), (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> revision > 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, header)->length : 20, ACPI_CAST_PTR(struct acpi_table_rsdp, header)->revision, local_header.oem_id)); } else {
BOOLEAN ApIsValidHeader ( ACPI_TABLE_HEADER *Table) { if (!ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { /* Make sure signature is all ASCII and a valid ACPI name */ if (!AcpiUtValidAcpiName (Table->Signature)) { AcpiLogError ("Table signature (0x%8.8X) is invalid\n", *(UINT32 *) Table->Signature); return (FALSE); } /* Check for minimum table length */ if (Table->Length < sizeof (ACPI_TABLE_HEADER)) { AcpiLogError ("Table length (0x%8.8X) is invalid\n", Table->Length); return (FALSE); } } return (TRUE); }
ACPI_STATUS AcpiTbValidateRsdp ( ACPI_TABLE_RSDP *Rsdp) { /* * The signature and checksum must both be correct * * Note: Sometimes there exists more than one RSDP in memory; the valid * RSDP has a valid checksum, all others have an invalid checksum. */ if (!ACPI_VALIDATE_RSDP_SIG (Rsdp->Signature)) { /* Nope, BAD Signature */ return (AE_BAD_SIGNATURE); } /* Check the standard checksum */ if (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { return (AE_BAD_CHECKSUM); } /* Check extended checksum if table version >= 2 */ if ((Rsdp->Revision >= 2) && (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { return (AE_BAD_CHECKSUM); } return (AE_OK); }
BOOLEAN ApIsValidChecksum ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; ACPI_TABLE_RSDP *Rsdp; if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { /* * Checksum for RSDP. * Note: Other checksums are computed during the table dump. */ Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); Status = AcpiTbValidateRsdp (Rsdp); } else { Status = AcpiTbVerifyChecksum (Table, Table->Length); } if (ACPI_FAILURE (Status)) { AcpiLogError ("%4.4s: Warning: wrong checksum in table\n", Table->Signature); } return (AE_OK); }
acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) { /* * The signature and checksum must both be correct * * Note: Sometimes there exists more than one RSDP in memory; the valid * RSDP has a valid checksum, all others have an invalid checksum. */ if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) { /* Nope, BAD Signature */ return (AE_BAD_SIGNATURE); } /* Check the standard checksum */ if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { return (AE_BAD_CHECKSUM); } /* Check extended checksum if table version >= 2 */ if ((rsdp->revision >= 2) && (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { return (AE_BAD_CHECKSUM); } return (AE_OK); }
void AcpiTbPrintTableHeader ( ACPI_PHYSICAL_ADDRESS Address, ACPI_TABLE_HEADER *Header) { ACPI_TABLE_HEADER LocalHeader; /* * The reason that we use ACPI_PRINTF_UINT and ACPI_FORMAT_TO_UINT is to * support both 32-bit and 64-bit hosts/addresses in a consistent manner. * The %p specifier does not emit uniform output on all hosts. On some, * leading zeros are not supported. */ if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS)) { /* FACS only has signature and length fields */ ACPI_INFO ((AE_INFO, "%-4.4s " ACPI_PRINTF_UINT " %06X", Header->Signature, ACPI_FORMAT_TO_UINT (Address), Header->Length)); } else if (ACPI_VALIDATE_RSDP_SIG (Header->Signature)) { /* RSDP has no common fields */ ACPI_MEMCPY (LocalHeader.OemId, ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE); AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE); ACPI_INFO ((AE_INFO, "RSDP " ACPI_PRINTF_UINT " %06X (v%.2d %-6.6s)", ACPI_FORMAT_TO_UINT (Address), (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ? ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20, ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision, LocalHeader.OemId)); } else { /* Standard ACPI table with full common header */ AcpiTbCleanupTableHeader (&LocalHeader, Header); ACPI_INFO ((AE_INFO, "%-4.4s " ACPI_PRINTF_UINT " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)", LocalHeader.Signature, ACPI_FORMAT_TO_UINT (Address), LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId, LocalHeader.OemTableId, LocalHeader.OemRevision, LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision)); } }
u8 ap_is_valid_checksum(struct acpi_table_header *table) { acpi_status status; struct acpi_table_rsdp *rsdp; if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { /* * Checksum for RSDP. * Note: Other checksums are computed during the table dump. */ rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table); status = acpi_tb_validate_rsdp(rsdp); } else {
void AcpiTbPrintTableHeader ( ACPI_PHYSICAL_ADDRESS Address, ACPI_TABLE_HEADER *Header) { ACPI_TABLE_HEADER LocalHeader; if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS)) { /* FACS only has signature and length fields */ ACPI_INFO (("%-4.4s 0x%8.8X%8.8X %06X", Header->Signature, ACPI_FORMAT_UINT64 (Address), Header->Length)); } else if (ACPI_VALIDATE_RSDP_SIG (Header->Signature)) { /* RSDP has no common fields */ memcpy (LocalHeader.OemId, ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE); AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE); ACPI_INFO (("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)", ACPI_FORMAT_UINT64 (Address), (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ? ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20, ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision, LocalHeader.OemId)); } else { /* Standard ACPI table with full common header */ AcpiTbCleanupTableHeader (&LocalHeader, Header); ACPI_INFO (( "%-4.4s 0x%8.8X%8.8X" " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)", LocalHeader.Signature, ACPI_FORMAT_UINT64 (Address), LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId, LocalHeader.OemTableId, LocalHeader.OemRevision, LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision)); } }
/******************************************************************************* * * FUNCTION: acpi_tb_get_rsdp_length * * PARAMETERS: rsdp - Pointer to RSDP * * RETURN: Table length * * DESCRIPTION: Get the length of the RSDP * ******************************************************************************/ u32 acpi_tb_get_rsdp_length(struct acpi_table_rsdp *rsdp) { if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) { /* BAD Signature */ return (0); } /* "Length" field is available if table version >= 2 */ if (rsdp->revision >= 2) { return (rsdp->length); } else { return (ACPI_RSDP_CHECKSUM_LENGTH); } }
void acpi_tb_print_table_header(acpi_physical_address address, struct acpi_table_header *header) { struct acpi_table_header local_header; /* * The reason that we use ACPI_PRINTF_UINT and ACPI_FORMAT_TO_UINT is to * support both 32-bit and 64-bit hosts/addresses in a consistent manner. * The %p specifier does not emit uniform output on all hosts. On some, * leading zeros are not supported. */ if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { /* FACS only has signature and length fields */ ACPI_INFO((AE_INFO, "%-4.4s " ACPI_PRINTF_UINT " %06X", header->signature, ACPI_FORMAT_TO_UINT(address), header->length)); } else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) { /* RSDP has no common fields */ ACPI_MEMCPY(local_header.oem_id, ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id, ACPI_OEM_ID_SIZE); acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); ACPI_INFO((AE_INFO, "RSDP " ACPI_PRINTF_UINT " %06X (v%.2d %-6.6s)", ACPI_FORMAT_TO_UINT(address), (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> revision > 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, header)->length : 20, ACPI_CAST_PTR(struct acpi_table_rsdp, header)->revision, local_header.oem_id)); } else {
UINT32 AcpiTbGetRsdpLength ( ACPI_TABLE_RSDP *Rsdp) { if (!ACPI_VALIDATE_RSDP_SIG (Rsdp->Signature)) { /* BAD Signature */ return (0); } /* "Length" field is available if table version >= 2 */ if (Rsdp->Revision >= 2) { return (Rsdp->Length); } else { return (ACPI_RSDP_CHECKSUM_LENGTH); } }
u8 ap_is_valid_header(struct acpi_table_header *table) { if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) { /* Make sure signature is all ASCII and a valid ACPI name */ if (!acpi_ut_valid_acpi_name(table->signature)) { acpi_log_error("Table signature (0x%8.8X) is invalid\n", *(u32 *)table->signature); return (FALSE); } /* Check for minimum table length */ if (table->length < sizeof(struct acpi_table_header)) { acpi_log_error("Table length (0x%8.8X) is invalid\n", table->length); return (FALSE); } } return (TRUE); }
UINT32 ApGetTableLength ( ACPI_TABLE_HEADER *Table) { ACPI_TABLE_RSDP *Rsdp; /* Check if table is valid */ if (!ApIsValidHeader (Table)) { return (0); } if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); return (AcpiTbGetRsdpLength (Rsdp)); } /* Normal ACPI table */ return (Table->Length); }
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); }
int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance) { char filename[ACPI_NAME_SIZE + 16]; char instance_str[16]; ACPI_FILE file; size_t actual; u32 table_length; /* Obtain table length */ table_length = ap_get_table_length(table); /* Construct lower-case filename from the table local signature */ if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME); } else { ACPI_MOVE_NAME(filename, table->signature); } filename[0] = (char)ACPI_TOLOWER(filename[0]); filename[1] = (char)ACPI_TOLOWER(filename[1]); filename[2] = (char)ACPI_TOLOWER(filename[2]); filename[3] = (char)ACPI_TOLOWER(filename[3]); filename[ACPI_NAME_SIZE] = 0; /* Handle multiple SSDts - create different filenames for each */ if (instance > 0) { acpi_ut_snprintf(instance_str, sizeof(instance_str), "%u", instance); ACPI_STRCAT(filename, instance_str); } ACPI_STRCAT(filename, ACPI_TABLE_FILE_SUFFIX); if (gbl_verbose_mode) { acpi_log_error ("Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", table->signature, filename, table->length, table->length); } /* Open the file and dump the entire table in binary mode */ file = acpi_os_open_file(filename, ACPI_FILE_WRITING | ACPI_FILE_BINARY); if (!file) { acpi_log_error("Could not open output file: %s\n", filename); return (-1); } actual = acpi_os_write_file(file, table, 1, table_length); if (actual != table_length) { acpi_log_error("Error writing binary output file: %s\n", filename); acpi_os_close_file(file); return (-1); } acpi_os_close_file(file); return (0); }
int ApWriteToBinaryFile ( ACPI_TABLE_HEADER *Table, UINT32 Instance) { char Filename[ACPI_NAME_SIZE + 16]; char InstanceStr [16]; ACPI_FILE File; ACPI_SIZE Actual; UINT32 TableLength; /* Obtain table length */ TableLength = ApGetTableLength (Table); /* Construct lower-case filename from the table local signature */ if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { ACPI_MOVE_NAME (Filename, ACPI_RSDP_NAME); } else { ACPI_MOVE_NAME (Filename, Table->Signature); } Filename[0] = (char) tolower ((int) Filename[0]); Filename[1] = (char) tolower ((int) Filename[1]); Filename[2] = (char) tolower ((int) Filename[2]); Filename[3] = (char) tolower ((int) Filename[3]); Filename[ACPI_NAME_SIZE] = 0; /* Handle multiple SSDTs - create different filenames for each */ if (Instance > 0) { snprintf (InstanceStr, sizeof (InstanceStr), "%u", Instance); strcat (Filename, InstanceStr); } strcat (Filename, FILE_SUFFIX_BINARY_TABLE); if (Gbl_VerboseMode) { fprintf (stderr, "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", Table->Signature, Filename, Table->Length, Table->Length); } /* Open the file and dump the entire table in binary mode */ File = fopen (Filename, "wb"); if (!File) { fprintf (stderr, "Could not open output file: %s\n", Filename); return (-1); } Actual = fwrite (Table, 1, TableLength, File); if (Actual != TableLength) { fprintf (stderr, "Error writing binary output file: %s\n", Filename); fclose (File); return (-1); } fclose (File); return (0); }
static ACPI_STATUS AcpiUtReadTable ( FILE *fp, ACPI_TABLE_HEADER **Table, UINT32 *TableLength) { ACPI_TABLE_HEADER TableHeader; UINT32 Actual; ACPI_STATUS Status; UINT32 FileSize; BOOLEAN StandardHeader = TRUE; INT32 Count; /* Get the file size */ FileSize = CmGetFileSize (fp); if (FileSize == ACPI_UINT32_MAX) { return (AE_ERROR); } if (FileSize < 4) { return (AE_BAD_HEADER); } /* Read the signature */ fseek (fp, 0, SEEK_SET); Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp); if (Count != sizeof (ACPI_TABLE_HEADER)) { AcpiOsPrintf ("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 (TableHeader.Signature)) { *TableLength = FileSize; StandardHeader = FALSE; } else { #if 0 /* Validate the table header/length */ Status = AcpiTbValidateTableHeader (&TableHeader); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Table header is invalid!\n"); return (Status); } #endif /* File size must be at least as long as the Header-specified length */ if (TableHeader.Length > FileSize) { AcpiOsPrintf ( "TableHeader length [0x%X] greater than the input file size [0x%X]\n", TableHeader.Length, FileSize); #ifdef ACPI_ASL_COMPILER AcpiOsPrintf ("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 *) TableHeader.Signature, ACPI_SIG_DSDT) && !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) && !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT)) { AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n", (char *) TableHeader.Signature); ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER)); return (AE_ERROR); } #endif *TableLength = TableHeader.Length; } /* Allocate a buffer for the table */ *Table = AcpiOsAllocate ((size_t) FileSize); if (!*Table) { AcpiOsPrintf ( "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n", TableHeader.Signature, *TableLength); return (AE_NO_MEMORY); } /* Get the rest of the table */ fseek (fp, 0, SEEK_SET); Actual = fread (*Table, 1, (size_t) FileSize, fp); if (Actual == FileSize) { if (StandardHeader) { /* Now validate the checksum */ Status = AcpiTbVerifyChecksum ((void *) *Table, ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length); if (Status == AE_BAD_CHECKSUM) { Status = AcpiUtCheckTextModeCorruption ((UINT8 *) *Table, FileSize, (*Table)->Length); return (Status); } } return (AE_OK); } if (Actual > 0) { AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n", FileSize, Actual); return (AE_OK); } AcpiOsPrintf ("Error - could not read the table file\n"); AcpiOsFree (*Table); *Table = NULL; *TableLength = 0; return (AE_ERROR); }
int ApWriteToBinaryFile ( ACPI_TABLE_HEADER *Table, UINT32 Instance) { char Filename[ACPI_NAME_SIZE + 16]; char InstanceStr [16]; ACPI_FILE File; size_t Actual; UINT32 TableLength; /* Obtain table length */ TableLength = ApGetTableLength (Table); /* Construct lower-case filename from the table local signature */ if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { ACPI_MOVE_NAME (Filename, ACPI_RSDP_NAME); } else { ACPI_MOVE_NAME (Filename, Table->Signature); } Filename[0] = (char) ACPI_TOLOWER (Filename[0]); Filename[1] = (char) ACPI_TOLOWER (Filename[1]); Filename[2] = (char) ACPI_TOLOWER (Filename[2]); Filename[3] = (char) ACPI_TOLOWER (Filename[3]); Filename[ACPI_NAME_SIZE] = 0; /* Handle multiple SSDTs - create different filenames for each */ if (Instance > 0) { AcpiUtSnprintf (InstanceStr, sizeof (InstanceStr), "%u", Instance); ACPI_STRCAT (Filename, InstanceStr); } ACPI_STRCAT (Filename, ACPI_TABLE_FILE_SUFFIX); if (Gbl_VerboseMode) { AcpiLogError ( "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", Table->Signature, Filename, Table->Length, Table->Length); } /* Open the file and dump the entire table in binary mode */ File = AcpiOsOpenFile (Filename, ACPI_FILE_WRITING | ACPI_FILE_BINARY); if (!File) { AcpiLogError ("Could not open output file: %s\n", Filename); return (-1); } Actual = AcpiOsWriteFile (File, Table, 1, TableLength); if (Actual != TableLength) { AcpiLogError ("Error writing binary output file: %s\n", Filename); AcpiOsCloseFile (File); return (-1); } AcpiOsCloseFile (File); return (0); }
static acpi_status osl_read_table_from_file(char *filename, acpi_size file_offset, char *signature, struct acpi_table_header **table) { FILE *table_file; struct acpi_table_header header; struct acpi_table_header *local_table = NULL; u32 table_length; s32 count; acpi_status status = AE_OK; /* Open the file */ table_file = fopen(filename, "rb"); if (table_file == NULL) { fprintf(stderr, "Could not open table file: %s\n", filename); return (osl_get_last_status(AE_NOT_FOUND)); } fseek(table_file, file_offset, SEEK_SET); /* Read the Table header to get the table length */ count = fread(&header, 1, sizeof(struct acpi_table_header), table_file); if (count != sizeof(struct acpi_table_header)) { fprintf(stderr, "Could not read table header: %s\n", filename); status = AE_BAD_HEADER; goto exit; } /* If signature is specified, it must match the table */ if (signature) { if (ACPI_VALIDATE_RSDP_SIG(signature)) { if (!ACPI_VALIDATE_RSDP_SIG(header.signature)) { fprintf(stderr, "Incorrect RSDP signature: found %8.8s\n", header.signature); status = AE_BAD_SIGNATURE; goto exit; } } else if (!ACPI_COMPARE_NAME(signature, header.signature)) { fprintf(stderr, "Incorrect signature: Expecting %4.4s, found %4.4s\n", signature, header.signature); status = AE_BAD_SIGNATURE; goto exit; } } table_length = ap_get_table_length(&header); if (table_length == 0) { status = AE_BAD_HEADER; goto exit; } /* Read the entire table into a local buffer */ local_table = calloc(1, table_length); if (!local_table) { fprintf(stderr, "%4.4s: Could not allocate buffer for table of length %X\n", header.signature, table_length); status = AE_NO_MEMORY; goto exit; } fseek(table_file, file_offset, SEEK_SET); count = fread(local_table, 1, table_length, table_file); if (count != table_length) { fprintf(stderr, "%4.4s: Could not read table content\n", header.signature); status = AE_INVALID_TABLE_LENGTH; goto exit; } /* Validate checksum */ (void)ap_is_valid_checksum(local_table); exit: fclose(table_file); *table = local_table; return (status); }
static ACPI_STATUS DtCompileDataTable ( DT_FIELD **FieldList) { ACPI_DMTABLE_DATA *TableData; DT_SUBTABLE *Subtable; char *Signature; ACPI_TABLE_HEADER *AcpiTableHeader; ACPI_STATUS Status; DT_FIELD *RootField = *FieldList; /* Verify that we at least have a table signature and save it */ Signature = DtGetFieldValue (*FieldList); if (!Signature) { sprintf (MsgBuffer, "Expected \"%s\"", "Signature"); DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, *FieldList, MsgBuffer); return (AE_ERROR); } Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1); strcpy (Gbl_Signature, Signature); /* * Handle tables that don't use the common ACPI table header structure. * Currently, these are the FACS and RSDP. Also check for an OEMx table, * these tables have user-defined contents. */ if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) { Status = DtCompileFacs (FieldList); if (ACPI_FAILURE (Status)) { return (Status); } DtSetTableLength (); return (Status); } else if (ACPI_VALIDATE_RSDP_SIG (Signature)) { Status = DtCompileRsdp (FieldList); return (Status); } else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT)) { Status = DtCompileS3pt (FieldList); if (ACPI_FAILURE (Status)) { return (Status); } DtSetTableLength (); return (Status); } /* * All other tables must use the common ACPI table header. Insert the * current iASL IDs (name, version), and compile the header now. */ DtInsertCompilerIds (*FieldList); Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader, &Gbl_RootTable, TRUE); if (ACPI_FAILURE (Status)) { return (Status); } DtPushSubtable (Gbl_RootTable); /* Validate the signature via the ACPI table list */ TableData = AcpiDmGetTableData (Signature); if (!TableData || Gbl_CompileGeneric) { DtCompileGeneric ((void **) FieldList); goto FinishHeader; } /* Dispatch to per-table compile */ if (TableData->CmTableHandler) { /* Complex table, has a handler */ Status = TableData->CmTableHandler ((void **) FieldList); if (ACPI_FAILURE (Status)) { return (Status); } } else if (TableData->TableInfo) { /* Simple table, just walk the info table */ Subtable = NULL; Status = DtCompileTable (FieldList, TableData->TableInfo, &Subtable, TRUE); if (ACPI_FAILURE (Status)) { return (Status); } DtInsertSubtable (Gbl_RootTable, Subtable); DtPopSubtable (); } else { DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList, "Missing table dispatch info"); return (AE_ERROR); } FinishHeader: /* Set the final table length and then the checksum */ DtSetTableLength (); AcpiTableHeader = ACPI_CAST_PTR ( ACPI_TABLE_HEADER, Gbl_RootTable->Buffer); DtSetTableChecksum (&AcpiTableHeader->Checksum); DtDumpFieldList (RootField); DtDumpSubtableList (); return (AE_OK); }
static acpi_status osl_map_table(acpi_size address, char *signature, struct acpi_table_header **table) { struct acpi_table_header *mapped_table; u32 length; if (!address) { return (AE_BAD_ADDRESS); } /* * Map the header so we can get the table length. * Use sizeof (struct acpi_table_header) as: * 1. it is bigger than 24 to include RSDP->Length * 2. it is smaller than sizeof (struct acpi_table_rsdp) */ mapped_table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); if (!mapped_table) { fprintf(stderr, "Could not map table header at 0x%8.8X%8.8X\n", ACPI_FORMAT_UINT64(address)); return (osl_get_last_status(AE_BAD_ADDRESS)); } /* If specified, signature must match */ if (signature) { if (ACPI_VALIDATE_RSDP_SIG(signature)) { if (!ACPI_VALIDATE_RSDP_SIG(mapped_table->signature)) { acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header)); return (AE_BAD_SIGNATURE); } } else if (!ACPI_COMPARE_NAME(signature, mapped_table->signature)) { acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header)); return (AE_BAD_SIGNATURE); } } /* Map the entire table */ length = ap_get_table_length(mapped_table); acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header)); if (length == 0) { return (AE_BAD_HEADER); } mapped_table = acpi_os_map_memory(address, length); if (!mapped_table) { fprintf(stderr, "Could not map table at 0x%8.8X%8.8X length %8.8X\n", ACPI_FORMAT_UINT64(address), length); return (osl_get_last_status(AE_INVALID_TABLE_LENGTH)); } (void)ap_is_valid_checksum(mapped_table); *table = mapped_table; return (AE_OK); }