aslopcodes.c revision 199767f8919635c4928607450d9e0abb932109ce
/******************************************************************************
*
* Module Name: aslopcode - AML opcode generation
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "aslcompiler.y.h"
#define _COMPONENT ACPI_COMPILER
ACPI_MODULE_NAME ("aslopcodes")
/* Local prototypes */
static void
static void
static void
static void
static void
OpcDoPld (
static void
static UINT8 *
/* ToPld strings */
static char *AslPldPanelList[] =
{
"TOP",
"BOTTOM",
"LEFT",
"RIGHT",
"FRONT",
"BACK",
"UNKNOWN",
};
static char *AslPldVerticalPositionList[] =
{
"UPPER",
"CENTER",
"LOWER",
};
static char *AslPldHorizontalPositionList[] =
{
"LEFT",
"CENTER",
"RIGHT",
};
static char *AslPldShapeList[] =
{
"ROUND",
"OVAL",
"SQUARE",
"VERTICALRECTANGLE",
"HORIZONTALRECTANGLE",
"VERTICALTRAPEZOID",
"HORIZONTALTRAPEZOID",
"UNKNOWN",
"CHAMFERED",
};
/*******************************************************************************
*
* FUNCTION: OpcAmlOpcodeUpdateWalk
*
* PARAMETERS: ASL_WALK_CALLBACK
*
* RETURN: Status
*
* DESCRIPTION: Opcode update walk, ascending callback
*
******************************************************************************/
void *Context)
{
/*
* Handle the Package() case where the actual opcode cannot be determined
* until the PackageLength operand has been folded and minimized.
* (PackageOp versus VarPackageOp)
*
* This is (as of ACPI 3.0) the only case where the AML opcode can change
* based upon the value of a parameter.
*
* The parser always inserts a VarPackage opcode, which can possibly be
* optimized to a Package opcode.
*/
{
OpnDoPackage (Op);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: OpcAmlOpcodeWalk
*
* PARAMETERS: ASL_WALK_CALLBACK
*
* RETURN: Status
*
* DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
* operands.
*
******************************************************************************/
void *Context)
{
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: OpcGetIntegerWidth
*
* PARAMETERS: Op - DEFINITION BLOCK op
*
* RETURN: none
*
* DESCRIPTION: Extract integer width from the table revision
*
******************************************************************************/
void
{
if (!Op)
{
return;
}
if (Gbl_RevisionOverride)
{
}
else
{
/* Use the revision to set the integer width */
}
}
/*******************************************************************************
*
* FUNCTION: OpcSetOptimalIntegerSize
*
* PARAMETERS: Op - A parse tree node
*
* RETURN: Integer width, in bytes. Also sets the node AML opcode to the
* optimal integer AML prefix opcode.
*
* DESCRIPTION: Determine the optimal AML encoding of an integer. All leading
* zeros can be truncated to squeeze the integer into the
* minimal number of AML bytes.
*
******************************************************************************/
{
#if 0
/*
* TBD: - we don't want to optimize integers in the block header, but the
* code below does not work correctly.
*/
{
return (0);
}
#endif
/*
* Check for the special AML integers first - Zero, One, Ones.
* These are single-byte opcodes that are the smallest possible
* representation of an integer.
*
* This optimization is optional.
*/
{
{
case 0:
Op, "Zero");
return (1);
case 1:
Op, "One");
return (1);
case ACPI_UINT32_MAX:
/* Check for table integer width (32 or 64) */
if (AcpiGbl_IntegerByteWidth == 4)
{
Op, "Ones");
return (1);
}
break;
case ACPI_UINT64_MAX:
/* Check for table integer width (32 or 64) */
if (AcpiGbl_IntegerByteWidth == 8)
{
Op, "Ones");
return (1);
}
break;
default:
break;
}
}
/* Find the best fit using the various AML integer prefixes */
{
return (1);
}
{
return (2);
}
{
return (4);
}
else
{
if (AcpiGbl_IntegerByteWidth == 4)
{
if (!Gbl_IgnoreErrors)
{
/* Truncate the integer to 32-bit */
return (4);
}
}
return (8);
}
}
/*******************************************************************************
*
* FUNCTION: OpcDoAccessAs
*
* PARAMETERS: Op - Parse node
*
* RETURN: None
*
* DESCRIPTION: Implement the ACCESS_AS ASL keyword.
*
******************************************************************************/
static void
{
/* First child is the access type */
/* Second child is the optional access attribute */
{
}
/* Only a few AccessAttributes support AccessLength */
if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) &&
(Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
{
return;
}
/*
* Child of Attributes is the AccessLength (required for Multibyte,
* RawBytes, RawProcess.)
*/
if (!LengthOp)
{
return;
}
/* TBD: probably can remove */
{
}
}
/*******************************************************************************
*
* FUNCTION: OpcDoConnection
*
* PARAMETERS: Op - Parse node
*
* RETURN: None
*
* DESCRIPTION: Implement the Connection ASL keyword.
*
******************************************************************************/
static void
{
{
return;
}
Info.CurrentByteOffset = 0;
if (!Rnode)
{
return; /* error */
}
/*
* Transform the nodes into the following
*
* Op -> AML_BUFFER_OP
* First Child -> BufferLength
* Second Child -> Descriptor Buffer (raw byte data)
*/
(void) OpcSetOptimalIntegerSize (BufferLengthOp);
}
/*******************************************************************************
*
* FUNCTION: OpcDoUnicode
*
* PARAMETERS: Op - Parse node
*
* RETURN: None
*
* DESCRIPTION: Implement the UNICODE ASL "macro". Convert the input string
* to a unicode buffer. There is no Unicode AML opcode.
*
* Note: The Unicode string is 16 bits per character, no leading signature,
* with a 16-bit terminating NULL.
*
******************************************************************************/
static void
{
UINT32 i;
/* Change op into a buffer object */
/* Buffer Length is first, followed by the string */
/* Create a new buffer for the Unicode string */
/* Convert to Unicode string (including null terminator) */
for (i = 0; i < Count; i++)
{
}
/*
* Just set the buffer size node to be the buffer length, regardless
* of whether it was previously an integer or a default_arg placeholder
*/
(void) OpcSetOptimalIntegerSize (BufferLengthOp);
/* The Unicode string is a raw data buffer */
}
/*******************************************************************************
*
* FUNCTION: OpcDoEisaId
*
* PARAMETERS: Op - Parse node
*
* RETURN: None
*
* DESCRIPTION: Convert a string EISA ID to numeric representation. See the
* Pnp BIOS Specification for details. Here is an excerpt:
*
* A seven character ASCII representation of the product
* identifier compressed into a 32-bit identifier. The seven
* character ID consists of a three character manufacturer code,
* a three character hexadecimal product identifier, and a one
* character hexadecimal revision number. The manufacturer code
* is a 3 uppercase character code that is compressed into 3 5-bit
* values as follows:
* 1) Find hex ASCII value for each letter
* 2) Subtract 40h from each ASCII value
* 3) Retain 5 least significant bits for each letter by
* discarding upper 3 bits because they are always 0.
* 4) Compressed code = concatenate 0 and the 3 5-bit values
*
* The format of the compressed product identifier is as follows:
* Byte 0: Bit 7 - Reserved (0)
* Bits 6-2: - 1st character of compressed mfg code
* Bits 1-0 - Upper 2 bits of 2nd character of mfg code
* Byte 1: Bits 7-5 - Lower 3 bits of 2nd character of mfg code
* Bits 4-0 - 3rd character of mfg code
* Byte 2: Bits 7-4 - 1st hex digit of product number
* Bits 3-0 - 2nd hex digit of product number
* Byte 3: Bits 7-4 - 3st hex digit of product number
* Bits 3-0 - Hex digit of the revision number
*
******************************************************************************/
static void
{
char *InString;
UINT32 i;
/*
* The EISAID string must be exactly 7 characters and of the form
* "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
*/
{
}
else
{
/* Check all 7 characters for correct format */
for (i = 0; i < 7; i++)
{
/* First 3 characters must be uppercase letters */
if (i < 3)
{
{
}
}
/* Last 4 characters must be hex digits */
{
}
}
}
if (ACPI_FAILURE (Status))
{
}
else
{
/* Create ID big-endian first (bits are contiguous) */
/* Swap to little-endian to get final ID (see function header) */
}
/*
* Morph the Op into an integer, regardless of whether there
* was an error in the EISAID string
*/
(void) OpcSetOptimalIntegerSize (Op);
/* Op is now an integer */
}
/*******************************************************************************
*
* FUNCTION: OpcEncodePldBuffer
*
* PARAMETERS: PldInfo - _PLD buffer struct (Using local struct)
*
* RETURN: Encode _PLD buffer suitable for return value from _PLD
*
* DESCRIPTION: Bit-packs a _PLD buffer struct.
*
******************************************************************************/
static UINT8 *
{
if (!Buffer)
{
return (NULL);
}
/* First 32 bits */
Dword = 0;
/* Second 32 bits */
Dword = 0;
/* Third 32 bits */
Dword = 0;
/* Fourth 32 bits */
Dword = 0;
{
/* Fifth 32 bits */
Dword = 0;
}
}
/*******************************************************************************
*
* FUNCTION: OpcFindName
*
* PARAMETERS: List - Array of char strings to be searched
* Name - Char string to string for
* Index - Index value to set if found
*
* RETURN: TRUE if any names matched, FALSE otherwise
*
* DESCRIPTION: Match PLD name to value in lookup table. Sets Value to
* equivalent parameter value.
*
******************************************************************************/
static BOOLEAN
char **List,
char *Name,
{
char *Str;
UINT32 i;
AcpiUtStrupr (Name);
{
{
*Index = i;
return (TRUE);
}
}
return (FALSE);
}
/*******************************************************************************
*
* FUNCTION: OpcDoPld
*
* PARAMETERS: Op - Parse node
*
* RETURN: None
*
* DESCRIPTION: Convert ToPLD macro to 20-byte buffer
*
******************************************************************************/
static void
OpcDoPld (
{
if (!Op)
{
return;
}
{
return;
}
while (Node)
{
{
case PARSEOP_PLD_REVISION:
{
break;
}
{
break;
}
break;
case PARSEOP_PLD_IGNORECOLOR:
{
break;
}
{
break;
}
break;
case PARSEOP_PLD_RED:
case PARSEOP_PLD_GREEN:
case PARSEOP_PLD_BLUE:
{
break;
}
{
break;
}
{
}
{
}
else /* PARSEOP_PLD_BLUE */
{
}
break;
case PARSEOP_PLD_WIDTH:
case PARSEOP_PLD_HEIGHT:
{
break;
}
{
break;
}
{
}
else /* PARSEOP_PLD_HEIGHT */
{
}
break;
case PARSEOP_PLD_USERVISIBLE:
case PARSEOP_PLD_DOCK:
case PARSEOP_PLD_LID:
{
break;
}
{
break;
}
{
}
{
}
else
{
}
break;
case PARSEOP_PLD_PANEL:
{
{
break;
}
}
else /* PARSEOP_STRING */
{
if (!OpcFindName(AslPldPanelList,
{
break;
}
}
break;
{
{
break;
}
}
else /* PARSEOP_STRING */
{
{
break;
}
}
break;
{
{
break;
}
}
else /* PARSEOP_STRING */
{
{
break;
}
}
break;
case PARSEOP_PLD_SHAPE:
{
{
break;
}
}
else /* PARSEOP_STRING */
{
if (!OpcFindName(AslPldShapeList,
{
break;
}
}
break;
{
break;
}
{
break;
}
break;
case PARSEOP_PLD_GROUPTOKEN:
{
break;
}
{
break;
}
{
}
else /* PARSEOP_PLD_GROUPPOSITION */
{
}
break;
case PARSEOP_PLD_BAY:
case PARSEOP_PLD_EJECTABLE:
{
break;
}
{
break;
}
{
}
{
}
else /* PARSEOP_PLD_EJECTREQUIRED */
{
}
break;
{
break;
}
{
break;
}
{
}
else /* PARSEOP_PLD_CARDCAGENUMBER */
{
}
break;
case PARSEOP_PLD_REFERENCE:
{
break;
}
{
break;
}
break;
case PARSEOP_PLD_ROTATION:
{
break;
}
{
{
case 45:
break;
case 90:
break;
case 135:
break;
case 180:
break;
case 225:
break;
case 270:
break;
case 315:
break;
default:
break;
}
}
break;
case PARSEOP_PLD_ORDER:
{
break;
}
{
break;
}
break;
{
break;
}
{
break;
}
{
}
else /* PARSEOP_PLD_HORIZONTALOFFSET */
{
}
break;
default:
break;
}
}
/* Change Op to a Buffer */
/* Disable further optimization */
/* Child node is the buffer length */
/* Peer to the child is the raw buffer data */
}
/*******************************************************************************
*
* FUNCTION: OpcDoUuId
*
* PARAMETERS: Op - Parse node
*
* RETURN: None
*
* DESCRIPTION: Convert UUID string to 16-byte buffer
*
******************************************************************************/
static void
{
char *InString;
if (ACPI_FAILURE (Status))
{
}
else
{
}
/* Change Op to a Buffer */
/* Disable further optimization */
/* Child node is the buffer length */
/* Peer to the child is the raw buffer data */
}
/*******************************************************************************
*
* FUNCTION: OpcGenerateAmlOpcode
*
* PARAMETERS: Op - Parse node
*
* RETURN: None
*
* DESCRIPTION: Generate the AML opcode associated with the node and its
* a mapping between the parse opcodes and the actual AML opcodes.
*
******************************************************************************/
void
{
{
}
/* Special handling for some opcodes */
{
case PARSEOP_INTEGER:
/*
* Set the opcode based on the size of the integer
*/
(void) OpcSetOptimalIntegerSize (Op);
break;
case PARSEOP_OFFSET:
break;
case PARSEOP_ACCESSAS:
OpcDoAccessAs (Op);
break;
case PARSEOP_CONNECTION:
break;
case PARSEOP_EISAID:
OpcDoEisaId (Op);
break;
case PARSEOP_PRINTF:
OpcDoPrintf (Op);
break;
case PARSEOP_FPRINTF:
OpcDoFprintf (Op);
break;
case PARSEOP_TOPLD:
break;
case PARSEOP_TOUUID:
break;
case PARSEOP_UNICODE:
OpcDoUnicode (Op);
break;
case PARSEOP_INCLUDE:
break;
case PARSEOP_EXTERNAL:
break;
case PARSEOP_TIMER:
if (AcpiGbl_IntegerBitWidth == 32)
{
}
break;
default:
/* Nothing to do for other opcodes */
break;
}
return;
}