ACPI_STATUS AcpiTbInitializeFacs ( void) { /* If Hardware Reduced flag is set, there is no FACS */ if (AcpiGbl_ReducedHardware) { AcpiGbl_FACS = NULL; return (AE_OK); } (void) AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_Facs32)); (void) AcpiGetTableByIndex (ACPI_TABLE_INDEX_X_FACS, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_Facs64)); if (AcpiGbl_Facs64 && (!AcpiGbl_Facs32 || !AcpiGbl_Use32BitFacsAddresses)) { AcpiGbl_FACS = AcpiGbl_Facs64; } else if (AcpiGbl_Facs32) { AcpiGbl_FACS = AcpiGbl_Facs32; } /* If there is no FACS, just continue. There was already an error msg */ return (AE_OK); }
ACPI_STATUS AcpiTbInitializeFacs ( void) { ACPI_TABLE_FACS *Facs; /* If Hardware Reduced flag is set, there is no FACS */ if (AcpiGbl_ReducedHardware) { AcpiGbl_FACS = NULL; return (AE_OK); } else if (AcpiGbl_FADT.XFacs && (!AcpiGbl_FADT.Facs || !AcpiGbl_Use32BitFacsAddresses)) { (void) AcpiGetTableByIndex (AcpiGbl_XFacsIndex, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs)); AcpiGbl_FACS = Facs; } else if (AcpiGbl_FADT.Facs) { (void) AcpiGetTableByIndex (AcpiGbl_FacsIndex, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs)); AcpiGbl_FACS = Facs; } /* If there is no FACS, just continue. There was already an error msg */ return (AE_OK); }
ACPI_STATUS AcpiExResolveToValue ( ACPI_OPERAND_OBJECT **StackPtr, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE_PTR (ExResolveToValue, StackPtr); if (!StackPtr || !*StackPtr) { ACPI_ERROR ((AE_INFO, "Internal - null pointer")); return_ACPI_STATUS (AE_AML_NO_OPERAND); } /* * The entity pointed to by the StackPtr can be either * 1) A valid ACPI_OPERAND_OBJECT, or * 2) A ACPI_NAMESPACE_NODE (NamedObj) */ if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_OPERAND) { Status = AcpiExResolveObjectToValue (StackPtr, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } if (!*StackPtr) { ACPI_ERROR ((AE_INFO, "Internal - null pointer")); return_ACPI_STATUS (AE_AML_NO_OPERAND); } } /* * Object on the stack may have changed if AcpiExResolveObjectToValue() * was called (i.e., we can't use an _else_ here.) */ if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_NAMED) { Status = AcpiExResolveNodeToValue ( ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, StackPtr), WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *StackPtr)); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiTbInitializeFacs ( void) { ACPI_STATUS Status; Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS)); return (Status); }
ACPI_STATUS AcpiRsConvertAmlToResources ( UINT8 *Aml, UINT32 Length, UINT32 Offset, UINT8 ResourceIndex, void *Context) { ACPI_RESOURCE **ResourcePtr = ACPI_CAST_INDIRECT_PTR ( ACPI_RESOURCE, Context); ACPI_RESOURCE *Resource; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (RsConvertAmlToResources); /* * Check that the input buffer and all subsequent pointers into it * are aligned on a native word boundary. Most important on IA64 */ Resource = *ResourcePtr; if (ACPI_IS_MISALIGNED (Resource)) { ACPI_WARNING ((AE_INFO, "Misaligned resource pointer %p", Resource)); } /* Convert the AML byte stream resource to a local resource struct */ Status = AcpiRsConvertAmlToResource ( Resource, ACPI_CAST_PTR (AML_RESOURCE, Aml), AcpiGbl_GetResourceDispatch[ResourceIndex]); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not convert AML resource (Type 0x%X)", *Aml)); return_ACPI_STATUS (Status); } ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, "Type %.2X, AmlLength %.2X InternalLength %.2X\n", AcpiUtGetResourceType (Aml), Length, Resource->Length)); /* Point to the next structure in the output buffer */ *ResourcePtr = ACPI_ADD_PTR (void, Resource, Resource->Length); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiTbInitializeFacs ( void) { ACPI_STATUS Status; /* If Hardware Reduced flag is set, there is no FACS */ if (AcpiGbl_ReducedHardware) { AcpiGbl_FACS = NULL; return (AE_OK); } Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS)); return (Status); }
ACPI_STATUS AcpiEvInitGlobalLockHandler ( void) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler); Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs)); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } AcpiGbl_GlobalLockPresent = TRUE; Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AcpiEvGlobalLockHandler, NULL); /* * If the global lock does not exist on this platform, the attempt * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick) * Map to AE_OK, but mark global lock as not present. * Any attempt to actually use the global lock will be flagged * with an error. */ if (Status == AE_NO_HARDWARE_RESPONSE) { ACPI_ERROR ((AE_INFO, "No response from Global Lock hardware, disabling lock")); AcpiGbl_GlobalLockPresent = FALSE; Status = AE_OK; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiDsCreateOperand ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Arg, UINT32 ArgIndex) { ACPI_STATUS Status = AE_OK; char *NameString; UINT32 NameLength; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_PARSE_OBJECT *ParentOp; UINT16 Opcode; ACPI_INTERPRETER_MODE InterpreterMode; const ACPI_OPCODE_INFO *OpInfo; ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg); /* A valid name must be looked up in the namespace */ if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && (Arg->Common.Value.String) && !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg)); /* Get the entire name string from the AML stream */ Status = AcpiExGetNameString (ACPI_TYPE_ANY, Arg->Common.Value.Buffer, &NameString, &NameLength); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* All prefixes have been handled, and the name is in NameString */ /* * Special handling for BufferField declarations. This is a deferred * opcode that unfortunately defines the field name as the last * parameter instead of the first. We get here when we are performing * the deferred execution, so the actual name of the field is already * in the namespace. We don't want to attempt to look it up again * because we may be executing in a different scope than where the * actual opcode exists. */ if ((WalkState->DeferredNode) && (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) && (ArgIndex == (UINT32) ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2))) { ObjDesc = ACPI_CAST_PTR ( ACPI_OPERAND_OBJECT, WalkState->DeferredNode); Status = AE_OK; } else /* All other opcodes */ { /* * Differentiate between a namespace "create" operation * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. * IMODE_EXECUTE) in order to support the creation of * namespace objects during the execution of control methods. */ ParentOp = Arg->Common.Parent; OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode); if ((OpInfo->Flags & AML_NSNODE) && (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) && (ParentOp->Common.AmlOpcode != AML_REGION_OP) && (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) { /* Enter name into namespace if not found */ InterpreterMode = ACPI_IMODE_LOAD_PASS2; } else { /* Return a failure if name not found */ InterpreterMode = ACPI_IMODE_EXECUTE; } Status = AcpiNsLookup (WalkState->ScopeInfo, NameString, ACPI_TYPE_ANY, InterpreterMode, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, WalkState, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc)); /* * The only case where we pass through (ignore) a NOT_FOUND * error is for the CondRefOf opcode. */ if (Status == AE_NOT_FOUND) { if (ParentOp->Common.AmlOpcode == AML_COND_REF_OF_OP) { /* * For the Conditional Reference op, it's OK if * the name is not found; We just need a way to * indicate this to the interpreter, set the * object to the root */ ObjDesc = ACPI_CAST_PTR ( ACPI_OPERAND_OBJECT, AcpiGbl_RootNode); Status = AE_OK; } else { /* * We just plain didn't find it -- which is a * very serious error at this point */ Status = AE_AML_NAME_NOT_FOUND; } } if (ACPI_FAILURE (Status)) { ACPI_ERROR_NAMESPACE (NameString, Status); } } /* Free the namestring created above */ ACPI_FREE (NameString); /* Check status from the lookup */ if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Put the resulting object onto the current object stack */ Status = AcpiDsObjStackPush (ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); } else { /* Check for null name case */ if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) { /* * If the name is null, this means that this is an * optional result parameter that was not specified * in the original ASL. Create a Zero Constant for a * placeholder. (Store to a constant is a Noop.) */ Opcode = AML_ZERO_OP; /* Has no arguments! */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", Arg)); } else { Opcode = Arg->Common.AmlOpcode; } /* Get the object type of the argument */ OpInfo = AcpiPsGetOpcodeInfo (Opcode); if (OpInfo->ObjectType == ACPI_TYPE_INVALID) { return_ACPI_STATUS (AE_NOT_IMPLEMENTED); } if ((OpInfo->Flags & AML_HAS_RETVAL) || (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Argument previously created, already stacked\n")); ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject ( WalkState->Operands [WalkState->NumOperands - 1], WalkState)); /* * Use value that was already previously returned * by the evaluation of this argument */ Status = AcpiDsResultPop (&ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { /* * Only error is underflow, and this indicates * a missing or null operand! */ ACPI_EXCEPTION ((AE_INFO, Status, "Missing or null operand")); return_ACPI_STATUS (Status); } } else { /* Create an ACPI_INTERNAL_OBJECT for the argument */ ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Initialize the new object */ Status = AcpiDsInitObjectFromOp ( WalkState, Arg, Opcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtDeleteObjectDesc (ObjDesc); return_ACPI_STATUS (Status); } } /* Put the operand object on the object stack */ Status = AcpiDsObjStackPush (ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); } return_ACPI_STATUS (AE_OK); }
static ACPI_STATUS AcpiDsBuildInternalObject ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (DsBuildInternalObject); *ObjDescPtr = NULL; if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { /* * This is a named object reference. If this name was * previously looked up in the namespace, it was stored in this op. * Otherwise, go ahead and look it up now */ if (!Op->Common.Node) { Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); if (ACPI_FAILURE (Status)) { /* Check if we are resolving a named reference within a package */ if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) { /* * We didn't find the target and we are populating elements * of a package - ignore if slack enabled. Some ASL code * contains dangling invalid references in packages and * expects that no exception will be issued. Leave the * element as a null element. It cannot be used, but it * can be overwritten by subsequent ASL code - this is * typically the case. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Ignoring unresolved reference in package [%4.4s]\n", WalkState->ScopeInfo->Scope.Node->Name.Ascii)); return_ACPI_STATUS (AE_OK); } else { ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); } return_ACPI_STATUS (Status); } } } /* Create and init a new internal ACPI object */ ObjDesc = AcpiUtCreateInternalObject ( (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); return_ACPI_STATUS (Status); } *ObjDescPtr = ObjDesc; return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiDsInitObjectFromOp ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, UINT16 Opcode, ACPI_OPERAND_OBJECT **RetObjDesc) { const ACPI_OPCODE_INFO *OpInfo; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE (DsInitObjectFromOp); ObjDesc = *RetObjDesc; OpInfo = AcpiPsGetOpcodeInfo (Opcode); if (OpInfo->Class == AML_CLASS_UNKNOWN) { /* Unknown opcode */ return_ACPI_STATUS (AE_TYPE); } /* Perform per-object initialization */ switch (ObjDesc->Common.Type) { case ACPI_TYPE_BUFFER: /* * Defer evaluation of Buffer TermArg operand */ ObjDesc->Buffer.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WalkState->Operands[0]); ObjDesc->Buffer.AmlStart = Op->Named.Data; ObjDesc->Buffer.AmlLength = Op->Named.Length; break; case ACPI_TYPE_PACKAGE: /* * Defer evaluation of Package TermArg operand */ ObjDesc->Package.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WalkState->Operands[0]); ObjDesc->Package.AmlStart = Op->Named.Data; ObjDesc->Package.AmlLength = Op->Named.Length; break; case ACPI_TYPE_INTEGER: switch (OpInfo->Type) { case AML_TYPE_CONSTANT: /* * Resolve AML Constants here - AND ONLY HERE! * All constants are integers. * We mark the integer with a flag that indicates that it started * life as a constant -- so that stores to constants will perform * as expected (noop). ZeroOp is used as a placeholder for optional * target operands. */ ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT; switch (Opcode) { case AML_ZERO_OP: ObjDesc->Integer.Value = 0; break; case AML_ONE_OP: ObjDesc->Integer.Value = 1; break; case AML_ONES_OP: ObjDesc->Integer.Value = ACPI_UINT64_MAX; /* Truncate value if we are executing from a 32-bit ACPI table */ #ifndef ACPI_NO_METHOD_EXECUTION (void) AcpiExTruncateFor32bitTable (ObjDesc); #endif break; case AML_REVISION_OP: ObjDesc->Integer.Value = ACPI_CA_VERSION; break; default: ACPI_ERROR ((AE_INFO, "Unknown constant opcode 0x%X", Opcode)); Status = AE_AML_OPERAND_TYPE; break; } break; case AML_TYPE_LITERAL: ObjDesc->Integer.Value = Op->Common.Value.Integer; #ifndef ACPI_NO_METHOD_EXECUTION if (AcpiExTruncateFor32bitTable (ObjDesc)) { /* Warn if we found a 64-bit constant in a 32-bit table */ ACPI_WARNING ((AE_INFO, "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer), (UINT32) ObjDesc->Integer.Value)); } #endif break; default: ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X", OpInfo->Type)); Status = AE_AML_OPERAND_TYPE; break; } break; case ACPI_TYPE_STRING: ObjDesc->String.Pointer = Op->Common.Value.String; ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Op->Common.Value.String); /* * The string is contained in the ACPI table, don't ever try * to delete it */ ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; break; case ACPI_TYPE_METHOD: break; case ACPI_TYPE_LOCAL_REFERENCE: switch (OpInfo->Type) { case AML_TYPE_LOCAL_VARIABLE: /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP; ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL; #ifndef ACPI_NO_METHOD_EXECUTION Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL, ObjDesc->Reference.Value, WalkState, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc->Reference.Object)); #endif break; case AML_TYPE_METHOD_ARGUMENT: /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP; ObjDesc->Reference.Class = ACPI_REFCLASS_ARG; #ifndef ACPI_NO_METHOD_EXECUTION Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG, ObjDesc->Reference.Value, WalkState, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc->Reference.Object)); #endif break; default: /* Object name or Debug object */ switch (Op->Common.AmlOpcode) { case AML_INT_NAMEPATH_OP: /* Node was saved in Op */ ObjDesc->Reference.Node = Op->Common.Node; ObjDesc->Reference.Object = Op->Common.Node->Object; ObjDesc->Reference.Class = ACPI_REFCLASS_NAME; break; case AML_DEBUG_OP: ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG; break; default: ACPI_ERROR ((AE_INFO, "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } break; } break; default: ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X", ObjDesc->Common.Type)); Status = AE_AML_OPERAND_TYPE; break; } return_ACPI_STATUS (Status); }
static ACPI_STATUS AcpiDsBuildInternalObject ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; ACPI_OBJECT_TYPE Type; ACPI_FUNCTION_TRACE (DsBuildInternalObject); *ObjDescPtr = NULL; if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { /* * This is a named object reference. If this name was * previously looked up in the namespace, it was stored in this op. * Otherwise, go ahead and look it up now */ if (!Op->Common.Node) { Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); if (ACPI_FAILURE (Status)) { /* Check if we are resolving a named reference within a package */ if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) { /* * We didn't find the target and we are populating elements * of a package - ignore if slack enabled. Some ASL code * contains dangling invalid references in packages and * expects that no exception will be issued. Leave the * element as a null element. It cannot be used, but it * can be overwritten by subsequent ASL code - this is * typically the case. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Ignoring unresolved reference in package [%4.4s]\n", WalkState->ScopeInfo->Scope.Node->Name.Ascii)); return_ACPI_STATUS (AE_OK); } else { ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); } return_ACPI_STATUS (Status); } } /* Special object resolution for elements of a package */ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) { /* * Attempt to resolve the node to a value before we insert it into * the package. If this is a reference to a common data type, * resolve it immediately. According to the ACPI spec, package * elements can only be "data objects" or method references. * Attempt to resolve to an Integer, Buffer, String or Package. * If cannot, return the named reference (for things like Devices, * Methods, etc.) Buffer Fields and Fields will resolve to simple * objects (int/buf/str/pkg). * * NOTE: References to things like Devices, Methods, Mutexes, etc. * will remain as named references. This behavior is not described * in the ACPI spec, but it appears to be an oversight. */ ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node); Status = AcpiExResolveNodeToValue ( ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc), WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * Special handling for Alias objects. We need to setup the type * and the Op->Common.Node to point to the Alias target. Note, * Alias has at most one level of indirection internally. */ Type = Op->Common.Node->Type; if (Type == ACPI_TYPE_LOCAL_ALIAS) { Type = ObjDesc->Common.Type; Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Op->Common.Node->Object); } switch (Type) { /* * For these types, we need the actual node, not the subobject. * However, the subobject did not get an extra reference count above. * * TBD: should ExResolveNodeToValue be changed to fix this? */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_THERMAL: AcpiUtAddReference (Op->Common.Node->Object); /*lint -fallthrough */ /* * For these types, we need the actual node, not the subobject. * The subobject got an extra reference count in ExResolveNodeToValue. */ case ACPI_TYPE_MUTEX: case ACPI_TYPE_METHOD: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_EVENT: case ACPI_TYPE_REGION: /* We will create a reference object for these types below */ break; default: /* * All other types - the node was resolved to an actual * object, we are done. */ goto Exit; } } } /* Create and init a new internal ACPI object */ ObjDesc = AcpiUtCreateInternalObject ( (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); return_ACPI_STATUS (Status); } Exit: *ObjDescPtr = ObjDesc; return_ACPI_STATUS (Status); }
ACPI_STATUS 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 AcpiDsBuildInternalObject ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (DsBuildInternalObject); *ObjDescPtr = NULL; if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) { /* * This is a named object reference. If this name was * previously looked up in the namespace, it was stored in * this op. Otherwise, go ahead and look it up now */ if (!Op->Common.Node) { /* Check if we are resolving a named reference within a package */ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)) { /* * We won't resolve package elements here, we will do this * after all ACPI tables are loaded into the namespace. This * behavior supports both forward references to named objects * and external references to objects in other tables. */ goto CreateNewObject; } else { Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, ACPI_CAST_INDIRECT_PTR ( ACPI_NAMESPACE_NODE, &(Op->Common.Node))); if (ACPI_FAILURE (Status)) { ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Op->Common.Value.String, Status); return_ACPI_STATUS (Status); } } } } CreateNewObject: /* Create and init a new internal ACPI object */ ObjDesc = AcpiUtCreateInternalObject ( (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); if (!ObjDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitObjectFromOp ( WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); return_ACPI_STATUS (Status); } /* * Handling for unresolved package reference elements. * These are elements that are namepaths. */ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)) { ObjDesc->Reference.Resolved = TRUE; if ((Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && !ObjDesc->Reference.Node) { /* * Name was unresolved above. * Get the prefix node for later lookup */ ObjDesc->Reference.Node = WalkState->ScopeInfo->Scope.Node; ObjDesc->Reference.Aml = Op->Common.Aml; ObjDesc->Reference.Resolved = FALSE; } } *ObjDescPtr = ObjDesc; return_ACPI_STATUS (Status); }
static void AcpiEvOrphanEcRegMethod ( void) { ACPI_TABLE_ECDT *Table; ACPI_STATUS Status; ACPI_OBJECT_LIST Args; ACPI_OBJECT Objects[2]; ACPI_NAMESPACE_NODE *EcDeviceNode; ACPI_NAMESPACE_NODE *RegMethod; ACPI_NAMESPACE_NODE *NextNode; ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod); /* Get the ECDT (if present in system) */ Status = AcpiGetTable (ACPI_SIG_ECDT, 0, ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Table)); if (ACPI_FAILURE (Status)) { return_VOID; } /* We need a valid EC_ID string */ if (!(*Table->Id)) { return_VOID; } /* Namespace is currently locked, must release */ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); /* Get a handle to the EC device referenced in the ECDT */ Status = AcpiGetHandle (NULL, ACPI_CAST_PTR (char, Table->Id), ACPI_CAST_PTR (ACPI_HANDLE, &EcDeviceNode)); if (ACPI_FAILURE (Status)) { goto Exit; } /* Get a handle to a _REG method immediately under the EC device */ Status = AcpiGetHandle (EcDeviceNode, METHOD_NAME__REG, ACPI_CAST_PTR (ACPI_HANDLE, &RegMethod)); if (ACPI_FAILURE (Status)) { goto Exit; } /* * Execute the _REG method only if there is no Operation Region in * this scope with the Embedded Controller space ID. Otherwise, it * will already have been executed. Note, this allows for Regions * with other space IDs to be present; but the code below will then * execute the _REG method with the EC space ID argument. */ NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL); while (NextNode) { if ((NextNode->Type == ACPI_TYPE_REGION) && (NextNode->Object) && (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC)) { goto Exit; /* Do not execute _REG */ } NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode); } /* Evaluate the _REG(EC,Connect) method */ Args.Count = 2; Args.Pointer = Objects; Objects[0].Type = ACPI_TYPE_INTEGER; Objects[0].Integer.Value = ACPI_ADR_SPACE_EC; Objects[1].Type = ACPI_TYPE_INTEGER; Objects[1].Integer.Value = ACPI_REG_CONNECT; Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL); Exit: /* We ignore all errors from above, don't care */ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); return_VOID; }
static void acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) { u8 *target = NULL; u8 *previous_target; char *name; u8 count; /* First table entry must contain the table length (# of table entries) */ count = table->offset; while (count) { previous_target = target; target = ACPI_ADD_PTR(u8, resource, table->offset); name = table->name; switch (table->opcode) { case ACPI_RSD_TITLE: /* * Optional resource title */ if (table->name) { acpi_os_printf("%s Resource\n", name); } break; /* Strings */ case ACPI_RSD_LITERAL: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table->pointer)); break; case ACPI_RSD_STRING: acpi_rs_out_string(name, ACPI_CAST_PTR(char, target)); break; /* Data items, 8/16/32/64 bit */ case ACPI_RSD_UINT8: if (table->pointer) { acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer [*target])); } else { acpi_rs_out_integer8(name, ACPI_GET8(target)); } break; case ACPI_RSD_UINT16: acpi_rs_out_integer16(name, ACPI_GET16(target)); break; case ACPI_RSD_UINT32: acpi_rs_out_integer32(name, ACPI_GET32(target)); break; case ACPI_RSD_UINT64: acpi_rs_out_integer64(name, ACPI_GET64(target)); break; /* Flags: 1-bit and 2-bit flags supported */ case ACPI_RSD_1BITFLAG: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer[*target & 0x01])); break; case ACPI_RSD_2BITFLAG: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer[*target & 0x03])); break; case ACPI_RSD_3BITFLAG: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer[*target & 0x07])); break; case ACPI_RSD_SHORTLIST: /* * Short byte list (single line output) for DMA and IRQ resources * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_out_title(name); acpi_rs_dump_short_byte_list(*previous_target, target); } break; case ACPI_RSD_SHORTLISTX: /* * Short byte list (single line output) for GPIO vendor data * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_out_title(name); acpi_rs_dump_short_byte_list(*previous_target, * (ACPI_CAST_INDIRECT_PTR (u8, target))); } break; case ACPI_RSD_LONGLIST: /* * Long byte list for Vendor resource data * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_dump_byte_list(ACPI_GET16 (previous_target), target); } break; case ACPI_RSD_DWORDLIST: /* * Dword list for Extended Interrupt resources * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_dump_dword_list(*previous_target, ACPI_CAST_PTR(u32, target)); } break; case ACPI_RSD_WORDLIST: /* * Word list for GPIO Pin Table * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_dump_word_list(*previous_target, *(ACPI_CAST_INDIRECT_PTR (u16, target))); } break; case ACPI_RSD_ADDRESS: /* * Common flags for all Address resources */ acpi_rs_dump_address_common(ACPI_CAST_PTR (union acpi_resource_data, target)); break; case ACPI_RSD_SOURCE: /* * Optional resource_source for Address resources */ acpi_rs_dump_resource_source(ACPI_CAST_PTR (struct acpi_resource_source, target)); break; default: acpi_os_printf("**** Invalid table opcode [%X] ****\n", table->opcode); return; }
ACPI_STATUS AcpiRsConvertAmlToResources ( UINT8 *Aml, UINT32 Length, UINT32 Offset, UINT8 ResourceIndex, void **Context) { ACPI_RESOURCE **ResourcePtr = ACPI_CAST_INDIRECT_PTR ( ACPI_RESOURCE, Context); ACPI_RESOURCE *Resource; AML_RESOURCE *AmlResource; ACPI_RSCONVERT_INFO *ConversionTable; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (RsConvertAmlToResources); /* * Check that the input buffer and all subsequent pointers into it * are aligned on a native word boundary. Most important on IA64 */ Resource = *ResourcePtr; if (ACPI_IS_MISALIGNED (Resource)) { ACPI_WARNING ((AE_INFO, "Misaligned resource pointer %p", Resource)); } /* Get the appropriate conversion info table */ AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml); if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_SERIAL_BUS) { if (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE) { ConversionTable = NULL; } else { /* This is an I2C, SPI, or UART SerialBus descriptor */ ConversionTable = AcpiGbl_ConvertResourceSerialBusDispatch[ AmlResource->CommonSerialBus.Type]; } } else { ConversionTable = AcpiGbl_GetResourceDispatch[ResourceIndex]; } if (!ConversionTable) { ACPI_ERROR ((AE_INFO, "Invalid/unsupported resource descriptor: Type 0x%2.2X", ResourceIndex)); return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } /* Convert the AML byte stream resource to a local resource struct */ Status = AcpiRsConvertAmlToResource ( Resource, AmlResource, ConversionTable); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not convert AML resource (Type 0x%X)", *Aml)); return_ACPI_STATUS (Status); } ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, "Type %.2X, AmlLength %.2X InternalLength %.2X\n", AcpiUtGetResourceType (Aml), Length, Resource->Length)); /* Point to the next structure in the output buffer */ *ResourcePtr = ACPI_NEXT_RESOURCE (Resource); return_ACPI_STATUS (AE_OK); }
static void AcpiRsDumpDescriptor ( void *Resource, ACPI_RSDUMP_INFO *Table) { UINT8 *Target = NULL; UINT8 *PreviousTarget; const char *Name; UINT8 Count; /* First table entry must contain the table length (# of table entries) */ Count = Table->Offset; while (Count) { PreviousTarget = Target; Target = ACPI_ADD_PTR (UINT8, Resource, Table->Offset); Name = Table->Name; switch (Table->Opcode) { case ACPI_RSD_TITLE: /* * Optional resource title */ if (Table->Name) { AcpiOsPrintf ("%s Resource\n", Name); } break; /* Strings */ case ACPI_RSD_LITERAL: AcpiRsOutString (Name, ACPI_CAST_PTR (char, Table->Pointer)); break; case ACPI_RSD_STRING: AcpiRsOutString (Name, ACPI_CAST_PTR (char, Target)); break; /* Data items, 8/16/32/64 bit */ case ACPI_RSD_UINT8: if (Table->Pointer) { AcpiRsOutString (Name, Table->Pointer [*Target]); } else { AcpiRsOutInteger8 (Name, ACPI_GET8 (Target)); } break; case ACPI_RSD_UINT16: AcpiRsOutInteger16 (Name, ACPI_GET16 (Target)); break; case ACPI_RSD_UINT32: AcpiRsOutInteger32 (Name, ACPI_GET32 (Target)); break; case ACPI_RSD_UINT64: AcpiRsOutInteger64 (Name, ACPI_GET64 (Target)); break; /* Flags: 1-bit and 2-bit flags supported */ case ACPI_RSD_1BITFLAG: AcpiRsOutString (Name, Table->Pointer [*Target & 0x01]); break; case ACPI_RSD_2BITFLAG: AcpiRsOutString (Name, Table->Pointer [*Target & 0x03]); break; case ACPI_RSD_3BITFLAG: AcpiRsOutString (Name, Table->Pointer [*Target & 0x07]); break; case ACPI_RSD_SHORTLIST: /* * Short byte list (single line output) for DMA and IRQ resources * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsOutTitle (Name); AcpiRsDumpShortByteList (*PreviousTarget, Target); } break; case ACPI_RSD_SHORTLISTX: /* * Short byte list (single line output) for GPIO vendor data * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsOutTitle (Name); AcpiRsDumpShortByteList (*PreviousTarget, *(ACPI_CAST_INDIRECT_PTR (UINT8, Target))); } break; case ACPI_RSD_LONGLIST: /* * Long byte list for Vendor resource data * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsDumpByteList (ACPI_GET16 (PreviousTarget), Target); } break; case ACPI_RSD_DWORDLIST: /* * Dword list for Extended Interrupt resources * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsDumpDwordList (*PreviousTarget, ACPI_CAST_PTR (UINT32, Target)); } break; case ACPI_RSD_WORDLIST: /* * Word list for GPIO Pin Table * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsDumpWordList (*PreviousTarget, *(ACPI_CAST_INDIRECT_PTR (UINT16, Target))); } break; case ACPI_RSD_ADDRESS: /* * Common flags for all Address resources */ AcpiRsDumpAddressCommon (ACPI_CAST_PTR ( ACPI_RESOURCE_DATA, Target)); break; case ACPI_RSD_SOURCE: /* * Optional ResourceSource for Address resources */ AcpiRsDumpResourceSource (ACPI_CAST_PTR ( ACPI_RESOURCE_SOURCE, Target)); break; case ACPI_RSD_LABEL: /* * ResourceLabel */ AcpiRsDumpResourceLabel ("Resource Label", ACPI_CAST_PTR ( ACPI_RESOURCE_LABEL, Target)); break; case ACPI_RSD_SOURCE_LABEL: /* * ResourceSourceLabel */ AcpiRsDumpResourceLabel ("Resource Source Label", ACPI_CAST_PTR ( ACPI_RESOURCE_LABEL, Target)); break; default: AcpiOsPrintf ("**** Invalid table opcode [%X] ****\n", Table->Opcode); return; } Table++; Count--; } }
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); }