xref: /freebsd/sys/contrib/dev/acpica/compiler/aslcodegen.c (revision f126890ac5386406dadf7c4cfa9566cbb56537c5)
1 /******************************************************************************
2  *
3  * Module Name: aslcodegen - AML code generation
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 <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include "aslcompiler.y.h"
154 #include <contrib/dev/acpica/include/amlcode.h>
155 #include <contrib/dev/acpica/include/acconvert.h>
156 #include <contrib/dev/acpica/include/actbinfo.h>
157 
158 #define _COMPONENT          ACPI_COMPILER
159         ACPI_MODULE_NAME    ("aslcodegen")
160 
161 /* Local prototypes */
162 
163 static ACPI_STATUS
164 CgAmlWriteWalk (
165     ACPI_PARSE_OBJECT       *Op,
166     UINT32                  Level,
167     void                    *Context);
168 
169 static void
170 CgWriteAmlOpcode (
171     ACPI_PARSE_OBJECT       *Op);
172 
173 static void
174 CgWriteTableHeader (
175     ACPI_PARSE_OBJECT       *Op);
176 
177 static void
178 CgWriteNode (
179     ACPI_PARSE_OBJECT       *Op);
180 
181 static void
182 CgUpdateHeader (
183     ACPI_PARSE_OBJECT       *Op);
184 
185 static void
186 CgUpdateCdatHeader (
187     ACPI_PARSE_OBJECT       *Op);
188 
189 
190 /*******************************************************************************
191  *
192  * FUNCTION:    CgGenerateAmlOutput
193  *
194  * PARAMETERS:  None.
195  *
196  * RETURN:      None
197  *
198  * DESCRIPTION: Generate AML code. Currently generates the listing file
199  *              simultaneously.
200  *
201  ******************************************************************************/
202 
203 void
204 CgGenerateAmlOutput (
205     void)
206 {
207 
208     /* Generate the AML output file */
209 
210     TrWalkParseTree (AslGbl_CurrentDB,
211         ASL_WALK_VISIT_DOWNWARD | ASL_WALK_VISIT_DB_SEPARATELY,
212         CgAmlWriteWalk, NULL, NULL);
213 
214     DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_HEADER2);
215     if (AcpiGbl_CDAT)
216     {
217         CgUpdateCdatHeader (AslGbl_CurrentDB);
218     }
219     else
220     {
221         CgUpdateHeader (AslGbl_CurrentDB);
222     }
223 }
224 
225 
226 /*******************************************************************************
227  *
228  * FUNCTION:    CgAmlWriteWalk
229  *
230  * PARAMETERS:  ASL_WALK_CALLBACK
231  *
232  * RETURN:      Status
233  *
234  * DESCRIPTION: Parse tree walk to generate the AML code.
235  *
236  ******************************************************************************/
237 
238 static ACPI_STATUS
239 CgAmlWriteWalk (
240     ACPI_PARSE_OBJECT       *Op,
241     UINT32                  Level,
242     void                    *Context)
243 {
244 
245     /* Generate the AML for this node */
246 
247     CgWriteNode (Op);
248 
249     if (!AslGbl_DebugFlag)
250     {
251         return (AE_OK);
252     }
253 
254     /* Print header at level 0. Alignment assumes 32-bit pointers */
255 
256     if (!Level)
257     {
258         DbgPrint (ASL_TREE_OUTPUT,
259             "\nFinal parse tree used for AML output:\n");
260         DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_HEADER2);
261     }
262 
263     /* Dump ParseOp name and possible value */
264 
265     switch (Op->Asl.ParseOpcode)
266     {
267     case PARSEOP_NAMESEG:
268     case PARSEOP_NAMESTRING:
269     case PARSEOP_METHODCALL:
270     case PARSEOP_STRING_LITERAL:
271 
272         UtDumpStringOp (Op, Level);
273         break;
274 
275     default:
276 
277         UtDumpBasicOp (Op, Level);
278         break;
279     }
280 
281     DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_DEBUG2,
282         /* 1  */ (UINT32) Op->Asl.Value.Integer,
283         /* 2  */ Op->Asl.ParseOpcode,
284         /* 3  */ Op->Asl.AmlOpcode,
285         /* 4  */ Op->Asl.AmlOpcodeLength,
286         /* 5  */ Op->Asl.AmlPkgLenBytes,
287         /* 6  */ Op->Asl.AmlLength,
288         /* 7  */ Op->Asl.AmlSubtreeLength,
289         /* 8  */ Op->Asl.Parent ? Op->Asl.Parent->Asl.AmlSubtreeLength : 0,
290         /* 9  */ Op,
291         /* 10 */ Op->Asl.Parent,
292         /* 11 */ Op->Asl.Child,
293         /* 12 */ Op->Asl.Next,
294         /* 13 */ Op->Asl.CompileFlags,
295         /* 14 */ Op->Asl.AcpiBtype,
296         /* 15 */ Op->Asl.FinalAmlLength,
297         /* 16 */ Op->Asl.Column,
298         /* 17 */ Op->Asl.LineNumber,
299         /* 18 */ Op->Asl.EndLine,
300         /* 19 */ Op->Asl.LogicalLineNumber,
301         /* 20 */ Op->Asl.EndLogicalLine);
302 
303     TrPrintOpFlags (Op->Asl.CompileFlags, ASL_TREE_OUTPUT);
304     DbgPrint (ASL_TREE_OUTPUT, "\n");
305     return (AE_OK);
306 }
307 
308 
309 /*******************************************************************************
310  *
311  * FUNCTION:    CgLocalWriteAmlData
312  *
313  * PARAMETERS:  Op              - Current parse op
314  *              Buffer          - Buffer to write
315  *              Length          - Size of data in buffer
316  *
317  * RETURN:      None
318  *
319  * DESCRIPTION: Write a buffer of AML data to the AML output file.
320  *
321  ******************************************************************************/
322 
323 void
324 CgLocalWriteAmlData (
325     ACPI_PARSE_OBJECT       *Op,
326     void                    *Buffer,
327     UINT32                  Length)
328 {
329 
330     /* Write the raw data to the AML file */
331 
332     FlWriteFile (ASL_FILE_AML_OUTPUT, Buffer, Length);
333 
334     /* Update the final AML length for this node (used for listings) */
335 
336     if (Op)
337     {
338         Op->Asl.FinalAmlLength += Length;
339     }
340 }
341 
342 
343 /*******************************************************************************
344  *
345  * FUNCTION:    CgWriteAmlOpcode
346  *
347  * PARAMETERS:  Op            - Parse node with an AML opcode
348  *
349  * RETURN:      None.
350  *
351  * DESCRIPTION: Write the AML opcode corresponding to a parse node.
352  *
353  ******************************************************************************/
354 
355 static void
356 CgWriteAmlOpcode (
357     ACPI_PARSE_OBJECT       *Op)
358 {
359     UINT8                   PkgLenFirstByte;
360     UINT32                  i;
361     union {
362         UINT16                  Opcode;
363         UINT8                   OpcodeBytes[2];
364     } Aml;
365     union {
366         UINT32                  Len;
367         UINT8                   LenBytes[4];
368     } PkgLen;
369 
370 
371     /* We expect some DEFAULT_ARGs, just ignore them */
372 
373     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
374     {
375         return;
376     }
377 
378     /*
379      * Before printing the bytecode, generate comment byte codes
380      * associated with this node.
381      */
382     if (AcpiGbl_CaptureComments)
383     {
384         CgWriteAmlComment(Op);
385     }
386 
387     switch (Op->Asl.AmlOpcode)
388     {
389     case AML_UNASSIGNED_OPCODE:
390 
391         /* These opcodes should not get here */
392 
393         printf ("Found a node with an unassigned AML opcode\n");
394         FlPrintFile (ASL_FILE_STDERR,
395             "Found a node with an unassigned AML opcode\n");
396         return;
397 
398     case AML_INT_RESERVEDFIELD_OP:
399 
400         /* Special opcodes for within a field definition */
401 
402         Aml.Opcode = AML_FIELD_OFFSET_OP;
403         break;
404 
405     case AML_INT_ACCESSFIELD_OP:
406 
407         Aml.Opcode = AML_FIELD_ACCESS_OP;
408         break;
409 
410     case AML_INT_CONNECTION_OP:
411 
412         Aml.Opcode = AML_FIELD_CONNECTION_OP;
413         break;
414 
415     default:
416 
417         Aml.Opcode = Op->Asl.AmlOpcode;
418         break;
419     }
420 
421 
422     switch (Aml.Opcode)
423     {
424     case AML_PACKAGE_LENGTH:
425 
426         /* Value is the length to be encoded (Used in field definitions) */
427 
428         PkgLen.Len = (UINT32) Op->Asl.Value.Integer;
429         break;
430 
431     default:
432 
433         /* Check for two-byte opcode */
434 
435         if (Aml.Opcode > 0x00FF)
436         {
437             /* Write the high byte first */
438 
439             CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[1], 1);
440         }
441 
442         CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[0], 1);
443 
444         /* Subtreelength doesn't include length of package length bytes */
445 
446         PkgLen.Len = Op->Asl.AmlSubtreeLength + Op->Asl.AmlPkgLenBytes;
447         break;
448     }
449 
450     /* Does this opcode have an associated "PackageLength" field? */
451 
452     if (Op->Asl.CompileFlags & OP_AML_PACKAGE)
453     {
454         if (Op->Asl.AmlPkgLenBytes == 1)
455         {
456             /* Simplest case -- no bytes to follow, just write the count */
457 
458             CgLocalWriteAmlData (Op, &PkgLen.LenBytes[0], 1);
459         }
460         else if (Op->Asl.AmlPkgLenBytes != 0)
461         {
462             /*
463              * Encode the "bytes to follow" in the first byte, top two bits.
464              * The low-order nybble of the length is in the bottom 4 bits
465              */
466             PkgLenFirstByte = (UINT8)
467                 (((UINT32) (Op->Asl.AmlPkgLenBytes - 1) << 6) |
468                 (PkgLen.LenBytes[0] & 0x0F));
469 
470             CgLocalWriteAmlData (Op, &PkgLenFirstByte, 1);
471 
472             /*
473              * Shift the length over by the 4 bits we just stuffed
474              * in the first byte
475              */
476             PkgLen.Len >>= 4;
477 
478             /*
479              * Now we can write the remaining bytes -
480              * either 1, 2, or 3 bytes
481              */
482             for (i = 0; i < (UINT32) (Op->Asl.AmlPkgLenBytes - 1); i++)
483             {
484                 CgLocalWriteAmlData (Op, &PkgLen.LenBytes[i], 1);
485             }
486         }
487     }
488 
489     switch (Aml.Opcode)
490     {
491     case AML_BYTE_OP:
492 
493         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 1);
494         break;
495 
496     case AML_WORD_OP:
497 
498         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 2);
499        break;
500 
501     case AML_DWORD_OP:
502 
503         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 4);
504         break;
505 
506     case AML_QWORD_OP:
507 
508         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 8);
509         break;
510 
511     case AML_STRING_OP:
512 
513         CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
514         break;
515 
516     default:
517 
518         /* All data opcodes must appear above */
519 
520         break;
521     }
522 }
523 
524 
525 /*******************************************************************************
526  *
527  * FUNCTION:    CgWriteTableHeader
528  *
529  * PARAMETERS:  Op        - The DEFINITIONBLOCK node
530  *
531  * RETURN:      None
532  *
533  * DESCRIPTION: Write a table header corresponding to the DEFINITIONBLOCK
534  *
535  * NOTE: Input strings should be validated before this function is invoked.
536  *
537  ******************************************************************************/
538 
539 static void
540 CgWriteTableHeader (
541     ACPI_PARSE_OBJECT       *Op)
542 {
543     ACPI_PARSE_OBJECT       *Child;
544     UINT32                  CommentLength;
545     ACPI_COMMENT_NODE       *Current;
546 
547 
548     memset (&AslGbl_TableHeader, 0, sizeof (ACPI_TABLE_HEADER));
549 
550     /* AML filename */
551 
552     Child = Op->Asl.Child;
553 
554     /* Signature */
555 
556     Child = Child->Asl.Next;
557 
558     /*
559      * For ASL-/ASL+ converter: replace the table signature with
560      * "XXXX" and save the original table signature. This results in an AML
561      * file with the signature "XXXX". The converter should remove this AML
562      * file. In the event where this AML file does not get deleted, the
563      * "XXXX" table signature prevents this AML file from running on the AML
564      * interpreter.
565      */
566     if (AcpiGbl_CaptureComments)
567     {
568         ACPI_COPY_NAMESEG (AcpiGbl_TableSig, Child->Asl.Value.String);
569         Child->Asl.Value.String = ACPI_SIG_XXXX;
570     }
571 
572     ACPI_COPY_NAMESEG (AslGbl_TableHeader.Signature, Child->Asl.Value.String);
573 
574     /* Revision */
575 
576     Child = Child->Asl.Next;
577     AslGbl_TableHeader.Revision = (UINT8) Child->Asl.Value.Integer;
578 
579     /* Command-line Revision override */
580 
581     if (AslGbl_RevisionOverride)
582     {
583         AslGbl_TableHeader.Revision = AslGbl_RevisionOverride;
584     }
585 
586     /* OEMID */
587 
588     Child = Child->Asl.Next;
589     memcpy (AslGbl_TableHeader.OemId, Child->Asl.Value.String,
590         strlen (Child->Asl.Value.String));
591 
592     /* OEM TableID */
593 
594     Child = Child->Asl.Next;
595     memcpy (AslGbl_TableHeader.OemTableId, Child->Asl.Value.String,
596         strlen (Child->Asl.Value.String));
597 
598     /* OEM Revision */
599 
600     Child = Child->Asl.Next;
601     AslGbl_TableHeader.OemRevision = (UINT32) Child->Asl.Value.Integer;
602 
603     /* Compiler ID */
604 
605     ACPI_COPY_NAMESEG (AslGbl_TableHeader.AslCompilerId, ASL_CREATOR_ID);
606 
607     /* Compiler version */
608 
609     AslGbl_TableHeader.AslCompilerRevision = ACPI_CA_VERSION;
610 
611     /* Table length. Checksum zero for now, will rewrite later */
612 
613     AslGbl_TableHeader.Length = sizeof (ACPI_TABLE_HEADER) +
614         Op->Asl.AmlSubtreeLength;
615 
616     /* Calculate the comment lengths for this definition block parseOp */
617 
618     if (AcpiGbl_CaptureComments)
619     {
620         CvDbgPrint ("Calculating comment lengths for %s in write header\n",
621             Op->Asl.ParseOpName);
622 
623         /*
624          * Take the filename without extensions, add 3 for the new extension
625          * and another 3 for the a908 bytecode and null terminator.
626          */
627         AslGbl_TableHeader.Length += strrchr (AslGbl_ParseTreeRoot->Asl.Filename, '.')
628             - AslGbl_ParseTreeRoot->Asl.Filename + 1 + 3 + 3;
629 
630         Op->Asl.AmlSubtreeLength +=
631             strlen (AslGbl_ParseTreeRoot->Asl.Filename) + 3;
632 
633         CvDbgPrint ("     Length: %u\n",
634             (UINT32) strlen (AslGbl_ParseTreeRoot->Asl.Filename) + 3);
635 
636         if (Op->Asl.CommentList)
637         {
638             Current = Op->Asl.CommentList;
639             while (Current)
640             {
641                 CommentLength = strlen (Current->Comment)+3;
642                 CvDbgPrint ("Length of standard comment): %d\n", CommentLength);
643                 CvDbgPrint ("    Comment string: %s\n\n", Current->Comment);
644                 AslGbl_TableHeader.Length += CommentLength;
645                 Op->Asl.AmlSubtreeLength += CommentLength;
646                 Current = Current->Next;
647                 CvDbgPrint ("    Length: %u\n", CommentLength);
648             }
649         }
650         if (Op->Asl.CloseBraceComment)
651         {
652             CommentLength = strlen (Op->Asl.CloseBraceComment)+3;
653             CvDbgPrint ("Length of inline comment +3: %d\n", CommentLength);
654             CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.CloseBraceComment);
655             AslGbl_TableHeader.Length += CommentLength;
656             Op->Asl.AmlSubtreeLength += CommentLength;
657             CvDbgPrint ("    Length: %u\n", CommentLength);
658         }
659     }
660 
661     AslGbl_TableHeader.Checksum = 0;
662     Op->Asl.FinalAmlOffset = ftell (AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle);
663 
664     /* Write entire header and clear the table header global */
665 
666     CgLocalWriteAmlData (Op, &AslGbl_TableHeader, sizeof (ACPI_TABLE_HEADER));
667     memset (&AslGbl_TableHeader, 0, sizeof (ACPI_TABLE_HEADER));
668 }
669 
670 
671 /*******************************************************************************
672  *
673  * FUNCTION:    CgUpdateCdatHeader
674  *
675  * PARAMETERS:  Op                  - Op for the Definition Block
676  *
677  * RETURN:      None.
678  *
679  * DESCRIPTION: Complete the ACPI table by calculating the checksum and
680  *              re-writing the header for the input definition block
681  *
682  ******************************************************************************/
683 
684 static void
685 CgUpdateCdatHeader (
686     ACPI_PARSE_OBJECT       *Op)
687 {
688     signed char             Sum;
689     UINT32                  i;
690     UINT32                  Length;
691     UINT8                   FileByte;
692     UINT8                   Checksum;
693 
694 
695     /* Calculate the checksum over the entire definition block */
696 
697     Sum = 0;
698     Length = sizeof (ACPI_TABLE_CDAT) + Op->Asl.AmlSubtreeLength;
699     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset);
700 
701     for (i = 0; i < Length; i++)
702     {
703         if (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1) != AE_OK)
704         {
705             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL,
706                 "Table length is greater than size of the input file");
707             return;
708         }
709 
710         Sum = (signed char) (Sum + FileByte);
711     }
712 
713     Checksum = (UINT8) (0 - Sum);
714 
715     DbgPrint (ASL_DEBUG_OUTPUT, "Computed checksum = %X\n", Checksum);
716 
717     /* Re-write the checksum byte */
718 
719     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset +
720         ACPI_CDAT_OFFSET (Checksum));
721 
722     FlWriteFile (ASL_FILE_AML_OUTPUT, &Checksum, 1);
723 
724     /*
725      * Seek to the end of the file. This is done to support multiple file
726      * compilation. Doing this simplifies other parts of the codebase because
727      * it eliminates the need to seek for a different starting place.
728      */
729     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset + Length);
730 }
731 
732 /*******************************************************************************
733  *
734  * FUNCTION:    CgUpdateHeader
735  *
736  * PARAMETERS:  Op                  - Op for the Definition Block
737  *
738  * RETURN:      None.
739  *
740  * DESCRIPTION: Complete the ACPI table by calculating the checksum and
741  *              re-writing the header for the input definition block
742  *
743  ******************************************************************************/
744 
745 static void
746 CgUpdateHeader (
747     ACPI_PARSE_OBJECT       *Op)
748 {
749     signed char             Sum;
750     UINT32                  i;
751     UINT32                  Length;
752     UINT8                   FileByte;
753     UINT8                   Checksum;
754 
755 
756     /* Calculate the checksum over the entire definition block */
757 
758     Sum = 0;
759     Length = sizeof (ACPI_TABLE_HEADER) + Op->Asl.AmlSubtreeLength;
760     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset);
761 
762     for (i = 0; i < Length; i++)
763     {
764         if (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1) != AE_OK)
765         {
766             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL,
767                 "Table length is greater than size of the input file");
768             return;
769         }
770 
771         Sum = (signed char) (Sum + FileByte);
772     }
773 
774     Checksum = (UINT8) (0 - Sum);
775 
776     /* Re-write the checksum byte */
777 
778     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset +
779         ACPI_OFFSET (ACPI_TABLE_HEADER, Checksum));
780 
781     FlWriteFile (ASL_FILE_AML_OUTPUT, &Checksum, 1);
782 
783     /*
784      * Seek to the end of the file. This is done to support multiple file
785      * compilation. Doing this simplifies other parts of the codebase because
786      * it eliminates the need to seek for a different starting place.
787      */
788     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset + Length);
789 }
790 
791 
792 /*******************************************************************************
793  *
794  * FUNCTION:    CgWriteNode
795  *
796  * PARAMETERS:  Op            - Parse node to write.
797  *
798  * RETURN:      None.
799  *
800  * DESCRIPTION: Write the AML that corresponds to a parse node.
801  *
802  ******************************************************************************/
803 
804 static void
805 CgWriteNode (
806     ACPI_PARSE_OBJECT       *Op)
807 {
808     ASL_RESOURCE_NODE       *Rnode;
809 
810 
811     /* Write all comments here. */
812 
813     if (AcpiGbl_CaptureComments)
814     {
815         CgWriteAmlComment(Op);
816     }
817 
818     /* Always check for DEFAULT_ARG and other "Noop" nodes */
819     /* TBD: this may not be the best place for this check */
820 
821     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)  ||
822         (Op->Asl.ParseOpcode == PARSEOP_INCLUDE)      ||
823         (Op->Asl.ParseOpcode == PARSEOP_INCLUDE_END))
824     {
825         return;
826     }
827 
828     Op->Asl.FinalAmlLength = 0;
829 
830     switch (Op->Asl.AmlOpcode)
831     {
832     case AML_RAW_DATA_BYTE:
833     case AML_RAW_DATA_WORD:
834     case AML_RAW_DATA_DWORD:
835     case AML_RAW_DATA_QWORD:
836 
837         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, Op->Asl.AmlLength);
838         return;
839 
840 
841     case AML_RAW_DATA_BUFFER:
842 
843         CgLocalWriteAmlData (Op, Op->Asl.Value.Buffer, Op->Asl.AmlLength);
844         return;
845 
846 
847     case AML_RAW_DATA_CHAIN:
848 
849         Rnode = ACPI_CAST_PTR (ASL_RESOURCE_NODE, Op->Asl.Value.Buffer);
850         while (Rnode)
851         {
852             CgLocalWriteAmlData (Op, Rnode->Buffer, Rnode->BufferLength);
853             Rnode = Rnode->Next;
854         }
855         return;
856 
857     default:
858 
859         /* Internal data opcodes must all appear above */
860 
861         break;
862     }
863 
864     switch (Op->Asl.ParseOpcode)
865     {
866     case PARSEOP_DEFAULT_ARG:
867 
868         break;
869 
870     case PARSEOP_DEFINITION_BLOCK:
871 
872         CgWriteTableHeader (Op);
873         if (AcpiGbl_CaptureComments)
874         {
875             CgWriteAmlDefBlockComment (Op);
876         }
877         break;
878 
879     case PARSEOP_NAMESEG:
880     case PARSEOP_NAMESTRING:
881     case PARSEOP_METHODCALL:
882 
883         CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
884         break;
885 
886     default:
887 
888         CgWriteAmlOpcode (Op);
889         break;
890     }
891 }
892