diff options
Diffstat (limited to 'sys/contrib/dev/acpica/exstore.c')
-rw-r--r-- | sys/contrib/dev/acpica/exstore.c | 542 |
1 files changed, 388 insertions, 154 deletions
diff --git a/sys/contrib/dev/acpica/exstore.c b/sys/contrib/dev/acpica/exstore.c index 51f1bb6..71d1dfb 100644 --- a/sys/contrib/dev/acpica/exstore.c +++ b/sys/contrib/dev/acpica/exstore.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amstore - AML Interpreter object store support - * $Revision: 118 $ + * $Revision: 121 $ * *****************************************************************************/ @@ -10,7 +10,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999, 2000, Intel Corp. + * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. * All rights reserved. * * 2. License @@ -130,6 +130,10 @@ MODULE_NAME ("amstore") + + + + /******************************************************************************* * * FUNCTION: AcpiAmlExecStore @@ -156,18 +160,10 @@ AcpiAmlExecStore ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; - ACPI_OPERAND_OBJECT *DeleteDestDesc = NULL; - ACPI_OPERAND_OBJECT *TmpDesc; - ACPI_NAMESPACE_NODE *Node = NULL; - UINT8 Value = 0; - UINT32 Length; - UINT32 i; - + ACPI_OPERAND_OBJECT *RefDesc = DestDesc; - FUNCTION_TRACE ("AmlExecStore"); - DEBUG_PRINT (ACPI_INFO, ("entered AcpiAmlExecStore: Val=%p, Dest=%p\n", - ValDesc, DestDesc)); + FUNCTION_TRACE_PTR ("AmlExecStore", DestDesc); /* Validate parameters */ @@ -179,80 +175,185 @@ AcpiAmlExecStore ( return_ACPI_STATUS (AE_AML_NO_OPERAND); } - /* Examine the datatype of the DestDesc */ + /* DestDesc can be either a namespace node or an ACPI object */ if (VALID_DESCRIPTOR_TYPE (DestDesc, ACPI_DESC_TYPE_NAMED)) { - /* Dest is an ACPI_HANDLE, create a new object */ - - Node = (ACPI_NAMESPACE_NODE *) DestDesc; - DestDesc = AcpiCmCreateInternalObject (INTERNAL_TYPE_REFERENCE); - if (!DestDesc) - { - /* Allocation failure */ - - return_ACPI_STATUS (AE_NO_MEMORY); - } + /* + * Dest is a namespace node, + * Storing an object into a Name "container" + */ + Status = AcpiAmlStoreObjectToNode (ValDesc, + (ACPI_NAMESPACE_NODE *) DestDesc, WalkState); - /* Build a new Reference wrapper around the handle */ + /* All done, that's it */ - DestDesc->Reference.OpCode = AML_NAME_OP; - DestDesc->Reference.Object = Node; + return_ACPI_STATUS (Status); } - else - { - DEBUG_PRINT (ACPI_INFO, - ("AmlExecStore: Dest is object (not handle) - may be deleted!\n")); - } - /* Destination object must be of type Reference */ + /* Destination object must be an object of type Reference */ if (DestDesc->Common.Type != INTERNAL_TYPE_REFERENCE) { /* Destination is not an Reference */ DEBUG_PRINT (ACPI_ERROR, - ("AmlExecStore: Destination is not an Reference [%p]\n", DestDesc)); + ("AmlExecStore: Destination is not a ReferenceObj [%p]\n", DestDesc)); DUMP_STACK_ENTRY (ValDesc); DUMP_STACK_ENTRY (DestDesc); DUMP_OPERANDS (&DestDesc, IMODE_EXECUTE, "AmlExecStore", - 2, "target not Reference"); + 2, "Target is not a ReferenceObj"); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* Examine the Reference opcode */ - switch (DestDesc->Reference.OpCode) + /* + * Examine the Reference opcode. These cases are handled: + * + * 1) Store to Name (Change the object associated with a name) + * 2) Store to an indexed area of a Buffer or Package + * 3) Store to a Method Local or Arg + * 4) Store to the debug object + * 5) Store to a constant -- a noop + */ + + switch (RefDesc->Reference.OpCode) { case AML_NAME_OP: - /* - * Storing into a Name - */ - DeleteDestDesc = DestDesc; - Status = AcpiAmlStoreObjectToNode (ValDesc, DestDesc->Reference.Object, - WalkState); + /* Storing an object into a Name "container" */ - break; /* Case NameOp */ + Status = AcpiAmlStoreObjectToNode (ValDesc, RefDesc->Reference.Object, + WalkState); + break; case AML_INDEX_OP: - DeleteDestDesc = DestDesc; + /* Storing to an Index (pointer into a packager or buffer) */ + + Status = AcpiAmlStoreObjectToIndex (ValDesc, RefDesc, WalkState); + break; + + + case AML_LOCAL_OP: + + Status = AcpiDsMethodDataSetValue (MTH_TYPE_LOCAL, + (RefDesc->Reference.Offset), ValDesc, WalkState); + break; + + + case AML_ARG_OP: + + Status = AcpiDsMethodDataSetValue (MTH_TYPE_ARG, + (RefDesc->Reference.Offset), ValDesc, WalkState); + break; + + + case AML_DEBUG_OP: /* - * Valid source value and destination reference pointer. + * Storing to the Debug object causes the value stored to be + * displayed and otherwise has no effect -- see ACPI Specification * - * ACPI Specification 1.0B section 15.2.3.4.2.13: - * Destination should point to either a buffer or a package + * TBD: print known object types "prettier". */ + DEBUG_PRINT (ACPI_INFO, ("**** Write to Debug Object: ****: \n")); + + if (ValDesc->Common.Type == ACPI_TYPE_STRING) + { + DEBUG_PRINT (ACPI_INFO, ("%s\n", ValDesc->String.Pointer)); + } + else + { + DUMP_STACK_ENTRY (ValDesc); + } + + break; + + + case AML_ZERO_OP: + case AML_ONE_OP: + case AML_ONES_OP: /* - * Actually, storing to a package is not so simple. The source must be + * Storing to a constant is a no-op -- see ACPI Specification + * Delete the reference descriptor, however + */ + break; + + + default: + + DEBUG_PRINT (ACPI_ERROR, + ("AmlExecStore: Internal error - Unknown Reference subtype %02x\n", + RefDesc->Reference.OpCode)); + + /* TBD: [Restructure] use object dump routine !! */ + + DUMP_BUFFER (RefDesc, sizeof (ACPI_OPERAND_OBJECT)); + + Status = AE_AML_INTERNAL; + break; + + } /* switch (RefDesc->Reference.OpCode) */ + + + + /* Always delete the reference descriptor object */ + + if (RefDesc) + { + AcpiCmRemoveReference (RefDesc); + } + + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiAmlStoreObjectToIndex + * + * PARAMETERS: *ValDesc - Value to be stored + * *Node - Named object to recieve the value + * + * RETURN: Status + * + * DESCRIPTION: Store the object to the named object. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiAmlStoreObjectToIndex ( + ACPI_OPERAND_OBJECT *ValDesc, + ACPI_OPERAND_OBJECT *DestDesc, + ACPI_WALK_STATE *WalkState) +{ + ACPI_STATUS Status = AE_OK; + ACPI_OPERAND_OBJECT *ObjDesc; + UINT32 Length; + UINT32 i; + UINT8 Value = 0; + + + FUNCTION_TRACE ("AcpiAmlStoreObjectToIndex"); + + + /* + * Destination must be a reference pointer, and + * must point to either a buffer or a package + */ + + switch (DestDesc->Reference.TargetType) + { + case ACPI_TYPE_PACKAGE: + /* + * Storing to a package element is not simple. The source must be * evaluated and converted to the type of the destination and then the * source is copied into the destination - we can't just point to the * source object. @@ -263,8 +364,8 @@ AcpiAmlExecStore ( * The object at *(DestDesc->Reference.Where) is the * element within the package that is to be modified. */ - TmpDesc = *(DestDesc->Reference.Where); - if (TmpDesc) + ObjDesc = *(DestDesc->Reference.Where); + if (ObjDesc) { /* * If the Destination element is a package, we will delete @@ -274,46 +375,44 @@ AcpiAmlExecStore ( * to be packages? * && (ValDesc->Common.Type == ACPI_TYPE_PACKAGE) */ - if (TmpDesc->Common.Type == ACPI_TYPE_PACKAGE) + if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) { /* * Take away the reference for being part of a package and * delete */ - AcpiCmRemoveReference (TmpDesc); - AcpiCmRemoveReference (TmpDesc); + AcpiCmRemoveReference (ObjDesc); + AcpiCmRemoveReference (ObjDesc); - TmpDesc = NULL; + ObjDesc = NULL; } } - if (!TmpDesc) + if (!ObjDesc) { /* - * If the TmpDesc is NULL, that means an uninitialized package - * has been used as a destination, therefore, we must create - * the destination element to match the type of the source - * element NOTE: ValDesc can be of any type. + * If the ObjDesc is NULL, it means that an uninitialized package + * element has been used as a destination (this is OK), therefore, + * we must create the destination element to match the type of the + * source element NOTE: ValDesc can be of any type. */ - TmpDesc = AcpiCmCreateInternalObject (ValDesc->Common.Type); - if (!TmpDesc) + ObjDesc = AcpiCmCreateInternalObject (ValDesc->Common.Type); + if (!ObjDesc) { - Status = AE_NO_MEMORY; - goto Cleanup; + return_ACPI_STATUS (AE_NO_MEMORY); } /* * If the source is a package, copy the source to the new dest */ - if (ACPI_TYPE_PACKAGE == TmpDesc->Common.Type) + if (ACPI_TYPE_PACKAGE == ObjDesc->Common.Type) { Status = AcpiAmlBuildCopyInternalPackageObject ( - ValDesc, TmpDesc, WalkState); + ValDesc, ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { - AcpiCmRemoveReference (TmpDesc); - TmpDesc = NULL; - goto Cleanup; + AcpiCmRemoveReference (ObjDesc); + return_ACPI_STATUS (Status); } } @@ -323,18 +422,18 @@ AcpiAmlExecStore ( * part of the parent package */ - *(DestDesc->Reference.Where) = TmpDesc; - AcpiCmAddReference (TmpDesc); + *(DestDesc->Reference.Where) = ObjDesc; + AcpiCmAddReference (ObjDesc); } - if (ACPI_TYPE_PACKAGE != TmpDesc->Common.Type) + if (ACPI_TYPE_PACKAGE != ObjDesc->Common.Type) { /* * The destination element is not a package, so we need to * convert the contents of the source (ValDesc) and copy into - * the destination (TmpDesc) + * the destination (ObjDesc) */ - Status = AcpiAmlStoreObjectToObject (ValDesc, TmpDesc, + Status = AcpiAmlStoreObjectToObject (ValDesc, ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { @@ -344,22 +443,14 @@ AcpiAmlExecStore ( */ DEBUG_PRINT (ACPI_ERROR, ("AmlExecStore/Index: Unable to copy the internal object\n")); - Status = AE_AML_OPERAND_TYPE; + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } } - - break; } + break; - /* - * Check that the destination is a Buffer Field type - */ - if (DestDesc->Reference.TargetType != ACPI_TYPE_BUFFER_FIELD) - { - Status = AE_AML_OPERAND_TYPE; - break; - } + case ACPI_TYPE_BUFFER_FIELD: /* * Storing into a buffer at a location defined by an Index. * @@ -368,14 +459,12 @@ AcpiAmlExecStore ( */ /* - * Set the TmpDesc to the destination object and type check. + * Set the ObjDesc to the destination object and type check. */ - TmpDesc = DestDesc->Reference.Object; - - if (TmpDesc->Common.Type != ACPI_TYPE_BUFFER) + ObjDesc = DestDesc->Reference.Object; + if (ObjDesc->Common.Type != ACPI_TYPE_BUFFER) { - Status = AE_AML_OPERAND_TYPE; - break; + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* @@ -386,16 +475,16 @@ AcpiAmlExecStore ( switch (ValDesc->Common.Type) { /* - * If the type is Integer, the Length is 4. + * If the type is Integer, assign bytewise * This loop to assign each of the elements is somewhat - * backward because of the Big Endian-ness of IA-64 + * backward because of the Big Endian-ness of IA-64 */ - case ACPI_TYPE_NUMBER: - Length = 4; + case ACPI_TYPE_INTEGER: + Length = sizeof (ACPI_INTEGER); for (i = Length; i != 0; i--) { - Value = (UINT8)(ValDesc->Number.Value >> (MUL_8 (i - 1))); - TmpDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; + Value = (UINT8)(ValDesc->Integer.Value >> (MUL_8 (i - 1))); + ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; } break; @@ -408,7 +497,7 @@ AcpiAmlExecStore ( for (i = 0; i < Length; i++) { Value = *(ValDesc->Buffer.Pointer + i); - TmpDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; + ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; } break; @@ -421,7 +510,7 @@ AcpiAmlExecStore ( for (i = 0; i < Length; i++) { Value = *(ValDesc->String.Pointer + i); - TmpDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; + ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; } break; @@ -435,97 +524,242 @@ AcpiAmlExecStore ( Status = AE_AML_OPERAND_TYPE; break; } + break; - /* - * If we had an error, break out of this case statement. - */ - if (ACPI_FAILURE (Status)) - { - break; - } - - /* - * Set the return pointer - */ - DestDesc = TmpDesc; + default: + DEBUG_PRINT (ACPI_ERROR, + ("AmlExecStoreIndex: Target is not a Package or BufferField\n")); + Status = AE_AML_OPERAND_TYPE; break; + } - case AML_ZERO_OP: - case AML_ONE_OP: - case AML_ONES_OP: - /* - * Storing to a constant is a no-op -- see ACPI Specification - * Delete the result descriptor. - */ + return_ACPI_STATUS (Status); +} - DeleteDestDesc = DestDesc; - break; - case AML_LOCAL_OP: - Status = AcpiDsMethodDataSetValue (MTH_TYPE_LOCAL, - (DestDesc->Reference.Offset), ValDesc, WalkState); - DeleteDestDesc = DestDesc; - break; +/******************************************************************************* + * + * FUNCTION: AcpiAmlStoreObjectToNode + * + * PARAMETERS: *SourceDesc - Value to be stored + * *Node - Named object to recieve the value + * + * 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. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiAmlStoreObjectToNode ( + ACPI_OPERAND_OBJECT *SourceDesc, + ACPI_NAMESPACE_NODE *Node, + ACPI_WALK_STATE *WalkState) +{ + ACPI_STATUS Status = AE_OK; + ACPI_OPERAND_OBJECT *TargetDesc; + OBJECT_TYPE_INTERNAL TargetType = ACPI_TYPE_ANY; - case AML_ARG_OP: - Status = AcpiDsMethodDataSetValue (MTH_TYPE_ARG, - (DestDesc->Reference.Offset), ValDesc, WalkState); - DeleteDestDesc = DestDesc; + FUNCTION_TRACE ("AmlStoreObjectToNode"); + + /* + * Assuming the parameters were already validated + */ + ACPI_ASSERT((Node) && (SourceDesc)); + + + /* + * Get current type of the node, and object attached to Node + */ + TargetType = AcpiNsGetType (Node); + TargetDesc = AcpiNsGetAttachedObject (Node); + + DEBUG_PRINT (ACPI_INFO, ("AmlStoreObjectToNode: Storing %p(%s) into node %p(%s)\n", + Node, AcpiCmGetTypeName (SourceDesc->Common.Type), + SourceDesc, AcpiCmGetTypeName (TargetType))); + + + /* + * Resolve the source object to an actual value + * (If it is a reference object) + */ + Status = AcpiAmlResolveObject (&SourceDesc, TargetType, WalkState); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + + /* + * Do the actual store operation + */ + switch (TargetType) + { + case INTERNAL_TYPE_DEF_FIELD: + + /* Raw data copy for target types Integer/String/Buffer */ + + Status = AcpiAmlCopyDataToNamedField (SourceDesc, Node); break; - case AML_DEBUG_OP: + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + case INTERNAL_TYPE_BANK_FIELD: + case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_FIELD_UNIT: - /* - * Storing to the Debug object causes the value stored to be - * displayed and otherwise has no effect -- see ACPI Specification + /* + * 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 */ - DEBUG_PRINT (ACPI_INFO, ("**** Write to Debug Object: ****: \n")); - if (ValDesc->Common.Type == ACPI_TYPE_STRING) - { - DEBUG_PRINT (ACPI_INFO, ("%s\n", ValDesc->String.Pointer)); - } - else + Status = AcpiAmlStoreObject (SourceDesc, TargetType, &TargetDesc, WalkState); + if (ACPI_FAILURE (Status)) { - DUMP_STACK_ENTRY (ValDesc); + return_ACPI_STATUS (Status); } - DeleteDestDesc = DestDesc; + /* + * Store the new TargetDesc 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. + */ + Status = AcpiNsAttachObject (Node, TargetDesc, TargetType); + DEBUG_PRINT (ACPI_INFO, + ("AmlStoreObjectToNode: Store %s into %s via Convert/Attach\n", + AcpiCmGetTypeName (TargetDesc->Common.Type), + AcpiCmGetTypeName (TargetType))); break; - + default: - DEBUG_PRINT (ACPI_ERROR, - ("AmlExecStore: Internal error - Unknown Reference subtype %02x\n", - DestDesc->Reference.OpCode)); + /* No conversions for all other types. Just attach the source object */ - /* TBD: [Restructure] use object dump routine !! */ + Status = AcpiNsAttachObject (Node, SourceDesc, SourceDesc->Common.Type); + + DEBUG_PRINT (ACPI_INFO, + ("AmlStoreObjectToNode: Store %s into %s via Attach only\n", + AcpiCmGetTypeName (SourceDesc->Common.Type), + AcpiCmGetTypeName (SourceDesc->Common.Type))); + break; + } - DUMP_BUFFER (DestDesc, sizeof (ACPI_OPERAND_OBJECT)); - DeleteDestDesc = DestDesc; - Status = AE_AML_INTERNAL; + return_ACPI_STATUS (Status); +} - } /* switch(DestDesc->Reference.OpCode) */ -Cleanup: +/******************************************************************************* + * + * FUNCTION: AcpiAmlStoreObjectToObject + * + * PARAMETERS: *SourceDesc - Value to be stored + * *DestDesc - Object to receive the value + * + * 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. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiAmlStoreObjectToObject ( + ACPI_OPERAND_OBJECT *SourceDesc, + ACPI_OPERAND_OBJECT *DestDesc, + ACPI_WALK_STATE *WalkState) +{ + ACPI_STATUS Status = AE_OK; + OBJECT_TYPE_INTERNAL DestinationType = DestDesc->Common.Type; + + + FUNCTION_TRACE ("AmlStoreObjectToObject"); + + + /* + * Assuming the parameters are valid! + */ + ACPI_ASSERT((DestDesc) && (SourceDesc)); - /* Cleanup and exit*/ + DEBUG_PRINT (ACPI_INFO, ("AmlStoreObjectToObject: Storing %p(%s) to (%p)%s\n", + SourceDesc, AcpiCmGetTypeName (SourceDesc->Common.Type), + DestDesc, AcpiCmGetTypeName (DestDesc->Common.Type))); - if (DeleteDestDesc) + + /* + * From this interface, we only support Integers/Strings/Buffers + */ + switch (DestinationType) + { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + break; + + default: + DEBUG_PRINT (ACPI_WARN, + ("AmlStoreObjectToObject: Store into %s not implemented\n", + AcpiCmGetTypeName (DestDesc->Common.Type))); + + return_ACPI_STATUS (AE_NOT_IMPLEMENTED); + } + + + + /* + * Resolve the source object to an actual value + * (If it is a reference object) + */ + Status = AcpiAmlResolveObject (&SourceDesc, DestinationType, WalkState); + if (ACPI_FAILURE (Status)) { - AcpiCmRemoveReference (DeleteDestDesc); + return_ACPI_STATUS (Status); } + + /* + * Copy and/or convert the source object to the destination object + */ + Status = AcpiAmlStoreObject (SourceDesc, DestinationType, &DestDesc, WalkState); + + return_ACPI_STATUS (Status); } - |