Home | History | Annotate | Line # | Download | only in acpibin
abcompare.c revision 1.1
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: abcompare - compare AML files
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2011, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 #include "acpibin.h"
     46 
     47 
     48 FILE                        *File1;
     49 FILE                        *File2;
     50 ACPI_TABLE_HEADER           Header1;
     51 ACPI_TABLE_HEADER           Header2;
     52 struct stat                 Gbl_StatBuf;
     53 
     54 #define BUFFER_SIZE         256
     55 char                        Buffer[BUFFER_SIZE];
     56 
     57 
     58 /* Local prototypes */
     59 
     60 static BOOLEAN
     61 AbValidateHeader (
     62     ACPI_TABLE_HEADER       *Header);
     63 
     64 static UINT8
     65 AcpiTbSumTable (
     66     void                    *Buffer,
     67     UINT32                  Length);
     68 
     69 static char *
     70 AbGetFile (
     71     char                    *Filename,
     72     UINT32                  *FileSize);
     73 
     74 static void
     75 AbPrintHeaderInfo (
     76     ACPI_TABLE_HEADER       *Header);
     77 
     78 ACPI_PHYSICAL_ADDRESS
     79 AeLocalGetRootPointer (
     80     void);
     81 
     82 
     83 /*******************************************************************************
     84  *
     85  * FUNCTION:    UtHexCharToValue
     86  *
     87  * PARAMETERS:  HexChar         - Hex character in Ascii
     88  *
     89  * RETURN:      The binary value of the hex character
     90  *
     91  * DESCRIPTION: Perform ascii-to-hex translation
     92  *
     93  ******************************************************************************/
     94 
     95 static UINT8
     96 UtHexCharToValue (
     97     int                     HexChar,
     98     UINT8                   *OutBinary)
     99 {
    100 
    101     if (HexChar >= 0x30 && HexChar <= 0x39)
    102     {
    103         *OutBinary = (UINT8) (HexChar - 0x30);
    104         return (1);
    105     }
    106 
    107     else if (HexChar >= 0x41 && HexChar <= 0x46)
    108     {
    109         *OutBinary = (UINT8) (HexChar - 0x37);
    110         return (1);
    111     }
    112 
    113     else if (HexChar >= 0x61 && HexChar <= 0x66)
    114     {
    115         *OutBinary = (UINT8) (HexChar - 0x57);
    116         return (1);
    117     }
    118     return (0);
    119 }
    120 
    121 static UINT8
    122 AbHexByteToBinary (
    123     char                    *HexString,
    124     char                    *OutBinary)
    125 {
    126     UINT8                   Local1;
    127     UINT8                   Local2;
    128 
    129 
    130     if (!UtHexCharToValue (HexString[0], &Local1))
    131     {
    132         return (0);
    133     }
    134     if (!UtHexCharToValue (HexString[1], &Local2))
    135     {
    136         return (0);
    137     }
    138 
    139     *OutBinary = (UINT8) ((Local1 << 4) | Local2);
    140     return (2);
    141 
    142 }
    143 
    144 
    145 /******************************************************************************
    146  *
    147  * FUNCTION:    AbValidateHeader
    148  *
    149  * DESCRIPTION: Check for valid ACPI table header
    150  *
    151  ******************************************************************************/
    152 
    153 static BOOLEAN
    154 AbValidateHeader (
    155     ACPI_TABLE_HEADER       *Header)
    156 {
    157 
    158     if (!AcpiUtValidAcpiName (* (UINT32 *) &Header->Signature))
    159     {
    160         printf ("Header signature is invalid\n");
    161         return FALSE;
    162     }
    163 
    164     return TRUE;
    165 }
    166 
    167 
    168 /*******************************************************************************
    169  *
    170  * FUNCTION:    AcpiTbSumTable
    171  *
    172  * PARAMETERS:  Buffer              - Buffer to checksum
    173  *              Length              - Size of the buffer
    174  *
    175  * RETURNS      8 bit checksum of buffer
    176  *
    177  * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
    178  *
    179  ******************************************************************************/
    180 
    181 static UINT8
    182 AcpiTbSumTable (
    183     void                    *Buffer,
    184     UINT32                  Length)
    185 {
    186     const UINT8             *limit;
    187     const UINT8             *rover;
    188     UINT8                   sum = 0;
    189 
    190 
    191     if (Buffer && Length)
    192     {
    193         /* Buffer and Length are valid */
    194 
    195         limit = (UINT8 *) Buffer + Length;
    196 
    197         for (rover = Buffer; rover < limit; rover++)
    198         {
    199             sum = (UINT8) (sum + *rover);
    200         }
    201     }
    202     return (sum);
    203 }
    204 
    205 
    206 /*******************************************************************************
    207  *
    208  * FUNCTION:    AbPrintHeaderInfo
    209  *
    210  * PARAMETERS:  Header              - An ACPI table header
    211  *
    212  * RETURNS      None.
    213  *
    214  * DESCRIPTION: Format and display header contents.
    215  *
    216  ******************************************************************************/
    217 
    218 static void
    219 AbPrintHeaderInfo (
    220     ACPI_TABLE_HEADER       *Header)
    221 {
    222 
    223     /* Display header information */
    224 
    225     printf ("Signature         : %4.4s\n",    Header->Signature);
    226     printf ("Length            : %8.8X\n",    Header->Length);
    227     printf ("Revision          : %2.2X\n",    Header->Revision);
    228     printf ("Checksum          : %2.2X\n",    Header->Checksum);
    229     printf ("OEM ID            : %6.6s\n",    Header->OemId);
    230     printf ("OEM Table ID      : %8.8s\n",    Header->OemTableId);
    231     printf ("OEM Revision      : %8.8X\n",    Header->OemRevision);
    232     printf ("ASL Compiler ID   : %4.4s\n",    Header->AslCompilerId);
    233     printf ("Compiler Revision : %8.8X\n",    Header->AslCompilerRevision);
    234     printf ("\n");
    235 }
    236 
    237 
    238 /******************************************************************************
    239  *
    240  * FUNCTION:    AbDisplayHeader
    241  *
    242  * DESCRIPTION: Display an ACPI table header
    243  *
    244  ******************************************************************************/
    245 
    246 void
    247 AbDisplayHeader (
    248     char                    *File1Path)
    249 {
    250     UINT32                  Actual1;
    251 
    252 
    253     File1 = fopen (File1Path, "rb");
    254     if (!File1)
    255     {
    256         printf ("Could not open file %s\n", File1Path);
    257         return;
    258     }
    259 
    260     Actual1 = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File1);
    261     if (Actual1 < sizeof (ACPI_TABLE_HEADER))
    262     {
    263         printf ("File %s does not contain an ACPI table header\n", File1Path);
    264         return;
    265     }
    266 
    267     if (!AbValidateHeader (&Header1))
    268     {
    269         return;
    270     }
    271 
    272     AbPrintHeaderInfo (&Header1);
    273 }
    274 
    275 
    276 /******************************************************************************
    277  *
    278  * FUNCTION:    AbComputeChecksum
    279  *
    280  * DESCRIPTION: Compute proper checksum for an ACPI table
    281  *
    282  ******************************************************************************/
    283 
    284 void
    285 AbComputeChecksum (
    286     char                    *File1Path)
    287 {
    288     UINT32                  Actual1;
    289     ACPI_TABLE_HEADER       *Table;
    290     UINT8                   Checksum;
    291 
    292 
    293     File1 = fopen (File1Path, "rb");
    294     if (!File1)
    295     {
    296         printf ("Could not open file %s\n", File1Path);
    297         return;
    298     }
    299 
    300     Actual1 = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File1);
    301     if (Actual1 < sizeof (ACPI_TABLE_HEADER))
    302     {
    303         printf ("File %s does not contain an ACPI table header\n", File1Path);
    304         return;
    305     }
    306 
    307     if (!AbValidateHeader (&Header1))
    308     {
    309         return;
    310     }
    311 
    312     if (!Gbl_TerseMode)
    313     {
    314         AbPrintHeaderInfo (&Header1);
    315     }
    316 
    317     /* Allocate a buffer to hold the entire table */
    318 
    319     Table = AcpiOsAllocate (Header1.Length);
    320     if (!Table)
    321     {
    322         printf ("could not allocate\n");
    323         return;
    324     }
    325 
    326     /* Read the entire table, including header */
    327 
    328     fseek (File1, 0, SEEK_SET);
    329     Actual1 = fread (Table, 1, Header1.Length, File1);
    330     if (Actual1 < Header1.Length)
    331     {
    332         printf ("could not read table\n");
    333         return;
    334     }
    335 
    336     /* Compute the checksum for the table */
    337 
    338     Table->Checksum = 0;
    339 
    340     Checksum = (UINT8) (0 - AcpiTbSumTable (Table, Table->Length));
    341     printf ("Computed checksum: 0x%X\n\n", Checksum);
    342 
    343     if (Header1.Checksum == Checksum)
    344     {
    345         printf ("Checksum ok in AML file, not updating\n");
    346         return;
    347     }
    348 
    349     /* Open the target file for writing, to update checksum */
    350 
    351     fclose (File1);
    352     File1 = fopen (File1Path, "r+b");
    353     if (!File1)
    354     {
    355         printf ("Could not open file %s for writing\n", File1Path);
    356         return;
    357     }
    358 
    359     /* Set the checksum, write the new header */
    360 
    361     Header1.Checksum = Checksum;
    362 
    363     Actual1 = fwrite (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File1);
    364     if (Actual1 < sizeof (ACPI_TABLE_HEADER))
    365     {
    366         printf ("Could not write updated table header\n");
    367         return;
    368     }
    369 
    370     printf ("Wrote new checksum\n");
    371     return;
    372 }
    373 
    374 
    375 /******************************************************************************
    376  *
    377  * FUNCTION:    AbCompareAmlFiles
    378  *
    379  * DESCRIPTION: Compare two AML files
    380  *
    381  ******************************************************************************/
    382 
    383 int
    384 AbCompareAmlFiles (
    385     char                    *File1Path,
    386     char                    *File2Path)
    387 {
    388     UINT32                  Actual1;
    389     UINT32                  Actual2;
    390     UINT32                  Offset;
    391     UINT8                   Char1;
    392     UINT8                   Char2;
    393     UINT8                   Mismatches = 0;
    394     BOOLEAN                 HeaderMismatch = FALSE;
    395 
    396 
    397     File1 = fopen (File1Path, "rb");
    398     if (!File1)
    399     {
    400         printf ("Could not open file %s\n", File1Path);
    401         return -1;
    402     }
    403 
    404     File2 = fopen (File2Path, "rb");
    405     if (!File2)
    406     {
    407         printf ("Could not open file %s\n", File2Path);
    408         return -1;
    409     }
    410 
    411     /* Read the ACPI header from each file */
    412 
    413     Actual1 = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File1);
    414     if (Actual1 < sizeof (ACPI_TABLE_HEADER))
    415     {
    416         printf ("File %s does not contain an ACPI table header\n", File1Path);
    417         return -1;
    418     }
    419 
    420     Actual2 = fread (&Header2, 1, sizeof (ACPI_TABLE_HEADER), File2);
    421     if (Actual2 < sizeof (ACPI_TABLE_HEADER))
    422     {
    423         printf ("File %s does not contain an ACPI table header\n", File2Path);
    424         return -1;
    425     }
    426 
    427     if ((!AbValidateHeader (&Header1)) ||
    428         (!AbValidateHeader (&Header2)))
    429     {
    430         return -1;
    431     }
    432 
    433     /* Table signatures must match */
    434 
    435     if (*((UINT32 *) Header1.Signature) != *((UINT32 *) Header2.Signature))
    436     {
    437         printf ("Table signatures do not match\n");
    438         return -1;
    439     }
    440 
    441     if (!Gbl_TerseMode)
    442     {
    443         /* Display header information */
    444 
    445         AbPrintHeaderInfo (&Header1);
    446         AbPrintHeaderInfo (&Header2);
    447     }
    448 
    449     if (memcmp (Header1.Signature, Header2.Signature, sizeof (ACPI_TABLE_HEADER)))
    450     {
    451         printf ("Headers do not match exactly\n");
    452         HeaderMismatch = TRUE;
    453     }
    454 
    455     /* Do the byte-by-byte compare */
    456 
    457     Actual1 = fread (&Char1, 1, 1, File1);
    458     Actual2 = fread (&Char2, 1, 1, File2);
    459     Offset = sizeof (ACPI_TABLE_HEADER);
    460 
    461     while (Actual1 && Actual2)
    462     {
    463         if (Char1 != Char2)
    464         {
    465             printf ("Error - Byte mismatch at offset %8.8X: 0x%2.2X 0x%2.2X\n",
    466                 Offset, Char1, Char2);
    467             Mismatches++;
    468             if (Mismatches > 100)
    469             {
    470                 printf ("100 Mismatches: Too many mismatches\n");
    471                 return -1;
    472             }
    473         }
    474 
    475         Offset++;
    476         Actual1 = fread (&Char1, 1, 1, File1);
    477         Actual2 = fread (&Char2, 1, 1, File2);
    478     }
    479 
    480     if (Actual1)
    481     {
    482         printf ("Error - file %s is longer than file %s\n", File1Path, File2Path);
    483         Mismatches++;
    484     }
    485     else if (Actual2)
    486     {
    487         printf ("Error - file %s is shorter than file %s\n", File1Path, File2Path);
    488         Mismatches++;
    489     }
    490     else if (!Mismatches)
    491     {
    492         if (HeaderMismatch)
    493         {
    494             printf ("Files compare exactly after header\n");
    495         }
    496         else
    497         {
    498             printf ("Files compare exactly\n");
    499         }
    500     }
    501 
    502     printf ("%u Mismatches found\n", Mismatches);
    503     return 0;
    504 }
    505 
    506 
    507 /******************************************************************************
    508  *
    509  * FUNCTION:    AsGetFile
    510  *
    511  * DESCRIPTION: Open a file and read it entirely into a new buffer
    512  *
    513  ******************************************************************************/
    514 
    515 static char *
    516 AbGetFile (
    517     char                    *Filename,
    518     UINT32                  *FileSize)
    519 {
    520     int                     FileHandle;
    521     UINT32                  Size;
    522     char                    *Buffer = NULL;
    523 
    524 
    525     /* Binary mode does not alter CR/LF pairs */
    526 
    527     FileHandle = open (Filename, O_BINARY | O_RDONLY);
    528     if (!FileHandle)
    529     {
    530         printf ("Could not open %s\n", Filename);
    531         return NULL;
    532     }
    533 
    534     /* Need file size to allocate a buffer */
    535 
    536     if (fstat (FileHandle, &Gbl_StatBuf))
    537     {
    538         printf ("Could not get file status for %s\n", Filename);
    539         goto ErrorExit;
    540     }
    541 
    542     /* Allocate a buffer for the entire file */
    543 
    544     Size = Gbl_StatBuf.st_size;
    545     Buffer = calloc (Size, 1);
    546     if (!Buffer)
    547     {
    548         printf ("Could not allocate buffer of size %u\n", Size);
    549         goto ErrorExit;
    550     }
    551 
    552     /* Read the entire file */
    553 
    554     Size = read (FileHandle, Buffer, Size);
    555     if (Size == -1)
    556     {
    557         printf ("Could not read the input file %s\n", Filename);
    558         free (Buffer);
    559         Buffer = NULL;
    560         goto ErrorExit;
    561     }
    562 
    563     *FileSize = Size;
    564 
    565 ErrorExit:
    566     close (FileHandle);
    567 
    568     return (Buffer);
    569 }
    570 
    571 
    572 /******************************************************************************
    573  *
    574  * FUNCTION:    AbDumpAmlFile
    575  *
    576  * DESCRIPTION: Dump a binary AML file to a text file
    577  *
    578  ******************************************************************************/
    579 
    580 int
    581 AbDumpAmlFile (
    582     char                    *File1Path,
    583     char                    *File2Path)
    584 {
    585     char                    *FileBuffer;
    586     UINT32                  FileSize = 0;
    587     FILE                    *FileOutHandle;
    588 
    589 
    590     /* Get the entire AML file, validate header */
    591 
    592     FileBuffer = AbGetFile (File1Path, &FileSize);
    593     printf ("File %s contains 0x%X bytes\n\n", File1Path, FileSize);
    594 
    595     FileOutHandle = fopen (File2Path, "wb");
    596     if (!FileOutHandle)
    597     {
    598         printf ("Could not open %s\n", File2Path);
    599         return -1;
    600     }
    601 
    602     if (!AbValidateHeader ((ACPI_TABLE_HEADER *) FileBuffer))
    603     {
    604         return -1;
    605     }
    606 
    607     /* Convert binary AML to text, using common dump buffer routine */
    608 
    609     AcpiGbl_DebugFile = FileOutHandle;
    610     AcpiGbl_DbOutputFlags = ACPI_DB_REDIRECTABLE_OUTPUT;
    611 
    612     AcpiOsPrintf ("%4.4s\n", ((ACPI_TABLE_HEADER *) FileBuffer)->Signature);
    613     AcpiDbgLevel = ACPI_UINT32_MAX;
    614     AcpiUtDumpBuffer ((UINT8 *) FileBuffer, FileSize,
    615         DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    616 
    617     return 0;
    618 }
    619 
    620 
    621 /******************************************************************************
    622  *
    623  * FUNCTION:    AbExtractAmlFile
    624  *
    625  * DESCRIPTION: Extract a binary AML file from a text file (as produced by the
    626  *              DumpAmlFile procedure or the "acpidmp" table utility.
    627  *
    628  ******************************************************************************/
    629 
    630 int
    631 AbExtractAmlFile (
    632     char                    *TableSig,
    633     char                    *File1Path,
    634     char                    *File2Path)
    635 {
    636     char                    *Table;
    637     char                    Value;
    638     UINT32                  i;
    639     FILE                    *FileHandle;
    640     FILE                    *FileOutHandle;
    641     UINT32                  Count = 0;
    642     int                     Scanned;
    643 
    644 
    645     /* Open in/out files. input is in text mode, output is in binary mode */
    646 
    647     FileHandle = fopen (File1Path, "rt");
    648     if (!FileHandle)
    649     {
    650         printf ("Could not open %s\n", File1Path);
    651         return -1;
    652     }
    653 
    654     FileOutHandle = fopen (File2Path, "w+b");
    655     if (!FileOutHandle)
    656     {
    657         printf ("Could not open %s\n", File2Path);
    658         return -1;
    659     }
    660 
    661     /* Force input table sig to uppercase */
    662 
    663     AcpiUtStrupr (TableSig);
    664 
    665 
    666     /* TBD: examine input for ASCII */
    667 
    668 
    669     /* We have an ascii file, grab one line at a time */
    670 
    671     while (fgets (Buffer, BUFFER_SIZE, FileHandle))
    672     {
    673         /* The 4-char ACPI signature appears at the beginning of a line */
    674 
    675         if (!strncmp (Buffer, TableSig, 4))
    676         {
    677             printf ("Found table [%4.4s]\n", TableSig);
    678 
    679             /*
    680              * Eat all lines in the table, of the form:
    681              *   <offset>: <16 bytes of hex data, separated by spaces> <ASCII representation> <newline>
    682              *
    683              * Example:
    684              *
    685              *   02C0: 5F 53 42 5F 4C 4E 4B 44 00 12 13 04 0C FF FF 08  _SB_LNKD........
    686              *
    687              */
    688             while (fgets (Buffer, BUFFER_SIZE, FileHandle))
    689             {
    690                 /* Get past the offset, terminated by a colon */
    691 
    692                 Table = strchr (Buffer, ':');
    693                 if (!Table)
    694                 {
    695                     /* No colon, all done */
    696                     goto Exit;
    697                 }
    698 
    699                 Table += 2; /* Eat the colon + space */
    700 
    701                 for (i = 0; i < 16; i++)
    702                 {
    703                     Scanned = AbHexByteToBinary (Table, &Value);
    704                     if (!Scanned)
    705                     {
    706                         goto Exit;
    707                     }
    708 
    709                     Table += 3; /* Go past this hex byte and space */
    710 
    711                     /* Write the converted (binary) byte */
    712 
    713                     fwrite (&Value, 1, 1, FileOutHandle);
    714                     Count++;
    715                 }
    716             }
    717 
    718             /* No more lines, EOF, all done */
    719 
    720             goto Exit;
    721         }
    722     }
    723 
    724     /* Searched entire file, no match to table signature */
    725 
    726     printf ("Could not match table signature\n");
    727     fclose (FileHandle);
    728     return -1;
    729 
    730 Exit:
    731     printf ("%u (0x%X) bytes written to %s\n", Count, Count, File2Path);
    732     fclose (FileHandle);
    733     fclose (FileOutHandle);
    734     return 0;
    735 }
    736 
    737 
    738 /******************************************************************************
    739  *
    740  * FUNCTION:    Stubs
    741  *
    742  * DESCRIPTION: For linkage
    743  *
    744  ******************************************************************************/
    745 
    746 ACPI_PHYSICAL_ADDRESS
    747 AeLocalGetRootPointer (
    748     void)
    749 {
    750     return AE_OK;
    751 }
    752 
    753 ACPI_THREAD_ID
    754 AcpiOsGetThreadId (
    755     void)
    756 {
    757     return (0xFFFF);
    758 }
    759 
    760 ACPI_STATUS
    761 AcpiOsExecute (
    762     ACPI_EXECUTE_TYPE       Type,
    763     ACPI_OSD_EXEC_CALLBACK  Function,
    764     void                    *Context)
    765 {
    766     return (AE_SUPPORT);
    767 }
    768