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