blob: b6cb4d0766b5856d0c34de9cc2020dc5fca3d689 [file] [log] [blame]
/******************************************************************************
*
* Module Name: acpixtract - convert ascii ACPI tables to binary
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2016, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "acpixtract.h"
/******************************************************************************
*
* FUNCTION: AxExtractTables
*
* PARAMETERS: InputPathname - Filename for input acpidump file
* Signature - Requested ACPI signature to extract.
* NULL means extract ALL tables.
* MinimumInstances - Min instances that are acceptable
*
* RETURN: Status
*
* DESCRIPTION: Convert text ACPI tables to binary
*
******************************************************************************/
int
AxExtractTables (
char *InputPathname,
char *Signature,
unsigned int MinimumInstances)
{
FILE *InputFile;
FILE *OutputFile = NULL;
unsigned int BytesConverted;
unsigned int ThisTableBytesWritten = 0;
unsigned int FoundTable = 0;
unsigned int Instances = 0;
unsigned int ThisInstance;
char ThisSignature[4];
int Status = 0;
unsigned int State = AX_STATE_FIND_HEADER;
/* Open input in text mode, output is in binary mode */
InputFile = fopen (InputPathname, "rt");
if (!InputFile)
{
printf ("Could not open input file %s\n", InputPathname);
return (-1);
}
if (Signature)
{
/* Are there enough instances of the table to continue? */
AxNormalizeSignature (Signature);
Instances = AxCountTableInstances (InputPathname, Signature);
if (Instances < MinimumInstances)
{
printf ("Table [%s] was not found in %s\n",
Signature, InputPathname);
fclose (InputFile);
return (-1);
}
if (Instances == 0)
{
fclose (InputFile);
return (-1);
}
}
/* Convert all instances of the table to binary */
while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
{
switch (State)
{
case AX_STATE_FIND_HEADER:
if (!AxIsDataBlockHeader ())
{
continue;
}
ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer);
if (Signature)
{
/* Ignore signatures that don't match */
if (!ACPI_COMPARE_NAME (ThisSignature, Signature))
{
continue;
}
}
/*
* Get the instance number for this signature. Only the
* SSDT and PSDT tables can have multiple instances.
*/
ThisInstance = AxGetNextInstance (InputPathname, ThisSignature);
/* Build an output filename and create/open the output file */
if (ThisInstance > 0)
{
/* Add instance number to the output filename */
sprintf (Gbl_OutputFilename, "%4.4s%u.dat",
ThisSignature, ThisInstance);
}
else
{
sprintf (Gbl_OutputFilename, "%4.4s.dat",
ThisSignature);
}
AcpiUtStrlwr (Gbl_OutputFilename);
OutputFile = fopen (Gbl_OutputFilename, "w+b");
if (!OutputFile)
{
printf ("Could not open output file %s\n",
Gbl_OutputFilename);
fclose (InputFile);
return (-1);
}
/*
* Toss this block header of the form "<sig> @ <addr>" line
* and move on to the actual data block
*/
Gbl_TableCount++;
FoundTable = 1;
ThisTableBytesWritten = 0;
State = AX_STATE_EXTRACT_DATA;
continue;
case AX_STATE_EXTRACT_DATA:
/* Empty line or non-data line terminates the data block */
BytesConverted = AxProcessOneTextLine (
OutputFile, ThisSignature, ThisTableBytesWritten);
switch (BytesConverted)
{
case 0:
State = AX_STATE_FIND_HEADER; /* No more data block lines */
continue;
case -1:
goto CleanupAndExit; /* There was a write error */
default: /* Normal case, get next line */
ThisTableBytesWritten += BytesConverted;
continue;
}
default:
Status = -1;
goto CleanupAndExit;
}
}
if (!FoundTable)
{
printf ("Table [%s] was not found in %s\n",
Signature, InputPathname);
}
CleanupAndExit:
if (State == AX_STATE_EXTRACT_DATA)
{
/* Received an input file EOF while extracting data */
printf (AX_TABLE_INFO_FORMAT,
ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename);
}
if (Gbl_TableCount > 1)
{
printf ("\n%d binary ACPI tables extracted\n",
Gbl_TableCount);
}
if (OutputFile)
{
fclose (OutputFile);
}
fclose (InputFile);
return (Status);
}
/******************************************************************************
*
* FUNCTION: AxExtractToMultiAmlFile
*
* PARAMETERS: InputPathname - Filename for input acpidump file
*
* RETURN: Status
*
* DESCRIPTION: Convert all DSDT/SSDT tables to binary and append them all
* into a single output file. Used to simplify the loading of
* multiple/many SSDTs into a utility like acpiexec -- instead
* of creating many separate output files.
*
******************************************************************************/
int
AxExtractToMultiAmlFile (
char *InputPathname)
{
FILE *InputFile;
FILE *OutputFile;
int Status = 0;
unsigned int TotalBytesWritten = 0;
unsigned int ThisTableBytesWritten = 0;
unsigned int BytesConverted;
char ThisSignature[4];
unsigned int State = AX_STATE_FIND_HEADER;
strcpy (Gbl_OutputFilename, AX_MULTI_TABLE_FILENAME);
/* Open the input file in text mode */
InputFile = fopen (InputPathname, "rt");
if (!InputFile)
{
printf ("Could not open input file %s\n", InputPathname);
return (-1);
}
/* Open the output file in binary mode */
OutputFile = fopen (Gbl_OutputFilename, "w+b");
if (!OutputFile)
{
printf ("Could not open output file %s\n", Gbl_OutputFilename);
fclose (InputFile);
return (-1);
}
/* Convert the DSDT and all SSDTs to binary */
while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
{
switch (State)
{
case AX_STATE_FIND_HEADER:
if (!AxIsDataBlockHeader ())
{
continue;
}
ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer);
/* Only want DSDT and SSDTs */
if (!ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_DSDT) &&
!ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_SSDT))
{
continue;
}
/*
* Toss this block header of the form "<sig> @ <addr>" line
* and move on to the actual data block
*/
Gbl_TableCount++;
ThisTableBytesWritten = 0;
State = AX_STATE_EXTRACT_DATA;
continue;
case AX_STATE_EXTRACT_DATA:
/* Empty line or non-data line terminates the data block */
BytesConverted = AxProcessOneTextLine (
OutputFile, ThisSignature, ThisTableBytesWritten);
switch (BytesConverted)
{
case 0:
State = AX_STATE_FIND_HEADER; /* No more data block lines */
continue;
case -1:
goto CleanupAndExit; /* There was a write error */
default: /* Normal case, get next line */
ThisTableBytesWritten += BytesConverted;
TotalBytesWritten += BytesConverted;
continue;
}
default:
Status = -1;
goto CleanupAndExit;
}
}
CleanupAndExit:
if (State == AX_STATE_EXTRACT_DATA)
{
/* Received an input file EOF or error while writing data */
printf (AX_TABLE_INFO_FORMAT,
ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename);
}
printf ("\n%d binary ACPI tables extracted and written to %s (%u bytes)\n",
Gbl_TableCount, Gbl_OutputFilename, TotalBytesWritten);
fclose (InputFile);
fclose (OutputFile);
return (Status);
}
/******************************************************************************
*
* FUNCTION: AxListTables
*
* PARAMETERS: InputPathname - Filename for acpidump file
*
* RETURN: Status
*
* DESCRIPTION: Display info for all ACPI tables found in input. Does not
* perform an actual extraction of the tables.
*
******************************************************************************/
int
AxListTables (
char *InputPathname)
{
FILE *InputFile;
size_t HeaderSize;
unsigned char Header[48];
ACPI_TABLE_HEADER *TableHeader = (ACPI_TABLE_HEADER *) (void *) Header;
/* Open input in text mode, output is in binary mode */
InputFile = fopen (InputPathname, "rt");
if (!InputFile)
{
printf ("Could not open input file %s\n", InputPathname);
return (-1);
}
/* Dump the headers for all tables found in the input file */
printf ("\nSignature Length Revision OemId OemTableId"
" OemRevision CompilerId CompilerRevision\n\n");
while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
{
/* Ignore empty lines and lines that start with a space */
if (AxIsEmptyLine (Gbl_LineBuffer) ||
(Gbl_LineBuffer[0] == ' '))
{
continue;
}
/* Get the 36 byte header and display the fields */
HeaderSize = AxGetTableHeader (InputFile, Header);
if (HeaderSize < 16)
{
continue;
}
/* RSDP has an oddball signature and header */
if (!strncmp (TableHeader->Signature, "RSD PTR ", 8))
{
AxCheckAscii ((char *) &Header[9], 6);
printf ("%7.4s \"%6.6s\"\n", "RSDP",
&Header[9]);
Gbl_TableCount++;
continue;
}
/* Minimum size for table with standard header */
if (HeaderSize < sizeof (ACPI_TABLE_HEADER))
{
continue;
}
/* Signature and Table length */
Gbl_TableCount++;
printf ("%7.4s 0x%8.8X", TableHeader->Signature,
TableHeader->Length);
/* FACS has only signature and length */
if (ACPI_COMPARE_NAME (TableHeader->Signature, "FACS"))
{
printf ("\n");
continue;
}
/* OEM IDs and Compiler IDs */
AxCheckAscii (TableHeader->OemId, 6);
AxCheckAscii (TableHeader->OemTableId, 8);
AxCheckAscii (TableHeader->AslCompilerId, 4);
printf (
" 0x%2.2X \"%6.6s\" \"%8.8s\" 0x%8.8X"
" \"%4.4s\" 0x%8.8X\n",
TableHeader->Revision, TableHeader->OemId,
TableHeader->OemTableId, TableHeader->OemRevision,
TableHeader->AslCompilerId, TableHeader->AslCompilerRevision);
}
printf ("\nFound %u ACPI tables\n", Gbl_TableCount);
fclose (InputFile);
return (0);
}