ACPI_STATUS AcpiDsBuildInternalObject ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; ACPI_FUNCTION_TRACE ("DsBuildInternalObject"); *ObjDescPtr = NULL; if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { /* * This is an named object reference. If this name was * previously looked up in the namespace, it was stored in this op. * Otherwise, go ahead and look it up now */ if (!Op->Common.Node) { Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, (ACPI_NAMESPACE_NODE **) &(Op->Common.Node)); if (ACPI_FAILURE (Status)) { ACPI_REPORT_NSERROR (Op->Common.Value.String, Status); return_ACPI_STATUS (Status); } } } /* Create and init the internal ACPI object */ ObjDesc = AcpiUtCreateInternalObject ((AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); return_ACPI_STATUS (Status); } *ObjDescPtr = ObjDesc; return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiDsCreateOperand ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Arg, UINT32 ArgIndex) { ACPI_STATUS Status = AE_OK; char *NameString; UINT32 NameLength; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_PARSE_OBJECT *ParentOp; UINT16 Opcode; ACPI_INTERPRETER_MODE InterpreterMode; const ACPI_OPCODE_INFO *OpInfo; ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg); /* A valid name must be looked up in the namespace */ if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && (Arg->Common.Value.String) && !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg)); /* Get the entire name string from the AML stream */ Status = AcpiExGetNameString (ACPI_TYPE_ANY, Arg->Common.Value.Buffer, &NameString, &NameLength); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* All prefixes have been handled, and the name is in NameString */ /* * Special handling for BufferField declarations. This is a deferred * opcode that unfortunately defines the field name as the last * parameter instead of the first. We get here when we are performing * the deferred execution, so the actual name of the field is already * in the namespace. We don't want to attempt to look it up again * because we may be executing in a different scope than where the * actual opcode exists. */ if ((WalkState->DeferredNode) && (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) && (ArgIndex == (UINT32) ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2))) { ObjDesc = ACPI_CAST_PTR ( ACPI_OPERAND_OBJECT, WalkState->DeferredNode); Status = AE_OK; } else /* All other opcodes */ { /* * Differentiate between a namespace "create" operation * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. * IMODE_EXECUTE) in order to support the creation of * namespace objects during the execution of control methods. */ ParentOp = Arg->Common.Parent; OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode); if ((OpInfo->Flags & AML_NSNODE) && (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) && (ParentOp->Common.AmlOpcode != AML_REGION_OP) && (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) { /* Enter name into namespace if not found */ InterpreterMode = ACPI_IMODE_LOAD_PASS2; } else { /* Return a failure if name not found */ InterpreterMode = ACPI_IMODE_EXECUTE; } Status = AcpiNsLookup (WalkState->ScopeInfo, NameString, ACPI_TYPE_ANY, InterpreterMode, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, WalkState, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc)); /* * The only case where we pass through (ignore) a NOT_FOUND * error is for the CondRefOf opcode. */ if (Status == AE_NOT_FOUND) { if (ParentOp->Common.AmlOpcode == AML_COND_REF_OF_OP) { /* * For the Conditional Reference op, it's OK if * the name is not found; We just need a way to * indicate this to the interpreter, set the * object to the root */ ObjDesc = ACPI_CAST_PTR ( ACPI_OPERAND_OBJECT, AcpiGbl_RootNode); Status = AE_OK; } else { /* * We just plain didn't find it -- which is a * very serious error at this point */ Status = AE_AML_NAME_NOT_FOUND; } } if (ACPI_FAILURE (Status)) { ACPI_ERROR_NAMESPACE (NameString, Status); } } /* Free the namestring created above */ ACPI_FREE (NameString); /* Check status from the lookup */ if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Put the resulting object onto the current object stack */ Status = AcpiDsObjStackPush (ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); } else { /* Check for null name case */ if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) { /* * If the name is null, this means that this is an * optional result parameter that was not specified * in the original ASL. Create a Zero Constant for a * placeholder. (Store to a constant is a Noop.) */ Opcode = AML_ZERO_OP; /* Has no arguments! */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", Arg)); } else { Opcode = Arg->Common.AmlOpcode; } /* Get the object type of the argument */ OpInfo = AcpiPsGetOpcodeInfo (Opcode); if (OpInfo->ObjectType == ACPI_TYPE_INVALID) { return_ACPI_STATUS (AE_NOT_IMPLEMENTED); } if ((OpInfo->Flags & AML_HAS_RETVAL) || (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Argument previously created, already stacked\n")); ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject ( WalkState->Operands [WalkState->NumOperands - 1], WalkState)); /* * Use value that was already previously returned * by the evaluation of this argument */ Status = AcpiDsResultPop (&ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { /* * Only error is underflow, and this indicates * a missing or null operand! */ ACPI_EXCEPTION ((AE_INFO, Status, "Missing or null operand")); return_ACPI_STATUS (Status); } } else { /* Create an ACPI_INTERNAL_OBJECT for the argument */ ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Initialize the new object */ Status = AcpiDsInitObjectFromOp ( WalkState, Arg, Opcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtDeleteObjectDesc (ObjDesc); return_ACPI_STATUS (Status); } } /* Put the operand object on the object stack */ Status = AcpiDsObjStackPush (ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); } return_ACPI_STATUS (AE_OK); }
static ACPI_STATUS AcpiDsBuildInternalObject ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; ACPI_OBJECT_TYPE Type; ACPI_FUNCTION_TRACE (DsBuildInternalObject); *ObjDescPtr = NULL; if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { /* * This is a named object reference. If this name was * previously looked up in the namespace, it was stored in this op. * Otherwise, go ahead and look it up now */ if (!Op->Common.Node) { Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); if (ACPI_FAILURE (Status)) { /* Check if we are resolving a named reference within a package */ if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) { /* * We didn't find the target and we are populating elements * of a package - ignore if slack enabled. Some ASL code * contains dangling invalid references in packages and * expects that no exception will be issued. Leave the * element as a null element. It cannot be used, but it * can be overwritten by subsequent ASL code - this is * typically the case. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Ignoring unresolved reference in package [%4.4s]\n", WalkState->ScopeInfo->Scope.Node->Name.Ascii)); return_ACPI_STATUS (AE_OK); } else { ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); } return_ACPI_STATUS (Status); } } /* Special object resolution for elements of a package */ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) { /* * Attempt to resolve the node to a value before we insert it into * the package. If this is a reference to a common data type, * resolve it immediately. According to the ACPI spec, package * elements can only be "data objects" or method references. * Attempt to resolve to an Integer, Buffer, String or Package. * If cannot, return the named reference (for things like Devices, * Methods, etc.) Buffer Fields and Fields will resolve to simple * objects (int/buf/str/pkg). * * NOTE: References to things like Devices, Methods, Mutexes, etc. * will remain as named references. This behavior is not described * in the ACPI spec, but it appears to be an oversight. */ ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node); Status = AcpiExResolveNodeToValue ( ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc), WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * Special handling for Alias objects. We need to setup the type * and the Op->Common.Node to point to the Alias target. Note, * Alias has at most one level of indirection internally. */ Type = Op->Common.Node->Type; if (Type == ACPI_TYPE_LOCAL_ALIAS) { Type = ObjDesc->Common.Type; Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Op->Common.Node->Object); } switch (Type) { /* * For these types, we need the actual node, not the subobject. * However, the subobject did not get an extra reference count above. * * TBD: should ExResolveNodeToValue be changed to fix this? */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_THERMAL: AcpiUtAddReference (Op->Common.Node->Object); /*lint -fallthrough */ /* * For these types, we need the actual node, not the subobject. * The subobject got an extra reference count in ExResolveNodeToValue. */ case ACPI_TYPE_MUTEX: case ACPI_TYPE_METHOD: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_EVENT: case ACPI_TYPE_REGION: /* We will create a reference object for these types below */ break; default: /* * All other types - the node was resolved to an actual * object, we are done. */ goto Exit; } } } /* Create and init a new internal ACPI object */ ObjDesc = AcpiUtCreateInternalObject ( (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); return_ACPI_STATUS (Status); } Exit: *ObjDescPtr = ObjDesc; return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiDsBuildInternalObject ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (DsBuildInternalObject); *ObjDescPtr = NULL; if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { /* * This is a named object reference. If this name was * previously looked up in the namespace, it was stored in * this op. Otherwise, go ahead and look it up now */ if (!Op->Common.Node) { /* Check if we are resolving a named reference within a package */ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)) { /* * We won't resolve package elements here, we will do this * after all ACPI tables are loaded into the namespace. This * behavior supports both forward references to named objects * and external references to objects in other tables. */ goto CreateNewObject; } else { Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, ACPI_CAST_INDIRECT_PTR ( ACPI_NAMESPACE_NODE, &(Op->Common.Node))); if (ACPI_FAILURE (Status)) { ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Op->Common.Value.String, Status); return_ACPI_STATUS (Status); } } } } CreateNewObject: /* Create and init a new internal ACPI object */ ObjDesc = AcpiUtCreateInternalObject ( (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitObjectFromOp ( WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); return_ACPI_STATUS (Status); } /* * Handling for unresolved package reference elements. * These are elements that are namepaths. */ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)) { ObjDesc->Reference.Resolved = TRUE; if ((Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && !ObjDesc->Reference.Node) { /* * Name was unresolved above. * Get the prefix node for later lookup */ ObjDesc->Reference.Node = WalkState->ScopeInfo->Scope.Node; ObjDesc->Reference.Aml = Op->Common.Aml; ObjDesc->Reference.Resolved = FALSE; } } *ObjDescPtr = ObjDesc; return_ACPI_STATUS (Status); }
static ACPI_STATUS AcpiDsBuildInternalObject ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (DsBuildInternalObject); *ObjDescPtr = NULL; if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { /* * This is a named object reference. If this name was * previously looked up in the namespace, it was stored in this op. * Otherwise, go ahead and look it up now */ if (!Op->Common.Node) { Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); if (ACPI_FAILURE (Status)) { /* Check if we are resolving a named reference within a package */ if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) { /* * We didn't find the target and we are populating elements * of a package - ignore if slack enabled. Some ASL code * contains dangling invalid references in packages and * expects that no exception will be issued. Leave the * element as a null element. It cannot be used, but it * can be overwritten by subsequent ASL code - this is * typically the case. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Ignoring unresolved reference in package [%4.4s]\n", WalkState->ScopeInfo->Scope.Node->Name.Ascii)); return_ACPI_STATUS (AE_OK); } else { ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); } return_ACPI_STATUS (Status); } } } /* Create and init a new internal ACPI object */ ObjDesc = AcpiUtCreateInternalObject ( (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); return_ACPI_STATUS (Status); } *ObjDescPtr = ObjDesc; return_ACPI_STATUS (AE_OK); }