Blame source/compiler/aslcodegen.c

Packit Service 1fb00e
/******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * Module Name: aslcodegen - AML code generation
Packit Service 1fb00e
 *
Packit Service 1fb00e
 *****************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
/*
Packit Service 1fb00e
 * Copyright (C) 2000 - 2018, Intel Corp.
Packit Service 1fb00e
 * All rights reserved.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * Redistribution and use in source and binary forms, with or without
Packit Service 1fb00e
 * modification, are permitted provided that the following conditions
Packit Service 1fb00e
 * are met:
Packit Service 1fb00e
 * 1. Redistributions of source code must retain the above copyright
Packit Service 1fb00e
 *    notice, this list of conditions, and the following disclaimer,
Packit Service 1fb00e
 *    without modification.
Packit Service 1fb00e
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
Packit Service 1fb00e
 *    substantially similar to the "NO WARRANTY" disclaimer below
Packit Service 1fb00e
 *    ("Disclaimer") and any redistribution must be conditioned upon
Packit Service 1fb00e
 *    including a substantially similar Disclaimer requirement for further
Packit Service 1fb00e
 *    binary redistribution.
Packit Service 1fb00e
 * 3. Neither the names of the above-listed copyright holders nor the names
Packit Service 1fb00e
 *    of any contributors may be used to endorse or promote products derived
Packit Service 1fb00e
 *    from this software without specific prior written permission.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * Alternatively, this software may be distributed under the terms of the
Packit Service 1fb00e
 * GNU General Public License ("GPL") version 2 as published by the Free
Packit Service 1fb00e
 * Software Foundation.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * NO WARRANTY
Packit Service 1fb00e
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 1fb00e
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 1fb00e
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
Packit Service 1fb00e
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit Service 1fb00e
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 1fb00e
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit Service 1fb00e
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit Service 1fb00e
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
Packit Service 1fb00e
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
Packit Service 1fb00e
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit Service 1fb00e
 * POSSIBILITY OF SUCH DAMAGES.
Packit Service 1fb00e
 */
Packit Service 1fb00e
Packit Service 1fb00e
#include "aslcompiler.h"
Packit Service 1fb00e
#include "aslcompiler.y.h"
Packit Service 1fb00e
#include "amlcode.h"
Packit Service 1fb00e
#include "acconvert.h"
Packit Service 1fb00e
Packit Service 1fb00e
#define _COMPONENT          ACPI_COMPILER
Packit Service 1fb00e
        ACPI_MODULE_NAME    ("aslcodegen")
Packit Service 1fb00e
Packit Service 1fb00e
/* Local prototypes */
Packit Service 1fb00e
Packit Service 1fb00e
static ACPI_STATUS
Packit Service 1fb00e
CgAmlWriteWalk (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op,
Packit Service 1fb00e
    UINT32                  Level,
Packit Service 1fb00e
    void                    *Context);
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgWriteAmlOpcode (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op);
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgWriteTableHeader (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op);
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgCloseTable (
Packit Service 1fb00e
    void);
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgWriteNode (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op);
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgGenerateAmlOutput
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  None.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Generate AML code. Currently generates the listing file
Packit Service 1fb00e
 *              simultaneously.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
void
Packit Service 1fb00e
CgGenerateAmlOutput (
Packit Service 1fb00e
    void)
Packit Service 1fb00e
{
Packit Service 1fb00e
Packit Service 1fb00e
    /* Generate the AML output file */
Packit Service 1fb00e
Packit Service 1fb00e
    FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
Packit Service 1fb00e
    Gbl_SourceLine = 0;
Packit Service 1fb00e
    Gbl_NextError = Gbl_ErrorLog;
Packit Service 1fb00e
Packit Service 1fb00e
    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
Packit Service 1fb00e
        CgAmlWriteWalk, NULL, NULL);
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_HEADER2);
Packit Service 1fb00e
    CgCloseTable ();
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgAmlWriteWalk
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  ASL_WALK_CALLBACK
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      Status
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Parse tree walk to generate the AML code.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static ACPI_STATUS
Packit Service 1fb00e
CgAmlWriteWalk (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op,
Packit Service 1fb00e
    UINT32                  Level,
Packit Service 1fb00e
    void                    *Context)
Packit Service 1fb00e
{
Packit Service 1fb00e
Packit Service 1fb00e
    /* Generate the AML for this node */
Packit Service 1fb00e
Packit Service 1fb00e
    CgWriteNode (Op);
Packit Service 1fb00e
Packit Service 1fb00e
    if (!Gbl_DebugFlag)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        return (AE_OK);
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    /* Print header at level 0. Alignment assumes 32-bit pointers */
Packit Service 1fb00e
Packit Service 1fb00e
    if (!Level)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        DbgPrint (ASL_TREE_OUTPUT,
Packit Service 1fb00e
            "\nFinal parse tree used for AML output:\n");
Packit Service 1fb00e
        DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_HEADER2);
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    /* Dump ParseOp name and possible value */
Packit Service 1fb00e
Packit Service 1fb00e
    switch (Op->Asl.ParseOpcode)
Packit Service 1fb00e
    {
Packit Service 1fb00e
    case PARSEOP_NAMESEG:
Packit Service 1fb00e
    case PARSEOP_NAMESTRING:
Packit Service 1fb00e
    case PARSEOP_METHODCALL:
Packit Service 1fb00e
    case PARSEOP_STRING_LITERAL:
Packit Service 1fb00e
Packit Service 1fb00e
        UtDumpStringOp (Op, Level);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    default:
Packit Service 1fb00e
Packit Service 1fb00e
        UtDumpBasicOp (Op, Level);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_TREE_OUTPUT, ASL_PARSE_TREE_DEBUG2,
Packit Service 1fb00e
        /* 1  */ (UINT32) Op->Asl.Value.Integer,
Packit Service 1fb00e
        /* 2  */ Op->Asl.ParseOpcode,
Packit Service 1fb00e
        /* 3  */ Op->Asl.AmlOpcode,
Packit Service 1fb00e
        /* 4  */ Op->Asl.AmlOpcodeLength,
Packit Service 1fb00e
        /* 5  */ Op->Asl.AmlPkgLenBytes,
Packit Service 1fb00e
        /* 6  */ Op->Asl.AmlLength,
Packit Service 1fb00e
        /* 7  */ Op->Asl.AmlSubtreeLength,
Packit Service 1fb00e
        /* 8  */ Op->Asl.Parent ? Op->Asl.Parent->Asl.AmlSubtreeLength : 0,
Packit Service 1fb00e
        /* 9  */ Op,
Packit Service 1fb00e
        /* 10 */ Op->Asl.Parent,
Packit Service 1fb00e
        /* 11 */ Op->Asl.Child,
Packit Service 1fb00e
        /* 12 */ Op->Asl.Next,
Packit Service 1fb00e
        /* 13 */ Op->Asl.CompileFlags,
Packit Service 1fb00e
        /* 14 */ Op->Asl.AcpiBtype,
Packit Service 1fb00e
        /* 15 */ Op->Asl.FinalAmlLength,
Packit Service 1fb00e
        /* 16 */ Op->Asl.Column,
Packit Service 1fb00e
        /* 17 */ Op->Asl.LineNumber,
Packit Service 1fb00e
        /* 18 */ Op->Asl.EndLine,
Packit Service 1fb00e
        /* 19 */ Op->Asl.LogicalLineNumber,
Packit Service 1fb00e
        /* 20 */ Op->Asl.EndLogicalLine);
Packit Service 1fb00e
Packit Service 1fb00e
    TrPrintOpFlags (Op->Asl.CompileFlags, ASL_TREE_OUTPUT);
Packit Service 1fb00e
    DbgPrint (ASL_TREE_OUTPUT, "\n");
Packit Service 1fb00e
    return (AE_OK);
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgLocalWriteAmlData
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Op              - Current parse op
Packit Service 1fb00e
 *              Buffer          - Buffer to write
Packit Service 1fb00e
 *              Length          - Size of data in buffer
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Write a buffer of AML data to the AML output file.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
void
Packit Service 1fb00e
CgLocalWriteAmlData (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op,
Packit Service 1fb00e
    void                    *Buffer,
Packit Service 1fb00e
    UINT32                  Length)
Packit Service 1fb00e
{
Packit Service 1fb00e
Packit Service 1fb00e
    /* Write the raw data to the AML file */
Packit Service 1fb00e
Packit Service 1fb00e
    FlWriteFile (ASL_FILE_AML_OUTPUT, Buffer, Length);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Update the final AML length for this node (used for listings) */
Packit Service 1fb00e
Packit Service 1fb00e
    if (Op)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        Op->Asl.FinalAmlLength += Length;
Packit Service 1fb00e
    }
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgWriteAmlOpcode
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Op            - Parse node with an AML opcode
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Write the AML opcode corresponding to a parse node.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgWriteAmlOpcode (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op)
Packit Service 1fb00e
{
Packit Service 1fb00e
    UINT8                   PkgLenFirstByte;
Packit Service 0129ce
    UINT8                   Byte;
Packit Service 0129ce
    UINT16                  Word;
Packit Service 0129ce
    UINT32                  DWord;
Packit Service 0129ce
    UINT64                  QWord;
Packit Service 0129ce
    UINT16                  AmlOpcode;
Packit Service 0129ce
    UINT32                  PkgLen;
Packit Service 1fb00e
Packit Service 1fb00e
    /* We expect some DEFAULT_ARGs, just ignore them */
Packit Service 1fb00e
Packit Service 1fb00e
    if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        return;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    /*
Packit Service 1fb00e
     * Before printing the bytecode, generate comment byte codes
Packit Service 1fb00e
     * associated with this node.
Packit Service 1fb00e
     */
Packit Service 1fb00e
    if (AcpiGbl_CaptureComments)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        CgWriteAmlComment(Op);
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    switch (Op->Asl.AmlOpcode)
Packit Service 1fb00e
    {
Packit Service 1fb00e
    case AML_UNASSIGNED_OPCODE:
Packit Service 1fb00e
Packit Service 1fb00e
        /* These opcodes should not get here */
Packit Service 1fb00e
Packit Service 1fb00e
        printf ("Found a node with an unassigned AML opcode\n");
Packit Service 1fb00e
        FlPrintFile (ASL_FILE_STDERR,
Packit Service 1fb00e
            "Found a node with an unassigned AML opcode\n");
Packit Service 1fb00e
        return;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_INT_RESERVEDFIELD_OP:
Packit Service 1fb00e
Packit Service 1fb00e
        /* Special opcodes for within a field definition */
Packit Service 1fb00e
Packit Service 0129ce
        AmlOpcode = AML_FIELD_OFFSET_OP;
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_INT_ACCESSFIELD_OP:
Packit Service 1fb00e
Packit Service 0129ce
        AmlOpcode = AML_FIELD_ACCESS_OP;
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_INT_CONNECTION_OP:
Packit Service 1fb00e
Packit Service 0129ce
        AmlOpcode = AML_FIELD_CONNECTION_OP;
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    default:
Packit Service 1fb00e
Packit Service 0129ce
        AmlOpcode = Op->Asl.AmlOpcode;
Packit Service 1fb00e
        break;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 0129ce
    switch (AmlOpcode)
Packit Service 1fb00e
    {
Packit Service 1fb00e
    case AML_PACKAGE_LENGTH:
Packit Service 1fb00e
Packit Service 1fb00e
        /* Value is the length to be encoded (Used in field definitions) */
Packit Service 1fb00e
Packit Service 0129ce
        PkgLen = (UINT32) Op->Asl.Value.Integer;
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    default:
Packit Service 1fb00e
Packit Service 1fb00e
        /* Check for two-byte opcode */
Packit Service 1fb00e
Packit Service 0129ce
        if (AmlOpcode > 0x00FF)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            /* Write the high byte first */
Packit Service 0129ce
	    Byte = ACPI_HIBYTE(AmlOpcode);
Packit Service 0129ce
	    CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 1fb00e
        }
Packit Service 1fb00e
Packit Service 0129ce
	Byte = ACPI_LOBYTE(AmlOpcode);
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 1fb00e
Packit Service 1fb00e
        /* Subtreelength doesn't include length of package length bytes */
Packit Service 1fb00e
Packit Service 0129ce
        PkgLen = Op->Asl.AmlSubtreeLength + Op->Asl.AmlPkgLenBytes;
Packit Service 1fb00e
        break;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    /* Does this opcode have an associated "PackageLength" field? */
Packit Service 1fb00e
Packit Service 1fb00e
    if (Op->Asl.CompileFlags & OP_AML_PACKAGE)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        if (Op->Asl.AmlPkgLenBytes == 1)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            /* Simplest case -- no bytes to follow, just write the count */
Packit Service 0129ce
            Byte = ACPI_LOBYTE(PkgLen);
Packit Service 0129ce
            CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 1fb00e
        }
Packit Service 1fb00e
        else if (Op->Asl.AmlPkgLenBytes != 0)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            /*
Packit Service 1fb00e
             * Encode the "bytes to follow" in the first byte, top two bits.
Packit Service 1fb00e
             * The low-order nybble of the length is in the bottom 4 bits
Packit Service 1fb00e
             */
Packit Service 1fb00e
            PkgLenFirstByte = (UINT8)
Packit Service 1fb00e
                (((UINT32) (Op->Asl.AmlPkgLenBytes - 1) << 6) |
Packit Service 0129ce
                (PkgLen & 0x0F));
Packit Service 1fb00e
Packit Service 1fb00e
            CgLocalWriteAmlData (Op, &PkgLenFirstByte, 1);
Packit Service 1fb00e
Packit Service 1fb00e
            /*
Packit Service 1fb00e
             * Shift the length over by the 4 bits we just stuffed
Packit Service 1fb00e
             * in the first byte
Packit Service 1fb00e
             */
Packit Service 0129ce
            PkgLen >>= 4;
Packit Service 1fb00e
Packit Service 1fb00e
            /*
Packit Service 1fb00e
             * Now we can write the remaining bytes -
Packit Service 1fb00e
             * either 1, 2, or 3 bytes
Packit Service 1fb00e
             */
Packit Service 0129ce
            Byte = ACPI_LOBYTE(PkgLen);
Packit Service 0129ce
            CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 0129ce
            if (Op->Asl.AmlPkgLenBytes >= 3)
Packit Service 0129ce
            {
Packit Service 0129ce
                Byte = ACPI_HIBYTE(PkgLen);
Packit Service 0129ce
                CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 0129ce
            }
Packit Service 0129ce
            if (Op->Asl.AmlPkgLenBytes >= 4)
Packit Service 1fb00e
            {
Packit Service 0129ce
                Byte = ACPI_LOBYTE(ACPI_HIWORD(PkgLen));
Packit Service 0129ce
                CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 1fb00e
            }
Packit Service 1fb00e
        }
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 0129ce
    switch (AmlOpcode)
Packit Service 1fb00e
    {
Packit Service 1fb00e
    case AML_BYTE_OP:
Packit Service 0129ce
        Byte = (UINT8) Op->Asl.Value.Integer;
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_WORD_OP:
Packit Service 0129ce
        ACPI_MOVE_64_TO_16(&Word, &Op->Asl.Value.Integer);
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &Word, 2);
Packit Service 1fb00e
       break;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_DWORD_OP:
Packit Service 0129ce
        ACPI_MOVE_64_TO_32(&DWord, &Op->Asl.Value.Integer);
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &DWord, 4);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_QWORD_OP:
Packit Service 0129ce
        ACPI_MOVE_64_TO_64(&QWord, &Op->Asl.Value.Integer);
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &QWord, 8);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_STRING_OP:
Packit Service 1fb00e
Packit Service 1fb00e
        CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    default:
Packit Service 1fb00e
Packit Service 1fb00e
        /* All data opcodes must appear above */
Packit Service 1fb00e
Packit Service 1fb00e
        break;
Packit Service 1fb00e
    }
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgWriteTableHeader
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Op        - The DEFINITIONBLOCK node
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Write a table header corresponding to the DEFINITIONBLOCK
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgWriteTableHeader (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op)
Packit Service 1fb00e
{
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Child;
Packit Service 0129ce
    UINT32                  DWord;
Packit Service 1fb00e
    UINT32                  CommentLength;
Packit Service 1fb00e
    ACPI_COMMENT_NODE       *Current;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    /* AML filename */
Packit Service 1fb00e
Packit Service 1fb00e
    Child = Op->Asl.Child;
Packit Service 1fb00e
Packit Service 1fb00e
    /* Signature */
Packit Service 1fb00e
Packit Service 1fb00e
    Child = Child->Asl.Next;
Packit Service 1fb00e
Packit Service 1fb00e
    /*
Packit Service 1fb00e
     * For ASL-/ASL+ converter: replace the table signature with
Packit Service 1fb00e
     * "XXXX" and save the original table signature. This results in an AML
Packit Service 1fb00e
     * file with the signature "XXXX". The converter should remove this AML
Packit Service 1fb00e
     * file. In the event where this AML file does not get deleted, the
Packit Service 1fb00e
     * "XXXX" table signature prevents this AML file from running on the AML
Packit Service 1fb00e
     * interpreter.
Packit Service 1fb00e
     */
Packit Service 1fb00e
    if (AcpiGbl_CaptureComments)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        strncpy(AcpiGbl_TableSig, Child->Asl.Value.String, ACPI_NAME_SIZE);
Packit Service 1fb00e
        Child->Asl.Value.String = ACPI_SIG_XXXX;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    strncpy (TableHeader.Signature, Child->Asl.Value.String, ACPI_NAME_SIZE);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Revision */
Packit Service 1fb00e
Packit Service 1fb00e
    Child = Child->Asl.Next;
Packit Service 1fb00e
    TableHeader.Revision = (UINT8) Child->Asl.Value.Integer;
Packit Service 1fb00e
Packit Service 1fb00e
    /* Command-line Revision override */
Packit Service 1fb00e
Packit Service 1fb00e
    if (Gbl_RevisionOverride)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        TableHeader.Revision = Gbl_RevisionOverride;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    /* OEMID */
Packit Service 1fb00e
Packit Service 1fb00e
    Child = Child->Asl.Next;
Packit Service 1fb00e
    strncpy (TableHeader.OemId, Child->Asl.Value.String, ACPI_OEM_ID_SIZE);
Packit Service 1fb00e
Packit Service 1fb00e
    /* OEM TableID */
Packit Service 1fb00e
Packit Service 1fb00e
    Child = Child->Asl.Next;
Packit Service 1fb00e
    strncpy (TableHeader.OemTableId, Child->Asl.Value.String, ACPI_OEM_TABLE_ID_SIZE);
Packit Service 1fb00e
Packit Service 1fb00e
    /* OEM Revision */
Packit Service 1fb00e
Packit Service 1fb00e
    Child = Child->Asl.Next;
Packit Service 0129ce
    ACPI_MOVE_64_TO_32(&TableHeader.OemRevision, &Child->Asl.Value.Integer);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Compiler ID */
Packit Service 1fb00e
Packit Service 1fb00e
    ACPI_MOVE_NAME (TableHeader.AslCompilerId, ASL_CREATOR_ID);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Compiler version */
Packit Service 1fb00e
Packit Service 0129ce
    DWord = ACPI_CA_VERSION;
Packit Service 0129ce
    ACPI_MOVE_32_TO_32(&TableHeader.AslCompilerRevision, &DWord);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Table length. Checksum zero for now, will rewrite later */
Packit Service 1fb00e
Packit Service aa01ce
    TableHeader.Length = sizeof (ACPI_TABLE_HEADER) + Op->Asl.AmlSubtreeLength;
Packit Service 1fb00e
Packit Service 1fb00e
    /* Calculate the comment lengths for this definition block parseOp */
Packit Service 1fb00e
Packit Service 1fb00e
    if (AcpiGbl_CaptureComments)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        CvDbgPrint ("Calculating comment lengths for %s in write header\n",
Packit Service 1fb00e
            Op->Asl.ParseOpName);
Packit Service 1fb00e
Packit Service 1fb00e
        /*
Packit Service 1fb00e
         * Take the filename without extensions, add 3 for the new extension
Packit Service 1fb00e
         * and another 3 for the a908 bytecode and null terminator.
Packit Service 1fb00e
         */
Packit Service 1fb00e
        TableHeader.Length += strrchr (Gbl_ParseTreeRoot->Asl.Filename, '.')
Packit Service 1fb00e
            - Gbl_ParseTreeRoot->Asl.Filename + 1 + 3 + 3;
Packit Service 1fb00e
        Op->Asl.AmlSubtreeLength +=
Packit Service 1fb00e
            strlen (Gbl_ParseTreeRoot->Asl.Filename) + 3;
Packit Service 1fb00e
    CvDbgPrint ("     Length: %lu\n",
Packit Service 1fb00e
            strlen (Gbl_ParseTreeRoot->Asl.Filename) + 3);
Packit Service 1fb00e
Packit Service 1fb00e
        if (Op->Asl.CommentList)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            Current = Op->Asl.CommentList;
Packit Service 1fb00e
            while (Current)
Packit Service 1fb00e
            {
Packit Service 1fb00e
                CommentLength = strlen (Current->Comment)+3;
Packit Service 1fb00e
                CvDbgPrint ("Length of standard comment): %d\n", CommentLength);
Packit Service 1fb00e
                CvDbgPrint ("    Comment string: %s\n\n", Current->Comment);
Packit Service 1fb00e
                TableHeader.Length += CommentLength;
Packit Service 1fb00e
                Op->Asl.AmlSubtreeLength += CommentLength;
Packit Service 1fb00e
                Current = Current->Next;
Packit Service 1fb00e
            CvDbgPrint ("    Length: %u\n", CommentLength);
Packit Service 1fb00e
            }
Packit Service 1fb00e
        }
Packit Service 1fb00e
        if (Op->Asl.CloseBraceComment)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            CommentLength = strlen (Op->Asl.CloseBraceComment)+3;
Packit Service 1fb00e
            CvDbgPrint ("Length of inline comment +3: %d\n", CommentLength);
Packit Service 1fb00e
            CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.CloseBraceComment);
Packit Service 1fb00e
            TableHeader.Length += CommentLength;
Packit Service 1fb00e
            Op->Asl.AmlSubtreeLength += CommentLength;
Packit Service 1fb00e
        CvDbgPrint ("    Length: %u\n", CommentLength);
Packit Service 1fb00e
        }
Packit Service 1fb00e
    }
Packit Service aa01ce
    DWord = TableHeader.Length;
Packit Service aa01ce
    ACPI_MOVE_32_TO_32(&TableHeader.Length, &DWord);
Packit Service 1fb00e
Packit Service 1fb00e
    TableHeader.Checksum = 0;
Packit Service 1fb00e
Packit Service 1fb00e
    Op->Asl.FinalAmlOffset = ftell (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Write entire header and clear the table header global */
Packit Service 1fb00e
Packit Service 1fb00e
    CgLocalWriteAmlData (Op, &TableHeader, sizeof (ACPI_TABLE_HEADER));
Packit Service 1fb00e
    memset (&TableHeader, 0, sizeof (ACPI_TABLE_HEADER));
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgUpdateHeader
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Op                  - Op for the Definition Block
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Complete the ACPI table by calculating the checksum and
Packit Service 1fb00e
 *              re-writing the header for the input definition block
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgUpdateHeader (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op)
Packit Service 1fb00e
{
Packit Service 1fb00e
    signed char             Sum;
Packit Service 1fb00e
    UINT32                  i;
Packit Service 1fb00e
    UINT32                  Length;
Packit Service 1fb00e
    UINT8                   FileByte;
Packit Service 1fb00e
    UINT8                   Checksum;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    /* Calculate the checksum over the entire definition block */
Packit Service 1fb00e
Packit Service 1fb00e
    Sum = 0;
Packit Service 1fb00e
    Length = sizeof (ACPI_TABLE_HEADER) + Op->Asl.AmlSubtreeLength;
Packit Service 1fb00e
    FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset);
Packit Service 1fb00e
Packit Service 1fb00e
    for (i = 0; i < Length; i++)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        if (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1) != AE_OK)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            printf ("EOF while reading checksum bytes\n");
Packit Service 1fb00e
            return;
Packit Service 1fb00e
        }
Packit Service 1fb00e
Packit Service 1fb00e
        Sum = (signed char) (Sum + FileByte);
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    Checksum = (UINT8) (0 - Sum);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Re-write the the checksum byte */
Packit Service 1fb00e
Packit Service 1fb00e
    FlSeekFile (ASL_FILE_AML_OUTPUT, Op->Asl.FinalAmlOffset +
Packit Service 1fb00e
        ACPI_OFFSET (ACPI_TABLE_HEADER, Checksum));
Packit Service 1fb00e
Packit Service 1fb00e
    FlWriteFile (ASL_FILE_AML_OUTPUT, &Checksum, 1);
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgCloseTable
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  None.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Complete the ACPI table by calculating the checksum and
Packit Service 1fb00e
 *              re-writing each table header. This allows support for
Packit Service 1fb00e
 *              multiple definition blocks in a single source file.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgCloseTable (
Packit Service 1fb00e
    void)
Packit Service 1fb00e
{
Packit Service 1fb00e
    ACPI_PARSE_OBJECT   *Op;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    /* Process all definition blocks */
Packit Service 1fb00e
Packit Service 1fb00e
    Op = Gbl_ParseTreeRoot->Asl.Child;
Packit Service 1fb00e
    while (Op)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        CgUpdateHeader (Op);
Packit Service 1fb00e
        Op = Op->Asl.Next;
Packit Service 1fb00e
    }
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/*******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    CgWriteNode
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Op            - Parse node to write.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Write the AML that corresponds to a parse node.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 ******************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
CgWriteNode (
Packit Service 1fb00e
    ACPI_PARSE_OBJECT       *Op)
Packit Service 1fb00e
{
Packit Service 1fb00e
    ASL_RESOURCE_NODE       *Rnode;
Packit Service 0129ce
    UINT8                   Byte;
Packit Service 0129ce
    UINT16                  Word;
Packit Service 0129ce
    UINT32                  DWord;
Packit Service 0129ce
    UINT64                  QWord;
Packit Service 1fb00e
Packit Service 1fb00e
    /* Write all comments here. */
Packit Service 1fb00e
Packit Service 1fb00e
    if (AcpiGbl_CaptureComments)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        CgWriteAmlComment(Op);
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    /* Always check for DEFAULT_ARG and other "Noop" nodes */
Packit Service 1fb00e
    /* TBD: this may not be the best place for this check */
Packit Service 1fb00e
Packit Service 1fb00e
    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)  ||
Packit Service 1fb00e
        (Op->Asl.ParseOpcode == PARSEOP_INCLUDE)      ||
Packit Service 1fb00e
        (Op->Asl.ParseOpcode == PARSEOP_INCLUDE_END))
Packit Service 1fb00e
    {
Packit Service 1fb00e
        return;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    if ((Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
Packit Service 1fb00e
        Gbl_DoExternals == FALSE)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        return;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    Op->Asl.FinalAmlLength = 0;
Packit Service 1fb00e
Packit Service 1fb00e
    switch (Op->Asl.AmlOpcode)
Packit Service 1fb00e
    {
Packit Service 1fb00e
    case AML_RAW_DATA_BYTE:
Packit Service 0129ce
        Byte = (UINT8) Op->Asl.Value.Integer;
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &Byte, 1);
Packit Service 0129ce
        return;
Packit Service 0129ce
Packit Service 1fb00e
    case AML_RAW_DATA_WORD:
Packit Service 0129ce
        ACPI_MOVE_64_TO_16(&Word, &Op->Asl.Value.Integer);
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &Word, 2);
Packit Service 0129ce
        return;
Packit Service 1fb00e
Packit Service 0129ce
    case AML_RAW_DATA_DWORD:
Packit Service 0129ce
        ACPI_MOVE_64_TO_32(&DWord, &Op->Asl.Value.Integer);
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &DWord, 4);
Packit Service 1fb00e
        return;
Packit Service 1fb00e
Packit Service 0129ce
    case AML_RAW_DATA_QWORD:
Packit Service 0129ce
        ACPI_MOVE_64_TO_64(&QWord, &Op->Asl.Value.Integer);
Packit Service 0129ce
        CgLocalWriteAmlData (Op, &QWord, 8);
Packit Service 0129ce
        return;
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_RAW_DATA_BUFFER:
Packit Service 1fb00e
Packit Service 1fb00e
        CgLocalWriteAmlData (Op, Op->Asl.Value.Buffer, Op->Asl.AmlLength);
Packit Service 1fb00e
        return;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    case AML_RAW_DATA_CHAIN:
Packit Service 1fb00e
Packit Service 1fb00e
        Rnode = ACPI_CAST_PTR (ASL_RESOURCE_NODE, Op->Asl.Value.Buffer);
Packit Service 1fb00e
        while (Rnode)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            CgLocalWriteAmlData (Op, Rnode->Buffer, Rnode->BufferLength);
Packit Service 1fb00e
            Rnode = Rnode->Next;
Packit Service 1fb00e
        }
Packit Service 1fb00e
        return;
Packit Service 1fb00e
Packit Service 1fb00e
    default:
Packit Service 1fb00e
Packit Service 1fb00e
        /* Internal data opcodes must all appear above */
Packit Service 1fb00e
Packit Service 1fb00e
        break;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    switch (Op->Asl.ParseOpcode)
Packit Service 1fb00e
    {
Packit Service 1fb00e
    case PARSEOP_DEFAULT_ARG:
Packit Service 1fb00e
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    case PARSEOP_DEFINITION_BLOCK:
Packit Service 1fb00e
Packit Service 1fb00e
        CgWriteTableHeader (Op);
Packit Service 1fb00e
        if (AcpiGbl_CaptureComments)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            CgWriteAmlDefBlockComment (Op);
Packit Service 1fb00e
        }
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    case PARSEOP_NAMESEG:
Packit Service 1fb00e
    case PARSEOP_NAMESTRING:
Packit Service 1fb00e
    case PARSEOP_METHODCALL:
Packit Service 1fb00e
Packit Service 1fb00e
        CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
Packit Service 1fb00e
    default:
Packit Service 1fb00e
Packit Service 1fb00e
        CgWriteAmlOpcode (Op);
Packit Service 1fb00e
        break;
Packit Service 1fb00e
    }
Packit Service 1fb00e
}