Restructured object store code, initial implementation of target

conversion


date	2001.01.25.22.55.00;	author rmoore1;	state Exp;
This commit is contained in:
aystarik 2005-06-29 17:54:44 +00:00
parent 511ca4500c
commit 4b99f128f1
2 changed files with 611 additions and 828 deletions

View File

@ -2,8 +2,8 @@
/******************************************************************************
*
* Module Name: amstoren - AML Interpreter object store support,
* Store to Node (namespace object)
* $Revision: 1.23 $
* Store to Node (namespace object)
* $Revision: 1.27 $
*
*****************************************************************************/
@ -11,8 +11,8 @@
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999, Intel Corp. All rights
* reserved.
* Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
* All rights reserved.
*
* 2. License
*
@ -131,587 +131,241 @@
MODULE_NAME ("amstoren")
/*******************************************************************************
*
* FUNCTION: AcpiAmlStoreObjectToNode
* FUNCTION: AcpiAmlResolveObject
*
* PARAMETERS: *ValDesc - Value to be stored
* *Node - Named object to recieve the value
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION: Store the object to the named object.
*
* The Assignment of an object to a named object is handled here
* The val passed in will replace the current value (if any)
* with the input value.
*
* When storing into an object the data is converted to the
* target object type then stored in the object. This means
* that the target object type (for an initialized target) will
* not be changed by a store operation.
*
* NOTE: the global lock is acquired early. This will result
* in the global lock being held a bit longer. Also, if the
* function fails during set up we may get the lock when we
* don't really need it. I don't think we care.
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlStoreObjectToNode (
ACPI_OPERAND_OBJECT *ValDesc,
ACPI_NAMESPACE_NODE *Node,
AcpiAmlResolveObject (
ACPI_OPERAND_OBJECT **SourceDescPtr,
OBJECT_TYPE_INTERNAL TargetType,
ACPI_WALK_STATE *WalkState)
{
ACPI_OPERAND_OBJECT *SourceDesc = *SourceDescPtr;
ACPI_STATUS Status = AE_OK;
UINT8 *Buffer = NULL;
UINT32 Length = 0;
UINT32 Mask;
UINT32 NewValue;
BOOLEAN Locked = FALSE;
UINT8 *Location=NULL;
ACPI_OPERAND_OBJECT *DestDesc;
OBJECT_TYPE_INTERNAL DestinationType = ACPI_TYPE_ANY;
FUNCTION_TRACE ("AmlStoreObjectToNte");
FUNCTION_TRACE ("AmlResolveObject");
DEBUG_PRINT (ACPI_INFO,
("entered AcpiAmlStoreObjectToNode: NamedObj=%p, Obj=%p\n",
Node, ValDesc));
/*
* Assuming the parameters are valid!!!
* Ensure we have a Source that can be stored in the target
*/
ACPI_ASSERT((Node) && (ValDesc));
DestinationType = AcpiNsGetType (Node);
DEBUG_PRINT (ACPI_INFO, ("AmlStoreObjectToNte: Storing %s into %s\n",
AcpiCmGetTypeName (ValDesc->Common.Type),
AcpiCmGetTypeName (DestinationType)));
/*
* First ensure we have a value that can be stored in the target
*/
switch (DestinationType)
switch (TargetType)
{
/* Type of Name's existing value */
/* This case handles the "interchangeable" types Integer, String, and Buffer. */
/*
* These cases all require only Integers or values that
* can be converted to Integers (Strings or Buffers)
*/
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_FIELD_UNIT:
case INTERNAL_TYPE_BANK_FIELD:
case INTERNAL_TYPE_INDEX_FIELD:
/*
* Stores into a Field/Region or into a Buffer/String
* are all essentially the same.
*/
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
case INTERNAL_TYPE_DEF_FIELD:
/*
* If SourceDesc is not a valid type, try to resolve it to one.
*/
if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) &&
(SourceDesc->Common.Type != ACPI_TYPE_BUFFER) &&
(SourceDesc->Common.Type != ACPI_TYPE_STRING))
{
/*
* Initially not a valid type, convert
*/
Status = AcpiAmlResolveToValue (SourceDescPtr, WalkState);
if (ACPI_SUCCESS (Status) &&
(SourceDesc->Common.Type != ACPI_TYPE_INTEGER) &&
(SourceDesc->Common.Type != ACPI_TYPE_BUFFER) &&
(SourceDesc->Common.Type != ACPI_TYPE_STRING))
{
/*
* Conversion successful but still not a valid type
*/
DEBUG_PRINT (ACPI_ERROR,
("AmlResolveObject: Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
AcpiCmGetTypeName ((*SourceDescPtr)->Common.Type),
AcpiCmGetTypeName (TargetType)));
Status = AE_AML_OPERAND_TYPE;
}
}
break;
case INTERNAL_TYPE_ALIAS:
/*
* Aliases are resolved by AcpiAmlPrepOperands
* Aliases are resolved by AcpiAmlPrepOperands
*/
DEBUG_PRINT (ACPI_WARN,
("AmlStoreObjectToNte: Store into Alias - should never happen\n"));
("AmlResolveObject: Store into Alias - should never happen\n"));
Status = AE_AML_INTERNAL;
break;
case INTERNAL_TYPE_BANK_FIELD:
case INTERNAL_TYPE_INDEX_FIELD:
case ACPI_TYPE_FIELD_UNIT:
case ACPI_TYPE_NUMBER:
/*
* These cases all require only number values or values that
* can be converted to numbers.
*
* If value is not a Number, try to resolve it to one.
*/
if (ValDesc->Common.Type != ACPI_TYPE_NUMBER)
{
/*
* Initially not a number, convert
*/
Status = AcpiAmlResolveToValue (&ValDesc, WalkState);
if (ACPI_SUCCESS (Status) &&
(ValDesc->Common.Type != ACPI_TYPE_NUMBER))
{
/*
* Conversion successful but still not a number
*/
DEBUG_PRINT (ACPI_ERROR,
("AmlStoreObjectToNte: Value assigned to %s must be Number, not %s\n",
AcpiCmGetTypeName (DestinationType),
AcpiCmGetTypeName (ValDesc->Common.Type)));
Status = AE_AML_OPERAND_TYPE;
}
}
break;
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
case INTERNAL_TYPE_DEF_FIELD:
/*
* Storing into a Field in a region or into a buffer or into
* a string all is essentially the same.
*
* If value is not a valid type, try to resolve it to one.
*/
if ((ValDesc->Common.Type != ACPI_TYPE_NUMBER) &&
(ValDesc->Common.Type != ACPI_TYPE_BUFFER) &&
(ValDesc->Common.Type != ACPI_TYPE_STRING))
{
/*
* Initially not a valid type, convert
*/
Status = AcpiAmlResolveToValue (&ValDesc, WalkState);
if (ACPI_SUCCESS (Status) &&
(ValDesc->Common.Type != ACPI_TYPE_NUMBER) &&
(ValDesc->Common.Type != ACPI_TYPE_BUFFER) &&
(ValDesc->Common.Type != ACPI_TYPE_STRING))
{
/*
* Conversion successful but still not a valid type
*/
DEBUG_PRINT (ACPI_ERROR,
("AmlStoreObjectToNte: Assign wrong type %s to %s (must be type Num/Str/Buf)\n",
AcpiCmGetTypeName (ValDesc->Common.Type),
AcpiCmGetTypeName (DestinationType)));
Status = AE_AML_OPERAND_TYPE;
}
}
break;
case ACPI_TYPE_PACKAGE:
/*
* TBD: [Unhandled] Not real sure what to do here
*/
Status = AE_NOT_IMPLEMENTED;
break;
default:
/*
* All other types than Alias and the various Fields come here.
* Store ValDesc as the new value of the Name, and set
* the Name's type to that of the value being stored in it.
* ValDesc reference count is incremented by AttachObject.
* All other types than Alias and the various Fields come here,
* including the untyped case - ACPI_TYPE_ANY.
*/
Status = AcpiNsAttachObject (Node, ValDesc, ValDesc->Common.Type);
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNte: Store %s into %s via Attach\n",
AcpiCmGetTypeName (ValDesc->Common.Type),
AcpiCmGetTypeName (DestinationType)));
goto CleanUpAndBailOut;
break;
}
/* Exit now if failure above */
if (ACPI_FAILURE (Status))
{
goto CleanUpAndBailOut;
}
/*
* Get descriptor for object attached to Node
*/
DestDesc = AcpiNsGetAttachedObject (Node);
if (!DestDesc)
{
/*
* There is no existing object attached to this Node
*/
DEBUG_PRINT (ACPI_ERROR,
("AmlStoreObjectToNte: Internal error - no destination object for %4.4s type %d\n",
&Node->Name, DestinationType));
Status = AE_AML_INTERNAL;
goto CleanUpAndBailOut;
}
/*
* Make sure the destination Object is the same as the Node
*/
if (DestDesc->Common.Type != (UINT8) DestinationType)
{
DEBUG_PRINT (ACPI_ERROR,
("AmlStoreObjectToNte: Internal error - Name %4.4s type %d does not match value-type %d at %p\n",
&Node->Name, AcpiNsGetType (Node),
DestDesc->Common.Type, DestDesc));
Status = AE_AML_INTERNAL;
goto CleanUpAndBailOut;
}
/*
* AcpiEverything is ready to execute now, We have
* a value we can handle, just perform the update
*/
switch (DestinationType)
{
/* Type of Name's existing value */
case INTERNAL_TYPE_BANK_FIELD:
/*
* Get the global lock if needed
*/
Locked = AcpiAmlAcquireGlobalLock (DestDesc->BankField.LockRule);
/*
* Set Bank value to select proper Bank
* Perform the update (Set Bank Select)
*/
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
DestDesc->BankField.BankSelect,
&DestDesc->BankField.Value,
sizeof (DestDesc->BankField.Value));
if (ACPI_SUCCESS (Status))
{
/* Set bank select successful, set data value */
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
DestDesc->BankField.BankSelect,
&ValDesc->BankField.Value,
sizeof (ValDesc->BankField.Value));
}
break;
case INTERNAL_TYPE_DEF_FIELD:
/*
* Get the global lock if needed
*/
Locked = AcpiAmlAcquireGlobalLock (ValDesc->Field.LockRule);
/*
* Perform the update
*/
switch (ValDesc->Common.Type)
{
case ACPI_TYPE_NUMBER:
Buffer = (UINT8 *) &ValDesc->Number.Value;
Length = sizeof (ValDesc->Number.Value);
break;
case ACPI_TYPE_BUFFER:
Buffer = (UINT8 *) ValDesc->Buffer.Pointer;
Length = ValDesc->Buffer.Length;
break;
case ACPI_TYPE_STRING:
Buffer = (UINT8 *) ValDesc->String.Pointer;
Length = ValDesc->String.Length;
break;
}
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
Node, Buffer, Length);
break; /* Global Lock released below */
case ACPI_TYPE_STRING:
/*
* Perform the update
*/
switch (ValDesc->Common.Type)
{
case ACPI_TYPE_NUMBER:
Buffer = (UINT8 *) &ValDesc->Number.Value;
Length = sizeof (ValDesc->Number.Value);
break;
case ACPI_TYPE_BUFFER:
Buffer = (UINT8 *) ValDesc->Buffer.Pointer;
Length = ValDesc->Buffer.Length;
break;
case ACPI_TYPE_STRING:
Buffer = (UINT8 *) ValDesc->String.Pointer;
Length = ValDesc->String.Length;
break;
}
/*
* Setting a string value replaces the old string
*/
if (Length < DestDesc->String.Length)
{
/*
* Zero fill, not willing to do pointer arithmetic for
* archetecture independance. Just clear the whole thing
*/
MEMSET(DestDesc->String.Pointer, 0, DestDesc->String.Length);
MEMCPY(DestDesc->String.Pointer, Buffer, Length);
}
else
{
/*
* Free the current buffer, then allocate a buffer
* large enough to hold the value
*/
if ( DestDesc->String.Pointer &&
!AcpiTbSystemTablePointer (DestDesc->String.Pointer))
{
/*
* Only free if not a pointer into the DSDT
*/
AcpiCmFree(DestDesc->String.Pointer);
}
DestDesc->String.Pointer = AcpiCmAllocate (Length + 1);
DestDesc->String.Length = Length;
if (!DestDesc->String.Pointer)
{
Status = AE_NO_MEMORY;
goto CleanUpAndBailOut;
}
MEMCPY(DestDesc->String.Pointer, Buffer, Length);
}
break;
case ACPI_TYPE_BUFFER:
/*
* Perform the update to the buffer
*/
switch (ValDesc->Common.Type)
{
case ACPI_TYPE_NUMBER:
Buffer = (UINT8 *) &ValDesc->Number.Value;
Length = sizeof (ValDesc->Number.Value);
break;
case ACPI_TYPE_BUFFER:
Buffer = (UINT8 *) ValDesc->Buffer.Pointer;
Length = ValDesc->Buffer.Length;
break;
case ACPI_TYPE_STRING:
Buffer = (UINT8 *) ValDesc->String.Pointer;
Length = ValDesc->String.Length;
break;
}
/*
* Buffer is a static allocation,
* only place what will fit in the buffer.
*/
if (Length <= DestDesc->Buffer.Length)
{
/*
* Zero fill first, not willing to do pointer arithmetic for
* archetecture independence. Just clear the whole thing
*/
MEMSET(DestDesc->Buffer.Pointer, 0, DestDesc->Buffer.Length);
MEMCPY(DestDesc->Buffer.Pointer, Buffer, Length);
}
else
{
/*
* truncate, copy only what will fit
*/
MEMCPY(DestDesc->Buffer.Pointer, Buffer, DestDesc->Buffer.Length);
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNte: Truncating src buffer from %d to %d\n",
Length, DestDesc->Buffer.Length));
}
break;
case INTERNAL_TYPE_INDEX_FIELD:
/*
* Get the global lock if needed
*/
Locked = AcpiAmlAcquireGlobalLock (DestDesc->IndexField.LockRule);
/*
* Set Index value to select proper Data register
* perform the update (Set index)
*/
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
DestDesc->IndexField.Index,
&DestDesc->IndexField.Value,
sizeof (DestDesc->IndexField.Value));
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNte: IndexField: set index returned %s\n",
AcpiCmFormatException (Status)));
if (ACPI_SUCCESS (Status))
{
/* set index successful, next set Data value */
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
DestDesc->IndexField.Data,
&ValDesc->Number.Value,
sizeof (ValDesc->Number.Value));
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNte: IndexField: set data returned %s\n",
AcpiCmFormatException (Status)));
}
break;
case ACPI_TYPE_FIELD_UNIT:
/*
* If the Field Buffer and Index have not been previously evaluated,
* evaluate them and save the results.
*/
if (!(DestDesc->Common.Flags & AOPOBJ_DATA_VALID))
{
Status = AcpiDsGetFieldUnitArguments (DestDesc);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
}
if ((!DestDesc->FieldUnit.Container ||
ACPI_TYPE_BUFFER != DestDesc->FieldUnit.Container->Common.Type))
{
DUMP_PATHNAME (Node,
"AmlStoreObjectToNte: FieldUnit: Bad container in ",
ACPI_ERROR, _COMPONENT);
DUMP_ENTRY (Node, ACPI_ERROR);
DEBUG_PRINT (ACPI_ERROR,
("Container: %p", DestDesc->FieldUnit.Container));
if (DestDesc->FieldUnit.Container)
{
DEBUG_PRINT_RAW (ACPI_ERROR, (" Type %d",
DestDesc->FieldUnit.Container->Common.Type));
}
DEBUG_PRINT_RAW (ACPI_ERROR, ("\n"));
Status = AE_AML_INTERNAL;
goto CleanUpAndBailOut;
}
/*
* Get the global lock if needed
*/
Locked = AcpiAmlAcquireGlobalLock (DestDesc->FieldUnit.LockRule);
/*
* TBD: [Unhandled] REMOVE this limitation
* Make sure the operation is within the limits of our implementation
* this is not a Spec limitation!!
*/
if (DestDesc->FieldUnit.Length + DestDesc->FieldUnit.BitOffset > 32)
{
DEBUG_PRINT (ACPI_ERROR,
("AmlStoreObjectToNte: FieldUnit: Implementation limitation - Field exceeds UINT32\n"));
Status = AE_NOT_IMPLEMENTED;
goto CleanUpAndBailOut;
}
/* Field location is (base of buffer) + (byte offset) */
Location = DestDesc->FieldUnit.Container->Buffer.Pointer
+ DestDesc->FieldUnit.Offset;
/*
* Construct Mask with 1 bits where the field is,
* 0 bits elsewhere
*/
Mask = ((UINT32) 1 << DestDesc->FieldUnit.Length) - ((UINT32)1
<< DestDesc->FieldUnit.BitOffset);
DEBUG_PRINT (TRACE_EXEC,
("** Store %lx in buffer %p byte %ld bit %d width %d addr %p mask %08lx\n",
ValDesc->Number.Value,
DestDesc->FieldUnit.Container->Buffer.Pointer,
DestDesc->FieldUnit.Offset, DestDesc->FieldUnit.BitOffset,
DestDesc->FieldUnit.Length,Location, Mask));
/* Zero out the field in the buffer */
MOVE_UNALIGNED32_TO_32 (&NewValue, Location);
NewValue &= ~Mask;
/*
* Shift and mask the new value into position,
* and or it into the buffer.
*/
NewValue |= (ValDesc->Number.Value << DestDesc->FieldUnit.BitOffset) &
Mask;
/* Store back the value */
MOVE_UNALIGNED32_TO_32 (Location, &NewValue);
DEBUG_PRINT (TRACE_EXEC, ("New Field value %08lx\n", NewValue));
break;
case ACPI_TYPE_NUMBER:
DestDesc->Number.Value = ValDesc->Number.Value;
/* Truncate value if we are executing from a 32-bit ACPI table */
AcpiAmlTruncateFor32bitTable (DestDesc, WalkState);
break;
case ACPI_TYPE_PACKAGE:
/*
* TBD: [Unhandled] Not real sure what to do here
*/
Status = AE_NOT_IMPLEMENTED;
break;
default:
/*
* All other types than Alias and the various Fields come here.
* Store ValDesc as the new value of the Name, and set
* the Name's type to that of the value being stored in it.
* ValDesc reference count is incremented by AttachObject.
*/
DEBUG_PRINT (ACPI_WARN,
("AmlStoreObjectToNte: Store into %s not implemented\n",
AcpiCmGetTypeName (AcpiNsGetType (Node))));
Status = AE_NOT_IMPLEMENTED;
break;
}
CleanUpAndBailOut:
/*
* Release global lock if we acquired it earlier
*/
AcpiAmlReleaseGlobalLock (Locked);
return_ACPI_STATUS (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiAmlStoreObject
*
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlStoreObject (
ACPI_OPERAND_OBJECT *SourceDesc,
OBJECT_TYPE_INTERNAL TargetType,
ACPI_OPERAND_OBJECT **TargetDescPtr,
ACPI_WALK_STATE *WalkState)
{
ACPI_OPERAND_OBJECT *TargetDesc = *TargetDescPtr;
ACPI_STATUS Status;
FUNCTION_TRACE ("AmlStoreObject");
/*
* Perform the "implicit conversion" of the source to the current type
* of the target - As per the ACPI specification.
*
* If no conversion performed, SourceDesc is left alone, otherwise it
* is updated with a new object.
*/
Status = AcpiAmlConvertToTargetType (TargetType, &SourceDesc, WalkState);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/*
* We now have two objects of identical types, and we can perform a
* copy of the *value* of the source object.
*/
switch (TargetType)
{
case ACPI_TYPE_ANY:
case INTERNAL_TYPE_DEF_ANY:
/*
* The target namespace node is uninitialized (has no target object),
* and will take on the type of the source object
*/
*TargetDescPtr = SourceDesc;
break;
case ACPI_TYPE_INTEGER:
TargetDesc->Integer.Value = SourceDesc->Integer.Value;
/* Truncate value if we are executing from a 32-bit ACPI table */
AcpiAmlTruncateFor32bitTable (TargetDesc, WalkState);
break;
case ACPI_TYPE_FIELD_UNIT:
Status = AcpiAmlCopyIntegerToFieldUnit (SourceDesc, TargetDesc, WalkState);
break;
case INTERNAL_TYPE_BANK_FIELD:
Status = AcpiAmlCopyIntegerToBankField (SourceDesc, TargetDesc);
break;
case INTERNAL_TYPE_INDEX_FIELD:
Status = AcpiAmlCopyIntegerToIndexField (SourceDesc, TargetDesc);
break;
case ACPI_TYPE_STRING:
Status = AcpiAmlCopyStringToString (SourceDesc, TargetDesc);
break;
case ACPI_TYPE_BUFFER:
Status = AcpiAmlCopyBufferToBuffer (SourceDesc, TargetDesc);
break;
case ACPI_TYPE_PACKAGE:
/*
* TBD: [Unhandled] Not real sure what to do here
*/
Status = AE_NOT_IMPLEMENTED;
break;
default:
/*
* All other types than Alias and the various Fields come here.
* Store SourceDesc 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.
*/
DEBUG_PRINT (ACPI_WARN,
("AmlStoreObject: Store into type %s not implemented\n",
AcpiCmGetTypeName (TargetType)));
Status = AE_NOT_IMPLEMENTED;
break;
}
return_ACPI_STATUS (Status);
}

View File

@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: amstorob - AML Interpreter object store support, store to object
* $Revision: 1.17 $
* $Revision: 1.21 $
*
*****************************************************************************/
@ -10,8 +10,8 @@
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999, Intel Corp. All rights
* reserved.
* Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
* All rights reserved.
*
* 2. License
*
@ -130,317 +130,446 @@
MODULE_NAME ("amstorob")
/*******************************************************************************
*
* FUNCTION: AcpiAmlStoreObjectToObject
* FUNCTION: AcpiAmlCopyBufferToBuffer
*
* PARAMETERS: *ValDesc - Value to be stored
* *DestDesc - Object to receive the value
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION: Store an object to another object.
*
* The Assignment of an object to another (not named) object
* is handled here.
* The val passed in will replace the current value (if any)
* with the input value.
*
* When storing into an object the data is converted to the
* target object type then stored in the object. This means
* that the target object type (for an initialized target) will
* not be changed by a store operation.
*
* This module allows destination types of Number, String,
* and Buffer.
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlStoreObjectToObject (
ACPI_OPERAND_OBJECT *ValDesc,
ACPI_OPERAND_OBJECT *DestDesc,
AcpiAmlCopyBufferToBuffer (
ACPI_OPERAND_OBJECT *SourceDesc,
ACPI_OPERAND_OBJECT *TargetDesc)
{
UINT32 Length;
UINT8 *Buffer;
/*
* We know that SourceDesc is a buffer by now
*/
Buffer = (UINT8 *) SourceDesc->Buffer.Pointer;
Length = SourceDesc->Buffer.Length;
/*
* Buffer is a static allocation,
* only place what will fit in the buffer.
*/
if (Length <= TargetDesc->Buffer.Length)
{
/* Clear existing buffer and copy in the new one */
MEMSET(TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
MEMCPY(TargetDesc->Buffer.Pointer, Buffer, Length);
}
else
{
/*
* Truncate the source, copy only what will fit
*/
MEMCPY(TargetDesc->Buffer.Pointer, Buffer, TargetDesc->Buffer.Length);
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNode: Truncating src buffer from %X to %X\n",
Length, TargetDesc->Buffer.Length));
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: AcpiAmlCopyStringToString
*
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlCopyStringToString (
ACPI_OPERAND_OBJECT *SourceDesc,
ACPI_OPERAND_OBJECT *TargetDesc)
{
UINT32 Length;
UINT8 *Buffer;
/*
* We know that SourceDesc is a string by now.
*/
Buffer = (UINT8 *) SourceDesc->String.Pointer;
Length = SourceDesc->String.Length;
/*
* Setting a string value replaces the old string
*/
if (Length < TargetDesc->String.Length)
{
/* Clear old string and copy in the new one */
MEMSET(TargetDesc->String.Pointer, 0, TargetDesc->String.Length);
MEMCPY(TargetDesc->String.Pointer, Buffer, Length);
}
else
{
/*
* Free the current buffer, then allocate a buffer
* large enough to hold the value
*/
if (TargetDesc->String.Pointer &&
!AcpiTbSystemTablePointer (TargetDesc->String.Pointer))
{
/*
* Only free if not a pointer into the DSDT
*/
AcpiCmFree(TargetDesc->String.Pointer);
}
TargetDesc->String.Pointer = AcpiCmAllocate (Length + 1);
TargetDesc->String.Length = Length;
if (!TargetDesc->String.Pointer)
{
return (AE_NO_MEMORY);
}
MEMCPY(TargetDesc->String.Pointer, Buffer, Length);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: AcpiAmlCopyIntegerToIndexField
*
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlCopyIntegerToIndexField (
ACPI_OPERAND_OBJECT *SourceDesc,
ACPI_OPERAND_OBJECT *TargetDesc)
{
ACPI_STATUS Status;
BOOLEAN Locked;
/*
* Get the global lock if needed
*/
Locked = AcpiAmlAcquireGlobalLock (TargetDesc->IndexField.LockRule);
/*
* Set Index value to select proper Data register
* perform the update (Set index)
*/
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
TargetDesc->IndexField.Index,
&TargetDesc->IndexField.Value,
sizeof (TargetDesc->IndexField.Value));
if (ACPI_SUCCESS (Status))
{
/* SetIndex was successful, next set Data value */
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
TargetDesc->IndexField.Data,
&SourceDesc->Integer.Value,
sizeof (SourceDesc->Integer.Value));
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNode: IndexField: set data returned %s\n",
AcpiCmFormatException (Status)));
}
else
{
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNode: IndexField: set index returned %s\n",
AcpiCmFormatException (Status)));
}
/*
* Release global lock if we acquired it earlier
*/
AcpiAmlReleaseGlobalLock (Locked);
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiAmlCopyIntegerToBankField
*
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlCopyIntegerToBankField (
ACPI_OPERAND_OBJECT *SourceDesc,
ACPI_OPERAND_OBJECT *TargetDesc)
{
ACPI_STATUS Status;
BOOLEAN Locked;
/*
* Get the global lock if needed
*/
Locked = AcpiAmlAcquireGlobalLock (TargetDesc->IndexField.LockRule);
/*
* Set Bank value to select proper Bank
* Perform the update (Set Bank Select)
*/
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
TargetDesc->BankField.BankSelect,
&TargetDesc->BankField.Value,
sizeof (TargetDesc->BankField.Value));
if (ACPI_SUCCESS (Status))
{
/* Set bank select successful, set data value */
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
TargetDesc->BankField.BankSelect,
&SourceDesc->BankField.Value,
sizeof (SourceDesc->BankField.Value));
}
else
{
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToNode: BankField: set bakn returned %s\n",
AcpiCmFormatException (Status)));
}
/*
* Release global lock if we acquired it earlier
*/
AcpiAmlReleaseGlobalLock (Locked);
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiAmlCopyDataToNamedField
*
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlCopyDataToNamedField (
ACPI_OPERAND_OBJECT *SourceDesc,
ACPI_NAMESPACE_NODE *Node)
{
ACPI_STATUS Status;
BOOLEAN Locked;
UINT32 Length;
UINT8 *Buffer;
/*
* Named fields (CreateXxxField) - We don't perform any conversions on the
* source operand, just use the raw data
*/
switch (SourceDesc->Common.Type)
{
case ACPI_TYPE_INTEGER:
Buffer = (UINT8 *) &SourceDesc->Integer.Value;
Length = sizeof (SourceDesc->Integer.Value);
break;
case ACPI_TYPE_BUFFER:
Buffer = (UINT8 *) SourceDesc->Buffer.Pointer;
Length = SourceDesc->Buffer.Length;
break;
case ACPI_TYPE_STRING:
Buffer = (UINT8 *) SourceDesc->String.Pointer;
Length = SourceDesc->String.Length;
break;
default:
return (AE_TYPE);
}
/*
* Get the global lock if needed before the update
* TBD: not needed!
*/
Locked = AcpiAmlAcquireGlobalLock (SourceDesc->Field.LockRule);
Status = AcpiAmlAccessNamedField (ACPI_WRITE,
Node, Buffer, Length);
AcpiAmlReleaseGlobalLock (Locked);
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiAmlCopyIntegerToFieldUnit
*
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION:
*
******************************************************************************/
ACPI_STATUS
AcpiAmlCopyIntegerToFieldUnit (
ACPI_OPERAND_OBJECT *SourceDesc,
ACPI_OPERAND_OBJECT *TargetDesc,
ACPI_WALK_STATE *WalkState)
{
ACPI_STATUS Status = AE_OK;
UINT8 *Buffer = NULL;
UINT32 Length = 0;
OBJECT_TYPE_INTERNAL DestinationType = DestDesc->Common.Type;
UINT8 *Location = NULL;
UINT32 Mask;
UINT32 NewValue;
BOOLEAN Locked = FALSE;
FUNCTION_TRACE ("AmlStoreObjectToObject");
DEBUG_PRINT (ACPI_INFO,
("entered AcpiAmlStoreObjectToObject: Dest=%p, Val=%p\n",
DestDesc, ValDesc));
FUNCTION_TRACE ("AmlCopyIntegerToFieldUnit");
/*
* Assuming the parameters are valid!!!
* If the Field Buffer and Index have not been previously evaluated,
* evaluate them and save the results.
*/
ACPI_ASSERT((DestDesc) && (ValDesc));
DEBUG_PRINT (ACPI_INFO, ("AmlStoreObjectToObject: Storing %s into %s\n",
AcpiCmGetTypeName (ValDesc->Common.Type),
AcpiCmGetTypeName (DestDesc->Common.Type)));
/*
* First ensure we have a value that can be stored in the target
*/
switch (DestinationType)
if (!(TargetDesc->Common.Flags & AOPOBJ_DATA_VALID))
{
/* Type of Name's existing value */
case ACPI_TYPE_NUMBER:
/*
* These cases all require only number values or values that
* can be converted to numbers.
*
* If value is not a Number, try to resolve it to one.
*/
if (ValDesc->Common.Type != ACPI_TYPE_NUMBER)
Status = AcpiDsGetFieldUnitArguments (TargetDesc);
if (ACPI_FAILURE (Status))
{
/*
* Initially not a number, convert
*/
Status = AcpiAmlResolveToValue (&ValDesc, WalkState);
if (ACPI_SUCCESS (Status) &&
(ValDesc->Common.Type != ACPI_TYPE_NUMBER))
{
/*
* Conversion successful but still not a number
*/
DEBUG_PRINT (ACPI_ERROR,
("AmlStoreObjectToObject: Value assigned to %s must be Number, not %s\n",
AcpiCmGetTypeName (DestinationType),
AcpiCmGetTypeName (ValDesc->Common.Type)));
Status = AE_AML_OPERAND_TYPE;
}
return_ACPI_STATUS (Status);
}
break;
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
/*
* Storing into a Field in a region or into a buffer or into
* a string all is essentially the same.
*
* If value is not a valid type, try to resolve it to one.
*/
if ((ValDesc->Common.Type != ACPI_TYPE_NUMBER) &&
(ValDesc->Common.Type != ACPI_TYPE_BUFFER) &&
(ValDesc->Common.Type != ACPI_TYPE_STRING))
{
/*
* Initially not a valid type, convert
*/
Status = AcpiAmlResolveToValue (&ValDesc, WalkState);
if (ACPI_SUCCESS (Status) &&
(ValDesc->Common.Type != ACPI_TYPE_NUMBER) &&
(ValDesc->Common.Type != ACPI_TYPE_BUFFER) &&
(ValDesc->Common.Type != ACPI_TYPE_STRING))
{
/*
* Conversion successful but still not a valid type
*/
DEBUG_PRINT (ACPI_ERROR,
("AmlStoreObjectToObject: Assign wrong type %s to %s (must be type Num/Str/Buf)\n",
AcpiCmGetTypeName (ValDesc->Common.Type),
AcpiCmGetTypeName (DestinationType)));
Status = AE_AML_OPERAND_TYPE;
}
}
break;
default:
/*
* TBD: [Unhandled] What other combinations must be implemented?
*/
Status = AE_NOT_IMPLEMENTED;
break;
}
/* Exit now if failure above */
if (ACPI_FAILURE (Status))
if ((!TargetDesc->FieldUnit.Container ||
ACPI_TYPE_BUFFER != TargetDesc->FieldUnit.Container->Common.Type))
{
goto CleanUpAndBailOut;
DEBUG_PRINT (ACPI_ERROR,
("Null Container or wrong type: %p", TargetDesc->FieldUnit.Container));
if (TargetDesc->FieldUnit.Container)
{
DEBUG_PRINT_RAW (ACPI_ERROR, (" Type %X",
TargetDesc->FieldUnit.Container->Common.Type));
}
DEBUG_PRINT_RAW (ACPI_ERROR, ("\n"));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/*
* AcpiEverything is ready to execute now, We have
* a value we can handle, just perform the update
* Get the global lock if needed
*/
Locked = AcpiAmlAcquireGlobalLock (TargetDesc->FieldUnit.LockRule);
switch (DestinationType)
/*
* TBD: [Unhandled] REMOVE this limitation
* Make sure the operation is within the limits of our implementation
* this is not a Spec limitation!!
*/
if (TargetDesc->FieldUnit.Length + TargetDesc->FieldUnit.BitOffset > 32)
{
case ACPI_TYPE_STRING:
/*
* Perform the update
*/
switch (ValDesc->Common.Type)
{
case ACPI_TYPE_NUMBER:
Buffer = (UINT8 *) &ValDesc->Number.Value;
Length = sizeof (ValDesc->Number.Value);
break;
case ACPI_TYPE_BUFFER:
Buffer = (UINT8 *) ValDesc->Buffer.Pointer;
Length = ValDesc->Buffer.Length;
break;
case ACPI_TYPE_STRING:
Buffer = (UINT8 *) ValDesc->String.Pointer;
Length = ValDesc->String.Length;
break;
}
/*
* Setting a string value replaces the old string
*/
if (Length < DestDesc->String.Length)
{
/*
* Zero fill, not willing to do pointer arithmetic for
* architecture independence. Just clear the whole thing
*/
MEMSET(DestDesc->String.Pointer, 0, DestDesc->String.Length);
MEMCPY(DestDesc->String.Pointer, Buffer, Length);
}
else
{
/*
* Free the current buffer, then allocate a buffer
* large enough to hold the value
*/
if ( DestDesc->String.Pointer &&
!AcpiTbSystemTablePointer (DestDesc->String.Pointer))
{
/*
* Only free if not a pointer into the DSDT
*/
AcpiCmFree(DestDesc->String.Pointer);
}
DestDesc->String.Pointer = AcpiCmAllocate (Length + 1);
DestDesc->String.Length = Length;
if (!DestDesc->String.Pointer)
{
Status = AE_NO_MEMORY;
goto CleanUpAndBailOut;
}
MEMCPY(DestDesc->String.Pointer, Buffer, Length);
}
break;
case ACPI_TYPE_BUFFER:
/*
* Perform the update to the buffer
*/
switch (ValDesc->Common.Type)
{
case ACPI_TYPE_NUMBER:
Buffer = (UINT8 *) &ValDesc->Number.Value;
Length = sizeof (ValDesc->Number.Value);
break;
case ACPI_TYPE_BUFFER:
Buffer = (UINT8 *) ValDesc->Buffer.Pointer;
Length = ValDesc->Buffer.Length;
break;
case ACPI_TYPE_STRING:
Buffer = (UINT8 *) ValDesc->String.Pointer;
Length = ValDesc->String.Length;
break;
}
/*
* If the buffer is uninitialized,
* memory needs to be allocated for the copy.
*/
if(0 == DestDesc->Buffer.Length)
{
DestDesc->Buffer.Pointer = AcpiCmCallocate(Length);
DestDesc->Buffer.Length = Length;
if (!DestDesc->Buffer.Pointer)
{
Status = AE_NO_MEMORY;
goto CleanUpAndBailOut;
}
}
/*
* Buffer is a static allocation,
* only place what will fit in the buffer.
*/
if (Length <= DestDesc->Buffer.Length)
{
/*
* Zero fill first, not willing to do pointer arithmetic for
* architecture independence. Just clear the whole thing
*/
MEMSET(DestDesc->Buffer.Pointer, 0, DestDesc->Buffer.Length);
MEMCPY(DestDesc->Buffer.Pointer, Buffer, Length);
}
else
{
/*
* truncate, copy only what will fit
*/
MEMCPY(DestDesc->Buffer.Pointer, Buffer, DestDesc->Buffer.Length);
DEBUG_PRINT (ACPI_INFO,
("AmlStoreObjectToObject: Truncating src buffer from %d to %d\n",
Length, DestDesc->Buffer.Length));
}
break;
case ACPI_TYPE_NUMBER:
DestDesc->Number.Value = ValDesc->Number.Value;
/* Truncate value if we are executing from a 32-bit ACPI table */
AcpiAmlTruncateFor32bitTable (DestDesc, WalkState);
break;
default:
/*
* All other types than Alias and the various Fields come here.
* Store ValDesc as the new value of the Name, and set
* the Name's type to that of the value being stored in it.
* ValDesc reference count is incremented by AttachObject.
*/
DEBUG_PRINT (ACPI_WARN,
("AmlStoreObjectToObject: Store into %s not implemented\n",
AcpiCmGetTypeName (DestDesc->Common.Type)));
Status = AE_NOT_IMPLEMENTED;
break;
DEBUG_PRINT (ACPI_ERROR,
("AmlCopyIntegerToFieldUnit: FieldUnit: Implementation limitation - Field exceeds UINT32\n"));
return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
}
CleanUpAndBailOut:
/* Field location is (base of buffer) + (byte offset) */
return_ACPI_STATUS (Status);
Location = TargetDesc->FieldUnit.Container->Buffer.Pointer
+ TargetDesc->FieldUnit.Offset;
/*
* Construct Mask with 1 bits where the field is,
* 0 bits elsewhere
*/
Mask = ((UINT32) 1 << TargetDesc->FieldUnit.Length) - ((UINT32)1
<< TargetDesc->FieldUnit.BitOffset);
DEBUG_PRINT (TRACE_EXEC,
("** Store %lx in buffer %p byte %ld bit %X width %d addr %p mask %08lx\n",
SourceDesc->Integer.Value,
TargetDesc->FieldUnit.Container->Buffer.Pointer,
TargetDesc->FieldUnit.Offset, TargetDesc->FieldUnit.BitOffset,
TargetDesc->FieldUnit.Length,Location, Mask));
/* Zero out the field in the buffer */
MOVE_UNALIGNED32_TO_32 (&NewValue, Location);
NewValue &= ~Mask;
/*
* Shift and mask the new value into position,
* and or it into the buffer.
*/
NewValue |= (SourceDesc->Integer.Value << TargetDesc->FieldUnit.BitOffset) &
Mask;
/* Store back the value */
MOVE_UNALIGNED32_TO_32 (Location, &NewValue);
DEBUG_PRINT (TRACE_EXEC, ("New Field value %08lx\n", NewValue));
return_ACPI_STATUS (AE_OK);
}