ACPI_STATUS AcpiDsStoreObjectToLocal ( UINT8 Type, UINT32 Index, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; ACPI_OPERAND_OBJECT *CurrentObjDesc; ACPI_OPERAND_OBJECT *NewObjDesc; ACPI_FUNCTION_TRACE (DsStoreObjectToLocal); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n", Type, Index, ObjDesc)); /* Parameter validation */ if (!ObjDesc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get the namespace node for the arg/local */ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } CurrentObjDesc = AcpiNsGetAttachedObject (Node); if (CurrentObjDesc == ObjDesc) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", ObjDesc)); return_ACPI_STATUS (Status); } /* * If the reference count on the object is more than one, we must * take a copy of the object before we store. A reference count * of exactly 1 means that the object was just created during the * evaluation of an expression, and we can safely use it since it * is not used anywhere else. */ NewObjDesc = ObjDesc; if (ObjDesc->Common.ReferenceCount > 1) { Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } /* * If there is an object already in this slot, we either * have to delete it, or if this is an argument and there * is an object reference stored there, we have to do * an indirect store! */ if (CurrentObjDesc) { /* * Check for an indirect store if an argument * contains an object reference (stored as an Node). * We don't allow this automatic dereferencing for * locals, since a store to a local should overwrite * anything there, including an object reference. * * If both Arg0 and Local0 contain RefOf (Local4): * * Store (1, Arg0) - Causes indirect store to local4 * Store (1, Local0) - Stores 1 in local0, overwriting * the reference to local4 * Store (1, DeRefof (Local0)) - Causes indirect store to local4 * * Weird, but true. */ if (Type == ACPI_REFCLASS_ARG) { /* * If we have a valid reference object that came from RefOf(), * do the indirect store */ if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) && (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Arg (%p) is an ObjRef(Node), storing in node %p\n", NewObjDesc, CurrentObjDesc)); /* * Store this object to the Node (perform the indirect store) * NOTE: No implicit conversion is performed, as per the ACPI * specification rules on storing to Locals/Args. */ Status = AcpiExStoreObjectToNode (NewObjDesc, CurrentObjDesc->Reference.Object, WalkState, ACPI_NO_IMPLICIT_CONVERSION); /* Remove local reference if we copied the object above */ if (NewObjDesc != ObjDesc) { AcpiUtRemoveReference (NewObjDesc); } return_ACPI_STATUS (Status); } } /* Delete the existing object before storing the new one */ AcpiDsMethodDataDeleteValue (Type, Index, WalkState); } /* * Install the Obj descriptor (*NewObjDesc) into * the descriptor for the Arg or Local. * (increments the object reference count by one) */ Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState); /* Remove local reference if we copied the object above */ if (NewObjDesc != ObjDesc) { AcpiUtRemoveReference (NewObjDesc); } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiDsStoreObjectToLocal ( UINT16 Opcode, UINT32 Index, ACPI_OPERAND_OBJECT *SrcDesc, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; ACPI_OPERAND_OBJECT **Entry; FUNCTION_TRACE ("DsMethodDataSetValue"); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n", Opcode, Index, SrcDesc)); /* Parameter validation */ if (!SrcDesc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the requested method stack entry */ Status = AcpiDsMethodDataGetEntry (Opcode, Index, WalkState, &Entry); if (ACPI_FAILURE (Status)) { goto Cleanup; } if (*Entry == SrcDesc) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", SrcDesc)); goto Cleanup; } /* * If there is an object already in this slot, we either * have to delete it, or if this is an argument and there * is an object reference stored there, we have to do * an indirect store! */ if (*Entry) { /* * Check for an indirect store if an argument * contains an object reference (stored as an Node). * We don't allow this automatic dereferencing for * locals, since a store to a local should overwrite * anything there, including an object reference. * * If both Arg0 and Local0 contain RefOf (Local4): * * Store (1, Arg0) - Causes indirect store to local4 * Store (1, Local0) - Stores 1 in local0, overwriting * the reference to local4 * Store (1, DeRefof (Local0)) - Causes indirect store to local4 * * Weird, but true. */ if ((Opcode == AML_ARG_OP) && (VALID_DESCRIPTOR_TYPE (*Entry, ACPI_DESC_TYPE_NAMED))) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Arg (%p) is an ObjRef(Node), storing in %p\n", SrcDesc, *Entry)); /* Detach an existing object from the Node */ AcpiNsDetachObject ((ACPI_NAMESPACE_NODE *) *Entry); /* * Store this object into the Node * (do the indirect store) */ Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) *Entry, SrcDesc, SrcDesc->Common.Type); return_ACPI_STATUS (Status); } #ifdef ACPI_ENABLE_IMPLICIT_CONVERSION /* * Perform "Implicit conversion" of the new object to the type of the * existing object */ Status = AcpiExConvertToTargetType ((*Entry)->Common.Type, &SrcDesc, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } #endif /* * Delete the existing object * before storing the new one */ AcpiDsMethodDataDeleteValue (Opcode, Index, WalkState); } /* * Install the ObjStack descriptor (*SrcDesc) into * the descriptor for the Arg or Local. * Install the new object in the stack entry * (increments the object reference count by one) */ Status = AcpiDsMethodDataSetEntry (Opcode, Index, SrcDesc, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* Normal exit */ return_ACPI_STATUS (AE_OK); /* Error exit */ Cleanup: return_ACPI_STATUS (Status); }