1 /******************************************************************************
2 *
3 * Module Name: dtio.c - File I/O support for data table compiler
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152 #include "aslcompiler.h"
153 #include "acapps.h"
154
155 #define _COMPONENT DT_COMPILER
156 ACPI_MODULE_NAME ("dtio")
157
158
159 /* Local prototypes */
160
161 static char *
162 DtTrim (
163 char *String);
164
165 static ACPI_STATUS
166 DtParseLine (
167 char *LineBuffer,
168 UINT32 Line,
169 UINT32 Offset);
170
171 static void
172 DtWriteBinary (
173 DT_SUBTABLE *Subtable,
174 void *Context,
175 void *ReturnValue);
176
177 static void
178 DtDumpBuffer (
179 UINT32 FileId,
180 UINT8 *Buffer,
181 UINT32 Offset,
182 UINT32 Length);
183
184 static void
185 DtDumpSubtableInfo (
186 DT_SUBTABLE *Subtable,
187 void *Context,
188 void *ReturnValue);
189
190 static void
191 DtDumpSubtableTree (
192 DT_SUBTABLE *Subtable,
193 void *Context,
194 void *ReturnValue);
195
196
197 /* States for DtGetNextLine */
198
199 #define DT_NORMAL_TEXT 0
200 #define DT_START_QUOTED_STRING 1
201 #define DT_START_COMMENT 2
202 #define DT_SLASH_ASTERISK_COMMENT 3
203 #define DT_SLASH_SLASH_COMMENT 4
204 #define DT_END_COMMENT 5
205 #define DT_MERGE_LINES 6
206 #define DT_ESCAPE_SEQUENCE 7
207
208 static UINT32 AslGbl_NextLineOffset;
209
210
211 /******************************************************************************
212 *
213 * FUNCTION: DtTrim
214 *
215 * PARAMETERS: String - Current source code line to trim
216 *
217 * RETURN: Trimmed line. Must be freed by caller.
218 *
219 * DESCRIPTION: Trim left and right spaces
220 *
221 *****************************************************************************/
222
223 static char *
DtTrim(char * String)224 DtTrim (
225 char *String)
226 {
227 char *Start;
228 char *End;
229 char *ReturnString;
230 ACPI_SIZE Length;
231
232
233 /* Skip lines that start with a space */
234
235 if (*String == 0 || !strcmp (String, " "))
236 {
237 ReturnString = UtLocalCacheCalloc (1);
238 return (ReturnString);
239 }
240
241 /* Setup pointers to start and end of input string */
242
243 Start = String;
244 End = String + strlen (String) - 1;
245
246 /* Find first non-whitespace character */
247
248 while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
249 {
250 Start++;
251 }
252
253 /* Find last non-space character */
254
255 while (End >= Start)
256 {
257 if (*End == '\n')
258 {
259 End--;
260 continue;
261 }
262
263 if (*End != ' ')
264 {
265 break;
266 }
267
268 End--;
269 }
270
271 /* Remove any quotes around the string */
272
273 if (*Start == '\"')
274 {
275 Start++;
276 }
277 if (*End == '\"')
278 {
279 End--;
280 }
281
282 /* Create the trimmed return string */
283
284 Length = ACPI_PTR_DIFF (End, Start) + 1;
285 ReturnString = UtLocalCacheCalloc (Length + 1);
286 if (strlen (Start))
287 {
288 strncpy (ReturnString, Start, Length);
289 }
290
291 ReturnString[Length] = 0;
292 return (ReturnString);
293 }
294
295
296 /******************************************************************************
297 *
298 * FUNCTION: DtParseLine
299 *
300 * PARAMETERS: LineBuffer - Current source code line
301 * Line - Current line number in the source
302 * Offset - Current byte offset of the line
303 *
304 * RETURN: Status
305 *
306 * DESCRIPTION: Parse one source line
307 *
308 *****************************************************************************/
309
310 static ACPI_STATUS
DtParseLine(char * LineBuffer,UINT32 Line,UINT32 Offset)311 DtParseLine (
312 char *LineBuffer,
313 UINT32 Line,
314 UINT32 Offset)
315 {
316 char *Start;
317 char *End;
318 char *TmpName;
319 char *TmpValue;
320 char *Name;
321 char *Value;
322 char *Colon;
323 UINT32 Length;
324 DT_FIELD *Field;
325 UINT32 Column;
326 UINT32 NameColumn;
327 BOOLEAN IsNullString = FALSE;
328
329
330 if (!LineBuffer)
331 {
332 return (AE_OK);
333 }
334
335 /* All lines after "Raw Table Data" are ignored */
336
337 if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
338 {
339 return (AE_NOT_FOUND);
340 }
341
342 Colon = strchr (LineBuffer, ':');
343 if (!Colon)
344 {
345 return (AE_OK);
346 }
347
348 Start = LineBuffer;
349 End = Colon;
350
351 while (Start < Colon)
352 {
353 if (*Start == '[')
354 {
355 /* Found left bracket, go to the right bracket */
356
357 while (Start < Colon && *Start != ']')
358 {
359 Start++;
360 }
361 }
362 else if (*Start != ' ')
363 {
364 break;
365 }
366
367 Start++;
368 }
369
370 /*
371 * There are two column values. One for the field name,
372 * and one for the field value.
373 */
374 Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
375 NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
376
377 Length = ACPI_PTR_DIFF (End, Start);
378
379 TmpName = UtLocalCalloc (Length + 1);
380 strncpy (TmpName, Start, Length);
381 Name = DtTrim (TmpName);
382 ACPI_FREE (TmpName);
383
384 Start = End = (Colon + 1);
385 while (*End)
386 {
387 /* Found left quotation, go to the right quotation and break */
388
389 if (*End == '"')
390 {
391 End++;
392
393 /* Check for an explicit null string */
394
395 if (*End == '"')
396 {
397 IsNullString = TRUE;
398 }
399 while (*End && (*End != '"'))
400 {
401 End++;
402 }
403
404 End++;
405 break;
406 }
407
408 /*
409 * Special "comment" fields at line end, ignore them.
410 * Note: normal slash-slash and slash-asterisk comments are
411 * stripped already by the DtGetNextLine parser.
412 *
413 * TBD: Perhaps DtGetNextLine should parse the following type
414 * of comments also.
415 */
416 if (*End == '[')
417 {
418 End--;
419 break;
420 }
421
422 End++;
423 }
424
425 Length = ACPI_PTR_DIFF (End, Start);
426 TmpValue = UtLocalCalloc (Length + 1);
427
428 strncpy (TmpValue, Start, Length);
429 Value = DtTrim (TmpValue);
430 ACPI_FREE (TmpValue);
431
432 /* Create a new field object only if we have a valid value field */
433
434 if ((Value && *Value) || IsNullString)
435 {
436 Field = UtFieldCacheCalloc ();
437 Field->Name = Name;
438 Field->Value = Value;
439 Field->Line = Line;
440 Field->ByteOffset = Offset;
441 Field->NameColumn = NameColumn;
442 Field->Column = Column;
443 Field->StringLength = Length;
444
445 DtLinkField (Field);
446 }
447 /* Else -- Ignore this field, it has no valid data */
448
449 return (AE_OK);
450 }
451
452
453 /******************************************************************************
454 *
455 * FUNCTION: DtGetNextLine
456 *
457 * PARAMETERS: Handle - Open file handle for the source file
458 *
459 * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
460 *
461 * DESCRIPTION: Get the next valid source line. Removes all comments.
462 * Ignores empty lines.
463 *
464 * Handles both slash-asterisk and slash-slash comments.
465 * Also, quoted strings, but no escapes within.
466 *
467 * Line is returned in AslGbl_CurrentLineBuffer.
468 * Line number in original file is returned in AslGbl_CurrentLineNumber.
469 *
470 *****************************************************************************/
471
472 UINT32
DtGetNextLine(FILE * Handle,UINT32 Flags)473 DtGetNextLine (
474 FILE *Handle,
475 UINT32 Flags)
476 {
477 BOOLEAN LineNotAllBlanks = FALSE;
478 UINT32 State = DT_NORMAL_TEXT;
479 UINT32 CurrentLineOffset;
480 UINT32 i;
481 int c;
482 int c1;
483
484
485 memset (AslGbl_CurrentLineBuffer, 0, AslGbl_LineBufferSize);
486 for (i = 0; ;)
487 {
488 /*
489 * If line is too long, expand the line buffers. Also increases
490 * AslGbl_LineBufferSize.
491 */
492 if (i >= AslGbl_LineBufferSize)
493 {
494 UtExpandLineBuffers ();
495 }
496
497 c = getc (Handle);
498 if (c == EOF)
499 {
500 switch (State)
501 {
502 case DT_START_QUOTED_STRING:
503 case DT_SLASH_ASTERISK_COMMENT:
504
505 AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
506 break;
507
508 default:
509
510 break;
511 }
512
513 /* Standalone EOF is OK */
514
515 if (i == 0)
516 {
517 return (ASL_EOF);
518 }
519
520 /*
521 * Received an EOF in the middle of a line. Terminate the
522 * line with a newline. The next call to this function will
523 * return a standalone EOF. Thus, the upper parsing software
524 * never has to deal with an EOF within a valid line (or
525 * the last line does not get tossed on the floor.)
526 */
527 c = '\n';
528 State = DT_NORMAL_TEXT;
529 }
530 else if (c == '\r')
531 {
532 c1 = getc (Handle);
533 if (c1 == '\n')
534 {
535 /*
536 * Skip the carriage return as if it didn't exist. This is
537 * onlt meant for input files in DOS format in unix. fopen in
538 * unix may not support "text mode" and leaves CRLF intact.
539 */
540 c = '\n';
541 }
542 else
543 {
544 /* This was not a CRLF. Only a CR */
545
546 ungetc(c1, Handle);
547
548 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL,
549 "Carriage return without linefeed detected");
550 return (ASL_EOF);
551 }
552 }
553
554 switch (State)
555 {
556 case DT_NORMAL_TEXT:
557
558 /* Normal text, insert char into line buffer */
559
560 AslGbl_CurrentLineBuffer[i] = (char) c;
561 switch (c)
562 {
563 case '/':
564
565 State = DT_START_COMMENT;
566 break;
567
568 case '"':
569
570 State = DT_START_QUOTED_STRING;
571 LineNotAllBlanks = TRUE;
572 i++;
573 break;
574
575 case '\\':
576 /*
577 * The continuation char MUST be last char on this line.
578 * Otherwise, it will be assumed to be a valid ASL char.
579 */
580 State = DT_MERGE_LINES;
581 break;
582
583 case '\n':
584
585 CurrentLineOffset = AslGbl_NextLineOffset;
586 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
587 AslGbl_CurrentLineNumber++;
588
589 /*
590 * Exit if line is complete. Ignore empty lines (only \n)
591 * or lines that contain nothing but blanks.
592 */
593 if ((i != 0) && LineNotAllBlanks)
594 {
595 if ((i + 1) >= AslGbl_LineBufferSize)
596 {
597 UtExpandLineBuffers ();
598 }
599
600 AslGbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
601 return (CurrentLineOffset);
602 }
603
604 /* Toss this line and start a new one */
605
606 i = 0;
607 LineNotAllBlanks = FALSE;
608 break;
609
610 default:
611
612 if (c != ' ')
613 {
614 LineNotAllBlanks = TRUE;
615 }
616
617 i++;
618 break;
619 }
620 break;
621
622 case DT_START_QUOTED_STRING:
623
624 /* Insert raw chars until end of quoted string */
625
626 AslGbl_CurrentLineBuffer[i] = (char) c;
627 i++;
628
629 switch (c)
630 {
631 case '"':
632
633 State = DT_NORMAL_TEXT;
634 break;
635
636 case '\\':
637
638 State = DT_ESCAPE_SEQUENCE;
639 break;
640
641 case '\n':
642
643 if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
644 {
645 AcpiOsPrintf (
646 "ERROR at line %u: Unterminated quoted string\n",
647 AslGbl_CurrentLineNumber++);
648 State = DT_NORMAL_TEXT;
649 }
650 break;
651
652 default: /* Get next character */
653
654 break;
655 }
656 break;
657
658 case DT_ESCAPE_SEQUENCE:
659
660 /* Just copy the escaped character. TBD: sufficient for table compiler? */
661
662 AslGbl_CurrentLineBuffer[i] = (char) c;
663 i++;
664 State = DT_START_QUOTED_STRING;
665 break;
666
667 case DT_START_COMMENT:
668
669 /* Open comment if this character is an asterisk or slash */
670
671 switch (c)
672 {
673 case '*':
674
675 State = DT_SLASH_ASTERISK_COMMENT;
676 break;
677
678 case '/':
679
680 State = DT_SLASH_SLASH_COMMENT;
681 break;
682
683 default: /* Not a comment */
684
685 i++; /* Save the preceding slash */
686 if (i >= AslGbl_LineBufferSize)
687 {
688 UtExpandLineBuffers ();
689 }
690
691 AslGbl_CurrentLineBuffer[i] = (char) c;
692 i++;
693 State = DT_NORMAL_TEXT;
694 break;
695 }
696 break;
697
698 case DT_SLASH_ASTERISK_COMMENT:
699
700 /* Ignore chars until an asterisk-slash is found */
701
702 switch (c)
703 {
704 case '\n':
705
706 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
707 AslGbl_CurrentLineNumber++;
708 break;
709
710 case '*':
711
712 State = DT_END_COMMENT;
713 break;
714
715 default:
716
717 break;
718 }
719 break;
720
721 case DT_SLASH_SLASH_COMMENT:
722
723 /* Ignore chars until end-of-line */
724
725 if (c == '\n')
726 {
727 /* We will exit via the NORMAL_TEXT path */
728
729 ungetc (c, Handle);
730 State = DT_NORMAL_TEXT;
731 }
732 break;
733
734 case DT_END_COMMENT:
735
736 /* End comment if this char is a slash */
737
738 switch (c)
739 {
740 case '/':
741
742 State = DT_NORMAL_TEXT;
743 break;
744
745 case '\n':
746
747 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
748 AslGbl_CurrentLineNumber++;
749 break;
750
751 case '*':
752
753 /* Consume all adjacent asterisks */
754 break;
755
756 default:
757
758 State = DT_SLASH_ASTERISK_COMMENT;
759 break;
760 }
761 break;
762
763 case DT_MERGE_LINES:
764
765 if (c != '\n')
766 {
767 /*
768 * This is not a continuation backslash, it is a normal
769 * normal ASL backslash - for example: Scope(\_SB_)
770 */
771 i++; /* Keep the backslash that is already in the buffer */
772
773 ungetc (c, Handle);
774 State = DT_NORMAL_TEXT;
775 }
776 else
777 {
778 /*
779 * This is a continuation line -- a backlash followed
780 * immediately by a newline. Insert a space between the
781 * lines (overwrite the backslash)
782 */
783 AslGbl_CurrentLineBuffer[i] = ' ';
784 i++;
785
786 /* Ignore newline, this will merge the lines */
787
788 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
789 AslGbl_CurrentLineNumber++;
790 State = DT_NORMAL_TEXT;
791 }
792 break;
793
794 default:
795
796 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
797 return (ASL_EOF);
798 }
799 }
800 }
801
802
803 /******************************************************************************
804 *
805 * FUNCTION: DtScanFile
806 *
807 * PARAMETERS: Handle - Open file handle for the source file
808 *
809 * RETURN: Pointer to start of the constructed parse tree.
810 *
811 * DESCRIPTION: Scan source file, link all field names and values
812 * to the global parse tree: AslGbl_FieldList
813 *
814 *****************************************************************************/
815
816 DT_FIELD *
DtScanFile(FILE * Handle)817 DtScanFile (
818 FILE *Handle)
819 {
820 ACPI_STATUS Status;
821 UINT32 Offset;
822
823
824 ACPI_FUNCTION_NAME (DtScanFile);
825
826
827 /* Get the file size */
828
829 AslGbl_InputByteCount = CmGetFileSize (Handle);
830 if (AslGbl_InputByteCount == ACPI_UINT32_MAX)
831 {
832 AslAbort ();
833 }
834
835 AslGbl_CurrentLineNumber = 0;
836 AslGbl_CurrentLineOffset = 0;
837 AslGbl_NextLineOffset = 0;
838
839 /* Scan line-by-line */
840
841 while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
842 {
843 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
844 AslGbl_CurrentLineNumber, Offset, AslGbl_CurrentLineBuffer));
845
846 Status = DtParseLine (AslGbl_CurrentLineBuffer,
847 AslGbl_CurrentLineNumber, Offset);
848 if (Status == AE_NOT_FOUND)
849 {
850 break;
851 }
852 }
853
854 /* Dump the parse tree if debug enabled */
855
856 DtDumpFieldList (AslGbl_FieldList);
857 return (AslGbl_FieldList);
858 }
859
860
861 /*
862 * Output functions
863 */
864
865 /******************************************************************************
866 *
867 * FUNCTION: DtWriteBinary
868 *
869 * PARAMETERS: DT_WALK_CALLBACK
870 *
871 * RETURN: Status
872 *
873 * DESCRIPTION: Write one subtable of a binary ACPI table
874 *
875 *****************************************************************************/
876
877 static void
DtWriteBinary(DT_SUBTABLE * Subtable,void * Context,void * ReturnValue)878 DtWriteBinary (
879 DT_SUBTABLE *Subtable,
880 void *Context,
881 void *ReturnValue)
882 {
883
884 FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
885 }
886
887
888 /******************************************************************************
889 *
890 * FUNCTION: DtOutputBinary
891 *
892 * PARAMETERS:
893 *
894 * RETURN: Status
895 *
896 * DESCRIPTION: Write entire binary ACPI table (result of compilation)
897 *
898 *****************************************************************************/
899
900 void
DtOutputBinary(DT_SUBTABLE * RootTable)901 DtOutputBinary (
902 DT_SUBTABLE *RootTable)
903 {
904
905 if (!RootTable)
906 {
907 return;
908 }
909
910 /* Walk the entire parse tree, emitting the binary data */
911
912 DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
913
914 AslGbl_TableLength = CmGetFileSize (AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle);
915 if (AslGbl_TableLength == ACPI_UINT32_MAX)
916 {
917 AslAbort ();
918 }
919 }
920
921
922 /*
923 * Listing support
924 */
925
926 /******************************************************************************
927 *
928 * FUNCTION: DtDumpBuffer
929 *
930 * PARAMETERS: FileID - Where to write buffer data
931 * Buffer - Buffer to dump
932 * Offset - Offset in current table
933 * Length - Buffer Length
934 *
935 * RETURN: None
936 *
937 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
938 *
939 * TBD: merge dump buffer routines
940 *
941 *****************************************************************************/
942
943 static void
DtDumpBuffer(UINT32 FileId,UINT8 * Buffer,UINT32 Offset,UINT32 Length)944 DtDumpBuffer (
945 UINT32 FileId,
946 UINT8 *Buffer,
947 UINT32 Offset,
948 UINT32 Length)
949 {
950 UINT32 i;
951 UINT32 j;
952 UINT8 BufChar;
953
954
955 FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3.3Xh] ",
956 Offset, Offset, Length);
957
958 i = 0;
959 while (i < Length)
960 {
961 if (i >= 16)
962 {
963 FlPrintFile (FileId, "%24s", "");
964 }
965
966 /* Print 16 hex chars */
967
968 for (j = 0; j < 16;)
969 {
970 if (i + j >= Length)
971 {
972 /* Dump fill spaces */
973
974 FlPrintFile (FileId, " ");
975 j++;
976 continue;
977 }
978
979 FlPrintFile (FileId, "%02X ", Buffer[i+j]);
980 j++;
981 }
982
983 FlPrintFile (FileId, " ");
984 for (j = 0; j < 16; j++)
985 {
986 if (i + j >= Length)
987 {
988 FlPrintFile (FileId, "\n\n");
989 return;
990 }
991
992 BufChar = Buffer[(ACPI_SIZE) i + j];
993 if (isprint (BufChar))
994 {
995 FlPrintFile (FileId, "%c", BufChar);
996 }
997 else
998 {
999 FlPrintFile (FileId, ".");
1000 }
1001 }
1002
1003 /* Done with that line. */
1004
1005 FlPrintFile (FileId, "\n");
1006 i += 16;
1007 }
1008
1009 FlPrintFile (FileId, "\n\n");
1010 }
1011
1012
1013 /******************************************************************************
1014 *
1015 * FUNCTION: DtDumpFieldList
1016 *
1017 * PARAMETERS: Field - Root field
1018 *
1019 * RETURN: None
1020 *
1021 * DESCRIPTION: Dump the entire field list
1022 *
1023 *****************************************************************************/
1024
1025 void
DtDumpFieldList(DT_FIELD * Field)1026 DtDumpFieldList (
1027 DT_FIELD *Field)
1028 {
1029
1030 if (!AslGbl_DebugFlag || !Field)
1031 {
1032 return;
1033 }
1034
1035 DbgPrint (ASL_DEBUG_OUTPUT, "\nField List:\n"
1036 "LineNo ByteOff NameCol Column TableOff "
1037 "Flags %32s : %s\n\n", "Name", "Value");
1038
1039 while (Field)
1040 {
1041 DbgPrint (ASL_DEBUG_OUTPUT,
1042 "%.08X %.08X %.08X %.08X %.08X %2.2X %32s : %s\n",
1043 Field->Line, Field->ByteOffset, Field->NameColumn,
1044 Field->Column, Field->TableOffset, Field->Flags,
1045 Field->Name, Field->Value);
1046
1047 Field = Field->Next;
1048 }
1049
1050 DbgPrint (ASL_DEBUG_OUTPUT, "\n\n");
1051 }
1052
1053
1054 /******************************************************************************
1055 *
1056 * FUNCTION: DtDumpSubtableInfo, DtDumpSubtableTree
1057 *
1058 * PARAMETERS: DT_WALK_CALLBACK
1059 *
1060 * RETURN: None
1061 *
1062 * DESCRIPTION: Info - dump a subtable tree entry with extra information.
1063 * Tree - dump a subtable tree formatted by depth indentation.
1064 *
1065 *****************************************************************************/
1066
1067 static void
DtDumpSubtableInfo(DT_SUBTABLE * Subtable,void * Context,void * ReturnValue)1068 DtDumpSubtableInfo (
1069 DT_SUBTABLE *Subtable,
1070 void *Context,
1071 void *ReturnValue)
1072 {
1073
1074 DbgPrint (ASL_DEBUG_OUTPUT,
1075 "[%.04X] %24s %.08X %.08X %.08X %.08X %p %p %p %p\n",
1076 Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength,
1077 Subtable->SizeOfLengthField, Subtable->Flags, Subtable,
1078 Subtable->Parent, Subtable->Child, Subtable->Peer);
1079 }
1080
1081 static void
DtDumpSubtableTree(DT_SUBTABLE * Subtable,void * Context,void * ReturnValue)1082 DtDumpSubtableTree (
1083 DT_SUBTABLE *Subtable,
1084 void *Context,
1085 void *ReturnValue)
1086 {
1087
1088 DbgPrint (ASL_DEBUG_OUTPUT,
1089 "[%.04X] %24s %*s%p (%.02X) - (%.02X) %.02X\n",
1090 Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ",
1091 Subtable, Subtable->Length, Subtable->TotalLength, *Subtable->Buffer);
1092 }
1093
1094
1095 /******************************************************************************
1096 *
1097 * FUNCTION: DtDumpSubtableList
1098 *
1099 * PARAMETERS: None
1100 *
1101 * RETURN: None
1102 *
1103 * DESCRIPTION: Dump the raw list of subtables with information, and also
1104 * dump the subtable list in formatted tree format. Assists with
1105 * the development of new table code.
1106 *
1107 *****************************************************************************/
1108
1109 void
DtDumpSubtableList(void)1110 DtDumpSubtableList (
1111 void)
1112 {
1113
1114 if (!AslGbl_DebugFlag || !AslGbl_RootTable)
1115 {
1116 return;
1117 }
1118
1119 DbgPrint (ASL_DEBUG_OUTPUT,
1120 "Subtable Info:\n"
1121 "Depth Name Length TotalLen LenSize Flags "
1122 "This Parent Child Peer\n\n");
1123 DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableInfo, NULL, NULL);
1124
1125 DbgPrint (ASL_DEBUG_OUTPUT,
1126 "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength, Integer Value)\n\n");
1127 DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableTree, NULL, NULL);
1128
1129 DbgPrint (ASL_DEBUG_OUTPUT, "\n");
1130 }
1131
1132
1133 /******************************************************************************
1134 *
1135 * FUNCTION: DtWriteFieldToListing
1136 *
1137 * PARAMETERS: Buffer - Contains the compiled data
1138 * Field - Field node for the input line
1139 * Length - Length of the output data
1140 *
1141 * RETURN: None
1142 *
1143 * DESCRIPTION: Write one field to the listing file (if listing is enabled).
1144 *
1145 *****************************************************************************/
1146
1147 void
DtWriteFieldToListing(UINT8 * Buffer,DT_FIELD * Field,UINT32 Length)1148 DtWriteFieldToListing (
1149 UINT8 *Buffer,
1150 DT_FIELD *Field,
1151 UINT32 Length)
1152 {
1153 UINT8 FileByte;
1154
1155
1156 if (!AslGbl_ListingFlag || !Field)
1157 {
1158 return;
1159 }
1160
1161 /* Dump the original source line */
1162
1163 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: ");
1164 FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
1165
1166 while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
1167 {
1168 FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
1169 if (FileByte == '\n')
1170 {
1171 break;
1172 }
1173 }
1174
1175 /* Dump the line as parsed and represented internally */
1176
1177 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
1178 Field->Column-4, Field->Name, Field->Value);
1179
1180 if (strlen (Field->Value) > 64)
1181 {
1182 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
1183 (UINT32) strlen (Field->Value));
1184 }
1185
1186 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
1187
1188 /* Dump the hex data that will be output for this field */
1189
1190 DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
1191 }
1192
1193
1194 /******************************************************************************
1195 *
1196 * FUNCTION: DtWriteTableToListing
1197 *
1198 * PARAMETERS: None
1199 *
1200 * RETURN: None
1201 *
1202 * DESCRIPTION: Write the entire compiled table to the listing file
1203 * in hex format
1204 *
1205 *****************************************************************************/
1206
1207 void
DtWriteTableToListing(void)1208 DtWriteTableToListing (
1209 void)
1210 {
1211 UINT8 *Buffer;
1212
1213
1214 if (!AslGbl_ListingFlag)
1215 {
1216 return;
1217 }
1218
1219 /* Read the entire table from the output file */
1220
1221 Buffer = UtLocalCalloc (AslGbl_TableLength);
1222 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1223 FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, AslGbl_TableLength);
1224
1225 /* Dump the raw table data */
1226
1227 AcpiOsRedirectOutput (AslGbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
1228
1229 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
1230 ACPI_RAW_TABLE_DATA_HEADER, AslGbl_TableLength, AslGbl_TableLength);
1231 AcpiUtDumpBuffer (Buffer, AslGbl_TableLength, DB_BYTE_DISPLAY, 0);
1232
1233 AcpiOsRedirectOutput (stdout);
1234 ACPI_FREE (Buffer);
1235 }
1236