Example #1
0
static ACPI_STATUS
AcpiDsInitBufferField (
    UINT16                  AmlOpcode,
    ACPI_OPERAND_OBJECT     *ObjDesc,
    ACPI_OPERAND_OBJECT     *BufferDesc,
    ACPI_OPERAND_OBJECT     *OffsetDesc,
    ACPI_OPERAND_OBJECT     *LengthDesc,
    ACPI_OPERAND_OBJECT     *ResultDesc)
{
    UINT32                  Offset;
    UINT32                  BitOffset;
    UINT32                  BitCount;
    UINT8                   FieldFlags;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);


    /* Host object must be a Buffer */

    if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
    {
        ACPI_ERROR ((AE_INFO,
            "Target of Create Field is not a Buffer object - %s",
            AcpiUtGetObjectTypeName (BufferDesc)));

        Status = AE_AML_OPERAND_TYPE;
        goto Cleanup;
    }

    /*
     * The last parameter to all of these opcodes (ResultDesc) started
     * out as a NameString, and should therefore now be a NS node
     * after resolution in AcpiExResolveOperands().
     */
    if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
    {
        ACPI_ERROR ((AE_INFO,
            "(%s) destination not a NS Node [%s]",
            AcpiPsGetOpcodeName (AmlOpcode),
            AcpiUtGetDescriptorName (ResultDesc)));

        Status = AE_AML_OPERAND_TYPE;
        goto Cleanup;
    }

    Offset = (UINT32) OffsetDesc->Integer.Value;

    /*
     * Setup the Bit offsets and counts, according to the opcode
     */
    switch (AmlOpcode)
    {
    case AML_CREATE_FIELD_OP:

        /* Offset is in bits, count is in bits */

        FieldFlags = AML_FIELD_ACCESS_BYTE;
        BitOffset  = Offset;
        BitCount   = (UINT32) LengthDesc->Integer.Value;

        /* Must have a valid (>0) bit count */

        if (BitCount == 0)
        {
            ACPI_ERROR ((AE_INFO,
                "Attempt to CreateField of length zero"));
            Status = AE_AML_OPERAND_VALUE;
            goto Cleanup;
        }
        break;

    case AML_CREATE_BIT_FIELD_OP:

        /* Offset is in bits, Field is one bit */

        BitOffset  = Offset;
        BitCount   = 1;
        FieldFlags = AML_FIELD_ACCESS_BYTE;
        break;

    case AML_CREATE_BYTE_FIELD_OP:

        /* Offset is in bytes, field is one byte */

        BitOffset  = 8 * Offset;
        BitCount   = 8;
        FieldFlags = AML_FIELD_ACCESS_BYTE;
        break;

    case AML_CREATE_WORD_FIELD_OP:

        /* Offset is in bytes, field is one word */

        BitOffset  = 8 * Offset;
        BitCount   = 16;
        FieldFlags = AML_FIELD_ACCESS_WORD;
        break;

    case AML_CREATE_DWORD_FIELD_OP:

        /* Offset is in bytes, field is one dword */

        BitOffset  = 8 * Offset;
        BitCount   = 32;
        FieldFlags = AML_FIELD_ACCESS_DWORD;
        break;

    case AML_CREATE_QWORD_FIELD_OP:

        /* Offset is in bytes, field is one qword */

        BitOffset  = 8 * Offset;
        BitCount   = 64;
        FieldFlags = AML_FIELD_ACCESS_QWORD;
        break;

    default:

        ACPI_ERROR ((AE_INFO,
            "Unknown field creation opcode 0x%02X",
            AmlOpcode));
        Status = AE_AML_BAD_OPCODE;
        goto Cleanup;
    }

    /* Entire field must fit within the current length of the buffer */

    if ((BitOffset + BitCount) >
        (8 * (UINT32) BufferDesc->Buffer.Length))
    {
        ACPI_ERROR ((AE_INFO,
            "Field [%4.4s] at bit offset/length %u/%u "
            "exceeds size of target Buffer (%u bits)",
            AcpiUtGetNodeName (ResultDesc), BitOffset, BitCount,
            8 * (UINT32) BufferDesc->Buffer.Length));
        Status = AE_AML_BUFFER_LIMIT;
        goto Cleanup;
    }

    /*
     * Initialize areas of the field object that are common to all fields
     * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
     * UPDATE_RULE = 0 (UPDATE_PRESERVE)
     */
    Status = AcpiExPrepCommonFieldObject (
        ObjDesc, FieldFlags, 0, BitOffset, BitCount);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    ObjDesc->BufferField.BufferObj = BufferDesc;

    /* Reference count for BufferDesc inherits ObjDesc count */

    BufferDesc->Common.ReferenceCount = (UINT16)
        (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);


Cleanup:

    /* Always delete the operands */

    AcpiUtRemoveReference (OffsetDesc);
    AcpiUtRemoveReference (BufferDesc);

    if (AmlOpcode == AML_CREATE_FIELD_OP)
    {
        AcpiUtRemoveReference (LengthDesc);
    }

    /* On failure, delete the result descriptor */

    if (ACPI_FAILURE (Status))
    {
        AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
    }
    else
    {
        /* Now the address and length are valid for this BufferField */

        ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
    }

    return_ACPI_STATUS (Status);
}
Example #2
0
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;
    ACPI_INTEGER            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_INTEGER_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_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 = AcpiNsGetNode (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)
                    {
                        AcpiUtAddReference (ReturnDesc);
                    }
                    break;


                default:

                    ACPI_ERROR ((AE_INFO,
                        "Unknown Index TargetType %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);
                }

                /* Add another reference to the object! */

                AcpiUtAddReference (ReturnDesc);
                break;


            default:
                ACPI_ERROR ((AE_INFO,
                    "Unknown class in reference(%p) - %2.2X",
                    Operand[0], Operand[0]->Reference.Class));

                Status = AE_TYPE;
                goto Cleanup;
            }
        }
        break;


    default:

        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %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
AcpiUtUpdateObjectReference (
    ACPI_OPERAND_OBJECT     *Object,
    UINT16                  Action)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GENERIC_STATE      *StateList = NULL;
    ACPI_OPERAND_OBJECT     *NextObject = NULL;
    ACPI_GENERIC_STATE      *State;
    UINT32                  i;


    ACPI_FUNCTION_TRACE_PTR (UtUpdateObjectReference, Object);


    while (Object)
    {
        /* Make sure that this isn't a namespace handle */

        if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
                "Object %p is NS handle\n", Object));
            return_ACPI_STATUS (AE_OK);
        }

        /*
         * All sub-objects must have their reference count incremented also.
         * Different object types have different subobjects.
         */
        switch (Object->Common.Type)
        {
        case ACPI_TYPE_DEVICE:
        case ACPI_TYPE_PROCESSOR:
        case ACPI_TYPE_POWER:
        case ACPI_TYPE_THERMAL:

            /* Update the notify objects for these types (if present) */

            AcpiUtUpdateRefCount (Object->CommonNotify.SystemNotify, Action);
            AcpiUtUpdateRefCount (Object->CommonNotify.DeviceNotify, Action);
            break;

        case ACPI_TYPE_PACKAGE:
            /*
             * We must update all the sub-objects of the package,
             * each of whom may have their own sub-objects.
             */
            for (i = 0; i < Object->Package.Count; i++)
            {
                /*
                 * Push each element onto the stack for later processing.
                 * Note: There can be null elements within the package,
                 * these are simply ignored
                 */
                Status = AcpiUtCreateUpdateStateAndPush (
                            Object->Package.Elements[i], Action, &StateList);
                if (ACPI_FAILURE (Status))
                {
                    goto ErrorExit;
                }
            }
            break;

        case ACPI_TYPE_BUFFER_FIELD:

            NextObject = Object->BufferField.BufferObj;
            break;

        case ACPI_TYPE_LOCAL_REGION_FIELD:

            NextObject = Object->Field.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_BANK_FIELD:

            NextObject = Object->BankField.BankObj;
            Status = AcpiUtCreateUpdateStateAndPush (
                        Object->BankField.RegionObj, Action, &StateList);
            if (ACPI_FAILURE (Status))
            {
                goto ErrorExit;
            }
            break;

        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            NextObject = Object->IndexField.IndexObj;
            Status = AcpiUtCreateUpdateStateAndPush (
                        Object->IndexField.DataObj, Action, &StateList);
            if (ACPI_FAILURE (Status))
            {
                goto ErrorExit;
            }
            break;

        case ACPI_TYPE_LOCAL_REFERENCE:
            /*
             * The target of an Index (a package, string, or buffer) or a named
             * reference must track changes to the ref count of the index or
             * target object.
             */
            if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
                (Object->Reference.Class== ACPI_REFCLASS_NAME))
            {
                NextObject = Object->Reference.Object;
            }
            break;

        case ACPI_TYPE_REGION:
        default:
            break; /* No subobjects for all other types */
        }

        /*
         * Now we can update the count in the main object. This can only
         * happen after we update the sub-objects in case this causes the
         * main object to be deleted.
         */
        AcpiUtUpdateRefCount (Object, Action);
        Object = NULL;

        /* Move on to the next object to be updated */

        if (NextObject)
        {
            Object = NextObject;
            NextObject = NULL;
        }
        else if (StateList)
        {
            State = AcpiUtPopGenericState (&StateList);
            Object = State->Update.Object;
            AcpiUtDeleteGenericState (State);
        }
    }

    return_ACPI_STATUS (AE_OK);


ErrorExit:

    ACPI_EXCEPTION ((AE_INFO, Status,
        "Could not update object reference count"));

    /* Free any stacked Update State objects */

    while (StateList)
    {
        State = AcpiUtPopGenericState (&StateList);
        AcpiUtDeleteGenericState (State);
    }

    return_ACPI_STATUS (Status);
}
Example #4
0
ACPI_STATUS
AcpiNsCheckObjectType (
    ACPI_EVALUATE_INFO          *Info,
    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
    UINT32                      ExpectedBtypes,
    UINT32                      PackageIndex)
{
    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
    ACPI_STATUS                 Status = AE_OK;
    char                        TypeBuffer[96]; /* Room for 10 types */


    /* A Namespace node should not get here, but make sure */

    if (ReturnObject &&
        ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
    {
        ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
            "Invalid return type - Found a Namespace node [%4.4s] type %s",
            ReturnObject->Node.Name.Ascii,
            AcpiUtGetTypeName (ReturnObject->Node.Type)));
        return (AE_AML_OPERAND_TYPE);
    }

    /*
     * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
     * The bitmapped type allows multiple possible return types.
     *
     * Note, the cases below must handle all of the possible types returned
     * from all of the predefined names (including elements of returned
     * packages)
     */
    Info->ReturnBtype = AcpiNsGetBitmappedType (ReturnObject);
    if (Info->ReturnBtype == ACPI_RTYPE_ANY)
    {
        /* Not one of the supported objects, must be incorrect */
        goto TypeErrorExit;
    }

    /* For reference objects, check that the reference type is correct */

    if ((Info->ReturnBtype & ExpectedBtypes) == ACPI_RTYPE_REFERENCE)
    {
        Status = AcpiNsCheckReference (Info, ReturnObject);
        return (Status);
    }

    /* Attempt simple repair of the returned object if necessary */

    Status = AcpiNsSimpleRepair (Info, ExpectedBtypes,
        PackageIndex, ReturnObjectPtr);
    if (ACPI_SUCCESS (Status))
    {
        return (AE_OK); /* Successful repair */
    }


TypeErrorExit:

    /* Create a string with all expected types for this predefined object */

    AcpiUtGetExpectedReturnTypes (TypeBuffer, ExpectedBtypes);

    if (!ReturnObject)
    {
        ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
            "Expected return object of type %s",
            TypeBuffer));
    }
    else if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
    {
        ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
            "Return type mismatch - found %s, expected %s",
            AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
    }
    else
    {
        ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
            "Return Package type mismatch at index %u - "
            "found %s, expected %s", PackageIndex,
            AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
    }

    return (AE_AML_OPERAND_TYPE);
}
Example #5
0
ACPI_STATUS
AcpiExResolveOperands (
    UINT16                  Opcode,
    ACPI_OPERAND_OBJECT     **StackPtr,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_STATUS             Status = AE_OK;
    UINT8                   ObjectType;
    UINT32                  ArgTypes;
    const ACPI_OPCODE_INFO  *OpInfo;
    UINT32                  ThisArgType;
    ACPI_OBJECT_TYPE        TypeNeeded;
    UINT16                  TargetOp = 0;


    ACPI_FUNCTION_TRACE_U32 (ExResolveOperands, Opcode);


    OpInfo = AcpiPsGetOpcodeInfo (Opcode);
    if (OpInfo->Class == AML_CLASS_UNKNOWN)
    {
        return_ACPI_STATUS (AE_AML_BAD_OPCODE);
    }

    ArgTypes = OpInfo->RuntimeArgs;
    if (ArgTypes == ARGI_INVALID_OPCODE)
    {
        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
            Opcode));

        return_ACPI_STATUS (AE_AML_INTERNAL);
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
        "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",
        Opcode, OpInfo->Name, ArgTypes));

    /*
     * Normal exit is with (ArgTypes == 0) at end of argument list.
     * Function will return an exception from within the loop upon
     * finding an entry which is not (or cannot be converted
     * to) the required type; if stack underflows; or upon
     * finding a NULL stack entry (which should not happen).
     */
    while (GET_CURRENT_ARG_TYPE (ArgTypes))
    {
        if (!StackPtr || !*StackPtr)
        {
            ACPI_ERROR ((AE_INFO, "Null stack entry at %p",
                StackPtr));

            return_ACPI_STATUS (AE_AML_INTERNAL);
        }

        /* Extract useful items */

        ObjDesc = *StackPtr;

        /* Decode the descriptor type */

        switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
        {
        case ACPI_DESC_TYPE_NAMED:

            /* Namespace Node */

            ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;

            /*
             * Resolve an alias object. The construction of these objects
             * guarantees that there is only one level of alias indirection;
             * thus, the attached object is always the aliased namespace node
             */
            if (ObjectType == ACPI_TYPE_LOCAL_ALIAS)
            {
                ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
                *StackPtr = ObjDesc;
                ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
            }
            break;


        case ACPI_DESC_TYPE_OPERAND:

            /* ACPI internal object */

            ObjectType = ObjDesc->Common.Type;

            /* Check for bad ACPI_OBJECT_TYPE */

            if (!AcpiUtValidObjectType (ObjectType))
            {
                ACPI_ERROR ((AE_INFO,
                    "Bad operand object type [0x%X]", ObjectType));

                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
            }

            if (ObjectType == (UINT8) ACPI_TYPE_LOCAL_REFERENCE)
            {
                /* Validate the Reference */

                switch (ObjDesc->Reference.Class)
                {
                case ACPI_REFCLASS_DEBUG:

                    TargetOp = AML_DEBUG_OP;

                    /*lint -fallthrough */

                case ACPI_REFCLASS_ARG:
                case ACPI_REFCLASS_LOCAL:
                case ACPI_REFCLASS_INDEX:
                case ACPI_REFCLASS_REFOF:
                case ACPI_REFCLASS_TABLE:    /* DdbHandle from LOAD_OP or LOAD_TABLE_OP */
                case ACPI_REFCLASS_NAME:     /* Reference to a named object */

                    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
                        "Operand is a Reference, Class [%s] %2.2X\n",
                        AcpiUtGetReferenceName (ObjDesc),
                        ObjDesc->Reference.Class));
                    break;

                default:

                    ACPI_ERROR ((AE_INFO,
                        "Unknown Reference Class 0x%2.2X in %p",
                        ObjDesc->Reference.Class, ObjDesc));

                    return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                }
            }
            break;


        default:

            /* Invalid descriptor */

            ACPI_ERROR ((AE_INFO, "Invalid descriptor %p [%s]",
                ObjDesc, AcpiUtGetDescriptorName (ObjDesc)));

            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
        }

        /* Get one argument type, point to the next */

        ThisArgType = GET_CURRENT_ARG_TYPE (ArgTypes);
        INCREMENT_ARG_LIST (ArgTypes);

        /*
         * Handle cases where the object does not need to be
         * resolved to a value
         */
        switch (ThisArgType)
        {
        case ARGI_REF_OR_STRING:        /* Can be a String or Reference */

            if ((ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
                (ObjDesc->Common.Type == ACPI_TYPE_STRING))
            {
                /*
                 * String found - the string references a named object and
                 * must be resolved to a node
                 */
                goto NextOperand;
            }

            /*
             * Else not a string - fall through to the normal Reference
             * case below
             */
            /*lint -fallthrough */

        case ARGI_REFERENCE:            /* References: */
        case ARGI_INTEGER_REF:
        case ARGI_OBJECT_REF:
        case ARGI_DEVICE_REF:
        case ARGI_TARGETREF:     /* Allows implicit conversion rules before store */
        case ARGI_FIXED_TARGET:  /* No implicit conversion before store to target */
        case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion  */

            /*
             * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
             * A Namespace Node is OK as-is
             */
            if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_NAMED)
            {
                goto NextOperand;
            }

            Status = AcpiExCheckObjectType (ACPI_TYPE_LOCAL_REFERENCE,
                            ObjectType, ObjDesc);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }
            goto NextOperand;


        case ARGI_DATAREFOBJ:  /* Store operator only */

            /*
             * We don't want to resolve IndexOp reference objects during
             * a store because this would be an implicit DeRefOf operation.
             * Instead, we just want to store the reference object.
             * -- All others must be resolved below.
             */
            if ((Opcode == AML_STORE_OP) &&
                ((*StackPtr)->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
                ((*StackPtr)->Reference.Class == ACPI_REFCLASS_INDEX))
            {
                goto NextOperand;
            }
            break;

        default:
            /* All cases covered above */
            break;
        }

        /*
         * Resolve this object to a value
         */
        Status = AcpiExResolveToValue (StackPtr, WalkState);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        /* Get the resolved object */

        ObjDesc = *StackPtr;

        /*
         * Check the resulting object (value) type
         */
        switch (ThisArgType)
        {
        /*
         * For the simple cases, only one type of resolved object
         * is allowed
         */
        case ARGI_MUTEX:

            /* Need an operand of type ACPI_TYPE_MUTEX */

            TypeNeeded = ACPI_TYPE_MUTEX;
            break;

        case ARGI_EVENT:

            /* Need an operand of type ACPI_TYPE_EVENT */

            TypeNeeded = ACPI_TYPE_EVENT;
            break;

        case ARGI_PACKAGE:   /* Package */

            /* Need an operand of type ACPI_TYPE_PACKAGE */

            TypeNeeded = ACPI_TYPE_PACKAGE;
            break;

        case ARGI_ANYTYPE:

            /* Any operand type will do */

            TypeNeeded = ACPI_TYPE_ANY;
            break;

        case ARGI_DDBHANDLE:

            /* Need an operand of type ACPI_TYPE_DDB_HANDLE */

            TypeNeeded = ACPI_TYPE_LOCAL_REFERENCE;
            break;


        /*
         * The more complex cases allow multiple resolved object types
         */
        case ARGI_INTEGER:

            /*
             * Need an operand of type ACPI_TYPE_INTEGER,
             * But we can implicitly convert from a STRING or BUFFER
             * Aka - "Implicit Source Operand Conversion"
             */
            Status = AcpiExConvertToInteger (ObjDesc, StackPtr, 16);
            if (ACPI_FAILURE (Status))
            {
                if (Status == AE_TYPE)
                {
                    ACPI_ERROR ((AE_INFO,
                        "Needed [Integer/String/Buffer], found [%s] %p",
                        AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                    return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                }

                return_ACPI_STATUS (Status);
            }

            if (ObjDesc != *StackPtr)
            {
                AcpiUtRemoveReference (ObjDesc);
            }
            goto NextOperand;


        case ARGI_BUFFER:

            /*
             * Need an operand of type ACPI_TYPE_BUFFER,
             * But we can implicitly convert from a STRING or INTEGER
             * Aka - "Implicit Source Operand Conversion"
             */
            Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
            if (ACPI_FAILURE (Status))
            {
                if (Status == AE_TYPE)
                {
                    ACPI_ERROR ((AE_INFO,
                        "Needed [Integer/String/Buffer], found [%s] %p",
                        AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                    return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                }

                return_ACPI_STATUS (Status);
            }

            if (ObjDesc != *StackPtr)
            {
                AcpiUtRemoveReference (ObjDesc);
            }
            goto NextOperand;


        case ARGI_STRING:

            /*
             * Need an operand of type ACPI_TYPE_STRING,
             * But we can implicitly convert from a BUFFER or INTEGER
             * Aka - "Implicit Source Operand Conversion"
             */
            Status = AcpiExConvertToString (ObjDesc, StackPtr,
                        ACPI_IMPLICIT_CONVERT_HEX);
            if (ACPI_FAILURE (Status))
            {
                if (Status == AE_TYPE)
                {
                    ACPI_ERROR ((AE_INFO,
                        "Needed [Integer/String/Buffer], found [%s] %p",
                        AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                    return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                }

                return_ACPI_STATUS (Status);
            }

            if (ObjDesc != *StackPtr)
            {
                AcpiUtRemoveReference (ObjDesc);
            }
            goto NextOperand;


        case ARGI_COMPUTEDATA:

            /* Need an operand of type INTEGER, STRING or BUFFER */

            switch (ObjDesc->Common.Type)
            {
            case ACPI_TYPE_INTEGER:
            case ACPI_TYPE_STRING:
            case ACPI_TYPE_BUFFER:

                /* Valid operand */
               break;

            default:
                ACPI_ERROR ((AE_INFO,
                    "Needed [Integer/String/Buffer], found [%s] %p",
                    AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
            }
            goto NextOperand;


        case ARGI_BUFFER_OR_STRING:

            /* Need an operand of type STRING or BUFFER */

            switch (ObjDesc->Common.Type)
            {
            case ACPI_TYPE_STRING:
            case ACPI_TYPE_BUFFER:

                /* Valid operand */
               break;

            case ACPI_TYPE_INTEGER:

                /* Highest priority conversion is to type Buffer */

                Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
                if (ACPI_FAILURE (Status))
                {
                    return_ACPI_STATUS (Status);
                }

                if (ObjDesc != *StackPtr)
                {
                    AcpiUtRemoveReference (ObjDesc);
                }
                break;

            default:
                ACPI_ERROR ((AE_INFO,
                    "Needed [Integer/String/Buffer], found [%s] %p",
                    AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
            }
            goto NextOperand;


        case ARGI_DATAOBJECT:
            /*
             * ARGI_DATAOBJECT is only used by the SizeOf operator.
             * Need a buffer, string, package, or RefOf reference.
             *
             * The only reference allowed here is a direct reference to
             * a namespace node.
             */
            switch (ObjDesc->Common.Type)
            {
            case ACPI_TYPE_PACKAGE:
            case ACPI_TYPE_STRING:
            case ACPI_TYPE_BUFFER:
            case ACPI_TYPE_LOCAL_REFERENCE:

                /* Valid operand */
                break;

            default:
                ACPI_ERROR ((AE_INFO,
                    "Needed [Buffer/String/Package/Reference], found [%s] %p",
                    AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
            }
            goto NextOperand;


        case ARGI_COMPLEXOBJ:

            /* Need a buffer or package or (ACPI 2.0) String */

            switch (ObjDesc->Common.Type)
            {
            case ACPI_TYPE_PACKAGE:
            case ACPI_TYPE_STRING:
            case ACPI_TYPE_BUFFER:

                /* Valid operand */
                break;

            default:
                ACPI_ERROR ((AE_INFO,
                    "Needed [Buffer/String/Package], found [%s] %p",
                    AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
            }
            goto NextOperand;


        case ARGI_REGION_OR_BUFFER: /* Used by Load() only */

            /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */

            switch (ObjDesc->Common.Type)
            {
            case ACPI_TYPE_BUFFER:
            case ACPI_TYPE_REGION:

                /* Valid operand */
                break;

            default:
                ACPI_ERROR ((AE_INFO,
                    "Needed [Region/Buffer], found [%s] %p",
                    AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
            }
            goto NextOperand;


        case ARGI_DATAREFOBJ:

            /* Used by the Store() operator only */

            switch (ObjDesc->Common.Type)
            {
            case ACPI_TYPE_INTEGER:
            case ACPI_TYPE_PACKAGE:
            case ACPI_TYPE_STRING:
            case ACPI_TYPE_BUFFER:
            case ACPI_TYPE_BUFFER_FIELD:
            case ACPI_TYPE_LOCAL_REFERENCE:
            case ACPI_TYPE_LOCAL_REGION_FIELD:
            case ACPI_TYPE_LOCAL_BANK_FIELD:
            case ACPI_TYPE_LOCAL_INDEX_FIELD:
            case ACPI_TYPE_DDB_HANDLE:

                /* Valid operand */
                break;

            default:

                if (AcpiGbl_EnableInterpreterSlack)
                {
                    /*
                     * Enable original behavior of Store(), allowing any and all
                     * objects as the source operand.  The ACPI spec does not
                     * allow this, however.
                     */
                    break;
                }

                if (TargetOp == AML_DEBUG_OP)
                {
                    /* Allow store of any object to the Debug object */

                    break;
                }

                ACPI_ERROR ((AE_INFO,
                    "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p",
                    AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));

                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
            }
            goto NextOperand;


        default:

            /* Unknown type */

            ACPI_ERROR ((AE_INFO,
                "Internal - Unknown ARGI (required operand) type 0x%X",
                ThisArgType));

            return_ACPI_STATUS (AE_BAD_PARAMETER);
        }

        /*
         * Make sure that the original object was resolved to the
         * required object type (Simple cases only).
         */
        Status = AcpiExCheckObjectType (TypeNeeded,
                        (*StackPtr)->Common.Type, *StackPtr);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

NextOperand:
        /*
         * If more operands needed, decrement StackPtr to point
         * to next operand on stack
         */
        if (GET_CURRENT_ARG_TYPE (ArgTypes))
        {
            StackPtr--;
        }
    }

    ACPI_DUMP_OPERANDS (WalkState->Operands,
        AcpiPsGetOpcodeName (Opcode), WalkState->NumOperands);

    return_ACPI_STATUS (Status);
}
Example #6
0
static ACPI_STATUS
AcpiUtCopySimpleObject (
    ACPI_OPERAND_OBJECT     *SourceDesc,
    ACPI_OPERAND_OBJECT     *DestDesc)
{
    UINT16                  ReferenceCount;
    ACPI_OPERAND_OBJECT     *NextObject;
    ACPI_STATUS             Status;
    ACPI_SIZE               CopySize;


    /* Save fields from destination that we don't want to overwrite */

    ReferenceCount = DestDesc->Common.ReferenceCount;
    NextObject = DestDesc->Common.NextObject;

    /*
     * Copy the entire source object over the destination object.
     * Note: Source can be either an operand object or namespace node.
     */
    CopySize = sizeof (ACPI_OPERAND_OBJECT);
    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
    {
        CopySize = sizeof (ACPI_NAMESPACE_NODE);
    }

    ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc),
        ACPI_CAST_PTR (char, SourceDesc), CopySize);

    /* Restore the saved fields */

    DestDesc->Common.ReferenceCount = ReferenceCount;
    DestDesc->Common.NextObject = NextObject;

    /* New object is not static, regardless of source */

    DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;

    /* Handle the objects with extra data */

    switch (DestDesc->Common.Type)
    {
    case ACPI_TYPE_BUFFER:
        /*
         * Allocate and copy the actual buffer if and only if:
         * 1) There is a valid buffer pointer
         * 2) The buffer has a length > 0
         */
        if ((SourceDesc->Buffer.Pointer) &&
            (SourceDesc->Buffer.Length))
        {
            DestDesc->Buffer.Pointer =
                ACPI_ALLOCATE (SourceDesc->Buffer.Length);
            if (!DestDesc->Buffer.Pointer)
            {
                return (AE_NO_MEMORY);
            }

            /* Copy the actual buffer data */

            ACPI_MEMCPY (DestDesc->Buffer.Pointer,
                SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
        }
        break;

    case ACPI_TYPE_STRING:
        /*
         * Allocate and copy the actual string if and only if:
         * 1) There is a valid string pointer
         * (Pointer to a NULL string is allowed)
         */
        if (SourceDesc->String.Pointer)
        {
            DestDesc->String.Pointer =
                ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
            if (!DestDesc->String.Pointer)
            {
                return (AE_NO_MEMORY);
            }

            /* Copy the actual string data */

            ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer,
                (ACPI_SIZE) SourceDesc->String.Length + 1);
        }
        break;

    case ACPI_TYPE_LOCAL_REFERENCE:
        /*
         * We copied the reference object, so we now must add a reference
         * to the object pointed to by the reference
         *
         * DDBHandle reference (from Load/LoadTable) is a special reference,
         * it does not have a Reference.Object, so does not need to
         * increase the reference count
         */
        if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
        {
            break;
        }

        AcpiUtAddReference (SourceDesc->Reference.Object);
        break;

    case ACPI_TYPE_REGION:
        /*
         * We copied the Region Handler, so we now must add a reference
         */
        if (DestDesc->Region.Handler)
        {
            AcpiUtAddReference (DestDesc->Region.Handler);
        }
        break;

    /*
     * For Mutex and Event objects, we cannot simply copy the underlying
     * OS object. We must create a new one.
     */
    case ACPI_TYPE_MUTEX:

        Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
        if (ACPI_FAILURE (Status))
        {
            return (Status);
        }
        break;

    case ACPI_TYPE_EVENT:

        Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
                    &DestDesc->Event.OsSemaphore);
        if (ACPI_FAILURE (Status))
        {
            return (Status);
        }
        break;

    default:
        /* Nothing to do for other simple objects */
        break;
    }

    return (AE_OK);
}
Example #7
0
static int
acpi_ex_dump_operand(char * buf, int maxlen, union acpi_operand_object *obj_desc, u32 depth)
{
	u32 length;
    int str_len = 0;

	ACPI_FUNCTION_NAME(ex_dump_operand)

    if (maxlen <= 0) {
        return maxlen;
    }

	if (!obj_desc) {

		/* This could be a null element of a package */

		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
		return maxlen;
	}

	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p Namespace Node: ",
				  obj_desc));
		ACPI_DUMP_ENTRY(obj_desc, ACPI_LV_EXEC);
		return maxlen;
	}

	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "%p is not a node or operand object: [%s]\n",
				  obj_desc,
				  acpi_ut_get_descriptor_name(obj_desc)));
		ACPI_DUMP_BUFFER(obj_desc, sizeof(union acpi_operand_object));
		return maxlen;
	}

	/* obj_desc is a valid object */

	if (depth > 0) {
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%*s[%u] %p ",
				  depth, " ", depth, obj_desc));
	} else {
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p ", obj_desc));
	}

	/* Decode object type */

	switch (obj_desc->common.type) {
#if 0
	case ACPI_TYPE_LOCAL_REFERENCE:

		//str_len += snprintf(buf + str_len, maxlen - str_len, "Reference: [%s] ",
        //                    acpi_ut_get_reference_name(obj_desc));

		switch (obj_desc->reference.class) {
		case ACPI_REFCLASS_DEBUG:

			str_len += snprintf(buf + str_len, maxlen - str_len, "\n");
			break;

		case ACPI_REFCLASS_INDEX:

			str_len += snprintf(buf + str_len, maxlen - str_len, "%p\n", obj_desc->reference.object);
			break;

		case ACPI_REFCLASS_TABLE:

			str_len += snprintf(buf + str_len, maxlen - str_len, "Table Index %X\n",
                                obj_desc->reference.value);
			break;

		case ACPI_REFCLASS_REFOF:

			//str_len += snprintf(buf + str_len, maxlen - str_len, "%p [%s]\n", obj_desc->reference.object,
            //                     acpi_ut_get_type_name(((union
            //                                 acpi_operand_object
            //                                 *)
            //                                obj_desc->
            //                                reference.
            //                                object)->common.
            //                               type));
			break;

		case ACPI_REFCLASS_NAME:

			str_len += snprintf(buf + str_len, maxlen - str_len, "- [%4.4s]\n",
                               obj_desc->reference.node->name.ascii);
			break;

		case ACPI_REFCLASS_ARG:
		case ACPI_REFCLASS_LOCAL:

			str_len += snprintf(buf + str_len, maxlen - str_len, "%X\n", obj_desc->reference.value);
			break;

		default:	/* Unknown reference class */

			str_len += snprintf(buf + str_len, maxlen - str_len, "%2.2X\n", obj_desc->reference.class);
			break;
		}
		break;

	case ACPI_TYPE_BUFFER:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Buffer length %.2X @ %p\n",
			       obj_desc->buffer.length,
			       obj_desc->buffer.pointer);

		/* Debug only -- dump the buffer contents */

		if (obj_desc->buffer.pointer) {
			length = obj_desc->buffer.length;
			if (length > 128) {
				length = 128;
			}

			str_len += snprintf(buf + str_len, maxlen - str_len,
			    "Buffer Contents: (displaying length 0x%.2X)\n",
			     length);
			ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length);
		}
		break;
#endif

	case ACPI_TYPE_INTEGER:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Integer %8.8X%8.8X\n",
			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
		break;

#if 0
	case ACPI_TYPE_PACKAGE:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Package [Len %X] ElementArray %p\n",
			       obj_desc->package.count,
			       obj_desc->package.elements);

		///*
		// * If elements exist, package element pointer is valid,
		// * and debug_level exceeds 1, dump package's elements.
		// */
		//if (obj_desc->package.count &&
		//    obj_desc->package.elements && acpi_dbg_level > 1) {
		//	for (index = 0; index < obj_desc->package.count; index++) {
		//		acpi_ex_dump_operand(obj_desc->package.
		//				     elements[index],
		//				     depth + 1);
		//	}
		//}
		break;

	case ACPI_TYPE_REGION:

		//str_len += snprintf(buf + str_len, maxlen - str_len, "Region %s (%X)",
		//	       acpi_ut_get_region_name(obj_desc->region.
		//				       space_id),
		//	       obj_desc->region.space_id);

		/*
		 * If the address and length have not been evaluated,
		 * don't print them.
		 */
		if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) {
			str_len += snprintf(buf + str_len, maxlen - str_len, "\n");
		} else {
			str_len += snprintf(buf + str_len, maxlen - str_len, " base %8.8X%8.8X Length %X\n",
				       ACPI_FORMAT_NATIVE_UINT(obj_desc->region.
							       address),
				       obj_desc->region.length);
		}
		break;

	case ACPI_TYPE_STRING:

		str_len += snprintf(buf + str_len, maxlen - str_len, "String length %X @ %p ",
			       obj_desc->string.length,
			       obj_desc->string.pointer);

		//acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
		str_len += snprintf(buf + str_len, maxlen - str_len, "\n");
		break;

	case ACPI_TYPE_LOCAL_BANK_FIELD:

		str_len += snprintf(buf + str_len, maxlen - str_len, "BankField\n");
		break;

	case ACPI_TYPE_LOCAL_REGION_FIELD:

		 str_len += snprintf(buf + str_len, maxlen - str_len, 
		    "RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
		     "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
		     obj_desc->field.access_byte_width,
		     obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
		     obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
		     obj_desc->field.base_byte_offset,
		     obj_desc->field.start_field_bit_offset);

		//acpi_ex_dump_operand(obj_desc->field.region_obj, depth + 1);
		break;

	case ACPI_TYPE_LOCAL_INDEX_FIELD:

		str_len += snprintf(buf + str_len, maxlen - str_len, "IndexField\n");
		break;

	case ACPI_TYPE_BUFFER_FIELD:

		str_len += snprintf(buf + str_len, maxlen - str_len, "BufferField: %X bits at byte %X bit %X of\n",
			       obj_desc->buffer_field.bit_length,
			       obj_desc->buffer_field.base_byte_offset,
			       obj_desc->buffer_field.start_field_bit_offset);

		if (!obj_desc->buffer_field.buffer_obj) {
			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
		} else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
			   ACPI_TYPE_BUFFER) {
			str_len += snprintf(buf + str_len, maxlen - str_len, "*not a Buffer*\n");
		} else {
			//acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
			//		     depth + 1);
		}
		break;

	case ACPI_TYPE_EVENT:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Event\n");
		break;

	case ACPI_TYPE_METHOD:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Method(%X) @ %p:%X\n",
			       obj_desc->method.param_count,
			       obj_desc->method.aml_start,
			       obj_desc->method.aml_length);
		break;

	case ACPI_TYPE_MUTEX:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Mutex\n");
		break;

	case ACPI_TYPE_DEVICE:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Device\n");
		break;

	case ACPI_TYPE_POWER:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Power\n");
		break;

	case ACPI_TYPE_PROCESSOR:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Processor\n");
		break;

	case ACPI_TYPE_THERMAL:

		str_len += snprintf(buf + str_len, maxlen - str_len, "Thermal\n");
		break;
#endif

	default:
		/* Unknown Type */

		str_len += snprintf(buf + str_len, maxlen - str_len, "Unknown Type %X\n", obj_desc->common.type);
		break;
	}

	return str_len;
}
acpi_status
acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
			    union acpi_parse_object * op)
{
	acpi_status status = AE_OK;
	union acpi_generic_state *control_state;

	ACPI_FUNCTION_NAME(ds_exec_end_control_op);

	switch (op->common.aml_opcode) {
	case AML_IF_OP:

		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));

		/*
		 * Save the result of the predicate in case there is an
		 * ELSE to come
		 */
		walk_state->last_predicate =
		    (u8) walk_state->control_state->common.value;

		/*
		 * Pop the control state that was created at the start
		 * of the IF and free it
		 */
		control_state =
		    acpi_ut_pop_generic_state(&walk_state->control_state);
		acpi_ut_delete_generic_state(control_state);
		break;

	case AML_ELSE_OP:

		break;

	case AML_WHILE_OP:

		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));

		if (walk_state->control_state->common.value) {

			/* Predicate was true, go back and evaluate it again! */

			status = AE_CTRL_PENDING;
		}

		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
				  "[WHILE_OP] termination! Op=%p\n", op));

		/* Pop this control state and free it */

		control_state =
		    acpi_ut_pop_generic_state(&walk_state->control_state);

		walk_state->aml_last_while =
		    control_state->control.aml_predicate_start;
		acpi_ut_delete_generic_state(control_state);
		break;

	case AML_RETURN_OP:

		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
				  "[RETURN_OP] Op=%p Arg=%p\n", op,
				  op->common.value.arg));

		/*
		 * One optional operand -- the return value
		 * It can be either an immediate operand or a result that
		 * has been bubbled up the tree
		 */
		if (op->common.value.arg) {

			/* Since we have a real Return(), delete any implicit return */

			acpi_ds_clear_implicit_return(walk_state);

			/* Return statement has an immediate operand */

			status =
			    acpi_ds_create_operands(walk_state,
						    op->common.value.arg);
			if (ACPI_FAILURE(status)) {
				return (status);
			}

			/*
			 * If value being returned is a Reference (such as
			 * an arg or local), resolve it now because it may
			 * cease to exist at the end of the method.
			 */
			status =
			    acpi_ex_resolve_to_value(&walk_state->operands[0],
						     walk_state);
			if (ACPI_FAILURE(status)) {
				return (status);
			}

			/*
			 * Get the return value and save as the last result
			 * value.  This is the only place where walk_state->return_desc
			 * is set to anything other than zero!
			 */
			walk_state->return_desc = walk_state->operands[0];
		} else if ((walk_state->results) &&
			   (walk_state->results->results.num_results > 0)) {

			/* Since we have a real Return(), delete any implicit return */

			acpi_ds_clear_implicit_return(walk_state);

			/*
			 * The return value has come from a previous calculation.
			 *
			 * If value being returned is a Reference (such as
			 * an arg or local), resolve it now because it may
			 * cease to exist at the end of the method.
			 *
			 * Allow references created by the Index operator to return unchanged.
			 */
			if ((ACPI_GET_DESCRIPTOR_TYPE
			     (walk_state->results->results.obj_desc[0]) ==
			     ACPI_DESC_TYPE_OPERAND)
			    &&
			    (ACPI_GET_OBJECT_TYPE
			     (walk_state->results->results.obj_desc[0]) ==
			     ACPI_TYPE_LOCAL_REFERENCE)
			    && ((walk_state->results->results.obj_desc[0])->
				reference.opcode != AML_INDEX_OP)) {
				status =
				    acpi_ex_resolve_to_value(&walk_state->
							     results->results.
							     obj_desc[0],
							     walk_state);
				if (ACPI_FAILURE(status)) {
					return (status);
				}
			}

			walk_state->return_desc =
			    walk_state->results->results.obj_desc[0];
		} else {
			/* No return operand */

			if (walk_state->num_operands) {
				acpi_ut_remove_reference(walk_state->
							 operands[0]);
			}

			walk_state->operands[0] = NULL;
			walk_state->num_operands = 0;
			walk_state->return_desc = NULL;
		}

		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
				  "Completed RETURN_OP State=%p, RetVal=%p\n",
				  walk_state, walk_state->return_desc));

		/* End the control method execution right now */

		status = AE_CTRL_TERMINATE;
		break;

	case AML_NOOP_OP:

		/* Just do nothing! */
		break;

	case AML_BREAK_POINT_OP:

		/* Call up to the OS service layer to handle this */

		status =
		    acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
				   "Executed AML Breakpoint opcode");

		/* If and when it returns, all done. */

		break;

	case AML_BREAK_OP:
	case AML_CONTINUE_OP:	/* ACPI 2.0 */

		/* Pop and delete control states until we find a while */

		while (walk_state->control_state &&
		       (walk_state->control_state->control.opcode !=
			AML_WHILE_OP)) {
			control_state =
			    acpi_ut_pop_generic_state(&walk_state->
						      control_state);
			acpi_ut_delete_generic_state(control_state);
		}

		/* No while found? */

		if (!walk_state->control_state) {
			return (AE_AML_NO_WHILE);
		}

		/* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */

		walk_state->aml_last_while =
		    walk_state->control_state->control.package_end;

		/* Return status depending on opcode */

		if (op->common.aml_opcode == AML_BREAK_OP) {
			status = AE_CTRL_BREAK;
		} else {
			status = AE_CTRL_CONTINUE;
		}
		break;

	default:

		ACPI_ERROR((AE_INFO, "Unknown control opcode=%X Op=%p",
			    op->common.aml_opcode, op));

		status = AE_AML_BAD_OPCODE;
		break;
	}

	return (status);
}
Example #9
0
acpi_status
acpi_evaluate_object (
	acpi_handle                     handle,
	acpi_string                     pathname,
	struct acpi_object_list         *external_params,
	struct acpi_buffer              *return_buffer)
{
	acpi_status                     status;
	acpi_status                     status2;
	struct acpi_parameter_info      info;
	acpi_size                       buffer_space_needed;
	u32                             i;


	ACPI_FUNCTION_TRACE ("acpi_evaluate_object");


	info.node = handle;
	info.parameters = NULL;
	info.return_object = NULL;
	info.parameter_type = ACPI_PARAM_ARGS;

	/*
	 * If there are parameters to be passed to the object
	 * (which must be a control method), the external objects
	 * must be converted to internal objects
	 */
	if (external_params && external_params->count) {
		/*
		 * Allocate a new parameter block for the internal objects
		 * Add 1 to count to allow for null terminated internal list
		 */
		info.parameters = ACPI_MEM_CALLOCATE (
				 ((acpi_size) external_params->count + 1) *
				 sizeof (void *));
		if (!info.parameters) {
			return_ACPI_STATUS (AE_NO_MEMORY);
		}

		/*
		 * Convert each external object in the list to an
		 * internal object
		 */
		for (i = 0; i < external_params->count; i++) {
			status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
					  &info.parameters[i]);
			if (ACPI_FAILURE (status)) {
				acpi_ut_delete_internal_object_list (info.parameters);
				return_ACPI_STATUS (status);
			}
		}
		info.parameters[external_params->count] = NULL;
	}


	/*
	 * Three major cases:
	 * 1) Fully qualified pathname
	 * 2) No handle, not fully qualified pathname (error)
	 * 3) Valid handle
	 */
	if ((pathname) &&
		(acpi_ns_valid_root_prefix (pathname[0]))) {
		/*
		 *  The path is fully qualified, just evaluate by name
		 */
		status = acpi_ns_evaluate_by_name (pathname, &info);
	}
	else if (!handle) {
		/*
		 * A handle is optional iff a fully qualified pathname
		 * is specified.  Since we've already handled fully
		 * qualified names above, this is an error
		 */
		if (!pathname) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Both Handle and Pathname are NULL\n"));
		}
		else {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Handle is NULL and Pathname is relative\n"));
		}

		status = AE_BAD_PARAMETER;
	}
	else {
		/*
		 * We get here if we have a handle -- and if we have a
		 * pathname it is relative.  The handle will be validated
		 * in the lower procedures
		 */
		if (!pathname) {
			/*
			 * The null pathname case means the handle is for
			 * the actual object to be evaluated
			 */
			status = acpi_ns_evaluate_by_handle (&info);
		}
		else {
		   /*
			* Both a Handle and a relative Pathname
			*/
			status = acpi_ns_evaluate_relative (pathname, &info);
		}
	}


	/*
	 * If we are expecting a return value, and all went well above,
	 * copy the return value to an external object.
	 */
	if (return_buffer) {
		if (!info.return_object) {
			return_buffer->length = 0;
		}
		else {
			if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) {
				/*
				 * If we received a NS Node as a return object, this means that
				 * the object we are evaluating has nothing interesting to
				 * return (such as a mutex, etc.)  We return an error because
				 * these types are essentially unsupported by this interface.
				 * We don't check up front because this makes it easier to add
				 * support for various types at a later date if necessary.
				 */
				status = AE_TYPE;
				info.return_object = NULL;  /* No need to delete a NS Node */
				return_buffer->length = 0;
			}

			if (ACPI_SUCCESS (status)) {
				/*
				 * Find out how large a buffer is needed
				 * to contain the returned object
				 */
				status = acpi_ut_get_object_size (info.return_object,
						   &buffer_space_needed);
				if (ACPI_SUCCESS (status)) {
					/* Validate/Allocate/Clear caller buffer */

					status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed);
					if (ACPI_FAILURE (status)) {
						/*
						 * Caller's buffer is too small or a new one can't be allocated
						 */
						ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
							"Needed buffer size %X, %s\n",
							(u32) buffer_space_needed,
							acpi_format_exception (status)));
					}
					else {
						/*
						 *  We have enough space for the object, build it
						 */
						status = acpi_ut_copy_iobject_to_eobject (info.return_object,
								  return_buffer);
					}
				}
			}
		}
	}

	if (info.return_object) {
		/*
		 * Delete the internal return object.  NOTE: Interpreter
		 * must be locked to avoid race condition.
		 */
		status2 = acpi_ex_enter_interpreter ();
		if (ACPI_SUCCESS (status2)) {
			/*
			 * Delete the internal return object. (Or at least
			 * decrement the reference count by one)
			 */
			acpi_ut_remove_reference (info.return_object);
			acpi_ex_exit_interpreter ();
		}
	}

	/*
	 * Free the input parameter list (if we created one),
	 */
	if (info.parameters) {
		/* Free the allocated parameter block */

		acpi_ut_delete_internal_object_list (info.parameters);
	}

	return_ACPI_STATUS (status);
}
ACPI_STATUS
AcpiEvaluateObject (
    ACPI_HANDLE             Handle,
    ACPI_STRING             Pathname,
    ACPI_OBJECT_LIST        *ExternalParams,
    ACPI_BUFFER             *ReturnBuffer)
{
    ACPI_STATUS             Status;
    ACPI_EVALUATE_INFO      *Info;
    ACPI_SIZE               BufferSpaceNeeded;
    UINT32                  i;


    ACPI_FUNCTION_TRACE (AcpiEvaluateObject);


    /* Allocate and initialize the evaluation information block */

    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
    if (!Info)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Convert and validate the device handle */

    Info->PrefixNode = AcpiNsValidateHandle (Handle);
    if (!Info->PrefixNode)
    {
        Status = AE_BAD_PARAMETER;
        goto Cleanup;
    }

    /*
     * Get the actual namespace node for the target object.
     * 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
     */
    if ((Pathname) &&
        (ACPI_IS_ROOT_PREFIX (Pathname[0])))
    {
        /* The path is fully qualified, just evaluate by name */

        Info->PrefixNode = NULL;
    }
    else if (!Handle)
    {
        /*
         * A handle is optional iff a fully qualified pathname is specified.
         * Since we've already handled fully qualified names above, this is
         * an error.
         */
        if (!Pathname)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
                "Both Handle and Pathname are NULL"));
        }
        else
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
                "Null Handle with relative pathname [%s]", Pathname));
        }

        Status = AE_BAD_PARAMETER;
        goto Cleanup;
    }

    Info->RelativePathname = Pathname;

    /*
     * Convert all external objects passed as arguments to the
     * internal version(s).
     */
    if (ExternalParams && ExternalParams->Count)
    {
        Info->ParamCount = (UINT16) ExternalParams->Count;

        /* Warn on impossible argument count */

        if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
        {
            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
                "Excess arguments (%u) - using only %u",
                Info->ParamCount, ACPI_METHOD_NUM_ARGS));

            Info->ParamCount = ACPI_METHOD_NUM_ARGS;
        }

        /*
         * Allocate a new parameter block for the internal objects
         * Add 1 to count to allow for null terminated internal list
         */
        Info->Parameters = ACPI_ALLOCATE_ZEROED (
            ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
        if (!Info->Parameters)
        {
            Status = AE_NO_MEMORY;
            goto Cleanup;
        }

        /* Convert each external object in the list to an internal object */

        for (i = 0; i < Info->ParamCount; i++)
        {
            Status = AcpiUtCopyEobjectToIobject (
                &ExternalParams->Pointer[i], &Info->Parameters[i]);
            if (ACPI_FAILURE (Status))
            {
                goto Cleanup;
            }
        }

        Info->Parameters[Info->ParamCount] = NULL;
    }


#if 0

    /*
     * Begin incoming argument count analysis. Check for too few args
     * and too many args.
     */

    switch (AcpiNsGetType (Info->Node))
    {
    case ACPI_TYPE_METHOD:

        /* Check incoming argument count against the method definition */

        if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
        {
            ACPI_ERROR ((AE_INFO,
                "Insufficient arguments (%u) - %u are required",
                Info->ParamCount,
                Info->ObjDesc->Method.ParamCount));

            Status = AE_MISSING_ARGUMENTS;
            goto Cleanup;
        }

        else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
        {
            ACPI_WARNING ((AE_INFO,
                "Excess arguments (%u) - only %u are required",
                Info->ParamCount,
                Info->ObjDesc->Method.ParamCount));

            /* Just pass the required number of arguments */

            Info->ParamCount = Info->ObjDesc->Method.ParamCount;
        }

        /*
         * Any incoming external objects to be passed as arguments to the
         * method must be converted to internal objects
         */
        if (Info->ParamCount)
        {
            /*
             * Allocate a new parameter block for the internal objects
             * Add 1 to count to allow for null terminated internal list
             */
            Info->Parameters = ACPI_ALLOCATE_ZEROED (
                ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
            if (!Info->Parameters)
            {
                Status = AE_NO_MEMORY;
                goto Cleanup;
            }

            /* Convert each external object in the list to an internal object */

            for (i = 0; i < Info->ParamCount; i++)
            {
                Status = AcpiUtCopyEobjectToIobject (
                    &ExternalParams->Pointer[i], &Info->Parameters[i]);
                if (ACPI_FAILURE (Status))
                {
                    goto Cleanup;
                }
            }

            Info->Parameters[Info->ParamCount] = NULL;
        }
        break;

    default:

        /* Warn if arguments passed to an object that is not a method */

        if (Info->ParamCount)
        {
            ACPI_WARNING ((AE_INFO,
                "%u arguments were passed to a non-method ACPI object",
                Info->ParamCount));
        }
        break;
    }

#endif


    /* Now we can evaluate the object */

    Status = AcpiNsEvaluate (Info);

    /*
     * If we are expecting a return value, and all went well above,
     * copy the return value to an external object.
     */
    if (ReturnBuffer)
    {
        if (!Info->ReturnObject)
        {
            ReturnBuffer->Length = 0;
        }
        else
        {
            if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
                ACPI_DESC_TYPE_NAMED)
            {
                /*
                 * If we received a NS Node as a return object, this means that
                 * the object we are evaluating has nothing interesting to
                 * return (such as a mutex, etc.)  We return an error because
                 * these types are essentially unsupported by this interface.
                 * We don't check up front because this makes it easier to add
                 * support for various types at a later date if necessary.
                 */
                Status = AE_TYPE;
                Info->ReturnObject = NULL;   /* No need to delete a NS Node */
                ReturnBuffer->Length = 0;
            }

            if (ACPI_SUCCESS (Status))
            {
                /* Dereference Index and RefOf references */

                AcpiNsResolveReferences (Info);

                /* Get the size of the returned object */

                Status = AcpiUtGetObjectSize (Info->ReturnObject,
                            &BufferSpaceNeeded);
                if (ACPI_SUCCESS (Status))
                {
                    /* Validate/Allocate/Clear caller buffer */

                    Status = AcpiUtInitializeBuffer (ReturnBuffer,
                                BufferSpaceNeeded);
                    if (ACPI_FAILURE (Status))
                    {
                        /*
                         * Caller's buffer is too small or a new one can't
                         * be allocated
                         */
                        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
                            "Needed buffer size %X, %s\n",
                            (UINT32) BufferSpaceNeeded,
                            AcpiFormatException (Status)));
                    }
                    else
                    {
                        /* We have enough space for the object, build it */

                        Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
                                    ReturnBuffer);
                    }
                }
            }
        }
    }

    if (Info->ReturnObject)
    {
        /*
         * Delete the internal return object. NOTE: Interpreter must be
         * locked to avoid race condition.
         */
        AcpiExEnterInterpreter ();

        /* Remove one reference on the return object (should delete it) */

        AcpiUtRemoveReference (Info->ReturnObject);
        AcpiExExitInterpreter ();
    }


Cleanup:

    /* Free the input parameter list (if we created one) */

    if (Info->Parameters)
    {
        /* Free the allocated parameter block */

        AcpiUtDeleteInternalObjectList (Info->Parameters);
    }

    ACPI_FREE (Info);
    return_ACPI_STATUS (Status);
}
static acpi_status
acpi_ds_init_buffer_field(u16 aml_opcode,
			  union acpi_operand_object *obj_desc,
			  union acpi_operand_object *buffer_desc,
			  union acpi_operand_object *offset_desc,
			  union acpi_operand_object *length_desc,
			  union acpi_operand_object *result_desc)
{
	u32 offset;
	u32 bit_offset;
	u32 bit_count;
	u8 field_flags;
	acpi_status status;

	ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);

	/* Host object must be a Buffer */

	if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
		ACPI_ERROR((AE_INFO,
			    "Target of Create Field is not a Buffer object - %s",
			    acpi_ut_get_object_type_name(buffer_desc)));

		status = AE_AML_OPERAND_TYPE;
		goto cleanup;
	}

	/*
	 * The last parameter to all of these opcodes (result_desc) started
	 * out as a name_string, and should therefore now be a NS node
	 * after resolution in acpi_ex_resolve_operands().
	 */
	if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
		ACPI_ERROR((AE_INFO,
			    "(%s) destination not a NS Node [%s]",
			    acpi_ps_get_opcode_name(aml_opcode),
			    acpi_ut_get_descriptor_name(result_desc)));

		status = AE_AML_OPERAND_TYPE;
		goto cleanup;
	}

	offset = (u32) offset_desc->integer.value;

	/*
	 * Setup the Bit offsets and counts, according to the opcode
	 */
	switch (aml_opcode) {
	case AML_CREATE_FIELD_OP:

		/* Offset is in bits, count is in bits */

		field_flags = AML_FIELD_ACCESS_BYTE;
		bit_offset = offset;
		bit_count = (u32) length_desc->integer.value;

		/* Must have a valid (>0) bit count */

		if (bit_count == 0) {
			ACPI_ERROR((AE_INFO,
				    "Attempt to CreateField of length zero"));
			status = AE_AML_OPERAND_VALUE;
			goto cleanup;
		}
		break;

	case AML_CREATE_BIT_FIELD_OP:

		/* Offset is in bits, Field is one bit */

		bit_offset = offset;
		bit_count = 1;
		field_flags = AML_FIELD_ACCESS_BYTE;
		break;

	case AML_CREATE_BYTE_FIELD_OP:

		/* Offset is in bytes, field is one byte */

		bit_offset = 8 * offset;
		bit_count = 8;
		field_flags = AML_FIELD_ACCESS_BYTE;
		break;

	case AML_CREATE_WORD_FIELD_OP:

		/* Offset is in bytes, field is one word */

		bit_offset = 8 * offset;
		bit_count = 16;
		field_flags = AML_FIELD_ACCESS_WORD;
		break;

	case AML_CREATE_DWORD_FIELD_OP:

		/* Offset is in bytes, field is one dword */

		bit_offset = 8 * offset;
		bit_count = 32;
		field_flags = AML_FIELD_ACCESS_DWORD;
		break;

	case AML_CREATE_QWORD_FIELD_OP:

		/* Offset is in bytes, field is one qword */

		bit_offset = 8 * offset;
		bit_count = 64;
		field_flags = AML_FIELD_ACCESS_QWORD;
		break;

	default:

		ACPI_ERROR((AE_INFO,
			    "Unknown field creation opcode %02x", aml_opcode));
		status = AE_AML_BAD_OPCODE;
		goto cleanup;
	}

	/* Entire field must fit within the current length of the buffer */

	if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) {
		ACPI_ERROR((AE_INFO,
			    "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)",
			    acpi_ut_get_node_name(result_desc),
			    bit_offset + bit_count,
			    acpi_ut_get_node_name(buffer_desc->buffer.node),
			    8 * (u32) buffer_desc->buffer.length));
		status = AE_AML_BUFFER_LIMIT;
		goto cleanup;
	}

	/*
	 * Initialize areas of the field object that are common to all fields
	 * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
	 * UPDATE_RULE = 0 (UPDATE_PRESERVE)
	 */
	status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
						  bit_offset, bit_count);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	obj_desc->buffer_field.buffer_obj = buffer_desc;

	/* Reference count for buffer_desc inherits obj_desc count */

	buffer_desc->common.reference_count = (u16)
	    (buffer_desc->common.reference_count +
	     obj_desc->common.reference_count);

      cleanup:

	/* Always delete the operands */

	acpi_ut_remove_reference(offset_desc);
	acpi_ut_remove_reference(buffer_desc);

	if (aml_opcode == AML_CREATE_FIELD_OP) {
		acpi_ut_remove_reference(length_desc);
	}

	/* On failure, delete the result descriptor */

	if (ACPI_FAILURE(status)) {
		acpi_ut_remove_reference(result_desc);	/* Result descriptor */
	} else {
		/* Now the address and length are valid for this buffer_field */

		obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
	}

	return_ACPI_STATUS(status);
}
Example #12
0
static acpi_status
acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
			       acpi_size * obj_length)
{
	acpi_size length;
	acpi_size size;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);

	/*
	 * Handle a null object (Could be a uninitialized package
	 * element -- which is legal)
	 */
	if (!internal_object) {
		*obj_length = sizeof(union acpi_object);
		return_ACPI_STATUS(AE_OK);
	}

	/* Start with the length of the Acpi object */

	length = sizeof(union acpi_object);

	if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {

		/* Object is a named object (reference), just return the length */

		*obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
		return_ACPI_STATUS(status);
	}

	/*
	 * The final length depends on the object type
	 * Strings and Buffers are packed right up against the parent object and
	 * must be accessed bytewise or there may be alignment problems on
	 * certain processors
	 */
	switch (internal_object->common.type) {
	case ACPI_TYPE_STRING:

		length += (acpi_size) internal_object->string.length + 1;
		break;

	case ACPI_TYPE_BUFFER:

		length += (acpi_size) internal_object->buffer.length;
		break;

	case ACPI_TYPE_INTEGER:
	case ACPI_TYPE_PROCESSOR:
	case ACPI_TYPE_POWER:

		/* No extra data for these types */

		break;

	case ACPI_TYPE_LOCAL_REFERENCE:

		switch (internal_object->reference.class) {
		case ACPI_REFCLASS_NAME:

			/*
			 * Get the actual length of the full pathname to this object.
			 * The reference will be converted to the pathname to the object
			 */
			size =
			    acpi_ns_get_pathname_length(internal_object->
							reference.node);
			if (!size) {
				return_ACPI_STATUS(AE_BAD_PARAMETER);
			}

			length += ACPI_ROUND_UP_TO_NATIVE_WORD(size);
			break;

		default:

			/*
			 * No other reference opcodes are supported.
			 * Notably, Locals and Args are not supported, but this may be
			 * required eventually.
			 */
			ACPI_ERROR((AE_INFO,
				    "Cannot convert to external object - "
				    "unsupported Reference Class [%s] 0x%X in object %p",
				    acpi_ut_get_reference_name(internal_object),
				    internal_object->reference.class,
				    internal_object));
			status = AE_TYPE;
			break;
		}
		break;

	default:

		ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
			    "unsupported type [%s] 0x%X in object %p",
			    acpi_ut_get_object_type_name(internal_object),
			    internal_object->common.type, internal_object));
		status = AE_TYPE;
		break;
	}

	/*
	 * Account for the space required by the object rounded up to the next
	 * multiple of the machine word size.  This keeps each object aligned
	 * on a machine word boundary. (preventing alignment faults on some
	 * machines.)
	 */
	*obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
	return_ACPI_STATUS(status);
}
Example #13
0
void
acpi_ex_dump_operand (
	union acpi_operand_object       *obj_desc,
	u32                             depth)
{
	u32                             length;
	u32                             index;


	ACPI_FUNCTION_NAME ("ex_dump_operand")


	if (!((ACPI_LV_EXEC & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
		return;
	}

	if (!obj_desc) {
		/*
		 * This could be a null element of a package
		 */
		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
		return;
	}

	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is a NS Node: ", obj_desc));
		ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC);
		return;
	}

	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
			"%p is not a node or operand object: [%s]\n",
			obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
		ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object));
		return;
	}

	/* obj_desc is a valid object */

	if (depth > 0) {
		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "%*s[%u] ", depth, " ", depth));
	}
	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "%p ", obj_desc));


	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
	case ACPI_TYPE_LOCAL_REFERENCE:

		switch (obj_desc->reference.opcode) {
		case AML_DEBUG_OP:

			acpi_os_printf ("Reference: Debug\n");
			break;


		case AML_NAME_OP:

			ACPI_DUMP_PATHNAME (obj_desc->reference.object,
				"Reference: Name: ", ACPI_LV_INFO, _COMPONENT);
			ACPI_DUMP_ENTRY (obj_desc->reference.object, ACPI_LV_INFO);
			break;


		case AML_INDEX_OP:

			acpi_os_printf ("Reference: Index %p\n",
				obj_desc->reference.object);
			break;


		case AML_REF_OF_OP:

			acpi_os_printf ("Reference: (ref_of) %p\n",
				obj_desc->reference.object);
			break;


		case AML_ARG_OP:

			acpi_os_printf ("Reference: Arg%d",
				obj_desc->reference.offset);

			if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
				/* Value is an Integer */

				acpi_os_printf (" value is [%8.8X%8.8x]",
					ACPI_FORMAT_UINT64 (obj_desc->integer.value));
			}

			acpi_os_printf ("\n");
			break;


		case AML_LOCAL_OP:

			acpi_os_printf ("Reference: Local%d",
				obj_desc->reference.offset);

			if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {

				/* Value is an Integer */

				acpi_os_printf (" value is [%8.8X%8.8x]",
					ACPI_FORMAT_UINT64 (obj_desc->integer.value));
			}

			acpi_os_printf ("\n");
			break;


		case AML_INT_NAMEPATH_OP:

			acpi_os_printf ("Reference.Node->Name %X\n",
				obj_desc->reference.node->name.integer);
			break;


		default:

			/* Unknown opcode */

			acpi_os_printf ("Unknown Reference opcode=%X\n",
				obj_desc->reference.opcode);
			break;

		}
		break;


	case ACPI_TYPE_BUFFER:

		acpi_os_printf ("Buffer len %X @ %p \n",
			obj_desc->buffer.length, obj_desc->buffer.pointer);

		length = obj_desc->buffer.length;
		if (length > 64) {
			length = 64;
		}

		/* Debug only -- dump the buffer contents */

		if (obj_desc->buffer.pointer) {
			acpi_os_printf ("Buffer Contents: ");

			for (index = 0; index < length; index++) {
				acpi_os_printf (" %02x", obj_desc->buffer.pointer[index]);
			}
			acpi_os_printf ("\n");
		}
		break;


	case ACPI_TYPE_INTEGER:

		acpi_os_printf ("Integer %8.8X%8.8X\n",
			ACPI_FORMAT_UINT64 (obj_desc->integer.value));
		break;


	case ACPI_TYPE_PACKAGE:

		acpi_os_printf ("Package [Len %X] element_array %p\n",
			obj_desc->package.count, obj_desc->package.elements);

		/*
		 * If elements exist, package element pointer is valid,
		 * and debug_level exceeds 1, dump package's elements.
		 */
		if (obj_desc->package.count &&
			obj_desc->package.elements &&
			acpi_dbg_level > 1) {
			for (index = 0; index < obj_desc->package.count; index++) {
				acpi_ex_dump_operand (obj_desc->package.elements[index], depth+1);
			}
		}
		break;


	case ACPI_TYPE_REGION:

		acpi_os_printf ("Region %s (%X)",
			acpi_ut_get_region_name (obj_desc->region.space_id),
			obj_desc->region.space_id);

		/*
		 * If the address and length have not been evaluated,
		 * don't print them.
		 */
		if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) {
			acpi_os_printf ("\n");
		}
		else {
			acpi_os_printf (" base %8.8X%8.8X Length %X\n",
				ACPI_FORMAT_UINT64 (obj_desc->region.address),
				obj_desc->region.length);
		}
		break;


	case ACPI_TYPE_STRING:

		acpi_os_printf ("String length %X @ %p ",
			obj_desc->string.length, obj_desc->string.pointer);
		acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
		acpi_os_printf ("\n");
		break;


	case ACPI_TYPE_LOCAL_BANK_FIELD:

		acpi_os_printf ("bank_field\n");
		break;


	case ACPI_TYPE_LOCAL_REGION_FIELD:

		acpi_os_printf (
			"region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
			obj_desc->field.bit_length, obj_desc->field.access_byte_width,
			obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
			obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
			obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset);
		acpi_ex_dump_operand (obj_desc->field.region_obj, depth+1);
		break;


	case ACPI_TYPE_LOCAL_INDEX_FIELD:

		acpi_os_printf ("index_field\n");
		break;


	case ACPI_TYPE_BUFFER_FIELD:

		acpi_os_printf (
			"buffer_field: %X bits at byte %X bit %X of \n",
			obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset,
			obj_desc->buffer_field.start_field_bit_offset);

		if (!obj_desc->buffer_field.buffer_obj) {
			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL* \n"));
		}
		else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER) {
			acpi_os_printf ("*not a Buffer* \n");
		}
		else {
			acpi_ex_dump_operand (obj_desc->buffer_field.buffer_obj, depth+1);
		}
		break;


	case ACPI_TYPE_EVENT:

		acpi_os_printf ("Event\n");
		break;


	case ACPI_TYPE_METHOD:

		acpi_os_printf (
			"Method(%X) @ %p:%X\n",
			obj_desc->method.param_count,
			obj_desc->method.aml_start, obj_desc->method.aml_length);
		break;


	case ACPI_TYPE_MUTEX:

		acpi_os_printf ("Mutex\n");
		break;


	case ACPI_TYPE_DEVICE:

		acpi_os_printf ("Device\n");
		break;


	case ACPI_TYPE_POWER:

		acpi_os_printf ("Power\n");
		break;


	case ACPI_TYPE_PROCESSOR:

		acpi_os_printf ("Processor\n");
		break;


	case ACPI_TYPE_THERMAL:

		acpi_os_printf ("Thermal\n");
		break;


	default:
		/* Unknown Type */

		acpi_os_printf ("Unknown Type %X\n", ACPI_GET_OBJECT_TYPE (obj_desc));
		break;
	}

	return;
}
Example #14
0
void
acpi_ex_dump_object_descriptor (
	union acpi_operand_object       *obj_desc,
	u32                             flags)
{
	u32                             i;


	ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor");


	if (!flags) {
		if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
			return_VOID;
		}
	}

	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
		acpi_ex_dump_node ((struct acpi_namespace_node *) obj_desc, flags);
		acpi_os_printf ("\nAttached Object (%p):\n",
			((struct acpi_namespace_node *) obj_desc)->object);
		acpi_ex_dump_object_descriptor (
			((struct acpi_namespace_node *) obj_desc)->object, flags);
		return_VOID;
	}

	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
		acpi_os_printf (
			"ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n",
			obj_desc, acpi_ut_get_descriptor_name (obj_desc));
		return_VOID;
	}

	/* Common Fields */

	acpi_ex_out_string ("Type",             acpi_ut_get_object_type_name (obj_desc));
	acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count);
	acpi_ex_out_integer ("Flags",           obj_desc->common.flags);

	/* Object-specific Fields */

	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
	case ACPI_TYPE_INTEGER:

		acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value",
				ACPI_FORMAT_UINT64 (obj_desc->integer.value));
		break;


	case ACPI_TYPE_STRING:

		acpi_ex_out_integer ("Length",      obj_desc->string.length);

		acpi_os_printf ("%20s : %p ", "Pointer", obj_desc->string.pointer);
		acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
		acpi_os_printf ("\n");
		break;


	case ACPI_TYPE_BUFFER:

		acpi_ex_out_integer ("Length",      obj_desc->buffer.length);
		acpi_ex_out_pointer ("Pointer",     obj_desc->buffer.pointer);
		ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length);
		break;


	case ACPI_TYPE_PACKAGE:

		acpi_ex_out_integer ("Flags",       obj_desc->package.flags);
		acpi_ex_out_integer ("Count",       obj_desc->package.count);
		acpi_ex_out_pointer ("Elements",    obj_desc->package.elements);

		/* Dump the package contents */

		if (obj_desc->package.count > 0) {
			acpi_os_printf ("\nPackage Contents:\n");
			for (i = 0; i < obj_desc->package.count; i++) {
				acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]);
				if (obj_desc->package.elements[i]) {
					acpi_os_printf (" %s",
						acpi_ut_get_object_type_name (obj_desc->package.elements[i]));
				}
				acpi_os_printf ("\n");
			}
		}
		break;


	case ACPI_TYPE_DEVICE:

		acpi_ex_out_pointer ("Handler",     obj_desc->device.handler);
		acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
		acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
		break;


	case ACPI_TYPE_EVENT:

		acpi_ex_out_pointer ("Semaphore",   obj_desc->event.semaphore);
		break;


	case ACPI_TYPE_METHOD:

		acpi_ex_out_integer ("param_count", obj_desc->method.param_count);
		acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency);
		acpi_ex_out_pointer ("Semaphore",   obj_desc->method.semaphore);
		acpi_ex_out_integer ("owning_id",   obj_desc->method.owning_id);
		acpi_ex_out_integer ("aml_length",  obj_desc->method.aml_length);
		acpi_ex_out_pointer ("aml_start",   obj_desc->method.aml_start);
		break;


	case ACPI_TYPE_MUTEX:

		acpi_ex_out_integer ("sync_level",  obj_desc->mutex.sync_level);
		acpi_ex_out_pointer ("owner_thread", obj_desc->mutex.owner_thread);
		acpi_ex_out_integer ("acquire_depth", obj_desc->mutex.acquisition_depth);
		acpi_ex_out_pointer ("Semaphore",   obj_desc->mutex.semaphore);
		break;


	case ACPI_TYPE_REGION:

		acpi_ex_out_integer ("space_id",    obj_desc->region.space_id);
		acpi_ex_out_integer ("Flags",       obj_desc->region.flags);
		acpi_ex_out_address ("Address",     obj_desc->region.address);
		acpi_ex_out_integer ("Length",      obj_desc->region.length);
		acpi_ex_out_pointer ("Handler",     obj_desc->region.handler);
		acpi_ex_out_pointer ("Next",        obj_desc->region.next);
		break;


	case ACPI_TYPE_POWER:

		acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level);
		acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order);
		acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify);
		acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify);
		break;


	case ACPI_TYPE_PROCESSOR:

		acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id);
		acpi_ex_out_integer ("Length",      obj_desc->processor.length);
		acpi_ex_out_address ("Address",     (acpi_physical_address) obj_desc->processor.address);
		acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify);
		acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify);
		acpi_ex_out_pointer ("Handler",     obj_desc->processor.handler);
		break;


	case ACPI_TYPE_THERMAL:

		acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify);
		acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify);
		acpi_ex_out_pointer ("Handler",     obj_desc->thermal_zone.handler);
		break;


	case ACPI_TYPE_BUFFER_FIELD:
	case ACPI_TYPE_LOCAL_REGION_FIELD:
	case ACPI_TYPE_LOCAL_BANK_FIELD:
	case ACPI_TYPE_LOCAL_INDEX_FIELD:

		acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags);
		acpi_ex_out_integer ("access_byte_width",obj_desc->common_field.access_byte_width);
		acpi_ex_out_integer ("bit_length",  obj_desc->common_field.bit_length);
		acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset);
		acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset);
		acpi_ex_out_integer ("datum_valid_bits", obj_desc->common_field.datum_valid_bits);
		acpi_ex_out_integer ("end_fld_valid_bits",obj_desc->common_field.end_field_valid_bits);
		acpi_ex_out_integer ("end_buf_valid_bits",obj_desc->common_field.end_buffer_valid_bits);
		acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node);

		switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
		case ACPI_TYPE_BUFFER_FIELD:
			acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj);
			break;

		case ACPI_TYPE_LOCAL_REGION_FIELD:
			acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj);
			break;

		case ACPI_TYPE_LOCAL_BANK_FIELD:
			acpi_ex_out_integer ("Value",   obj_desc->bank_field.value);
			acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj);
			acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj);
			break;

		case ACPI_TYPE_LOCAL_INDEX_FIELD:
			acpi_ex_out_integer ("Value",   obj_desc->index_field.value);
			acpi_ex_out_pointer ("Index",   obj_desc->index_field.index_obj);
			acpi_ex_out_pointer ("Data",    obj_desc->index_field.data_obj);
			break;

		default:
			/* All object types covered above */
			break;
		}
		break;


	case ACPI_TYPE_LOCAL_REFERENCE:

		acpi_ex_out_integer ("target_type", obj_desc->reference.target_type);
		acpi_ex_out_string ("Opcode",       (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name);
		acpi_ex_out_integer ("Offset",      obj_desc->reference.offset);
		acpi_ex_out_pointer ("obj_desc",    obj_desc->reference.object);
		acpi_ex_out_pointer ("Node",        obj_desc->reference.node);
		acpi_ex_out_pointer ("Where",       obj_desc->reference.where);
		break;


	case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:

		acpi_ex_out_integer ("space_id",    obj_desc->address_space.space_id);
		acpi_ex_out_pointer ("Next",        obj_desc->address_space.next);
		acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list);
		acpi_ex_out_pointer ("Node",        obj_desc->address_space.node);
		acpi_ex_out_pointer ("Context",     obj_desc->address_space.context);
		break;


	case ACPI_TYPE_LOCAL_NOTIFY:

		acpi_ex_out_pointer ("Node",        obj_desc->notify.node);
		acpi_ex_out_pointer ("Context",     obj_desc->notify.context);
		break;


	case ACPI_TYPE_LOCAL_ALIAS:
	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
	case ACPI_TYPE_LOCAL_EXTRA:
	case ACPI_TYPE_LOCAL_DATA:
	default:

		acpi_os_printf (
			"ex_dump_object_descriptor: Display not implemented for object type %s\n",
			acpi_ut_get_object_type_name (obj_desc));
		break;
	}

	return_VOID;
}
Example #15
0
acpi_status
acpi_ns_lookup(union acpi_generic_state *scope_info,
               char *pathname,
               acpi_object_type type,
               acpi_interpreter_mode interpreter_mode,
               u32 flags,
               struct acpi_walk_state *walk_state,
               struct acpi_namespace_node **return_node)
{
    acpi_status status;
    char *path = pathname;
    struct acpi_namespace_node *prefix_node;
    struct acpi_namespace_node *current_node = NULL;
    struct acpi_namespace_node *this_node = NULL;
    u32 num_segments;
    u32 num_carats;
    acpi_name simple_name;
    acpi_object_type type_to_check_for;
    acpi_object_type this_search_type;
    u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
    u32 local_flags;

    ACPI_FUNCTION_TRACE(ns_lookup);

    if (!return_node) {
        return_ACPI_STATUS(AE_BAD_PARAMETER);
    }

    local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT);
    *return_node = ACPI_ENTRY_NOT_FOUND;
    acpi_gbl_ns_lookup_count++;

    if (!acpi_gbl_root_node) {
        return_ACPI_STATUS(AE_NO_NAMESPACE);
    }

    /* Get the prefix scope. A null scope means use the root scope */

    if ((!scope_info) || (!scope_info->scope.node)) {
        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                          "Null scope prefix, using root node (%p)\n",
                          acpi_gbl_root_node));

        prefix_node = acpi_gbl_root_node;
    } else {
        prefix_node = scope_info->scope.node;
        if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
                ACPI_DESC_TYPE_NAMED) {
            ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
                        prefix_node,
                        acpi_ut_get_descriptor_name(prefix_node)));
            return_ACPI_STATUS(AE_AML_INTERNAL);
        }

        if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
            /*
             * This node might not be a actual "scope" node (such as a
             * Device/Method, etc.)  It could be a Package or other object
             * node. Backup up the tree to find the containing scope node.
             */
            while (!acpi_ns_opens_scope(prefix_node->type) &&
                    prefix_node->type != ACPI_TYPE_ANY) {
                prefix_node = prefix_node->parent;
            }
        }
    }

    /* Save type. TBD: may be no longer necessary */

    type_to_check_for = type;

    /*
     * Begin examination of the actual pathname
     */
    if (!pathname) {

        /* A Null name_path is allowed and refers to the root */

        num_segments = 0;
        this_node = acpi_gbl_root_node;
        path = "";

        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                          "Null Pathname (Zero segments), Flags=%X\n",
                          flags));
    } else {
        /*
         * Name pointer is valid (and must be in internal name format)
         *
         * Check for scope prefixes:
         *
         * As represented in the AML stream, a namepath consists of an
         * optional scope prefix followed by a name segment part.
         *
         * If present, the scope prefix is either a Root Prefix (in
         * which case the name is fully qualified), or one or more
         * Parent Prefixes (in which case the name's scope is relative
         * to the current scope).
         */
        if (*path == (u8) AML_ROOT_PREFIX) {

            /* Pathname is fully qualified, start from the root */

            this_node = acpi_gbl_root_node;
            search_parent_flag = ACPI_NS_NO_UPSEARCH;

            /* Point to name segment part */

            path++;

            ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                              "Path is absolute from root [%p]\n",
                              this_node));
        } else {
            /* Pathname is relative to current scope, start there */

            ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                              "Searching relative to prefix scope [%4.4s] (%p)\n",
                              acpi_ut_get_node_name(prefix_node),
                              prefix_node));

            /*
             * Handle multiple Parent Prefixes (carat) by just getting
             * the parent node for each prefix instance.
             */
            this_node = prefix_node;
            num_carats = 0;
            while (*path == (u8) AML_PARENT_PREFIX) {

                /* Name is fully qualified, no search rules apply */

                search_parent_flag = ACPI_NS_NO_UPSEARCH;

                /*
                 * Point past this prefix to the name segment
                 * part or the next Parent Prefix
                 */
                path++;

                /* Backup to the parent node */

                num_carats++;
                this_node = this_node->parent;
                if (!this_node) {

                    /* Current scope has no parent scope */

                    ACPI_ERROR((AE_INFO,
                                "ACPI path has too many parent prefixes (^) "
                                "- reached beyond root node"));
                    return_ACPI_STATUS(AE_NOT_FOUND);
                }
            }

            if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
                ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                                  "Search scope is [%4.4s], path has %d carat(s)\n",
                                  acpi_ut_get_node_name
                                  (this_node), num_carats));
            }
        }

        /*
         * Determine the number of ACPI name segments in this pathname.
         *
         * The segment part consists of either:
         *  - A Null name segment (0)
         *  - A dual_name_prefix followed by two 4-byte name segments
         *  - A multi_name_prefix followed by a byte indicating the
         *      number of segments and the segments themselves.
         *  - A single 4-byte name segment
         *
         * Examine the name prefix opcode, if any, to determine the number of
         * segments.
         */
        switch (*path) {
        case 0:
            /*
             * Null name after a root or parent prefixes. We already
             * have the correct target node and there are no name segments.
             */
            num_segments = 0;
            type = this_node->type;

            ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                              "Prefix-only Pathname (Zero name segments), Flags=%X\n",
                              flags));
            break;

        case AML_DUAL_NAME_PREFIX:

            /* More than one name_seg, search rules do not apply */

            search_parent_flag = ACPI_NS_NO_UPSEARCH;

            /* Two segments, point to first name segment */

            num_segments = 2;
            path++;

            ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                              "Dual Pathname (2 segments, Flags=%X)\n",
                              flags));
            break;

        case AML_MULTI_NAME_PREFIX_OP:

            /* More than one name_seg, search rules do not apply */

            search_parent_flag = ACPI_NS_NO_UPSEARCH;

            /* Extract segment count, point to first name segment */

            path++;
            num_segments = (u32) (u8) * path;
            path++;

            ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                              "Multi Pathname (%d Segments, Flags=%X)\n",
                              num_segments, flags));
            break;

        default:
            /*
             * Not a Null name, no Dual or Multi prefix, hence there is
             * only one name segment and Pathname is already pointing to it.
             */
            num_segments = 1;

            ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                              "Simple Pathname (1 segment, Flags=%X)\n",
                              flags));
            break;
        }

        ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
    }

    /*
     * Search namespace for each segment of the name. Loop through and
     * verify (or add to the namespace) each name segment.
     *
     * The object type is significant only at the last name
     * segment. (We don't care about the types along the path, only
     * the type of the final target object.)
     */
    this_search_type = ACPI_TYPE_ANY;
    current_node = this_node;
    while (num_segments && current_node) {
        num_segments--;
        if (!num_segments) {

            /* This is the last segment, enable typechecking */

            this_search_type = type;

            /*
             * Only allow automatic parent search (search rules) if the caller
             * requested it AND we have a single, non-fully-qualified name_seg
             */
            if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
                    (flags & ACPI_NS_SEARCH_PARENT)) {
                local_flags |= ACPI_NS_SEARCH_PARENT;
            }

            /* Set error flag according to caller */

            if (flags & ACPI_NS_ERROR_IF_FOUND) {
                local_flags |= ACPI_NS_ERROR_IF_FOUND;
            }
        }

        /* Extract one ACPI name from the front of the pathname */

        ACPI_MOVE_32_TO_32(&simple_name, path);

        /* Try to find the single (4 character) ACPI name */

        status =
            acpi_ns_search_and_enter(simple_name, walk_state,
                                     current_node, interpreter_mode,
                                     this_search_type, local_flags,
                                     &this_node);
        if (ACPI_FAILURE(status)) {
            if (status == AE_NOT_FOUND) {

                /* Name not found in ACPI namespace */

                ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                                  "Name [%4.4s] not found in scope [%4.4s] %p\n",
                                  (char *)&simple_name,
                                  (char *)&current_node->name,
                                  current_node));
            }

            *return_node = this_node;
            return_ACPI_STATUS(status);
        }

        /* More segments to follow? */

        if (num_segments > 0) {
            /*
             * If we have an alias to an object that opens a scope (such as a
             * device or processor), we need to dereference the alias here so
             * that we can access any children of the original node (via the
             * remaining segments).
             */
            if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
                if (!this_node->object) {
                    return_ACPI_STATUS(AE_NOT_EXIST);
                }

                if (acpi_ns_opens_scope
                        (((struct acpi_namespace_node *)
                          this_node->object)->type)) {
                    this_node =
                        (struct acpi_namespace_node *)
                        this_node->object;
                }
            }
        }

        /* Special handling for the last segment (num_segments == 0) */

        else {
            /*
             * Sanity typecheck of the target object:
             *
             * If 1) This is the last segment (num_segments == 0)
             *    2) And we are looking for a specific type
             *       (Not checking for TYPE_ANY)
             *    3) Which is not an alias
             *    4) Which is not a local type (TYPE_SCOPE)
             *    5) And the type of target object is known (not TYPE_ANY)
             *    6) And target object does not match what we are looking for
             *
             * Then we have a type mismatch. Just warn and ignore it.
             */
            if ((type_to_check_for != ACPI_TYPE_ANY) &&
                    (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
                    (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
                    && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
                    && (this_node->type != ACPI_TYPE_ANY)
                    && (this_node->type != type_to_check_for)) {

                /* Complain about a type mismatch */

                ACPI_WARNING((AE_INFO,
                              "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
                              ACPI_CAST_PTR(char, &simple_name),
                              acpi_ut_get_type_name(this_node->
                                                    type),
                              acpi_ut_get_type_name
                              (type_to_check_for)));
            }

            /*
             * If this is the last name segment and we are not looking for a
             * specific type, but the type of found object is known, use that
             * type to (later) see if it opens a scope.
             */
            if (type == ACPI_TYPE_ANY) {
                type = this_node->type;
            }
        }

        /* Point to next name segment and make this node current */

        path += ACPI_NAME_SIZE;
        current_node = this_node;
    }
Example #16
0
static ACPI_STATUS
AcpiUtGetSimpleObjectSize (
    ACPI_OPERAND_OBJECT     *InternalObject,
    ACPI_SIZE               *ObjLength)
{
    ACPI_SIZE               Length;
    ACPI_SIZE               Size;
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject);


    /* Start with the length of the (external) Acpi object */

    Length = sizeof (ACPI_OBJECT);

    /* A NULL object is allowed, can be a legal uninitialized package element */

    if (!InternalObject)
    {
        /*
         * Object is NULL, just return the length of ACPI_OBJECT
         * (A NULL ACPI_OBJECT is an object of all zeroes.)
         */
        *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
        return_ACPI_STATUS (AE_OK);
    }

    /* A Namespace Node should never appear here */

    if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED)
    {
        /* A namespace node should never get here */

        return_ACPI_STATUS (AE_AML_INTERNAL);
    }

    /*
     * The final length depends on the object type
     * Strings and Buffers are packed right up against the parent object and
     * must be accessed bytewise or there may be alignment problems on
     * certain processors
     */
    switch (InternalObject->Common.Type)
    {
    case ACPI_TYPE_STRING:

        Length += (ACPI_SIZE) InternalObject->String.Length + 1;
        break;

    case ACPI_TYPE_BUFFER:

        Length += (ACPI_SIZE) InternalObject->Buffer.Length;
        break;

    case ACPI_TYPE_INTEGER:
    case ACPI_TYPE_PROCESSOR:
    case ACPI_TYPE_POWER:

        /* No extra data for these types */

        break;

    case ACPI_TYPE_LOCAL_REFERENCE:

        switch (InternalObject->Reference.Class)
        {
        case ACPI_REFCLASS_NAME:
            /*
             * Get the actual length of the full pathname to this object.
             * The reference will be converted to the pathname to the object
             */
            Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node);
            if (!Size)
            {
                return_ACPI_STATUS (AE_BAD_PARAMETER);
            }

            Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size);
            break;

        default:
            /*
             * No other reference opcodes are supported.
             * Notably, Locals and Args are not supported, but this may be
             * required eventually.
             */
            ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
                "unsupported Reference Class [%s] 0x%X in object %p",
                AcpiUtGetReferenceName (InternalObject),
                InternalObject->Reference.Class, InternalObject));
            Status = AE_TYPE;
            break;
        }
        break;

    default:

        ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
            "unsupported type [%s] 0x%X in object %p",
            AcpiUtGetObjectTypeName (InternalObject),
            InternalObject->Common.Type, InternalObject));
        Status = AE_TYPE;
        break;
    }

    /*
     * Account for the space required by the object rounded up to the next
     * multiple of the machine word size. This keeps each object aligned
     * on a machine word boundary. (preventing alignment faults on some
     * machines.)
     */
    *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
    return_ACPI_STATUS (Status);
}
Example #17
0
ACPI_STATUS
AcpiNsDumpOneObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    ACPI_NAMESPACE_NODE     *ThisNode;
    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
    ACPI_OBJECT_TYPE        ObjType;
    ACPI_OBJECT_TYPE        Type;
    UINT32                  BytesToDump;
    UINT32                  DbgLevel;
    UINT32                  i;


    ACPI_FUNCTION_NAME (NsDumpOneObject);


    /* Is output enabled? */

    if (!(AcpiDbgLevel & Info->DebugLevel))
    {
        return (AE_OK);
    }

    if (!ObjHandle)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
        return (AE_OK);
    }

    ThisNode = AcpiNsValidateHandle (ObjHandle);
    if (!ThisNode)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Invalid object handle %p\n",
            ObjHandle));
        return (AE_OK);
    }

    Type = ThisNode->Type;
    Info->Count++;

    /* Check if the owner matches */

    if ((Info->OwnerId != ACPI_OWNER_ID_MAX) &&
        (Info->OwnerId != ThisNode->OwnerId))
    {
        return (AE_OK);
    }

    if (!(Info->DisplayType & ACPI_DISPLAY_SHORT))
    {
        /* Indent the object according to the level */

        AcpiOsPrintf ("%2d%*s", (UINT32) Level - 1, (int) Level * 2, " ");

        /* Check the node type and name */

        if (Type > ACPI_TYPE_LOCAL_MAX)
        {
            ACPI_WARNING ((AE_INFO,
                "Invalid ACPI Object Type 0x%08X", Type));
        }

        AcpiOsPrintf ("%4.4s", AcpiUtGetNodeName (ThisNode));
    }

    /* Now we can print out the pertinent information */

    AcpiOsPrintf (" %-12s %p %2.2X ",
        AcpiUtGetTypeName (Type), ThisNode, ThisNode->OwnerId);

    DbgLevel = AcpiDbgLevel;
    AcpiDbgLevel = 0;
    ObjDesc = AcpiNsGetAttachedObject (ThisNode);
    AcpiDbgLevel = DbgLevel;

    /* Temp nodes are those nodes created by a control method */

    if (ThisNode->Flags & ANOBJ_TEMPORARY)
    {
        AcpiOsPrintf ("(T) ");
    }

    switch (Info->DisplayType & ACPI_DISPLAY_MASK)
    {
    case ACPI_DISPLAY_SUMMARY:

        if (!ObjDesc)
        {
            /* No attached object. Some types should always have an object */

            switch (Type)
            {
            case ACPI_TYPE_INTEGER:
            case ACPI_TYPE_PACKAGE:
            case ACPI_TYPE_BUFFER:
            case ACPI_TYPE_STRING:
            case ACPI_TYPE_METHOD:

                AcpiOsPrintf ("<No attached object>");
                break;

            default:

                break;
            }

            AcpiOsPrintf ("\n");
            return (AE_OK);
        }

        switch (Type)
        {
        case ACPI_TYPE_PROCESSOR:

            AcpiOsPrintf ("ID %02X Len %02X Addr %8.8X%8.8X\n",
                ObjDesc->Processor.ProcId, ObjDesc->Processor.Length,
                ACPI_FORMAT_UINT64 (ObjDesc->Processor.Address));
            break;

        case ACPI_TYPE_DEVICE:

            AcpiOsPrintf ("Notify Object: %p\n", ObjDesc);
            break;

        case ACPI_TYPE_METHOD:

            AcpiOsPrintf ("Args %X Len %.4X Aml %p\n",
                (UINT32) ObjDesc->Method.ParamCount,
                ObjDesc->Method.AmlLength, ObjDesc->Method.AmlStart);
            break;

        case ACPI_TYPE_INTEGER:

            AcpiOsPrintf ("= %8.8X%8.8X\n",
                ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
            break;

        case ACPI_TYPE_PACKAGE:

            if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf ("Elements %.2X\n",
                    ObjDesc->Package.Count);
            }
            else
            {
                AcpiOsPrintf ("[Length not yet evaluated]\n");
            }
            break;

        case ACPI_TYPE_BUFFER:

            if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf ("Len %.2X",
                    ObjDesc->Buffer.Length);

                /* Dump some of the buffer */

                if (ObjDesc->Buffer.Length > 0)
                {
                    AcpiOsPrintf (" =");
                    for (i = 0; (i < ObjDesc->Buffer.Length && i < 12); i++)
                    {
                        AcpiOsPrintf (" %.2hX", ObjDesc->Buffer.Pointer[i]);
                    }
                }
                AcpiOsPrintf ("\n");
            }
            else
            {
                AcpiOsPrintf ("[Length not yet evaluated]\n");
            }
            break;

        case ACPI_TYPE_STRING:

            AcpiOsPrintf ("Len %.2X ", ObjDesc->String.Length);
            AcpiUtPrintString (ObjDesc->String.Pointer, 80);
            AcpiOsPrintf ("\n");
            break;

        case ACPI_TYPE_REGION:

            AcpiOsPrintf ("[%s]",
                AcpiUtGetRegionName (ObjDesc->Region.SpaceId));
            if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf (" Addr %8.8X%8.8X Len %.4X\n",
                    ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
                    ObjDesc->Region.Length);
            }
            else
            {
                AcpiOsPrintf (" [Address/Length not yet evaluated]\n");
            }
            break;

        case ACPI_TYPE_LOCAL_REFERENCE:

            AcpiOsPrintf ("[%s]\n", AcpiUtGetReferenceName (ObjDesc));
            break;

        case ACPI_TYPE_BUFFER_FIELD:

            if (ObjDesc->BufferField.BufferObj &&
                ObjDesc->BufferField.BufferObj->Buffer.Node)
            {
                AcpiOsPrintf ("Buf [%4.4s]",
                    AcpiUtGetNodeName (
                        ObjDesc->BufferField.BufferObj->Buffer.Node));
            }
            break;

        case ACPI_TYPE_LOCAL_REGION_FIELD:

            AcpiOsPrintf ("Rgn [%4.4s]",
                AcpiUtGetNodeName (
                    ObjDesc->CommonField.RegionObj->Region.Node));
            break;

        case ACPI_TYPE_LOCAL_BANK_FIELD:

            AcpiOsPrintf ("Rgn [%4.4s] Bnk [%4.4s]",
                AcpiUtGetNodeName (
                    ObjDesc->CommonField.RegionObj->Region.Node),
                AcpiUtGetNodeName (
                    ObjDesc->BankField.BankObj->CommonField.Node));
            break;

        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            AcpiOsPrintf ("Idx [%4.4s] Dat [%4.4s]",
                AcpiUtGetNodeName (
                    ObjDesc->IndexField.IndexObj->CommonField.Node),
                AcpiUtGetNodeName (
                    ObjDesc->IndexField.DataObj->CommonField.Node));
            break;

        case ACPI_TYPE_LOCAL_ALIAS:
        case ACPI_TYPE_LOCAL_METHOD_ALIAS:

            AcpiOsPrintf ("Target %4.4s (%p)\n",
                AcpiUtGetNodeName (ObjDesc), ObjDesc);
            break;

        default:

            AcpiOsPrintf ("Object %p\n", ObjDesc);
            break;
        }

        /* Common field handling */

        switch (Type)
        {
        case ACPI_TYPE_BUFFER_FIELD:
        case ACPI_TYPE_LOCAL_REGION_FIELD:
        case ACPI_TYPE_LOCAL_BANK_FIELD:
        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            AcpiOsPrintf (" Off %.3X Len %.2X Acc %.2hd\n",
                (ObjDesc->CommonField.BaseByteOffset * 8)
                    + ObjDesc->CommonField.StartFieldBitOffset,
                ObjDesc->CommonField.BitLength,
                ObjDesc->CommonField.AccessByteWidth);
            break;

        default:

            break;
        }
        break;

    case ACPI_DISPLAY_OBJECTS:

        AcpiOsPrintf ("O:%p", ObjDesc);
        if (!ObjDesc)
        {
            /* No attached object, we are done */

            AcpiOsPrintf ("\n");
            return (AE_OK);
        }

        AcpiOsPrintf ("(R%u)", ObjDesc->Common.ReferenceCount);

        switch (Type)
        {
        case ACPI_TYPE_METHOD:

            /* Name is a Method and its AML offset/length are set */

            AcpiOsPrintf (" M:%p-%X\n", ObjDesc->Method.AmlStart,
                ObjDesc->Method.AmlLength);
            break;

        case ACPI_TYPE_INTEGER:

            AcpiOsPrintf (" I:%8.8X8.8%X\n",
                ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
            break;

        case ACPI_TYPE_STRING:

            AcpiOsPrintf (" S:%p-%X\n", ObjDesc->String.Pointer,
                ObjDesc->String.Length);
            break;

        case ACPI_TYPE_BUFFER:

            AcpiOsPrintf (" B:%p-%X\n", ObjDesc->Buffer.Pointer,
                ObjDesc->Buffer.Length);
            break;

        default:

            AcpiOsPrintf ("\n");
            break;
        }
        break;

    default:
        AcpiOsPrintf ("\n");
        break;
    }

    /* If debug turned off, done */

    if (!(AcpiDbgLevel & ACPI_LV_VALUES))
    {
        return (AE_OK);
    }

    /* If there is an attached object, display it */

    DbgLevel = AcpiDbgLevel;
    AcpiDbgLevel = 0;
    ObjDesc = AcpiNsGetAttachedObject (ThisNode);
    AcpiDbgLevel = DbgLevel;

    /* Dump attached objects */

    while (ObjDesc)
    {
        ObjType = ACPI_TYPE_INVALID;
        AcpiOsPrintf ("Attached Object %p: ", ObjDesc);

        /* Decode the type of attached object and dump the contents */

        switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
        {
        case ACPI_DESC_TYPE_NAMED:

            AcpiOsPrintf ("(Ptr to Node)\n");
            BytesToDump = sizeof (ACPI_NAMESPACE_NODE);
            ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);
            break;

        case ACPI_DESC_TYPE_OPERAND:

            ObjType = ObjDesc->Common.Type;

            if (ObjType > ACPI_TYPE_LOCAL_MAX)
            {
                AcpiOsPrintf (
                    "(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
                    ObjType);

                BytesToDump = 32;
            }
            else
            {
                AcpiOsPrintf (
                    "(Pointer to ACPI Object type %.2X [%s])\n",
                    ObjType, AcpiUtGetTypeName (ObjType));

                BytesToDump = sizeof (ACPI_OPERAND_OBJECT);
            }

            ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);
            break;

        default:

            break;
        }

        /* If value is NOT an internal object, we are done */

        if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
        {
            goto Cleanup;
        }

        /* Valid object, get the pointer to next level, if any */

        switch (ObjType)
        {
        case ACPI_TYPE_BUFFER:
        case ACPI_TYPE_STRING:
            /*
             * NOTE: takes advantage of common fields between string/buffer
             */
            BytesToDump = ObjDesc->String.Length;
            ObjDesc = (void *) ObjDesc->String.Pointer;

            AcpiOsPrintf ("(Buffer/String pointer %p length %X)\n",
                ObjDesc, BytesToDump);
            ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);
            goto Cleanup;

        case ACPI_TYPE_BUFFER_FIELD:

            ObjDesc = (ACPI_OPERAND_OBJECT *) ObjDesc->BufferField.BufferObj;
            break;

        case ACPI_TYPE_PACKAGE:

            ObjDesc = (void *) ObjDesc->Package.Elements;
            break;

        case ACPI_TYPE_METHOD:

            ObjDesc = (void *) ObjDesc->Method.AmlStart;
            break;

        case ACPI_TYPE_LOCAL_REGION_FIELD:

            ObjDesc = (void *) ObjDesc->Field.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_BANK_FIELD:

            ObjDesc = (void *) ObjDesc->BankField.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            ObjDesc = (void *) ObjDesc->IndexField.IndexObj;
            break;

        default:

            goto Cleanup;
        }

        ObjType = ACPI_TYPE_INVALID;   /* Terminate loop after next pass */
    }

Cleanup:
    AcpiOsPrintf ("\n");
    return (AE_OK);
}
Example #18
0
acpi_status
acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
			  void *target_object,
			  acpi_pkg_callback walk_callback, void *context)
{
	acpi_status status = AE_OK;
	union acpi_generic_state *state_list = NULL;
	union acpi_generic_state *state;
	u32 this_index;
	union acpi_operand_object *this_source_obj;

	ACPI_FUNCTION_TRACE(ut_walk_package_tree);

	state = acpi_ut_create_pkg_state(source_object, target_object, 0);
	if (!state) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	while (state) {

		/* Get one element of the package */

		this_index = state->pkg.index;
		this_source_obj = (union acpi_operand_object *)
		    state->pkg.source_object->package.elements[this_index];

		/*
		 * Check for:
		 * 1) An uninitialized package element. It is completely
		 *    legal to declare a package and leave it uninitialized
		 * 2) Not an internal object - can be a namespace node instead
		 * 3) Any type other than a package. Packages are handled in else
		 *    case below.
		 */
		if ((!this_source_obj) ||
		    (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
		     ACPI_DESC_TYPE_OPERAND) ||
		    (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
			status =
			    walk_callback(ACPI_COPY_TYPE_SIMPLE,
					  this_source_obj, state, context);
			if (ACPI_FAILURE(status)) {
				return_ACPI_STATUS(status);
			}

			state->pkg.index++;
			while (state->pkg.index >=
			       state->pkg.source_object->package.count) {
				/*
				 * We've handled all of the objects at this level,  This means
				 * that we have just completed a package. That package may
				 * have contained one or more packages itself.
				 *
				 * Delete this state and pop the previous state (package).
				 */
				acpi_ut_delete_generic_state(state);
				state = acpi_ut_pop_generic_state(&state_list);

				/* Finished when there are no more states */

				if (!state) {
					/*
					 * We have handled all of the objects in the top level
					 * package just add the length of the package objects
					 * and exit
					 */
					return_ACPI_STATUS(AE_OK);
				}

				/*
				 * Go back up a level and move the index past the just
				 * completed package object.
				 */
				state->pkg.index++;
			}
		} else {
			/* This is a subobject of type package */

			status =
			    walk_callback(ACPI_COPY_TYPE_PACKAGE,
					  this_source_obj, state, context);
			if (ACPI_FAILURE(status)) {
				return_ACPI_STATUS(status);
			}

			/*
			 * Push the current state and create a new one
			 * The callback above returned a new target package object.
			 */
			acpi_ut_push_generic_state(&state_list, state);
			state =
			    acpi_ut_create_pkg_state(this_source_obj,
						     state->pkg.this_target_obj,
						     0);
			if (!state) {

				/* Free any stacked Update State objects */

				while (state_list) {
					state =
					    acpi_ut_pop_generic_state
					    (&state_list);
					acpi_ut_delete_generic_state(state);
				}
				return_ACPI_STATUS(AE_NO_MEMORY);
			}
		}
	}

	/* We should never get here */

	return_ACPI_STATUS(AE_AML_INTERNAL);
}
Example #19
0
void
AcpiExDoDebugObject (
    ACPI_OPERAND_OBJECT     *SourceDesc,
    UINT32                  Level,
    UINT32                  Index)
{
    UINT32                  i;


    ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);


    /* Output must be enabled via the DebugObject global or the DbgLevel */

    if (!AcpiGbl_EnableAmlDebugObject &&
        !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT))
    {
        return_VOID;
    }

    /*
     * Print line header as long as we are not in the middle of an
     * object display
     */
    if (!((Level > 0) && Index == 0))
    {
        AcpiOsPrintf ("[ACPI Debug] %*s", Level, " ");
    }

    /* Display the index for package output only */

    if (Index > 0)
    {
       AcpiOsPrintf ("(%.2u) ", Index-1);
    }

    if (!SourceDesc)
    {
        AcpiOsPrintf ("[Null Object]\n");
        return_VOID;
    }

    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
    {
        AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc));

        if (!AcpiUtValidInternalObject (SourceDesc))
        {
           AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc);
           return_VOID;
        }
    }
    else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
    {
        AcpiOsPrintf ("%s: %p\n",
            AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
            SourceDesc);
        return_VOID;
    }
    else
    {
        return_VOID;
    }

    /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */

    switch (SourceDesc->Common.Type)
    {
    case ACPI_TYPE_INTEGER:

        /* Output correct integer width */

        if (AcpiGbl_IntegerByteWidth == 4)
        {
            AcpiOsPrintf ("0x%8.8X\n",
                (UINT32) SourceDesc->Integer.Value);
        }
        else
        {
            AcpiOsPrintf ("0x%8.8X%8.8X\n",
                ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value));
        }
        break;

    case ACPI_TYPE_BUFFER:

        AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
        AcpiUtDumpBuffer (SourceDesc->Buffer.Pointer,
            (SourceDesc->Buffer.Length < 256) ?
                SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY, 0);
        break;

    case ACPI_TYPE_STRING:

        AcpiOsPrintf ("[0x%.2X] \"%s\"\n",
            SourceDesc->String.Length, SourceDesc->String.Pointer);
        break;

    case ACPI_TYPE_PACKAGE:

        AcpiOsPrintf ("[Contains 0x%.2X Elements]\n",
            SourceDesc->Package.Count);

        /* Output the entire contents of the package */

        for (i = 0; i < SourceDesc->Package.Count; i++)
        {
            AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
                Level+4, i+1);
        }
        break;

    case ACPI_TYPE_LOCAL_REFERENCE:

        AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc));

        /* Decode the reference */

        switch (SourceDesc->Reference.Class)
        {
        case ACPI_REFCLASS_INDEX:

            AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value);
            break;

        case ACPI_REFCLASS_TABLE:

            /* Case for DdbHandle */

            AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value);
            return_VOID;

        default:
            break;
        }

        AcpiOsPrintf ("  ");

        /* Check for valid node first, then valid object */

        if (SourceDesc->Reference.Node)
        {
            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
                    ACPI_DESC_TYPE_NAMED)
            {
                AcpiOsPrintf (" %p - Not a valid namespace node\n",
                    SourceDesc->Reference.Node);
            }
            else
            {
                AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node,
                    (SourceDesc->Reference.Node)->Name.Ascii);

                switch ((SourceDesc->Reference.Node)->Type)
                {
                /* These types have no attached object */

                case ACPI_TYPE_DEVICE:
                    AcpiOsPrintf ("Device\n");
                    break;

                case ACPI_TYPE_THERMAL:
                    AcpiOsPrintf ("Thermal Zone\n");
                    break;

                default:
                    AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
                        Level+4, 0);
                    break;
                }
            }
        }
        else if (SourceDesc->Reference.Object)
        {
            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
                    ACPI_DESC_TYPE_NAMED)
            {
                AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
                    SourceDesc->Reference.Object)->Object,
                    Level+4, 0);
            }
            else
            {
                AcpiExDoDebugObject (SourceDesc->Reference.Object,
                    Level+4, 0);
            }
        }
        break;

    default:

        AcpiOsPrintf ("%p\n", SourceDesc);
        break;
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
    return_VOID;
}
Example #20
0
acpi_status
acpi_ns_attach_object (
	struct acpi_namespace_node      *node,
	union acpi_operand_object       *object,
	acpi_object_type                type)
{
	union acpi_operand_object       *obj_desc;
	union acpi_operand_object       *last_obj_desc;
	acpi_object_type                object_type = ACPI_TYPE_ANY;


	ACPI_FUNCTION_TRACE ("ns_attach_object");


	/*
	 * Parameter validation
	 */
	if (!node) {
		/* Invalid handle */

		ACPI_REPORT_ERROR (("ns_attach_object: Null named_obj handle\n"));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	if (!object && (ACPI_TYPE_ANY != type)) {
		/* Null object */

		ACPI_REPORT_ERROR (("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
		/* Not a name handle */

		ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle %p [%s]\n",
				node, acpi_ut_get_descriptor_name (node)));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/* Check if this object is already attached */

	if (node->object == object) {
		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj %p already installed in name_obj %p\n",
			object, node));

		return_ACPI_STATUS (AE_OK);
	}

	/* If null object, we will just install it */

	if (!object) {
		obj_desc   = NULL;
		object_type = ACPI_TYPE_ANY;
	}

	/*
	 * If the source object is a namespace Node with an attached object,
	 * we will use that (attached) object
	 */
	else if ((ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) &&
			((struct acpi_namespace_node *) object)->object) {
		/*
		 * Value passed is a name handle and that name has a
		 * non-null value.  Use that name's value and type.
		 */
		obj_desc   = ((struct acpi_namespace_node *) object)->object;
		object_type = ((struct acpi_namespace_node *) object)->type;
	}

	/*
	 * Otherwise, we will use the parameter object, but we must type
	 * it first
	 */
	else {
		obj_desc = (union acpi_operand_object   *) object;

		/* Use the given type */

		object_type = type;
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
		obj_desc, node, acpi_ut_get_node_name (node)));

	/* Detach an existing attached object if present */

	if (node->object) {
		acpi_ns_detach_object (node);
	}

	if (obj_desc) {
		/*
		 * Must increment the new value's reference count
		 * (if it is an internal object)
		 */
		acpi_ut_add_reference (obj_desc);

		/*
		 * Handle objects with multiple descriptors - walk
		 * to the end of the descriptor list
		 */
		last_obj_desc = obj_desc;
		while (last_obj_desc->common.next_object) {
			last_obj_desc = last_obj_desc->common.next_object;
		}

		/* Install the object at the front of the object list */

		last_obj_desc->common.next_object = node->object;
	}

	node->type     = (u8) object_type;
	node->object   = obj_desc;

	return_ACPI_STATUS (AE_OK);
}
Example #21
0
static ACPI_STATUS
AcpiNsCheckObjectType (
    ACPI_PREDEFINED_DATA        *Data,
    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
    UINT32                      ExpectedBtypes,
    UINT32                      PackageIndex)
{
    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
    ACPI_STATUS                 Status = AE_OK;
    UINT32                      ReturnBtype;
    char                        TypeBuffer[48]; /* Room for 5 types */


    /*
     * If we get a NULL ReturnObject here, it is a NULL package element,
     * and this is always an error.
     */
    if (!ReturnObject)
    {
        goto TypeErrorExit;
    }

    /* A Namespace node should not get here, but make sure */

    if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
    {
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
            "Invalid return type - Found a Namespace node [%4.4s] type %s",
            ReturnObject->Node.Name.Ascii,
            AcpiUtGetTypeName (ReturnObject->Node.Type)));
        return (AE_AML_OPERAND_TYPE);
    }

    /*
     * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
     * The bitmapped type allows multiple possible return types.
     *
     * Note, the cases below must handle all of the possible types returned
     * from all of the predefined names (including elements of returned
     * packages)
     */
    switch (ReturnObject->Common.Type)
    {
    case ACPI_TYPE_INTEGER:
        ReturnBtype = ACPI_RTYPE_INTEGER;
        break;

    case ACPI_TYPE_BUFFER:
        ReturnBtype = ACPI_RTYPE_BUFFER;
        break;

    case ACPI_TYPE_STRING:
        ReturnBtype = ACPI_RTYPE_STRING;
        break;

    case ACPI_TYPE_PACKAGE:
        ReturnBtype = ACPI_RTYPE_PACKAGE;
        break;

    case ACPI_TYPE_LOCAL_REFERENCE:
        ReturnBtype = ACPI_RTYPE_REFERENCE;
        break;

    default:
        /* Not one of the supported objects, must be incorrect */

        goto TypeErrorExit;
    }

    /* Is the object one of the expected types? */

    if (!(ReturnBtype & ExpectedBtypes))
    {
        /* Type mismatch -- attempt repair of the returned object */

        Status = AcpiNsRepairObject (Data, ExpectedBtypes,
                    PackageIndex, ReturnObjectPtr);
        if (ACPI_SUCCESS (Status))
        {
            return (AE_OK); /* Repair was successful */
        }
        goto TypeErrorExit;
    }

    /* For reference objects, check that the reference type is correct */

    if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
    {
        Status = AcpiNsCheckReference (Data, ReturnObject);
    }

    return (Status);


TypeErrorExit:

    /* Create a string with all expected types for this predefined object */

    AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);

    if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
    {
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
            "Return type mismatch - found %s, expected %s",
            AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
    }
    else
    {
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
            "Return Package type mismatch at index %u - "
            "found %s, expected %s", PackageIndex,
            AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
    }

    return (AE_AML_OPERAND_TYPE);
}
Example #22
0
static ACPI_STATUS
NsDoOneNamespaceObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_PARSE_OBJECT       *Op;


    AslGbl_NumNamespaceObjects++;

    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
        AslGbl_NumNamespaceObjects, Level, (Level * 3), " ",
        &Node->Name, AcpiUtGetTypeName (Node->Type));

    Op = Node->Op;
    ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);

    if (!Op)
    {
        FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
        return (AE_OK);
    }


    if ((ObjDesc) &&
        (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
    {
        switch (Node->Type)
        {
        case ACPI_TYPE_INTEGER:

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "       [Initial Value   0x%8.8X%8.8X]",
                ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
            break;

        case ACPI_TYPE_STRING:

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "        [Initial Value   \"%s\"]",
                ObjDesc->String.Pointer);
            break;

        default:

            /* Nothing to do for other types */

            break;
        }

    }
    else
    {
        switch (Node->Type)
        {
        case ACPI_TYPE_INTEGER:

            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
            {
                Op = Op->Asl.Child;
            }

            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
            {
                Op = Op->Asl.Next;
            }

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "       [Initial Value   0x%8.8X%8.8X]",
                ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
            break;

        case ACPI_TYPE_STRING:

            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
            {
                Op = Op->Asl.Child;
            }

            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
            {
                Op = Op->Asl.Next;
            }

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "        [Initial Value   \"%s\"]",
                Op->Asl.Value.String);
            break;

        case ACPI_TYPE_LOCAL_REGION_FIELD:

            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
            {
                Op = Op->Asl.Child;
            }

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "   [Offset 0x%04X   Length 0x%04X bits]",
                Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
            break;

        case ACPI_TYPE_BUFFER_FIELD:

            switch (Op->Asl.ParseOpcode)
            {
            case PARSEOP_CREATEBYTEFIELD:

                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
                break;

            case PARSEOP_CREATEDWORDFIELD:

                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
                break;

            case PARSEOP_CREATEQWORDFIELD:

                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
                break;

            case PARSEOP_CREATEWORDFIELD:

                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
                break;

            case PARSEOP_CREATEBITFIELD:

                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
                break;

            case PARSEOP_CREATEFIELD:

                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
                break;

            default:

                break;

            }
            break;

        case ACPI_TYPE_PACKAGE:

            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
            {
                Op = Op->Asl.Child;
            }

            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
            {
                Op = Op->Asl.Next;
            }

            Op = Op->Asl.Child;

            if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
                (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
            {
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                    "       [Initial Length  0x%.2X elements]",
                    Op->Asl.Value.Integer);
            }
            break;

        case ACPI_TYPE_BUFFER:

            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
            {
                Op = Op->Asl.Child;
            }

            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
            {
                Op = Op->Asl.Next;
            }

            Op = Op->Asl.Child;

            if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
            {
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                    "        [Initial Length  0x%.2X bytes]",
                    Op->Asl.Value.Integer);
            }
            break;

        case ACPI_TYPE_METHOD:

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "        [Code Length     0x%.4X bytes]",
                Op->Asl.AmlSubtreeLength);
            break;

        case ACPI_TYPE_LOCAL_RESOURCE:

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "  [Desc Offset     0x%.4X Bytes]", Node->Value);
            break;

        case ACPI_TYPE_LOCAL_RESOURCE_FIELD:

            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                "   [Field Offset    0x%.4X Bits 0x%.4X Bytes] ",
                Node->Value, Node->Value / 8);

            if (Node->Flags & ANOBJ_IS_REFERENCED)
            {
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                    "Referenced");
            }
            else
            {
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
                    "Name not referenced");
            }
            break;

        default:

            /* Nothing to do for other types */

            break;
        }
    }

    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
    return (AE_OK);
}
Example #23
0
ACPI_STATUS
AcpiExUnloadTable (
    ACPI_OPERAND_OBJECT     *DdbHandle)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_OPERAND_OBJECT     *TableDesc = DdbHandle;
    UINT32                  TableIndex;
    ACPI_TABLE_HEADER       *Table;


    ACPI_FUNCTION_TRACE (ExUnloadTable);


    /*
     * Temporarily emit a warning so that the ASL for the machine can be
     * hopefully obtained. This is to say that the Unload() operator is
     * extremely rare if not completely unused.
     */
    ACPI_WARNING ((AE_INFO,
        "Received request to unload an ACPI table"));

    /*
     * Validate the handle
     * Although the handle is partially validated in AcpiExReconfiguration()
     * when it calls AcpiExResolveOperands(), the handle is more completely
     * validated here.
     *
     * Handle must be a valid operand object of type reference. Also, the
     * DdbHandle must still be marked valid (table has not been previously
     * unloaded)
     */
    if ((!DdbHandle) ||
        (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) ||
        (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) ||
        (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID)))
    {
        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }

    /* Get the table index from the DdbHandle */

    TableIndex = TableDesc->Reference.Value;

    /* Ensure the table is still loaded */

    if (!AcpiTbIsTableLoaded (TableIndex))
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /* Invoke table handler if present */

    if (AcpiGbl_TableHandler)
    {
        Status = AcpiGetTableByIndex (TableIndex, &Table);
        if (ACPI_SUCCESS (Status))
        {
            (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
                AcpiGbl_TableHandlerContext);
        }
    }

    /* Delete the portion of the namespace owned by this table */

    Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    (void) AcpiTbReleaseOwnerId (TableIndex);
    AcpiTbSetTableLoadedFlag (TableIndex, FALSE);

    /*
     * Invalidate the handle. We do this because the handle may be stored
     * in a named object and may not be actually deleted until much later.
     */
    DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID;
    return_ACPI_STATUS (AE_OK);
}
Example #24
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_evaluate_object
 *
 * PARAMETERS:  handle              - Object handle (optional)
 *              pathname            - Object pathname (optional)
 *              external_params     - List of parameters to pass to method,
 *                                    terminated by NULL. May be NULL
 *                                    if no parameters are being passed.
 *              return_buffer       - Where to put method's return value (if
 *                                    any). If NULL, no value is returned.
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Find and evaluate the given object, passing the given
 *              parameters if necessary. One of "Handle" or "Pathname" must
 *              be valid (non-null)
 *
 ******************************************************************************/
acpi_status
acpi_evaluate_object(acpi_handle handle,
		     acpi_string pathname,
		     struct acpi_object_list *external_params,
		     struct acpi_buffer *return_buffer)
{
	acpi_status status;
	struct acpi_evaluate_info *info;
	acpi_size buffer_space_needed;
	u32 i;

	ACPI_FUNCTION_TRACE(acpi_evaluate_object);

	/* Allocate and initialize the evaluation information block */

	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
	if (!info) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/* Convert and validate the device handle */

	info->prefix_node = acpi_ns_validate_handle(handle);
	if (!info->prefix_node) {
		status = AE_BAD_PARAMETER;
		goto cleanup;
	}

	/*
	 * Get the actual namespace node for the target object.
	 * 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
	 */
	if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {

		/* The path is fully qualified, just evaluate by name */

		info->prefix_node = NULL;
	} else if (!handle) {
		/*
		 * A handle is optional iff a fully qualified pathname is specified.
		 * Since we've already handled fully qualified names above, this is
		 * an error.
		 */
		if (!pathname) {
			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
					  "Both Handle and Pathname are NULL"));
		} else {
			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
					  "Null Handle with relative pathname [%s]",
					  pathname));
		}

		status = AE_BAD_PARAMETER;
		goto cleanup;
	}

	info->relative_pathname = pathname;

	/*
	 * Convert all external objects passed as arguments to the
	 * internal version(s).
	 */
	if (external_params && external_params->count) {
		info->param_count = (u16)external_params->count;

		/* Warn on impossible argument count */

		if (info->param_count > ACPI_METHOD_NUM_ARGS) {
			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
					      ACPI_WARN_ALWAYS,
					      "Excess arguments (%u) - using only %u",
					      info->param_count,
					      ACPI_METHOD_NUM_ARGS));

			info->param_count = ACPI_METHOD_NUM_ARGS;
		}

		/*
		 * Allocate a new parameter block for the internal objects
		 * Add 1 to count to allow for null terminated internal list
		 */
		info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) info->
							 param_count +
							 1) * sizeof(void *));
		if (!info->parameters) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		/* Convert each external object in the list to an internal object */

		for (i = 0; i < info->param_count; i++) {
			status =
			    acpi_ut_copy_eobject_to_iobject(&external_params->
							    pointer[i],
							    &info->
							    parameters[i]);
			if (ACPI_FAILURE(status)) {
				goto cleanup;
			}
		}

		info->parameters[info->param_count] = NULL;
	}

#if 0

	/*
	 * Begin incoming argument count analysis. Check for too few args
	 * and too many args.
	 */

	switch (acpi_ns_get_type(info->node)) {
	case ACPI_TYPE_METHOD:

		/* Check incoming argument count against the method definition */

		if (info->obj_desc->method.param_count > info->param_count) {
			ACPI_ERROR((AE_INFO,
				    "Insufficient arguments (%u) - %u are required",
				    info->param_count,
				    info->obj_desc->method.param_count));

			status = AE_MISSING_ARGUMENTS;
			goto cleanup;
		}

		else if (info->obj_desc->method.param_count < info->param_count) {
			ACPI_WARNING((AE_INFO,
				      "Excess arguments (%u) - only %u are required",
				      info->param_count,
				      info->obj_desc->method.param_count));

			/* Just pass the required number of arguments */

			info->param_count = info->obj_desc->method.param_count;
		}

		/*
		 * Any incoming external objects to be passed as arguments to the
		 * method must be converted to internal objects
		 */
		if (info->param_count) {
			/*
			 * Allocate a new parameter block for the internal objects
			 * Add 1 to count to allow for null terminated internal list
			 */
			info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
								 info->
								 param_count +
								 1) *
								sizeof(void *));
			if (!info->parameters) {
				status = AE_NO_MEMORY;
				goto cleanup;
			}

			/* Convert each external object in the list to an internal object */

			for (i = 0; i < info->param_count; i++) {
				status =
				    acpi_ut_copy_eobject_to_iobject
				    (&external_params->pointer[i],
				     &info->parameters[i]);
				if (ACPI_FAILURE(status)) {
					goto cleanup;
				}
			}

			info->parameters[info->param_count] = NULL;
		}
		break;

	default:

		/* Warn if arguments passed to an object that is not a method */

		if (info->param_count) {
			ACPI_WARNING((AE_INFO,
				      "%u arguments were passed to a non-method ACPI object",
				      info->param_count));
		}
		break;
	}

#endif

	/* Now we can evaluate the object */

	status = acpi_ns_evaluate(info);

	/*
	 * If we are expecting a return value, and all went well above,
	 * copy the return value to an external object.
	 */
	if (return_buffer) {
		if (!info->return_object) {
			return_buffer->length = 0;
		} else {
			if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
			    ACPI_DESC_TYPE_NAMED) {
				/*
				 * If we received a NS Node as a return object, this means that
				 * the object we are evaluating has nothing interesting to
				 * return (such as a mutex, etc.)  We return an error because
				 * these types are essentially unsupported by this interface.
				 * We don't check up front because this makes it easier to add
				 * support for various types at a later date if necessary.
				 */
				status = AE_TYPE;
				info->return_object = NULL;	/* No need to delete a NS Node */
				return_buffer->length = 0;
			}

			if (ACPI_SUCCESS(status)) {

				/* Dereference Index and ref_of references */

				acpi_ns_resolve_references(info);

				/* Get the size of the returned object */

				status =
				    acpi_ut_get_object_size(info->return_object,
							    &buffer_space_needed);
				if (ACPI_SUCCESS(status)) {

					/* Validate/Allocate/Clear caller buffer */

					status =
					    acpi_ut_initialize_buffer
					    (return_buffer,
					     buffer_space_needed);
					if (ACPI_FAILURE(status)) {
						/*
						 * Caller's buffer is too small or a new one can't
						 * be allocated
						 */
						ACPI_DEBUG_PRINT((ACPI_DB_INFO,
								  "Needed buffer size %X, %s\n",
								  (u32)
								  buffer_space_needed,
								  acpi_format_exception
								  (status)));
					} else {
						/* We have enough space for the object, build it */

						status =
						    acpi_ut_copy_iobject_to_eobject
						    (info->return_object,
						     return_buffer);
					}
				}
			}
		}
	}

	if (info->return_object) {
		/*
		 * Delete the internal return object. NOTE: Interpreter must be
		 * locked to avoid race condition.
		 */
		acpi_ex_enter_interpreter();

		/* Remove one reference on the return object (should delete it) */

		acpi_ut_remove_reference(info->return_object);
		acpi_ex_exit_interpreter();
	}

      cleanup:

	/* Free the input parameter list (if we created one) */

	if (info->parameters) {

		/* Free the allocated parameter block */

		acpi_ut_delete_internal_object_list(info->parameters);
	}

	ACPI_FREE(info);
	return_ACPI_STATUS(status);
}
Example #25
0
ACPI_STATUS
AcpiExStore (
    ACPI_OPERAND_OBJECT     *SourceDesc,
    ACPI_OPERAND_OBJECT     *DestDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_OPERAND_OBJECT     *RefDesc = DestDesc;


    ACPI_FUNCTION_TRACE_PTR (ExStore, DestDesc);


    /* Validate parameters */

    if (!SourceDesc || !DestDesc)
    {
        ACPI_ERROR ((AE_INFO, "Null parameter"));
        return_ACPI_STATUS (AE_AML_NO_OPERAND);
    }

    /* DestDesc can be either a namespace node or an ACPI object */

    if (ACPI_GET_DESCRIPTOR_TYPE (DestDesc) == ACPI_DESC_TYPE_NAMED)
    {
        /*
         * Dest is a namespace node,
         * Storing an object into a Named node.
         */
        Status = AcpiExStoreObjectToNode (SourceDesc,
            (ACPI_NAMESPACE_NODE *) DestDesc, WalkState,
            ACPI_IMPLICIT_CONVERSION);

        return_ACPI_STATUS (Status);
    }

    /* Destination object must be a Reference or a Constant object */

    switch (DestDesc->Common.Type)
    {
    case ACPI_TYPE_LOCAL_REFERENCE:

        break;

    case ACPI_TYPE_INTEGER:

        /* Allow stores to Constants -- a Noop as per ACPI spec */

        if (DestDesc->Common.Flags & AOPOBJ_AML_CONSTANT)
        {
            return_ACPI_STATUS (AE_OK);
        }

        /*lint -fallthrough */

    default:

        /* Destination is not a Reference object */

        ACPI_ERROR ((AE_INFO,
            "Target is not a Reference or Constant object - [%s] %p",
            AcpiUtGetObjectTypeName (DestDesc), DestDesc));

        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }

    /*
     * Examine the Reference class. 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
     */
    switch (RefDesc->Reference.Class)
    {
    case ACPI_REFCLASS_REFOF:

        /* Storing an object into a Name "container" */

        Status = AcpiExStoreObjectToNode (SourceDesc,
            RefDesc->Reference.Object,
            WalkState, ACPI_IMPLICIT_CONVERSION);
        break;

    case ACPI_REFCLASS_INDEX:

        /* Storing to an Index (pointer into a packager or buffer) */

        Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState);
        break;

    case ACPI_REFCLASS_LOCAL:
    case ACPI_REFCLASS_ARG:

        /* Store to a method local/arg  */

        Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Class,
            RefDesc->Reference.Value, SourceDesc, WalkState);
        break;

    case ACPI_REFCLASS_DEBUG:
        /*
         * Storing to the Debug object causes the value stored to be
         * displayed and otherwise has no effect -- see ACPI Specification
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
            "**** Write to Debug Object: Object %p [%s] ****:\n\n",
            SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));

        ACPI_DEBUG_OBJECT (SourceDesc, 0, 0);
        break;

    default:

        ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
            RefDesc->Reference.Class));
        ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);

        Status = AE_AML_INTERNAL;
        break;
    }

    return_ACPI_STATUS (Status);
}
Example #26
0
ACPI_STATUS
AcpiUtUpdateObjectReference (
    ACPI_OPERAND_OBJECT     *Object,
    UINT16                  Action)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GENERIC_STATE      *StateList = NULL;
    ACPI_OPERAND_OBJECT     *NextObject = NULL;
    ACPI_OPERAND_OBJECT     *PrevObject;
    ACPI_GENERIC_STATE      *State;
    UINT32                  i;


    ACPI_FUNCTION_NAME (UtUpdateObjectReference);


    while (Object)
    {
        /* Make sure that this isn't a namespace handle */

        if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
                "Object %p is NS handle\n", Object));
            return (AE_OK);
        }

        /*
         * All sub-objects must have their reference count incremented also.
         * Different object types have different subobjects.
         */
        switch (Object->Common.Type)
        {
        case ACPI_TYPE_DEVICE:
        case ACPI_TYPE_PROCESSOR:
        case ACPI_TYPE_POWER:
        case ACPI_TYPE_THERMAL:
            /*
             * Update the notify objects for these types (if present)
             * Two lists, system and device notify handlers.
             */
            for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
            {
                PrevObject = Object->CommonNotify.NotifyList[i];
                while (PrevObject)
                {
                    NextObject = PrevObject->Notify.Next[i];
                    AcpiUtUpdateRefCount (PrevObject, Action);
                    PrevObject = NextObject;
                }
            }
            break;

        case ACPI_TYPE_PACKAGE:
            /*
             * We must update all the sub-objects of the package,
             * each of whom may have their own sub-objects.
             */
            for (i = 0; i < Object->Package.Count; i++)
            {
                /*
                 * Null package elements are legal and can be simply
                 * ignored.
                 */
                NextObject = Object->Package.Elements[i];
                if (!NextObject)
                {
                    continue;
                }

                switch (NextObject->Common.Type)
                {
                case ACPI_TYPE_INTEGER:
                case ACPI_TYPE_STRING:
                case ACPI_TYPE_BUFFER:
                    /*
                     * For these very simple sub-objects, we can just
                     * update the reference count here and continue.
                     * Greatly increases performance of this operation.
                     */
                    AcpiUtUpdateRefCount (NextObject, Action);
                    break;

                default:
                    /*
                     * For complex sub-objects, push them onto the stack
                     * for later processing (this eliminates recursion.)
                     */
                    Status = AcpiUtCreateUpdateStateAndPush (
                                 NextObject, Action, &StateList);
                    if (ACPI_FAILURE (Status))
                    {
                        goto ErrorExit;
                    }
                    break;
                }
            }
            NextObject = NULL;
            break;

        case ACPI_TYPE_BUFFER_FIELD:

            NextObject = Object->BufferField.BufferObj;
            break;

        case ACPI_TYPE_LOCAL_REGION_FIELD:

            NextObject = Object->Field.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_BANK_FIELD:

            NextObject = Object->BankField.BankObj;
            Status = AcpiUtCreateUpdateStateAndPush (
                        Object->BankField.RegionObj, Action, &StateList);
            if (ACPI_FAILURE (Status))
            {
                goto ErrorExit;
            }
            break;

        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            NextObject = Object->IndexField.IndexObj;
            Status = AcpiUtCreateUpdateStateAndPush (
                        Object->IndexField.DataObj, Action, &StateList);
            if (ACPI_FAILURE (Status))
            {
                goto ErrorExit;
            }
            break;

        case ACPI_TYPE_LOCAL_REFERENCE:
            /*
             * The target of an Index (a package, string, or buffer) or a named
             * reference must track changes to the ref count of the index or
             * target object.
             */
            if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
                (Object->Reference.Class== ACPI_REFCLASS_NAME))
            {
                NextObject = Object->Reference.Object;
            }
            break;

        case ACPI_TYPE_REGION:
        default:

            break; /* No subobjects for all other types */
        }

        /*
         * Now we can update the count in the main object. This can only
         * happen after we update the sub-objects in case this causes the
         * main object to be deleted.
         */
        AcpiUtUpdateRefCount (Object, Action);
        Object = NULL;

        /* Move on to the next object to be updated */

        if (NextObject)
        {
            Object = NextObject;
            NextObject = NULL;
        }
        else if (StateList)
        {
            State = AcpiUtPopGenericState (&StateList);
            Object = State->Update.Object;
            AcpiUtDeleteGenericState (State);
        }
    }

    return (AE_OK);


ErrorExit:

    ACPI_EXCEPTION ((AE_INFO, Status,
        "Could not update object reference count"));

    /* Free any stacked Update State objects */

    while (StateList)
    {
        State = AcpiUtPopGenericState (&StateList);
        AcpiUtDeleteGenericState (State);
    }

    return (Status);
}
Example #27
0
void
AcpiDbDecodeAndDisplayObject (
    char                    *Target,
    char                    *OutputType)
{
    void                    *ObjPtr;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    UINT32                  Display = DB_BYTE_DISPLAY;
    char                    Buffer[80];
    ACPI_BUFFER             RetBuf;
    ACPI_STATUS             Status;
    UINT32                  Size;


    if (!Target)
    {
        return;
    }

    /* Decode the output type */

    if (OutputType)
    {
        AcpiUtStrupr (OutputType);
        if (OutputType[0] == 'W')
        {
            Display = DB_WORD_DISPLAY;
        }
        else if (OutputType[0] == 'D')
        {
            Display = DB_DWORD_DISPLAY;
        }
        else if (OutputType[0] == 'Q')
        {
            Display = DB_QWORD_DISPLAY;
        }
    }

    RetBuf.Length = sizeof (Buffer);
    RetBuf.Pointer = Buffer;

    /* Differentiate between a number and a name */

    if ((Target[0] >= 0x30) && (Target[0] <= 0x39))
    {
        ObjPtr = AcpiDbGetPointer (Target);
        if (!AcpiOsReadable (ObjPtr, 16))
        {
            AcpiOsPrintf ("Address %p is invalid in this address space\n",
                ObjPtr);
            return;
        }

        /* Decode the object type */

        switch (ACPI_GET_DESCRIPTOR_TYPE (ObjPtr))
        {
        case ACPI_DESC_TYPE_NAMED:

            /* This is a namespace Node */

            if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_NAMESPACE_NODE)))
            {
                AcpiOsPrintf (
                    "Cannot read entire Named object at address %p\n", ObjPtr);
                return;
            }

            Node = ObjPtr;
            goto DumpNode;

        case ACPI_DESC_TYPE_OPERAND:

            /* This is a ACPI OPERAND OBJECT */

            if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_OPERAND_OBJECT)))
            {
                AcpiOsPrintf ("Cannot read entire ACPI object at address %p\n",
                    ObjPtr);
                return;
            }

            AcpiUtDebugDumpBuffer (ObjPtr, sizeof (ACPI_OPERAND_OBJECT), Display,
                ACPI_UINT32_MAX);
            AcpiExDumpObjectDescriptor (ObjPtr, 1);
            break;

        case ACPI_DESC_TYPE_PARSER:

            /* This is a Parser Op object */

            if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_PARSE_OBJECT)))
            {
                AcpiOsPrintf (
                    "Cannot read entire Parser object at address %p\n", ObjPtr);
                return;
            }

            AcpiUtDebugDumpBuffer (ObjPtr, sizeof (ACPI_PARSE_OBJECT), Display,
                ACPI_UINT32_MAX);
            AcpiDbDumpParserDescriptor ((ACPI_PARSE_OBJECT *) ObjPtr);
            break;

        default:

            /* Is not a recognizeable object */

            AcpiOsPrintf (
                "Not a known ACPI internal object, descriptor type %2.2X\n",
                ACPI_GET_DESCRIPTOR_TYPE (ObjPtr));

            Size = 16;
            if (AcpiOsReadable (ObjPtr, 64))
            {
                Size = 64;
            }

            /* Just dump some memory */

            AcpiUtDebugDumpBuffer (ObjPtr, Size, Display, ACPI_UINT32_MAX);
            break;
        }

        return;
    }

    /* The parameter is a name string that must be resolved to a Named obj */

    Node = AcpiDbLocalNsLookup (Target);
    if (!Node)
    {
        return;
    }


DumpNode:
    /* Now dump the NS node */

    Status = AcpiGetName (Node, ACPI_FULL_PATHNAME, &RetBuf);
    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("Could not convert name to pathname\n");
    }

    else
    {
        AcpiOsPrintf ("Object (%p) Pathname:  %s\n",
            Node, (char *) RetBuf.Pointer);
    }

    if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
    {
        AcpiOsPrintf ("Invalid Named object at address %p\n", Node);
        return;
    }

    AcpiUtDebugDumpBuffer ((void *) Node, sizeof (ACPI_NAMESPACE_NODE),
        Display, ACPI_UINT32_MAX);
    AcpiExDumpNamespaceNode (Node, 1);

    ObjDesc = AcpiNsGetAttachedObject (Node);
    if (ObjDesc)
    {
        AcpiOsPrintf ("\nAttached Object (%p):\n", ObjDesc);
        if (!AcpiOsReadable (ObjDesc, sizeof (ACPI_OPERAND_OBJECT)))
        {
            AcpiOsPrintf ("Invalid internal ACPI Object at address %p\n",
                ObjDesc);
            return;
        }

        AcpiUtDebugDumpBuffer ((void *) ObjDesc, sizeof (ACPI_OPERAND_OBJECT),
            Display, ACPI_UINT32_MAX);
        AcpiExDumpObjectDescriptor (ObjDesc, 1);
    }
}
Example #28
0
ACPI_STATUS
AcpiExResolveMultiple (
    ACPI_WALK_STATE         *WalkState,
    ACPI_OPERAND_OBJECT     *Operand,
    ACPI_OBJECT_TYPE        *ReturnType,
    ACPI_OPERAND_OBJECT     **ReturnDesc)
{
    ACPI_OPERAND_OBJECT     *ObjDesc = (void *) Operand;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_OBJECT_TYPE        Type;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (AcpiExResolveMultiple);


    /* Operand can be either a namespace node or an operand descriptor */

    switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
    {
    case ACPI_DESC_TYPE_OPERAND:
        Type = ObjDesc->Common.Type;
        break;

    case ACPI_DESC_TYPE_NAMED:
        Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
        ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);

        /* If we had an Alias node, use the attached object for type info */

        if (Type == ACPI_TYPE_LOCAL_ALIAS)
        {
            Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
            ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
        }
        break;

    default:
        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }

    /* If type is anything other than a reference, we are done */

    if (Type != ACPI_TYPE_LOCAL_REFERENCE)
    {
        goto Exit;
    }

    /*
     * For reference objects created via the RefOf, Index, or Load/LoadTable
     * operators, we need to get to the base object (as per the ACPI
     * specification of the ObjectType and SizeOf operators). This means
     * traversing the list of possibly many nested references.
     */
    while (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
    {
        switch (ObjDesc->Reference.Class)
        {
        case ACPI_REFCLASS_REFOF:
        case ACPI_REFCLASS_NAME:

            /* Dereference the reference pointer */

            if (ObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)
            {
                Node = ObjDesc->Reference.Object;
            }
            else /* AML_INT_NAMEPATH_OP */
            {
                Node = ObjDesc->Reference.Node;
            }

            /* All "References" point to a NS node */

            if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
            {
                ACPI_ERROR ((AE_INFO,
                    "Not a namespace node %p [%s]",
                    Node, AcpiUtGetDescriptorName (Node)));
                return_ACPI_STATUS (AE_AML_INTERNAL);
            }

            /* Get the attached object */

            ObjDesc = AcpiNsGetAttachedObject (Node);
            if (!ObjDesc)
            {
                /* No object, use the NS node type */

                Type = AcpiNsGetType (Node);
                goto Exit;
            }

            /* Check for circular references */

            if (ObjDesc == Operand)
            {
                return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
            }
            break;


        case ACPI_REFCLASS_INDEX:

            /* Get the type of this reference (index into another object) */

            Type = ObjDesc->Reference.TargetType;
            if (Type != ACPI_TYPE_PACKAGE)
            {
                goto Exit;
            }

            /*
             * The main object is a package, we want to get the type
             * of the individual package element that is referenced by
             * the index.
             *
             * This could of course in turn be another reference object.
             */
            ObjDesc = *(ObjDesc->Reference.Where);
            if (!ObjDesc)
            {
                /* NULL package elements are allowed */

                Type = 0; /* Uninitialized */
                goto Exit;
            }
            break;


        case ACPI_REFCLASS_TABLE:

            Type = ACPI_TYPE_DDB_HANDLE;
            goto Exit;


        case ACPI_REFCLASS_LOCAL:
        case ACPI_REFCLASS_ARG:

            if (ReturnDesc)
            {
                Status = AcpiDsMethodDataGetValue (ObjDesc->Reference.Class,
                            ObjDesc->Reference.Value, WalkState, &ObjDesc);
                if (ACPI_FAILURE (Status))
                {
                    return_ACPI_STATUS (Status);
                }
                AcpiUtRemoveReference (ObjDesc);
            }
            else
            {
                Status = AcpiDsMethodDataGetNode (ObjDesc->Reference.Class,
                            ObjDesc->Reference.Value, WalkState, &Node);
                if (ACPI_FAILURE (Status))
                {
                    return_ACPI_STATUS (Status);
                }

                ObjDesc = AcpiNsGetAttachedObject (Node);
                if (!ObjDesc)
                {
                    Type = ACPI_TYPE_ANY;
                    goto Exit;
                }
            }
            break;


        case ACPI_REFCLASS_DEBUG:

            /* The Debug Object is of type "DebugObject" */

            Type = ACPI_TYPE_DEBUG_OBJECT;
            goto Exit;


        default:

            ACPI_ERROR ((AE_INFO,
                "Unknown Reference Class 0x%2.2X", ObjDesc->Reference.Class));
            return_ACPI_STATUS (AE_AML_INTERNAL);
        }
    }

    /*
     * Now we are guaranteed to have an object that has not been created
     * via the RefOf or Index operators.
     */
    Type = ObjDesc->Common.Type;


Exit:
    /* Convert internal types to external types */

    switch (Type)
    {
    case ACPI_TYPE_LOCAL_REGION_FIELD:
    case ACPI_TYPE_LOCAL_BANK_FIELD:
    case ACPI_TYPE_LOCAL_INDEX_FIELD:

        Type = ACPI_TYPE_FIELD_UNIT;
        break;

    case ACPI_TYPE_LOCAL_SCOPE:

        /* Per ACPI Specification, Scope is untyped */

        Type = ACPI_TYPE_ANY;
        break;

    default:
        /* No change to Type required */
        break;
    }

    *ReturnType = Type;
    if (ReturnDesc)
    {
        *ReturnDesc = ObjDesc;
    }
    return_ACPI_STATUS (AE_OK);
}
Example #29
0
void
AcpiUtDumpAllocations (
    UINT32                  Component,
    const char              *Module)
{
    ACPI_DEBUG_MEM_BLOCK    *Element;
    ACPI_DESCRIPTOR         *Descriptor;
    UINT32                  NumOutstanding = 0;
    UINT8                   DescriptorType;


    ACPI_FUNCTION_TRACE (UtDumpAllocations);


    if (AcpiGbl_DisableMemTracking)
    {
        return_VOID;
    }

    /*
     * Walk the allocation list.
     */
    if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY)))
    {
        return_VOID;
    }

    Element = AcpiGbl_GlobalList->ListHead;
    while (Element)
    {
        if ((Element->Component & Component) &&
            ((Module == NULL) || (0 == strcmp (Module, Element->Module))))
        {
            Descriptor = ACPI_CAST_PTR (
                ACPI_DESCRIPTOR, &Element->UserSpace);

            if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR))
            {
                AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u "
                    "[Not a Descriptor - too small]\n",
                    Descriptor, Element->Size, Element->Module,
                    Element->Line);
            }
            else
            {
                /* Ignore allocated objects that are in a cache */

                if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) !=
                    ACPI_DESC_TYPE_CACHED)
                {
                    AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u [%s] ",
                        Descriptor, Element->Size, Element->Module,
                        Element->Line, AcpiUtGetDescriptorName (Descriptor));

                    /* Validate the descriptor type using Type field and length */

                    DescriptorType = 0; /* Not a valid descriptor type */

                    switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor))
                    {
                    case ACPI_DESC_TYPE_OPERAND:

                        if (Element->Size == sizeof (ACPI_OPERAND_OBJECT))
                        {
                            DescriptorType = ACPI_DESC_TYPE_OPERAND;
                        }
                        break;

                    case ACPI_DESC_TYPE_PARSER:

                        if (Element->Size == sizeof (ACPI_PARSE_OBJECT))
                        {
                            DescriptorType = ACPI_DESC_TYPE_PARSER;
                        }
                        break;

                    case ACPI_DESC_TYPE_NAMED:

                        if (Element->Size == sizeof (ACPI_NAMESPACE_NODE))
                        {
                            DescriptorType = ACPI_DESC_TYPE_NAMED;
                        }
                        break;

                    default:

                        break;
                    }

                    /* Display additional info for the major descriptor types */

                    switch (DescriptorType)
                    {
                    case ACPI_DESC_TYPE_OPERAND:

                        AcpiOsPrintf ("%12.12s  RefCount 0x%04X\n",
                            AcpiUtGetTypeName (Descriptor->Object.Common.Type),
                            Descriptor->Object.Common.ReferenceCount);
                        break;

                    case ACPI_DESC_TYPE_PARSER:

                        AcpiOsPrintf ("AmlOpcode 0x%04hX\n",
                            Descriptor->Op.Asl.AmlOpcode);
                        break;

                    case ACPI_DESC_TYPE_NAMED:

                        AcpiOsPrintf ("%4.4s\n",
                            AcpiUtGetNodeName (&Descriptor->Node));
                        break;

                    default:

                        AcpiOsPrintf ( "\n");
                        break;
                    }
                }
            }

            NumOutstanding++;
        }

        Element = Element->Next;
    }

    (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY);

    /* Print summary */

    if (!NumOutstanding)
    {
        ACPI_INFO (("No outstanding allocations"));
    }
    else
    {
        ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations",
            NumOutstanding, NumOutstanding));
    }

    return_VOID;
}
acpi_status
acpi_ns_dump_one_object(acpi_handle obj_handle,
			u32 level, void *context, void **return_value)
{
	struct acpi_walk_info *info = (struct acpi_walk_info *)context;
	struct acpi_namespace_node *this_node;
	union acpi_operand_object *obj_desc = NULL;
	acpi_object_type obj_type;
	acpi_object_type type;
	u32 bytes_to_dump;
	u32 dbg_level;
	u32 i;

	ACPI_FUNCTION_NAME(ns_dump_one_object);

	

	if (!(acpi_dbg_level & info->debug_level)) {
		return (AE_OK);
	}

	if (!obj_handle) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Null object handle\n"));
		return (AE_OK);
	}

	this_node = acpi_ns_validate_handle(obj_handle);
	if (!this_node) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
				  obj_handle));
		return (AE_OK);
	}

	type = this_node->type;

	

	if ((info->owner_id != ACPI_OWNER_ID_MAX) &&
	    (info->owner_id != this_node->owner_id)) {
		return (AE_OK);
	}

	if (!(info->display_type & ACPI_DISPLAY_SHORT)) {

		

		acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " ");

		

		if (type > ACPI_TYPE_LOCAL_MAX) {
			ACPI_WARNING((AE_INFO,
				      "Invalid ACPI Object Type 0x%08X", type));
		}

		if (!acpi_ut_valid_acpi_name(this_node->name.integer)) {
			this_node->name.integer =
			    acpi_ut_repair_name(this_node->name.ascii);

			ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X",
				      this_node->name.integer));
		}

		acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
	}

	

	acpi_os_printf(" %-12s %p %2.2X ",
		       acpi_ut_get_type_name(type), this_node,
		       this_node->owner_id);

	dbg_level = acpi_dbg_level;
	acpi_dbg_level = 0;
	obj_desc = acpi_ns_get_attached_object(this_node);
	acpi_dbg_level = dbg_level;

	

	if (this_node->flags & ANOBJ_TEMPORARY) {
		acpi_os_printf("(T) ");
	}

	switch (info->display_type & ACPI_DISPLAY_MASK) {
	case ACPI_DISPLAY_SUMMARY:

		if (!obj_desc) {

			

			switch (type) {
			case ACPI_TYPE_INTEGER:
			case ACPI_TYPE_PACKAGE:
			case ACPI_TYPE_BUFFER:
			case ACPI_TYPE_STRING:
			case ACPI_TYPE_METHOD:
				acpi_os_printf("<No attached object>");
				break;

			default:
				break;
			}

			acpi_os_printf("\n");
			return (AE_OK);
		}

		switch (type) {
		case ACPI_TYPE_PROCESSOR:

			acpi_os_printf("ID %X Len %.4X Addr %p\n",
				       obj_desc->processor.proc_id,
				       obj_desc->processor.length,
				       ACPI_CAST_PTR(void,
						     obj_desc->processor.
						     address));
			break;

		case ACPI_TYPE_DEVICE:

			acpi_os_printf("Notify Object: %p\n", obj_desc);
			break;

		case ACPI_TYPE_METHOD:

			acpi_os_printf("Args %X Len %.4X Aml %p\n",
				       (u32) obj_desc->method.param_count,
				       obj_desc->method.aml_length,
				       obj_desc->method.aml_start);
			break;

		case ACPI_TYPE_INTEGER:

			acpi_os_printf("= %8.8X%8.8X\n",
				       ACPI_FORMAT_UINT64(obj_desc->integer.
							  value));
			break;

		case ACPI_TYPE_PACKAGE:

			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
				acpi_os_printf("Elements %.2X\n",
					       obj_desc->package.count);
			} else {
				acpi_os_printf("[Length not yet evaluated]\n");
			}
			break;

		case ACPI_TYPE_BUFFER:

			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
				acpi_os_printf("Len %.2X",
					       obj_desc->buffer.length);

				

				if (obj_desc->buffer.length > 0) {
					acpi_os_printf(" =");
					for (i = 0;
					     (i < obj_desc->buffer.length
					      && i < 12); i++) {
						acpi_os_printf(" %.2hX",
							       obj_desc->buffer.
							       pointer[i]);
					}
				}
				acpi_os_printf("\n");
			} else {
				acpi_os_printf("[Length not yet evaluated]\n");
			}
			break;

		case ACPI_TYPE_STRING:

			acpi_os_printf("Len %.2X ", obj_desc->string.length);
			acpi_ut_print_string(obj_desc->string.pointer, 32);
			acpi_os_printf("\n");
			break;

		case ACPI_TYPE_REGION:

			acpi_os_printf("[%s]",
				       acpi_ut_get_region_name(obj_desc->region.
							       space_id));
			if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
				acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n",
					       ACPI_FORMAT_NATIVE_UINT
					       (obj_desc->region.address),
					       obj_desc->region.length);
			} else {
				acpi_os_printf
				    (" [Address/Length not yet evaluated]\n");
			}
			break;

		case ACPI_TYPE_LOCAL_REFERENCE:

			acpi_os_printf("[%s]\n",
				       acpi_ut_get_reference_name(obj_desc));
			break;

		case ACPI_TYPE_BUFFER_FIELD:

			if (obj_desc->buffer_field.buffer_obj &&
			    obj_desc->buffer_field.buffer_obj->buffer.node) {
				acpi_os_printf("Buf [%4.4s]",
					       acpi_ut_get_node_name(obj_desc->
								     buffer_field.
								     buffer_obj->
								     buffer.
								     node));
			}
			break;

		case ACPI_TYPE_LOCAL_REGION_FIELD:

			acpi_os_printf("Rgn [%4.4s]",
				       acpi_ut_get_node_name(obj_desc->
							     common_field.
							     region_obj->region.
							     node));
			break;

		case ACPI_TYPE_LOCAL_BANK_FIELD:

			acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]",
				       acpi_ut_get_node_name(obj_desc->
							     common_field.
							     region_obj->region.
							     node),
				       acpi_ut_get_node_name(obj_desc->
							     bank_field.
							     bank_obj->
							     common_field.
							     node));
			break;

		case ACPI_TYPE_LOCAL_INDEX_FIELD:

			acpi_os_printf("Idx [%4.4s] Dat [%4.4s]",
				       acpi_ut_get_node_name(obj_desc->
							     index_field.
							     index_obj->
							     common_field.node),
				       acpi_ut_get_node_name(obj_desc->
							     index_field.
							     data_obj->
							     common_field.
							     node));
			break;

		case ACPI_TYPE_LOCAL_ALIAS:
		case ACPI_TYPE_LOCAL_METHOD_ALIAS:

			acpi_os_printf("Target %4.4s (%p)\n",
				       acpi_ut_get_node_name(obj_desc),
				       obj_desc);
			break;

		default:

			acpi_os_printf("Object %p\n", obj_desc);
			break;
		}

		

		switch (type) {
		case ACPI_TYPE_BUFFER_FIELD:
		case ACPI_TYPE_LOCAL_REGION_FIELD:
		case ACPI_TYPE_LOCAL_BANK_FIELD:
		case ACPI_TYPE_LOCAL_INDEX_FIELD:

			acpi_os_printf(" Off %.3X Len %.2X Acc %.2hd\n",
				       (obj_desc->common_field.
					base_byte_offset * 8)
				       +
				       obj_desc->common_field.
				       start_field_bit_offset,
				       obj_desc->common_field.bit_length,
				       obj_desc->common_field.
				       access_byte_width);
			break;

		default:
			break;
		}
		break;

	case ACPI_DISPLAY_OBJECTS:

		acpi_os_printf("O:%p", obj_desc);
		if (!obj_desc) {

			

			acpi_os_printf("\n");
			return (AE_OK);
		}

		acpi_os_printf("(R%u)", obj_desc->common.reference_count);

		switch (type) {
		case ACPI_TYPE_METHOD:

			

			acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start,
				       obj_desc->method.aml_length);
			break;

		case ACPI_TYPE_INTEGER:

			acpi_os_printf(" I:%8.8X8.8%X\n",
				       ACPI_FORMAT_UINT64(obj_desc->integer.
							  value));
			break;

		case ACPI_TYPE_STRING:

			acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer,
				       obj_desc->string.length);
			break;

		case ACPI_TYPE_BUFFER:

			acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer,
				       obj_desc->buffer.length);
			break;

		default:

			acpi_os_printf("\n");
			break;
		}
		break;

	default:
		acpi_os_printf("\n");
		break;
	}

	

	if (!(acpi_dbg_level & ACPI_LV_VALUES)) {
		return (AE_OK);
	}

	

	dbg_level = acpi_dbg_level;
	acpi_dbg_level = 0;
	obj_desc = acpi_ns_get_attached_object(this_node);
	acpi_dbg_level = dbg_level;

	

	while (obj_desc) {
		obj_type = ACPI_TYPE_INVALID;
		acpi_os_printf("Attached Object %p: ", obj_desc);

		

		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
		case ACPI_DESC_TYPE_NAMED:

			acpi_os_printf("(Ptr to Node)\n");
			bytes_to_dump = sizeof(struct acpi_namespace_node);
			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
			break;

		case ACPI_DESC_TYPE_OPERAND:

			obj_type = obj_desc->common.type;

			if (obj_type > ACPI_TYPE_LOCAL_MAX) {
				acpi_os_printf
				    ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
				     obj_type);
				bytes_to_dump = 32;
			} else {
				acpi_os_printf
				    ("(Pointer to ACPI Object type %.2X [%s])\n",
				     obj_type, acpi_ut_get_type_name(obj_type));
				bytes_to_dump =
				    sizeof(union acpi_operand_object);
			}

			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
			break;

		default:

			break;
		}

		

		if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
		    ACPI_DESC_TYPE_OPERAND) {
			goto cleanup;
		}

		

		switch (obj_type) {
		case ACPI_TYPE_BUFFER:
		case ACPI_TYPE_STRING:
			bytes_to_dump = obj_desc->string.length;
			obj_desc = (void *)obj_desc->string.pointer;
			acpi_os_printf("(Buffer/String pointer %p length %X)\n",
				       obj_desc, bytes_to_dump);
			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
			goto cleanup;

		case ACPI_TYPE_BUFFER_FIELD:
			obj_desc =
			    (union acpi_operand_object *)obj_desc->buffer_field.
			    buffer_obj;
			break;

		case ACPI_TYPE_PACKAGE:
			obj_desc = (void *)obj_desc->package.elements;
			break;

		case ACPI_TYPE_METHOD:
			obj_desc = (void *)obj_desc->method.aml_start;
			break;

		case ACPI_TYPE_LOCAL_REGION_FIELD:
			obj_desc = (void *)obj_desc->field.region_obj;
			break;

		case ACPI_TYPE_LOCAL_BANK_FIELD:
			obj_desc = (void *)obj_desc->bank_field.region_obj;
			break;

		case ACPI_TYPE_LOCAL_INDEX_FIELD:
			obj_desc = (void *)obj_desc->index_field.index_obj;
			break;

		default:
			goto cleanup;
		}

		obj_type = ACPI_TYPE_INVALID;	
	}

      cleanup:
	acpi_os_printf("\n");
	return (AE_OK);
}