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