Sync ACPICA with Intel's version 20161117.
[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 - 2016, 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
46
47 ACPI_TABLE_HEADER           Header1;
48 ACPI_TABLE_HEADER           Header2;
49
50 #define BUFFER_SIZE         256
51 char                        Buffer[BUFFER_SIZE];
52
53
54 /* Local prototypes */
55
56 static BOOLEAN
57 AbValidateHeader (
58     ACPI_TABLE_HEADER       *Header);
59
60 static UINT8
61 AcpiTbSumTable (
62     void                    *Buffer,
63     UINT32                  Length);
64
65 static char *
66 AbGetFile (
67     char                    *Filename,
68     UINT32                  *FileSize);
69
70 static void
71 AbPrintHeaderInfo (
72     ACPI_TABLE_HEADER       *Header);
73
74 static void
75 AbPrintHeadersInfo (
76     ACPI_TABLE_HEADER       *Header,
77     ACPI_TABLE_HEADER       *Header2);
78
79
80 /******************************************************************************
81  *
82  * FUNCTION:    AbValidateHeader
83  *
84  * DESCRIPTION: Check for valid ACPI table header
85  *
86  ******************************************************************************/
87
88 static BOOLEAN
89 AbValidateHeader (
90     ACPI_TABLE_HEADER       *Header)
91 {
92
93     if (!AcpiUtValidNameseg (Header->Signature))
94     {
95         printf ("Header signature is invalid\n");
96         return (FALSE);
97     }
98
99     return (TRUE);
100 }
101
102
103 /*******************************************************************************
104  *
105  * FUNCTION:    AcpiTbSumTable
106  *
107  * PARAMETERS:  Buffer              - Buffer to checksum
108  *              Length              - Size of the buffer
109  *
110  * RETURNS      8 bit checksum of buffer
111  *
112  * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
113  *
114  ******************************************************************************/
115
116 static UINT8
117 AcpiTbSumTable (
118     void                    *Buffer,
119     UINT32                  Length)
120 {
121     const UINT8             *Limit;
122     const UINT8             *Rover;
123     UINT8                   Sum = 0;
124
125
126     if (Buffer && Length)
127     {
128         /* Buffer and Length are valid */
129
130         Limit = (UINT8 *) Buffer + Length;
131
132         for (Rover = Buffer; Rover < Limit; Rover++)
133         {
134             Sum = (UINT8) (Sum + *Rover);
135         }
136     }
137
138     return (Sum);
139 }
140
141
142 /*******************************************************************************
143  *
144  * FUNCTION:    AbPrintHeaderInfo
145  *
146  * PARAMETERS:  Header              - An ACPI table header
147  *
148  * RETURNS      None.
149  *
150  * DESCRIPTION: Format and display header contents.
151  *
152  ******************************************************************************/
153
154 static void
155 AbPrintHeaderInfo (
156     ACPI_TABLE_HEADER       *Header)
157 {
158
159     /* Display header information */
160
161     printf ("Signature         : %4.4s\n",    Header->Signature);
162     printf ("Length            : %8.8X\n",    Header->Length);
163     printf ("Revision          : %2.2X\n",    Header->Revision);
164     printf ("Checksum          : %2.2X\n",    Header->Checksum);
165     printf ("OEM ID            : %.6s\n",     Header->OemId);
166     printf ("OEM Table ID      : %.8s\n",     Header->OemTableId);
167     printf ("OEM Revision      : %8.8X\n",    Header->OemRevision);
168     printf ("ASL Compiler ID   : %.4s\n",     Header->AslCompilerId);
169     printf ("Compiler Revision : %8.8X\n",    Header->AslCompilerRevision);
170     printf ("\n");
171 }
172
173 static void
174 AbPrintHeadersInfo (
175     ACPI_TABLE_HEADER       *Header,
176     ACPI_TABLE_HEADER       *Header2)
177 {
178
179     /* Display header information for both headers */
180
181     printf ("Signature          %8.4s : %4.4s\n",    Header->Signature, Header2->Signature);
182     printf ("Length             %8.8X : %8.8X\n",    Header->Length, Header2->Length);
183     printf ("Revision           %8.2X : %2.2X\n",    Header->Revision, Header2->Revision);
184     printf ("Checksum           %8.2X : %2.2X\n",    Header->Checksum, Header2->Checksum);
185     printf ("OEM ID             %8.6s : %.6s\n",     Header->OemId, Header2->OemId);
186     printf ("OEM Table ID       %8.8s : %.8s\n",     Header->OemTableId, Header2->OemTableId);
187     printf ("OEM Revision       %8.8X : %8.8X\n",    Header->OemRevision, Header2->OemRevision);
188     printf ("ASL Compiler ID    %8.4s : %.4s\n",     Header->AslCompilerId, Header2->AslCompilerId);
189     printf ("Compiler Revision  %8.8X : %8.8X\n",    Header->AslCompilerRevision, Header2->AslCompilerRevision);
190     printf ("\n");
191 }
192
193
194 /******************************************************************************
195  *
196  * FUNCTION:    AbDisplayHeader
197  *
198  * DESCRIPTION: Display an ACPI table header
199  *
200  ******************************************************************************/
201
202 void
203 AbDisplayHeader (
204     char                    *FilePath)
205 {
206     UINT32                  Actual;
207     FILE                    *File;
208
209
210     File = fopen (FilePath, "rb");
211     if (!File)
212     {
213         printf ("Could not open file %s\n", FilePath);
214         return;
215     }
216
217     Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
218     fclose (File);
219
220     if (Actual != sizeof (ACPI_TABLE_HEADER))
221     {
222         printf ("File %s does not contain a valid ACPI table header\n", FilePath);
223         return;
224     }
225
226     if (!AbValidateHeader (&Header1))
227     {
228         return;
229     }
230
231     AbPrintHeaderInfo (&Header1);
232 }
233
234
235 /******************************************************************************
236  *
237  * FUNCTION:    AbComputeChecksum
238  *
239  * DESCRIPTION: Compute proper checksum for an ACPI table
240  *
241  ******************************************************************************/
242
243 void
244 AbComputeChecksum (
245     char                    *FilePath)
246 {
247     UINT32                  Actual;
248     ACPI_TABLE_HEADER       *Table;
249     UINT8                   Checksum;
250     FILE                    *File;
251
252
253     File = fopen (FilePath, "rb");
254     if (!File)
255     {
256         printf ("Could not open file %s\n", FilePath);
257         return;
258     }
259
260     Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
261     if (Actual < sizeof (ACPI_TABLE_HEADER))
262     {
263         printf ("File %s does not contain a valid ACPI table header\n", FilePath);
264         goto Exit1;
265     }
266
267     if (!AbValidateHeader (&Header1))
268     {
269         goto Exit1;
270     }
271
272     if (!Gbl_TerseMode)
273     {
274         AbPrintHeaderInfo (&Header1);
275     }
276
277     /* Allocate a buffer to hold the entire table */
278
279     Table = AcpiOsAllocate (Header1.Length);
280     if (!Table)
281     {
282         printf ("Could not allocate buffer for table\n");
283         goto Exit1;
284     }
285
286     /* Read the entire table, including header */
287
288     fseek (File, 0, SEEK_SET);
289     Actual = fread (Table, 1, Header1.Length, File);
290     if (Actual != Header1.Length)
291     {
292         printf ("Could not read table, length %u\n", Header1.Length);
293         goto Exit2;
294     }
295
296     /* Compute the checksum for the table */
297
298     Table->Checksum = 0;
299
300     Checksum = (UINT8) (0 - AcpiTbSumTable (Table, Table->Length));
301     printf ("Computed checksum: 0x%X\n\n", Checksum);
302
303     if (Header1.Checksum == Checksum)
304     {
305         printf ("Checksum OK in AML file, not updating\n");
306         goto Exit2;
307     }
308
309     /* Open the target file for writing, to update checksum */
310
311     fclose (File);
312     File = fopen (FilePath, "r+b");
313     if (!File)
314     {
315         printf ("Could not open file %s for writing\n", FilePath);
316         goto Exit2;
317     }
318
319     /* Set the checksum, write the new header */
320
321     Header1.Checksum = Checksum;
322
323     Actual = fwrite (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
324     if (Actual != sizeof (ACPI_TABLE_HEADER))
325     {
326         printf ("Could not write updated table header\n");
327         goto Exit2;
328     }
329
330     printf ("Wrote new checksum\n");
331
332 Exit2:
333     AcpiOsFree (Table);
334
335 Exit1:
336     if (File)
337     {
338         fclose (File);
339     }
340     return;
341 }
342
343
344 /******************************************************************************
345  *
346  * FUNCTION:    AbCompareAmlFiles
347  *
348  * DESCRIPTION: Compare two AML files
349  *
350  ******************************************************************************/
351
352 int
353 AbCompareAmlFiles (
354     char                    *File1Path,
355     char                    *File2Path)
356 {
357     UINT32                  Actual1;
358     UINT32                  Actual2;
359     UINT32                  Offset;
360     UINT8                   Char1;
361     UINT8                   Char2;
362     UINT8                   Mismatches = 0;
363     BOOLEAN                 HeaderMismatch = FALSE;
364     FILE                    *File1;
365     FILE                    *File2;
366     int                     Status = -1;
367
368
369     File1 = fopen (File1Path, "rb");
370     if (!File1)
371     {
372         printf ("Could not open file %s\n", File1Path);
373         return (-1);
374     }
375
376     File2 = fopen (File2Path, "rb");
377     if (!File2)
378     {
379         printf ("Could not open file %s\n", File2Path);
380         goto Exit1;
381     }
382
383     /* Read the ACPI header from each file */
384
385     Actual1 = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File1);
386     if (Actual1 != sizeof (ACPI_TABLE_HEADER))
387     {
388         printf ("File %s does not contain an ACPI table header\n", File1Path);
389         goto Exit2;
390     }
391
392     Actual2 = fread (&Header2, 1, sizeof (ACPI_TABLE_HEADER), File2);
393     if (Actual2 != sizeof (ACPI_TABLE_HEADER))
394     {
395         printf ("File %s does not contain an ACPI table header\n", File2Path);
396         goto Exit2;
397     }
398
399     if ((!AbValidateHeader (&Header1)) ||
400         (!AbValidateHeader (&Header2)))
401     {
402         goto Exit2;
403     }
404
405     /* Table signatures must match */
406
407     if (*((UINT32 *) Header1.Signature) != *((UINT32 *) Header2.Signature))
408     {
409         printf ("Table signatures do not match\n");
410         goto Exit2;
411     }
412
413     if (!Gbl_TerseMode)
414     {
415         /* Display header information */
416
417         printf ("Comparing %s to %s\n", File1Path, File2Path);
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     printf ("Compare offset: %u\n", AbGbl_CompareOffset);
430     if (AbGbl_CompareOffset)
431     {
432         fseek (File2, AbGbl_CompareOffset, SEEK_CUR);
433     }
434
435     Actual1 = fread (&Char1, 1, 1, File1);
436     Actual2 = fread (&Char2, 1, 1, File2);
437     Offset = sizeof (ACPI_TABLE_HEADER);
438
439     while ((Actual1 == 1) && (Actual2 == 1))
440     {
441         if (Char1 != Char2)
442         {
443             printf ("Error - Byte mismatch at offset %8.4X: 0x%2.2X 0x%2.2X\n",
444                 Offset, Char1, Char2);
445             Mismatches++;
446             if ((Mismatches > 100) && (!AbGbl_DisplayAllMiscompares))
447             {
448                 printf ("100 Mismatches: Too many mismatches\n");
449                 goto Exit2;
450             }
451         }
452
453         Offset++;
454         Actual1 = fread (&Char1, 1, 1, File1);
455         Actual2 = fread (&Char2, 1, 1, File2);
456     }
457
458     if (Actual1)
459     {
460         printf ("Error - file %s is longer than file %s\n", File1Path, File2Path);
461         Mismatches++;
462     }
463     else if (Actual2)
464     {
465         printf ("Error - file %s is shorter than file %s\n", File1Path, File2Path);
466         Mismatches++;
467     }
468     else if (!Mismatches)
469     {
470         if (HeaderMismatch)
471         {
472             printf ("Files compare exactly after header\n");
473         }
474         else
475         {
476             printf ("Files compare exactly\n");
477         }
478     }
479
480     printf ("%u Mismatches found\n", Mismatches);
481     if (Mismatches == 0)
482     {
483         Status = 0;
484     }
485
486 Exit2:
487     fclose (File2);
488
489 Exit1:
490     fclose (File1);
491     return (Status);
492 }
493
494
495 /******************************************************************************
496  *
497  * FUNCTION:    AbGetFile
498  *
499  * DESCRIPTION: Open a file and read it entirely into a new buffer
500  *
501  ******************************************************************************/
502
503 static char *
504 AbGetFile (
505     char                    *Filename,
506     UINT32                  *FileSize)
507 {
508     FILE                    *File;
509     UINT32                  Size;
510     char                    *Buffer = NULL;
511     size_t                  Actual;
512
513
514     /* Binary mode does not alter CR/LF pairs */
515
516     File = fopen (Filename, "rb");
517     if (!File)
518     {
519         printf ("Could not open file %s\n", Filename);
520         return (NULL);
521     }
522
523     /* Need file size to allocate a buffer */
524
525     Size = CmGetFileSize (File);
526     if (Size == ACPI_UINT32_MAX)
527     {
528         printf ("Could not get file size (seek) for %s\n", Filename);
529         goto ErrorExit;
530     }
531
532     /* Allocate a buffer for the entire file */
533
534     Buffer = calloc (Size, 1);
535     if (!Buffer)
536     {
537         printf ("Could not allocate buffer of size %u\n", Size);
538         goto ErrorExit;
539     }
540
541     /* Read the entire file */
542
543     Actual = fread (Buffer, 1, Size, File);
544     if (Actual != Size)
545     {
546         printf ("Could not read the input file %s\n", Filename);
547         free (Buffer);
548         Buffer = NULL;
549         goto ErrorExit;
550     }
551
552     *FileSize = Size;
553
554 ErrorExit:
555     fclose (File);
556     return (Buffer);
557 }
558
559
560 /******************************************************************************
561  *
562  * FUNCTION:    AbDumpAmlFile
563  *
564  * DESCRIPTION: Dump a binary AML file to a text file
565  *
566  ******************************************************************************/
567
568 int
569 AbDumpAmlFile (
570     char                    *File1Path,
571     char                    *File2Path)
572 {
573     char                    *FileBuffer;
574     FILE                    *FileOutHandle;
575     UINT32                  FileSize = 0;
576     int                     Status = -1;
577
578
579     /* Get the entire AML file, validate header */
580
581     FileBuffer = AbGetFile (File1Path, &FileSize);
582     if (!FileBuffer)
583     {
584         return (-1);
585     }
586
587     printf ("Input file:  %s contains %u (0x%X) bytes\n",
588         File1Path, FileSize, FileSize);
589
590     FileOutHandle = fopen (File2Path, "wb");
591     if (!FileOutHandle)
592     {
593         printf ("Could not open file %s\n", File2Path);
594         goto Exit1;
595     }
596
597     if (!AbValidateHeader ((ACPI_TABLE_HEADER *) FileBuffer))
598     {
599         goto Exit2;
600     }
601
602     /* Convert binary AML to text, using common dump buffer routine */
603
604     AcpiGbl_DebugFile = FileOutHandle;
605     AcpiGbl_DbOutputFlags = ACPI_DB_REDIRECTABLE_OUTPUT;
606
607     AcpiOsPrintf ("%4.4s @ 0x%8.8X\n",
608         ((ACPI_TABLE_HEADER *) FileBuffer)->Signature, 0);
609
610     AcpiUtDumpBuffer ((UINT8 *) FileBuffer, FileSize, DB_BYTE_DISPLAY, 0);
611
612     /* Summary for the output file */
613
614     FileSize = CmGetFileSize (FileOutHandle);
615     printf ("Output file: %s contains %u (0x%X) bytes\n\n",
616         File2Path, FileSize, FileSize);
617
618     Status = 0;
619
620 Exit2:
621     fclose (FileOutHandle);
622
623 Exit1:
624     free (FileBuffer);
625     return (Status);
626 }