Example #1
0
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 {
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #5
0
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);
}
Example #6
0
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));
    }
}
Example #7
0
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 {
Example #8
0
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));
    }
}
Example #9
0
/*******************************************************************************
 *
 * 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);
	}
}
Example #10
0
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 {
Example #11
0
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);
    }
}
Example #12
0
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);
}
Example #13
0
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);
}
Example #14
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);
}
Example #15
0
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);
}
Example #16
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);
}
Example #17
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);
}
Example #18
0
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);
}
Example #19
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);
}
Example #20
0
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);
}
Example #21
0
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);
}