summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/compiler
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2011-02-12 01:03:15 +0000
committerjkim <jkim@FreeBSD.org>2011-02-12 01:03:15 +0000
commitf74b693166215a41e29f1932c91ef7c921e662a7 (patch)
tree77080c497fdac042ac2702fc74a130a870de5215 /sys/contrib/dev/acpica/compiler
parent060dcf42aad3ccbc8df13ec962fd6a93e9f78070 (diff)
parent6636ac3533f4af02a42a7302b5cd1197817f4ed9 (diff)
downloadFreeBSD-src-f74b693166215a41e29f1932c91ef7c921e662a7.zip
FreeBSD-src-f74b693166215a41e29f1932c91ef7c921e662a7.tar.gz
Merge ACPICA 20110211.
Diffstat (limited to 'sys/contrib/dev/acpica/compiler')
-rw-r--r--sys/contrib/dev/acpica/compiler/aslanalyze.c1734
-rw-r--r--sys/contrib/dev/acpica/compiler/aslbtypes.c525
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompile.c14
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.h79
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.l3
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.y12
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmessages.h14
-rw-r--r--sys/contrib/dev/acpica/compiler/aslpredef.c69
-rw-r--r--sys/contrib/dev/acpica/compiler/asltree.c70
-rw-r--r--sys/contrib/dev/acpica/compiler/aslwalks.c1148
-rw-r--r--sys/contrib/dev/acpica/compiler/dtcompile.c16
-rw-r--r--sys/contrib/dev/acpica/compiler/dtcompiler.h32
-rw-r--r--sys/contrib/dev/acpica/compiler/dtexpress.c390
-rw-r--r--sys/contrib/dev/acpica/compiler/dtfield.c51
-rw-r--r--sys/contrib/dev/acpica/compiler/dtio.c64
-rw-r--r--sys/contrib/dev/acpica/compiler/dttable.c22
-rw-r--r--sys/contrib/dev/acpica/compiler/dtutils.c7
17 files changed, 2499 insertions, 1751 deletions
diff --git a/sys/contrib/dev/acpica/compiler/aslanalyze.c b/sys/contrib/dev/acpica/compiler/aslanalyze.c
index 3aa5025..f563a3c 100644
--- a/sys/contrib/dev/acpica/compiler/aslanalyze.c
+++ b/sys/contrib/dev/acpica/compiler/aslanalyze.c
@@ -1,7 +1,6 @@
-
/******************************************************************************
*
- * Module Name: aslanalyze.c - check for semantic errors
+ * Module Name: aslanalyze.c - Support functions for parse tree walks
*
*****************************************************************************/
@@ -45,65 +44,18 @@
#include <contrib/dev/acpica/compiler/aslcompiler.h>
#include "aslcompiler.y.h"
-#include <contrib/dev/acpica/include/acparser.h>
-#include <contrib/dev/acpica/include/amlcode.h>
+#include <string.h>
+
#define _COMPONENT ACPI_COMPILER
ACPI_MODULE_NAME ("aslanalyze")
-/* Local prototypes */
-
-static UINT32
-AnMapArgTypeToBtype (
- UINT32 ArgType);
-
-static UINT32
-AnMapEtypeToBtype (
- UINT32 Etype);
-
-static void
-AnFormatBtype (
- char *Buffer,
- UINT32 Btype);
-
-static UINT32
-AnGetBtype (
- ACPI_PARSE_OBJECT *Op);
-
-static UINT32
-AnMapObjTypeToBtype (
- ACPI_PARSE_OBJECT *Op);
-
-static BOOLEAN
-AnLastStatementIsReturn (
- ACPI_PARSE_OBJECT *Op);
-
-static void
-AnCheckMethodReturnValue (
- ACPI_PARSE_OBJECT *Op,
- const ACPI_OPCODE_INFO *OpInfo,
- ACPI_PARSE_OBJECT *ArgOp,
- UINT32 RequiredBtypes,
- UINT32 ThisNodeBtype);
-
-static BOOLEAN
-AnIsInternalMethod (
- ACPI_PARSE_OBJECT *Op);
-
-static UINT32
-AnGetInternalMethodReturnType (
- ACPI_PARSE_OBJECT *Op);
-
-static BOOLEAN
-AnIsResultUsed (
- ACPI_PARSE_OBJECT *Op);
-
/*******************************************************************************
*
* FUNCTION: AnIsInternalMethod
*
- * PARAMETERS: Op - Current op
+ * PARAMETERS: Op - Current op
*
* RETURN: Boolean
*
@@ -111,7 +63,7 @@ AnIsResultUsed (
*
******************************************************************************/
-static BOOLEAN
+BOOLEAN
AnIsInternalMethod (
ACPI_PARSE_OBJECT *Op)
{
@@ -130,7 +82,7 @@ AnIsInternalMethod (
*
* FUNCTION: AnGetInternalMethodReturnType
*
- * PARAMETERS: Op - Current op
+ * PARAMETERS: Op - Current op
*
* RETURN: Btype
*
@@ -138,7 +90,7 @@ AnIsInternalMethod (
*
******************************************************************************/
-static UINT32
+UINT32
AnGetInternalMethodReturnType (
ACPI_PARSE_OBJECT *Op)
{
@@ -155,437 +107,6 @@ AnGetInternalMethodReturnType (
/*******************************************************************************
*
- * FUNCTION: AnMapArgTypeToBtype
- *
- * PARAMETERS: ArgType - The ARGI required type(s) for this argument,
- * from the opcode info table
- *
- * RETURN: The corresponding Bit-encoded types
- *
- * DESCRIPTION: Convert an encoded ARGI required argument type code into a
- * bitfield type code. Implements the implicit source conversion
- * rules.
- *
- ******************************************************************************/
-
-static UINT32
-AnMapArgTypeToBtype (
- UINT32 ArgType)
-{
-
- switch (ArgType)
- {
-
- /* Simple types */
-
- case ARGI_ANYTYPE:
- return (ACPI_BTYPE_OBJECTS_AND_REFS);
-
- case ARGI_PACKAGE:
- return (ACPI_BTYPE_PACKAGE);
-
- case ARGI_EVENT:
- return (ACPI_BTYPE_EVENT);
-
- case ARGI_MUTEX:
- return (ACPI_BTYPE_MUTEX);
-
- case ARGI_DDBHANDLE:
- /*
- * DDBHandleObject := SuperName
- * ACPI_BTYPE_REFERENCE: Index reference as parameter of Load/Unload
- */
- return (ACPI_BTYPE_DDB_HANDLE | ACPI_BTYPE_REFERENCE);
-
- /* Interchangeable types */
- /*
- * Source conversion rules:
- * Integer, String, and Buffer are all interchangeable
- */
- case ARGI_INTEGER:
- case ARGI_STRING:
- case ARGI_BUFFER:
- case ARGI_BUFFER_OR_STRING:
- case ARGI_COMPUTEDATA:
- return (ACPI_BTYPE_COMPUTE_DATA);
-
- /* References */
-
- case ARGI_INTEGER_REF:
- return (ACPI_BTYPE_INTEGER);
-
- case ARGI_OBJECT_REF:
- return (ACPI_BTYPE_ALL_OBJECTS);
-
- case ARGI_DEVICE_REF:
- return (ACPI_BTYPE_DEVICE_OBJECTS);
-
- case ARGI_REFERENCE:
- return (ACPI_BTYPE_REFERENCE);
-
- case ARGI_TARGETREF:
- case ARGI_FIXED_TARGET:
- case ARGI_SIMPLE_TARGET:
- return (ACPI_BTYPE_OBJECTS_AND_REFS);
-
- /* Complex types */
-
- case ARGI_DATAOBJECT:
-
- /*
- * Buffer, string, package or reference to a Op -
- * Used only by SizeOf operator
- */
- return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
- ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
-
- case ARGI_COMPLEXOBJ:
-
- /* Buffer, String, or package */
-
- return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
-
- case ARGI_REF_OR_STRING:
- return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
-
- case ARGI_REGION_OR_BUFFER:
-
- /* Used by Load() only. Allow buffers in addition to regions/fields */
-
- return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT);
-
- case ARGI_DATAREFOBJ:
- return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
- ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
-
- default:
- break;
- }
-
- return (ACPI_BTYPE_OBJECTS_AND_REFS);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnMapEtypeToBtype
- *
- * PARAMETERS: Etype - Encoded ACPI Type
- *
- * RETURN: Btype corresponding to the Etype
- *
- * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
- * operand conversion rules. In other words, returns the type(s)
- * this Etype is implicitly converted to during interpretation.
- *
- ******************************************************************************/
-
-static UINT32
-AnMapEtypeToBtype (
- UINT32 Etype)
-{
-
-
- if (Etype == ACPI_TYPE_ANY)
- {
- return ACPI_BTYPE_OBJECTS_AND_REFS;
- }
-
- /* Try the standard ACPI data types */
-
- if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
- {
- /*
- * This switch statement implements the allowed operand conversion
- * rules as per the "ASL Data Types" section of the ACPI
- * specification.
- */
- switch (Etype)
- {
- case ACPI_TYPE_INTEGER:
- return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
-
- case ACPI_TYPE_STRING:
- case ACPI_TYPE_BUFFER:
- return (ACPI_BTYPE_COMPUTE_DATA);
-
- case ACPI_TYPE_PACKAGE:
- return (ACPI_BTYPE_PACKAGE);
-
- case ACPI_TYPE_FIELD_UNIT:
- return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
-
- case ACPI_TYPE_BUFFER_FIELD:
- return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
-
- case ACPI_TYPE_DDB_HANDLE:
- return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
-
- case ACPI_BTYPE_DEBUG_OBJECT:
-
- /* Cannot be used as a source operand */
-
- return (0);
-
- default:
- return (1 << (Etype - 1));
- }
- }
-
- /* Try the internal data types */
-
- switch (Etype)
- {
- case ACPI_TYPE_LOCAL_REGION_FIELD:
- case ACPI_TYPE_LOCAL_BANK_FIELD:
- case ACPI_TYPE_LOCAL_INDEX_FIELD:
-
- /* Named fields can be either Integer/Buffer/String */
-
- return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
-
- case ACPI_TYPE_LOCAL_ALIAS:
-
- return (ACPI_BTYPE_INTEGER);
-
-
- case ACPI_TYPE_LOCAL_RESOURCE:
- case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
-
- return (ACPI_BTYPE_REFERENCE);
-
- default:
- printf ("Unhandled encoded type: %X\n", Etype);
- return (0);
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnFormatBtype
- *
- * PARAMETERS: Btype - Bitfield of ACPI types
- * Buffer - Where to put the ascii string
- *
- * RETURN: None.
- *
- * DESCRIPTION: Convert a Btype to a string of ACPI types
- *
- ******************************************************************************/
-
-static void
-AnFormatBtype (
- char *Buffer,
- UINT32 Btype)
-{
- UINT32 Type;
- BOOLEAN First = TRUE;
-
-
- *Buffer = 0;
-
- if (Btype == 0)
- {
- strcat (Buffer, "NoReturnValue");
- return;
- }
-
- for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
- {
- if (Btype & 0x00000001)
- {
- if (!First)
- {
- strcat (Buffer, "|");
- }
- First = FALSE;
- strcat (Buffer, AcpiUtGetTypeName (Type));
- }
- Btype >>= 1;
- }
-
- if (Btype & 0x00000001)
- {
- if (!First)
- {
- strcat (Buffer, "|");
- }
- First = FALSE;
- strcat (Buffer, "Reference");
- }
-
- Btype >>= 1;
- if (Btype & 0x00000001)
- {
- if (!First)
- {
- strcat (Buffer, "|");
- }
- First = FALSE;
- strcat (Buffer, "Resource");
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnGetBtype
- *
- * PARAMETERS: Op - Parse node whose type will be returned.
- *
- * RETURN: The Btype associated with the Op.
- *
- * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
- * Handles the case where the node is a name or method call and
- * the actual type must be obtained from the namespace node.
- *
- ******************************************************************************/
-
-static UINT32
-AnGetBtype (
- ACPI_PARSE_OBJECT *Op)
-{
- ACPI_NAMESPACE_NODE *Node;
- ACPI_PARSE_OBJECT *ReferencedNode;
- UINT32 ThisNodeBtype = 0;
-
-
- if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
- (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
- (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
- {
- Node = Op->Asl.Node;
- if (!Node)
- {
- DbgPrint (ASL_DEBUG_OUTPUT,
- "No attached Nsnode: [%s] at line %u name [%s], ignoring typecheck\n",
- Op->Asl.ParseOpName, Op->Asl.LineNumber,
- Op->Asl.ExternalName);
- return ACPI_UINT32_MAX;
- }
-
- ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
- if (!ThisNodeBtype)
- {
- AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
- "could not map type");
- }
-
- /*
- * Since it was a named reference, enable the
- * reference bit also
- */
- ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
-
- if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
- {
- ReferencedNode = Node->Op;
- if (!ReferencedNode)
- {
- /* Check for an internal method */
-
- if (AnIsInternalMethod (Op))
- {
- return (AnGetInternalMethodReturnType (Op));
- }
-
- AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
- "null Op pointer");
- return ACPI_UINT32_MAX;
- }
-
- if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
- {
- ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
- }
- else
- {
- return (ACPI_UINT32_MAX -1);
- }
- }
- }
- else
- {
- ThisNodeBtype = Op->Asl.AcpiBtype;
- }
-
- return (ThisNodeBtype);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnMapObjTypeToBtype
- *
- * PARAMETERS: Op - A parse node
- *
- * RETURN: A Btype
- *
- * DESCRIPTION: Map object to the associated "Btype"
- *
- ******************************************************************************/
-
-static UINT32
-AnMapObjTypeToBtype (
- ACPI_PARSE_OBJECT *Op)
-{
-
- switch (Op->Asl.ParseOpcode)
- {
- case PARSEOP_OBJECTTYPE_BFF: /* "BuffFieldObj" */
- return (ACPI_BTYPE_BUFFER_FIELD);
-
- case PARSEOP_OBJECTTYPE_BUF: /* "BuffObj" */
- return (ACPI_BTYPE_BUFFER);
-
- case PARSEOP_OBJECTTYPE_DDB: /* "DDBHandleObj" */
- return (ACPI_BTYPE_DDB_HANDLE);
-
- case PARSEOP_OBJECTTYPE_DEV: /* "DeviceObj" */
- return (ACPI_BTYPE_DEVICE);
-
- case PARSEOP_OBJECTTYPE_EVT: /* "EventObj" */
- return (ACPI_BTYPE_EVENT);
-
- case PARSEOP_OBJECTTYPE_FLD: /* "FieldUnitObj" */
- return (ACPI_BTYPE_FIELD_UNIT);
-
- case PARSEOP_OBJECTTYPE_INT: /* "IntObj" */
- return (ACPI_BTYPE_INTEGER);
-
- case PARSEOP_OBJECTTYPE_MTH: /* "MethodObj" */
- return (ACPI_BTYPE_METHOD);
-
- case PARSEOP_OBJECTTYPE_MTX: /* "MutexObj" */
- return (ACPI_BTYPE_MUTEX);
-
- case PARSEOP_OBJECTTYPE_OPR: /* "OpRegionObj" */
- return (ACPI_BTYPE_REGION);
-
- case PARSEOP_OBJECTTYPE_PKG: /* "PkgObj" */
- return (ACPI_BTYPE_PACKAGE);
-
- case PARSEOP_OBJECTTYPE_POW: /* "PowerResObj" */
- return (ACPI_BTYPE_POWER);
-
- case PARSEOP_OBJECTTYPE_STR: /* "StrObj" */
- return (ACPI_BTYPE_STRING);
-
- case PARSEOP_OBJECTTYPE_THZ: /* "ThermalZoneObj" */
- return (ACPI_BTYPE_THERMAL);
-
- case PARSEOP_OBJECTTYPE_UNK: /* "UnknownObj" */
- return (ACPI_BTYPE_OBJECTS_AND_REFS);
-
- default:
- return (0);
- }
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AnCheckId
*
* PARAMETERS: Op - Current parse op
@@ -598,11 +119,7 @@ AnMapObjTypeToBtype (
*
******************************************************************************/
-#define ASL_TYPE_HID 0
-#define ASL_TYPE_CID 1
-#include <string.h>
-
-static void
+void
AnCheckId (
ACPI_PARSE_OBJECT *Op,
ACPI_NAME Type)
@@ -694,371 +211,9 @@ AnCheckId (
/*******************************************************************************
*
- * FUNCTION: AnMethodAnalysisWalkBegin
- *
- * PARAMETERS: ASL_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
- * 1) Initialized local variables
- * 2) Valid arguments
- * 3) Return types
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AnMethodAnalysisWalkBegin (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
-{
- ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
- ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
- ACPI_PARSE_OBJECT *Next;
- UINT32 RegisterNumber;
- UINT32 i;
- char LocalName[] = "Local0";
- char ArgName[] = "Arg0";
- ACPI_PARSE_OBJECT *ArgNode;
- ACPI_PARSE_OBJECT *NextType;
- ACPI_PARSE_OBJECT *NextParamType;
- UINT8 ActualArgs = 0;
-
-
- switch (Op->Asl.ParseOpcode)
- {
- case PARSEOP_METHOD:
-
- TotalMethods++;
-
- /* Create and init method info */
-
- MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
- MethodInfo->Next = WalkInfo->MethodStack;
- MethodInfo->Op = Op;
-
- WalkInfo->MethodStack = MethodInfo;
-
- /* Get the name node, ignored here */
-
- Next = Op->Asl.Child;
-
- /* Get the NumArguments node */
-
- Next = Next->Asl.Next;
- MethodInfo->NumArguments = (UINT8)
- (((UINT8) Next->Asl.Value.Integer) & 0x07);
-
- /* Get the SerializeRule and SyncLevel nodes, ignored here */
-
- Next = Next->Asl.Next;
- Next = Next->Asl.Next;
- ArgNode = Next;
-
- /* Get the ReturnType node */
-
- Next = Next->Asl.Next;
-
- NextType = Next->Asl.Child;
- while (NextType)
- {
- /* Get and map each of the ReturnTypes */
-
- MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
- NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
- NextType = NextType->Asl.Next;
- }
-
- /* Get the ParameterType node */
-
- Next = Next->Asl.Next;
-
- NextType = Next->Asl.Child;
- while (NextType)
- {
- if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
- {
- NextParamType = NextType->Asl.Child;
- while (NextParamType)
- {
- MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
- NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
- NextParamType = NextParamType->Asl.Next;
- }
- }
- else
- {
- MethodInfo->ValidArgTypes[ActualArgs] =
- AnMapObjTypeToBtype (NextType);
- NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
- ActualArgs++;
- }
-
- NextType = NextType->Asl.Next;
- }
-
- if ((MethodInfo->NumArguments) &&
- (MethodInfo->NumArguments != ActualArgs))
- {
- /* error: Param list did not match number of args */
- }
-
- /* Allow numarguments == 0 for Function() */
-
- if ((!MethodInfo->NumArguments) && (ActualArgs))
- {
- MethodInfo->NumArguments = ActualArgs;
- ArgNode->Asl.Value.Integer |= ActualArgs;
- }
-
- /*
- * Actual arguments are initialized at method entry.
- * All other ArgX "registers" can be used as locals, so we
- * track their initialization.
- */
- for (i = 0; i < MethodInfo->NumArguments; i++)
- {
- MethodInfo->ArgInitialized[i] = TRUE;
- }
- break;
-
-
- case PARSEOP_METHODCALL:
-
- if (MethodInfo &&
- (Op->Asl.Node == MethodInfo->Op->Asl.Node))
- {
- AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
- }
- break;
-
-
- case PARSEOP_LOCAL0:
- case PARSEOP_LOCAL1:
- case PARSEOP_LOCAL2:
- case PARSEOP_LOCAL3:
- case PARSEOP_LOCAL4:
- case PARSEOP_LOCAL5:
- case PARSEOP_LOCAL6:
- case PARSEOP_LOCAL7:
-
- if (!MethodInfo)
- {
- /*
- * Local was used outside a control method, or there was an error
- * in the method declaration.
- */
- AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
- return (AE_ERROR);
- }
-
- RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
-
- /*
- * If the local is being used as a target, mark the local
- * initialized
- */
- if (Op->Asl.CompileFlags & NODE_IS_TARGET)
- {
- MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
- }
-
- /*
- * Otherwise, this is a reference, check if the local
- * has been previously initialized.
- *
- * The only operator that accepts an uninitialized value is ObjectType()
- */
- else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
- (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
- {
- LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
- AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
- }
- break;
-
-
- case PARSEOP_ARG0:
- case PARSEOP_ARG1:
- case PARSEOP_ARG2:
- case PARSEOP_ARG3:
- case PARSEOP_ARG4:
- case PARSEOP_ARG5:
- case PARSEOP_ARG6:
-
- if (!MethodInfo)
- {
- /*
- * Arg was used outside a control method, or there was an error
- * in the method declaration.
- */
- AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
- return (AE_ERROR);
- }
-
- RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
- ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
-
- /*
- * If the Arg is being used as a target, mark the local
- * initialized
- */
- if (Op->Asl.CompileFlags & NODE_IS_TARGET)
- {
- MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
- }
-
- /*
- * Otherwise, this is a reference, check if the Arg
- * has been previously initialized.
- *
- * The only operator that accepts an uninitialized value is ObjectType()
- */
- else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
- (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
- {
- AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
- }
-
- /* Flag this arg if it is not a "real" argument to the method */
-
- if (RegisterNumber >= MethodInfo->NumArguments)
- {
- AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
- }
- break;
-
-
- case PARSEOP_RETURN:
-
- if (!MethodInfo)
- {
- /*
- * Probably was an error in the method declaration,
- * no additional error here
- */
- ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
- return (AE_ERROR);
- }
-
- /* Child indicates a return value */
-
- if ((Op->Asl.Child) &&
- (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
- {
- MethodInfo->NumReturnWithValue++;
- }
- else
- {
- MethodInfo->NumReturnNoValue++;
- }
- break;
-
-
- case PARSEOP_BREAK:
- case PARSEOP_CONTINUE:
-
- Next = Op->Asl.Parent;
- while (Next)
- {
- if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
- {
- break;
- }
- Next = Next->Asl.Parent;
- }
-
- if (!Next)
- {
- AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
- }
- break;
-
-
- case PARSEOP_STALL:
-
- /* We can range check if the argument is an integer */
-
- if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
- (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
- {
- AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
- }
- break;
-
-
- case PARSEOP_DEVICE:
- case PARSEOP_EVENT:
- case PARSEOP_MUTEX:
- case PARSEOP_OPERATIONREGION:
- case PARSEOP_POWERRESOURCE:
- case PARSEOP_PROCESSOR:
- case PARSEOP_THERMALZONE:
-
- /*
- * The first operand is a name to be created in the namespace.
- * Check against the reserved list.
- */
- i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
- if (i < ACPI_VALID_RESERVED_NAME_MAX)
- {
- AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
- }
- break;
-
-
- case PARSEOP_NAME:
-
- /* Typecheck any predefined names statically defined with Name() */
-
- ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
-
- /* Special typechecking for _HID */
-
- if (!ACPI_STRCMP (METHOD_NAME__HID, Op->Asl.NameSeg))
- {
- Next = Op->Asl.Child->Asl.Next;
- AnCheckId (Next, ASL_TYPE_HID);
- }
-
- /* Special typechecking for _CID */
-
- else if (!ACPI_STRCMP (METHOD_NAME__CID, Op->Asl.NameSeg))
- {
- Next = Op->Asl.Child->Asl.Next;
-
- if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
- (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
- {
- Next = Next->Asl.Child;
- while (Next)
- {
- AnCheckId (Next, ASL_TYPE_CID);
- Next = Next->Asl.Next;
- }
- }
- else
- {
- AnCheckId (Next, ASL_TYPE_CID);
- }
- }
- break;
-
-
- default:
- break;
- }
-
- return AE_OK;
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AnLastStatementIsReturn
*
- * PARAMETERS: Op - A method parse node
+ * PARAMETERS: Op - A method parse node
*
* RETURN: TRUE if last statement is an ASL RETURN. False otherwise
*
@@ -1068,307 +223,28 @@ AnMethodAnalysisWalkBegin (
*
******************************************************************************/
-static BOOLEAN
+BOOLEAN
AnLastStatementIsReturn (
ACPI_PARSE_OBJECT *Op)
{
ACPI_PARSE_OBJECT *Next;
- /*
- * Check if last statement is a return
- */
+ /* Check if last statement is a return */
+
Next = ASL_GET_CHILD_NODE (Op);
while (Next)
{
if ((!Next->Asl.Next) &&
(Next->Asl.ParseOpcode == PARSEOP_RETURN))
{
- return TRUE;
+ return (TRUE);
}
Next = ASL_GET_PEER_NODE (Next);
}
- return FALSE;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnMethodAnalysisWalkEnd
- *
- * PARAMETERS: ASL_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Ascending callback for analysis walk. Complete method
- * return analysis.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AnMethodAnalysisWalkEnd (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
-{
- ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
- ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
-
-
- switch (Op->Asl.ParseOpcode)
- {
- case PARSEOP_METHOD:
- case PARSEOP_RETURN:
- if (!MethodInfo)
- {
- printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
- AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
- "No method info for this method");
- CmCleanupAndExit ();
- return (AE_AML_INTERNAL);
- }
- break;
-
- default:
- break;
- }
-
- switch (Op->Asl.ParseOpcode)
- {
- case PARSEOP_METHOD:
-
- WalkInfo->MethodStack = MethodInfo->Next;
-
- /*
- * Check if there is no return statement at the end of the
- * method AND we can actually get there -- i.e., the execution
- * of the method can possibly terminate without a return statement.
- */
- if ((!AnLastStatementIsReturn (Op)) &&
- (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
- {
- /*
- * No return statement, and execution can possibly exit
- * via this path. This is equivalent to Return ()
- */
- MethodInfo->NumReturnNoValue++;
- }
-
- /*
- * Check for case where some return statements have a return value
- * and some do not. Exit without a return statement is a return with
- * no value
- */
- if (MethodInfo->NumReturnNoValue &&
- MethodInfo->NumReturnWithValue)
- {
- AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
- Op->Asl.ExternalName);
- }
-
- /*
- * If there are any RETURN() statements with no value, or there is a
- * control path that allows the method to exit without a return value,
- * we mark the method as a method that does not return a value. This
- * knowledge can be used to check method invocations that expect a
- * returned value.
- */
- if (MethodInfo->NumReturnNoValue)
- {
- if (MethodInfo->NumReturnWithValue)
- {
- Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
- }
- else
- {
- Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
- }
- }
-
- /*
- * Check predefined method names for correct return behavior
- * and correct number of arguments
- */
- ApCheckForPredefinedMethod (Op, MethodInfo);
- ACPI_FREE (MethodInfo);
- break;
-
-
- case PARSEOP_RETURN:
-
- /*
- * If the parent is a predefined method name, attempt to typecheck
- * the return value. Only static types can be validated.
- */
- ApCheckPredefinedReturnValue (Op, MethodInfo);
-
- /*
- * The parent block does not "exit" and continue execution -- the
- * method is terminated here with the Return() statement.
- */
- Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
-
- /* Used in the "typing" pass later */
-
- Op->Asl.ParentMethod = MethodInfo->Op;
-
- /*
- * If there is a peer node after the return statement, then this
- * node is unreachable code -- i.e., it won't be executed because of
- * the preceeding Return() statement.
- */
- if (Op->Asl.Next)
- {
- AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
- }
- break;
-
-
- case PARSEOP_IF:
-
- if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
- (Op->Asl.Next) &&
- (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
- {
- /*
- * This IF has a corresponding ELSE. The IF block has no exit,
- * (it contains an unconditional Return)
- * mark the ELSE block to remember this fact.
- */
- Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
- }
- break;
-
-
- case PARSEOP_ELSE:
-
- if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
- (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
- {
- /*
- * This ELSE block has no exit and the corresponding IF block
- * has no exit either. Therefore, the parent node has no exit.
- */
- Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
- }
- break;
-
-
- default:
-
- if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
- (Op->Asl.Parent))
- {
- /* If this node has no exit, then the parent has no exit either */
-
- Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
- }
- break;
- }
-
- return AE_OK;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnMethodTypingWalkBegin
- *
- * PARAMETERS: ASL_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Descending callback for the typing walk.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AnMethodTypingWalkBegin (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
-{
-
- return AE_OK;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnMethodTypingWalkEnd
- *
- * PARAMETERS: ASL_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Ascending callback for typing walk. Complete the method
- * return analysis. Check methods for:
- * 1) Initialized local variables
- * 2) Valid arguments
- * 3) Return types
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AnMethodTypingWalkEnd (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
-{
- UINT32 ThisNodeBtype;
-
-
- switch (Op->Asl.ParseOpcode)
- {
- case PARSEOP_METHOD:
-
- Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
- break;
-
- case PARSEOP_RETURN:
-
- if ((Op->Asl.Child) &&
- (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
- {
- ThisNodeBtype = AnGetBtype (Op->Asl.Child);
-
- if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
- (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
- {
- /*
- * The called method is untyped at this time (typically a
- * forward reference).
- *
- * Check for a recursive method call first.
- */
- if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
- {
- /* We must type the method here */
-
- TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
- ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
- AnMethodTypingWalkEnd, NULL);
-
- ThisNodeBtype = AnGetBtype (Op->Asl.Child);
- }
- }
-
- /* Returns a value, save the value type */
-
- if (Op->Asl.ParentMethod)
- {
- Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
- }
- }
- break;
-
- default:
- break;
- }
-
- return AE_OK;
+ return (FALSE);
}
@@ -1389,7 +265,7 @@ AnMethodTypingWalkEnd (
*
******************************************************************************/
-static void
+void
AnCheckMethodReturnValue (
ACPI_PARSE_OBJECT *Op,
const ACPI_OPCODE_INFO *OpInfo,
@@ -1426,7 +302,6 @@ AnCheckMethodReturnValue (
AnFormatBtype (StringBuffer, ThisNodeBtype);
AnFormatBtype (StringBuffer2, RequiredBtypes);
-
/*
* The case where the method does not return any value at all
* was already handled in the namespace cross reference
@@ -1447,347 +322,9 @@ AnCheckMethodReturnValue (
/*******************************************************************************
*
- * FUNCTION: AnOperandTypecheckWalkBegin
- *
- * PARAMETERS: ASL_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
- * 1) Initialized local variables
- * 2) Valid arguments
- * 3) Return types
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AnOperandTypecheckWalkBegin (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
-{
-
- return AE_OK;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnOperandTypecheckWalkEnd
- *
- * PARAMETERS: ASL_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Ascending callback for analysis walk. Complete method
- * return analysis.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AnOperandTypecheckWalkEnd (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
-{
- const ACPI_OPCODE_INFO *OpInfo;
- UINT32 RuntimeArgTypes;
- UINT32 RuntimeArgTypes2;
- UINT32 RequiredBtypes;
- UINT32 ThisNodeBtype;
- UINT32 CommonBtypes;
- UINT32 OpcodeClass;
- ACPI_PARSE_OBJECT *ArgOp;
- UINT32 ArgType;
-
-
- switch (Op->Asl.AmlOpcode)
- {
- case AML_RAW_DATA_BYTE:
- case AML_RAW_DATA_WORD:
- case AML_RAW_DATA_DWORD:
- case AML_RAW_DATA_QWORD:
- case AML_RAW_DATA_BUFFER:
- case AML_RAW_DATA_CHAIN:
- case AML_PACKAGE_LENGTH:
- case AML_UNASSIGNED_OPCODE:
- case AML_DEFAULT_ARG_OP:
-
- /* Ignore the internal (compiler-only) AML opcodes */
-
- return (AE_OK);
-
- default:
- break;
- }
-
- OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
- if (!OpInfo)
- {
- return (AE_OK);
- }
-
- ArgOp = Op->Asl.Child;
- RuntimeArgTypes = OpInfo->RuntimeArgs;
- OpcodeClass = OpInfo->Class;
-
-#ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
- /*
- * Update 11/2008: In practice, we can't perform this check. A simple
- * analysis is not sufficient. Also, it can cause errors when compiling
- * disassembled code because of the way Switch operators are implemented
- * (a While(One) loop with a named temp variable created within.)
- */
-
- /*
- * If we are creating a named object, check if we are within a while loop
- * by checking if the parent is a WHILE op. This is a simple analysis, but
- * probably sufficient for many cases.
- *
- * Allow Scope(), Buffer(), and Package().
- */
- if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
- ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
- {
- if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
- {
- AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
- }
- }
-#endif
-
- /*
- * Special case for control opcodes IF/RETURN/WHILE since they
- * have no runtime arg list (at this time)
- */
- switch (Op->Asl.AmlOpcode)
- {
- case AML_IF_OP:
- case AML_WHILE_OP:
- case AML_RETURN_OP:
-
- if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
- {
- /* Check for an internal method */
-
- if (AnIsInternalMethod (ArgOp))
- {
- return (AE_OK);
- }
-
- /* The lone arg is a method call, check it */
-
- RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
- if (Op->Asl.AmlOpcode == AML_RETURN_OP)
- {
- RequiredBtypes = 0xFFFFFFFF;
- }
-
- ThisNodeBtype = AnGetBtype (ArgOp);
- if (ThisNodeBtype == ACPI_UINT32_MAX)
- {
- return (AE_OK);
- }
- AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
- RequiredBtypes, ThisNodeBtype);
- }
- return (AE_OK);
-
- default:
- break;
- }
-
- /* Ignore the non-executable opcodes */
-
- if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
- {
- return (AE_OK);
- }
-
- switch (OpcodeClass)
- {
- case AML_CLASS_EXECUTE:
- case AML_CLASS_CREATE:
- case AML_CLASS_CONTROL:
- case AML_CLASS_RETURN_VALUE:
-
- /* TBD: Change class or fix typechecking for these */
-
- if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) ||
- (Op->Asl.AmlOpcode == AML_PACKAGE_OP) ||
- (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
- {
- break;
- }
-
- /* Reverse the runtime argument list */
-
- RuntimeArgTypes2 = 0;
- while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
- {
- RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
- RuntimeArgTypes2 |= ArgType;
- INCREMENT_ARG_LIST (RuntimeArgTypes);
- }
-
- while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
- {
- RequiredBtypes = AnMapArgTypeToBtype (ArgType);
-
- ThisNodeBtype = AnGetBtype (ArgOp);
- if (ThisNodeBtype == ACPI_UINT32_MAX)
- {
- goto NextArgument;
- }
-
- /* Examine the arg based on the required type of the arg */
-
- switch (ArgType)
- {
- case ARGI_TARGETREF:
-
- if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
- {
- /* ZERO is the placeholder for "don't store result" */
-
- ThisNodeBtype = RequiredBtypes;
- break;
- }
-
- if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
- {
- /*
- * This is the case where an original reference to a resource
- * descriptor field has been replaced by an (Integer) offset.
- * These named fields are supported at compile-time only;
- * the names are not passed to the interpreter (via the AML).
- */
- if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
- (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
- {
- AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
- }
- else
- {
- AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
- }
- break;
- }
-
- if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
- (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
- {
- break;
- }
-
- ThisNodeBtype = RequiredBtypes;
- break;
-
-
- case ARGI_REFERENCE: /* References */
- case ARGI_INTEGER_REF:
- case ARGI_OBJECT_REF:
- case ARGI_DEVICE_REF:
-
- switch (ArgOp->Asl.ParseOpcode)
- {
- case PARSEOP_LOCAL0:
- case PARSEOP_LOCAL1:
- case PARSEOP_LOCAL2:
- case PARSEOP_LOCAL3:
- case PARSEOP_LOCAL4:
- case PARSEOP_LOCAL5:
- case PARSEOP_LOCAL6:
- case PARSEOP_LOCAL7:
-
- /* TBD: implement analysis of current value (type) of the local */
- /* For now, just treat any local as a typematch */
-
- /*ThisNodeBtype = RequiredBtypes;*/
- break;
-
- case PARSEOP_ARG0:
- case PARSEOP_ARG1:
- case PARSEOP_ARG2:
- case PARSEOP_ARG3:
- case PARSEOP_ARG4:
- case PARSEOP_ARG5:
- case PARSEOP_ARG6:
-
- /* Hard to analyze argument types, sow we won't */
- /* For now, just treat any arg as a typematch */
-
- /* ThisNodeBtype = RequiredBtypes; */
- break;
-
- case PARSEOP_DEBUG:
- break;
-
- case PARSEOP_REFOF:
- case PARSEOP_INDEX:
- default:
- break;
-
- }
- break;
-
- case ARGI_INTEGER:
- default:
- break;
- }
-
-
- CommonBtypes = ThisNodeBtype & RequiredBtypes;
-
- if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
- {
- if (AnIsInternalMethod (ArgOp))
- {
- return (AE_OK);
- }
-
- /* Check a method call for a valid return value */
-
- AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
- RequiredBtypes, ThisNodeBtype);
- }
-
- /*
- * Now check if the actual type(s) match at least one
- * bit to the required type
- */
- else if (!CommonBtypes)
- {
- /* No match -- this is a type mismatch error */
-
- AnFormatBtype (StringBuffer, ThisNodeBtype);
- AnFormatBtype (StringBuffer2, RequiredBtypes);
-
- sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
- StringBuffer, OpInfo->Name, StringBuffer2);
-
- AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
- }
-
- NextArgument:
- ArgOp = ArgOp->Asl.Next;
- INCREMENT_ARG_LIST (RuntimeArgTypes2);
- }
- break;
-
- default:
- break;
- }
-
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AnIsResultUsed
*
- * PARAMETERS: Op - Parent op for the operator
+ * PARAMETERS: Op - Parent op for the operator
*
* RETURN: TRUE if result from this operation is actually consumed
*
@@ -1796,7 +333,7 @@ AnOperandTypecheckWalkEnd (
*
******************************************************************************/
-static BOOLEAN
+BOOLEAN
AnIsResultUsed (
ACPI_PARSE_OBJECT *Op)
{
@@ -1852,212 +389,97 @@ AnIsResultUsed (
/*******************************************************************************
*
- * FUNCTION: AnOtherSemanticAnalysisWalkBegin
+ * FUNCTION: ApCheckForGpeNameConflict
*
- * PARAMETERS: ASL_WALK_CALLBACK
+ * PARAMETERS: Op - Current parse op
*
- * RETURN: Status
+ * RETURN: None
*
- * DESCRIPTION: Descending callback for the analysis walk. Checks for
- * miscellaneous issues in the code.
+ * DESCRIPTION: Check for a conflict between GPE names within this scope.
+ * Conflict means two GPE names with the same GPE number, but
+ * different types -- such as _L1C and _E1C.
*
******************************************************************************/
-ACPI_STATUS
-AnOtherSemanticAnalysisWalkBegin (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
+void
+ApCheckForGpeNameConflict (
+ ACPI_PARSE_OBJECT *Op)
{
- ACPI_PARSE_OBJECT *ArgNode;
- ACPI_PARSE_OBJECT *PrevArgNode = NULL;
- const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 GpeNumber;
+ char Name[ACPI_NAME_SIZE + 1];
+ char Target[ACPI_NAME_SIZE];
+
+ /* Need a null-terminated string version of NameSeg */
- OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+ ACPI_MOVE_32_TO_32 (Name, &Op->Asl.NameSeg);
+ Name[ACPI_NAME_SIZE] = 0;
/*
- * Determine if an execution class operator actually does something by
- * checking if it has a target and/or the function return value is used.
- * (Target is optional, so a standalone statement can actually do nothing.)
+ * For a GPE method:
+ * 1st char must be underscore
+ * 2nd char must be L or E
+ * 3rd/4th chars must be a hex number
*/
- if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
- (OpInfo->Flags & AML_HAS_RETVAL) &&
- (!AnIsResultUsed (Op)))
+ if ((Name[0] != '_') ||
+ ((Name[1] != 'L') && (Name[1] != 'E')))
{
- if (OpInfo->Flags & AML_HAS_TARGET)
- {
- /*
- * Find the target node, it is always the last child. If the traget
- * is not specified in the ASL, a default node of type Zero was
- * created by the parser.
- */
- ArgNode = Op->Asl.Child;
- while (ArgNode->Asl.Next)
- {
- PrevArgNode = ArgNode;
- ArgNode = ArgNode->Asl.Next;
- }
+ return;
+ }
- /* Divide() is the only weird case, it has two targets */
+ /* Verify 3rd/4th chars are a valid hex value */
- if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
- {
- if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
- (PrevArgNode) &&
- (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
- {
- AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
- }
- }
- else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
- {
- AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
- }
- }
- else
- {
- /*
- * Has no target and the result is not used. Only a couple opcodes
- * can have this combination.
- */
- switch (Op->Asl.ParseOpcode)
- {
- case PARSEOP_ACQUIRE:
- case PARSEOP_WAIT:
- case PARSEOP_LOADTABLE:
- break;
-
- default:
- AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
- break;
- }
- }
+ GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
+ if (GpeNumber == ACPI_UINT32_MAX)
+ {
+ return;
}
-
/*
- * Semantic checks for individual ASL operators
+ * We are now sure we have an _Lxx or _Exx.
+ * Create the target name that would cause collision (Flip E/L)
*/
- switch (Op->Asl.ParseOpcode)
- {
- case PARSEOP_ACQUIRE:
- case PARSEOP_WAIT:
- /*
- * Emit a warning if the timeout parameter for these operators is not
- * ACPI_WAIT_FOREVER, and the result value from the operator is not
- * checked, meaning that a timeout could happen, but the code
- * would not know about it.
- */
+ ACPI_MOVE_32_TO_32 (Target, Name);
- /* First child is the namepath, 2nd child is timeout */
+ /* Inject opposite letter ("L" versus "E") */
- ArgNode = Op->Asl.Child;
- ArgNode = ArgNode->Asl.Next;
+ if (Name[1] == 'L')
+ {
+ Target[1] = 'E';
+ }
+ else /* Name[1] == 'E' */
+ {
+ Target[1] = 'L';
+ }
- /*
- * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
- * 0xFFFF or greater
- */
- if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
- (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) &&
- (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
- {
- break;
- }
+ /* Search all peers (objects within this scope) for target match */
+ NextOp = Op->Asl.Next;
+ while (NextOp)
+ {
/*
- * The operation could timeout. If the return value is not used
- * (indicates timeout occurred), issue a warning
+ * We mostly care about methods, but check Name() constructs also,
+ * even though they will get another error for not being a method.
+ * All GPE names must be defined as control methods.
*/
- if (!AnIsResultUsed (Op))
+ if ((NextOp->Asl.ParseOpcode == PARSEOP_METHOD) ||
+ (NextOp->Asl.ParseOpcode == PARSEOP_NAME))
{
- AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, Op->Asl.ExternalName);
- }
- break;
-
- case PARSEOP_CREATEFIELD:
- /*
- * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
- */
- ArgNode = Op->Asl.Child;
- ArgNode = ArgNode->Asl.Next;
- ArgNode = ArgNode->Asl.Next;
+ if (ACPI_COMPARE_NAME (Target, NextOp->Asl.NameSeg))
+ {
+ /* Found both _Exy and _Lxy in the same scope, error */
- if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) ||
- ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
- (ArgNode->Asl.Value.Integer == 0)))
- {
- AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
+ AslError (ASL_ERROR, ASL_MSG_GPE_NAME_CONFLICT, NextOp,
+ Name);
+ return;
+ }
}
- break;
-
- default:
- break;
- }
-
- return AE_OK;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnOtherSemanticAnalysisWalkEnd
- *
- * PARAMETERS: ASL_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Ascending callback for analysis walk. Complete method
- * return analysis.
- *
- ******************************************************************************/
-ACPI_STATUS
-AnOtherSemanticAnalysisWalkEnd (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context)
-{
-
- return AE_OK;
-
-}
-
-
-#ifdef ACPI_OBSOLETE_FUNCTIONS
-/*******************************************************************************
- *
- * FUNCTION: AnMapBtypeToEtype
- *
- * PARAMETERS: Btype - Bitfield of ACPI types
- *
- * RETURN: The Etype corresponding the the Btype
- *
- * DESCRIPTION: Convert a bitfield type to an encoded type
- *
- ******************************************************************************/
-
-UINT32
-AnMapBtypeToEtype (
- UINT32 Btype)
-{
- UINT32 i;
- UINT32 Etype;
-
-
- if (Btype == 0)
- {
- return 0;
+ NextOp = NextOp->Asl.Next;
}
- Etype = 1;
- for (i = 1; i < Btype; i *= 2)
- {
- Etype++;
- }
+ /* OK, no conflict found */
- return (Etype);
+ return;
}
-#endif
-
diff --git a/sys/contrib/dev/acpica/compiler/aslbtypes.c b/sys/contrib/dev/acpica/compiler/aslbtypes.c
new file mode 100644
index 0000000..bc1f17a
--- /dev/null
+++ b/sys/contrib/dev/acpica/compiler/aslbtypes.c
@@ -0,0 +1,525 @@
+/******************************************************************************
+ *
+ * Module Name: aslbtypes - Support for bitfield types
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2011, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslbtypes")
+
+/* Local prototypes */
+
+static UINT32
+AnMapEtypeToBtype (
+ UINT32 Etype);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapArgTypeToBtype
+ *
+ * PARAMETERS: ArgType - The ARGI required type(s) for this
+ * argument, from the opcode info table
+ *
+ * RETURN: The corresponding Bit-encoded types
+ *
+ * DESCRIPTION: Convert an encoded ARGI required argument type code into a
+ * bitfield type code. Implements the implicit source conversion
+ * rules.
+ *
+ ******************************************************************************/
+
+UINT32
+AnMapArgTypeToBtype (
+ UINT32 ArgType)
+{
+
+ switch (ArgType)
+ {
+
+ /* Simple types */
+
+ case ARGI_ANYTYPE:
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+
+ case ARGI_PACKAGE:
+ return (ACPI_BTYPE_PACKAGE);
+
+ case ARGI_EVENT:
+ return (ACPI_BTYPE_EVENT);
+
+ case ARGI_MUTEX:
+ return (ACPI_BTYPE_MUTEX);
+
+ case ARGI_DDBHANDLE:
+ /*
+ * DDBHandleObject := SuperName
+ * ACPI_BTYPE_REFERENCE: Index reference as parameter of Load/Unload
+ */
+ return (ACPI_BTYPE_DDB_HANDLE | ACPI_BTYPE_REFERENCE);
+
+ /* Interchangeable types */
+ /*
+ * Source conversion rules:
+ * Integer, String, and Buffer are all interchangeable
+ */
+ case ARGI_INTEGER:
+ case ARGI_STRING:
+ case ARGI_BUFFER:
+ case ARGI_BUFFER_OR_STRING:
+ case ARGI_COMPUTEDATA:
+ return (ACPI_BTYPE_COMPUTE_DATA);
+
+ /* References */
+
+ case ARGI_INTEGER_REF:
+ return (ACPI_BTYPE_INTEGER);
+
+ case ARGI_OBJECT_REF:
+ return (ACPI_BTYPE_ALL_OBJECTS);
+
+ case ARGI_DEVICE_REF:
+ return (ACPI_BTYPE_DEVICE_OBJECTS);
+
+ case ARGI_REFERENCE:
+ return (ACPI_BTYPE_REFERENCE);
+
+ case ARGI_TARGETREF:
+ case ARGI_FIXED_TARGET:
+ case ARGI_SIMPLE_TARGET:
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+
+ /* Complex types */
+
+ case ARGI_DATAOBJECT:
+
+ /*
+ * Buffer, string, package or reference to a Op -
+ * Used only by SizeOf operator
+ */
+ return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
+ ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
+
+ case ARGI_COMPLEXOBJ:
+
+ /* Buffer, String, or package */
+
+ return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
+
+ case ARGI_REF_OR_STRING:
+ return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
+
+ case ARGI_REGION_OR_BUFFER:
+
+ /* Used by Load() only. Allow buffers in addition to regions/fields */
+
+ return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT);
+
+ case ARGI_DATAREFOBJ:
+ return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
+ ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
+
+ default:
+ break;
+ }
+
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapEtypeToBtype
+ *
+ * PARAMETERS: Etype - Encoded ACPI Type
+ *
+ * RETURN: Btype corresponding to the Etype
+ *
+ * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
+ * operand conversion rules. In other words, returns the type(s)
+ * this Etype is implicitly converted to during interpretation.
+ *
+ ******************************************************************************/
+
+static UINT32
+AnMapEtypeToBtype (
+ UINT32 Etype)
+{
+
+
+ if (Etype == ACPI_TYPE_ANY)
+ {
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+ }
+
+ /* Try the standard ACPI data types */
+
+ if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
+ {
+ /*
+ * This switch statement implements the allowed operand conversion
+ * rules as per the "ASL Data Types" section of the ACPI
+ * specification.
+ */
+ switch (Etype)
+ {
+ case ACPI_TYPE_INTEGER:
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
+
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ return (ACPI_BTYPE_COMPUTE_DATA);
+
+ case ACPI_TYPE_PACKAGE:
+ return (ACPI_BTYPE_PACKAGE);
+
+ case ACPI_TYPE_FIELD_UNIT:
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
+
+ case ACPI_TYPE_BUFFER_FIELD:
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
+
+ case ACPI_TYPE_DDB_HANDLE:
+ return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
+
+ case ACPI_BTYPE_DEBUG_OBJECT:
+
+ /* Cannot be used as a source operand */
+
+ return (0);
+
+ default:
+ return (1 << (Etype - 1));
+ }
+ }
+
+ /* Try the internal data types */
+
+ switch (Etype)
+ {
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ /* Named fields can be either Integer/Buffer/String */
+
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
+
+ case ACPI_TYPE_LOCAL_ALIAS:
+
+ return (ACPI_BTYPE_INTEGER);
+
+
+ case ACPI_TYPE_LOCAL_RESOURCE:
+ case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
+
+ return (ACPI_BTYPE_REFERENCE);
+
+ default:
+ printf ("Unhandled encoded type: %X\n", Etype);
+ return (0);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnFormatBtype
+ *
+ * PARAMETERS: Btype - Bitfield of ACPI types
+ * Buffer - Where to put the ascii string
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Convert a Btype to a string of ACPI types
+ *
+ ******************************************************************************/
+
+void
+AnFormatBtype (
+ char *Buffer,
+ UINT32 Btype)
+{
+ UINT32 Type;
+ BOOLEAN First = TRUE;
+
+
+ *Buffer = 0;
+
+ if (Btype == 0)
+ {
+ strcat (Buffer, "NoReturnValue");
+ return;
+ }
+
+ for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
+ {
+ if (Btype & 0x00000001)
+ {
+ if (!First)
+ {
+ strcat (Buffer, "|");
+ }
+ First = FALSE;
+ strcat (Buffer, AcpiUtGetTypeName (Type));
+ }
+ Btype >>= 1;
+ }
+
+ if (Btype & 0x00000001)
+ {
+ if (!First)
+ {
+ strcat (Buffer, "|");
+ }
+ First = FALSE;
+ strcat (Buffer, "Reference");
+ }
+
+ Btype >>= 1;
+ if (Btype & 0x00000001)
+ {
+ if (!First)
+ {
+ strcat (Buffer, "|");
+ }
+ First = FALSE;
+ strcat (Buffer, "Resource");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnGetBtype
+ *
+ * PARAMETERS: Op - Parse node whose type will be returned.
+ *
+ * RETURN: The Btype associated with the Op.
+ *
+ * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
+ * Handles the case where the node is a name or method call and
+ * the actual type must be obtained from the namespace node.
+ *
+ ******************************************************************************/
+
+UINT32
+AnGetBtype (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *ReferencedNode;
+ UINT32 ThisNodeBtype = 0;
+
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
+ (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
+ {
+ Node = Op->Asl.Node;
+ if (!Node)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "No attached Nsnode: [%s] at line %u name [%s], ignoring typecheck\n",
+ Op->Asl.ParseOpName, Op->Asl.LineNumber,
+ Op->Asl.ExternalName);
+ return (ACPI_UINT32_MAX);
+ }
+
+ ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
+ if (!ThisNodeBtype)
+ {
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
+ "could not map type");
+ }
+
+ /*
+ * Since it was a named reference, enable the
+ * reference bit also
+ */
+ ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
+
+ if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
+ {
+ ReferencedNode = Node->Op;
+ if (!ReferencedNode)
+ {
+ /* Check for an internal method */
+
+ if (AnIsInternalMethod (Op))
+ {
+ return (AnGetInternalMethodReturnType (Op));
+ }
+
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
+ "null Op pointer");
+ return (ACPI_UINT32_MAX);
+ }
+
+ if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
+ {
+ ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
+ }
+ else
+ {
+ return (ACPI_UINT32_MAX -1);
+ }
+ }
+ }
+ else
+ {
+ ThisNodeBtype = Op->Asl.AcpiBtype;
+ }
+
+ return (ThisNodeBtype);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapObjTypeToBtype
+ *
+ * PARAMETERS: Op - A parse node
+ *
+ * RETURN: A Btype
+ *
+ * DESCRIPTION: Map object to the associated "Btype"
+ *
+ ******************************************************************************/
+
+UINT32
+AnMapObjTypeToBtype (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_OBJECTTYPE_BFF: /* "BuffFieldObj" */
+ return (ACPI_BTYPE_BUFFER_FIELD);
+
+ case PARSEOP_OBJECTTYPE_BUF: /* "BuffObj" */
+ return (ACPI_BTYPE_BUFFER);
+
+ case PARSEOP_OBJECTTYPE_DDB: /* "DDBHandleObj" */
+ return (ACPI_BTYPE_DDB_HANDLE);
+
+ case PARSEOP_OBJECTTYPE_DEV: /* "DeviceObj" */
+ return (ACPI_BTYPE_DEVICE);
+
+ case PARSEOP_OBJECTTYPE_EVT: /* "EventObj" */
+ return (ACPI_BTYPE_EVENT);
+
+ case PARSEOP_OBJECTTYPE_FLD: /* "FieldUnitObj" */
+ return (ACPI_BTYPE_FIELD_UNIT);
+
+ case PARSEOP_OBJECTTYPE_INT: /* "IntObj" */
+ return (ACPI_BTYPE_INTEGER);
+
+ case PARSEOP_OBJECTTYPE_MTH: /* "MethodObj" */
+ return (ACPI_BTYPE_METHOD);
+
+ case PARSEOP_OBJECTTYPE_MTX: /* "MutexObj" */
+ return (ACPI_BTYPE_MUTEX);
+
+ case PARSEOP_OBJECTTYPE_OPR: /* "OpRegionObj" */
+ return (ACPI_BTYPE_REGION);
+
+ case PARSEOP_OBJECTTYPE_PKG: /* "PkgObj" */
+ return (ACPI_BTYPE_PACKAGE);
+
+ case PARSEOP_OBJECTTYPE_POW: /* "PowerResObj" */
+ return (ACPI_BTYPE_POWER);
+
+ case PARSEOP_OBJECTTYPE_STR: /* "StrObj" */
+ return (ACPI_BTYPE_STRING);
+
+ case PARSEOP_OBJECTTYPE_THZ: /* "ThermalZoneObj" */
+ return (ACPI_BTYPE_THERMAL);
+
+ case PARSEOP_OBJECTTYPE_UNK: /* "UnknownObj" */
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+
+ default:
+ return (0);
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapBtypeToEtype
+ *
+ * PARAMETERS: Btype - Bitfield of ACPI types
+ *
+ * RETURN: The Etype corresponding the the Btype
+ *
+ * DESCRIPTION: Convert a bitfield type to an encoded type
+ *
+ ******************************************************************************/
+
+UINT32
+AnMapBtypeToEtype (
+ UINT32 Btype)
+{
+ UINT32 i;
+ UINT32 Etype;
+
+
+ if (Btype == 0)
+ {
+ return (0);
+ }
+
+ Etype = 1;
+ for (i = 1; i < Btype; i *= 2)
+ {
+ Etype++;
+ }
+
+ return (Etype);
+}
+#endif
diff --git a/sys/contrib/dev/acpica/compiler/aslcompile.c b/sys/contrib/dev/acpica/compiler/aslcompile.c
index 2689b5d..0981cd6 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompile.c
+++ b/sys/contrib/dev/acpica/compiler/aslcompile.c
@@ -600,27 +600,25 @@ CmDoCompile (
Event = UtBeginEvent ("Determine object types returned by methods");
DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
- TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
- AnMethodTypingWalkBegin,
- AnMethodTypingWalkEnd, NULL);
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
+ NULL, AnMethodTypingWalkEnd, NULL);
UtEndEvent (Event);
/* Semantic error checking part three - operand type checking */
Event = UtBeginEvent ("Analyze AML operand types");
DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
- TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
- AnOperandTypecheckWalkBegin,
- AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
+ NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
UtEndEvent (Event);
/* Semantic error checking part four - other miscellaneous checks */
Event = UtBeginEvent ("Miscellaneous analysis");
DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
- TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
AnOtherSemanticAnalysisWalkBegin,
- AnOtherSemanticAnalysisWalkEnd, &AnalysisWalkInfo);
+ NULL, &AnalysisWalkInfo);
UtEndEvent (Event);
/* Calculate all AML package lengths */
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h
index 3149095..e18546e 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h
@@ -164,7 +164,7 @@ FlCheckForAscii (
/*
- * aslanalyze - semantic analysis
+ * aslwalks - semantic analysis and parse tree walks
*/
ACPI_STATUS
AnOtherSemanticAnalysisWalkBegin (
@@ -179,12 +179,6 @@ AnOtherSemanticAnalysisWalkEnd (
void *Context);
ACPI_STATUS
-AnOperandTypecheckWalkBegin (
- ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context);
-
-ACPI_STATUS
AnOperandTypecheckWalkEnd (
ACPI_PARSE_OBJECT *Op,
UINT32 Level,
@@ -203,16 +197,73 @@ AnMethodAnalysisWalkEnd (
void *Context);
ACPI_STATUS
-AnMethodTypingWalkBegin (
+AnMethodTypingWalkEnd (
ACPI_PARSE_OBJECT *Op,
UINT32 Level,
void *Context);
-ACPI_STATUS
-AnMethodTypingWalkEnd (
+
+/*
+ * aslbtypes - bitfield data types
+ */
+UINT32
+AnMapObjTypeToBtype (
+ ACPI_PARSE_OBJECT *Op);
+
+UINT32
+AnMapArgTypeToBtype (
+ UINT32 ArgType);
+
+UINT32
+AnGetBtype (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AnFormatBtype (
+ char *Buffer,
+ UINT32 Btype);
+
+
+/*
+ * aslanalyze - Support functions for parse tree walks
+ */
+void
+AnCheckId (
ACPI_PARSE_OBJECT *Op,
- UINT32 Level,
- void *Context);
+ ACPI_NAME Type);
+
+/* Values for Type argument above */
+
+#define ASL_TYPE_HID 0
+#define ASL_TYPE_CID 1
+
+BOOLEAN
+AnIsInternalMethod (
+ ACPI_PARSE_OBJECT *Op);
+
+UINT32
+AnGetInternalMethodReturnType (
+ ACPI_PARSE_OBJECT *Op);
+
+BOOLEAN
+AnLastStatementIsReturn (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AnCheckMethodReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ const ACPI_OPCODE_INFO *OpInfo,
+ ACPI_PARSE_OBJECT *ArgOp,
+ UINT32 RequiredBtypes,
+ UINT32 ThisNodeBtype);
+
+BOOLEAN
+AnIsResultUsed (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+ApCheckForGpeNameConflict (
+ ACPI_PARSE_OBJECT *Op);
/*
@@ -488,6 +539,10 @@ TrCreateValuedLeafNode (
UINT64 Value);
ACPI_PARSE_OBJECT *
+TrCreateConstantLeafNode (
+ UINT32 ParseOpcode);
+
+ACPI_PARSE_OBJECT *
TrLinkChildren (
ACPI_PARSE_OBJECT *Op,
UINT32 NumChildren,
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.l b/sys/contrib/dev/acpica/compiler/aslcompiler.l
index abcc24c..bb41537 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.l
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.l
@@ -392,6 +392,9 @@ NamePathTail [.]{NameSeg}
"AddressRangeNVS" { count (0); return (PARSEOP_ADDRESSTYPE_NVS); }
"AddressRangeACPI" { count (0); return (PARSEOP_ADDRESSTYPE_ACPI); }
+"__DATE__" { count (0); return (PARSEOP___DATE__); }
+"__FILE__" { count (0); return (PARSEOP___FILE__); }
+"__LINE__" { count (0); return (PARSEOP___LINE__); }
"{" { count (0); return('{'); }
"}" { count (0); return('}'); }
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.y b/sys/contrib/dev/acpica/compiler/aslcompiler.y
index 6712586..6a8d4a4 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.y
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.y
@@ -392,6 +392,13 @@ AslLocalAllocate (unsigned int Size);
%token <i> PARSEOP_XOR
%token <i> PARSEOP_ZERO
+/*
+ * Special functions. These should probably stay at the end of this
+ * table.
+ */
+%token <i> PARSEOP___DATE__
+%token <i> PARSEOP___FILE__
+%token <i> PARSEOP___LINE__
/*
* Production names
@@ -695,7 +702,6 @@ AslLocalAllocate (unsigned int Size);
%type <n> OptionalReference
%type <n> OptionalAccessSize
-
%type <n> TermArgItem
%type <n> NameStringItem
@@ -2317,6 +2323,9 @@ ConstExprTerm
: PARSEOP_ZERO {$$ = TrCreateValuedLeafNode (PARSEOP_ZERO, 0);}
| PARSEOP_ONE {$$ = TrCreateValuedLeafNode (PARSEOP_ONE, 1);}
| PARSEOP_ONES {$$ = TrCreateValuedLeafNode (PARSEOP_ONES, ACPI_UINT64_MAX);}
+ | PARSEOP___DATE__ {$$ = TrCreateConstantLeafNode (PARSEOP___DATE__);}
+ | PARSEOP___FILE__ {$$ = TrCreateConstantLeafNode (PARSEOP___FILE__);}
+ | PARSEOP___LINE__ {$$ = TrCreateConstantLeafNode (PARSEOP___LINE__);}
;
/* OptionalCount must appear before ByteList or an incorrect reduction will result */
@@ -3070,7 +3079,6 @@ NameStringItem
| ',' error {$$ = AslDoError (); yyclearin;}
;
-
%%
diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.h b/sys/contrib/dev/acpica/compiler/aslmessages.h
index cab6968..62c51e4 100644
--- a/sys/contrib/dev/acpica/compiler/aslmessages.h
+++ b/sys/contrib/dev/acpica/compiler/aslmessages.h
@@ -188,6 +188,8 @@ typedef enum
ASL_MSG_HID_LENGTH,
ASL_MSG_NULL_STRING,
ASL_MSG_LEADING_ASTERISK,
+ ASL_MSG_RESERVED_NO_RETURN_VAL,
+ ASL_MSG_GPE_NAME_CONFLICT,
ASL_MSG_INVALID_FIELD_NAME,
ASL_MSG_INTEGER_SIZE,
@@ -198,7 +200,10 @@ typedef enum
ASL_MSG_ZERO_VALUE,
ASL_MSG_UNKNOWN_TABLE,
ASL_MSG_UNKNOWN_SUBTABLE,
- ASL_MSG_OEM_TABLE
+ ASL_MSG_OEM_TABLE,
+ ASL_MSG_UNKNOWN_LABEL,
+ ASL_MSG_INVALID_EXPRESSION,
+ ASL_MSG_DIVIDE_BY_ZERO
} ASL_MESSAGE_IDS;
@@ -336,6 +341,8 @@ char *AslMessages [] = {
/* ASL_MSG_HID_LENGTH */ "_HID string must be exactly 7 or 8 characters",
/* ASL_MSG_NULL_STRING */ "Invalid zero-length (null) string",
/* ASL_MSG_LEADING_ASTERISK */ "Invalid leading asterisk",
+/* ASL_MSG_RESERVED_NO_RETURN_VAL */ "Reserved method should not return a value",
+/* ASL_MSG_GPE_NAME_CONFLICT */ "Name conflicts with a previous GPE method",
/* These messages are used by the data table compiler only */
@@ -348,7 +355,10 @@ char *AslMessages [] = {
/* ASL_MSG_ZERO_VALUE */ "Value must be non-zero",
/* ASL_MSG_UNKNOWN_TABLE */ "Unknown ACPI table signature",
/* ASL_MSG_UNKNOWN_SUBTABLE */ "Unknown subtable type",
-/* ASL_MSG_OEM_TABLE */ "OEM table - unknown contents"
+/* ASL_MSG_OEM_TABLE */ "OEM table - unknown contents",
+/* ASL_MSG_UNKNOWN_LABEL */ "Label is undefined",
+/* ASL_MSG_INVALID_EXPRESSION */ "Invalid expression",
+/* ASL_MSG_DIVIDE_BY_ZERO */ "Expression contains divide-by-zero"
};
diff --git a/sys/contrib/dev/acpica/compiler/aslpredef.c b/sys/contrib/dev/acpica/compiler/aslpredef.c
index 10fa91f..e75723c 100644
--- a/sys/contrib/dev/acpica/compiler/aslpredef.c
+++ b/sys/contrib/dev/acpica/compiler/aslpredef.c
@@ -54,6 +54,11 @@
/* Local prototypes */
+static void
+ApCheckForUnexpectedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
static UINT32
ApCheckForSpecialName (
ACPI_PARSE_OBJECT *Op,
@@ -238,6 +243,53 @@ ApCheckForPredefinedMethod (
/*******************************************************************************
*
+ * FUNCTION: ApCheckForUnexpectedReturnValue
+ *
+ * PARAMETERS: Op - A parse node of type "RETURN".
+ * MethodInfo - Saved info about this method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for an unexpected return value from a predefined method.
+ * Invoked for predefined methods that are defined to not return
+ * any value. If there is a return value, issue a remark, since
+ * the ASL writer may be confused as to the method definition
+ * and/or functionality.
+ *
+ * Note: We ignore all return values of "Zero", since this is what a standalone
+ * Return() statement will always generate -- so we ignore it here --
+ * i.e., there is no difference between Return() and Return(Zero).
+ * Also, a null Return() will be disassembled to return(Zero) -- so, we
+ * don't want to generate extraneous remarks/warnings for a disassembled
+ * ASL file.
+ *
+ ******************************************************************************/
+
+static void
+ApCheckForUnexpectedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ ACPI_PARSE_OBJECT *ReturnValueOp;
+
+
+ /* Ignore Return() and Return(Zero) (they are the same) */
+
+ ReturnValueOp = Op->Asl.Child;
+ if (ReturnValueOp->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ return;
+ }
+
+ /* We have a valid return value, but the reserved name did not expect it */
+
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_NO_RETURN_VAL,
+ Op, MethodInfo->Op->Asl.ExternalName);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: ApCheckPredefinedReturnValue
*
* PARAMETERS: Op - A parse node of type "RETURN".
@@ -249,7 +301,9 @@ ApCheckForPredefinedMethod (
* value. Only "static" types can be validated - a simple return
* of an integer/string/buffer/package or a named reference to
* a static object. Values such as a Localx or Argx or a control
- * method invocation are not checked.
+ * method invocation are not checked. Issue a warning if there is
+ * a valid return value, but the reserved method defines no
+ * return value.
*
******************************************************************************/
@@ -269,20 +323,27 @@ ApCheckPredefinedReturnValue (
switch (Index)
{
+ case ACPI_EVENT_RESERVED_NAME: /* _Lxx/_Exx/_Wxx/_Qxx methods */
+
+ /* No return value expected, warn if there is one */
+
+ ApCheckForUnexpectedReturnValue (Op, MethodInfo);
+ return;
+
case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
- case ACPI_EVENT_RESERVED_NAME: /* _Lxx/_Exx/_Wxx/_Qxx methods */
/* Just return, nothing to do */
return;
default: /* A standard predefined ACPI name */
- /* Exit if no return value expected */
-
if (!PredefinedNames[Index].Info.ExpectedBtypes)
{
+ /* No return value expected, warn if there is one */
+
+ ApCheckForUnexpectedReturnValue (Op, MethodInfo);
return;
}
diff --git a/sys/contrib/dev/acpica/compiler/asltree.c b/sys/contrib/dev/acpica/compiler/asltree.c
index da5e9b0..151d3a8 100644
--- a/sys/contrib/dev/acpica/compiler/asltree.c
+++ b/sys/contrib/dev/acpica/compiler/asltree.c
@@ -45,6 +45,7 @@
#include <contrib/dev/acpica/compiler/aslcompiler.h>
#include "aslcompiler.y.h"
+#include <time.h>
#define _COMPONENT ACPI_COMPILER
ACPI_MODULE_NAME ("asltree")
@@ -403,6 +404,75 @@ TrCreateLeafNode (
/*******************************************************************************
*
+ * FUNCTION: TrCreateConstantLeafNode
+ *
+ * PARAMETERS: ParseOpcode - The constant opcode
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Create a leaf node (no children or peers) for one of the
+ * special constants - __LINE__, __FILE__, and __DATE__.
+ *
+ * Note: An implemenation of __FUNC__ cannot happen here because we don't
+ * have a full parse tree at this time and cannot find the parent control
+ * method. If it is ever needed, __FUNC__ must be implemented later, after
+ * the parse tree has been fully constructed.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateConstantLeafNode (
+ UINT32 ParseOpcode)
+{
+ ACPI_PARSE_OBJECT *Op = NULL;
+ time_t CurrentTime;
+ char *StaticTimeString;
+ char *TimeString;
+
+
+ switch (ParseOpcode)
+ {
+ case PARSEOP___LINE__:
+ Op = TrAllocateNode (PARSEOP_INTEGER);
+ Op->Asl.Value.Integer = Op->Asl.LineNumber;
+ break;
+
+ case PARSEOP___FILE__:
+ Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
+
+ /* Op.Asl.Filename contains the full pathname to the file */
+
+ Op->Asl.Value.String = Op->Asl.Filename;
+ break;
+
+ case PARSEOP___DATE__:
+ Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
+
+ /* Get a copy of the current time */
+
+ CurrentTime = time (NULL);
+ StaticTimeString = ctime (&CurrentTime);
+ TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
+ strcpy (TimeString, StaticTimeString);
+
+ TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */
+ Op->Asl.Value.String = TimeString;
+ break;
+
+ default: /* This would be an internal error */
+ return (NULL);
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nCreateConstantLeafNode Ln/Col %u/%u NewNode %p Op %s Value %8.8X%8.8X ",
+ Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
+ ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: TrCreateValuedLeafNode
*
* PARAMETERS: ParseOpcode - New opcode to be assigned to the node
diff --git a/sys/contrib/dev/acpica/compiler/aslwalks.c b/sys/contrib/dev/acpica/compiler/aslwalks.c
new file mode 100644
index 0000000..71dfb43
--- /dev/null
+++ b/sys/contrib/dev/acpica/compiler/aslwalks.c
@@ -0,0 +1,1148 @@
+/******************************************************************************
+ *
+ * Module Name: aslwalks.c - major analytical parse tree walks
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2011, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslwalks")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMethodAnalysisWalkBegin
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
+ * 1) Initialized local variables
+ * 2) Valid arguments
+ * 3) Return types
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnMethodAnalysisWalkBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
+ ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
+ ACPI_PARSE_OBJECT *Next;
+ UINT32 RegisterNumber;
+ UINT32 i;
+ char LocalName[] = "Local0";
+ char ArgName[] = "Arg0";
+ ACPI_PARSE_OBJECT *ArgNode;
+ ACPI_PARSE_OBJECT *NextType;
+ ACPI_PARSE_OBJECT *NextParamType;
+ UINT8 ActualArgs = 0;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+
+ TotalMethods++;
+
+ /* Create and init method info */
+
+ MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
+ MethodInfo->Next = WalkInfo->MethodStack;
+ MethodInfo->Op = Op;
+
+ WalkInfo->MethodStack = MethodInfo;
+
+ /* Get the name node, ignored here */
+
+ Next = Op->Asl.Child;
+
+ /* Get the NumArguments node */
+
+ Next = Next->Asl.Next;
+ MethodInfo->NumArguments = (UINT8)
+ (((UINT8) Next->Asl.Value.Integer) & 0x07);
+
+ /* Get the SerializeRule and SyncLevel nodes, ignored here */
+
+ Next = Next->Asl.Next;
+ Next = Next->Asl.Next;
+ ArgNode = Next;
+
+ /* Get the ReturnType node */
+
+ Next = Next->Asl.Next;
+
+ NextType = Next->Asl.Child;
+ while (NextType)
+ {
+ /* Get and map each of the ReturnTypes */
+
+ MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
+ NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ NextType = NextType->Asl.Next;
+ }
+
+ /* Get the ParameterType node */
+
+ Next = Next->Asl.Next;
+
+ NextType = Next->Asl.Child;
+ while (NextType)
+ {
+ if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ NextParamType = NextType->Asl.Child;
+ while (NextParamType)
+ {
+ MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
+ NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ NextParamType = NextParamType->Asl.Next;
+ }
+ }
+ else
+ {
+ MethodInfo->ValidArgTypes[ActualArgs] =
+ AnMapObjTypeToBtype (NextType);
+ NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ ActualArgs++;
+ }
+
+ NextType = NextType->Asl.Next;
+ }
+
+ if ((MethodInfo->NumArguments) &&
+ (MethodInfo->NumArguments != ActualArgs))
+ {
+ /* error: Param list did not match number of args */
+ }
+
+ /* Allow numarguments == 0 for Function() */
+
+ if ((!MethodInfo->NumArguments) && (ActualArgs))
+ {
+ MethodInfo->NumArguments = ActualArgs;
+ ArgNode->Asl.Value.Integer |= ActualArgs;
+ }
+
+ /*
+ * Actual arguments are initialized at method entry.
+ * All other ArgX "registers" can be used as locals, so we
+ * track their initialization.
+ */
+ for (i = 0; i < MethodInfo->NumArguments; i++)
+ {
+ MethodInfo->ArgInitialized[i] = TRUE;
+ }
+ break;
+
+
+ case PARSEOP_METHODCALL:
+
+ if (MethodInfo &&
+ (Op->Asl.Node == MethodInfo->Op->Asl.Node))
+ {
+ AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
+ }
+ break;
+
+
+ case PARSEOP_LOCAL0:
+ case PARSEOP_LOCAL1:
+ case PARSEOP_LOCAL2:
+ case PARSEOP_LOCAL3:
+ case PARSEOP_LOCAL4:
+ case PARSEOP_LOCAL5:
+ case PARSEOP_LOCAL6:
+ case PARSEOP_LOCAL7:
+
+ if (!MethodInfo)
+ {
+ /*
+ * Local was used outside a control method, or there was an error
+ * in the method declaration.
+ */
+ AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
+ return (AE_ERROR);
+ }
+
+ RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
+
+ /*
+ * If the local is being used as a target, mark the local
+ * initialized
+ */
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
+ }
+
+ /*
+ * Otherwise, this is a reference, check if the local
+ * has been previously initialized.
+ *
+ * The only operator that accepts an uninitialized value is ObjectType()
+ */
+ else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
+ (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
+ {
+ LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
+ AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
+ }
+ break;
+
+
+ case PARSEOP_ARG0:
+ case PARSEOP_ARG1:
+ case PARSEOP_ARG2:
+ case PARSEOP_ARG3:
+ case PARSEOP_ARG4:
+ case PARSEOP_ARG5:
+ case PARSEOP_ARG6:
+
+ if (!MethodInfo)
+ {
+ /*
+ * Arg was used outside a control method, or there was an error
+ * in the method declaration.
+ */
+ AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
+ return (AE_ERROR);
+ }
+
+ RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
+ ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
+
+ /*
+ * If the Arg is being used as a target, mark the local
+ * initialized
+ */
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
+ }
+
+ /*
+ * Otherwise, this is a reference, check if the Arg
+ * has been previously initialized.
+ *
+ * The only operator that accepts an uninitialized value is ObjectType()
+ */
+ else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
+ (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
+ {
+ AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
+ }
+
+ /* Flag this arg if it is not a "real" argument to the method */
+
+ if (RegisterNumber >= MethodInfo->NumArguments)
+ {
+ AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
+ }
+ break;
+
+
+ case PARSEOP_RETURN:
+
+ if (!MethodInfo)
+ {
+ /*
+ * Probably was an error in the method declaration,
+ * no additional error here
+ */
+ ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
+ return (AE_ERROR);
+ }
+
+ /* Child indicates a return value */
+
+ if ((Op->Asl.Child) &&
+ (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
+ {
+ MethodInfo->NumReturnWithValue++;
+ }
+ else
+ {
+ MethodInfo->NumReturnNoValue++;
+ }
+ break;
+
+
+ case PARSEOP_BREAK:
+ case PARSEOP_CONTINUE:
+
+ Next = Op->Asl.Parent;
+ while (Next)
+ {
+ if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
+ {
+ break;
+ }
+ Next = Next->Asl.Parent;
+ }
+
+ if (!Next)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
+ }
+ break;
+
+
+ case PARSEOP_STALL:
+
+ /* We can range check if the argument is an integer */
+
+ if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
+ (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
+ }
+ break;
+
+
+ case PARSEOP_DEVICE:
+ case PARSEOP_EVENT:
+ case PARSEOP_MUTEX:
+ case PARSEOP_OPERATIONREGION:
+ case PARSEOP_POWERRESOURCE:
+ case PARSEOP_PROCESSOR:
+ case PARSEOP_THERMALZONE:
+
+ /*
+ * The first operand is a name to be created in the namespace.
+ * Check against the reserved list.
+ */
+ i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
+ if (i < ACPI_VALID_RESERVED_NAME_MAX)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
+ }
+ break;
+
+
+ case PARSEOP_NAME:
+
+ /* Typecheck any predefined names statically defined with Name() */
+
+ ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
+
+ /* Special typechecking for _HID */
+
+ if (!ACPI_STRCMP (METHOD_NAME__HID, Op->Asl.NameSeg))
+ {
+ Next = Op->Asl.Child->Asl.Next;
+ AnCheckId (Next, ASL_TYPE_HID);
+ }
+
+ /* Special typechecking for _CID */
+
+ else if (!ACPI_STRCMP (METHOD_NAME__CID, Op->Asl.NameSeg))
+ {
+ Next = Op->Asl.Child->Asl.Next;
+
+ if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
+ (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
+ {
+ Next = Next->Asl.Child;
+ while (Next)
+ {
+ AnCheckId (Next, ASL_TYPE_CID);
+ Next = Next->Asl.Next;
+ }
+ }
+ else
+ {
+ AnCheckId (Next, ASL_TYPE_CID);
+ }
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMethodAnalysisWalkEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback for analysis walk. Complete method
+ * return analysis.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnMethodAnalysisWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
+ ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+ case PARSEOP_RETURN:
+ if (!MethodInfo)
+ {
+ printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
+ "No method info for this method");
+
+ CmCleanupAndExit ();
+ return (AE_AML_INTERNAL);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+
+ WalkInfo->MethodStack = MethodInfo->Next;
+
+ /*
+ * Check if there is no return statement at the end of the
+ * method AND we can actually get there -- i.e., the execution
+ * of the method can possibly terminate without a return statement.
+ */
+ if ((!AnLastStatementIsReturn (Op)) &&
+ (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
+ {
+ /*
+ * No return statement, and execution can possibly exit
+ * via this path. This is equivalent to Return ()
+ */
+ MethodInfo->NumReturnNoValue++;
+ }
+
+ /*
+ * Check for case where some return statements have a return value
+ * and some do not. Exit without a return statement is a return with
+ * no value
+ */
+ if (MethodInfo->NumReturnNoValue &&
+ MethodInfo->NumReturnWithValue)
+ {
+ AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
+ Op->Asl.ExternalName);
+ }
+
+ /*
+ * If there are any RETURN() statements with no value, or there is a
+ * control path that allows the method to exit without a return value,
+ * we mark the method as a method that does not return a value. This
+ * knowledge can be used to check method invocations that expect a
+ * returned value.
+ */
+ if (MethodInfo->NumReturnNoValue)
+ {
+ if (MethodInfo->NumReturnWithValue)
+ {
+ Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
+ }
+ else
+ {
+ Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
+ }
+ }
+
+ /*
+ * Check predefined method names for correct return behavior
+ * and correct number of arguments
+ */
+ ApCheckForPredefinedMethod (Op, MethodInfo);
+
+ /* Special check for two names like _L01 and _E01 in same scope */
+
+ ApCheckForGpeNameConflict (Op);
+ ACPI_FREE (MethodInfo);
+ break;
+
+
+ case PARSEOP_NAME:
+
+ /* Special check for two names like _L01 and _E01 in same scope */
+
+ ApCheckForGpeNameConflict (Op);
+ break;
+
+
+ case PARSEOP_RETURN:
+
+ /*
+ * If the parent is a predefined method name, attempt to typecheck
+ * the return value. Only static types can be validated.
+ */
+ ApCheckPredefinedReturnValue (Op, MethodInfo);
+
+ /*
+ * The parent block does not "exit" and continue execution -- the
+ * method is terminated here with the Return() statement.
+ */
+ Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
+
+ /* Used in the "typing" pass later */
+
+ Op->Asl.ParentMethod = MethodInfo->Op;
+
+ /*
+ * If there is a peer node after the return statement, then this
+ * node is unreachable code -- i.e., it won't be executed because of
+ * the preceeding Return() statement.
+ */
+ if (Op->Asl.Next)
+ {
+ AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
+ }
+ break;
+
+
+ case PARSEOP_IF:
+
+ if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
+ (Op->Asl.Next) &&
+ (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
+ {
+ /*
+ * This IF has a corresponding ELSE. The IF block has no exit,
+ * (it contains an unconditional Return)
+ * mark the ELSE block to remember this fact.
+ */
+ Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
+ }
+ break;
+
+
+ case PARSEOP_ELSE:
+
+ if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
+ (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
+ {
+ /*
+ * This ELSE block has no exit and the corresponding IF block
+ * has no exit either. Therefore, the parent node has no exit.
+ */
+ Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
+ }
+ break;
+
+
+ default:
+
+ if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
+ (Op->Asl.Parent))
+ {
+ /* If this node has no exit, then the parent has no exit either */
+
+ Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
+ }
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMethodTypingWalkEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback for typing walk. Complete the method
+ * return analysis. Check methods for:
+ * 1) Initialized local variables
+ * 2) Valid arguments
+ * 3) Return types
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnMethodTypingWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ UINT32 ThisNodeBtype;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+
+ Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
+ break;
+
+ case PARSEOP_RETURN:
+
+ if ((Op->Asl.Child) &&
+ (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
+ {
+ ThisNodeBtype = AnGetBtype (Op->Asl.Child);
+
+ if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
+ (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
+ {
+ /*
+ * The called method is untyped at this time (typically a
+ * forward reference).
+ *
+ * Check for a recursive method call first.
+ */
+ if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
+ {
+ /* We must type the method here */
+
+ TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
+ ASL_WALK_VISIT_UPWARD, NULL,
+ AnMethodTypingWalkEnd, NULL);
+
+ ThisNodeBtype = AnGetBtype (Op->Asl.Child);
+ }
+ }
+
+ /* Returns a value, save the value type */
+
+ if (Op->Asl.ParentMethod)
+ {
+ Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnOperandTypecheckWalkEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback for analysis walk. Complete method
+ * return analysis.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnOperandTypecheckWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 RuntimeArgTypes;
+ UINT32 RuntimeArgTypes2;
+ UINT32 RequiredBtypes;
+ UINT32 ThisNodeBtype;
+ UINT32 CommonBtypes;
+ UINT32 OpcodeClass;
+ ACPI_PARSE_OBJECT *ArgOp;
+ UINT32 ArgType;
+
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_RAW_DATA_BYTE:
+ case AML_RAW_DATA_WORD:
+ case AML_RAW_DATA_DWORD:
+ case AML_RAW_DATA_QWORD:
+ case AML_RAW_DATA_BUFFER:
+ case AML_RAW_DATA_CHAIN:
+ case AML_PACKAGE_LENGTH:
+ case AML_UNASSIGNED_OPCODE:
+ case AML_DEFAULT_ARG_OP:
+
+ /* Ignore the internal (compiler-only) AML opcodes */
+
+ return (AE_OK);
+
+ default:
+ break;
+ }
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+ if (!OpInfo)
+ {
+ return (AE_OK);
+ }
+
+ ArgOp = Op->Asl.Child;
+ RuntimeArgTypes = OpInfo->RuntimeArgs;
+ OpcodeClass = OpInfo->Class;
+
+#ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
+ /*
+ * Update 11/2008: In practice, we can't perform this check. A simple
+ * analysis is not sufficient. Also, it can cause errors when compiling
+ * disassembled code because of the way Switch operators are implemented
+ * (a While(One) loop with a named temp variable created within.)
+ */
+
+ /*
+ * If we are creating a named object, check if we are within a while loop
+ * by checking if the parent is a WHILE op. This is a simple analysis, but
+ * probably sufficient for many cases.
+ *
+ * Allow Scope(), Buffer(), and Package().
+ */
+ if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
+ ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
+ {
+ if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
+ }
+ }
+#endif
+
+ /*
+ * Special case for control opcodes IF/RETURN/WHILE since they
+ * have no runtime arg list (at this time)
+ */
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_RETURN_OP:
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
+ {
+ /* Check for an internal method */
+
+ if (AnIsInternalMethod (ArgOp))
+ {
+ return (AE_OK);
+ }
+
+ /* The lone arg is a method call, check it */
+
+ RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
+ if (Op->Asl.AmlOpcode == AML_RETURN_OP)
+ {
+ RequiredBtypes = 0xFFFFFFFF;
+ }
+
+ ThisNodeBtype = AnGetBtype (ArgOp);
+ if (ThisNodeBtype == ACPI_UINT32_MAX)
+ {
+ return (AE_OK);
+ }
+ AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
+ RequiredBtypes, ThisNodeBtype);
+ }
+ return (AE_OK);
+
+ default:
+ break;
+ }
+
+ /* Ignore the non-executable opcodes */
+
+ if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
+ {
+ return (AE_OK);
+ }
+
+ switch (OpcodeClass)
+ {
+ case AML_CLASS_EXECUTE:
+ case AML_CLASS_CREATE:
+ case AML_CLASS_CONTROL:
+ case AML_CLASS_RETURN_VALUE:
+
+ /* TBD: Change class or fix typechecking for these */
+
+ if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) ||
+ (Op->Asl.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ break;
+ }
+
+ /* Reverse the runtime argument list */
+
+ RuntimeArgTypes2 = 0;
+ while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
+ {
+ RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
+ RuntimeArgTypes2 |= ArgType;
+ INCREMENT_ARG_LIST (RuntimeArgTypes);
+ }
+
+ while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
+ {
+ RequiredBtypes = AnMapArgTypeToBtype (ArgType);
+
+ ThisNodeBtype = AnGetBtype (ArgOp);
+ if (ThisNodeBtype == ACPI_UINT32_MAX)
+ {
+ goto NextArgument;
+ }
+
+ /* Examine the arg based on the required type of the arg */
+
+ switch (ArgType)
+ {
+ case ARGI_TARGETREF:
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ /* ZERO is the placeholder for "don't store result" */
+
+ ThisNodeBtype = RequiredBtypes;
+ break;
+ }
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
+ {
+ /*
+ * This is the case where an original reference to a resource
+ * descriptor field has been replaced by an (Integer) offset.
+ * These named fields are supported at compile-time only;
+ * the names are not passed to the interpreter (via the AML).
+ */
+ if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
+ (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
+ }
+ else
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
+ }
+ break;
+ }
+
+ if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
+ (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
+ {
+ break;
+ }
+
+ ThisNodeBtype = RequiredBtypes;
+ break;
+
+
+ case ARGI_REFERENCE: /* References */
+ case ARGI_INTEGER_REF:
+ case ARGI_OBJECT_REF:
+ case ARGI_DEVICE_REF:
+
+ switch (ArgOp->Asl.ParseOpcode)
+ {
+ case PARSEOP_LOCAL0:
+ case PARSEOP_LOCAL1:
+ case PARSEOP_LOCAL2:
+ case PARSEOP_LOCAL3:
+ case PARSEOP_LOCAL4:
+ case PARSEOP_LOCAL5:
+ case PARSEOP_LOCAL6:
+ case PARSEOP_LOCAL7:
+
+ /* TBD: implement analysis of current value (type) of the local */
+ /* For now, just treat any local as a typematch */
+
+ /*ThisNodeBtype = RequiredBtypes;*/
+ break;
+
+ case PARSEOP_ARG0:
+ case PARSEOP_ARG1:
+ case PARSEOP_ARG2:
+ case PARSEOP_ARG3:
+ case PARSEOP_ARG4:
+ case PARSEOP_ARG5:
+ case PARSEOP_ARG6:
+
+ /* Hard to analyze argument types, sow we won't */
+ /* For now, just treat any arg as a typematch */
+
+ /* ThisNodeBtype = RequiredBtypes; */
+ break;
+
+ case PARSEOP_DEBUG:
+ break;
+
+ case PARSEOP_REFOF:
+ case PARSEOP_INDEX:
+ default:
+ break;
+
+ }
+ break;
+
+ case ARGI_INTEGER:
+ default:
+ break;
+ }
+
+
+ CommonBtypes = ThisNodeBtype & RequiredBtypes;
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
+ {
+ if (AnIsInternalMethod (ArgOp))
+ {
+ return (AE_OK);
+ }
+
+ /* Check a method call for a valid return value */
+
+ AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
+ RequiredBtypes, ThisNodeBtype);
+ }
+
+ /*
+ * Now check if the actual type(s) match at least one
+ * bit to the required type
+ */
+ else if (!CommonBtypes)
+ {
+ /* No match -- this is a type mismatch error */
+
+ AnFormatBtype (StringBuffer, ThisNodeBtype);
+ AnFormatBtype (StringBuffer2, RequiredBtypes);
+
+ sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
+ StringBuffer, OpInfo->Name, StringBuffer2);
+
+ AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
+ }
+
+ NextArgument:
+ ArgOp = ArgOp->Asl.Next;
+ INCREMENT_ARG_LIST (RuntimeArgTypes2);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnOtherSemanticAnalysisWalkBegin
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback for the analysis walk. Checks for
+ * miscellaneous issues in the code.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnOtherSemanticAnalysisWalkBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_PARSE_OBJECT *ArgNode;
+ ACPI_PARSE_OBJECT *PrevArgNode = NULL;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+
+ /*
+ * Determine if an execution class operator actually does something by
+ * checking if it has a target and/or the function return value is used.
+ * (Target is optional, so a standalone statement can actually do nothing.)
+ */
+ if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
+ (OpInfo->Flags & AML_HAS_RETVAL) &&
+ (!AnIsResultUsed (Op)))
+ {
+ if (OpInfo->Flags & AML_HAS_TARGET)
+ {
+ /*
+ * Find the target node, it is always the last child. If the traget
+ * is not specified in the ASL, a default node of type Zero was
+ * created by the parser.
+ */
+ ArgNode = Op->Asl.Child;
+ while (ArgNode->Asl.Next)
+ {
+ PrevArgNode = ArgNode;
+ ArgNode = ArgNode->Asl.Next;
+ }
+
+ /* Divide() is the only weird case, it has two targets */
+
+ if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
+ {
+ if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
+ (PrevArgNode) &&
+ (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
+ {
+ AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED,
+ Op, Op->Asl.ExternalName);
+ }
+ }
+ else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED,
+ Op, Op->Asl.ExternalName);
+ }
+ }
+ else
+ {
+ /*
+ * Has no target and the result is not used. Only a couple opcodes
+ * can have this combination.
+ */
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_ACQUIRE:
+ case PARSEOP_WAIT:
+ case PARSEOP_LOADTABLE:
+ break;
+
+ default:
+ AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED,
+ Op, Op->Asl.ExternalName);
+ break;
+ }
+ }
+ }
+
+
+ /*
+ * Semantic checks for individual ASL operators
+ */
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_ACQUIRE:
+ case PARSEOP_WAIT:
+ /*
+ * Emit a warning if the timeout parameter for these operators is not
+ * ACPI_WAIT_FOREVER, and the result value from the operator is not
+ * checked, meaning that a timeout could happen, but the code
+ * would not know about it.
+ */
+
+ /* First child is the namepath, 2nd child is timeout */
+
+ ArgNode = Op->Asl.Child;
+ ArgNode = ArgNode->Asl.Next;
+
+ /*
+ * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
+ * 0xFFFF or greater
+ */
+ if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
+ (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) &&
+ (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
+ {
+ break;
+ }
+
+ /*
+ * The operation could timeout. If the return value is not used
+ * (indicates timeout occurred), issue a warning
+ */
+ if (!AnIsResultUsed (Op))
+ {
+ AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode,
+ Op->Asl.ExternalName);
+ }
+ break;
+
+ case PARSEOP_CREATEFIELD:
+ /*
+ * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
+ */
+ ArgNode = Op->Asl.Child;
+ ArgNode = ArgNode->Asl.Next;
+ ArgNode = ArgNode->Asl.Next;
+
+ if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) ||
+ ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
+ (ArgNode->Asl.Value.Integer == 0)))
+ {
+ AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (AE_OK);
+}
diff --git a/sys/contrib/dev/acpica/compiler/dtcompile.c b/sys/contrib/dev/acpica/compiler/dtcompile.c
index 206d212..9d5682d 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompile.c
+++ b/sys/contrib/dev/acpica/compiler/dtcompile.c
@@ -426,7 +426,10 @@ DtCompileTable (
Length = DtGetSubtableLength (*Field, Info);
Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE));
- Subtable->Buffer = UtLocalCalloc (Length);
+ if (Length > 0)
+ {
+ Subtable->Buffer = UtLocalCalloc (Length);
+ }
Subtable->Length = Length;
Subtable->TotalLength = Length;
Buffer = Subtable->Buffer;
@@ -470,7 +473,12 @@ DtCompileTable (
}
}
+ /* Maintain table offsets */
+
+ LocalField->TableOffset = Gbl_CurrentTableOffset;
FieldLength = DtGetFieldLength (LocalField, Info);
+ Gbl_CurrentTableOffset += FieldLength;
+
FieldType = DtGetFieldType (Info);
Gbl_InputFieldCount++;
@@ -537,6 +545,12 @@ DtCompileTable (
LocalField = *Field;
break;
+ case DT_FIELD_TYPE_LABEL:
+
+ DtWriteFieldToListing (Buffer, LocalField, 0);
+ LocalField = LocalField->Next;
+ break;
+
default:
/* Normal case for most field types (Integer, String, etc.) */
diff --git a/sys/contrib/dev/acpica/compiler/dtcompiler.h b/sys/contrib/dev/acpica/compiler/dtcompiler.h
index b1c72e2..bce9a1a 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/dtcompiler.h
@@ -73,6 +73,7 @@
#define DT_FIELD_TYPE_UUID 7
#define DT_FIELD_TYPE_UNICODE 8
#define DT_FIELD_TYPE_DEVICE_PATH 9
+#define DT_FIELD_TYPE_LABEL 10
/*
@@ -80,13 +81,15 @@
*/
typedef struct dt_field
{
- char *Name;
- char *Value;
- struct dt_field *Next;
+ char *Name; /* Field name (from name : value) */
+ char *Value; /* Field value (from name : value) */
+ struct dt_field *Next; /* Next field */
+ struct dt_field *NextLabel; /* If field is a label, next label */
UINT32 Line; /* Line number for this field */
UINT32 ByteOffset; /* Offset in source file for field */
UINT32 NameColumn; /* Start column for field name */
UINT32 Column; /* Start column for field value */
+ UINT32 TableOffset;/* Binary offset within ACPI table */
UINT8 Flags;
} DT_FIELD;
@@ -131,6 +134,14 @@ DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_RootTable, NULL);
DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_SubtableStack, NULL);
+/* List for defined labels */
+
+DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_LabelList, NULL);
+
+/* Current offset within the binary output table */
+
+DT_EXTERN UINT32 DT_INIT_GLOBAL (Gbl_CurrentTableOffset, 0);
+
/* dtcompiler - main module */
@@ -207,6 +218,17 @@ DtGetParentSubtable (
DT_SUBTABLE *Subtable);
+/* dtexpress - Integer expressions and labels */
+
+UINT64
+DtResolveIntegerExpression (
+ DT_FIELD *Field);
+
+void
+DtDetectAllLabels (
+ DT_FIELD *FieldList);
+
+
/* dtfield - Compile individual fields within a table */
void
@@ -391,6 +413,10 @@ ACPI_STATUS
DtCompileXsdt (
void **PFieldList);
+ACPI_DMTABLE_INFO *
+DtGetGenericTableInfo (
+ char *Name);
+
/* ACPI Table templates */
extern const unsigned char TemplateAsf[];
diff --git a/sys/contrib/dev/acpica/compiler/dtexpress.c b/sys/contrib/dev/acpica/compiler/dtexpress.c
new file mode 100644
index 0000000..aae83ee
--- /dev/null
+++ b/sys/contrib/dev/acpica/compiler/dtexpress.c
@@ -0,0 +1,390 @@
+/******************************************************************************
+ *
+ * Module Name: dtexpress.c - Support for integer expressions and labels
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2011, 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.
+ */
+
+#define __DTEXPRESS_C__
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtexpress")
+
+
+/* Local prototypes */
+
+static UINT64
+DtResolveInteger (
+ DT_FIELD *Field,
+ char *IntegerString);
+
+static void
+DtInsertLabelField (
+ DT_FIELD *Field);
+
+static DT_FIELD *
+DtLookupLabel (
+ char *Name);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtResolveIntegerExpression
+ *
+ * PARAMETERS: Field - Field object with Integer expression
+ *
+ * RETURN: A 64-bit integer value
+ *
+ * DESCRIPTION: Resolve an integer expression to a single value. Supports
+ * both integer constants and labels. Supported operators are:
+ * +,-,*,/,%,|,&,^
+ *
+ *****************************************************************************/
+
+UINT64
+DtResolveIntegerExpression (
+ DT_FIELD *Field)
+{
+ char *IntegerString;
+ char *Operator;
+ UINT64 Value;
+ UINT64 Value2;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Full Integer expression: %s\n",
+ Field->Value);
+
+ strcpy (MsgBuffer, Field->Value); /* Must take a copy for strtok() */
+
+ /* Obtain and resolve the first operand */
+
+ IntegerString = strtok (MsgBuffer, " ");
+ if (!IntegerString)
+ {
+ DtError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, Field, Field->Value);
+ return (0);
+ }
+
+ Value = DtResolveInteger (Field, IntegerString);
+ DbgPrint (ASL_DEBUG_OUTPUT, "Integer resolved to V1: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (Value));
+
+ /*
+ * Consume the entire expression string. For the rest of the
+ * expression string, values are of the form:
+ * <operator> <integer>
+ */
+ while (1)
+ {
+ Operator = strtok (NULL, " ");
+ if (!Operator)
+ {
+ /* Normal exit */
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Expression Resolved to: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (Value));
+
+ return (Value);
+ }
+
+ IntegerString = strtok (NULL, " ");
+ if (!IntegerString ||
+ (strlen (Operator) > 1))
+ {
+ /* No corresponding operand for operator or invalid operator */
+
+ DtError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, Field, Field->Value);
+ return (0);
+ }
+
+ Value2 = DtResolveInteger (Field, IntegerString);
+ DbgPrint (ASL_DEBUG_OUTPUT, "Integer resolved to V2: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (Value2));
+
+ /* Perform the requested operation */
+
+ switch (*Operator)
+ {
+ case '-':
+ Value -= Value2;
+ break;
+
+ case '+':
+ Value += Value2;
+ break;
+
+ case '*':
+ Value *= Value2;
+ break;
+
+ case '|':
+ Value |= Value2;
+ break;
+
+ case '&':
+ Value &= Value2;
+ break;
+
+ case '^':
+ Value ^= Value2;
+ break;
+
+ case '/':
+ if (!Value2)
+ {
+ DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, Field, Field->Value);
+ return (0);
+ }
+ Value /= Value2;
+ break;
+
+ case '%':
+ if (!Value2)
+ {
+ DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, Field, Field->Value);
+ return (0);
+ }
+ Value %= Value2;
+ break;
+
+ default:
+
+ /* Unknown operator */
+
+ DtFatal (ASL_MSG_INVALID_EXPRESSION, Field, Field->Value);
+ break;
+ }
+ }
+
+ return (Value);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtResolveInteger
+ *
+ * PARAMETERS: Field - Field object with string to be resolved
+ * IntegerString - Integer to be resolved
+ *
+ * RETURN: A 64-bit integer value
+ *
+ * DESCRIPTION: Resolve a single integer string to a value. Supports both
+ * integer constants and labels.
+ *
+ * NOTE: References to labels must begin with a dollar sign ($)
+ *
+ *****************************************************************************/
+
+static UINT64
+DtResolveInteger (
+ DT_FIELD *Field,
+ char *IntegerString)
+{
+ DT_FIELD *LabelField;
+ UINT64 Value = 0;
+ char *Message = NULL;
+ ACPI_STATUS Status;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Resolve Integer: %s\n", IntegerString);
+
+ /* Resolve a label reference to an integer (table offset) */
+
+ if (*IntegerString == '$')
+ {
+ LabelField = DtLookupLabel (IntegerString);
+ if (!LabelField)
+ {
+ DtError (ASL_ERROR, ASL_MSG_UNKNOWN_LABEL, Field, IntegerString);
+ return (0);
+ }
+
+ /* All we need from the label is the offset in the table */
+
+ Value = LabelField->TableOffset;
+ return (Value);
+ }
+
+ /* Convert string to an actual integer */
+
+ Status = DtStrtoul64 (IntegerString, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_LIMIT)
+ {
+ Message = "Constant larger than 64 bits";
+ }
+ else if (Status == AE_BAD_CHARACTER)
+ {
+ Message = "Invalid character in constant";
+ }
+
+ DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, Message);
+ }
+
+ return (Value);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDetectAllLabels
+ *
+ * PARAMETERS: FieldList - Field object at start of generic list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Detect all labels in a list of "generic" opcodes (such as
+ * a UEFI table.) and insert them into the global label list.
+ *
+ *****************************************************************************/
+
+void
+DtDetectAllLabels (
+ DT_FIELD *FieldList)
+{
+ ACPI_DMTABLE_INFO *Info;
+ DT_FIELD *GenericField;
+ UINT32 TableOffset;
+
+
+ TableOffset = Gbl_CurrentTableOffset;
+ GenericField = FieldList;
+
+ /*
+ * Process all "Label:" fields within the parse tree. We need
+ * to know the offsets for all labels before we can compile
+ * the parse tree in order to handle forward references. Traverse
+ * tree and get/set all field lengths of all operators in order to
+ * determine the label offsets.
+ */
+ while (GenericField)
+ {
+ Info = DtGetGenericTableInfo (GenericField->Name);
+ if (Info)
+ {
+ /* Maintain table offsets */
+
+ GenericField->TableOffset = TableOffset;
+ TableOffset += DtGetFieldLength (GenericField, Info);
+
+ /* Insert all labels in the global label list */
+
+ if (Info->Opcode == ACPI_DMT_LABEL)
+ {
+ DtInsertLabelField (GenericField);
+ }
+ }
+
+ GenericField = GenericField->Next;
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtInsertLabelField
+ *
+ * PARAMETERS: Field - Field object with Label to be inserted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a label field into the global label list
+ *
+ *****************************************************************************/
+
+static void
+DtInsertLabelField (
+ DT_FIELD *Field)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "DtInsertLabelField: Found Label : %s at output table offset %X\n",
+ Field->Value, Field->TableOffset);
+
+ Field->NextLabel = Gbl_LabelList;
+ Gbl_LabelList = Field;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtLookupLabel
+ *
+ * PARAMETERS: Name - Label to be resolved
+ *
+ * RETURN: Field object associated with the label
+ *
+ * DESCRIPTION: Lookup a label in the global label list. Used during the
+ * resolution of integer expressions.
+ *
+ *****************************************************************************/
+
+static DT_FIELD *
+DtLookupLabel (
+ char *Name)
+{
+ DT_FIELD *LabelField;
+
+
+ /* Skip a leading $ */
+
+ if (*Name == '$')
+ {
+ Name++;
+ }
+
+ /* Search global list */
+
+ LabelField = Gbl_LabelList;
+ while (LabelField)
+ {
+ if (!ACPI_STRCMP (Name, LabelField->Value))
+ {
+ return (LabelField);
+ }
+ LabelField = LabelField->NextLabel;
+ }
+
+ return (NULL);
+}
diff --git a/sys/contrib/dev/acpica/compiler/dtfield.c b/sys/contrib/dev/acpica/compiler/dtfield.c
index d9d89e0..7039ae8 100644
--- a/sys/contrib/dev/acpica/compiler/dtfield.c
+++ b/sys/contrib/dev/acpica/compiler/dtfield.c
@@ -266,10 +266,12 @@ DtCompileUuid (
* PARAMETERS: Buffer - Output buffer
* Field - Field obj with Integer to be compiled
* ByteLength - Byte length of the integer
+ * Flags - Additional compile info
*
* RETURN: None
*
- * DESCRIPTION: Compile an integer
+ * DESCRIPTION: Compile an integer. Supports integer expressions with C-style
+ * operators.
*
*****************************************************************************/
@@ -280,15 +282,11 @@ DtCompileInteger (
UINT32 ByteLength,
UINT8 Flags)
{
- UINT64 Value = 0;
+ UINT64 Value;
UINT64 MaxValue;
- UINT8 *Hex;
- char *Message = NULL;
- ACPI_STATUS Status;
- int i;
- /* Byte length must be in range 1-8 */
+ /* Output buffer byte length must be in range 1-8 */
if ((ByteLength > 8) || (ByteLength == 0))
{
@@ -297,23 +295,9 @@ DtCompileInteger (
return;
}
- /* Convert string to an actual integer */
-
- Status = DtStrtoul64 (Field->Value, &Value);
- if (ACPI_FAILURE (Status))
- {
- if (Status == AE_LIMIT)
- {
- Message = "Constant larger than 64 bits";
- }
- else if (Status == AE_BAD_CHARACTER)
- {
- Message = "Invalid character in constant";
- }
+ /* Resolve integer expression to a single integer value */
- DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, Message);
- goto Exit;
- }
+ Value = DtResolveIntegerExpression (Field);
/* Ensure that reserved fields are set to zero */
/* TBD: should we set to zero, or just make this an ERROR? */
@@ -344,29 +328,10 @@ DtCompileInteger (
if (Value > MaxValue)
{
- sprintf (MsgBuffer, "Maximum %u bytes", ByteLength);
+ sprintf (MsgBuffer, "%8.8X%8.8X", ACPI_FORMAT_UINT64 (Value));
DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, MsgBuffer);
}
- /*
- * TBD: hard code for ASF! Capabilites field.
- *
- * This field is actually a buffer, not a 56-bit integer --
- * so, the ordering is reversed. Something should be fixed
- * so we don't need this code.
- */
- if (ByteLength == 7)
- {
- Hex = ACPI_CAST_PTR (UINT8, &Value);
- for (i = 6; i >= 0; i--)
- {
- Buffer[i] = *Hex;
- Hex++;
- }
- return;
- }
-
-Exit:
ACPI_MEMCPY (Buffer, &Value, ByteLength);
return;
}
diff --git a/sys/contrib/dev/acpica/compiler/dtio.c b/sys/contrib/dev/acpica/compiler/dtio.c
index e34e777..9ba9acc 100644
--- a/sys/contrib/dev/acpica/compiler/dtio.c
+++ b/sys/contrib/dev/acpica/compiler/dtio.c
@@ -66,7 +66,7 @@ DtParseLine (
UINT32 Line,
UINT32 Offset);
-static UINT32
+UINT32
DtGetNextLine (
FILE *Handle);
@@ -80,8 +80,10 @@ static void
DtDumpBuffer (
UINT32 FileId,
UINT8 *Buffer,
+ UINT32 Offset,
UINT32 Length);
+
/* States for DtGetNextLine */
#define DT_NORMAL_TEXT 0
@@ -324,7 +326,7 @@ DtParseLine (
if (*End == '"')
{
End++;
- while (*End && *End != '"')
+ while (*End && (*End != '"'))
{
End++;
}
@@ -333,9 +335,16 @@ DtParseLine (
break;
}
+ /*
+ * Special "comment" fields at line end, ignore them.
+ * Note: normal slash-slash and slash-asterisk comments are
+ * stripped already by the DtGetNextLine parser.
+ *
+ * TBD: Perhaps DtGetNextLine should parse the following type
+ * of comments also.
+ */
if (*End == '(' ||
- *End == '<' ||
- *End == '/')
+ *End == '<')
{
break;
}
@@ -385,7 +394,7 @@ DtParseLine (
*
*****************************************************************************/
-static UINT32
+UINT32
DtGetNextLine (
FILE *Handle)
{
@@ -400,6 +409,19 @@ DtGetNextLine (
c = (char) getc (Handle);
if (c == EOF)
{
+ switch (State)
+ {
+ case DT_START_QUOTED_STRING:
+ case DT_SLASH_ASTERISK_COMMENT:
+ case DT_SLASH_SLASH_COMMENT:
+
+ AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
+ break;
+
+ default:
+ break;
+ }
+
return (0);
}
@@ -520,6 +542,16 @@ DtGetNextLine (
State = DT_NORMAL_TEXT;
break;
+ case '\n':
+ CurrentLineOffset = Gbl_NextLineOffset;
+ Gbl_NextLineOffset = (UINT32) ftell (Handle);
+ Gbl_CurrentLineNumber++;
+ break;
+
+ case '*':
+ /* Consume all adjacent asterisks */
+ break;
+
default:
State = DT_SLASH_ASTERISK_COMMENT;
break;
@@ -653,6 +685,7 @@ DtOutputBinary (
*
* PARAMETERS: FileID - Where to write buffer data
* Buffer - Buffer to dump
+ * Offset - Offset in current table
* Length - Buffer Length
*
* RETURN: None
@@ -667,6 +700,7 @@ static void
DtDumpBuffer (
UINT32 FileId,
UINT8 *Buffer,
+ UINT32 Offset,
UINT32 Length)
{
UINT32 i;
@@ -674,12 +708,18 @@ DtDumpBuffer (
UINT8 BufChar;
+ FlPrintFile (FileId, "Output: [%3.3Xh %4.4d% 3d] ",
+ Offset, Offset, Length);
+
i = 0;
while (i < Length)
{
- /* Print 16 hex chars */
+ if (i >= 16)
+ {
+ FlPrintFile (FileId, "%23s", "");
+ }
- FlPrintFile (FileId, "Output: [%.3d] ", Length);
+ /* Print 16 hex chars */
for (j = 0; j < 16;)
{
@@ -773,17 +813,9 @@ DtWriteFieldToListing (
FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %s\n",
Field->Column-4, Field->Name, Field->Value);
-#if 0
- /* TBD Dump the length and AML offset */
-
- FlPrintFile (ASL_FILE_LISTING_OUTPUT,
- "Output: Length %d(0x%X) Offset %d(0x%X)\n",
- Field->Column-4, Field->Name, Field->Value);
-#endif
-
/* Dump the hex data that will be output for this field */
- DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Length);
+ DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
}
diff --git a/sys/contrib/dev/acpica/compiler/dttable.c b/sys/contrib/dev/acpica/compiler/dttable.c
index d8ebeb4..8938e2d 100644
--- a/sys/contrib/dev/acpica/compiler/dttable.c
+++ b/sys/contrib/dev/acpica/compiler/dttable.c
@@ -1278,7 +1278,7 @@ DtCompileSrat (
/******************************************************************************
*
- * FUNCTION: DtTableInfoGeneric
+ * FUNCTION: DtGetGenericTableInfo
*
* PARAMETERS: Name - Generic type name
*
@@ -1288,8 +1288,8 @@ DtCompileSrat (
*
*****************************************************************************/
-static ACPI_DMTABLE_INFO *
-DtTableInfoGeneric (
+ACPI_DMTABLE_INFO *
+DtGetGenericTableInfo (
char *Name)
{
ACPI_DMTABLE_INFO *Info;
@@ -1346,6 +1346,8 @@ DtCompileUefi (
UINT16 *DataOffset;
+ /* Compile the predefined portion of the UEFI table */
+
Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
&Subtable, TRUE);
if (ACPI_FAILURE (Status))
@@ -1359,9 +1361,21 @@ DtCompileUefi (
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
+ /*
+ * Compile the "generic" portion of the UEFI table. This
+ * part of the table is not predefined and any of the generic
+ * operators may be used.
+ */
+
+ /* Find any and all labels in the entire generic portion */
+
+ DtDetectAllLabels (*PFieldList);
+
+ /* Now we can actually compile the parse tree */
+
while (*PFieldList)
{
- Info = DtTableInfoGeneric ((*PFieldList)->Name);
+ Info = DtGetGenericTableInfo ((*PFieldList)->Name);
if (!Info)
{
sprintf (MsgBuffer, "Generic data type \"%s\" not found",
diff --git a/sys/contrib/dev/acpica/compiler/dtutils.c b/sys/contrib/dev/acpica/compiler/dtutils.c
index 8ab5e24..e5495b9 100644
--- a/sys/contrib/dev/acpica/compiler/dtutils.c
+++ b/sys/contrib/dev/acpica/compiler/dtutils.c
@@ -399,6 +399,7 @@ DtGetFieldType (
break;
case ACPI_DMT_BUFFER:
+ case ACPI_DMT_BUF7:
case ACPI_DMT_BUF16:
case ACPI_DMT_PCI_PATH:
Type = DT_FIELD_TYPE_BUFFER;
@@ -421,6 +422,10 @@ DtGetFieldType (
Type = DT_FIELD_TYPE_DEVICE_PATH;
break;
+ case ACPI_DMT_LABEL:
+ Type = DT_FIELD_TYPE_LABEL;
+ break;
+
default:
Type = DT_FIELD_TYPE_INTEGER;
break;
@@ -507,6 +512,7 @@ DtGetFieldLength (
case ACPI_DMT_FLAG7:
case ACPI_DMT_FLAGS0:
case ACPI_DMT_FLAGS2:
+ case ACPI_DMT_LABEL:
ByteLength = 0;
break;
@@ -549,6 +555,7 @@ DtGetFieldLength (
break;
case ACPI_DMT_UINT56:
+ case ACPI_DMT_BUF7:
ByteLength = 7;
break;
OpenPOWER on IntegriCloud