Deleted Added
full compact
asllisting.c (241973) asllisting.c (243347)
1/******************************************************************************
2 *
3 * Module Name: asllisting - Listing file generation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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
45#include <contrib/dev/acpica/compiler/aslcompiler.h>
46#include "aslcompiler.y.h"
47#include <contrib/dev/acpica/include/amlcode.h>
48#include <contrib/dev/acpica/include/acparser.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50
51#define _COMPONENT ACPI_COMPILER
52 ACPI_MODULE_NAME ("aslisting")
53
54/* Local prototypes */
55
56static void
57LsDumpAscii (
58 UINT32 FileId,
59 UINT32 Count,
60 UINT8 *Buffer);
61
62static void
63LsDumpAsciiInComment (
64 UINT32 FileId,
65 UINT32 Count,
66 UINT8 *Buffer);
67
68static ACPI_STATUS
69LsAmlListingWalk (
70 ACPI_PARSE_OBJECT *Op,
71 UINT32 Level,
72 void *Context);
73
74static void
75LsGenerateListing (
76 UINT32 FileId);
77
78static void
79LsPushNode (
80 char *Filename);
81
82static ASL_LISTING_NODE *
83LsPopNode (
84 void);
85
86static void
87LsCheckException (
88 UINT32 LineNumber,
89 UINT32 FileId);
90
91static void
92LsFlushListingBuffer (
93 UINT32 FileId);
94
95static void
96LsWriteListingHexBytes (
97 UINT8 *Buffer,
98 UINT32 Length,
99 UINT32 FileId);
100
101static UINT32
102LsWriteOneSourceLine (
103 UINT32 FileId);
104
105static void
106LsFinishSourceListing (
107 UINT32 FileId);
108
109static void
110LsWriteSourceLines (
111 UINT32 ToLineNumber,
112 UINT32 ToLogicalLineNumber,
113 UINT32 FileId);
114
115static void
116LsWriteNodeToListing (
117 ACPI_PARSE_OBJECT *Op,
118 UINT32 FileId);
119
120static void
121LsDoHexOutputC (
122 void);
123
124static void
125LsDoHexOutputAsm (
126 void);
127
128static void
129LsDoHexOutputAsl (
130 void);
131
132static ACPI_STATUS
133LsTreeWriteWalk (
134 ACPI_PARSE_OBJECT *Op,
135 UINT32 Level,
136 void *Context);
137
1/******************************************************************************
2 *
3 * Module Name: asllisting - Listing file generation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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
45#include <contrib/dev/acpica/compiler/aslcompiler.h>
46#include "aslcompiler.y.h"
47#include <contrib/dev/acpica/include/amlcode.h>
48#include <contrib/dev/acpica/include/acparser.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50
51#define _COMPONENT ACPI_COMPILER
52 ACPI_MODULE_NAME ("aslisting")
53
54/* Local prototypes */
55
56static void
57LsDumpAscii (
58 UINT32 FileId,
59 UINT32 Count,
60 UINT8 *Buffer);
61
62static void
63LsDumpAsciiInComment (
64 UINT32 FileId,
65 UINT32 Count,
66 UINT8 *Buffer);
67
68static ACPI_STATUS
69LsAmlListingWalk (
70 ACPI_PARSE_OBJECT *Op,
71 UINT32 Level,
72 void *Context);
73
74static void
75LsGenerateListing (
76 UINT32 FileId);
77
78static void
79LsPushNode (
80 char *Filename);
81
82static ASL_LISTING_NODE *
83LsPopNode (
84 void);
85
86static void
87LsCheckException (
88 UINT32 LineNumber,
89 UINT32 FileId);
90
91static void
92LsFlushListingBuffer (
93 UINT32 FileId);
94
95static void
96LsWriteListingHexBytes (
97 UINT8 *Buffer,
98 UINT32 Length,
99 UINT32 FileId);
100
101static UINT32
102LsWriteOneSourceLine (
103 UINT32 FileId);
104
105static void
106LsFinishSourceListing (
107 UINT32 FileId);
108
109static void
110LsWriteSourceLines (
111 UINT32 ToLineNumber,
112 UINT32 ToLogicalLineNumber,
113 UINT32 FileId);
114
115static void
116LsWriteNodeToListing (
117 ACPI_PARSE_OBJECT *Op,
118 UINT32 FileId);
119
120static void
121LsDoHexOutputC (
122 void);
123
124static void
125LsDoHexOutputAsm (
126 void);
127
128static void
129LsDoHexOutputAsl (
130 void);
131
132static ACPI_STATUS
133LsTreeWriteWalk (
134 ACPI_PARSE_OBJECT *Op,
135 UINT32 Level,
136 void *Context);
137
138static UINT32
139LsReadAmlOutputFile (
140 UINT8 *Buffer);
138
141
142
139/*******************************************************************************
140 *
141 * FUNCTION: LsTreeWriteWalk
142 *
143 * PARAMETERS: ASL_WALK_CALLBACK
144 *
145 *
146 * RETURN: None.
147 *
148 * DESCRIPTION: Dump entire parse tree, for compiler debug only
149 *
150 ******************************************************************************/
151
152static ACPI_STATUS
153LsTreeWriteWalk (
154 ACPI_PARSE_OBJECT *Op,
155 UINT32 Level,
156 void *Context)
157{
158
159 /* Debug output */
160
161 DbgPrint (ASL_TREE_OUTPUT,
162 "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level);
163 UtPrintFormattedName (Op->Asl.ParseOpcode, Level);
164
165
166 DbgPrint (ASL_TREE_OUTPUT, "\n");
167 return (AE_OK);
168}
169
170
171void
172LsDumpParseTree (
173 void)
174{
175
176 if (!Gbl_DebugFlag)
177 {
178 return;
179 }
180
181 DbgPrint (ASL_TREE_OUTPUT, "\nOriginal parse tree from parser:\n\n");
182 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
183 LsTreeWriteWalk, NULL, NULL);
184}
185
186
187/*******************************************************************************
188 *
189 * FUNCTION: LsDumpAscii
190 *
191 * PARAMETERS: FileId - ID of current listing file
192 * Count - Number of bytes to convert
193 * Buffer - Buffer of bytes to convert
194 *
195 * RETURN: None.
196 *
197 * DESCRIPTION: Convert hex bytes to ascii
198 *
199 ******************************************************************************/
200
201static void
202LsDumpAscii (
203 UINT32 FileId,
204 UINT32 Count,
205 UINT8 *Buffer)
206{
207 UINT8 BufChar;
208 UINT32 i;
209
210
211 FlPrintFile (FileId, " \"");
212 for (i = 0; i < Count; i++)
213 {
214 BufChar = Buffer[i];
215 if (isprint (BufChar))
216 {
217 FlPrintFile (FileId, "%c", BufChar);
218 }
219 else
220 {
221 /* Not a printable character, just put out a dot */
222
223 FlPrintFile (FileId, ".");
224 }
225 }
226 FlPrintFile (FileId, "\"");
227}
228
229
230/*******************************************************************************
231 *
232 * FUNCTION: LsDumpAsciiInComment
233 *
234 * PARAMETERS: FileId - ID of current listing file
235 * Count - Number of bytes to convert
236 * Buffer - Buffer of bytes to convert
237 *
238 * RETURN: None.
239 *
240 * DESCRIPTION: Convert hex bytes to ascii
241 *
242 ******************************************************************************/
243
244static void
245LsDumpAsciiInComment (
246 UINT32 FileId,
247 UINT32 Count,
248 UINT8 *Buffer)
249{
250 UINT8 BufChar = 0;
251 UINT8 LastChar;
252 UINT32 i;
253
254
255 FlPrintFile (FileId, " \"");
256 for (i = 0; i < Count; i++)
257 {
258 LastChar = BufChar;
259 BufChar = Buffer[i];
260
261 if (isprint (BufChar))
262 {
263 /* Handle embedded C comment sequences */
264
265 if (((LastChar == '*') && (BufChar == '/')) ||
266 ((LastChar == '/') && (BufChar == '*')))
267 {
268 /* Insert a space to break the sequence */
269
270 FlPrintFile (FileId, ".", BufChar);
271 }
272
273 FlPrintFile (FileId, "%c", BufChar);
274 }
275 else
276 {
277 /* Not a printable character, just put out a dot */
278
279 FlPrintFile (FileId, ".");
280 }
281 }
282 FlPrintFile (FileId, "\"");
283}
284
285
286/*******************************************************************************
287 *
288 * FUNCTION: LsAmlListingWalk
289 *
290 * PARAMETERS: ASL_WALK_CALLBACK
291 *
292 * RETURN: Status
293 *
294 * DESCRIPTION: Process one node during a listing file generation.
295 *
296 ******************************************************************************/
297
298static ACPI_STATUS
299LsAmlListingWalk (
300 ACPI_PARSE_OBJECT *Op,
301 UINT32 Level,
302 void *Context)
303{
304 UINT8 FileByte;
305 UINT32 i;
306 UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context);
307
308
309 LsWriteNodeToListing (Op, FileId);
310
311 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA)
312 {
313 /* Buffer is a resource template, don't dump the data all at once */
314
315 return (AE_OK);
316 }
317
318 /* Write the hex bytes to the listing file(s) (if requested) */
319
320 for (i = 0; i < Op->Asl.FinalAmlLength; i++)
321 {
322 if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1)))
323 {
324 FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
325 AslAbort ();
326 }
327 LsWriteListingHexBytes (&FileByte, 1, FileId);
328 }
329
330 return (AE_OK);
331}
332
333
334/*******************************************************************************
335 *
336 * FUNCTION: LsGenerateListing
337 *
338 * PARAMETERS: FileId - ID of listing file
339 *
340 * RETURN: None
341 *
342 * DESCRIPTION: Generate a listing file. This can be one of the several types
343 * of "listings" supported.
344 *
345 ******************************************************************************/
346
347static void
348LsGenerateListing (
349 UINT32 FileId)
350{
351
352 /* Start at the beginning of both the source and AML files */
353
354 FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
355 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
356 Gbl_SourceLine = 0;
357 Gbl_CurrentHexColumn = 0;
358 LsPushNode (Gbl_Files[ASL_FILE_INPUT].Filename);
359
360 /* Process all parse nodes */
361
362 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlListingWalk,
363 NULL, (void *) ACPI_TO_POINTER (FileId));
364
365 /* Final processing */
366
367 LsFinishSourceListing (FileId);
368}
369
370
371/*******************************************************************************
372 *
373 * FUNCTION: LsDoListings
374 *
375 * PARAMETERS: None.
376 *
377 * RETURN: None
378 *
379 * DESCRIPTION: Generate all requested listing files.
380 *
381 ******************************************************************************/
382
383void
384LsDoListings (
385 void)
386{
387
388 if (Gbl_C_OutputFlag)
389 {
390 LsGenerateListing (ASL_FILE_C_SOURCE_OUTPUT);
391 }
392
393 if (Gbl_ListingFlag)
394 {
395 LsGenerateListing (ASL_FILE_LISTING_OUTPUT);
396 }
397
398 if (Gbl_AsmOutputFlag)
399 {
400 LsGenerateListing (ASL_FILE_ASM_SOURCE_OUTPUT);
401 }
402
403 if (Gbl_C_IncludeOutputFlag)
404 {
405 LsGenerateListing (ASL_FILE_C_INCLUDE_OUTPUT);
406 }
407
408 if (Gbl_AsmIncludeOutputFlag)
409 {
410 LsGenerateListing (ASL_FILE_ASM_INCLUDE_OUTPUT);
411 }
412}
413
414
415/*******************************************************************************
416 *
417 * FUNCTION: LsPushNode
418 *
419 * PARAMETERS: Filename - Pointer to the include filename
420 *
421 * RETURN: None
422 *
423 * DESCRIPTION: Push a listing node on the listing/include file stack. This
424 * stack enables tracking of include files (infinitely nested)
425 * and resumption of the listing of the parent file when the
426 * include file is finished.
427 *
428 ******************************************************************************/
429
430static void
431LsPushNode (
432 char *Filename)
433{
434 ASL_LISTING_NODE *Lnode;
435
436
437 /* Create a new node */
438
439 Lnode = UtLocalCalloc (sizeof (ASL_LISTING_NODE));
440
441 /* Initialize */
442
443 Lnode->Filename = Filename;
444 Lnode->LineNumber = 0;
445
446 /* Link (push) */
447
448 Lnode->Next = Gbl_ListingNode;
449 Gbl_ListingNode = Lnode;
450}
451
452
453/*******************************************************************************
454 *
455 * FUNCTION: LsPopNode
456 *
457 * PARAMETERS: None
458 *
459 * RETURN: List head after current head is popped off
460 *
461 * DESCRIPTION: Pop the current head of the list, free it, and return the
462 * next node on the stack (the new current node).
463 *
464 ******************************************************************************/
465
466static ASL_LISTING_NODE *
467LsPopNode (
468 void)
469{
470 ASL_LISTING_NODE *Lnode;
471
472
473 /* Just grab the node at the head of the list */
474
475 Lnode = Gbl_ListingNode;
476 if ((!Lnode) ||
477 (!Lnode->Next))
478 {
479 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL,
480 "Could not pop empty listing stack");
481 return (Gbl_ListingNode);
482 }
483
484 Gbl_ListingNode = Lnode->Next;
485 ACPI_FREE (Lnode);
486
487 /* New "Current" node is the new head */
488
489 return (Gbl_ListingNode);
490}
491
492
493/*******************************************************************************
494 *
495 * FUNCTION: LsCheckException
496 *
497 * PARAMETERS: LineNumber - Current logical (cumulative) line #
498 * FileId - ID of output listing file
499 *
500 * RETURN: None
501 *
502 * DESCRIPTION: Check if there is an exception for this line, and if there is,
503 * put it in the listing immediately. Handles multiple errors
504 * per line. Gbl_NextError points to the next error in the
505 * sorted (by line #) list of compile errors/warnings.
506 *
507 ******************************************************************************/
508
509static void
510LsCheckException (
511 UINT32 LineNumber,
512 UINT32 FileId)
513{
514
515 if ((!Gbl_NextError) ||
516 (LineNumber < Gbl_NextError->LogicalLineNumber ))
517 {
518 return;
519 }
520
521 /* Handle multiple errors per line */
522
523 if (FileId == ASL_FILE_LISTING_OUTPUT)
524 {
525 while (Gbl_NextError &&
526 (LineNumber >= Gbl_NextError->LogicalLineNumber))
527 {
528 AePrintException (FileId, Gbl_NextError, "\n[****iasl****]\n");
529
530 Gbl_NextError = Gbl_NextError->Next;
531 }
532
533 FlPrintFile (FileId, "\n");
534 }
535}
536
537
538/*******************************************************************************
539 *
540 * FUNCTION: LsFlushListingBuffer
541 *
542 * PARAMETERS: FileId - ID of the listing file
543 *
544 * RETURN: None
545 *
546 * DESCRIPTION: Flush out the current contents of the 16-byte hex AML code
547 * buffer. Usually called at the termination of a single line
548 * of source code or when the buffer is full.
549 *
550 ******************************************************************************/
551
552static void
553LsFlushListingBuffer (
554 UINT32 FileId)
555{
556 UINT32 i;
557
558
559 if (Gbl_CurrentHexColumn == 0)
560 {
561 return;
562 }
563
564 /* Write the hex bytes */
565
566 switch (FileId)
567 {
568 case ASL_FILE_LISTING_OUTPUT:
569
570 for (i = 0; i < Gbl_CurrentHexColumn; i++)
571 {
572 FlPrintFile (FileId, "%2.2X ", Gbl_AmlBuffer[i]);
573 }
574
575 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 3); i++)
576 {
577 FlWriteFile (FileId, ".", 1);
578 }
579
580 /* Write the ASCII character associated with each of the bytes */
581
582 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
583 break;
584
585
586 case ASL_FILE_ASM_SOURCE_OUTPUT:
587
588 for (i = 0; i < Gbl_CurrentHexColumn; i++)
589 {
590 if (i > 0)
591 {
592 FlPrintFile (FileId, ",");
593 }
594 FlPrintFile (FileId, "0%2.2Xh", Gbl_AmlBuffer[i]);
595 }
596
597 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
598 {
599 FlWriteFile (FileId, " ", 1);
600 }
601
602 FlPrintFile (FileId, " ;%8.8X",
603 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
604
605 /* Write the ASCII character associated with each of the bytes */
606
607 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
608 break;
609
610
611 case ASL_FILE_C_SOURCE_OUTPUT:
612
613 for (i = 0; i < Gbl_CurrentHexColumn; i++)
614 {
615 FlPrintFile (FileId, "0x%2.2X,", Gbl_AmlBuffer[i]);
616 }
617
618 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
619 {
620 FlWriteFile (FileId, " ", 1);
621 }
622
623 FlPrintFile (FileId, " /* %8.8X",
624 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
625
626 /* Write the ASCII character associated with each of the bytes */
627
628 LsDumpAsciiInComment (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
629 FlPrintFile (FileId, " */");
630 break;
631
632 default:
633 /* No other types supported */
634 return;
635 }
636
637 FlPrintFile (FileId, "\n");
638
639 Gbl_CurrentHexColumn = 0;
640 Gbl_HexBytesWereWritten = TRUE;
641}
642
643
644/*******************************************************************************
645 *
646 * FUNCTION: LsWriteListingHexBytes
647 *
648 * PARAMETERS: Buffer - AML code buffer
649 * Length - Number of AML bytes to write
650 * FileId - ID of current listing file.
651 *
652 * RETURN: None
653 *
654 * DESCRIPTION: Write the contents of the AML buffer to the listing file via
655 * the listing buffer. The listing buffer is flushed every 16
656 * AML bytes.
657 *
658 ******************************************************************************/
659
660static void
661LsWriteListingHexBytes (
662 UINT8 *Buffer,
663 UINT32 Length,
664 UINT32 FileId)
665{
666 UINT32 i;
667
668
669 /* Transfer all requested bytes */
670
671 for (i = 0; i < Length; i++)
672 {
673 /* Print line header when buffer is empty */
674
675 if (Gbl_CurrentHexColumn == 0)
676 {
677 if (Gbl_HasIncludeFiles)
678 {
679 FlPrintFile (FileId, "%*s", 10, " ");
680 }
681
682 switch (FileId)
683 {
684 case ASL_FILE_LISTING_OUTPUT:
685
686 FlPrintFile (FileId, "%8.8X....", Gbl_CurrentAmlOffset);
687 break;
688
689 case ASL_FILE_ASM_SOURCE_OUTPUT:
690
691 FlPrintFile (FileId, " db ");
692 break;
693
694 case ASL_FILE_C_SOURCE_OUTPUT:
695
696 FlPrintFile (FileId, " ");
697 break;
698
699 default:
700 /* No other types supported */
701 return;
702 }
703 }
704
705 /* Transfer AML byte and update counts */
706
707 Gbl_AmlBuffer[Gbl_CurrentHexColumn] = Buffer[i];
708
709 Gbl_CurrentHexColumn++;
710 Gbl_CurrentAmlOffset++;
711
712 /* Flush buffer when it is full */
713
714 if (Gbl_CurrentHexColumn >= HEX_LISTING_LINE_SIZE)
715 {
716 LsFlushListingBuffer (FileId);
717 }
718 }
719}
720
721
722/*******************************************************************************
723 *
724 * FUNCTION: LsWriteOneSourceLine
725 *
726 * PARAMETERS: FileID - ID of current listing file
727 *
728 * RETURN: FALSE on EOF (input source file), TRUE otherwise
729 *
730 * DESCRIPTION: Read one line from the input source file and echo it to the
731 * listing file, prefixed with the line number, and if the source
732 * file contains include files, prefixed with the current filename
733 *
734 ******************************************************************************/
735
736static UINT32
737LsWriteOneSourceLine (
738 UINT32 FileId)
739{
740 UINT8 FileByte;
741
742
743 Gbl_SourceLine++;
744 Gbl_ListingNode->LineNumber++;
745
746 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
747 {
748 FlPrintFile (FileId, " *");
749 }
750 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
751 {
752 FlPrintFile (FileId, "; ");
753 }
754
755 if (Gbl_HasIncludeFiles)
756 {
757 /*
758 * This file contains "include" statements, print the current
759 * filename and line number within the current file
760 */
761 FlPrintFile (FileId, "%12s %5d....",
762 Gbl_ListingNode->Filename, Gbl_ListingNode->LineNumber);
763 }
764 else
765 {
766 /* No include files, just print the line number */
767
768 FlPrintFile (FileId, "%8d....", Gbl_SourceLine);
769 }
770
771 /* Read one line (up to a newline or EOF) */
772
773 while (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) == AE_OK)
774 {
775 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
776 {
777 if (FileByte == '/')
778 {
779 FileByte = '*';
780 }
781 }
782
783 FlWriteFile (FileId, &FileByte, 1);
784 if (FileByte == '\n')
785 {
786 /*
787 * Check if an error occurred on this source line during the compile.
788 * If so, we print the error message after the source line.
789 */
790 LsCheckException (Gbl_SourceLine, FileId);
791 return (1);
792 }
793 }
794
795 /* EOF on the input file was reached */
796
797 return (0);
798}
799
800
801/*******************************************************************************
802 *
803 * FUNCTION: LsFinishSourceListing
804 *
805 * PARAMETERS: FileId - ID of current listing file.
806 *
807 * RETURN: None
808 *
809 * DESCRIPTION: Cleanup routine for the listing file. Flush the hex AML
810 * listing buffer, and flush out any remaining lines in the
811 * source input file.
812 *
813 ******************************************************************************/
814
815static void
816LsFinishSourceListing (
817 UINT32 FileId)
818{
819
820 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
821 (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
822 {
823 return;
824 }
825
826 LsFlushListingBuffer (FileId);
827 Gbl_CurrentAmlOffset = 0;
828
829 /* Flush any remaining text in the source file */
830
831 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
832 {
833 FlPrintFile (FileId, " /*\n");
834 }
835
836 while (LsWriteOneSourceLine (FileId))
837 { ; }
838
839 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
840 {
841 FlPrintFile (FileId, "\n */\n };\n");
842 }
843
844 FlPrintFile (FileId, "\n");
845
846 if (FileId == ASL_FILE_LISTING_OUTPUT)
847 {
848 /* Print a summary of the compile exceptions */
849
850 FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n");
851 AePrintErrorLog (FileId);
852 FlPrintFile (FileId, "\n");
853 UtDisplaySummary (FileId);
854 FlPrintFile (FileId, "\n");
855 }
856}
857
858
859/*******************************************************************************
860 *
861 * FUNCTION: LsWriteSourceLines
862 *
863 * PARAMETERS: ToLineNumber -
864 * ToLogicalLineNumber - Write up to this source line number
865 * FileId - ID of current listing file
866 *
867 * RETURN: None
868 *
869 * DESCRIPTION: Read then write source lines to the listing file until we have
870 * reached the specified logical (cumulative) line number. This
871 * automatically echos out comment blocks and other non-AML
872 * generating text until we get to the actual AML-generating line
873 * of ASL code specified by the logical line number.
874 *
875 ******************************************************************************/
876
877static void
878LsWriteSourceLines (
879 UINT32 ToLineNumber,
880 UINT32 ToLogicalLineNumber,
881 UINT32 FileId)
882{
883
884 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
885 (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
886 {
887 return;
888 }
889
890 Gbl_CurrentLine = ToLogicalLineNumber;
891
892 /* Flush any hex bytes remaining from the last opcode */
893
894 LsFlushListingBuffer (FileId);
895
896 /* Read lines and write them as long as we are not caught up */
897
898 if (Gbl_SourceLine < Gbl_CurrentLine)
899 {
900 /*
901 * If we just completed writing some AML hex bytes, output a linefeed
902 * to add some whitespace for readability.
903 */
904 if (Gbl_HexBytesWereWritten)
905 {
906 FlPrintFile (FileId, "\n");
907 Gbl_HexBytesWereWritten = FALSE;
908 }
909
910 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
911 {
912 FlPrintFile (FileId, " /*\n");
913 }
914
915 /* Write one line at a time until we have reached the target line # */
916
917 while ((Gbl_SourceLine < Gbl_CurrentLine) &&
918 LsWriteOneSourceLine (FileId))
919 { ; }
920
921 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
922 {
923 FlPrintFile (FileId, " */");
924 }
925 FlPrintFile (FileId, "\n");
926 }
927}
928
929
930/*******************************************************************************
931 *
932 * FUNCTION: LsWriteNodeToListing
933 *
934 * PARAMETERS: Op - Parse node to write to the listing file.
935 * FileId - ID of current listing file
936 *
937 * RETURN: None.
938 *
939 * DESCRIPTION: Write "a node" to the listing file. This means to
940 * 1) Write out all of the source text associated with the node
941 * 2) Write out all of the AML bytes associated with the node
942 * 3) Write any compiler exceptions associated with the node
943 *
944 ******************************************************************************/
945
946static void
947LsWriteNodeToListing (
948 ACPI_PARSE_OBJECT *Op,
949 UINT32 FileId)
950{
951 const ACPI_OPCODE_INFO *OpInfo;
952 UINT32 OpClass;
953 char *Pathname;
954 UINT32 Length;
955 UINT32 i;
956
957
958 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
959 OpClass = OpInfo->Class;
960
961 /* TBD: clean this up with a single flag that says:
962 * I start a named output block
963 */
964 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
965 {
966 switch (Op->Asl.ParseOpcode)
967 {
968 case PARSEOP_DEFINITIONBLOCK:
969 case PARSEOP_METHODCALL:
970 case PARSEOP_INCLUDE:
971 case PARSEOP_INCLUDE_END:
972 case PARSEOP_DEFAULT_ARG:
973
974 break;
975
976 default:
977 switch (OpClass)
978 {
979 case AML_CLASS_NAMED_OBJECT:
980 switch (Op->Asl.AmlOpcode)
981 {
982 case AML_SCOPE_OP:
983 case AML_ALIAS_OP:
984 break;
985
986 default:
987 if (Op->Asl.ExternalName)
988 {
989 LsFlushListingBuffer (FileId);
990 FlPrintFile (FileId, " };\n");
991 }
992 break;
993 }
994 break;
995
996 default:
997 /* Don't care about other objects */
998 break;
999 }
1000 break;
1001 }
1002 }
1003
1004 /* These cases do not have a corresponding AML opcode */
1005
1006 switch (Op->Asl.ParseOpcode)
1007 {
1008 case PARSEOP_DEFINITIONBLOCK:
1009
1010 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId);
1011
1012 /* Use the table Signature and TableId to build a unique name */
1013
1014 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
1015 {
1016 FlPrintFile (FileId,
1017 "%s_%s_Header \\\n",
1018 Gbl_TableSignature, Gbl_TableId);
1019 }
1020 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
1021 {
1022 FlPrintFile (FileId,
1023 " unsigned char %s_%s_Header [] =\n {\n",
1024 Gbl_TableSignature, Gbl_TableId);
1025 }
1026 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
1027 {
1028 FlPrintFile (FileId,
1029 "extrn %s_%s_Header : byte\n",
1030 Gbl_TableSignature, Gbl_TableId);
1031 }
1032 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
1033 {
1034 FlPrintFile (FileId,
1035 "extern unsigned char %s_%s_Header [];\n",
1036 Gbl_TableSignature, Gbl_TableId);
1037 }
1038 return;
1039
1040
1041 case PARSEOP_METHODCALL:
1042
1043 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1044 FileId);
1045 return;
1046
1047
1048 case PARSEOP_INCLUDE:
1049
1050 /* Flush everything up to and including the include source line */
1051
1052 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1053 FileId);
1054
1055 /* Create a new listing node and push it */
1056
1057 LsPushNode (Op->Asl.Child->Asl.Value.String);
1058 return;
1059
1060
1061 case PARSEOP_INCLUDE_END:
1062
1063 /* Flush out the rest of the include file */
1064
1065 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1066 FileId);
1067
1068 /* Pop off this listing node and go back to the parent file */
1069
1070 (void) LsPopNode ();
1071 return;
1072
1073
1074 case PARSEOP_DEFAULT_ARG:
1075
1076 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
1077 {
1078 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.EndLogicalLine,
1079 FileId);
1080 }
1081 return;
1082
1083
1084 default:
1085 /* All other opcodes have an AML opcode */
1086 break;
1087 }
1088
1089 /*
1090 * Otherwise, we look at the AML opcode because we can
1091 * switch on the opcode type, getting an entire class
1092 * at once
1093 */
1094 switch (OpClass)
1095 {
1096 case AML_CLASS_ARGUMENT: /* argument type only */
1097 case AML_CLASS_INTERNAL:
1098
1099 break;
1100
1101
1102 case AML_CLASS_NAMED_OBJECT:
1103
1104 switch (Op->Asl.AmlOpcode)
1105 {
1106 case AML_FIELD_OP:
1107 case AML_INDEX_FIELD_OP:
1108 case AML_BANK_FIELD_OP:
1109
1110 /*
1111 * For fields, we want to dump all the AML after the
1112 * entire definition
1113 */
1114 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
1115 FileId);
1116 break;
1117
1118 case AML_NAME_OP:
1119
1120 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
1121 {
1122 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1123 FileId);
1124 }
1125 else
1126 {
1127 /*
1128 * For fields, we want to dump all the AML after the
1129 * entire definition
1130 */
1131 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
1132 FileId);
1133 }
1134 break;
1135
1136 default:
1137 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1138 FileId);
1139 break;
1140 }
1141
1142 switch (Op->Asl.AmlOpcode)
1143 {
1144 case AML_SCOPE_OP:
1145 case AML_ALIAS_OP:
1146
1147 /* These opcodes do not declare a new object, ignore them */
1148
1149 break;
1150
1151 default:
1152
1153 /* All other named object opcodes come here */
1154
1155 switch (FileId)
1156 {
1157 case ASL_FILE_ASM_SOURCE_OUTPUT:
1158 case ASL_FILE_C_SOURCE_OUTPUT:
1159 case ASL_FILE_ASM_INCLUDE_OUTPUT:
1160 case ASL_FILE_C_INCLUDE_OUTPUT:
1161
1162 /*
1163 * For named objects, we will create a valid symbol so that the
1164 * AML code can be referenced from C or ASM
1165 */
1166 if (Op->Asl.ExternalName)
1167 {
1168 /* Get the full pathname associated with this node */
1169
1170 Pathname = AcpiNsGetExternalPathname (Op->Asl.Node);
1171 Length = strlen (Pathname);
1172 if (Length >= 4)
1173 {
1174 /* Convert all dots in the path to underscores */
1175
1176 for (i = 0; i < Length; i++)
1177 {
1178 if (Pathname[i] == '.')
1179 {
1180 Pathname[i] = '_';
1181 }
1182 }
1183
1184 /* Create the appropriate symbol in the output file */
1185
1186 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
1187 {
1188 FlPrintFile (FileId,
1189 "%s_%s_%s \\\n",
1190 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1191 }
1192 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
1193 {
1194 FlPrintFile (FileId,
1195 " unsigned char %s_%s_%s [] =\n {\n",
1196 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1197 }
1198 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
1199 {
1200 FlPrintFile (FileId,
1201 "extrn %s_%s_%s : byte\n",
1202 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1203 }
1204 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
1205 {
1206 FlPrintFile (FileId,
1207 "extern unsigned char %s_%s_%s [];\n",
1208 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1209 }
1210 }
1211 ACPI_FREE (Pathname);
1212 }
1213 break;
1214
1215 default:
1216 /* Nothing to do for listing file */
1217 break;
1218 }
1219 }
1220 break;
1221
1222 case AML_CLASS_EXECUTE:
1223 case AML_CLASS_CREATE:
1224 default:
1225
1226 if ((Op->Asl.ParseOpcode == PARSEOP_BUFFER) &&
1227 (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC))
1228 {
1229 return;
1230 }
1231
1232 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1233 FileId);
1234 break;
1235
1236 case AML_CLASS_UNKNOWN:
1237 break;
1238 }
1239}
1240
1241
1242/*******************************************************************************
1243 *
1244 * FUNCTION: LsDoHexOutput
1245 *
1246 * PARAMETERS: None
1247 *
1248 * RETURN: None.
1249 *
1250 * DESCRIPTION: Create the hex output file.
1251 *
1252 ******************************************************************************/
1253
1254void
1255LsDoHexOutput (
1256 void)
1257{
1258
1259 switch (Gbl_HexOutputFlag)
1260 {
1261 case HEX_OUTPUT_C:
1262
1263 LsDoHexOutputC ();
1264 break;
1265
1266 case HEX_OUTPUT_ASM:
1267
1268 LsDoHexOutputAsm ();
1269 break;
1270
1271 case HEX_OUTPUT_ASL:
1272
1273 LsDoHexOutputAsl ();
1274 break;
1275
1276 default:
1277 /* No other output types supported */
1278 break;
1279 }
1280}
1281
1282
1283/*******************************************************************************
1284 *
143/*******************************************************************************
144 *
145 * FUNCTION: LsTreeWriteWalk
146 *
147 * PARAMETERS: ASL_WALK_CALLBACK
148 *
149 *
150 * RETURN: None.
151 *
152 * DESCRIPTION: Dump entire parse tree, for compiler debug only
153 *
154 ******************************************************************************/
155
156static ACPI_STATUS
157LsTreeWriteWalk (
158 ACPI_PARSE_OBJECT *Op,
159 UINT32 Level,
160 void *Context)
161{
162
163 /* Debug output */
164
165 DbgPrint (ASL_TREE_OUTPUT,
166 "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level);
167 UtPrintFormattedName (Op->Asl.ParseOpcode, Level);
168
169
170 DbgPrint (ASL_TREE_OUTPUT, "\n");
171 return (AE_OK);
172}
173
174
175void
176LsDumpParseTree (
177 void)
178{
179
180 if (!Gbl_DebugFlag)
181 {
182 return;
183 }
184
185 DbgPrint (ASL_TREE_OUTPUT, "\nOriginal parse tree from parser:\n\n");
186 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
187 LsTreeWriteWalk, NULL, NULL);
188}
189
190
191/*******************************************************************************
192 *
193 * FUNCTION: LsDumpAscii
194 *
195 * PARAMETERS: FileId - ID of current listing file
196 * Count - Number of bytes to convert
197 * Buffer - Buffer of bytes to convert
198 *
199 * RETURN: None.
200 *
201 * DESCRIPTION: Convert hex bytes to ascii
202 *
203 ******************************************************************************/
204
205static void
206LsDumpAscii (
207 UINT32 FileId,
208 UINT32 Count,
209 UINT8 *Buffer)
210{
211 UINT8 BufChar;
212 UINT32 i;
213
214
215 FlPrintFile (FileId, " \"");
216 for (i = 0; i < Count; i++)
217 {
218 BufChar = Buffer[i];
219 if (isprint (BufChar))
220 {
221 FlPrintFile (FileId, "%c", BufChar);
222 }
223 else
224 {
225 /* Not a printable character, just put out a dot */
226
227 FlPrintFile (FileId, ".");
228 }
229 }
230 FlPrintFile (FileId, "\"");
231}
232
233
234/*******************************************************************************
235 *
236 * FUNCTION: LsDumpAsciiInComment
237 *
238 * PARAMETERS: FileId - ID of current listing file
239 * Count - Number of bytes to convert
240 * Buffer - Buffer of bytes to convert
241 *
242 * RETURN: None.
243 *
244 * DESCRIPTION: Convert hex bytes to ascii
245 *
246 ******************************************************************************/
247
248static void
249LsDumpAsciiInComment (
250 UINT32 FileId,
251 UINT32 Count,
252 UINT8 *Buffer)
253{
254 UINT8 BufChar = 0;
255 UINT8 LastChar;
256 UINT32 i;
257
258
259 FlPrintFile (FileId, " \"");
260 for (i = 0; i < Count; i++)
261 {
262 LastChar = BufChar;
263 BufChar = Buffer[i];
264
265 if (isprint (BufChar))
266 {
267 /* Handle embedded C comment sequences */
268
269 if (((LastChar == '*') && (BufChar == '/')) ||
270 ((LastChar == '/') && (BufChar == '*')))
271 {
272 /* Insert a space to break the sequence */
273
274 FlPrintFile (FileId, ".", BufChar);
275 }
276
277 FlPrintFile (FileId, "%c", BufChar);
278 }
279 else
280 {
281 /* Not a printable character, just put out a dot */
282
283 FlPrintFile (FileId, ".");
284 }
285 }
286 FlPrintFile (FileId, "\"");
287}
288
289
290/*******************************************************************************
291 *
292 * FUNCTION: LsAmlListingWalk
293 *
294 * PARAMETERS: ASL_WALK_CALLBACK
295 *
296 * RETURN: Status
297 *
298 * DESCRIPTION: Process one node during a listing file generation.
299 *
300 ******************************************************************************/
301
302static ACPI_STATUS
303LsAmlListingWalk (
304 ACPI_PARSE_OBJECT *Op,
305 UINT32 Level,
306 void *Context)
307{
308 UINT8 FileByte;
309 UINT32 i;
310 UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context);
311
312
313 LsWriteNodeToListing (Op, FileId);
314
315 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA)
316 {
317 /* Buffer is a resource template, don't dump the data all at once */
318
319 return (AE_OK);
320 }
321
322 /* Write the hex bytes to the listing file(s) (if requested) */
323
324 for (i = 0; i < Op->Asl.FinalAmlLength; i++)
325 {
326 if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1)))
327 {
328 FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
329 AslAbort ();
330 }
331 LsWriteListingHexBytes (&FileByte, 1, FileId);
332 }
333
334 return (AE_OK);
335}
336
337
338/*******************************************************************************
339 *
340 * FUNCTION: LsGenerateListing
341 *
342 * PARAMETERS: FileId - ID of listing file
343 *
344 * RETURN: None
345 *
346 * DESCRIPTION: Generate a listing file. This can be one of the several types
347 * of "listings" supported.
348 *
349 ******************************************************************************/
350
351static void
352LsGenerateListing (
353 UINT32 FileId)
354{
355
356 /* Start at the beginning of both the source and AML files */
357
358 FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
359 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
360 Gbl_SourceLine = 0;
361 Gbl_CurrentHexColumn = 0;
362 LsPushNode (Gbl_Files[ASL_FILE_INPUT].Filename);
363
364 /* Process all parse nodes */
365
366 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlListingWalk,
367 NULL, (void *) ACPI_TO_POINTER (FileId));
368
369 /* Final processing */
370
371 LsFinishSourceListing (FileId);
372}
373
374
375/*******************************************************************************
376 *
377 * FUNCTION: LsDoListings
378 *
379 * PARAMETERS: None.
380 *
381 * RETURN: None
382 *
383 * DESCRIPTION: Generate all requested listing files.
384 *
385 ******************************************************************************/
386
387void
388LsDoListings (
389 void)
390{
391
392 if (Gbl_C_OutputFlag)
393 {
394 LsGenerateListing (ASL_FILE_C_SOURCE_OUTPUT);
395 }
396
397 if (Gbl_ListingFlag)
398 {
399 LsGenerateListing (ASL_FILE_LISTING_OUTPUT);
400 }
401
402 if (Gbl_AsmOutputFlag)
403 {
404 LsGenerateListing (ASL_FILE_ASM_SOURCE_OUTPUT);
405 }
406
407 if (Gbl_C_IncludeOutputFlag)
408 {
409 LsGenerateListing (ASL_FILE_C_INCLUDE_OUTPUT);
410 }
411
412 if (Gbl_AsmIncludeOutputFlag)
413 {
414 LsGenerateListing (ASL_FILE_ASM_INCLUDE_OUTPUT);
415 }
416}
417
418
419/*******************************************************************************
420 *
421 * FUNCTION: LsPushNode
422 *
423 * PARAMETERS: Filename - Pointer to the include filename
424 *
425 * RETURN: None
426 *
427 * DESCRIPTION: Push a listing node on the listing/include file stack. This
428 * stack enables tracking of include files (infinitely nested)
429 * and resumption of the listing of the parent file when the
430 * include file is finished.
431 *
432 ******************************************************************************/
433
434static void
435LsPushNode (
436 char *Filename)
437{
438 ASL_LISTING_NODE *Lnode;
439
440
441 /* Create a new node */
442
443 Lnode = UtLocalCalloc (sizeof (ASL_LISTING_NODE));
444
445 /* Initialize */
446
447 Lnode->Filename = Filename;
448 Lnode->LineNumber = 0;
449
450 /* Link (push) */
451
452 Lnode->Next = Gbl_ListingNode;
453 Gbl_ListingNode = Lnode;
454}
455
456
457/*******************************************************************************
458 *
459 * FUNCTION: LsPopNode
460 *
461 * PARAMETERS: None
462 *
463 * RETURN: List head after current head is popped off
464 *
465 * DESCRIPTION: Pop the current head of the list, free it, and return the
466 * next node on the stack (the new current node).
467 *
468 ******************************************************************************/
469
470static ASL_LISTING_NODE *
471LsPopNode (
472 void)
473{
474 ASL_LISTING_NODE *Lnode;
475
476
477 /* Just grab the node at the head of the list */
478
479 Lnode = Gbl_ListingNode;
480 if ((!Lnode) ||
481 (!Lnode->Next))
482 {
483 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL,
484 "Could not pop empty listing stack");
485 return (Gbl_ListingNode);
486 }
487
488 Gbl_ListingNode = Lnode->Next;
489 ACPI_FREE (Lnode);
490
491 /* New "Current" node is the new head */
492
493 return (Gbl_ListingNode);
494}
495
496
497/*******************************************************************************
498 *
499 * FUNCTION: LsCheckException
500 *
501 * PARAMETERS: LineNumber - Current logical (cumulative) line #
502 * FileId - ID of output listing file
503 *
504 * RETURN: None
505 *
506 * DESCRIPTION: Check if there is an exception for this line, and if there is,
507 * put it in the listing immediately. Handles multiple errors
508 * per line. Gbl_NextError points to the next error in the
509 * sorted (by line #) list of compile errors/warnings.
510 *
511 ******************************************************************************/
512
513static void
514LsCheckException (
515 UINT32 LineNumber,
516 UINT32 FileId)
517{
518
519 if ((!Gbl_NextError) ||
520 (LineNumber < Gbl_NextError->LogicalLineNumber ))
521 {
522 return;
523 }
524
525 /* Handle multiple errors per line */
526
527 if (FileId == ASL_FILE_LISTING_OUTPUT)
528 {
529 while (Gbl_NextError &&
530 (LineNumber >= Gbl_NextError->LogicalLineNumber))
531 {
532 AePrintException (FileId, Gbl_NextError, "\n[****iasl****]\n");
533
534 Gbl_NextError = Gbl_NextError->Next;
535 }
536
537 FlPrintFile (FileId, "\n");
538 }
539}
540
541
542/*******************************************************************************
543 *
544 * FUNCTION: LsFlushListingBuffer
545 *
546 * PARAMETERS: FileId - ID of the listing file
547 *
548 * RETURN: None
549 *
550 * DESCRIPTION: Flush out the current contents of the 16-byte hex AML code
551 * buffer. Usually called at the termination of a single line
552 * of source code or when the buffer is full.
553 *
554 ******************************************************************************/
555
556static void
557LsFlushListingBuffer (
558 UINT32 FileId)
559{
560 UINT32 i;
561
562
563 if (Gbl_CurrentHexColumn == 0)
564 {
565 return;
566 }
567
568 /* Write the hex bytes */
569
570 switch (FileId)
571 {
572 case ASL_FILE_LISTING_OUTPUT:
573
574 for (i = 0; i < Gbl_CurrentHexColumn; i++)
575 {
576 FlPrintFile (FileId, "%2.2X ", Gbl_AmlBuffer[i]);
577 }
578
579 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 3); i++)
580 {
581 FlWriteFile (FileId, ".", 1);
582 }
583
584 /* Write the ASCII character associated with each of the bytes */
585
586 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
587 break;
588
589
590 case ASL_FILE_ASM_SOURCE_OUTPUT:
591
592 for (i = 0; i < Gbl_CurrentHexColumn; i++)
593 {
594 if (i > 0)
595 {
596 FlPrintFile (FileId, ",");
597 }
598 FlPrintFile (FileId, "0%2.2Xh", Gbl_AmlBuffer[i]);
599 }
600
601 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
602 {
603 FlWriteFile (FileId, " ", 1);
604 }
605
606 FlPrintFile (FileId, " ;%8.8X",
607 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
608
609 /* Write the ASCII character associated with each of the bytes */
610
611 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
612 break;
613
614
615 case ASL_FILE_C_SOURCE_OUTPUT:
616
617 for (i = 0; i < Gbl_CurrentHexColumn; i++)
618 {
619 FlPrintFile (FileId, "0x%2.2X,", Gbl_AmlBuffer[i]);
620 }
621
622 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
623 {
624 FlWriteFile (FileId, " ", 1);
625 }
626
627 FlPrintFile (FileId, " /* %8.8X",
628 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
629
630 /* Write the ASCII character associated with each of the bytes */
631
632 LsDumpAsciiInComment (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
633 FlPrintFile (FileId, " */");
634 break;
635
636 default:
637 /* No other types supported */
638 return;
639 }
640
641 FlPrintFile (FileId, "\n");
642
643 Gbl_CurrentHexColumn = 0;
644 Gbl_HexBytesWereWritten = TRUE;
645}
646
647
648/*******************************************************************************
649 *
650 * FUNCTION: LsWriteListingHexBytes
651 *
652 * PARAMETERS: Buffer - AML code buffer
653 * Length - Number of AML bytes to write
654 * FileId - ID of current listing file.
655 *
656 * RETURN: None
657 *
658 * DESCRIPTION: Write the contents of the AML buffer to the listing file via
659 * the listing buffer. The listing buffer is flushed every 16
660 * AML bytes.
661 *
662 ******************************************************************************/
663
664static void
665LsWriteListingHexBytes (
666 UINT8 *Buffer,
667 UINT32 Length,
668 UINT32 FileId)
669{
670 UINT32 i;
671
672
673 /* Transfer all requested bytes */
674
675 for (i = 0; i < Length; i++)
676 {
677 /* Print line header when buffer is empty */
678
679 if (Gbl_CurrentHexColumn == 0)
680 {
681 if (Gbl_HasIncludeFiles)
682 {
683 FlPrintFile (FileId, "%*s", 10, " ");
684 }
685
686 switch (FileId)
687 {
688 case ASL_FILE_LISTING_OUTPUT:
689
690 FlPrintFile (FileId, "%8.8X....", Gbl_CurrentAmlOffset);
691 break;
692
693 case ASL_FILE_ASM_SOURCE_OUTPUT:
694
695 FlPrintFile (FileId, " db ");
696 break;
697
698 case ASL_FILE_C_SOURCE_OUTPUT:
699
700 FlPrintFile (FileId, " ");
701 break;
702
703 default:
704 /* No other types supported */
705 return;
706 }
707 }
708
709 /* Transfer AML byte and update counts */
710
711 Gbl_AmlBuffer[Gbl_CurrentHexColumn] = Buffer[i];
712
713 Gbl_CurrentHexColumn++;
714 Gbl_CurrentAmlOffset++;
715
716 /* Flush buffer when it is full */
717
718 if (Gbl_CurrentHexColumn >= HEX_LISTING_LINE_SIZE)
719 {
720 LsFlushListingBuffer (FileId);
721 }
722 }
723}
724
725
726/*******************************************************************************
727 *
728 * FUNCTION: LsWriteOneSourceLine
729 *
730 * PARAMETERS: FileID - ID of current listing file
731 *
732 * RETURN: FALSE on EOF (input source file), TRUE otherwise
733 *
734 * DESCRIPTION: Read one line from the input source file and echo it to the
735 * listing file, prefixed with the line number, and if the source
736 * file contains include files, prefixed with the current filename
737 *
738 ******************************************************************************/
739
740static UINT32
741LsWriteOneSourceLine (
742 UINT32 FileId)
743{
744 UINT8 FileByte;
745
746
747 Gbl_SourceLine++;
748 Gbl_ListingNode->LineNumber++;
749
750 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
751 {
752 FlPrintFile (FileId, " *");
753 }
754 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
755 {
756 FlPrintFile (FileId, "; ");
757 }
758
759 if (Gbl_HasIncludeFiles)
760 {
761 /*
762 * This file contains "include" statements, print the current
763 * filename and line number within the current file
764 */
765 FlPrintFile (FileId, "%12s %5d....",
766 Gbl_ListingNode->Filename, Gbl_ListingNode->LineNumber);
767 }
768 else
769 {
770 /* No include files, just print the line number */
771
772 FlPrintFile (FileId, "%8d....", Gbl_SourceLine);
773 }
774
775 /* Read one line (up to a newline or EOF) */
776
777 while (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) == AE_OK)
778 {
779 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
780 {
781 if (FileByte == '/')
782 {
783 FileByte = '*';
784 }
785 }
786
787 FlWriteFile (FileId, &FileByte, 1);
788 if (FileByte == '\n')
789 {
790 /*
791 * Check if an error occurred on this source line during the compile.
792 * If so, we print the error message after the source line.
793 */
794 LsCheckException (Gbl_SourceLine, FileId);
795 return (1);
796 }
797 }
798
799 /* EOF on the input file was reached */
800
801 return (0);
802}
803
804
805/*******************************************************************************
806 *
807 * FUNCTION: LsFinishSourceListing
808 *
809 * PARAMETERS: FileId - ID of current listing file.
810 *
811 * RETURN: None
812 *
813 * DESCRIPTION: Cleanup routine for the listing file. Flush the hex AML
814 * listing buffer, and flush out any remaining lines in the
815 * source input file.
816 *
817 ******************************************************************************/
818
819static void
820LsFinishSourceListing (
821 UINT32 FileId)
822{
823
824 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
825 (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
826 {
827 return;
828 }
829
830 LsFlushListingBuffer (FileId);
831 Gbl_CurrentAmlOffset = 0;
832
833 /* Flush any remaining text in the source file */
834
835 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
836 {
837 FlPrintFile (FileId, " /*\n");
838 }
839
840 while (LsWriteOneSourceLine (FileId))
841 { ; }
842
843 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
844 {
845 FlPrintFile (FileId, "\n */\n };\n");
846 }
847
848 FlPrintFile (FileId, "\n");
849
850 if (FileId == ASL_FILE_LISTING_OUTPUT)
851 {
852 /* Print a summary of the compile exceptions */
853
854 FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n");
855 AePrintErrorLog (FileId);
856 FlPrintFile (FileId, "\n");
857 UtDisplaySummary (FileId);
858 FlPrintFile (FileId, "\n");
859 }
860}
861
862
863/*******************************************************************************
864 *
865 * FUNCTION: LsWriteSourceLines
866 *
867 * PARAMETERS: ToLineNumber -
868 * ToLogicalLineNumber - Write up to this source line number
869 * FileId - ID of current listing file
870 *
871 * RETURN: None
872 *
873 * DESCRIPTION: Read then write source lines to the listing file until we have
874 * reached the specified logical (cumulative) line number. This
875 * automatically echos out comment blocks and other non-AML
876 * generating text until we get to the actual AML-generating line
877 * of ASL code specified by the logical line number.
878 *
879 ******************************************************************************/
880
881static void
882LsWriteSourceLines (
883 UINT32 ToLineNumber,
884 UINT32 ToLogicalLineNumber,
885 UINT32 FileId)
886{
887
888 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
889 (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
890 {
891 return;
892 }
893
894 Gbl_CurrentLine = ToLogicalLineNumber;
895
896 /* Flush any hex bytes remaining from the last opcode */
897
898 LsFlushListingBuffer (FileId);
899
900 /* Read lines and write them as long as we are not caught up */
901
902 if (Gbl_SourceLine < Gbl_CurrentLine)
903 {
904 /*
905 * If we just completed writing some AML hex bytes, output a linefeed
906 * to add some whitespace for readability.
907 */
908 if (Gbl_HexBytesWereWritten)
909 {
910 FlPrintFile (FileId, "\n");
911 Gbl_HexBytesWereWritten = FALSE;
912 }
913
914 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
915 {
916 FlPrintFile (FileId, " /*\n");
917 }
918
919 /* Write one line at a time until we have reached the target line # */
920
921 while ((Gbl_SourceLine < Gbl_CurrentLine) &&
922 LsWriteOneSourceLine (FileId))
923 { ; }
924
925 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
926 {
927 FlPrintFile (FileId, " */");
928 }
929 FlPrintFile (FileId, "\n");
930 }
931}
932
933
934/*******************************************************************************
935 *
936 * FUNCTION: LsWriteNodeToListing
937 *
938 * PARAMETERS: Op - Parse node to write to the listing file.
939 * FileId - ID of current listing file
940 *
941 * RETURN: None.
942 *
943 * DESCRIPTION: Write "a node" to the listing file. This means to
944 * 1) Write out all of the source text associated with the node
945 * 2) Write out all of the AML bytes associated with the node
946 * 3) Write any compiler exceptions associated with the node
947 *
948 ******************************************************************************/
949
950static void
951LsWriteNodeToListing (
952 ACPI_PARSE_OBJECT *Op,
953 UINT32 FileId)
954{
955 const ACPI_OPCODE_INFO *OpInfo;
956 UINT32 OpClass;
957 char *Pathname;
958 UINT32 Length;
959 UINT32 i;
960
961
962 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
963 OpClass = OpInfo->Class;
964
965 /* TBD: clean this up with a single flag that says:
966 * I start a named output block
967 */
968 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
969 {
970 switch (Op->Asl.ParseOpcode)
971 {
972 case PARSEOP_DEFINITIONBLOCK:
973 case PARSEOP_METHODCALL:
974 case PARSEOP_INCLUDE:
975 case PARSEOP_INCLUDE_END:
976 case PARSEOP_DEFAULT_ARG:
977
978 break;
979
980 default:
981 switch (OpClass)
982 {
983 case AML_CLASS_NAMED_OBJECT:
984 switch (Op->Asl.AmlOpcode)
985 {
986 case AML_SCOPE_OP:
987 case AML_ALIAS_OP:
988 break;
989
990 default:
991 if (Op->Asl.ExternalName)
992 {
993 LsFlushListingBuffer (FileId);
994 FlPrintFile (FileId, " };\n");
995 }
996 break;
997 }
998 break;
999
1000 default:
1001 /* Don't care about other objects */
1002 break;
1003 }
1004 break;
1005 }
1006 }
1007
1008 /* These cases do not have a corresponding AML opcode */
1009
1010 switch (Op->Asl.ParseOpcode)
1011 {
1012 case PARSEOP_DEFINITIONBLOCK:
1013
1014 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId);
1015
1016 /* Use the table Signature and TableId to build a unique name */
1017
1018 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
1019 {
1020 FlPrintFile (FileId,
1021 "%s_%s_Header \\\n",
1022 Gbl_TableSignature, Gbl_TableId);
1023 }
1024 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
1025 {
1026 FlPrintFile (FileId,
1027 " unsigned char %s_%s_Header [] =\n {\n",
1028 Gbl_TableSignature, Gbl_TableId);
1029 }
1030 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
1031 {
1032 FlPrintFile (FileId,
1033 "extrn %s_%s_Header : byte\n",
1034 Gbl_TableSignature, Gbl_TableId);
1035 }
1036 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
1037 {
1038 FlPrintFile (FileId,
1039 "extern unsigned char %s_%s_Header [];\n",
1040 Gbl_TableSignature, Gbl_TableId);
1041 }
1042 return;
1043
1044
1045 case PARSEOP_METHODCALL:
1046
1047 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1048 FileId);
1049 return;
1050
1051
1052 case PARSEOP_INCLUDE:
1053
1054 /* Flush everything up to and including the include source line */
1055
1056 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1057 FileId);
1058
1059 /* Create a new listing node and push it */
1060
1061 LsPushNode (Op->Asl.Child->Asl.Value.String);
1062 return;
1063
1064
1065 case PARSEOP_INCLUDE_END:
1066
1067 /* Flush out the rest of the include file */
1068
1069 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1070 FileId);
1071
1072 /* Pop off this listing node and go back to the parent file */
1073
1074 (void) LsPopNode ();
1075 return;
1076
1077
1078 case PARSEOP_DEFAULT_ARG:
1079
1080 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
1081 {
1082 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.EndLogicalLine,
1083 FileId);
1084 }
1085 return;
1086
1087
1088 default:
1089 /* All other opcodes have an AML opcode */
1090 break;
1091 }
1092
1093 /*
1094 * Otherwise, we look at the AML opcode because we can
1095 * switch on the opcode type, getting an entire class
1096 * at once
1097 */
1098 switch (OpClass)
1099 {
1100 case AML_CLASS_ARGUMENT: /* argument type only */
1101 case AML_CLASS_INTERNAL:
1102
1103 break;
1104
1105
1106 case AML_CLASS_NAMED_OBJECT:
1107
1108 switch (Op->Asl.AmlOpcode)
1109 {
1110 case AML_FIELD_OP:
1111 case AML_INDEX_FIELD_OP:
1112 case AML_BANK_FIELD_OP:
1113
1114 /*
1115 * For fields, we want to dump all the AML after the
1116 * entire definition
1117 */
1118 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
1119 FileId);
1120 break;
1121
1122 case AML_NAME_OP:
1123
1124 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
1125 {
1126 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1127 FileId);
1128 }
1129 else
1130 {
1131 /*
1132 * For fields, we want to dump all the AML after the
1133 * entire definition
1134 */
1135 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
1136 FileId);
1137 }
1138 break;
1139
1140 default:
1141 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1142 FileId);
1143 break;
1144 }
1145
1146 switch (Op->Asl.AmlOpcode)
1147 {
1148 case AML_SCOPE_OP:
1149 case AML_ALIAS_OP:
1150
1151 /* These opcodes do not declare a new object, ignore them */
1152
1153 break;
1154
1155 default:
1156
1157 /* All other named object opcodes come here */
1158
1159 switch (FileId)
1160 {
1161 case ASL_FILE_ASM_SOURCE_OUTPUT:
1162 case ASL_FILE_C_SOURCE_OUTPUT:
1163 case ASL_FILE_ASM_INCLUDE_OUTPUT:
1164 case ASL_FILE_C_INCLUDE_OUTPUT:
1165
1166 /*
1167 * For named objects, we will create a valid symbol so that the
1168 * AML code can be referenced from C or ASM
1169 */
1170 if (Op->Asl.ExternalName)
1171 {
1172 /* Get the full pathname associated with this node */
1173
1174 Pathname = AcpiNsGetExternalPathname (Op->Asl.Node);
1175 Length = strlen (Pathname);
1176 if (Length >= 4)
1177 {
1178 /* Convert all dots in the path to underscores */
1179
1180 for (i = 0; i < Length; i++)
1181 {
1182 if (Pathname[i] == '.')
1183 {
1184 Pathname[i] = '_';
1185 }
1186 }
1187
1188 /* Create the appropriate symbol in the output file */
1189
1190 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
1191 {
1192 FlPrintFile (FileId,
1193 "%s_%s_%s \\\n",
1194 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1195 }
1196 if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
1197 {
1198 FlPrintFile (FileId,
1199 " unsigned char %s_%s_%s [] =\n {\n",
1200 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1201 }
1202 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
1203 {
1204 FlPrintFile (FileId,
1205 "extrn %s_%s_%s : byte\n",
1206 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1207 }
1208 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
1209 {
1210 FlPrintFile (FileId,
1211 "extern unsigned char %s_%s_%s [];\n",
1212 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1213 }
1214 }
1215 ACPI_FREE (Pathname);
1216 }
1217 break;
1218
1219 default:
1220 /* Nothing to do for listing file */
1221 break;
1222 }
1223 }
1224 break;
1225
1226 case AML_CLASS_EXECUTE:
1227 case AML_CLASS_CREATE:
1228 default:
1229
1230 if ((Op->Asl.ParseOpcode == PARSEOP_BUFFER) &&
1231 (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC))
1232 {
1233 return;
1234 }
1235
1236 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1237 FileId);
1238 break;
1239
1240 case AML_CLASS_UNKNOWN:
1241 break;
1242 }
1243}
1244
1245
1246/*******************************************************************************
1247 *
1248 * FUNCTION: LsDoHexOutput
1249 *
1250 * PARAMETERS: None
1251 *
1252 * RETURN: None.
1253 *
1254 * DESCRIPTION: Create the hex output file.
1255 *
1256 ******************************************************************************/
1257
1258void
1259LsDoHexOutput (
1260 void)
1261{
1262
1263 switch (Gbl_HexOutputFlag)
1264 {
1265 case HEX_OUTPUT_C:
1266
1267 LsDoHexOutputC ();
1268 break;
1269
1270 case HEX_OUTPUT_ASM:
1271
1272 LsDoHexOutputAsm ();
1273 break;
1274
1275 case HEX_OUTPUT_ASL:
1276
1277 LsDoHexOutputAsl ();
1278 break;
1279
1280 default:
1281 /* No other output types supported */
1282 break;
1283 }
1284}
1285
1286
1287/*******************************************************************************
1288 *
1289 * FUNCTION: LsReadAmlOutputFile
1290 *
1291 * PARAMETERS: Buffer - Where to return data
1292 *
1293 * RETURN: None.
1294 *
1295 * DESCRIPTION: Read a line of the AML output prior to formatting the data
1296 *
1297 ******************************************************************************/
1298
1299static UINT32
1300LsReadAmlOutputFile (
1301 UINT8 *Buffer)
1302{
1303 UINT32 Actual;
1304
1305
1306 Actual = fread (Buffer, 1, HEX_TABLE_LINE_SIZE,
1307 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
1308
1309 if (ferror (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle))
1310 {
1311 FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
1312 AslAbort ();
1313 }
1314
1315 return (Actual);
1316}
1317
1318
1319/*******************************************************************************
1320 *
1285 * FUNCTION: LsDoHexOutputC
1286 *
1287 * PARAMETERS: None
1288 *
1289 * RETURN: None.
1290 *
1291 * DESCRIPTION: Create the hex output file. This is the same data as the AML
1292 * output file, but formatted into hex/ascii bytes suitable for
1293 * inclusion into a C source file.
1294 *
1295 ******************************************************************************/
1296
1297static void
1298LsDoHexOutputC (
1299 void)
1300{
1301 UINT8 FileData[HEX_TABLE_LINE_SIZE];
1302 UINT32 LineLength;
1303 UINT32 Offset = 0;
1304 UINT32 AmlFileSize;
1305 UINT32 i;
1306
1307
1308 /* Get AML size, seek back to start */
1309
1310 AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
1311 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1312
1313 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n");
1314 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
1315 AmlFileSize);
1316 FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char AmlCode[] =\n{\n");
1317
1318 while (Offset < AmlFileSize)
1319 {
1320 /* Read enough bytes needed for one output line */
1321
1321 * FUNCTION: LsDoHexOutputC
1322 *
1323 * PARAMETERS: None
1324 *
1325 * RETURN: None.
1326 *
1327 * DESCRIPTION: Create the hex output file. This is the same data as the AML
1328 * output file, but formatted into hex/ascii bytes suitable for
1329 * inclusion into a C source file.
1330 *
1331 ******************************************************************************/
1332
1333static void
1334LsDoHexOutputC (
1335 void)
1336{
1337 UINT8 FileData[HEX_TABLE_LINE_SIZE];
1338 UINT32 LineLength;
1339 UINT32 Offset = 0;
1340 UINT32 AmlFileSize;
1341 UINT32 i;
1342
1343
1344 /* Get AML size, seek back to start */
1345
1346 AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
1347 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1348
1349 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n");
1350 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
1351 AmlFileSize);
1352 FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char AmlCode[] =\n{\n");
1353
1354 while (Offset < AmlFileSize)
1355 {
1356 /* Read enough bytes needed for one output line */
1357
1322 LineLength = fread (FileData, 1, HEX_TABLE_LINE_SIZE,
1323 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
1358 LineLength = LsReadAmlOutputFile (FileData);
1324 if (!LineLength)
1325 {
1326 break;
1327 }
1328
1329 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1330
1331 for (i = 0; i < LineLength; i++)
1332 {
1333 /*
1334 * Print each hex byte.
1335 * Add a comma until the very last byte of the AML file
1336 * (Some C compilers complain about a trailing comma)
1337 */
1338 FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
1339 if ((Offset + i + 1) < AmlFileSize)
1340 {
1341 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1342 }
1343 else
1344 {
1345 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1346 }
1347 }
1348
1349 /* Add fill spaces if needed for last line */
1350
1351 if (LineLength < HEX_TABLE_LINE_SIZE)
1352 {
1353 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
1354 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
1355 }
1356
1357 /* Emit the offset and ascii dump for the entire line */
1358
1359 FlPrintFile (ASL_FILE_HEX_OUTPUT, " /* %8.8X", Offset);
1360 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
1361 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
1362 HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
1363
1364 Offset += LineLength;
1365 }
1366
1367 FlPrintFile (ASL_FILE_HEX_OUTPUT, "};\n");
1368}
1369
1370
1371/*******************************************************************************
1372 *
1373 * FUNCTION: LsDoHexOutputAsl
1374 *
1375 * PARAMETERS: None
1376 *
1377 * RETURN: None.
1378 *
1379 * DESCRIPTION: Create the hex output file. This is the same data as the AML
1380 * output file, but formatted into hex/ascii bytes suitable for
1381 * inclusion into a C source file.
1382 *
1383 ******************************************************************************/
1384
1385static void
1386LsDoHexOutputAsl (
1387 void)
1388{
1389 UINT8 FileData[HEX_TABLE_LINE_SIZE];
1390 UINT32 LineLength;
1391 UINT32 Offset = 0;
1392 UINT32 AmlFileSize;
1393 UINT32 i;
1394
1395
1396 /* Get AML size, seek back to start */
1397
1398 AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
1399 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1400
1401 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * ASL source code output\n");
1402 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
1403 AmlFileSize);
1404 FlPrintFile (ASL_FILE_HEX_OUTPUT, " Name (BUF1, Buffer()\n {\n");
1405
1406 while (Offset < AmlFileSize)
1407 {
1408 /* Read enough bytes needed for one output line */
1409
1359 if (!LineLength)
1360 {
1361 break;
1362 }
1363
1364 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1365
1366 for (i = 0; i < LineLength; i++)
1367 {
1368 /*
1369 * Print each hex byte.
1370 * Add a comma until the very last byte of the AML file
1371 * (Some C compilers complain about a trailing comma)
1372 */
1373 FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
1374 if ((Offset + i + 1) < AmlFileSize)
1375 {
1376 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1377 }
1378 else
1379 {
1380 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1381 }
1382 }
1383
1384 /* Add fill spaces if needed for last line */
1385
1386 if (LineLength < HEX_TABLE_LINE_SIZE)
1387 {
1388 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
1389 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
1390 }
1391
1392 /* Emit the offset and ascii dump for the entire line */
1393
1394 FlPrintFile (ASL_FILE_HEX_OUTPUT, " /* %8.8X", Offset);
1395 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
1396 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
1397 HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
1398
1399 Offset += LineLength;
1400 }
1401
1402 FlPrintFile (ASL_FILE_HEX_OUTPUT, "};\n");
1403}
1404
1405
1406/*******************************************************************************
1407 *
1408 * FUNCTION: LsDoHexOutputAsl
1409 *
1410 * PARAMETERS: None
1411 *
1412 * RETURN: None.
1413 *
1414 * DESCRIPTION: Create the hex output file. This is the same data as the AML
1415 * output file, but formatted into hex/ascii bytes suitable for
1416 * inclusion into a C source file.
1417 *
1418 ******************************************************************************/
1419
1420static void
1421LsDoHexOutputAsl (
1422 void)
1423{
1424 UINT8 FileData[HEX_TABLE_LINE_SIZE];
1425 UINT32 LineLength;
1426 UINT32 Offset = 0;
1427 UINT32 AmlFileSize;
1428 UINT32 i;
1429
1430
1431 /* Get AML size, seek back to start */
1432
1433 AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
1434 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1435
1436 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * ASL source code output\n");
1437 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
1438 AmlFileSize);
1439 FlPrintFile (ASL_FILE_HEX_OUTPUT, " Name (BUF1, Buffer()\n {\n");
1440
1441 while (Offset < AmlFileSize)
1442 {
1443 /* Read enough bytes needed for one output line */
1444
1410 LineLength = fread (FileData, 1, HEX_TABLE_LINE_SIZE,
1411 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
1445 LineLength = LsReadAmlOutputFile (FileData);
1412 if (!LineLength)
1413 {
1414 break;
1415 }
1416
1417 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1418
1419 for (i = 0; i < LineLength; i++)
1420 {
1421 /*
1422 * Print each hex byte.
1423 * Add a comma until the very last byte of the AML file
1424 * (Some C compilers complain about a trailing comma)
1425 */
1426 FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
1427 if ((Offset + i + 1) < AmlFileSize)
1428 {
1429 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1430 }
1431 else
1432 {
1433 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1434 }
1435 }
1436
1437 /* Add fill spaces if needed for last line */
1438
1439 if (LineLength < HEX_TABLE_LINE_SIZE)
1440 {
1441 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
1442 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
1443 }
1444
1445 /* Emit the offset and ascii dump for the entire line */
1446
1447 FlPrintFile (ASL_FILE_HEX_OUTPUT, " /* %8.8X", Offset);
1448 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
1449 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
1450 HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
1451
1452 Offset += LineLength;
1453 }
1454
1455 FlPrintFile (ASL_FILE_HEX_OUTPUT, " })\n");
1456}
1457
1458
1459/*******************************************************************************
1460 *
1461 * FUNCTION: LsDoHexOutputAsm
1462 *
1463 * PARAMETERS: None
1464 *
1465 * RETURN: None.
1466 *
1467 * DESCRIPTION: Create the hex output file. This is the same data as the AML
1468 * output file, but formatted into hex/ascii bytes suitable for
1469 * inclusion into a ASM source file.
1470 *
1471 ******************************************************************************/
1472
1473static void
1474LsDoHexOutputAsm (
1475 void)
1476{
1477 UINT8 FileData[HEX_TABLE_LINE_SIZE];
1478 UINT32 LineLength;
1479 UINT32 Offset = 0;
1480 UINT32 AmlFileSize;
1481 UINT32 i;
1482
1483
1484 /* Get AML size, seek back to start */
1485
1486 AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
1487 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1488
1489 FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n");
1490 FlPrintFile (ASL_FILE_HEX_OUTPUT, "; AML code block contains 0x%X bytes\n;\n",
1491 AmlFileSize);
1492
1493 while (Offset < AmlFileSize)
1494 {
1495 /* Read enough bytes needed for one output line */
1496
1446 if (!LineLength)
1447 {
1448 break;
1449 }
1450
1451 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1452
1453 for (i = 0; i < LineLength; i++)
1454 {
1455 /*
1456 * Print each hex byte.
1457 * Add a comma until the very last byte of the AML file
1458 * (Some C compilers complain about a trailing comma)
1459 */
1460 FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
1461 if ((Offset + i + 1) < AmlFileSize)
1462 {
1463 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1464 }
1465 else
1466 {
1467 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1468 }
1469 }
1470
1471 /* Add fill spaces if needed for last line */
1472
1473 if (LineLength < HEX_TABLE_LINE_SIZE)
1474 {
1475 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
1476 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
1477 }
1478
1479 /* Emit the offset and ascii dump for the entire line */
1480
1481 FlPrintFile (ASL_FILE_HEX_OUTPUT, " /* %8.8X", Offset);
1482 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
1483 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
1484 HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
1485
1486 Offset += LineLength;
1487 }
1488
1489 FlPrintFile (ASL_FILE_HEX_OUTPUT, " })\n");
1490}
1491
1492
1493/*******************************************************************************
1494 *
1495 * FUNCTION: LsDoHexOutputAsm
1496 *
1497 * PARAMETERS: None
1498 *
1499 * RETURN: None.
1500 *
1501 * DESCRIPTION: Create the hex output file. This is the same data as the AML
1502 * output file, but formatted into hex/ascii bytes suitable for
1503 * inclusion into a ASM source file.
1504 *
1505 ******************************************************************************/
1506
1507static void
1508LsDoHexOutputAsm (
1509 void)
1510{
1511 UINT8 FileData[HEX_TABLE_LINE_SIZE];
1512 UINT32 LineLength;
1513 UINT32 Offset = 0;
1514 UINT32 AmlFileSize;
1515 UINT32 i;
1516
1517
1518 /* Get AML size, seek back to start */
1519
1520 AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
1521 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1522
1523 FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n");
1524 FlPrintFile (ASL_FILE_HEX_OUTPUT, "; AML code block contains 0x%X bytes\n;\n",
1525 AmlFileSize);
1526
1527 while (Offset < AmlFileSize)
1528 {
1529 /* Read enough bytes needed for one output line */
1530
1497 LineLength = fread (FileData, 1, HEX_TABLE_LINE_SIZE,
1498 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
1531 LineLength = LsReadAmlOutputFile (FileData);
1499 if (!LineLength)
1500 {
1501 break;
1502 }
1503
1504 FlPrintFile (ASL_FILE_HEX_OUTPUT, " db ");
1505
1506 for (i = 0; i < LineLength; i++)
1507 {
1508 /*
1509 * Print each hex byte.
1510 * Add a comma until the last byte of the line
1511 */
1512 FlPrintFile (ASL_FILE_HEX_OUTPUT, "0%2.2Xh", FileData[i]);
1513 if ((i + 1) < LineLength)
1514 {
1515 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1516 }
1517 }
1518
1519 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1520
1521 /* Add fill spaces if needed for last line */
1522
1523 if (LineLength < HEX_TABLE_LINE_SIZE)
1524 {
1525 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
1526 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
1527 }
1528
1529 /* Emit the offset and ascii dump for the entire line */
1530
1531 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ; %8.8X", Offset);
1532 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
1533 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1534
1535 Offset += LineLength;
1536 }
1537
1538 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1539}
1532 if (!LineLength)
1533 {
1534 break;
1535 }
1536
1537 FlPrintFile (ASL_FILE_HEX_OUTPUT, " db ");
1538
1539 for (i = 0; i < LineLength; i++)
1540 {
1541 /*
1542 * Print each hex byte.
1543 * Add a comma until the last byte of the line
1544 */
1545 FlPrintFile (ASL_FILE_HEX_OUTPUT, "0%2.2Xh", FileData[i]);
1546 if ((i + 1) < LineLength)
1547 {
1548 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1549 }
1550 }
1551
1552 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
1553
1554 /* Add fill spaces if needed for last line */
1555
1556 if (LineLength < HEX_TABLE_LINE_SIZE)
1557 {
1558 FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
1559 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
1560 }
1561
1562 /* Emit the offset and ascii dump for the entire line */
1563
1564 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ; %8.8X", Offset);
1565 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
1566 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1567
1568 Offset += LineLength;
1569 }
1570
1571 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1572}