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
163static ACPI_STATUS
164CgAmlWriteWalk (
165    ACPI_PARSE_OBJECT       *Op,
166    UINT32                  Level,
167    void                    *Context);
168
169static void
170CgWriteAmlOpcode (
171    ACPI_PARSE_OBJECT       *Op);
172
173static void
174CgWriteTableHeader (
175    ACPI_PARSE_OBJECT       *Op);
176
177static void
178CgWriteNode (
179    ACPI_PARSE_OBJECT       *Op);
180
181static void
182CgUpdateHeader (
183    ACPI_PARSE_OBJECT       *Op);
184
185static void
186CgUpdateCdatHeader (
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
203void
204CgGenerateAmlOutput (
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
238static ACPI_STATUS
239CgAmlWriteWalk (
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
323void
324CgLocalWriteAmlData (
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
355static void
356CgWriteAmlOpcode (
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
539static void
540CgWriteTableHeader (
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
684static void
685CgUpdateCdatHeader (
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
745static void
746CgUpdateHeader (
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
804static void
805CgWriteNode (
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