acpixtract.c revision 1.19 1 /******************************************************************************
2 *
3 * Module Name: acpixtract - Top level functions to convert ascii/hex
4 * ACPI tables to the original binary tables
5 *
6 *****************************************************************************/
7
8 /******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************
116 *
117 * Alternatively, you may choose to be licensed under the terms of the
118 * following license:
119 *
120 * Redistribution and use in source and binary forms, with or without
121 * modification, are permitted provided that the following conditions
122 * are met:
123 * 1. Redistributions of source code must retain the above copyright
124 * notice, this list of conditions, and the following disclaimer,
125 * without modification.
126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127 * substantially similar to the "NO WARRANTY" disclaimer below
128 * ("Disclaimer") and any redistribution must be conditioned upon
129 * including a substantially similar Disclaimer requirement for further
130 * binary redistribution.
131 * 3. Neither the names of the above-listed copyright holders nor the names
132 * of any contributors may be used to endorse or promote products derived
133 * from this software without specific prior written permission.
134 *
135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 *
147 * Alternatively, you may choose to be licensed under the terms of the
148 * GNU General Public License ("GPL") version 2 as published by the Free
149 * Software Foundation.
150 *
151 *****************************************************************************/
152
153 #include "acpixtract.h"
154
155
156 /******************************************************************************
157 *
158 * FUNCTION: AxExtractTables
159 *
160 * PARAMETERS: InputPathname - Filename for input acpidump file
161 * Signature - Requested ACPI signature to extract.
162 * NULL means extract ALL tables.
163 * MinimumInstances - Min instances that are acceptable
164 *
165 * RETURN: Status
166 *
167 * DESCRIPTION: Convert text ACPI tables to binary
168 *
169 ******************************************************************************/
170
171 int
172 AxExtractTables (
173 char *InputPathname,
174 char *Signature,
175 unsigned int MinimumInstances)
176 {
177 FILE *InputFile;
178 FILE *OutputFile = NULL;
179 int BytesConverted;
180 int ThisTableBytesWritten = 0;
181 unsigned int FoundTable = 0;
182 unsigned int Instances = 0;
183 unsigned int ThisInstance;
184 char ThisSignature[5];
185 char UpperSignature[5];
186 int Status = 0;
187 unsigned int State = AX_STATE_FIND_HEADER;
188
189 memset (UpperSignature, 0, sizeof(UpperSignature));
190
191 /* Open input in text mode, output is in binary mode */
192
193 InputFile = fopen (InputPathname, "r");
194 if (!InputFile)
195 {
196 printf ("Could not open input file %s\n", InputPathname);
197 return (-1);
198 }
199
200 if (!AxIsFileAscii (InputFile))
201 {
202 fclose (InputFile);
203 return (-1);
204 }
205
206 if (Signature)
207 {
208 strncpy (UpperSignature, Signature, ACPI_NAMESEG_SIZE);
209 AcpiUtStrupr (UpperSignature);
210
211 /* Are there enough instances of the table to continue? */
212
213 AxNormalizeSignature (UpperSignature);
214 Instances = AxCountTableInstances (InputPathname, UpperSignature);
215
216 if (Instances < MinimumInstances ||
217 (Instances == 0 && MinimumInstances == AX_OPTIONAL_TABLES))
218 {
219 printf ("Table [%s] was not found in %s\n",
220 UpperSignature, InputPathname);
221 fclose (InputFile);
222 return (0); /* Don't abort */
223 }
224
225 if (Instances == 0)
226 {
227 fclose (InputFile);
228 return (-1);
229 }
230 }
231
232 /* Convert all instances of the table to binary */
233
234 while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
235 {
236 /*
237 * Check up front if we have a header line of the form:
238 * DSDT @ 0xdfffd0c0 (10999 bytes)
239 */
240 if (AX_IS_TABLE_BLOCK_HEADER &&
241 (State == AX_STATE_EXTRACT_DATA))
242 {
243 /* End of previous table, start of new table */
244
245 if (ThisTableBytesWritten)
246 {
247 printf (AX_TABLE_INFO_FORMAT, ThisSignature, ThisTableBytesWritten,
248 ThisTableBytesWritten, Gbl_OutputFilename);
249 }
250 else
251 {
252 Gbl_TableCount--;
253 }
254
255 State = AX_STATE_FIND_HEADER;
256 }
257
258 switch (State)
259 {
260 case AX_STATE_FIND_HEADER:
261
262 if (!AxIsDataBlockHeader ())
263 {
264 continue;
265 }
266
267 ACPI_COPY_NAMESEG (ThisSignature, Gbl_LineBuffer);
268 if (Signature)
269 {
270 /* Ignore signatures that don't match */
271
272 if (!ACPI_COMPARE_NAMESEG (ThisSignature, UpperSignature))
273 {
274 continue;
275 }
276 }
277
278 /*
279 * Get the instance number for this signature. Only the
280 * SSDT and PSDT tables can have multiple instances.
281 */
282 ThisInstance = AxGetNextInstance (InputPathname, ThisSignature);
283
284 /* Build an output filename and create/open the output file */
285
286 if (ThisInstance > 0)
287 {
288 /* Add instance number to the output filename */
289
290 sprintf (Gbl_OutputFilename, "%4.4s%u.dat",
291 ThisSignature, ThisInstance);
292 }
293 else
294 {
295 sprintf (Gbl_OutputFilename, "%4.4s.dat",
296 ThisSignature);
297 }
298
299 AcpiUtStrlwr (Gbl_OutputFilename);
300 OutputFile = fopen (Gbl_OutputFilename, "w+b");
301 if (!OutputFile)
302 {
303 printf ("Could not open output file %s\n",
304 Gbl_OutputFilename);
305 fclose (InputFile);
306 return (-1);
307 }
308
309 /*
310 * Toss this block header of the form "<sig> @ <addr>" line
311 * and move on to the actual data block
312 */
313 Gbl_TableCount++;
314 FoundTable = 1;
315 ThisTableBytesWritten = 0;
316 State = AX_STATE_EXTRACT_DATA;
317 continue;
318
319 case AX_STATE_EXTRACT_DATA:
320
321 if (!AxIsHexDataLine ())
322 {
323 continue; /* Toss any lines that are not raw hex data */
324 }
325
326 /* Empty line or non-data line terminates the data block */
327
328 BytesConverted = AxConvertAndWrite (OutputFile, ThisSignature);
329 switch (BytesConverted)
330 {
331 case 0:
332
333 State = AX_STATE_FIND_HEADER; /* No more data block lines */
334 continue;
335
336 case -1:
337
338 Status = -1;
339 goto CleanupAndExit; /* There was a write error */
340
341 default: /* Normal case, get next line */
342
343 ThisTableBytesWritten += BytesConverted;
344 continue;
345 }
346
347 default:
348
349 Status = -1;
350 goto CleanupAndExit;
351 }
352 }
353
354 if (!FoundTable)
355 {
356 printf ("No ACPI tables were found in %s\n", InputPathname);
357 }
358
359
360 CleanupAndExit:
361
362 if (State == AX_STATE_EXTRACT_DATA)
363 {
364 /* Received an input file EOF while extracting data */
365
366 printf (AX_TABLE_INFO_FORMAT, ThisSignature, ThisTableBytesWritten,
367 ThisTableBytesWritten, Gbl_OutputFilename);
368 }
369
370 if (OutputFile)
371 {
372 fclose (OutputFile);
373 }
374
375 fclose (InputFile);
376 return (Status);
377 }
378
379
380 /******************************************************************************
381 *
382 * FUNCTION: AxExtractToMultiAmlFile
383 *
384 * PARAMETERS: InputPathname - Filename for input acpidump file
385 *
386 * RETURN: Status
387 *
388 * DESCRIPTION: Convert all DSDT/SSDT tables to binary and append them all
389 * into a single output file. Used to simplify the loading of
390 * multiple/many SSDTs into a utility like acpiexec -- instead
391 * of creating many separate output files.
392 *
393 ******************************************************************************/
394
395 int
396 AxExtractToMultiAmlFile (
397 char *InputPathname)
398 {
399 FILE *InputFile;
400 FILE *OutputFile;
401 int Status = 0;
402 int TotalBytesWritten = 0;
403 int ThisTableBytesWritten = 0;
404 unsigned int BytesConverted;
405 char ThisSignature[4];
406 unsigned int State = AX_STATE_FIND_HEADER;
407
408
409 strcpy (Gbl_OutputFilename, AX_MULTI_TABLE_FILENAME);
410
411 /* Open the input file in text mode */
412
413 InputFile = fopen (InputPathname, "r");
414 if (!InputFile)
415 {
416 printf ("Could not open input file %s\n", InputPathname);
417 return (-1);
418 }
419
420 if (!AxIsFileAscii (InputFile))
421 {
422 fclose (InputFile);
423 return (-1);
424 }
425
426 /* Open the output file in binary mode */
427
428 OutputFile = fopen (Gbl_OutputFilename, "w+b");
429 if (!OutputFile)
430 {
431 printf ("Could not open output file %s\n", Gbl_OutputFilename);
432 fclose (InputFile);
433 return (-1);
434 }
435
436 /* Convert the DSDT and all SSDTs to binary */
437
438 while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
439 {
440 /*
441 * Check up front if we have a header line of the form:
442 * DSDT @ 0xdfffd0c0 (10999 bytes)
443 */
444 if (AX_IS_TABLE_BLOCK_HEADER &&
445 (State == AX_STATE_EXTRACT_DATA))
446 {
447 /* End of previous table, start of new table */
448
449 if (ThisTableBytesWritten)
450 {
451 printf (AX_TABLE_INFO_FORMAT, ThisSignature, ThisTableBytesWritten,
452 ThisTableBytesWritten, Gbl_OutputFilename);
453 }
454 else
455 {
456 Gbl_TableCount--;
457 }
458
459 State = AX_STATE_FIND_HEADER;
460 }
461
462 switch (State)
463 {
464 case AX_STATE_FIND_HEADER:
465
466 if (!AxIsDataBlockHeader ())
467 {
468 continue;
469 }
470
471 ACPI_COPY_NAMESEG (ThisSignature, Gbl_LineBuffer);
472
473 /* Only want DSDT and SSDTs */
474
475 if (!ACPI_COMPARE_NAMESEG (ThisSignature, ACPI_SIG_DSDT) &&
476 !ACPI_COMPARE_NAMESEG (ThisSignature, ACPI_SIG_SSDT))
477 {
478 continue;
479 }
480
481 /*
482 * Toss this block header of the form "<sig> @ <addr>" line
483 * and move on to the actual data block
484 */
485 Gbl_TableCount++;
486 ThisTableBytesWritten = 0;
487 State = AX_STATE_EXTRACT_DATA;
488 continue;
489
490 case AX_STATE_EXTRACT_DATA:
491
492 if (!AxIsHexDataLine ())
493 {
494 continue; /* Toss any lines that are not raw hex data */
495 }
496
497 /* Empty line or non-data line terminates the data block */
498
499 BytesConverted = AxConvertAndWrite (OutputFile, ThisSignature);
500 switch (BytesConverted)
501 {
502 case 0:
503
504 State = AX_STATE_FIND_HEADER; /* No more data block lines */
505 continue;
506
507 case -1:
508
509 Status = -1;
510 goto CleanupAndExit; /* There was a write error */
511
512 default: /* Normal case, get next line */
513
514 ThisTableBytesWritten += BytesConverted;
515 TotalBytesWritten += BytesConverted;
516 continue;
517 }
518
519 default:
520
521 Status = -1;
522 goto CleanupAndExit;
523 }
524 }
525
526
527 CleanupAndExit:
528
529 if (State == AX_STATE_EXTRACT_DATA)
530 {
531 /* Received an input file EOF or error while writing data */
532
533 printf (AX_TABLE_INFO_FORMAT, ThisSignature, ThisTableBytesWritten,
534 ThisTableBytesWritten, Gbl_OutputFilename);
535 }
536
537 printf ("\n%u binary ACPI tables extracted and written to %s (%u bytes)\n",
538 Gbl_TableCount, Gbl_OutputFilename, TotalBytesWritten);
539
540 fclose (InputFile);
541 fclose (OutputFile);
542 return (Status);
543 }
544
545
546 /******************************************************************************
547 *
548 * FUNCTION: AxListAllTables
549 *
550 * PARAMETERS: InputPathname - Filename for acpidump file
551 *
552 * RETURN: Status
553 *
554 * DESCRIPTION: Display info for all ACPI tables found in input. Does not
555 * perform an actual extraction of the tables.
556 *
557 ******************************************************************************/
558
559 int
560 AxListAllTables (
561 char *InputPathname)
562 {
563 FILE *InputFile;
564 unsigned char Header[48];
565 UINT32 ByteCount = 0;
566 INT32 ThisLineByteCount;
567 unsigned int State = AX_STATE_FIND_HEADER;
568
569
570 /* Open input in text mode, output is in binary mode */
571
572 InputFile = fopen (InputPathname, "r");
573 if (!InputFile)
574 {
575 printf ("Could not open input file %s\n", InputPathname);
576 return (-1);
577 }
578
579 if (!AxIsFileAscii (InputFile))
580 {
581 fclose (InputFile);
582 return (-1);
583 }
584
585 /* Info header */
586
587 printf ("\n Signature Length Version Oem Oem "
588 "Oem Compiler Compiler\n");
589 printf ( " Id TableId "
590 "RevisionId Name Revision\n");
591 printf ( " _________ __________ ____ ________ __________ "
592 "__________ _______ __________\n\n");
593
594 /* Dump the headers for all tables found in the input file */
595
596 while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
597 {
598 /* Ignore empty lines */
599
600 if (AxIsEmptyLine (Gbl_LineBuffer))
601 {
602 continue;
603 }
604
605 /*
606 * Check up front if we have a header line of the form:
607 * DSDT @ 0xdfffd0c0 (10999 bytes)
608 */
609 if (AX_IS_TABLE_BLOCK_HEADER &&
610 (State == AX_STATE_EXTRACT_DATA))
611 {
612 State = AX_STATE_FIND_HEADER;
613 }
614
615 switch (State)
616 {
617 case AX_STATE_FIND_HEADER:
618
619 ByteCount = 0;
620 if (!AxIsDataBlockHeader ())
621 {
622 continue;
623 }
624
625 State = AX_STATE_EXTRACT_DATA;
626 continue;
627
628 case AX_STATE_EXTRACT_DATA:
629
630 /* Ignore any lines that don't look like a data line */
631
632 if (!AxIsHexDataLine ())
633 {
634 continue; /* Toss any lines that are not raw hex data */
635 }
636
637 /* Convert header to hex and display it */
638
639 ThisLineByteCount = AxConvertToBinary (Gbl_LineBuffer,
640 &Header[ByteCount]);
641 if (ThisLineByteCount == EOF)
642 {
643 fclose (InputFile);
644 return (-1);
645 }
646
647 ByteCount += ThisLineByteCount;
648 if (ByteCount >= sizeof (ACPI_TABLE_HEADER))
649 {
650 AxDumpTableHeader (Header);
651 State = AX_STATE_FIND_HEADER;
652 }
653 continue;
654
655 default:
656 break;
657 }
658 }
659
660 printf ("\nFound %u ACPI tables in %s\n", Gbl_TableCount, InputPathname);
661 fclose (InputFile);
662 return (0);
663 }
664