static ACPI_STATUS XfNamespaceLocateEnd ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; const ACPI_OPCODE_INFO *OpInfo; ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd); /* We are only interested in opcodes that have an associated name */ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); if (!(OpInfo->Flags & AML_NAMED)) { return_ACPI_STATUS (AE_OK); } /* Not interested in name references, we did not open a scope for them */ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) { return_ACPI_STATUS (AE_OK); } /* Pop the scope stack if necessary */ if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode))) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "%s: Popping scope for Op %p\n", AcpiUtGetTypeName (OpInfo->ObjectType), Op)); (void) AcpiDsScopeStackPop (WalkState); } return_ACPI_STATUS (AE_OK); }
static ACPI_STATUS AcpiNsDumpOneObjectPath ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { UINT32 MaxLevel = *((UINT32 *) Context); char *Pathname; ACPI_NAMESPACE_NODE *Node; int PathIndent; if (!ObjHandle) { return (AE_OK); } Node = AcpiNsValidateHandle (ObjHandle); if (!Node) { /* Ignore bad node during namespace walk */ return (AE_OK); } Pathname = AcpiNsGetNormalizedPathname (Node, TRUE); PathIndent = 1; if (Level <= MaxLevel) { PathIndent = MaxLevel - Level + 1; } AcpiOsPrintf ("%2d%*s%-12s%*s", Level, Level, " ", AcpiUtGetTypeName (Node->Type), PathIndent, " "); AcpiOsPrintf ("%s\n", &Pathname[1]); ACPI_FREE (Pathname); return (AE_OK); }
void AcpiDsScopeStackClear ( ACPI_WALK_STATE *WalkState) { ACPI_GENERIC_STATE *ScopeInfo; ACPI_FUNCTION_NAME ("DsScopeStackClear"); while (WalkState->ScopeInfo) { /* Pop a scope off the stack */ ScopeInfo = WalkState->ScopeInfo; WalkState->ScopeInfo = ScopeInfo->Scope.Next; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Popped object type (%s)\n", AcpiUtGetTypeName (ScopeInfo->Common.Value))); AcpiUtDeleteGenericState (ScopeInfo); } }
static ACPI_STATUS AcpiDsMethodDataSetValue ( UINT8 Type, UINT32 Index, ACPI_OPERAND_OBJECT *Object, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; ACPI_FUNCTION_TRACE (DsMethodDataSetValue); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object, Type, Object->Common.ReferenceCount, AcpiUtGetTypeName (Object->Common.Type))); /* Get the namespace node for the arg/local */ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * Increment ref count so object can't be deleted while installed. * NOTE: We do not copy the object in order to preserve the call by * reference semantics of ACPI Control Method invocation. * (See ACPI Specification 2.0C) */ AcpiUtAddReference (Object); /* Install the object */ Node->Object = Object; return_ACPI_STATUS (Status); }
void AcpiDbDisplayResources ( char *ObjectArg) { ACPI_NAMESPACE_NODE *Node; AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); AcpiDbgLevel |= ACPI_LV_RESOURCES; /* Asterisk means "display resources for all devices" */ if (!ObjectArg || (!strcmp (ObjectArg, "*"))) { (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL); } else { /* Convert string to object pointer */ Node = AcpiDbConvertToNode (ObjectArg); if (Node) { if (Node->Type != ACPI_TYPE_DEVICE) { AcpiOsPrintf ( "%4.4s: Name is not a device object (%s)\n", Node->Name.Ascii, AcpiUtGetTypeName (Node->Type)); } else { (void) AcpiDbDeviceResources (Node, 0, NULL, NULL); } } } AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); }
static ACPI_STATUS AcpiNsCheckObjectType ( ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT **ReturnObjectPtr, UINT32 ExpectedBtypes, UINT32 PackageIndex) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_STATUS Status = AE_OK; UINT32 ReturnBtype; char TypeBuffer[48]; /* Room for 5 types */ /* * If we get a NULL ReturnObject here, it is a NULL package element. * Since all extraneous NULL package elements were removed earlier by a * call to AcpiNsRemoveNullElements, this is an unexpected NULL element. * We will attempt to repair it. */ if (!ReturnObject) { Status = AcpiNsRepairNullElement (Data, ExpectedBtypes, PackageIndex, ReturnObjectPtr); if (ACPI_SUCCESS (Status)) { return (AE_OK); /* Repair was successful */ } goto TypeErrorExit; } /* A Namespace node should not get here, but make sure */ if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) { ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Invalid return type - Found a Namespace node [%4.4s] type %s", ReturnObject->Node.Name.Ascii, AcpiUtGetTypeName (ReturnObject->Node.Type))); return (AE_AML_OPERAND_TYPE); } /* * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. * The bitmapped type allows multiple possible return types. * * Note, the cases below must handle all of the possible types returned * from all of the predefined names (including elements of returned * packages) */ switch (ReturnObject->Common.Type) { case ACPI_TYPE_INTEGER: ReturnBtype = ACPI_RTYPE_INTEGER; break; case ACPI_TYPE_BUFFER: ReturnBtype = ACPI_RTYPE_BUFFER; break; case ACPI_TYPE_STRING: ReturnBtype = ACPI_RTYPE_STRING; break; case ACPI_TYPE_PACKAGE: ReturnBtype = ACPI_RTYPE_PACKAGE; break; case ACPI_TYPE_LOCAL_REFERENCE: ReturnBtype = ACPI_RTYPE_REFERENCE; break; default: /* Not one of the supported objects, must be incorrect */ goto TypeErrorExit; } /* Is the object one of the expected types? */ if (ReturnBtype & ExpectedBtypes) { /* For reference objects, check that the reference type is correct */ if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) { Status = AcpiNsCheckReference (Data, ReturnObject); } return (Status); } /* Type mismatch -- attempt repair of the returned object */ Status = AcpiNsRepairObject (Data, ExpectedBtypes, PackageIndex, ReturnObjectPtr); if (ACPI_SUCCESS (Status)) { return (AE_OK); /* Repair was successful */ } TypeErrorExit: /* Create a string with all expected types for this predefined object */ AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes); if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) { ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Return type mismatch - found %s, expected %s", AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); } else { ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Return Package type mismatch at index %u - " "found %s, expected %s", PackageIndex, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); } return (AE_AML_OPERAND_TYPE); }
static ACPI_STATUS XfNamespaceLocateBegin ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; ACPI_NAMESPACE_NODE *Node; ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; char *Path; UINT8 PassedArgs; ACPI_PARSE_OBJECT *NextOp; ACPI_PARSE_OBJECT *OwningOp; ACPI_PARSE_OBJECT *SpaceIdOp; UINT32 MinimumLength; UINT32 Offset; UINT32 FieldBitLength; UINT32 TagBitLength; UINT8 Message = 0; const ACPI_OPCODE_INFO *OpInfo; UINT32 Flags; ASL_METHOD_LOCAL *MethodLocals = NULL; ASL_METHOD_LOCAL *MethodArgs = NULL; int RegisterNumber; UINT32 i; ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op); if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node) { Node = Op->Asl.Node; /* Support for method LocalX/ArgX analysis */ if (!Node->MethodLocals) { /* Create local/arg info blocks */ MethodLocals = UtLocalCalloc ( sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS); Node->MethodLocals = MethodLocals; MethodArgs = UtLocalCalloc ( sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS); Node->MethodArgs = MethodArgs; /* * Get the method argument count * First, get the name node */ NextOp = Op->Asl.Child; /* Get the NumArguments node */ NextOp = NextOp->Asl.Next; Node->ArgCount = (UINT8) (((UINT8) NextOp->Asl.Value.Integer) & 0x07); /* We will track all possible ArgXs */ for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) { if (i < Node->ArgCount) { /* Real Args are always "initialized" */ MethodArgs[i].Flags = ASL_ARG_INITIALIZED; } else { /* Other ArgXs can be used as locals */ MethodArgs[i].Flags = ASL_ARG_IS_LOCAL; } MethodArgs[i].Op = Op; } } } /* * If this node is the actual declaration of a name * [such as the XXXX name in "Method (XXXX)"], * we are not interested in it here. We only care about names that are * references to other objects within the namespace and the parent objects * of name declarations */ if (Op->Asl.CompileFlags & OP_IS_NAME_DECLARATION) { return_ACPI_STATUS (AE_OK); } OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); /* Check method LocalX variables */ if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE) { /* Find parent method Op */ NextOp = XfGetParentMethod (Op); if (!NextOp) { return_ACPI_STATUS (AE_OK); } /* Get method node */ Node = NextOp->Asl.Node; RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */ MethodLocals = Node->MethodLocals; if (Op->Asl.CompileFlags & OP_IS_TARGET) { /* Local is being initialized */ MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED; MethodLocals[RegisterNumber].Op = Op; return_ACPI_STATUS (AE_OK); } /* Mark this Local as referenced */ MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED; MethodLocals[RegisterNumber].Op = Op; return_ACPI_STATUS (AE_OK); } /* Check method ArgX variables */ if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT) { /* Find parent method Op */ NextOp = XfGetParentMethod (Op); if (!NextOp) { return_ACPI_STATUS (AE_OK); } /* Get method node */ Node = NextOp->Asl.Node; /* Get Arg # */ RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */ MethodArgs = Node->MethodArgs; /* Mark this Arg as referenced */ MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED; MethodArgs[RegisterNumber].Op = Op; if (Op->Asl.CompileFlags & OP_IS_TARGET) { /* Arg is being initialized */ MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED; } return_ACPI_STATUS (AE_OK); } /* * After method ArgX and LocalX, we are only interested in opcodes * that have an associated name */ if ((!(OpInfo->Flags & AML_NAMED)) && (!(OpInfo->Flags & AML_CREATE)) && (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) && (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) && (Op->Asl.ParseOpcode != PARSEOP_METHODCALL) && (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) { return_ACPI_STATUS (AE_OK); } /* * One special case: CondRefOf operator - we don't care if the name exists * or not at this point, just ignore it, the point of the operator is to * determine if the name exists at runtime. */ if ((Op->Asl.Parent) && (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)) { return_ACPI_STATUS (AE_OK); } /* * We must enable the "search-to-root" for single NameSegs, but * we have to be very careful about opening up scopes */ Flags = ACPI_NS_SEARCH_PARENT; if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) || (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) { /* * These are name references, do not push the scope stack * for them. */ Flags |= ACPI_NS_DONT_OPEN_SCOPE; } /* Get the NamePath from the appropriate place */ if (OpInfo->Flags & AML_NAMED) { /* For nearly all NAMED operators, the name reference is the first child */ Path = Op->Asl.Child->Asl.Value.String; if (Op->Asl.AmlOpcode == AML_ALIAS_OP) { /* * ALIAS is the only oddball opcode, the name declaration * (alias name) is the second operand */ Path = Op->Asl.Child->Asl.Next->Asl.Value.String; } } else if (OpInfo->Flags & AML_CREATE) { /* Name must appear as the last parameter */ NextOp = Op->Asl.Child; while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION)) { NextOp = NextOp->Asl.Next; } Path = NextOp->Asl.Value.String; } else { Path = Op->Asl.Value.String; } ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Type=%s\n", AcpiUtGetTypeName (ObjectType))); /* * Lookup the name in the namespace. Name must exist at this point, or it * is an invalid reference. * * The namespace is also used as a lookup table for references to resource * descriptors and the fields within them. */ AslGbl_NsLookupCount++; Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_EXECUTE, Flags, WalkState, &Node); if (ACPI_FAILURE (Status)) { if (Status == AE_NOT_FOUND) { /* * We didn't find the name reference by path -- we can qualify this * a little better before we print an error message */ if (strlen (Path) == ACPI_NAME_SIZE) { /* A simple, one-segment ACPI name */ if (XfObjectExists (Path)) { /* * There exists such a name, but we couldn't get to it * from this scope */ AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op, Op->Asl.ExternalName); } else { /* The name doesn't exist, period */ AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName); } } else { /* The NamePath contains multiple NameSegs */ if ((OpInfo->Flags & AML_CREATE) || (OpInfo->ObjectType == ACPI_TYPE_LOCAL_ALIAS)) { /* * The new name is the last parameter. For the * CreateXXXXField and Alias operators */ NextOp = Op->Asl.Child; while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION)) { NextOp = NextOp->Asl.Next; } AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, NextOp, NextOp->Asl.ExternalName); } else if (OpInfo->Flags & AML_NAMED) { /* The new name is the first parameter */ AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, Op, Op->Asl.ExternalName); } else if (Path[0] == AML_ROOT_PREFIX) { /* Full namepath from root, the object does not exist */ AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName); } else { /* * Generic "not found" error. Cannot determine whether it * doesn't exist or just can't be reached. However, we * can differentiate between a NameSeg vs. NamePath. */ if (strlen (Op->Asl.ExternalName) == ACPI_NAME_SIZE) { AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName); } else { AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op, Op->Asl.ExternalName); } } } Status = AE_OK; } return_ACPI_STATUS (Status); } /* Check for an attempt to access an object in another method */ if (!XfValidateCrossReference (Op, OpInfo, Node)) { AslError (ASL_ERROR, ASL_MSG_TEMPORARY_OBJECT, Op, Op->Asl.ExternalName); return_ACPI_STATUS (Status); } /* Object was found above, check for an illegal forward reference */ if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD) { /* * During the load phase, this Op was flagged as a possible * illegal forward reference * * Note: Allow "forward references" from within a method to an * object that is not within any method (module-level code) */ if (!WalkState->ScopeInfo || (UtGetParentMethod (Node) && !UtNodeIsDescendantOf (WalkState->ScopeInfo->Scope.Node, UtGetParentMethod (Node)))) { AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op, Op->Asl.ExternalName); } } /* Check for a reference vs. name declaration */ if (!(OpInfo->Flags & AML_NAMED) && !(OpInfo->Flags & AML_CREATE)) { /* This node has been referenced, mark it for reference check */ Node->Flags |= ANOBJ_IS_REFERENCED; } /* Attempt to optimize the NamePath */ OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node); /* * 1) Dereference an alias (A name reference that is an alias) * Aliases are not nested, the alias always points to the final object */ if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) && (Node->Type == ACPI_TYPE_LOCAL_ALIAS)) { /* This node points back to the original PARSEOP_ALIAS */ NextOp = Node->Op; /* The first child is the alias target op */ NextOp = NextOp->Asl.Child; /* That in turn points back to original target alias node */ if (NextOp->Asl.Node) { Node = NextOp->Asl.Node; } /* Else - forward reference to alias, will be resolved later */ } /* 2) Check for a reference to a resource descriptor */ if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || (Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) { /* * This was a reference to a field within a resource descriptor. * Extract the associated field offset (either a bit or byte * offset depending on the field type) and change the named * reference into an integer for AML code generation */ Offset = Node->Value; TagBitLength = Node->Length; /* * If a field is being created, generate the length (in bits) of * the field. Note: Opcodes other than CreateXxxField and Index * can come through here. For other opcodes, we just need to * convert the resource tag reference to an integer offset. */ switch (Op->Asl.Parent->Asl.AmlOpcode) { case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */ /* * We know the length operand is an integer constant because * we know that it contains a reference to a resource * descriptor tag. */ FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer; break; case AML_CREATE_BIT_FIELD_OP: FieldBitLength = 1; break; case AML_CREATE_BYTE_FIELD_OP: case AML_INDEX_OP: FieldBitLength = 8; break; case AML_CREATE_WORD_FIELD_OP: FieldBitLength = 16; break; case AML_CREATE_DWORD_FIELD_OP: FieldBitLength = 32; break; case AML_CREATE_QWORD_FIELD_OP: FieldBitLength = 64; break; default: FieldBitLength = 0; break; } /* Check the field length against the length of the resource tag */ if (FieldBitLength) { if (TagBitLength < FieldBitLength) { Message = ASL_MSG_TAG_SMALLER; } else if (TagBitLength > FieldBitLength) { Message = ASL_MSG_TAG_LARGER; } if (Message) { sprintf (AslGbl_MsgBuffer, "Size mismatch, Tag: %u bit%s, Field: %u bit%s", TagBitLength, (TagBitLength > 1) ? "s" : "", FieldBitLength, (FieldBitLength > 1) ? "s" : ""); AslError (ASL_WARNING, Message, Op, AslGbl_MsgBuffer); } } /* Convert the BitOffset to a ByteOffset for certain opcodes */ switch (Op->Asl.Parent->Asl.AmlOpcode) { case AML_CREATE_BYTE_FIELD_OP: case AML_CREATE_WORD_FIELD_OP: case AML_CREATE_DWORD_FIELD_OP: case AML_CREATE_QWORD_FIELD_OP: case AML_INDEX_OP: Offset = ACPI_DIV_8 (Offset); break; default: break; } /* Now convert this node to an integer whose value is the field offset */ Op->Asl.AmlLength = 0; Op->Asl.ParseOpcode = PARSEOP_INTEGER; Op->Asl.Value.Integer = (UINT64) Offset; Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD; OpcGenerateAmlOpcode (Op); } /* 3) Check for a method invocation */ else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) && (Node->Type == ACPI_TYPE_METHOD) && (Op->Asl.Parent) && (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) || (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) { /* * A reference to a method within one of these opcodes is not an * invocation of the method, it is simply a reference to the method. * * September 2016: Removed DeRefOf from this list */ if ((Op->Asl.Parent) && ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF) || (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE) || (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)|| (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE))) { return_ACPI_STATUS (AE_OK); } /* * There are two types of method invocation: * 1) Invocation with arguments -- the parser recognizes this * as a METHODCALL. * 2) Invocation with no arguments --the parser cannot determine that * this is a method invocation, therefore we have to figure it out * here. */ if (Node->Type != ACPI_TYPE_METHOD) { sprintf (AslGbl_MsgBuffer, "%s is a %s", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, AslGbl_MsgBuffer); return_ACPI_STATUS (AE_OK); } /* Save the method node in the caller's op */ Op->Asl.Node = Node; if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF) { return_ACPI_STATUS (AE_OK); } /* * This is a method invocation, with or without arguments. * Count the number of arguments, each appears as a child * under the parent node */ Op->Asl.ParseOpcode = PARSEOP_METHODCALL; UtSetParseOpName (Op); PassedArgs = 0; NextOp = Op->Asl.Child; while (NextOp) { PassedArgs++; NextOp = NextOp->Asl.Next; } if (Node->Value != ASL_EXTERNAL_METHOD && Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL) { /* * Check the parsed arguments with the number expected by the * method declaration itself */ if (PassedArgs != Node->Value) { sprintf (AslGbl_MsgBuffer, "%s requires %u", Op->Asl.ExternalName, Node->Value); if (PassedArgs < Node->Value) { AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, AslGbl_MsgBuffer); } else { AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, AslGbl_MsgBuffer); } } } } /* 4) Check for an ASL Field definition */ else if ((Op->Asl.Parent) && ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) || (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD))) { /* * Offset checking for fields. If the parent operation region has a * constant length (known at compile time), we can check fields * defined in that region against the region length. This will catch * fields and field units that cannot possibly fit within the region. * * Note: Index fields do not directly reference an operation region, * thus they are not included in this check. */ if (Op == Op->Asl.Parent->Asl.Child) { /* * This is the first child of the field node, which is * the name of the region. Get the parse node for the * region -- which contains the length of the region. */ OwningOp = Node->Op; Op->Asl.Parent->Asl.ExtraValue = ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer); /* Examine the field access width */ switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer) { case AML_FIELD_ACCESS_ANY: case AML_FIELD_ACCESS_BYTE: case AML_FIELD_ACCESS_BUFFER: default: MinimumLength = 1; break; case AML_FIELD_ACCESS_WORD: MinimumLength = 2; break; case AML_FIELD_ACCESS_DWORD: MinimumLength = 4; break; case AML_FIELD_ACCESS_QWORD: MinimumLength = 8; break; } /* * Is the region at least as big as the access width? * Note: DataTableRegions have 0 length */ if (((UINT32) OwningOp->Asl.Value.Integer) && ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength)) { AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL); } /* * Check EC/CMOS/SMBUS fields to make sure that the correct * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS) */ SpaceIdOp = OwningOp->Asl.Child->Asl.Next; switch ((UINT32) SpaceIdOp->Asl.Value.Integer) { case ACPI_ADR_SPACE_EC: case ACPI_ADR_SPACE_CMOS: case ACPI_ADR_SPACE_GPIO: if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE) { AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL); } break; case ACPI_ADR_SPACE_SMBUS: case ACPI_ADR_SPACE_IPMI: case ACPI_ADR_SPACE_GSBUS: if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER) { AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL); } break; default: /* Nothing to do for other address spaces */ break; } } else { /* * This is one element of the field list. Check to make sure * that it does not go beyond the end of the parent operation region. * * In the code below: * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits) * Op->Asl.ExtraValue - Field start offset (bits) * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits) * Op->Asl.Child->Asl.ExtraValue - Field access width (bits) */ if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child) { XfCheckFieldRange (Op, Op->Asl.Parent->Asl.ExtraValue, Op->Asl.ExtraValue, (UINT32) Op->Asl.Child->Asl.Value.Integer, Op->Asl.Child->Asl.ExtraValue); } } } /* 5) Check for a connection object */ #if 0 else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION) { return_ACPI_STATUS (Status); } #endif Op->Asl.Node = Node; return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiExResolveObject ( ACPI_OPERAND_OBJECT **SourceDescPtr, ACPI_OBJECT_TYPE TargetType, ACPI_WALK_STATE *WalkState) { ACPI_OPERAND_OBJECT *SourceDesc = *SourceDescPtr; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE (ExResolveObject); /* Ensure we have a Target that can be stored to */ switch (TargetType) { case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: /* * These cases all require only Integers or values that * can be converted to Integers (Strings or Buffers) */ case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * Stores into a Field/Region or into a Integer/Buffer/String * are all essentially the same. This case handles the * "interchangeable" types Integer, String, and Buffer. */ if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) { /* Resolve a reference object first */ Status = AcpiExResolveToValue (SourceDescPtr, WalkState); if (ACPI_FAILURE (Status)) { break; } } /* For CopyObject, no further validation necessary */ if (WalkState->Opcode == AML_COPY_OP) { break; } /* Must have a Integer, Buffer, or String */ if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) && (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) && (SourceDesc->Common.Type != ACPI_TYPE_STRING) && !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE))) { /* Conversion successful but still not a valid type */ ACPI_ERROR ((AE_INFO, "Cannot assign type %s to %s (must be type Int/Str/Buf)", AcpiUtGetObjectTypeName (SourceDesc), AcpiUtGetTypeName (TargetType))); Status = AE_AML_OPERAND_TYPE; } break; case ACPI_TYPE_LOCAL_ALIAS: case ACPI_TYPE_LOCAL_METHOD_ALIAS: /* * All aliases should have been resolved earlier, during the * operand resolution phase. */ ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object")); Status = AE_AML_INTERNAL; break; case ACPI_TYPE_PACKAGE: default: /* * All other types than Alias and the various Fields come here, * including the untyped case - ACPI_TYPE_ANY. */ break; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiEvQueueNotifyRequest ( ACPI_NAMESPACE_NODE *Node, UINT32 NotifyValue) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_OPERAND_OBJECT *HandlerListHead = NULL; ACPI_GENERIC_STATE *Info; UINT8 HandlerListId = 0; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_NAME (EvQueueNotifyRequest); /* Are Notifies allowed on this object? */ if (!AcpiEvIsNotifyObject (Node)) { return (AE_TYPE); } /* Get the correct notify list type (System or Device) */ if (NotifyValue <= ACPI_MAX_SYS_NOTIFY) { HandlerListId = ACPI_SYSTEM_HANDLER_LIST; } else { HandlerListId = ACPI_DEVICE_HANDLER_LIST; } /* Get the notify object attached to the namespace Node */ ObjDesc = AcpiNsGetAttachedObject (Node); if (ObjDesc) { /* We have an attached object, Get the correct handler list */ HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId]; } /* * If there is no notify handler (Global or Local) * for this object, just ignore the notify */ if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n", AcpiUtGetNodeName (Node), NotifyValue, Node)); return (AE_OK); } /* Setup notify info and schedule the notify dispatcher */ Info = AcpiUtCreateGenericState (); if (!Info) { return (AE_NO_MEMORY); } Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY; Info->Notify.Node = Node; Info->Notify.Value = (UINT16) NotifyValue; Info->Notify.HandlerListId = HandlerListId; Info->Notify.HandlerListHead = HandlerListHead; Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId]; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), NotifyValue, AcpiUtGetNotifyName (NotifyValue, ACPI_TYPE_ANY), Node)); Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch, Info); if (ACPI_FAILURE (Status)) { AcpiUtDeleteGenericState (Info); } return (Status); }
ACPI_OPERAND_OBJECT * AcpiUtCreateInternalObjectDbg ( const char *ModuleName, UINT32 LineNumber, UINT32 ComponentId, ACPI_OBJECT_TYPE Type) { ACPI_OPERAND_OBJECT *Object; ACPI_OPERAND_OBJECT *SecondObject; ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg, AcpiUtGetTypeName (Type)); /* Allocate the raw object descriptor */ Object = AcpiUtAllocateObjectDescDbg ( ModuleName, LineNumber, ComponentId); if (!Object) { return_PTR (NULL); } switch (Type) { case ACPI_TYPE_REGION: case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: /* These types require a secondary object */ SecondObject = AcpiUtAllocateObjectDescDbg ( ModuleName, LineNumber, ComponentId); if (!SecondObject) { AcpiUtDeleteObjectDesc (Object); return_PTR (NULL); } SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA; SecondObject->Common.ReferenceCount = 1; /* Link the second object to the first */ Object->Common.NextObject = SecondObject; break; default: /* All others have no secondary object */ break; } /* Save the object type in the object descriptor */ Object->Common.Type = (UINT8) Type; /* Init the reference count */ Object->Common.ReferenceCount = 1; /* Any per-type initialization should go here */ return_PTR (Object); }
static ACPI_STATUS AcpiNsInitOneObject ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_OBJECT_TYPE Type; ACPI_STATUS Status = AE_OK; ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_FUNCTION_NAME (NsInitOneObject); Info->ObjectCount++; /* And even then, we are only interested in a few object types */ Type = AcpiNsGetType (ObjHandle); ObjDesc = AcpiNsGetAttachedObject (Node); if (!ObjDesc) { return (AE_OK); } /* Increment counters for object types we are looking for */ switch (Type) { case ACPI_TYPE_REGION: Info->OpRegionCount++; break; case ACPI_TYPE_BUFFER_FIELD: Info->FieldCount++; break; case ACPI_TYPE_LOCAL_BANK_FIELD: Info->FieldCount++; break; case ACPI_TYPE_BUFFER: Info->BufferCount++; break; case ACPI_TYPE_PACKAGE: Info->PackageCount++; break; default: /* No init required, just exit now */ return (AE_OK); } /* If the object is already initialized, nothing else to do */ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) { return (AE_OK); } /* Must lock the interpreter before executing AML code */ AcpiExEnterInterpreter (); /* * Each of these types can contain executable AML code within the * declaration. */ switch (Type) { case ACPI_TYPE_REGION: Info->OpRegionInit++; Status = AcpiDsGetRegionArguments (ObjDesc); break; case ACPI_TYPE_BUFFER_FIELD: Info->FieldInit++; Status = AcpiDsGetBufferFieldArguments (ObjDesc); break; case ACPI_TYPE_LOCAL_BANK_FIELD: Info->FieldInit++; Status = AcpiDsGetBankFieldArguments (ObjDesc); break; case ACPI_TYPE_BUFFER: Info->BufferInit++; Status = AcpiDsGetBufferArguments (ObjDesc); break; case ACPI_TYPE_PACKAGE: Info->PackageInit++; Status = AcpiDsGetPackageArguments (ObjDesc); break; default: /* No other types can get here */ break; } if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not execute arguments for [%4.4s] (%s)", AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type))); } /* * We ignore errors from above, and always return OK, since we don't want * to abort the walk on any single error. */ AcpiExExitInterpreter (); return (AE_OK); }
ACPI_STATUS AcpiDsScopeStackPush ( ACPI_NAMESPACE_NODE *Node, ACPI_OBJECT_TYPE Type, ACPI_WALK_STATE *WalkState) { ACPI_GENERIC_STATE *ScopeInfo; ACPI_GENERIC_STATE *OldScopeInfo; ACPI_FUNCTION_TRACE (DsScopeStackPush); if (!Node) { /* Invalid scope */ ACPI_ERROR ((AE_INFO, "Null scope parameter")); return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Make sure object type is valid */ if (!AcpiUtValidObjectType (Type)) { ACPI_WARNING ((AE_INFO, "Invalid object type: 0x%X", Type)); } /* Allocate a new scope object */ ScopeInfo = AcpiUtCreateGenericState (); if (!ScopeInfo) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Init new scope object */ ScopeInfo->Common.DescriptorType = ACPI_DESC_TYPE_STATE_WSCOPE; ScopeInfo->Scope.Node = Node; ScopeInfo->Common.Value = (UINT16) Type; WalkState->ScopeDepth++; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%.2d] Pushed scope ", (UINT32) WalkState->ScopeDepth)); OldScopeInfo = WalkState->ScopeInfo; if (OldScopeInfo) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "[%4.4s] (%s)", AcpiUtGetNodeName (OldScopeInfo->Scope.Node), AcpiUtGetTypeName (OldScopeInfo->Common.Value))); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, ACPI_NAMESPACE_ROOT)); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, ", New scope -> [%4.4s] (%s)\n", AcpiUtGetNodeName (ScopeInfo->Scope.Node), AcpiUtGetTypeName (ScopeInfo->Common.Value))); /* Push new scope object onto stack */ AcpiUtPushGenericState (&WalkState->ScopeInfo, ScopeInfo); return_ACPI_STATUS (AE_OK); }
static ACPI_STATUS AcpiNsDumpOneObject ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; ACPI_NAMESPACE_NODE *ThisNode; UINT8 *Value; ACPI_OPERAND_OBJECT *ObjDesc = NULL; ACPI_OBJECT_TYPE8 ObjType; ACPI_OBJECT_TYPE8 Type; UINT32 BytesToDump; UINT32 DownstreamSiblingMask = 0; UINT32 LevelTmp; UINT32 WhichBit; PROC_NAME ("NsDumpOneObject"); ThisNode = AcpiNsConvertHandleToEntry (ObjHandle); LevelTmp = Level; Type = ThisNode->Type; WhichBit = 1; if (!(AcpiDbgLevel & Info->DebugLevel)) { return (AE_OK); } if (!ObjHandle) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n")); return (AE_OK); } /* Check if the owner matches */ if ((Info->OwnerId != ACPI_UINT32_MAX) && (Info->OwnerId != ThisNode->OwnerId)) { return (AE_OK); } /* Indent the object according to the level */ while (LevelTmp--) { /* Print appropriate characters to form tree structure */ if (LevelTmp) { if (DownstreamSiblingMask & WhichBit) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|")); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); } WhichBit <<= 1; } else { if (AcpiNsExistDownstreamSibling (ThisNode + 1)) { DownstreamSiblingMask |= (1 << (Level - 1)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } else { DownstreamSiblingMask &= ACPI_UINT32_MAX ^ (1 << (Level - 1)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } if (ThisNode->Child == NULL) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); } else if (AcpiNsExistDownstreamSibling (ThisNode->Child)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); } } } /* Check the integrity of our data */ if (Type > INTERNAL_TYPE_MAX) { Type = INTERNAL_TYPE_DEF_ANY; /* prints as *ERROR* */ } if (!AcpiUtValidAcpiName (ThisNode->Name)) { REPORT_WARNING (("Invalid ACPI Name %08X\n", ThisNode->Name)); } /* * Now we can print out the pertinent information */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-9s ", &ThisNode->Name, AcpiUtGetTypeName (Type))); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p S:%p O:%p", ThisNode, ThisNode->Child, ThisNode->Object)); if (!ThisNode->Object) { /* No attached object, we are done */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); return (AE_OK); } switch (Type) { case ACPI_TYPE_METHOD: /* Name is a Method and its AML offset/length are set */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Method.Pcode, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Method.PcodeLength)); break; case ACPI_TYPE_INTEGER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Integer.Value)); break; case ACPI_TYPE_STRING: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->String.Pointer, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->String.Length)); break; case ACPI_TYPE_BUFFER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Buffer.Pointer, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Buffer.Length)); break; default: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); break; } /* If debug turned off, done */ if (!(AcpiDbgLevel & ACPI_LV_VALUES)) { return (AE_OK); } /* If there is an attached object, display it */ Value = ThisNode->Object; /* Dump attached objects */ while (Value) { ObjType = INTERNAL_TYPE_INVALID; /* Decode the type of attached object and dump the contents */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Attached Object %p: ", Value)); if (AcpiTbSystemTablePointer (Value)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to AML Code)\n")); BytesToDump = 16; } else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n")); BytesToDump = sizeof (ACPI_NAMESPACE_NODE); } else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_INTERNAL)) { ObjDesc = (ACPI_OPERAND_OBJECT *) Value; ObjType = ObjDesc->Common.Type; if (ObjType > INTERNAL_TYPE_MAX) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", ObjType)); BytesToDump = 32; } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [%s])\n", ObjType, AcpiUtGetTypeName (ObjType))); BytesToDump = sizeof (ACPI_OPERAND_OBJECT); } } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n", Value)); BytesToDump = 16; } DUMP_BUFFER (Value, BytesToDump); /* If value is NOT an internal object, we are done */ if ((AcpiTbSystemTablePointer (Value)) || (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED))) { goto Cleanup; } /* * Valid object, get the pointer to next level, if any */ switch (ObjType) { case ACPI_TYPE_STRING: Value = (UINT8 *) ObjDesc->String.Pointer; break; case ACPI_TYPE_BUFFER: Value = (UINT8 *) ObjDesc->Buffer.Pointer; break; case ACPI_TYPE_BUFFER_FIELD: Value = (UINT8 *) ObjDesc->BufferField.BufferObj; break; case ACPI_TYPE_PACKAGE: Value = (UINT8 *) ObjDesc->Package.Elements; break; case ACPI_TYPE_METHOD: Value = (UINT8 *) ObjDesc->Method.Pcode; break; case INTERNAL_TYPE_REGION_FIELD: Value = (UINT8 *) ObjDesc->Field.RegionObj; break; case INTERNAL_TYPE_BANK_FIELD: Value = (UINT8 *) ObjDesc->BankField.RegionObj; break; case INTERNAL_TYPE_INDEX_FIELD: Value = (UINT8 *) ObjDesc->IndexField.IndexObj; break; default: goto Cleanup; } ObjType = INTERNAL_TYPE_INVALID; /* Terminate loop after next pass */ } Cleanup: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); return (AE_OK); }
void AcpiNsInstallNode ( ACPI_WALK_STATE *WalkState, ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ ACPI_NAMESPACE_NODE *Node, /* New Child*/ ACPI_OBJECT_TYPE Type) { ACPI_OWNER_ID OwnerId = 0; ACPI_NAMESPACE_NODE *ChildNode; ACPI_FUNCTION_TRACE (NsInstallNode); /* * Get the owner ID from the Walk state * The owner ID is used to track table deletion and * deletion of objects created by methods */ if (WalkState) { OwnerId = WalkState->OwnerId; } /* Link the new entry into the parent and existing children */ ChildNode = ParentNode->Child; if (!ChildNode) { ParentNode->Child = Node; Node->Flags |= ANOBJ_END_OF_PEER_LIST; Node->Peer = ParentNode; } else { while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) { ChildNode = ChildNode->Peer; } ChildNode->Peer = Node; /* Clear end-of-list flag */ ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; Node->Flags |= ANOBJ_END_OF_PEER_LIST; Node->Peer = ParentNode; } /* Init the new entry */ Node->OwnerId = OwnerId; Node->Type = (UINT8) Type; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), ParentNode)); return_VOID; }
ACPI_STATUS AcpiDsExecBeginOp ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT **OutOp) { ACPI_PARSE_OBJECT *Op; ACPI_STATUS Status = AE_OK; UINT32 OpcodeClass; ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState); Op = WalkState->Op; if (!Op) { Status = AcpiDsLoad2BeginOp (WalkState, OutOp); if (ACPI_FAILURE (Status)) { goto ErrorExit; } Op = *OutOp; WalkState->Op = Op; WalkState->Opcode = Op->Common.AmlOpcode; WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n", AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op)); Status = AcpiDsScopeStackPop (WalkState); if (ACPI_FAILURE (Status)) { goto ErrorExit; } } } if (Op == WalkState->Origin) { if (OutOp) { *OutOp = Op; } return_ACPI_STATUS (AE_OK); } /* * If the previous opcode was a conditional, this opcode * must be the beginning of the associated predicate. * Save this knowledge in the current scope descriptor */ if ((WalkState->ControlState) && (WalkState->ControlState->Common.State == ACPI_CONTROL_CONDITIONAL_EXECUTING)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n", Op, WalkState)); WalkState->ControlState->Common.State = ACPI_CONTROL_PREDICATE_EXECUTING; /* Save start of predicate */ WalkState->ControlState->Control.PredicateOp = Op; } OpcodeClass = WalkState->OpInfo->Class; /* We want to send namepaths to the load code */ if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { OpcodeClass = AML_CLASS_NAMED_OBJECT; } /* * Handle the opcode based upon the opcode type */ switch (OpcodeClass) { case AML_CLASS_CONTROL: Status = AcpiDsExecBeginControlOp (WalkState, Op); break; case AML_CLASS_NAMED_OBJECT: if (WalkState->WalkType & ACPI_WALK_METHOD) { /* * Found a named object declaration during method execution; * we must enter this object into the namespace. The created * object is temporary and will be deleted upon completion of * the execution of this method. * * Note 10/2010: Except for the Scope() op. This opcode does * not actually create a new object, it refers to an existing * object. However, for Scope(), we want to indeed open a * new scope. */ if (Op->Common.AmlOpcode != AML_SCOPE_OP) { Status = AcpiDsLoad2BeginOp (WalkState, NULL); } else { Status = AcpiDsScopeStackPush ( Op->Named.Node, Op->Named.Node->Type, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } } break; case AML_CLASS_EXECUTE: case AML_CLASS_CREATE: break; default: break; } /* Nothing to do here during method execution */ return_ACPI_STATUS (Status); ErrorExit: Status = AcpiDsMethodError (Status, WalkState); return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiEvaluateObjectTyped ( ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer, ACPI_OBJECT_TYPE ReturnType) { ACPI_STATUS Status; BOOLEAN MustFree = FALSE; ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); /* Return buffer must be valid */ if (!ReturnBuffer) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) { MustFree = TRUE; } /* Evaluate the object */ Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Type ANY means "don't care" */ if (ReturnType == ACPI_TYPE_ANY) { return_ACPI_STATUS (AE_OK); } if (ReturnBuffer->Length == 0) { /* Error because caller specifically asked for a return value */ ACPI_ERROR ((AE_INFO, "No return value")); return_ACPI_STATUS (AE_NULL_OBJECT); } /* Examine the object type returned from EvaluateObject */ if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) { return_ACPI_STATUS (AE_OK); } /* Return object type does not match requested type */ ACPI_ERROR ((AE_INFO, "Incorrect return type [%s] requested [%s]", AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), AcpiUtGetTypeName (ReturnType))); if (MustFree) { /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ AcpiOsFree (ReturnBuffer->Pointer); ReturnBuffer->Pointer = NULL; } ReturnBuffer->Length = 0; return_ACPI_STATUS (AE_TYPE); }
ACPI_STATUS AcpiExResolveNodeToValue ( ACPI_NAMESPACE_NODE **ObjectPtr, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_OPERAND_OBJECT *SourceDesc; ACPI_OPERAND_OBJECT *ObjDesc = NULL; ACPI_NAMESPACE_NODE *Node; ACPI_OBJECT_TYPE EntryType; ACPI_FUNCTION_TRACE (ExResolveNodeToValue); /* * The stack pointer points to a ACPI_NAMESPACE_NODE (Node). Get the * object that is attached to the Node. */ Node = *ObjectPtr; SourceDesc = AcpiNsGetAttachedObject (Node); EntryType = AcpiNsGetType ((ACPI_HANDLE) Node); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p SourceDesc=%p [%s]\n", Node, SourceDesc, AcpiUtGetTypeName (EntryType))); if ((EntryType == ACPI_TYPE_LOCAL_ALIAS) || (EntryType == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { /* There is always exactly one level of indirection */ Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Node->Object); SourceDesc = AcpiNsGetAttachedObject (Node); EntryType = AcpiNsGetType ((ACPI_HANDLE) Node); *ObjectPtr = Node; } /* * Several object types require no further processing: * 1) Device/Thermal objects don't have a "real" subobject, return the Node * 2) Method locals and arguments have a pseudo-Node * 3) 10/2007: Added method type to assist with Package construction. */ if ((EntryType == ACPI_TYPE_DEVICE) || (EntryType == ACPI_TYPE_THERMAL) || (EntryType == ACPI_TYPE_METHOD) || (Node->Flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { return_ACPI_STATUS (AE_OK); } if (!SourceDesc) { ACPI_ERROR ((AE_INFO, "No object attached to node %p", Node)); return_ACPI_STATUS (AE_AML_NO_OPERAND); } /* * Action is based on the type of the Node, which indicates the type * of the attached object or pointer */ switch (EntryType) { case ACPI_TYPE_PACKAGE: if (SourceDesc->Common.Type != ACPI_TYPE_PACKAGE) { ACPI_ERROR ((AE_INFO, "Object not a Package, type %s", AcpiUtGetObjectTypeName (SourceDesc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } Status = AcpiDsGetPackageArguments (SourceDesc); if (ACPI_SUCCESS (Status)) { /* Return an additional reference to the object */ ObjDesc = SourceDesc; AcpiUtAddReference (ObjDesc); } break; case ACPI_TYPE_BUFFER: if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) { ACPI_ERROR ((AE_INFO, "Object not a Buffer, type %s", AcpiUtGetObjectTypeName (SourceDesc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } Status = AcpiDsGetBufferArguments (SourceDesc); if (ACPI_SUCCESS (Status)) { /* Return an additional reference to the object */ ObjDesc = SourceDesc; AcpiUtAddReference (ObjDesc); } break; case ACPI_TYPE_STRING: if (SourceDesc->Common.Type != ACPI_TYPE_STRING) { ACPI_ERROR ((AE_INFO, "Object not a String, type %s", AcpiUtGetObjectTypeName (SourceDesc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Return an additional reference to the object */ ObjDesc = SourceDesc; AcpiUtAddReference (ObjDesc); break; case ACPI_TYPE_INTEGER: if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER) { ACPI_ERROR ((AE_INFO, "Object not a Integer, type %s", AcpiUtGetObjectTypeName (SourceDesc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Return an additional reference to the object */ ObjDesc = SourceDesc; AcpiUtAddReference (ObjDesc); break; case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "FieldRead Node=%p SourceDesc=%p Type=%X\n", Node, SourceDesc, EntryType)); Status = AcpiExReadDataFromField (WalkState, SourceDesc, &ObjDesc); break; /* For these objects, just return the object attached to the Node */ case ACPI_TYPE_MUTEX: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_EVENT: case ACPI_TYPE_REGION: /* Return an additional reference to the object */ ObjDesc = SourceDesc; AcpiUtAddReference (ObjDesc); break; /* TYPE_ANY is untyped, and thus there is no object associated with it */ case ACPI_TYPE_ANY: ACPI_ERROR ((AE_INFO, "Untyped entry %p, no attached object!", Node)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ case ACPI_TYPE_LOCAL_REFERENCE: switch (SourceDesc->Reference.Class) { case ACPI_REFCLASS_TABLE: /* This is a DdbHandle */ case ACPI_REFCLASS_REFOF: case ACPI_REFCLASS_INDEX: /* Return an additional reference to the object */ ObjDesc = SourceDesc; AcpiUtAddReference (ObjDesc); break; default: /* No named references are allowed here */ ACPI_ERROR ((AE_INFO, "Unsupported Reference type 0x%X", SourceDesc->Reference.Class)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } break; default: /* Default case is for unknown types */ ACPI_ERROR ((AE_INFO, "Node %p - Unknown object type 0x%X", Node, EntryType)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* switch (EntryType) */ /* Return the object descriptor */ *ObjectPtr = (void *) ObjDesc; return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiExStoreObjectToNode ( ACPI_OPERAND_OBJECT *SourceDesc, ACPI_NAMESPACE_NODE *Node, ACPI_WALK_STATE *WalkState, UINT8 ImplicitConversion) { ACPI_STATUS Status = AE_OK; ACPI_OPERAND_OBJECT *TargetDesc; ACPI_OPERAND_OBJECT *NewDesc; ACPI_OBJECT_TYPE TargetType; ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToNode, SourceDesc); /* Get current type of the node, and object attached to Node */ TargetType = AcpiNsGetType (Node); TargetDesc = AcpiNsGetAttachedObject (Node); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n", SourceDesc, AcpiUtGetObjectTypeName (SourceDesc), Node, AcpiUtGetTypeName (TargetType))); /* * Resolve the source object to an actual value * (If it is a reference object) */ Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Do the actual store operation */ switch (TargetType) { case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * The simple data types all support implicit source operand * conversion before the store. */ if ((WalkState->Opcode == AML_COPY_OP) || !ImplicitConversion) { /* * However, CopyObject and Stores to ArgX do not perform * an implicit conversion, as per the ACPI specification. * A direct store is performed instead. */ Status = AcpiExStoreDirectToNode (SourceDesc, Node, WalkState); break; } /* Store with implicit source operand conversion support */ Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc, &NewDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } if (NewDesc != TargetDesc) { /* * Store the new NewDesc as the new value of the Name, and set * the Name's type to that of the value being stored in it. * SourceDesc reference count is incremented by AttachObject. * * Note: This may change the type of the node if an explicit * store has been performed such that the node/object type * has been changed. */ Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Store %s into %s via Convert/Attach\n", AcpiUtGetObjectTypeName (SourceDesc), AcpiUtGetObjectTypeName (NewDesc))); } break; case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: /* * For all fields, always write the source data to the target * field. Any required implicit source operand conversion is * performed in the function below as necessary. Note, field * objects must retain their original type permanently. */ Status = AcpiExWriteDataToField (SourceDesc, TargetDesc, &WalkState->ResultObj); break; default: /* * No conversions for all other types. Directly store a copy of * the source object. This is the ACPI spec-defined behavior for * the CopyObject operator. * * NOTE: For the Store operator, this is a departure from the * ACPI spec, which states "If conversion is impossible, abort * the running control method". Instead, this code implements * "If conversion is impossible, treat the Store operation as * a CopyObject". */ Status = AcpiExStoreDirectToNode (SourceDesc, Node, WalkState); break; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiNsEvaluate ( ACPI_EVALUATE_INFO *Info) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE (NsEvaluate); if (!Info) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (!Info->Node) { /* * Get the actual namespace node for the target object if we * need to. Handles these cases: * * 1) Null node, valid pathname from root (absolute path) * 2) Node and valid pathname (path relative to Node) * 3) Node, Null pathname */ Status = AcpiNsGetNode (Info->PrefixNode, Info->RelativePathname, ACPI_NS_NO_UPSEARCH, &Info->Node); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } /* * For a method alias, we must grab the actual method node so that * proper scoping context will be established before execution. */ if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { Info->Node = ACPI_CAST_PTR ( ACPI_NAMESPACE_NODE, Info->Node->Object); } /* Complete the info block initialization */ Info->ReturnObject = NULL; Info->NodeFlags = Info->Node->Flags; Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node); ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", Info->RelativePathname, Info->Node, AcpiNsGetAttachedObject (Info->Node))); /* Get info if we have a predefined name (_HID, etc.) */ Info->Predefined = AcpiUtMatchPredefinedMethod (Info->Node->Name.Ascii); /* Get the full pathname to the object, for use in warning messages */ Info->FullPathname = AcpiNsGetExternalPathname (Info->Node); if (!Info->FullPathname) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Count the number of arguments being passed in */ Info->ParamCount = 0; if (Info->Parameters) { while (Info->Parameters[Info->ParamCount]) { Info->ParamCount++; } /* Warn on impossible argument count */ if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) { ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, "Excess arguments (%u) - using only %u", Info->ParamCount, ACPI_METHOD_NUM_ARGS)); Info->ParamCount = ACPI_METHOD_NUM_ARGS; } } /* * For predefined names: Check that the declared argument count * matches the ACPI spec -- otherwise this is a BIOS error. */ AcpiNsCheckAcpiCompliance (Info->FullPathname, Info->Node, Info->Predefined); /* * For all names: Check that the incoming argument count for * this method/object matches the actual ASL/AML definition. */ AcpiNsCheckArgumentCount (Info->FullPathname, Info->Node, Info->ParamCount, Info->Predefined); /* For predefined names: Typecheck all incoming arguments */ AcpiNsCheckArgumentTypes (Info); /* * Three major evaluation cases: * * 1) Object types that cannot be evaluated by definition * 2) The object is a control method -- execute it * 3) The object is not a method -- just return it's current value */ switch (AcpiNsGetType (Info->Node)) { case ACPI_TYPE_DEVICE: case ACPI_TYPE_EVENT: case ACPI_TYPE_MUTEX: case ACPI_TYPE_REGION: case ACPI_TYPE_THERMAL: case ACPI_TYPE_LOCAL_SCOPE: /* * 1) Disallow evaluation of certain object types. For these, * object evaluation is undefined and not supported. */ ACPI_ERROR ((AE_INFO, "%s: Evaluation of object type [%s] is not supported", Info->FullPathname, AcpiUtGetTypeName (Info->Node->Type))); Status = AE_TYPE; goto Cleanup; case ACPI_TYPE_METHOD: /* * 2) Object is a control method - execute it */ /* Verify that there is a method object associated with this node */ if (!Info->ObjDesc) { ACPI_ERROR ((AE_INFO, "%s: Method has no attached sub-object", Info->FullPathname)); Status = AE_NULL_OBJECT; goto Cleanup; } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Execute method [%s] at AML address %p length %X\n", Info->FullPathname, Info->ObjDesc->Method.AmlStart + 1, Info->ObjDesc->Method.AmlLength - 1)); /* * Any namespace deletion must acquire both the namespace and * interpreter locks to ensure that no thread is using the portion of * the namespace that is being deleted. * * Execute the method via the interpreter. The interpreter is locked * here before calling into the AML parser */ AcpiExEnterInterpreter (); Status = AcpiPsExecuteMethod (Info); AcpiExExitInterpreter (); break; default: /* * 3) All other non-method objects -- get the current object value */ /* * Some objects require additional resolution steps (e.g., the Node * may be a field that must be read, etc.) -- we can't just grab * the object out of the node. * * Use ResolveNodeToValue() to get the associated value. * * NOTE: we can get away with passing in NULL for a walk state because * the Node is guaranteed to not be a reference to either a method * local or a method argument (because this interface is never called * from a running method.) * * Even though we do not directly invoke the interpreter for object * resolution, we must lock it because we could access an OpRegion. * The OpRegion access code assumes that the interpreter is locked. */ AcpiExEnterInterpreter (); /* TBD: ResolveNodeToValue has a strange interface, fix */ Info->ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->Node); Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR ( ACPI_NAMESPACE_NODE, &Info->ReturnObject), NULL); AcpiExExitInterpreter (); if (ACPI_FAILURE (Status)) { goto Cleanup; } ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returned object %p [%s]\n", Info->ReturnObject, AcpiUtGetObjectTypeName (Info->ReturnObject))); Status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */ break; } /* * For predefined names, check the return value against the ACPI * specification. Some incorrect return value types are repaired. */ (void) AcpiNsCheckReturnValue (Info->Node, Info, Info->ParamCount, Status, &Info->ReturnObject); /* Check if there is a return value that must be dealt with */ if (Status == AE_CTRL_RETURN_VALUE) { /* If caller does not want the return value, delete it */ if (Info->Flags & ACPI_IGNORE_RETURN_VALUE) { AcpiUtRemoveReference (Info->ReturnObject); Info->ReturnObject = NULL; } /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ Status = AE_OK; } ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed evaluation of object %s ***\n", Info->RelativePathname)); Cleanup: /* * Namespace was unlocked by the handling AcpiNs* function, so we * just free the pathname and return */ ACPI_FREE (Info->FullPathname); Info->FullPathname = NULL; return_ACPI_STATUS (Status); }
void AcpiNsInstallNode ( ACPI_WALK_STATE *WalkState, ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ ACPI_NAMESPACE_NODE *Node, /* New Child*/ ACPI_OBJECT_TYPE Type) { ACPI_OWNER_ID OwnerId = 0; ACPI_NAMESPACE_NODE *ChildNode; ACPI_FUNCTION_TRACE (NsInstallNode); if (WalkState) { /* * Get the owner ID from the Walk state. The owner ID is used to * track table deletion and deletion of objects created by methods. */ OwnerId = WalkState->OwnerId; if ((WalkState->MethodDesc) && (ParentNode != WalkState->MethodNode)) { /* * A method is creating a new node that is not a child of the * method (it is non-local). Mark the executing method as having * modified the namespace. This is used for cleanup when the * method exits. */ WalkState->MethodDesc->Method.InfoFlags |= ACPI_METHOD_MODIFIED_NAMESPACE; } } /* Link the new entry into the parent and existing children */ Node->Peer = NULL; Node->Parent = ParentNode; ChildNode = ParentNode->Child; if (!ChildNode) { ParentNode->Child = Node; } else { /* Add node to the end of the peer list */ while (ChildNode->Peer) { ChildNode = ChildNode->Peer; } ChildNode->Peer = Node; } /* Init the new entry */ Node->OwnerId = OwnerId; Node->Type = (UINT8) Type; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), ParentNode)); return_VOID; }
ACPI_STATUS AcpiDsLoad1BeginOp ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT **OutOp) { ACPI_PARSE_OBJECT *Op; ACPI_NAMESPACE_NODE *Node; ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; char *Path; UINT32 Flags; ACPI_FUNCTION_TRACE (DsLoad1BeginOp); Op = WalkState->Op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState)); /* We are only interested in opcodes that have an associated name */ if (Op) { if (!(WalkState->OpInfo->Flags & AML_NAMED)) { *OutOp = Op; return_ACPI_STATUS (AE_OK); } /* Check if this object has already been installed in the namespace */ if (Op->Common.Node) { *OutOp = Op; return_ACPI_STATUS (AE_OK); } } Path = AcpiPsGetNextNamestring (&WalkState->ParserState); /* Map the raw opcode into an internal object type */ ObjectType = WalkState->OpInfo->ObjectType; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "State=%p Op=%p [%s]\n", WalkState, Op, AcpiUtGetTypeName (ObjectType))); switch (WalkState->Opcode) { case AML_SCOPE_OP: /* * The target name of the Scope() operator must exist at this point so * that we can actually open the scope to enter new names underneath it. * Allow search-to-root for single namesegs. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node)); #ifdef ACPI_ASL_COMPILER if (Status == AE_NOT_FOUND) { /* * Table disassembly: * Target of Scope() not found. Generate an External for it, and * insert the name into the namespace. */ AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0, 0); Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, &Node); } #endif if (ACPI_FAILURE (Status)) { ACPI_ERROR_NAMESPACE (Path, Status); return_ACPI_STATUS (Status); } /* * Check to make sure that the target is * one of the opcodes that actually opens a scope */ switch (Node->Type) { case ACPI_TYPE_ANY: case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_THERMAL: /* These are acceptable types */ break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These types we will allow, but we will change the type. * This enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } * * Note: silently change the type here. On the second pass, * we will report a warning */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Type override - [%4.4s] had invalid type (%s) " "for Scope operator, changed to type ANY\n", AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type))); Node->Type = ACPI_TYPE_ANY; WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY; break; case ACPI_TYPE_METHOD: /* * Allow scope change to root during execution of module-level * code. Root is typed METHOD during this time. */ if ((Node == AcpiGbl_RootNode) && (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) { break; } /*lint -fallthrough */ default: /* All other types are an error */ ACPI_ERROR ((AE_INFO, "Invalid type (%s) for target of " "Scope operator [%4.4s] (Cannot override)", AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } break; default: /* * For all other named opcodes, we will enter the name into * the namespace. * * Setup the search flags. * Since we are entering a name into the namespace, we do not want to * enable the search-to-root upsearch. * * There are only two conditions where it is acceptable that the name * already exists: * 1) the Scope() operator can reopen a scoping object that was * previously defined (Scope, Method, Device, etc.) * 2) Whenever we are parsing a deferred opcode (OpRegion, Buffer, * BufferField, or Package), the name of the object is already * in the namespace. */ if (WalkState->DeferredNode) { /* This name is already in the namespace, get the node */ Node = WalkState->DeferredNode; Status = AE_OK; break; } /* * If we are executing a method, do not create any namespace objects * during the load phase, only during execution. */ if (WalkState->MethodNode) { Node = NULL; Status = AE_OK; break; } Flags = ACPI_NS_NO_UPSEARCH; if ((WalkState->Opcode != AML_SCOPE_OP) && (!(WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP))) { if (WalkState->NamespaceOverride) { Flags |= ACPI_NS_OVERRIDE_IF_FOUND; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Override allowed\n", AcpiUtGetTypeName (ObjectType))); } else { Flags |= ACPI_NS_ERROR_IF_FOUND; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n", AcpiUtGetTypeName (ObjectType))); } } else { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n", AcpiUtGetTypeName (ObjectType))); } /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that * involve arguments to the opcode must be created as we go back up the * parse tree later. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); if (ACPI_FAILURE (Status)) { if (Status == AE_ALREADY_EXISTS) { /* The name already exists in this scope */ if (Node->Flags & ANOBJ_IS_EXTERNAL) { /* * Allow one create on an object or segment that was * previously declared External */ Node->Flags &= ~ANOBJ_IS_EXTERNAL; Node->Type = (UINT8) ObjectType; /* Just retyped a node, probably will need to open a scope */ if (AcpiNsOpensScope (ObjectType)) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } Status = AE_OK; } } if (ACPI_FAILURE (Status)) { ACPI_ERROR_NAMESPACE (Path, Status); return_ACPI_STATUS (Status); } } break; } /* Common exit */ if (!Op) { /* Create a new op */ Op = AcpiPsAllocOp (WalkState->Opcode); if (!Op) { return_ACPI_STATUS (AE_NO_MEMORY); } } /* Initialize the op */ #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) Op->Named.Path = ACPI_CAST_PTR (UINT8, Path); #endif if (Node) { /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed */ Op->Common.Node = Node; Op->Named.Name = Node->Name.Integer; } AcpiPsAppendArg (AcpiPsGetParentScope (&WalkState->ParserState), Op); *OutOp = Op; return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiExOpcode_1A_0T_1R ( ACPI_WALK_STATE *WalkState) { ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; ACPI_OPERAND_OBJECT *TempDesc; ACPI_OPERAND_OBJECT *ReturnDesc = NULL; ACPI_STATUS Status = AE_OK; UINT32 Type; UINT64 Value; ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R, AcpiPsGetOpcodeName (WalkState->Opcode)); /* Examine the AML opcode */ switch (WalkState->Opcode) { case AML_LNOT_OP: /* LNot (Operand) */ ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } /* * Set result to ONES (TRUE) if Value == 0. Note: * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above. */ if (!Operand[0]->Integer.Value) { ReturnDesc->Integer.Value = ACPI_UINT64_MAX; } break; case AML_DECREMENT_OP: /* Decrement (Operand) */ case AML_INCREMENT_OP: /* Increment (Operand) */ /* * Create a new integer. Can't just get the base integer and * increment it because it may be an Arg or Field. */ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } /* * Since we are expecting a Reference operand, it can be either a * NS Node or an internal object. */ TempDesc = Operand[0]; if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND) { /* Internal reference object - prevent deletion */ AcpiUtAddReference (TempDesc); } /* * Convert the Reference operand to an Integer (This removes a * reference on the Operand[0] object) * * NOTE: We use LNOT_OP here in order to force resolution of the * reference operand to an actual integer. */ Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While resolving operands for [%s]", AcpiPsGetOpcodeName (WalkState->Opcode))); goto Cleanup; } /* * TempDesc is now guaranteed to be an Integer object -- * Perform the actual increment or decrement */ if (WalkState->Opcode == AML_INCREMENT_OP) { ReturnDesc->Integer.Value = TempDesc->Integer.Value + 1; } else { ReturnDesc->Integer.Value = TempDesc->Integer.Value - 1; } /* Finished with this Integer object */ AcpiUtRemoveReference (TempDesc); /* * Store the result back (indirectly) through the original * Reference object */ Status = AcpiExStore (ReturnDesc, Operand[0], WalkState); break; case AML_OBJECT_TYPE_OP: /* ObjectType (SourceObject) */ /* * Note: The operand is not resolved at this point because we want to * get the associated object, not its value. For example, we don't * want to resolve a FieldUnit to its value, we want the actual * FieldUnit object. */ /* Get the type of the base object */ Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* Allocate a descriptor to hold the type. */ ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } break; case AML_SIZE_OF_OP: /* SizeOf (SourceObject) */ /* * Note: The operand is not resolved at this point because we want to * get the associated object, not its value. */ /* Get the base object */ Status = AcpiExResolveMultiple ( WalkState, Operand[0], &Type, &TempDesc); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* * The type of the base object must be integer, buffer, string, or * package. All others are not supported. * * NOTE: Integer is not specifically supported by the ACPI spec, * but is supported implicitly via implicit operand conversion. * rather than bother with conversion, we just use the byte width * global (4 or 8 bytes). */ switch (Type) { case ACPI_TYPE_INTEGER: Value = AcpiGbl_IntegerByteWidth; break; case ACPI_TYPE_STRING: Value = TempDesc->String.Length; break; case ACPI_TYPE_BUFFER: /* Buffer arguments may not be evaluated at this point */ Status = AcpiDsGetBufferArguments (TempDesc); Value = TempDesc->Buffer.Length; break; case ACPI_TYPE_PACKAGE: /* Package arguments may not be evaluated at this point */ Status = AcpiDsGetPackageArguments (TempDesc); Value = TempDesc->Package.Count; break; default: ACPI_ERROR ((AE_INFO, "Operand must be Buffer/Integer/String/Package" " - found type %s", AcpiUtGetTypeName (Type))); Status = AE_AML_OPERAND_TYPE; goto Cleanup; } if (ACPI_FAILURE (Status)) { goto Cleanup; } /* * Now that we have the size of the object, create a result * object to hold the value */ ReturnDesc = AcpiUtCreateIntegerObject (Value); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } break; case AML_REF_OF_OP: /* RefOf (SourceObject) */ Status = AcpiExGetObjectReference ( Operand[0], &ReturnDesc, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } break; case AML_DEREF_OF_OP: /* DerefOf (ObjReference | String) */ /* Check for a method local or argument, or standalone String */ if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED) { TempDesc = AcpiNsGetAttachedObject ( (ACPI_NAMESPACE_NODE *) Operand[0]); if (TempDesc && ((TempDesc->Common.Type == ACPI_TYPE_STRING) || (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE))) { Operand[0] = TempDesc; AcpiUtAddReference (TempDesc); } else { Status = AE_AML_OPERAND_TYPE; goto Cleanup; } } else { switch ((Operand[0])->Common.Type) { case ACPI_TYPE_LOCAL_REFERENCE: /* * This is a DerefOf (LocalX | ArgX) * * Must resolve/dereference the local/arg reference first */ switch (Operand[0]->Reference.Class) { case ACPI_REFCLASS_LOCAL: case ACPI_REFCLASS_ARG: /* Set Operand[0] to the value of the local/arg */ Status = AcpiDsMethodDataGetValue ( Operand[0]->Reference.Class, Operand[0]->Reference.Value, WalkState, &TempDesc); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* * Delete our reference to the input object and * point to the object just retrieved */ AcpiUtRemoveReference (Operand[0]); Operand[0] = TempDesc; break; case ACPI_REFCLASS_REFOF: /* Get the object to which the reference refers */ TempDesc = Operand[0]->Reference.Object; AcpiUtRemoveReference (Operand[0]); Operand[0] = TempDesc; break; default: /* Must be an Index op - handled below */ break; } break; case ACPI_TYPE_STRING: break; default: Status = AE_AML_OPERAND_TYPE; goto Cleanup; } } if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED) { if ((Operand[0])->Common.Type == ACPI_TYPE_STRING) { /* * This is a DerefOf (String). The string is a reference * to a named ACPI object. * * 1) Find the owning Node * 2) Dereference the node to an actual object. Could be a * Field, so we need to resolve the node to a value. */ Status = AcpiNsGetNodeUnlocked (WalkState->ScopeInfo->Scope.Node, Operand[0]->String.Pointer, ACPI_NS_SEARCH_PARENT, ACPI_CAST_INDIRECT_PTR ( ACPI_NAMESPACE_NODE, &ReturnDesc)); if (ACPI_FAILURE (Status)) { goto Cleanup; } Status = AcpiExResolveNodeToValue ( ACPI_CAST_INDIRECT_PTR ( ACPI_NAMESPACE_NODE, &ReturnDesc), WalkState); goto Cleanup; } } /* Operand[0] may have changed from the code above */ if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED) { /* * This is a DerefOf (ObjectReference) * Get the actual object from the Node (This is the dereference). * This case may only happen when a LocalX or ArgX is * dereferenced above. */ ReturnDesc = AcpiNsGetAttachedObject ( (ACPI_NAMESPACE_NODE *) Operand[0]); AcpiUtAddReference (ReturnDesc); } else { /* * This must be a reference object produced by either the * Index() or RefOf() operator */ switch (Operand[0]->Reference.Class) { case ACPI_REFCLASS_INDEX: /* * The target type for the Index operator must be * either a Buffer or a Package */ switch (Operand[0]->Reference.TargetType) { case ACPI_TYPE_BUFFER_FIELD: TempDesc = Operand[0]->Reference.Object; /* * Create a new object that contains one element of the * buffer -- the element pointed to by the index. * * NOTE: index into a buffer is NOT a pointer to a * sub-buffer of the main buffer, it is only a pointer to a * single element (byte) of the buffer! * * Since we are returning the value of the buffer at the * indexed location, we don't need to add an additional * reference to the buffer itself. */ ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } break; case ACPI_TYPE_PACKAGE: /* * Return the referenced element of the package. We must * add another reference to the referenced object, however. */ ReturnDesc = *(Operand[0]->Reference.Where); if (!ReturnDesc) { /* * Element is NULL, do not allow the dereference. * This provides compatibility with other ACPI * implementations. */ return_ACPI_STATUS (AE_AML_UNINITIALIZED_ELEMENT); } AcpiUtAddReference (ReturnDesc); break; default: ACPI_ERROR ((AE_INFO, "Unknown Index TargetType 0x%X in reference object %p", Operand[0]->Reference.TargetType, Operand[0])); Status = AE_AML_OPERAND_TYPE; goto Cleanup; } break; case ACPI_REFCLASS_REFOF: ReturnDesc = Operand[0]->Reference.Object; if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) == ACPI_DESC_TYPE_NAMED) { ReturnDesc = AcpiNsGetAttachedObject ( (ACPI_NAMESPACE_NODE *) ReturnDesc); if (!ReturnDesc) { break; } /* * June 2013: * BufferFields/FieldUnits require additional resolution */ switch (ReturnDesc->Common.Type) { case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: Status = AcpiExReadDataFromField ( WalkState, ReturnDesc, &TempDesc); if (ACPI_FAILURE (Status)) { goto Cleanup; } ReturnDesc = TempDesc; break; default: /* Add another reference to the object */ AcpiUtAddReference (ReturnDesc); break; } } break; default: ACPI_ERROR ((AE_INFO, "Unknown class in reference(%p) - 0x%2.2X", Operand[0], Operand[0]->Reference.Class)); Status = AE_TYPE; goto Cleanup; } } break; default: ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", WalkState->Opcode)); Status = AE_AML_BAD_OPCODE; goto Cleanup; } Cleanup: /* Delete return object on error */ if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ReturnDesc); } /* Save return object on success */ else { WalkState->ResultObj = ReturnDesc; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiExConvertToTargetType ( ACPI_OBJECT_TYPE DestinationType, ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT **ResultDesc, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE (ExConvertToTargetType); /* Default behavior */ *ResultDesc = SourceDesc; /* * If required by the target, * perform implicit conversion on the source before we store it. */ switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs)) { case ARGI_SIMPLE_TARGET: case ARGI_FIXED_TARGET: case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ switch (DestinationType) { case ACPI_TYPE_LOCAL_REGION_FIELD: /* * Named field can always handle conversions */ break; default: /* No conversion allowed for these types */ if (DestinationType != SourceDesc->Common.Type) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Explicit operator, will store (%s) over existing type (%s)\n", AcpiUtGetObjectTypeName (SourceDesc), AcpiUtGetTypeName (DestinationType))); Status = AE_TYPE; } } break; case ARGI_TARGETREF: switch (DestinationType) { case ACPI_TYPE_INTEGER: case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: /* * These types require an Integer operand. We can convert * a Buffer or a String to an Integer if necessary. */ Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, 16); break; case ACPI_TYPE_STRING: /* * The operand must be a String. We can convert an * Integer or Buffer if necessary */ Status = AcpiExConvertToString (SourceDesc, ResultDesc, ACPI_IMPLICIT_CONVERT_HEX); break; case ACPI_TYPE_BUFFER: /* * The operand must be a Buffer. We can convert an * Integer or String if necessary */ Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc); break; default: ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: 0x%X", DestinationType)); Status = AE_AML_INTERNAL; break; } break; case ARGI_REFERENCE: /* * CreateXxxxField cases - we are storing the field object into the name */ break; default: ACPI_ERROR ((AE_INFO, "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s", GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs), WalkState->Opcode, AcpiUtGetTypeName (DestinationType))); Status = AE_AML_INTERNAL; } /* * Source-to-Target conversion semantics: * * If conversion to the target type cannot be performed, then simply * overwrite the target with the new object and type. */ if (Status == AE_TYPE) { Status = AE_OK; } return_ACPI_STATUS (Status); }
void AcpiUtDumpAllocations ( UINT32 Component, const char *Module) { ACPI_DEBUG_MEM_BLOCK *Element; ACPI_DESCRIPTOR *Descriptor; UINT32 NumOutstanding = 0; UINT8 DescriptorType; ACPI_FUNCTION_TRACE (UtDumpAllocations); /* * Walk the allocation list. */ if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY))) { return; } Element = AcpiGbl_GlobalList->ListHead; while (Element) { if ((Element->Component & Component) && ((Module == NULL) || (0 == ACPI_STRCMP (Module, Element->Module)))) { Descriptor = ACPI_CAST_PTR (ACPI_DESCRIPTOR, &Element->UserSpace); if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR)) { AcpiOsPrintf ("%p Length 0x%04X %9.9s-%d " "[Not a Descriptor - too small]\n", Descriptor, Element->Size, Element->Module, Element->Line); } else { /* Ignore allocated objects that are in a cache */ if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) != ACPI_DESC_TYPE_CACHED) { AcpiOsPrintf ("%p Length 0x%04X %9.9s-%d [%s] ", Descriptor, Element->Size, Element->Module, Element->Line, AcpiUtGetDescriptorName (Descriptor)); /* Validate the descriptor type using Type field and length */ DescriptorType = 0; /* Not a valid descriptor type */ switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor)) { case ACPI_DESC_TYPE_OPERAND: if (Element->Size == sizeof (ACPI_DESC_TYPE_OPERAND)) { DescriptorType = ACPI_DESC_TYPE_OPERAND; } break; case ACPI_DESC_TYPE_PARSER: if (Element->Size == sizeof (ACPI_DESC_TYPE_PARSER)) { DescriptorType = ACPI_DESC_TYPE_PARSER; } break; case ACPI_DESC_TYPE_NAMED: if (Element->Size == sizeof (ACPI_DESC_TYPE_NAMED)) { DescriptorType = ACPI_DESC_TYPE_NAMED; } break; default: break; } /* Display additional info for the major descriptor types */ switch (DescriptorType) { case ACPI_DESC_TYPE_OPERAND: AcpiOsPrintf ("%12.12s RefCount 0x%04X\n", AcpiUtGetTypeName (Descriptor->Object.Common.Type), Descriptor->Object.Common.ReferenceCount); break; case ACPI_DESC_TYPE_PARSER: AcpiOsPrintf ("AmlOpcode 0x%04hX\n", Descriptor->Op.Asl.AmlOpcode); break; case ACPI_DESC_TYPE_NAMED: AcpiOsPrintf ("%4.4s\n", AcpiUtGetNodeName (&Descriptor->Node)); break; default: AcpiOsPrintf ( "\n"); break; } } } NumOutstanding++; } Element = Element->Next; } (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY); /* Print summary */ if (!NumOutstanding) { ACPI_INFO ((AE_INFO, "No outstanding allocations")); } else { ACPI_ERROR ((AE_INFO, "%d(0x%X) Outstanding allocations", NumOutstanding, NumOutstanding)); } return_VOID; }
ACPI_STATUS AcpiDbDisassembleMethod ( char *Name) { ACPI_STATUS Status; ACPI_PARSE_OBJECT *Op; ACPI_WALK_STATE *WalkState; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_NAMESPACE_NODE *Method; Method = AcpiDbConvertToNode (Name); if (!Method) { return (AE_BAD_PARAMETER); } if (Method->Type != ACPI_TYPE_METHOD) { ACPI_ERROR ((AE_INFO, "%s (%s): Object must be a control method", Name, AcpiUtGetTypeName (Method->Type))); return (AE_BAD_PARAMETER); } ObjDesc = Method->Object; Op = AcpiPsCreateScopeOp (); if (!Op) { return (AE_NO_MEMORY); } /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); if (!WalkState) { return (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); if (ACPI_FAILURE (Status)) { return (Status); } Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId); WalkState->OwnerId = ObjDesc->Method.OwnerId; /* Push start scope on scope stack and make it current */ Status = AcpiDsScopeStackPush (Method, Method->Type, WalkState); if (ACPI_FAILURE (Status)) { return (Status); } /* Parse the entire method AML including deferred operators */ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; Status = AcpiPsParseAml (WalkState); (void) AcpiDmParseDeferredOps (Op); /* Now we can disassemble the method */ AcpiGbl_DbOpt_verbose = FALSE; AcpiDmDisassemble (NULL, Op, 0); AcpiGbl_DbOpt_verbose = TRUE; AcpiPsDeleteParseTree (Op); /* Method cleanup */ AcpiNsDeleteNamespaceSubtree (Method); AcpiNsDeleteNamespaceByOwner (ObjDesc->Method.OwnerId); AcpiUtReleaseOwnerId (&ObjDesc->Method.OwnerId); return (AE_OK); }
ACPI_STATUS AcpiNsDumpOneObject ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; ACPI_NAMESPACE_NODE *ThisNode; ACPI_OPERAND_OBJECT *ObjDesc = NULL; ACPI_OBJECT_TYPE ObjType; ACPI_OBJECT_TYPE Type; UINT32 BytesToDump; UINT32 DbgLevel; UINT32 i; ACPI_FUNCTION_NAME (NsDumpOneObject); /* Is output enabled? */ if (!(AcpiDbgLevel & Info->DebugLevel)) { return (AE_OK); } if (!ObjHandle) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n")); return (AE_OK); } ThisNode = AcpiNsValidateHandle (ObjHandle); if (!ThisNode) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Invalid object handle %p\n", ObjHandle)); return (AE_OK); } Type = ThisNode->Type; /* Check if the owner matches */ if ((Info->OwnerId != ACPI_OWNER_ID_MAX) && (Info->OwnerId != ThisNode->OwnerId)) { return (AE_OK); } if (!(Info->DisplayType & ACPI_DISPLAY_SHORT)) { /* Indent the object according to the level */ AcpiOsPrintf ("%2d%*s", (UINT32) Level - 1, (int) Level * 2, " "); /* Check the node type and name */ if (Type > ACPI_TYPE_LOCAL_MAX) { ACPI_WARNING ((AE_INFO, "Invalid ACPI Object Type 0x%08X", Type)); } AcpiOsPrintf ("%4.4s", AcpiUtGetNodeName (ThisNode)); } /* Now we can print out the pertinent information */ AcpiOsPrintf (" %-12s %p %2.2X ", AcpiUtGetTypeName (Type), ThisNode, ThisNode->OwnerId); DbgLevel = AcpiDbgLevel; AcpiDbgLevel = 0; ObjDesc = AcpiNsGetAttachedObject (ThisNode); AcpiDbgLevel = DbgLevel; /* Temp nodes are those nodes created by a control method */ if (ThisNode->Flags & ANOBJ_TEMPORARY) { AcpiOsPrintf ("(T) "); } switch (Info->DisplayType & ACPI_DISPLAY_MASK) { case ACPI_DISPLAY_SUMMARY: if (!ObjDesc) { /* No attached object. Some types should always have an object */ switch (Type) { case ACPI_TYPE_INTEGER: case ACPI_TYPE_PACKAGE: case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: case ACPI_TYPE_METHOD: AcpiOsPrintf ("<No attached object>"); break; default: break; } AcpiOsPrintf ("\n"); return (AE_OK); } switch (Type) { case ACPI_TYPE_PROCESSOR: AcpiOsPrintf ("ID %02X Len %02X Addr %8.8X%8.8X\n", ObjDesc->Processor.ProcId, ObjDesc->Processor.Length, ACPI_FORMAT_UINT64 (ObjDesc->Processor.Address)); break; case ACPI_TYPE_DEVICE: AcpiOsPrintf ("Notify Object: %p\n", ObjDesc); break; case ACPI_TYPE_METHOD: AcpiOsPrintf ("Args %X Len %.4X Aml %p\n", (UINT32) ObjDesc->Method.ParamCount, ObjDesc->Method.AmlLength, ObjDesc->Method.AmlStart); break; case ACPI_TYPE_INTEGER: AcpiOsPrintf ("= %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); break; case ACPI_TYPE_PACKAGE: if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) { AcpiOsPrintf ("Elements %.2X\n", ObjDesc->Package.Count); } else { AcpiOsPrintf ("[Length not yet evaluated]\n"); } break; case ACPI_TYPE_BUFFER: if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) { AcpiOsPrintf ("Len %.2X", ObjDesc->Buffer.Length); /* Dump some of the buffer */ if (ObjDesc->Buffer.Length > 0) { AcpiOsPrintf (" ="); for (i = 0; (i < ObjDesc->Buffer.Length && i < 12); i++) { AcpiOsPrintf (" %.2hX", ObjDesc->Buffer.Pointer[i]); } } AcpiOsPrintf ("\n"); } else { AcpiOsPrintf ("[Length not yet evaluated]\n"); } break; case ACPI_TYPE_STRING: AcpiOsPrintf ("Len %.2X ", ObjDesc->String.Length); AcpiUtPrintString (ObjDesc->String.Pointer, 80); AcpiOsPrintf ("\n"); break; case ACPI_TYPE_REGION: AcpiOsPrintf ("[%s]", AcpiUtGetRegionName (ObjDesc->Region.SpaceId)); if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID) { AcpiOsPrintf (" Addr %8.8X%8.8X Len %.4X\n", ACPI_FORMAT_UINT64 (ObjDesc->Region.Address), ObjDesc->Region.Length); } else { AcpiOsPrintf (" [Address/Length not yet evaluated]\n"); } break; case ACPI_TYPE_LOCAL_REFERENCE: AcpiOsPrintf ("[%s]\n", AcpiUtGetReferenceName (ObjDesc)); break; case ACPI_TYPE_BUFFER_FIELD: if (ObjDesc->BufferField.BufferObj && ObjDesc->BufferField.BufferObj->Buffer.Node) { AcpiOsPrintf ("Buf [%4.4s]", AcpiUtGetNodeName ( ObjDesc->BufferField.BufferObj->Buffer.Node)); } break; case ACPI_TYPE_LOCAL_REGION_FIELD: AcpiOsPrintf ("Rgn [%4.4s]", AcpiUtGetNodeName ( ObjDesc->CommonField.RegionObj->Region.Node)); break; case ACPI_TYPE_LOCAL_BANK_FIELD: AcpiOsPrintf ("Rgn [%4.4s] Bnk [%4.4s]", AcpiUtGetNodeName ( ObjDesc->CommonField.RegionObj->Region.Node), AcpiUtGetNodeName ( ObjDesc->BankField.BankObj->CommonField.Node)); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: AcpiOsPrintf ("Idx [%4.4s] Dat [%4.4s]", AcpiUtGetNodeName ( ObjDesc->IndexField.IndexObj->CommonField.Node), AcpiUtGetNodeName ( ObjDesc->IndexField.DataObj->CommonField.Node)); break; case ACPI_TYPE_LOCAL_ALIAS: case ACPI_TYPE_LOCAL_METHOD_ALIAS: AcpiOsPrintf ("Target %4.4s (%p)\n", AcpiUtGetNodeName (ObjDesc), ObjDesc); break; default: AcpiOsPrintf ("Object %p\n", ObjDesc); break; } /* Common field handling */ switch (Type) { case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: AcpiOsPrintf (" Off %.3X Len %.2X Acc %.2hd\n", (ObjDesc->CommonField.BaseByteOffset * 8) + ObjDesc->CommonField.StartFieldBitOffset, ObjDesc->CommonField.BitLength, ObjDesc->CommonField.AccessByteWidth); break; default: break; } break; case ACPI_DISPLAY_OBJECTS: AcpiOsPrintf ("O:%p", ObjDesc); if (!ObjDesc) { /* No attached object, we are done */ AcpiOsPrintf ("\n"); return (AE_OK); } AcpiOsPrintf ("(R%u)", ObjDesc->Common.ReferenceCount); switch (Type) { case ACPI_TYPE_METHOD: /* Name is a Method and its AML offset/length are set */ AcpiOsPrintf (" M:%p-%X\n", ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength); break; case ACPI_TYPE_INTEGER: AcpiOsPrintf (" I:%8.8X8.8%X\n", ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); break; case ACPI_TYPE_STRING: AcpiOsPrintf (" S:%p-%X\n", ObjDesc->String.Pointer, ObjDesc->String.Length); break; case ACPI_TYPE_BUFFER: AcpiOsPrintf (" B:%p-%X\n", ObjDesc->Buffer.Pointer, ObjDesc->Buffer.Length); break; default: AcpiOsPrintf ("\n"); break; } break; default: AcpiOsPrintf ("\n"); break; } /* If debug turned off, done */ if (!(AcpiDbgLevel & ACPI_LV_VALUES)) { return (AE_OK); } /* If there is an attached object, display it */ DbgLevel = AcpiDbgLevel; AcpiDbgLevel = 0; ObjDesc = AcpiNsGetAttachedObject (ThisNode); AcpiDbgLevel = DbgLevel; /* Dump attached objects */ while (ObjDesc) { ObjType = ACPI_TYPE_INVALID; AcpiOsPrintf ("Attached Object %p: ", ObjDesc); /* Decode the type of attached object and dump the contents */ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) { case ACPI_DESC_TYPE_NAMED: AcpiOsPrintf ("(Ptr to Node)\n"); BytesToDump = sizeof (ACPI_NAMESPACE_NODE); ACPI_DUMP_BUFFER (ObjDesc, BytesToDump); break; case ACPI_DESC_TYPE_OPERAND: ObjType = ObjDesc->Common.Type; if (ObjType > ACPI_TYPE_LOCAL_MAX) { AcpiOsPrintf ( "(Pointer to ACPI Object type %.2X [UNKNOWN])\n", ObjType); BytesToDump = 32; } else { AcpiOsPrintf ( "(Pointer to ACPI Object type %.2X [%s])\n", ObjType, AcpiUtGetTypeName (ObjType)); BytesToDump = sizeof (ACPI_OPERAND_OBJECT); } ACPI_DUMP_BUFFER (ObjDesc, BytesToDump); break; default: break; } /* If value is NOT an internal object, we are done */ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND) { goto Cleanup; } /* Valid object, get the pointer to next level, if any */ switch (ObjType) { case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: /* * NOTE: takes advantage of common fields between string/buffer */ BytesToDump = ObjDesc->String.Length; ObjDesc = (void *) ObjDesc->String.Pointer; AcpiOsPrintf ("(Buffer/String pointer %p length %X)\n", ObjDesc, BytesToDump); ACPI_DUMP_BUFFER (ObjDesc, BytesToDump); goto Cleanup; case ACPI_TYPE_BUFFER_FIELD: ObjDesc = (ACPI_OPERAND_OBJECT *) ObjDesc->BufferField.BufferObj; break; case ACPI_TYPE_PACKAGE: ObjDesc = (void *) ObjDesc->Package.Elements; break; case ACPI_TYPE_METHOD: ObjDesc = (void *) ObjDesc->Method.AmlStart; break; case ACPI_TYPE_LOCAL_REGION_FIELD: ObjDesc = (void *) ObjDesc->Field.RegionObj; break; case ACPI_TYPE_LOCAL_BANK_FIELD: ObjDesc = (void *) ObjDesc->BankField.RegionObj; break; case ACPI_TYPE_LOCAL_INDEX_FIELD: ObjDesc = (void *) ObjDesc->IndexField.IndexObj; break; default: goto Cleanup; } ObjType = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ } Cleanup: AcpiOsPrintf ("\n"); return (AE_OK); }
ACPI_STATUS AcpiDbDisplayStatistics ( char *TypeArg) { UINT32 i; UINT32 Temp; if (!TypeArg) { AcpiOsPrintf ("The following subcommands are available:\n ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n"); return (AE_OK); } AcpiUtStrupr (TypeArg); Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes); if (Temp == (UINT32) -1) { AcpiOsPrintf ("Invalid or unsupported argument\n"); return (AE_OK); } switch (Temp) { case CMD_STAT_ALLOCATIONS: #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiUtDumpAllocationInfo (); #endif break; case CMD_STAT_TABLES: AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n"); break; case CMD_STAT_OBJECTS: AcpiDbCountNamespaceObjects (); AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n"); AcpiOsPrintf ("%16.16s %10.10s %10.10s\n", "ACPI_TYPE", "NODES", "OBJECTS"); for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) { AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i), AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]); } AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown", AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc); AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:", AcpiGbl_NumNodes, AcpiGbl_NumObjects); break; case CMD_STAT_MEMORY: #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n"); AcpiDbListInfo (AcpiGbl_GlobalList); AcpiDbListInfo (AcpiGbl_NsNodeList); #endif #ifdef ACPI_USE_LOCAL_CACHE AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n"); AcpiDbListInfo (AcpiGbl_OperandCache); AcpiDbListInfo (AcpiGbl_PsNodeCache); AcpiDbListInfo (AcpiGbl_PsNodeExtCache); AcpiDbListInfo (AcpiGbl_StateCache); #endif break; case CMD_STAT_MISC: AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n"); AcpiOsPrintf ("Calls to AcpiPsFind:.. ........% 7ld\n", AcpiGbl_PsFindCount); AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n", AcpiGbl_NsLookupCount); AcpiOsPrintf ("\n"); AcpiOsPrintf ("Mutex usage:\n\n"); for (i = 0; i < ACPI_NUM_MUTEX; i++) { AcpiOsPrintf ("%-28s: % 7ld\n", AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount); } break; case CMD_STAT_SIZES: AcpiOsPrintf ("\nInternal object sizes:\n\n"); AcpiOsPrintf ("Common %3d\n", sizeof (ACPI_OBJECT_COMMON)); AcpiOsPrintf ("Number %3d\n", sizeof (ACPI_OBJECT_INTEGER)); AcpiOsPrintf ("String %3d\n", sizeof (ACPI_OBJECT_STRING)); AcpiOsPrintf ("Buffer %3d\n", sizeof (ACPI_OBJECT_BUFFER)); AcpiOsPrintf ("Package %3d\n", sizeof (ACPI_OBJECT_PACKAGE)); AcpiOsPrintf ("BufferField %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD)); AcpiOsPrintf ("Device %3d\n", sizeof (ACPI_OBJECT_DEVICE)); AcpiOsPrintf ("Event %3d\n", sizeof (ACPI_OBJECT_EVENT)); AcpiOsPrintf ("Method %3d\n", sizeof (ACPI_OBJECT_METHOD)); AcpiOsPrintf ("Mutex %3d\n", sizeof (ACPI_OBJECT_MUTEX)); AcpiOsPrintf ("Region %3d\n", sizeof (ACPI_OBJECT_REGION)); AcpiOsPrintf ("PowerResource %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE)); AcpiOsPrintf ("Processor %3d\n", sizeof (ACPI_OBJECT_PROCESSOR)); AcpiOsPrintf ("ThermalZone %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE)); AcpiOsPrintf ("RegionField %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD)); AcpiOsPrintf ("BankField %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD)); AcpiOsPrintf ("IndexField %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD)); AcpiOsPrintf ("Reference %3d\n", sizeof (ACPI_OBJECT_REFERENCE)); AcpiOsPrintf ("Notify %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER)); AcpiOsPrintf ("AddressSpace %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER)); AcpiOsPrintf ("Extra %3d\n", sizeof (ACPI_OBJECT_EXTRA)); AcpiOsPrintf ("Data %3d\n", sizeof (ACPI_OBJECT_DATA)); AcpiOsPrintf ("\n"); AcpiOsPrintf ("ParseObject %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON)); AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED)); AcpiOsPrintf ("ParseObjectAsl %3d\n", sizeof (ACPI_PARSE_OBJ_ASL)); AcpiOsPrintf ("OperandObject %3d\n", sizeof (ACPI_OPERAND_OBJECT)); AcpiOsPrintf ("NamespaceNode %3d\n", sizeof (ACPI_NAMESPACE_NODE)); AcpiOsPrintf ("AcpiObject %3d\n", sizeof (ACPI_OBJECT)); break; case CMD_STAT_STACK: #if defined(ACPI_DEBUG_OUTPUT) Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer); AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n"); AcpiOsPrintf ("Entry Stack Pointer %p\n", AcpiGbl_EntryStackPointer); AcpiOsPrintf ("Lowest Stack Pointer %p\n", AcpiGbl_LowestStackPointer); AcpiOsPrintf ("Stack Use %X (%u)\n", Temp, Temp); AcpiOsPrintf ("Deepest Procedure Nesting %u\n", AcpiGbl_DeepestNesting); #endif break; default: break; } AcpiOsPrintf ("\n"); return (AE_OK); }
ACPI_STATUS AcpiEvaluateObjectTyped ( ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer, ACPI_OBJECT_TYPE ReturnType) { ACPI_STATUS Status; BOOLEAN FreeBufferOnError = FALSE; ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); /* Return buffer must be valid */ if (!ReturnBuffer) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) { FreeBufferOnError = TRUE; } /* Evaluate the object */ Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Type ANY means "don't care" */ if (ReturnType == ACPI_TYPE_ANY) { return_ACPI_STATUS (AE_OK); } if (ReturnBuffer->Length == 0) { /* Error because caller specifically asked for a return value */ ACPI_ERROR ((AE_INFO, "No return value")); return_ACPI_STATUS (AE_NULL_OBJECT); } /* Examine the object type returned from EvaluateObject */ if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) { return_ACPI_STATUS (AE_OK); } /* Return object type does not match requested type */ ACPI_ERROR ((AE_INFO, "Incorrect return type [%s] requested [%s]", AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), AcpiUtGetTypeName (ReturnType))); if (FreeBufferOnError) { /* * Free a buffer created via ACPI_ALLOCATE_BUFFER. * Note: We use AcpiOsFree here because AcpiOsAllocate was used * to allocate the buffer. This purposefully bypasses the * (optionally enabled) allocation tracking mechanism since we * only want to track internal allocations. */ AcpiOsFree (ReturnBuffer->Pointer); ReturnBuffer->Pointer = NULL; } ReturnBuffer->Length = 0; return_ACPI_STATUS (AE_TYPE); }
static ACPI_STATUS LdNamespace1Begin ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; ACPI_NAMESPACE_NODE *Node; ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; char *Path; UINT32 Flags = ACPI_NS_NO_UPSEARCH; ACPI_PARSE_OBJECT *Arg; UINT32 i; BOOLEAN ForceNewScope = FALSE; ACPI_FUNCTION_NAME (LdNamespace1Begin); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", Op, Op->Asl.ParseOpName)); /* * We are only interested in opcodes that have an associated name * (or multiple names) */ switch (Op->Asl.AmlOpcode) { case AML_BANK_FIELD_OP: case AML_INDEX_FIELD_OP: case AML_FIELD_OP: Status = LdLoadFieldElements (Op, WalkState); return (Status); default: /* All other opcodes go below */ break; } /* Check if this object has already been installed in the namespace */ if (Op->Asl.Node) { return (AE_OK); } Path = Op->Asl.Namepath; if (!Path) { return (AE_OK); } /* Map the raw opcode into an internal object type */ switch (Op->Asl.ParseOpcode) { case PARSEOP_NAME: Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ /* * If this name refers to a ResourceTemplate, we will need to open * a new scope so that the resource subfield names can be entered into * the namespace underneath this name */ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) { ForceNewScope = TRUE; } /* Get the data type associated with the named object, not the name itself */ /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ ObjectType = 1; for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) { ObjectType++; } break; case PARSEOP_EXTERNAL: /* * "External" simply enters a name and type into the namespace. * We must be careful to not open a new scope, however, no matter * what type the external name refers to (e.g., a method) * * first child is name, next child is ObjectType */ ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; ObjectType = ACPI_TYPE_ANY; /* * We will mark every new node along the path as "External". This * allows some or all of the nodes to be created later in the ASL * code. Handles cases like this: * * External (\_SB_.PCI0.ABCD, IntObj) * Scope (_SB_) * { * Device (PCI0) * { * } * } * Method (X) * { * Store (\_SB_.PCI0.ABCD, Local0) * } */ Flags |= ACPI_NS_EXTERNAL; break; case PARSEOP_DEFAULT_ARG: if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) { Status = LdLoadResourceElements (Op, WalkState); return_ACPI_STATUS (Status); } ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; case PARSEOP_SCOPE: /* * The name referenced by Scope(Name) must already exist at this point. * In other words, forward references for Scope() are not supported. * The only real reason for this is that the MS interpreter cannot * handle this case. Perhaps someday this case can go away. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node)); if (ACPI_FAILURE (Status)) { if (Status == AE_NOT_FOUND) { /* The name was not found, go ahead and create it */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &(Node)); /* * However, this is an error -- primarily because the MS * interpreter can't handle a forward reference from the * Scope() operator. */ AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName); AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, Op->Asl.ExternalName); goto FinishNode; } AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } /* We found a node with this name, now check the type */ switch (Node->Type) { case ACPI_TYPE_LOCAL_SCOPE: case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_THERMAL: /* These are acceptable types - they all open a new scope */ break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These types we will allow, but we will change the type. * This enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } * * Which is used to workaround the fact that the MS interpreter * does not allow Scope() forward references. */ sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* Switch the type to scope, open the new scope */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; default: /* All other types are an error */ sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* * However, switch the type to be an actual scope so * that compilation can continue without generating a whole * cascade of additional errors. Open the new scope. */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; } Status = AE_OK; goto FinishNode; default: ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; } ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); /* The name must not already exist */ Flags |= ACPI_NS_ERROR_IF_FOUND; /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that * involve arguments to the opcode must be created as we go back up the * parse tree later. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); if (ACPI_FAILURE (Status)) { if (Status == AE_ALREADY_EXISTS) { /* The name already exists in this scope */ if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { /* Allow multiple references to the same scope */ Node->Type = (UINT8) ObjectType; Status = AE_OK; } else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) { /* * Allow one create on an object or segment that was * previously declared External */ Node->Flags &= ~ANOBJ_IS_EXTERNAL; Node->Type = (UINT8) ObjectType; /* Just retyped a node, probably will need to open a scope */ if (AcpiNsOpensScope (ObjectType)) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } Status = AE_OK; } else { /* Valid error, object already exists */ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, Op->Asl.ExternalName); return_ACPI_STATUS (AE_OK); } } else { AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } } if (ForceNewScope) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } FinishNode: /* * Point the parse node to the new namespace node, and point * the Node back to the original Parse node */ Op->Asl.Node = Node; Node->Op = Op; /* Set the actual data type if appropriate (EXTERNAL term only) */ if (ActualObjectType != ACPI_TYPE_ANY) { Node->Type = (UINT8) ActualObjectType; Node->Value = ASL_EXTERNAL_METHOD; } if (Op->Asl.ParseOpcode == PARSEOP_METHOD) { /* * Get the method argument count from "Extra" and save * it in the namespace node */ Node->Value = (UINT32) Op->Asl.Extra; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiNsCheckObjectType ( ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT **ReturnObjectPtr, UINT32 ExpectedBtypes, UINT32 PackageIndex) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_STATUS Status = AE_OK; char TypeBuffer[48]; /* Room for 5 types */ /* A Namespace node should not get here, but make sure */ if (ReturnObject && ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) { ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Invalid return type - Found a Namespace node [%4.4s] type %s", ReturnObject->Node.Name.Ascii, AcpiUtGetTypeName (ReturnObject->Node.Type))); return (AE_AML_OPERAND_TYPE); } /* * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. * The bitmapped type allows multiple possible return types. * * Note, the cases below must handle all of the possible types returned * from all of the predefined names (including elements of returned * packages) */ Data->ReturnBtype = AcpiNsGetBitmappedType (ReturnObject); if (Data->ReturnBtype == ACPI_RTYPE_ANY) { /* Not one of the supported objects, must be incorrect */ goto TypeErrorExit; } /* For reference objects, check that the reference type is correct */ if ((Data->ReturnBtype & ExpectedBtypes) == ACPI_RTYPE_REFERENCE) { Status = AcpiNsCheckReference (Data, ReturnObject); return (Status); } /* Attempt simple repair of the returned object if necessary */ Status = AcpiNsSimpleRepair (Data, ExpectedBtypes, PackageIndex, ReturnObjectPtr); return (Status); TypeErrorExit: /* Create a string with all expected types for this predefined object */ AcpiUtGetExpectedReturnTypes (TypeBuffer, ExpectedBtypes); if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) { ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Return type mismatch - found %s, expected %s", AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); } else { ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Return Package type mismatch at index %u - " "found %s, expected %s", PackageIndex, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); } return (AE_AML_OPERAND_TYPE); }