Home | History | Annotate | Line # | Download | only in compiler
aslcodegen.c revision 1.1.1.15
      1 /******************************************************************************
      2  *
      3  * Module Name: aslcodegen - AML code generation
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2019, 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 #include "aslcompiler.h"
     45 #include "aslcompiler.y.h"
     46 #include "amlcode.h"
     47 #include "acconvert.h"
     48 
     49 #define _COMPONENT          ACPI_COMPILER
     50         ACPI_MODULE_NAME    ("aslcodegen")
     51 
     52 /* Local prototypes */
     53 
     54 static ACPI_STATUS
     55 CgAmlWriteWalk (
     56     ACPI_PARSE_OBJECT       *Op,
     57     UINT32                  Level,
     58     void                    *Context);
     59 
     60 static void
     61 CgWriteAmlOpcode (
     62     ACPI_PARSE_OBJECT       *Op);
     63 
     64 static void
     65 CgWriteTableHeader (
     66     ACPI_PARSE_OBJECT       *Op);
     67 
     68 static void
     69 CgWriteNode (
     70     ACPI_PARSE_OBJECT       *Op);
     71 
     72 static void
     73 CgUpdateHeader (
     74     ACPI_PARSE_OBJECT       *Op);
     75 
     76 
     77 /*******************************************************************************
     78  *
     79  * FUNCTION:    CgGenerateAmlOutput
     80  *
     81  * PARAMETERS:  None.
     82  *
     83  * RETURN:      None
     84  *
     85  * DESCRIPTION: Generate AML code. Currently generates the listing file
     86  *              simultaneously.
     87  *
     88  ******************************************************************************/
     89 
     90 void
     91 CgGenerateAmlOutput (
     92     void)
     93 {
     94 
     95     /* Generate the AML output file */
     96 
     97     TrWalkParseTree (AslGbl_CurrentDB,
     98         ASL_WALK_VISIT_DOWNWARD | ASL_WALK_VISIT_DB_SEPARATELY,
     99         CgAmlWriteWalk, NULL, NULL);
    100 
    101     DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_HEADER2);
    102     CgUpdateHeader (AslGbl_CurrentDB);
    103 }
    104 
    105 
    106 /*******************************************************************************
    107  *
    108  * FUNCTION:    CgAmlWriteWalk
    109  *
    110  * PARAMETERS:  ASL_WALK_CALLBACK
    111  *
    112  * RETURN:      Status
    113  *
    114  * DESCRIPTION: Parse tree walk to generate the AML code.
    115  *
    116  ******************************************************************************/
    117 
    118 static ACPI_STATUS
    119 CgAmlWriteWalk (
    120     ACPI_PARSE_OBJECT       *Op,
    121     UINT32                  Level,
    122     void                    *Context)
    123 {
    124 
    125     /* Generate the AML for this node */
    126 
    127     CgWriteNode (Op);
    128 
    129     if (!AslGbl_DebugFlag)
    130     {
    131         return (AE_OK);
    132     }
    133 
    134     /* Print header at level 0. Alignment assumes 32-bit pointers */
    135 
    136     if (!Level)
    137     {
    138         DbgPrint (ASL_TREE_OUTPUT,
    139             "\nFinal parse tree used for AML output:\n");
    140         DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_HEADER2);
    141     }
    142 
    143     /* Dump ParseOp name and possible value */
    144 
    145     switch (Op->Asl.ParseOpcode)
    146     {
    147     case PARSEOP_NAMESEG:
    148     case PARSEOP_NAMESTRING:
    149     case PARSEOP_METHODCALL:
    150     case PARSEOP_STRING_LITERAL:
    151 
    152         UtDumpStringOp (Op, Level);
    153         break;
    154 
    155     default:
    156 
    157         UtDumpBasicOp (Op, Level);
    158         break;
    159     }
    160 
    161     DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_DEBUG2,
    162         /* 1  */ (UINT32) Op->Asl.Value.Integer,
    163         /* 2  */ Op->Asl.ParseOpcode,
    164         /* 3  */ Op->Asl.AmlOpcode,
    165         /* 4  */ Op->Asl.AmlOpcodeLength,
    166         /* 5  */ Op->Asl.AmlPkgLenBytes,
    167         /* 6  */ Op->Asl.AmlLength,
    168         /* 7  */ Op->Asl.AmlSubtreeLength,
    169         /* 8  */ Op->Asl.Parent ? Op->Asl.Parent->Asl.AmlSubtreeLength : 0,
    170         /* 9  */ Op,
    171         /* 10 */ Op->Asl.Parent,
    172         /* 11 */ Op->Asl.Child,
    173         /* 12 */ Op->Asl.Next,
    174         /* 13 */ Op->Asl.CompileFlags,
    175         /* 14 */ Op->Asl.AcpiBtype,
    176         /* 15 */ Op->Asl.FinalAmlLength,
    177         /* 16 */ Op->Asl.Column,
    178         /* 17 */ Op->Asl.LineNumber,
    179         /* 18 */ Op->Asl.EndLine,
    180         /* 19 */ Op->Asl.LogicalLineNumber,
    181         /* 20 */ Op->Asl.EndLogicalLine);
    182 
    183     TrPrintOpFlags (Op->Asl.CompileFlags, ASL_TREE_OUTPUT);
    184     DbgPrint (ASL_TREE_OUTPUT, "\n");
    185     return (AE_OK);
    186 }
    187 
    188 
    189 /*******************************************************************************
    190  *
    191  * FUNCTION:    CgLocalWriteAmlData
    192  *
    193  * PARAMETERS:  Op              - Current parse op
    194  *              Buffer          - Buffer to write
    195  *              Length          - Size of data in buffer
    196  *
    197  * RETURN:      None
    198  *
    199  * DESCRIPTION: Write a buffer of AML data to the AML output file.
    200  *
    201  ******************************************************************************/
    202 
    203 void
    204 CgLocalWriteAmlData (
    205     ACPI_PARSE_OBJECT       *Op,
    206     void                    *Buffer,
    207     UINT32                  Length)
    208 {
    209 
    210     /* Write the raw data to the AML file */
    211 
    212     FlWriteFile (ASL_FILE_AML_OUTPUT, Buffer, Length);
    213 
    214     /* Update the final AML length for this node (used for listings) */
    215 
    216     if (Op)
    217     {
    218         Op->Asl.FinalAmlLength += Length;
    219     }
    220 }
    221 
    222 
    223 /*******************************************************************************
    224  *
    225  * FUNCTION:    CgWriteAmlOpcode
    226  *
    227  * PARAMETERS:  Op            - Parse node with an AML opcode
    228  *
    229  * RETURN:      None.
    230  *
    231  * DESCRIPTION: Write the AML opcode corresponding to a parse node.
    232  *
    233  ******************************************************************************/
    234 
    235 static void
    236 CgWriteAmlOpcode (
    237     ACPI_PARSE_OBJECT       *Op)
    238 {
    239     UINT8                   PkgLenFirstByte;
    240     UINT32                  i;
    241     union {
    242         UINT16                  Opcode;
    243         UINT8                   OpcodeBytes[2];
    244     } Aml;
    245     union {
    246         UINT32                  Len;
    247         UINT8                   LenBytes[4];
    248     } PkgLen;
    249 
    250 
    251     /* We expect some DEFAULT_ARGs, just ignore them */
    252 
    253     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
    254     {
    255         return;
    256     }
    257 
    258     /*
    259      * Before printing the bytecode, generate comment byte codes
    260      * associated with this node.
    261      */
    262     if (AcpiGbl_CaptureComments)
    263     {
    264         CgWriteAmlComment(Op);
    265     }
    266 
    267     switch (Op->Asl.AmlOpcode)
    268     {
    269     case AML_UNASSIGNED_OPCODE:
    270 
    271         /* These opcodes should not get here */
    272 
    273         printf ("Found a node with an unassigned AML opcode\n");
    274         FlPrintFile (ASL_FILE_STDERR,
    275             "Found a node with an unassigned AML opcode\n");
    276         return;
    277 
    278     case AML_INT_RESERVEDFIELD_OP:
    279 
    280         /* Special opcodes for within a field definition */
    281 
    282         Aml.Opcode = AML_FIELD_OFFSET_OP;
    283         break;
    284 
    285     case AML_INT_ACCESSFIELD_OP:
    286 
    287         Aml.Opcode = AML_FIELD_ACCESS_OP;
    288         break;
    289 
    290     case AML_INT_CONNECTION_OP:
    291 
    292         Aml.Opcode = AML_FIELD_CONNECTION_OP;
    293         break;
    294 
    295     default:
    296 
    297         Aml.Opcode = Op->Asl.AmlOpcode;
    298         break;
    299     }
    300 
    301 
    302     switch (Aml.Opcode)
    303     {
    304     case AML_PACKAGE_LENGTH:
    305 
    306         /* Value is the length to be encoded (Used in field definitions) */
    307 
    308         PkgLen.Len = (UINT32) Op->Asl.Value.Integer;
    309         break;
    310 
    311     default:
    312 
    313         /* Check for two-byte opcode */
    314 
    315         if (Aml.Opcode > 0x00FF)
    316         {
    317             /* Write the high byte first */
    318 
    319             CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[1], 1);
    320         }
    321 
    322         CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[0], 1);
    323 
    324         /* Subtreelength doesn't include length of package length bytes */
    325 
    326         PkgLen.Len = Op->Asl.AmlSubtreeLength + Op->Asl.AmlPkgLenBytes;
    327         break;
    328     }
    329 
    330     /* Does this opcode have an associated "PackageLength" field? */
    331 
    332     if (Op->Asl.CompileFlags & OP_AML_PACKAGE)
    333     {
    334         if (Op->Asl.AmlPkgLenBytes == 1)
    335         {
    336             /* Simplest case -- no bytes to follow, just write the count */
    337 
    338             CgLocalWriteAmlData (Op, &PkgLen.LenBytes[0], 1);
    339         }
    340         else if (Op->Asl.AmlPkgLenBytes != 0)
    341         {
    342             /*
    343              * Encode the "bytes to follow" in the first byte, top two bits.
    344              * The low-order nybble of the length is in the bottom 4 bits
    345              */
    346             PkgLenFirstByte = (UINT8)
    347                 (((UINT32) (Op->Asl.AmlPkgLenBytes - 1) << 6) |
    348                 (PkgLen.LenBytes[0] & 0x0F));
    349 
    350             CgLocalWriteAmlData (Op, &PkgLenFirstByte, 1);
    351 
    352             /*
    353              * Shift the length over by the 4 bits we just stuffed
    354              * in the first byte
    355              */
    356             PkgLen.Len >>= 4;
    357 
    358             /*
    359              * Now we can write the remaining bytes -
    360              * either 1, 2, or 3 bytes
    361              */
    362             for (i = 0; i < (UINT32) (Op->Asl.AmlPkgLenBytes - 1); i++)
    363             {
    364                 CgLocalWriteAmlData (Op, &PkgLen.LenBytes[i], 1);
    365             }
    366         }
    367     }
    368 
    369     switch (Aml.Opcode)
    370     {
    371     case AML_BYTE_OP:
    372 
    373         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 1);
    374         break;
    375 
    376     case AML_WORD_OP:
    377 
    378         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 2);
    379        break;
    380 
    381     case AML_DWORD_OP:
    382 
    383         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 4);
    384         break;
    385 
    386     case AML_QWORD_OP:
    387 
    388         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 8);
    389         break;
    390 
    391     case AML_STRING_OP:
    392 
    393         CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
    394         break;
    395 
    396     default:
    397 
    398         /* All data opcodes must appear above */
    399 
    400         break;
    401     }
    402 }
    403 
    404 
    405 /*******************************************************************************
    406  *
    407  * FUNCTION:    CgWriteTableHeader
    408  *
    409  * PARAMETERS:  Op        - The DEFINITIONBLOCK node
    410  *
    411  * RETURN:      None
    412  *
    413  * DESCRIPTION: Write a table header corresponding to the DEFINITIONBLOCK
    414  *
    415  * NOTE: Input strings should be validated before this function is invoked.
    416  *
    417  ******************************************************************************/
    418 
    419 static void
    420 CgWriteTableHeader (
    421     ACPI_PARSE_OBJECT       *Op)
    422 {
    423     ACPI_PARSE_OBJECT       *Child;
    424     UINT32                  CommentLength;
    425     ACPI_COMMENT_NODE       *Current;
    426 
    427 
    428     memset (&AslGbl_TableHeader, 0, sizeof (ACPI_TABLE_HEADER));
    429 
    430     /* AML filename */
    431 
    432     Child = Op->Asl.Child;
    433 
    434     /* Signature */
    435 
    436     Child = Child->Asl.Next;
    437 
    438     /*
    439      * For ASL-/ASL+ converter: replace the table signature with
    440      * "XXXX" and save the original table signature. This results in an AML
    441      * file with the signature "XXXX". The converter should remove this AML
    442      * file. In the event where this AML file does not get deleted, the
    443      * "XXXX" table signature prevents this AML file from running on the AML
    444      * interpreter.
    445      */
    446     if (AcpiGbl_CaptureComments)
    447     {
    448         ACPI_COPY_NAMESEG (AcpiGbl_TableSig, Child->Asl.Value.String);
    449         Child->Asl.Value.String = ACPI_SIG_XXXX;
    450     }
    451 
    452     ACPI_COPY_NAMESEG (AslGbl_TableHeader.Signature, Child->Asl.Value.String);
    453 
    454     /* Revision */
    455 
    456     Child = Child->Asl.Next;
    457     AslGbl_TableHeader.Revision = (UINT8) Child->Asl.Value.Integer;
    458 
    459     /* Command-line Revision override */
    460 
    461     if (AslGbl_RevisionOverride)
    462     {
    463         AslGbl_TableHeader.Revision = AslGbl_RevisionOverride;
    464     }
    465 
    466     /* OEMID */
    467 
    468     Child = Child->Asl.Next;
    469     memcpy (AslGbl_TableHeader.OemId, Child->Asl.Value.String,
    470         strlen (Child->Asl.Value.String));
    471 
    472     /* OEM TableID */
    473 
    474     Child = Child->Asl.Next;
    475     memcpy (AslGbl_TableHeader.OemTableId, Child->Asl.Value.String,
    476         strlen (Child->Asl.Value.String));
    477 
    478     /* OEM Revision */
    479 
    480     Child = Child->Asl.Next;
    481     AslGbl_TableHeader.OemRevision = (UINT32) Child->Asl.Value.Integer;
    482 
    483     /* Compiler ID */
    484 
    485     ACPI_COPY_NAMESEG (AslGbl_TableHeader.AslCompilerId, ASL_CREATOR_ID);
    486 
    487     /* Compiler version */
    488 
    489     AslGbl_TableHeader.AslCompilerRevision = ACPI_CA_VERSION;
    490 
    491     /* Table length. Checksum zero for now, will rewrite later */
    492 
    493     AslGbl_TableHeader.Length = sizeof (ACPI_TABLE_HEADER) +
    494         Op->Asl.AmlSubtreeLength;
    495 
    496     /* Calculate the comment lengths for this definition block parseOp */
    497 
    498     if (AcpiGbl_CaptureComments)
    499     {
    500         CvDbgPrint ("Calculating comment lengths for %s in write header\n",
    501             Op->Asl.ParseOpName);
    502 
    503         /*
    504          * Take the filename without extensions, add 3 for the new extension
    505          * and another 3 for the a908 bytecode and null terminator.
    506          */
    507         AslGbl_TableHeader.Length += strrchr (AslGbl_ParseTreeRoot->Asl.Filename, '.')
    508             - AslGbl_ParseTreeRoot->Asl.Filename + 1 + 3 + 3;
    509 
    510         Op->Asl.AmlSubtreeLength +=
    511             strlen (AslGbl_ParseTreeRoot->Asl.Filename) + 3;
    512 
    513         CvDbgPrint ("     Length: %u\n",
    514             (UINT32) strlen (AslGbl_ParseTreeRoot->Asl.Filename) + 3);
    515 
    516         if (Op->Asl.CommentList)
    517         {
    518             Current = Op->Asl.CommentList;
    519             while (Current)
    520             {
    521                 CommentLength = strlen (Current->Comment)+3;
    522                 CvDbgPrint ("Length of standard comment): %d\n", CommentLength);
    523                 CvDbgPrint ("    Comment string: %s\n\n", Current->Comment);
    524                 AslGbl_TableHeader.Length += CommentLength;
    525                 Op->Asl.AmlSubtreeLength += CommentLength;
    526                 Current = Current->Next;
    527                 CvDbgPrint ("    Length: %u\n", CommentLength);
    528             }
    529         }
    530         if (Op->Asl.CloseBraceComment)
    531         {
    532             CommentLength = strlen (Op->Asl.CloseBraceComment)+3;
    533             CvDbgPrint ("Length of inline comment +3: %d\n", CommentLength);
    534             CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.CloseBraceComment);
    535             AslGbl_TableHeader.Length += CommentLength;
    536             Op->Asl.AmlSubtreeLength += CommentLength;
    537             CvDbgPrint ("    Length: %u\n", CommentLength);
    538         }
    539     }
    540 
    541     AslGbl_TableHeader.Checksum = 0;
    542     Op->Asl.FinalAmlOffset = ftell (AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle);
    543 
    544     /* Write entire header and clear the table header global */
    545 
    546     CgLocalWriteAmlData (Op, &AslGbl_TableHeader, sizeof (ACPI_TABLE_HEADER));
    547     memset (&AslGbl_TableHeader, 0, sizeof (ACPI_TABLE_HEADER));
    548 }
    549 
    550 
    551 /*******************************************************************************
    552  *
    553  * FUNCTION:    CgUpdateHeader
    554  *
    555  * PARAMETERS:  Op                  - Op for the Definition Block
    556  *
    557  * RETURN:      None.
    558  *
    559  * DESCRIPTION: Complete the ACPI table by calculating the checksum and
    560  *              re-writing the header for the input definition block
    561  *
    562  ******************************************************************************/
    563 
    564 static void
    565 CgUpdateHeader (
    566     ACPI_PARSE_OBJECT       *Op)
    567 {
    568     signed char             Sum;
    569     UINT32                  i;
    570     UINT32                  Length;
    571     UINT8                   FileByte;
    572     UINT8                   Checksum;
    573 
    574 
    575     /* Calculate the checksum over the entire definition block */
    576 
    577     Sum = 0;
    578     Length = sizeof (ACPI_TABLE_HEADER) + Op->Asl.AmlSubtreeLength;
    579     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset);
    580 
    581     for (i = 0; i < Length; i++)
    582     {
    583         if (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1) != AE_OK)
    584         {
    585             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL,
    586                 "Table length is greater than size of the input file");
    587             return;
    588         }
    589 
    590         Sum = (signed char) (Sum + FileByte);
    591     }
    592 
    593     Checksum = (UINT8) (0 - Sum);
    594 
    595     /* Re-write the the checksum byte */
    596 
    597     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset +
    598         ACPI_OFFSET (ACPI_TABLE_HEADER, Checksum));
    599 
    600     FlWriteFile (ASL_FILE_AML_OUTPUT, &Checksum, 1);
    601 
    602     /*
    603      * Seek to the end of the file. This is done to support multiple file
    604      * compilation. Doing this simplifies other parts of the codebase because
    605      * it eliminates the need to seek for a different starting place.
    606      */
    607     FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset + Length);
    608 }
    609 
    610 
    611 /*******************************************************************************
    612  *
    613  * FUNCTION:    CgWriteNode
    614  *
    615  * PARAMETERS:  Op            - Parse node to write.
    616  *
    617  * RETURN:      None.
    618  *
    619  * DESCRIPTION: Write the AML that corresponds to a parse node.
    620  *
    621  ******************************************************************************/
    622 
    623 static void
    624 CgWriteNode (
    625     ACPI_PARSE_OBJECT       *Op)
    626 {
    627     ASL_RESOURCE_NODE       *Rnode;
    628 
    629 
    630     /* Write all comments here. */
    631 
    632     if (AcpiGbl_CaptureComments)
    633     {
    634         CgWriteAmlComment(Op);
    635     }
    636 
    637     /* Always check for DEFAULT_ARG and other "Noop" nodes */
    638     /* TBD: this may not be the best place for this check */
    639 
    640     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)  ||
    641         (Op->Asl.ParseOpcode == PARSEOP_INCLUDE)      ||
    642         (Op->Asl.ParseOpcode == PARSEOP_INCLUDE_END))
    643     {
    644         return;
    645     }
    646 
    647     Op->Asl.FinalAmlLength = 0;
    648 
    649     switch (Op->Asl.AmlOpcode)
    650     {
    651     case AML_RAW_DATA_BYTE:
    652     case AML_RAW_DATA_WORD:
    653     case AML_RAW_DATA_DWORD:
    654     case AML_RAW_DATA_QWORD:
    655 
    656         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, Op->Asl.AmlLength);
    657         return;
    658 
    659 
    660     case AML_RAW_DATA_BUFFER:
    661 
    662         CgLocalWriteAmlData (Op, Op->Asl.Value.Buffer, Op->Asl.AmlLength);
    663         return;
    664 
    665 
    666     case AML_RAW_DATA_CHAIN:
    667 
    668         Rnode = ACPI_CAST_PTR (ASL_RESOURCE_NODE, Op->Asl.Value.Buffer);
    669         while (Rnode)
    670         {
    671             CgLocalWriteAmlData (Op, Rnode->Buffer, Rnode->BufferLength);
    672             Rnode = Rnode->Next;
    673         }
    674         return;
    675 
    676     default:
    677 
    678         /* Internal data opcodes must all appear above */
    679 
    680         break;
    681     }
    682 
    683     switch (Op->Asl.ParseOpcode)
    684     {
    685     case PARSEOP_DEFAULT_ARG:
    686 
    687         break;
    688 
    689     case PARSEOP_DEFINITION_BLOCK:
    690 
    691         CgWriteTableHeader (Op);
    692         if (AcpiGbl_CaptureComments)
    693         {
    694             CgWriteAmlDefBlockComment (Op);
    695         }
    696         break;
    697 
    698     case PARSEOP_NAMESEG:
    699     case PARSEOP_NAMESTRING:
    700     case PARSEOP_METHODCALL:
    701 
    702         CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
    703         break;
    704 
    705     default:
    706 
    707         CgWriteAmlOpcode (Op);
    708         break;
    709     }
    710 }
    711