summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/compiler/aslwalks.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/compiler/aslwalks.c')
-rw-r--r--sys/contrib/dev/acpica/compiler/aslwalks.c573
1 files changed, 2 insertions, 571 deletions
diff --git a/sys/contrib/dev/acpica/compiler/aslwalks.c b/sys/contrib/dev/acpica/compiler/aslwalks.c
index 77bff82..6613cac 100644
--- a/sys/contrib/dev/acpica/compiler/aslwalks.c
+++ b/sys/contrib/dev/acpica/compiler/aslwalks.c
@@ -1,11 +1,11 @@
/******************************************************************************
*
- * Module Name: aslwalks.c - major analytical parse tree walks
+ * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
*
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,575 +54,6 @@
/*******************************************************************************
*
- * 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);
- }
-
- /*
- * A child indicates a possible return value. A simple Return or
- * Return() is marked with NODE_IS_NULL_RETURN by the parser so
- * that it is not counted as a "real" return-with-value, although
- * the AML code that is actually emitted is Return(0). The AML
- * definition of Return has a required parameter, so we are
- * forced to convert a null return to Return(0).
- */
- if ((Op->Asl.Child) &&
- (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
- (!(Op->Asl.Child->Asl.CompileFlags & NODE_IS_NULL_RETURN)))
- {
- 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. Also, some special checks
- * For GPE and _REG methods.
- */
- if (ApCheckForPredefinedMethod (Op, MethodInfo))
- {
- /* Special check for two names like _L01 and _E01 in same scope */
-
- ApCheckForGpeNameConflict (Op);
-
- /*
- * Special check for _REG: Must have an operation region definition
- * within the same scope!
- */
- ApCheckRegMethod (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 preceding 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
OpenPOWER on IntegriCloud