kernel: Sync ACPICA with Intel's version 20140627.
[dragonfly.git] / sys / contrib / dev / acpica / source / tools / acpibin / abcompare.c
1 /******************************************************************************
2  *
3  * Module Name: abcompare - compare AML files
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include "acpibin.h"
45 #include "acapps.h"
46
47
48 ACPI_TABLE_HEADER           Header1;
49 ACPI_TABLE_HEADER           Header2;
50
51 #define BUFFER_SIZE         256
52 char                        Buffer[BUFFER_SIZE];
53
54
55 /* Local prototypes */
56
57 static BOOLEAN
58 AbValidateHeader (
59     ACPI_TABLE_HEADER       *Header);
60
61 static UINT8
62 AcpiTbSumTable (
63     void                    *Buffer,
64     UINT32                  Length);
65
66 static char *
67 AbGetFile (
68     char                    *Filename,
69     UINT32                  *FileSize);
70
71 static void
72 AbPrintHeaderInfo (
73     ACPI_TABLE_HEADER       *Header);
74
75 static void
76 AbPrintHeadersInfo (
77     ACPI_TABLE_HEADER       *Header,
78     ACPI_TABLE_HEADER       *Header2);
79
80
81 /******************************************************************************
82  *
83  * FUNCTION:    AbValidateHeader
84  *
85  * DESCRIPTION: Check for valid ACPI table header
86  *
87  ******************************************************************************/
88
89 static BOOLEAN
90 AbValidateHeader (
91     ACPI_TABLE_HEADER       *Header)
92 {
93
94     if (!AcpiUtValidAcpiName (Header->Signature))
95     {
96         printf ("Header signature is invalid\n");
97         return (FALSE);
98     }
99
100     return (TRUE);
101 }
102
103
104 /*******************************************************************************
105  *
106  * FUNCTION:    AcpiTbSumTable
107  *
108  * PARAMETERS:  Buffer              - Buffer to checksum
109  *              Length              - Size of the buffer
110  *
111  * RETURNS      8 bit checksum of buffer
112  *
113  * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
114  *
115  ******************************************************************************/
116
117 static UINT8
118 AcpiTbSumTable (
119     void                    *Buffer,
120     UINT32                  Length)
121 {
122     const UINT8             *Limit;
123     const UINT8             *Rover;
124     UINT8                   Sum = 0;
125
126
127     if (Buffer && Length)
128     {
129         /* Buffer and Length are valid */
130
131         Limit = (UINT8 *) Buffer + Length;
132
133         for (Rover = Buffer; Rover < Limit; Rover++)
134         {
135             Sum = (UINT8) (Sum + *Rover);
136         }
137     }
138
139     return (Sum);
140 }
141
142
143 /*******************************************************************************
144  *
145  * FUNCTION:    AbPrintHeaderInfo
146  *
147  * PARAMETERS:  Header              - An ACPI table header
148  *
149  * RETURNS      None.
150  *
151  * DESCRIPTION: Format and display header contents.
152  *
153  ******************************************************************************/
154
155 static void
156 AbPrintHeaderInfo (
157     ACPI_TABLE_HEADER       *Header)
158 {
159
160     /* Display header information */
161
162     printf ("Signature         : %4.4s\n",    Header->Signature);
163     printf ("Length            : %8.8X\n",    Header->Length);
164     printf ("Revision          : %2.2X\n",    Header->Revision);
165     printf ("Checksum          : %2.2X\n",    Header->Checksum);
166     printf ("OEM ID            : %.6s\n",     Header->OemId);
167     printf ("OEM Table ID      : %.8s\n",     Header->OemTableId);
168     printf ("OEM Revision      : %8.8X\n",    Header->OemRevision);
169     printf ("ASL Compiler ID   : %.4s\n",     Header->AslCompilerId);
170     printf ("Compiler Revision : %8.8X\n",    Header->AslCompilerRevision);
171     printf ("\n");
172 }
173
174 static void
175 AbPrintHeadersInfo (
176     ACPI_TABLE_HEADER       *Header,
177     ACPI_TABLE_HEADER       *Header2)
178 {
179
180     /* Display header information for both headers */
181
182     printf ("Signature          %8.4s : %4.4s\n",    Header->Signature, Header2->Signature);
183     printf ("Length             %8.8X : %8.8X\n",    Header->Length, Header2->Length);
184     printf ("Revision           %8.2X : %2.2X\n",    Header->Revision, Header2->Revision);
185     printf ("Checksum           %8.2X : %2.2X\n",    Header->Checksum, Header2->Checksum);
186     printf ("OEM ID             %8.6s : %.6s\n",     Header->OemId, Header2->OemId);
187     printf ("OEM Table ID       %8.8s : %.8s\n",     Header->OemTableId, Header2->OemTableId);
188     printf ("OEM Revision       %8.8X : %8.8X\n",    Header->OemRevision, Header2->OemRevision);
189     printf ("ASL Compiler ID    %8.4s : %.4s\n",     Header->AslCompilerId, Header2->AslCompilerId);
190     printf ("Compiler Revision  %8.8X : %8.8X\n",    Header->AslCompilerRevision, Header2->AslCompilerRevision);
191     printf ("\n");
192 }
193
194
195 /******************************************************************************
196  *
197  * FUNCTION:    AbDisplayHeader
198  *
199  * DESCRIPTION: Display an ACPI table header
200  *
201  ******************************************************************************/
202
203 void
204 AbDisplayHeader (
205     char                    *FilePath)
206 {
207     UINT32                  Actual;
208     FILE                    *File;
209
210
211     File = fopen (FilePath, "rb");
212     if (!File)
213     {
214         printf ("Could not open file %s\n", FilePath);
215         return;
216     }
217
218     Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
219     fclose (File);
220
221     if (Actual != sizeof (ACPI_TABLE_HEADER))
222     {
223         printf ("File %s does not contain a valid ACPI table header\n", FilePath);
224         return;
225     }
226
227     if (!AbValidateHeader (&Header1))
228     {
229         return;
230     }
231
232     AbPrintHeaderInfo (&Header1);
233 }
234
235
236 /******************************************************************************
237  *
238  * FUNCTION:    AbComputeChecksum
239  *
240  * DESCRIPTION: Compute proper checksum for an ACPI table
241  *
242  ******************************************************************************/
243
244 void
245 AbComputeChecksum (
246     char                    *FilePath)
247 {
248     UINT32                  Actual;
249     ACPI_TABLE_HEADER       *Table;
250     UINT8                   Checksum;
251     FILE                    *File;
252
253
254     File = fopen (FilePath, "rb");
255     if (!File)
256     {
257         printf ("Could not open file %s\n", FilePath);
258         return;
259     }
260
261     Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
262     if (Actual < sizeof (ACPI_TABLE_HEADER))
263     {
264         printf ("File %s does not contain a valid ACPI table header\n", FilePath);
265         goto Exit1;
266     }
267
268     if (!AbValidateHeader (&Header1))
269     {
270         goto Exit1;
271     }
272
273     if (!Gbl_TerseMode)
274     {
275         AbPrintHeaderInfo (&Header1);
276     }
277
278     /* Allocate a buffer to hold the entire table */
279
280     Table = AcpiOsAllocate (Header1.Length);
281     if (!Table)
282     {
283         printf ("Could not allocate buffer for table\n");
284         goto Exit1;
285     }
286
287     /* Read the entire table, including header */
288
289     fseek (File, 0, SEEK_SET);
290     Actual = fread (Table, 1, Header1.Length, File);
291     if (Actual != Header1.Length)
292     {
293         printf ("Could not read table, length %u\n", Header1.Length);
294         goto Exit2;
295     }
296
297     /* Compute the checksum for the table */
298
299     Table->Checksum = 0;
300
301     Checksum = (UINT8) (0 - AcpiTbSumTable (Table, Table->Length));
302     printf ("Computed checksum: 0x%X\n\n", Checksum);
303
304     if (Header1.Checksum == Checksum)
305     {
306         printf ("Checksum OK in AML file, not updating\n");
307         goto Exit2;
308     }
309
310     /* Open the target file for writing, to update checksum */
311
312     fclose (File);
313     File = fopen (FilePath, "r+b");
314     if (!File)
315     {
316         printf ("Could not open file %s for writing\n", FilePath);
317         goto Exit2;
318     }
319
320     /* Set the checksum, write the new header */
321
322     Header1.Checksum = Checksum;
323
324     Actual = fwrite (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
325     if (Actual != sizeof (ACPI_TABLE_HEADER))
326     {
327         printf ("Could not write updated table header\n");
328         goto Exit2;
329     }
330
331     printf ("Wrote new checksum\n");
332
333 Exit2:
334     AcpiOsFree (Table);
335
336 Exit1:
337     if (File)
338     {
339         fclose (File);
340     }
341     return;
342 }
343
344
345 /******************************************************************************
346  *
347  * FUNCTION:    AbCompareAmlFiles
348  *
349  * DESCRIPTION: Compare two AML files
350  *
351  ******************************************************************************/
352
353 int
354 AbCompareAmlFiles (
355     char                    *File1Path,
356     char                    *File2Path)
357 {
358     UINT32                  Actual1;
359     UINT32                  Actual2;
360     UINT32                  Offset;
361     UINT8                   Char1;
362     UINT8                   Char2;
363     UINT8                   Mismatches = 0;
364     BOOLEAN                 HeaderMismatch = FALSE;
365     FILE                    *File1;
366     FILE                    *File2;
367     int                     Status = -1;
368
369
370     File1 = fopen (File1Path, "rb");
371     if (!File1)
372     {
373         printf ("Could not open file %s\n", File1Path);
374         return (-1);
375     }
376
377     File2 = fopen (File2Path, "rb");
378     if (!File2)
379     {
380         printf ("Could not open file %s\n", File2Path);
381         goto Exit1;
382     }
383
384     /* Read the ACPI header from each file */
385
386     Actual1 = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File1);
387     if (Actual1 != sizeof (ACPI_TABLE_HEADER))
388     {
389         printf ("File %s does not contain an ACPI table header\n", File1Path);
390         goto Exit2;
391     }
392
393     Actual2 = fread (&Header2, 1, sizeof (ACPI_TABLE_HEADER), File2);
394     if (Actual2 != sizeof (ACPI_TABLE_HEADER))
395     {
396         printf ("File %s does not contain an ACPI table header\n", File2Path);
397         goto Exit2;
398     }
399
400     if ((!AbValidateHeader (&Header1)) ||
401         (!AbValidateHeader (&Header2)))
402     {
403         goto Exit2;
404     }
405
406     /* Table signatures must match */
407
408     if (*((UINT32 *) Header1.Signature) != *((UINT32 *) Header2.Signature))
409     {
410         printf ("Table signatures do not match\n");
411         goto Exit2;
412     }
413
414     if (!Gbl_TerseMode)
415     {
416         /* Display header information */
417
418         AbPrintHeadersInfo (&Header1, &Header2);
419     }
420
421     if (memcmp (&Header1, &Header2, sizeof (ACPI_TABLE_HEADER)))
422     {
423         printf ("Headers do not match exactly\n");
424         HeaderMismatch = TRUE;
425     }
426
427     /* Do the byte-by-byte compare */
428
429     Actual1 = fread (&Char1, 1, 1, File1);
430     Actual2 = fread (&Char2, 1, 1, File2);
431     Offset = sizeof (ACPI_TABLE_HEADER);
432
433     while ((Actual1 == 1) && (Actual2 == 1))
434     {
435         if (Char1 != Char2)
436         {
437             printf ("Error - Byte mismatch at offset %8.8X: 0x%2.2X 0x%2.2X\n",
438                 Offset, Char1, Char2);
439             Mismatches++;
440             if (Mismatches > 100)
441             {
442                 printf ("100 Mismatches: Too many mismatches\n");
443                 goto Exit2;
444             }
445         }
446
447         Offset++;
448         Actual1 = fread (&Char1, 1, 1, File1);
449         Actual2 = fread (&Char2, 1, 1, File2);
450     }
451
452     if (Actual1)
453     {
454         printf ("Error - file %s is longer than file %s\n", File1Path, File2Path);
455         Mismatches++;
456     }
457     else if (Actual2)
458     {
459         printf ("Error - file %s is shorter than file %s\n", File1Path, File2Path);
460         Mismatches++;
461     }
462     else if (!Mismatches)
463     {
464         if (HeaderMismatch)
465         {
466             printf ("Files compare exactly after header\n");
467         }
468         else
469         {
470             printf ("Files compare exactly\n");
471         }
472     }
473
474     printf ("%u Mismatches found\n", Mismatches);
475     Status = 0;
476
477 Exit2:
478     fclose (File2);
479
480 Exit1:
481     fclose (File1);
482     return (Status);
483 }
484
485
486 /******************************************************************************
487  *
488  * FUNCTION:    AbGetFile
489  *
490  * DESCRIPTION: Open a file and read it entirely into a new buffer
491  *
492  ******************************************************************************/
493
494 static char *
495 AbGetFile (
496     char                    *Filename,
497     UINT32                  *FileSize)
498 {
499     FILE                    *File;
500     UINT32                  Size;
501     char                    *Buffer = NULL;
502     size_t                  Actual;
503
504
505     /* Binary mode does not alter CR/LF pairs */
506
507     File = fopen (Filename, "rb");
508     if (!File)
509     {
510         printf ("Could not open file %s\n", Filename);
511         return (NULL);
512     }
513
514     /* Need file size to allocate a buffer */
515
516     Size = CmGetFileSize (File);
517     if (Size == ACPI_UINT32_MAX)
518     {
519         printf ("Could not get file size (seek) for %s\n", Filename);
520         goto ErrorExit;
521     }
522
523     /* Allocate a buffer for the entire file */
524
525     Buffer = calloc (Size, 1);
526     if (!Buffer)
527     {
528         printf ("Could not allocate buffer of size %u\n", Size);
529         goto ErrorExit;
530     }
531
532     /* Read the entire file */
533
534     Actual = fread (Buffer, 1, Size, File);
535     if (Actual != Size)
536     {
537         printf ("Could not read the input file %s\n", Filename);
538         free (Buffer);
539         Buffer = NULL;
540         goto ErrorExit;
541     }
542
543     *FileSize = Size;
544
545 ErrorExit:
546     fclose (File);
547     return (Buffer);
548 }
549
550
551 /******************************************************************************
552  *
553  * FUNCTION:    AbDumpAmlFile
554  *
555  * DESCRIPTION: Dump a binary AML file to a text file
556  *
557  ******************************************************************************/
558
559 int
560 AbDumpAmlFile (
561     char                    *File1Path,
562     char                    *File2Path)
563 {
564     char                    *FileBuffer;
565     FILE                    *FileOutHandle;
566     UINT32                  FileSize = 0;
567     int                     Status = -1;
568
569
570     /* Get the entire AML file, validate header */
571
572     FileBuffer = AbGetFile (File1Path, &FileSize);
573     if (!FileBuffer)
574     {
575         return (-1);
576     }
577
578     printf ("Input file:  %s contains %u (0x%X) bytes\n",
579         File1Path, FileSize, FileSize);
580
581     FileOutHandle = fopen (File2Path, "wb");
582     if (!FileOutHandle)
583     {
584         printf ("Could not open file %s\n", File2Path);
585         goto Exit1;
586     }
587
588     if (!AbValidateHeader ((ACPI_TABLE_HEADER *) FileBuffer))
589     {
590         goto Exit2;
591     }
592
593     /* Convert binary AML to text, using common dump buffer routine */
594
595     AcpiGbl_DebugFile = FileOutHandle;
596     AcpiGbl_DbOutputFlags = ACPI_DB_REDIRECTABLE_OUTPUT;
597
598     AcpiOsPrintf ("%4.4s @ 0x%8.8X\n",
599         ((ACPI_TABLE_HEADER *) FileBuffer)->Signature, 0);
600
601     AcpiUtDumpBuffer ((UINT8 *) FileBuffer, FileSize, DB_BYTE_DISPLAY, 0);
602
603     /* Summary for the output file */
604
605     FileSize = CmGetFileSize (FileOutHandle);
606     printf ("Output file: %s contains %u (0x%X) bytes\n\n",
607         File2Path, FileSize, FileSize);
608
609     Status = 0;
610
611 Exit2:
612     fclose (FileOutHandle);
613
614 Exit1:
615     free (FileBuffer);
616     return (Status);
617 }
618
619
620 /******************************************************************************
621  *
622  * FUNCTION:    Stubs
623  *
624  * DESCRIPTION: For linkage
625  *
626  ******************************************************************************/