static ACPI_STATUS AcpiExStoreDirectToNode ( ACPI_OPERAND_OBJECT *SourceDesc, ACPI_NAMESPACE_NODE *Node, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; ACPI_OPERAND_OBJECT *NewDesc; ACPI_FUNCTION_TRACE (ExStoreDirectToNode); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing [%s] (%p) directly into node [%s] (%p)" " with no implicit conversion\n", AcpiUtGetObjectTypeName (SourceDesc), SourceDesc, AcpiUtGetTypeName (Node->Type), Node)); /* Copy the source object to a new object */ Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Attach the new object to the node */ Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type); AcpiUtRemoveReference (NewDesc); return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiDsEvaluateNamePath ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_PARSE_OBJECT *Op = WalkState->Op; ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; ACPI_OPERAND_OBJECT *NewObjDesc; UINT8 Type; ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState); if (!Op->Common.Parent) { /* This happens after certain exception processing */ goto Exit; } if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP)) { /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */ goto Exit; } Status = AcpiDsCreateOperand (WalkState, Op, 0); if (ACPI_FAILURE (Status)) { goto Exit; } if (Op->Common.Flags & ACPI_PARSEOP_TARGET) { NewObjDesc = *Operand; goto PushResult; } Type = (*Operand)->Common.Type; Status = AcpiExResolveToValue (Operand, WalkState); if (ACPI_FAILURE (Status)) { goto Exit; } if (Type == ACPI_TYPE_INTEGER) { /* It was incremented by AcpiExResolveToValue */ AcpiUtRemoveReference (*Operand); Status = AcpiUtCopyIobjectToIobject (*Operand, &NewObjDesc, WalkState); if (ACPI_FAILURE (Status)) { goto Exit; } } else { /* * The object either was anew created or is * a Namespace node - don't decrement it. */ NewObjDesc = *Operand; } /* Cleanup for name-path operand */ Status = AcpiDsObjStackPop (1, WalkState); if (ACPI_FAILURE (Status)) { WalkState->ResultObj = NewObjDesc; goto Exit; } PushResult: WalkState->ResultObj = NewObjDesc; Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); if (ACPI_SUCCESS (Status)) { /* Force to take it from stack */ Op->Common.Flags |= ACPI_PARSEOP_IN_STACK; } Exit: return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiExOpcode_1A_1T_1R ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; ACPI_OPERAND_OBJECT *ReturnDesc = NULL; ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL; UINT32 Temp32; UINT32 i; UINT64 PowerOfTen; UINT64 Digit; ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R, AcpiPsGetOpcodeName (WalkState->Opcode)); /* Examine the AML opcode */ switch (WalkState->Opcode) { case AML_BIT_NOT_OP: case AML_FIND_SET_LEFT_BIT_OP: case AML_FIND_SET_RIGHT_BIT_OP: case AML_FROM_BCD_OP: case AML_TO_BCD_OP: case AML_COND_REF_OF_OP: /* Create a return object of type Integer for these opcodes */ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } switch (WalkState->Opcode) { case AML_BIT_NOT_OP: /* Not (Operand, Result) */ ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value; break; case AML_FIND_SET_LEFT_BIT_OP: /* FindSetLeftBit (Operand, Result) */ ReturnDesc->Integer.Value = Operand[0]->Integer.Value; /* * Acpi specification describes Integer type as a little * endian unsigned value, so this boundary condition is valid. */ for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) { ReturnDesc->Integer.Value >>= 1; } ReturnDesc->Integer.Value = Temp32; break; case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */ ReturnDesc->Integer.Value = Operand[0]->Integer.Value; /* * The Acpi specification describes Integer type as a little * endian unsigned value, so this boundary condition is valid. */ for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) { ReturnDesc->Integer.Value <<= 1; } /* Since the bit position is one-based, subtract from 33 (65) */ ReturnDesc->Integer.Value = Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32; break; case AML_FROM_BCD_OP: /* FromBcd (BCDValue, Result) */ /* * The 64-bit ACPI integer can hold 16 4-bit BCD characters * (if table is 32-bit, integer can hold 8 BCD characters) * Convert each 4-bit BCD value */ PowerOfTen = 1; ReturnDesc->Integer.Value = 0; Digit = Operand[0]->Integer.Value; /* Convert each BCD digit (each is one nybble wide) */ for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++) { /* Get the least significant 4-bit BCD digit */ Temp32 = ((UINT32) Digit) & 0xF; /* Check the range of the digit */ if (Temp32 > 9) { ACPI_ERROR ((AE_INFO, "BCD digit too large (not decimal): 0x%X", Temp32)); Status = AE_AML_NUMERIC_OVERFLOW; goto Cleanup; } /* Sum the digit into the result with the current power of 10 */ ReturnDesc->Integer.Value += (((UINT64) Temp32) * PowerOfTen); /* Shift to next BCD digit */ Digit >>= 4; /* Next power of 10 */ PowerOfTen *= 10; } break; case AML_TO_BCD_OP: /* ToBcd (Operand, Result) */ ReturnDesc->Integer.Value = 0; Digit = Operand[0]->Integer.Value; /* Each BCD digit is one nybble wide */ for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++) { (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32); /* * Insert the BCD digit that resides in the * remainder from above */ ReturnDesc->Integer.Value |= (((UINT64) Temp32) << ACPI_MUL_4 (i)); } /* Overflow if there is any data left in Digit */ if (Digit > 0) { ACPI_ERROR ((AE_INFO, "Integer too large to convert to BCD: 0x%8.8X%8.8X", ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value))); Status = AE_AML_NUMERIC_OVERFLOW; goto Cleanup; } break; case AML_COND_REF_OF_OP: /* CondRefOf (SourceObject, Result) */ /* * This op is a little strange because the internal return value is * different than the return value stored in the result descriptor * (There are really two return values) */ if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode) { /* * This means that the object does not exist in the namespace, * return FALSE */ ReturnDesc->Integer.Value = 0; goto Cleanup; } /* Get the object reference, store it, and remove our reference */ Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc2, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState); AcpiUtRemoveReference (ReturnDesc2); /* The object exists in the namespace, return TRUE */ ReturnDesc->Integer.Value = ACPI_UINT64_MAX; goto Cleanup; default: /* No other opcodes get here */ break; } break; case AML_STORE_OP: /* Store (Source, Target) */ /* * A store operand is typically a number, string, buffer or lvalue * Be careful about deleting the source object, * since the object itself may have been stored. */ Status = AcpiExStore (Operand[0], Operand[1], WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* It is possible that the Store already produced a return object */ if (!WalkState->ResultObj) { /* * Normally, we would remove a reference on the Operand[0] * parameter; But since it is being used as the internal return * object (meaning we would normally increment it), the two * cancel out, and we simply don't do anything. */ WalkState->ResultObj = Operand[0]; WalkState->Operands[0] = NULL; /* Prevent deletion */ } return_ACPI_STATUS (Status); /* * ACPI 2.0 Opcodes */ case AML_COPY_OP: /* Copy (Source, Target) */ Status = AcpiUtCopyIobjectToIobject ( Operand[0], &ReturnDesc, WalkState); break; case AML_TO_DECSTRING_OP: /* ToDecimalString (Data, Result) */ Status = AcpiExConvertToString ( Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_DECIMAL); if (ReturnDesc == Operand[0]) { /* No conversion performed, add ref to handle return value */ AcpiUtAddReference (ReturnDesc); } break; case AML_TO_HEXSTRING_OP: /* ToHexString (Data, Result) */ Status = AcpiExConvertToString ( Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_HEX); if (ReturnDesc == Operand[0]) { /* No conversion performed, add ref to handle return value */ AcpiUtAddReference (ReturnDesc); } break; case AML_TO_BUFFER_OP: /* ToBuffer (Data, Result) */ Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc); if (ReturnDesc == Operand[0]) { /* No conversion performed, add ref to handle return value */ AcpiUtAddReference (ReturnDesc); } break; case AML_TO_INTEGER_OP: /* ToInteger (Data, Result) */ /* Perform "explicit" conversion */ Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc, 0); if (ReturnDesc == Operand[0]) { /* No conversion performed, add ref to handle return value */ AcpiUtAddReference (ReturnDesc); } break; case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */ case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */ /* These are two obsolete opcodes */ ACPI_ERROR ((AE_INFO, "%s is obsolete and not implemented", AcpiPsGetOpcodeName (WalkState->Opcode))); Status = AE_SUPPORT; goto Cleanup; default: /* Unknown opcode */ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", WalkState->Opcode)); Status = AE_AML_BAD_OPCODE; goto Cleanup; } if (ACPI_SUCCESS (Status)) { /* Store the return value computed above into the target object */ Status = AcpiExStore (ReturnDesc, Operand[1], WalkState); } Cleanup: /* Delete return object on error */ if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ReturnDesc); } /* Save return object on success */ else if (!WalkState->ResultObj) { WalkState->ResultObj = ReturnDesc; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiExStoreObjectToObject ( ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *DestDesc, ACPI_OPERAND_OBJECT **NewDesc, ACPI_WALK_STATE *WalkState) { ACPI_OPERAND_OBJECT *ActualSrcDesc; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc); ActualSrcDesc = SourceDesc; if (!DestDesc) { /* * There is no destination object (An uninitialized node or * package element), so we can simply copy the source object * creating a new destination object */ Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState); return_ACPI_STATUS (Status); } if (SourceDesc->Common.Type != DestDesc->Common.Type) { /* * The source type does not match the type of the destination. * Perform the "implicit conversion" of the source to the current type * of the target as per the ACPI specification. * * If no conversion performed, ActualSrcDesc = SourceDesc. * Otherwise, ActualSrcDesc is a temporary object to hold the * converted object. */ Status = AcpiExConvertToTargetType (DestDesc->Common.Type, SourceDesc, &ActualSrcDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } if (SourceDesc == ActualSrcDesc) { /* * No conversion was performed. Return the SourceDesc as the * new object. */ *NewDesc = SourceDesc; return_ACPI_STATUS (AE_OK); } } /* * We now have two objects of identical types, and we can perform a * copy of the *value* of the source object. */ switch (DestDesc->Common.Type) { case ACPI_TYPE_INTEGER: DestDesc->Integer.Value = ActualSrcDesc->Integer.Value; /* Truncate value if we are executing from a 32-bit ACPI table */ AcpiExTruncateFor32bitTable (DestDesc); break; case ACPI_TYPE_STRING: Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc); break; case ACPI_TYPE_BUFFER: Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc); break; case ACPI_TYPE_PACKAGE: Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc, WalkState); break; default: /* * All other types come here. */ ACPI_WARNING ((AE_INFO, "Store into type %s not implemented", AcpiUtGetObjectTypeName (DestDesc))); Status = AE_NOT_IMPLEMENTED; break; } if (ActualSrcDesc != SourceDesc) { /* Delete the intermediate (temporary) source object */ AcpiUtRemoveReference (ActualSrcDesc); } *NewDesc = DestDesc; return_ACPI_STATUS (Status); }
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); }
static ACPI_STATUS AcpiExStoreObjectToIndex ( ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *IndexDesc, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_OPERAND_OBJECT *NewDesc; UINT8 Value = 0; UINT32 i; ACPI_FUNCTION_TRACE (ExStoreObjectToIndex); /* * Destination must be a reference pointer, and * must point to either a buffer or a package */ switch (IndexDesc->Reference.TargetType) { case ACPI_TYPE_PACKAGE: /* * Storing to a package element. Copy the object and replace * any existing object with the new object. No implicit * conversion is performed. * * The object at *(IndexDesc->Reference.Where) is the * element within the package that is to be modified. * The parent package object is at IndexDesc->Reference.Object */ ObjDesc = *(IndexDesc->Reference.Where); if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE && SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE) { /* This is a DDBHandle, just add a reference to it */ AcpiUtAddReference (SourceDesc); NewDesc = SourceDesc; } else { /* Normal object, copy it */ Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } if (ObjDesc) { /* Decrement reference count by the ref count of the parent package */ for (i = 0; i < ((ACPI_OPERAND_OBJECT *) IndexDesc->Reference.Object)->Common.ReferenceCount; i++) { AcpiUtRemoveReference (ObjDesc); } } *(IndexDesc->Reference.Where) = NewDesc; /* Increment ref count by the ref count of the parent package-1 */ for (i = 1; i < ((ACPI_OPERAND_OBJECT *) IndexDesc->Reference.Object)->Common.ReferenceCount; i++) { AcpiUtAddReference (NewDesc); } break; case ACPI_TYPE_BUFFER_FIELD: /* * Store into a Buffer or String (not actually a real BufferField) * at a location defined by an Index. * * The first 8-bit element of the source object is written to the * 8-bit Buffer location defined by the Index destination object, * according to the ACPI 2.0 specification. */ /* * Make sure the target is a Buffer or String. An error should * not happen here, since the ReferenceObject was constructed * by the INDEX_OP code. */ ObjDesc = IndexDesc->Reference.Object; if ((ObjDesc->Common.Type != ACPI_TYPE_BUFFER) && (ObjDesc->Common.Type != ACPI_TYPE_STRING)) { return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* * The assignment of the individual elements will be slightly * different for each source type. */ switch (SourceDesc->Common.Type) { case ACPI_TYPE_INTEGER: /* Use the least-significant byte of the integer */ Value = (UINT8) (SourceDesc->Integer.Value); break; case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: /* Note: Takes advantage of common string/buffer fields */ Value = SourceDesc->Buffer.Pointer[0]; break; default: /* All other types are invalid */ ACPI_ERROR ((AE_INFO, "Source must be Integer/Buffer/String type, not %s", AcpiUtGetObjectTypeName (SourceDesc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Store the source value into the target buffer byte */ ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value; break; default: ACPI_ERROR ((AE_INFO, "Target is not a Package or BufferField")); Status = AE_AML_OPERAND_TYPE; break; } 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) into 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); } /* If no implicit conversion, drop into the default case below */ if ((!ImplicitConversion) || ((WalkState->Opcode == AML_COPY_OP) && (TargetType != ACPI_TYPE_LOCAL_REGION_FIELD) && (TargetType != ACPI_TYPE_LOCAL_BANK_FIELD) && (TargetType != ACPI_TYPE_LOCAL_INDEX_FIELD))) { /* * Force execution of default (no implicit conversion). Note: * CopyObject does not perform an implicit conversion, as per the ACPI * spec -- except in case of region/bank/index fields -- because these * objects must retain their original type permanently. */ TargetType = ACPI_TYPE_ANY; } /* Do the actual store operation */ 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: /* For fields, copy the source data to the target field. */ Status = AcpiExWriteDataToField (SourceDesc, TargetDesc, &WalkState->ResultObj); break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These target types are all of type Integer/String/Buffer, and * therefore support implicit conversion before the store. * * Copy and/or convert the source object to a new target object */ 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; default: ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing [%s] (%p) directly into node [%s] (%p)" " with no implicit conversion\n", AcpiUtGetObjectTypeName (SourceDesc), SourceDesc, AcpiUtGetObjectTypeName (TargetDesc), Node)); /* * No conversions for all other types. Directly store a copy of * the source object. NOTE: This is a departure from the ACPI * spec, which states "If conversion is impossible, abort the * running control method". * * This code implements "If conversion is impossible, treat the * Store operation as a CopyObject". */ Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type); AcpiUtRemoveReference (NewDesc); break; } return_ACPI_STATUS (Status); }