Exemple #1
0
acpi_status
acpi_ex_get_object_reference (
	acpi_operand_object     *obj_desc,
	acpi_operand_object     **return_desc,
	acpi_walk_state         *walk_state)
{
	acpi_status             status = AE_OK;


	FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc);


	if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
		if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) {
			*return_desc = NULL;
			status = AE_TYPE;
			goto cleanup;
		}

		/*
		 * Not a Name -- an indirect name pointer would have
		 * been converted to a direct name pointer in Acpi_ex_resolve_operands
		 */
		switch (obj_desc->reference.opcode) {
		case AML_LOCAL_OP:
		case AML_ARG_OP:

			*return_desc = (void *) acpi_ds_method_data_get_node (obj_desc->reference.opcode,
					  obj_desc->reference.offset, walk_state);
			break;

		default:

			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n",
				obj_desc->reference.opcode));
			*return_desc = NULL;
			status = AE_AML_INTERNAL;
			goto cleanup;
		}

	}

	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
		/* Must be a named object;  Just return the Node */

		*return_desc = obj_desc;
	}

	else {
		*return_desc = NULL;
		status = AE_TYPE;
	}


cleanup:

	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *return_desc));
	return_ACPI_STATUS (status);
}
Exemple #2
0
BOOLEAN
AcpiUtValidInternalObject (
    void                    *Object)
{

    PROC_NAME ("UtValidInternalObject");


    /* Check for a null pointer */

    if (!Object)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
            "**** Null Object Ptr\n"));
        return (FALSE);
    }

    /* Check for a pointer within one of the ACPI tables */

    if (AcpiTbSystemTablePointer (Object))
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Object %p is a Pcode Ptr\n", Object));
        return (FALSE);
    }

    /* Check the descriptor type field */

    if (!VALID_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_INTERNAL))
    {
        /* Not an ACPI internal object, do some further checking */

        if (VALID_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_NAMED))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
                "**** Obj %p is a named obj, not ACPI obj\n", Object));
        }

        else if (VALID_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_PARSER))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
                "**** Obj %p is a parser obj, not ACPI obj\n", Object));
        }

        else
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
                "**** Obj %p is of unknown type\n", Object));
        }

        return (FALSE);
    }


    /* The object appears to be a valid ACPI_OPERAND_OBJECT  */

    return (TRUE);
}
Exemple #3
0
ACPI_STATUS
AcpiExResolveToValue (
    ACPI_OPERAND_OBJECT     **StackPtr,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;


    FUNCTION_TRACE_PTR ("ExResolveToValue", StackPtr);


    if (!StackPtr || !*StackPtr)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
        return_ACPI_STATUS (AE_AML_NO_OPERAND);
    }


    /*
     * The entity pointed to by the StackPtr can be either
     * 1) A valid ACPI_OPERAND_OBJECT, or
     * 2) A ACPI_NAMESPACE_NODE (NamedObj)
     */
    if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_INTERNAL))
    {
        Status = AcpiExResolveObjectToValue (StackPtr, WalkState);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }

    /*
     * Object on the stack may have changed if AcpiExResolveObjectToValue()
     * was called (i.e., we can't use an _else_ here.)
     */
    if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_NAMED))
    {
        Status = AcpiExResolveNodeToValue ((ACPI_NAMESPACE_NODE **) StackPtr,
                        WalkState);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }


    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Resolved object %p\n", *StackPtr));
    return_ACPI_STATUS (AE_OK);
}
Exemple #4
0
acpi_namespace_node *
acpi_ns_map_handle_to_node (
	acpi_handle             handle)
{

	FUNCTION_ENTRY ();


	/*
	 * Simple implementation for now;
	 * TBD: [Future] Real integer handles allow for more verification
	 * and keep all pointers within this subsystem!
	 */
	if (!handle) {
		return (NULL);
	}

	if (handle == ACPI_ROOT_OBJECT) {
		return (acpi_gbl_root_node);
	}


	/* We can at least attempt to verify the handle */

	if (!VALID_DESCRIPTOR_TYPE (handle, ACPI_DESC_TYPE_NAMED)) {
		return (NULL);
	}

	return ((acpi_namespace_node *) handle);
}
u8
acpi_ut_valid_internal_object (
	void                    *object)
{

	PROC_NAME ("Ut_valid_internal_object");


	/* Check for a null pointer */

	if (!object) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"**** Null Object Ptr\n"));
		return (FALSE);
	}

	/* Check the descriptor type field */

	if (!VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)) {
		/* Not an ACPI internal object, do some further checking */

		if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
				"**** Obj %p is a named obj, not ACPI obj\n", object));
		}

		else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_PARSER)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
				"**** Obj %p is a parser obj, not ACPI obj\n", object));
		}

		else {
			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
				"**** Obj %p is of unknown type\n", object));
		}

		return (FALSE);
	}


	/* The object appears to be a valid acpi_operand_object  */

	return (TRUE);
}
void
acpi_db_dump_namespace (
	NATIVE_CHAR             *start_arg,
	NATIVE_CHAR             *depth_arg)
{
	acpi_handle             subtree_entry = acpi_gbl_root_node;
	u32                     max_depth = ACPI_UINT32_MAX;


	/* No argument given, just start at the root and dump entire namespace */

	if (start_arg) {
		/* Check if numeric argument, must be a Node */

		if ((start_arg[0] >= 0x30) && (start_arg[0] <= 0x39)) {
			subtree_entry = (acpi_handle) STRTOUL (start_arg, NULL, 16);
			if (!acpi_os_readable (subtree_entry, sizeof (acpi_namespace_node))) {
				acpi_os_printf ("Address %p is invalid in this address space\n", subtree_entry);
				return;
			}

			if (!VALID_DESCRIPTOR_TYPE ((subtree_entry), ACPI_DESC_TYPE_NAMED)) {
				acpi_os_printf ("Address %p is not a valid Named object\n", subtree_entry);
				return;
			}
		}

		/* Alpha argument */

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

			subtree_entry = acpi_db_local_ns_lookup (start_arg);
			if (!subtree_entry) {
				subtree_entry = acpi_gbl_root_node;
			}
		}

		/* Now we can check for the depth argument */

		if (depth_arg) {
			max_depth = STRTOUL (depth_arg, NULL, 0);
		}
	}


	acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
	acpi_os_printf ("ACPI Namespace (from %p subtree):\n", subtree_entry);

	/* Display the subtree */

	acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
	acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, ACPI_UINT32_MAX, subtree_entry);
	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
}
Exemple #7
0
ACPI_STATUS
AcpiDsMethodDataDeleteValue (
    UINT16                  Opcode,
    UINT32                  Index,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;
    ACPI_OPERAND_OBJECT     **Entry;
    ACPI_OPERAND_OBJECT     *Object;


    FUNCTION_TRACE ("DsMethodDataDeleteValue");


    /* Get a pointer to the requested entry */

    Status = AcpiDsMethodDataGetEntry (Opcode, Index, WalkState, &Entry);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Get the current entry in this slot k */

    Object = *Entry;

    /*
     * Undefine the Arg or Local by setting its descriptor
     * pointer to NULL. Locals/Args can contain both
     * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
     */
    *Entry = NULL;

    if ((Object) &&
            (VALID_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_INTERNAL)))
    {
        /*
         * There is a valid object in this slot
         * Decrement the reference count by one to balance the
         * increment when the object was stored in the slot.
         */
        AcpiUtRemoveReference (Object);
    }

    return_ACPI_STATUS (AE_OK);
}
Exemple #8
0
ACPI_STATUS
acpi_ds_method_data_delete_value (
	u32                     type,
	u32                     index,
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_STATUS             status;
	ACPI_OPERAND_OBJECT     **entry;
	ACPI_OPERAND_OBJECT     *object;


	/* Get a pointer to the requested entry */

	status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
	if (ACPI_FAILURE (status)) {
		return (status);
	}

	/* Get the current entry in this slot k */

	object = *entry;

	/*
	 * Undefine the Arg or Local by setting its descriptor
	 * pointer to NULL. Locals/Args can contain both
	 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
	 */
	*entry = NULL;


	if ((object) &&
		(VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)))
	{
		/*
		 * There is a valid object in this slot
		 * Decrement the reference count by one to balance the
		 * increment when the object was stored in the slot.
		 */

		acpi_cm_remove_reference (object);
	}


	return (AE_OK);
}
acpi_status
acpi_ut_get_object_size(
	acpi_operand_object     *internal_object,
	u32                     *obj_length)
{
	acpi_status             status;


	FUNCTION_ENTRY ();


	if ((VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_INTERNAL)) &&
		(IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE))) {
		status = acpi_ut_get_package_object_size (internal_object, obj_length);
	}

	else {
		status = acpi_ut_get_simple_object_size (internal_object, obj_length);
	}

	return (status);
}
Exemple #10
0
ACPI_STATUS
AcpiUtGetObjectSize(
    ACPI_OPERAND_OBJECT     *InternalObject,
    UINT32                  *ObjLength)
{
    ACPI_STATUS             Status;


    FUNCTION_ENTRY ();


    if ((VALID_DESCRIPTOR_TYPE (InternalObject, ACPI_DESC_TYPE_INTERNAL)) &&
        (IS_THIS_OBJECT_TYPE (InternalObject, ACPI_TYPE_PACKAGE)))
    {
        Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
    }

    else
    {
        Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
    }

    return (Status);
}
Exemple #11
0
ACPI_STATUS
AcpiUtWalkPackageTree (
    ACPI_OPERAND_OBJECT     *SourceObject,
    void                    *TargetObject,
    ACPI_PKG_CALLBACK       WalkCallback,
    void                    *Context)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GENERIC_STATE      *StateList = NULL;
    ACPI_GENERIC_STATE      *State;
    UINT32                  ThisIndex;
    ACPI_OPERAND_OBJECT     *ThisSourceObj;


    FUNCTION_TRACE ("UtWalkPackageTree");


    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
    if (!State)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    while (State)
    {
        ThisIndex     = State->Pkg.Index;
        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
                        State->Pkg.SourceObject->Package.Elements[ThisIndex];

        /*
         * 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 ((!ThisSourceObj) ||
                (!VALID_DESCRIPTOR_TYPE (
                     ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) ||
                (!IS_THIS_OBJECT_TYPE (
                     ThisSourceObj, ACPI_TYPE_PACKAGE)))
        {

            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
                                   State, Context);
            if (ACPI_FAILURE (Status))
            {
                /* TBD: must delete package created up to this point */

                return_ACPI_STATUS (Status);
            }

            State->Pkg.Index++;
            while (State->Pkg.Index >= State->Pkg.SourceObject->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).
                 */
                AcpiUtDeleteGenericState (State);
                State = AcpiUtPopGenericState (&StateList);


                /* 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 sub-object of type package */

            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
                                   State, Context);
            if (ACPI_FAILURE (Status))
            {
                /* TBD: must delete package created up to this point */

                return_ACPI_STATUS (Status);
            }


            /*
             * The callback above returned a new target package object.
             */

            /*
             * Push the current state and create a new one
             */
            AcpiUtPushGenericState (&StateList, State);
            State = AcpiUtCreatePkgState (ThisSourceObj,
                                          State->Pkg.ThisTargetObj, 0);
            if (!State)
            {
                /* TBD: must delete package created up to this point */

                return_ACPI_STATUS (AE_NO_MEMORY);
            }
        }
    }

    /* We should never get here */

    return (AE_AML_INTERNAL);
}
Exemple #12
0
static ACPI_STATUS
AcpiNsDumpOneObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    ACPI_NAMESPACE_NODE     *ThisNode;
    UINT8                   *Value;
    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
    ACPI_OBJECT_TYPE8       ObjType;
    ACPI_OBJECT_TYPE8       Type;
    UINT32                  BytesToDump;
    UINT32                  DownstreamSiblingMask = 0;
    UINT32                  LevelTmp;
    UINT32                  WhichBit;


    PROC_NAME ("NsDumpOneObject");


    ThisNode = AcpiNsConvertHandleToEntry (ObjHandle);

    LevelTmp    = Level;
    Type        = ThisNode->Type;
    WhichBit    = 1;


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

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

    /* Check if the owner matches */

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


    /* Indent the object according to the level */

    while (LevelTmp--)
    {

        /* Print appropriate characters to form tree structure */

        if (LevelTmp)
        {
            if (DownstreamSiblingMask & WhichBit)
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|"));
            }

            else
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
            }

            WhichBit <<= 1;
        }

        else
        {
            if (AcpiNsExistDownstreamSibling (ThisNode + 1))
            {
                DownstreamSiblingMask |= (1 << (Level - 1));
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
            }

            else
            {
                DownstreamSiblingMask &= ACPI_UINT32_MAX ^ (1 << (Level - 1));
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
            }

            if (ThisNode->Child == NULL)
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-"));
            }

            else if (AcpiNsExistDownstreamSibling (ThisNode->Child))
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
            }

            else
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-"));
            }
        }
    }


    /* Check the integrity of our data */

    if (Type > INTERNAL_TYPE_MAX)
    {
        Type = INTERNAL_TYPE_DEF_ANY;                                /* prints as *ERROR* */
    }

    if (!AcpiUtValidAcpiName (ThisNode->Name))
    {
        REPORT_WARNING (("Invalid ACPI Name %08X\n", ThisNode->Name));
    }

    /*
     * Now we can print out the pertinent information
     */
    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-9s ", &ThisNode->Name, AcpiUtGetTypeName (Type)));
    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p S:%p O:%p",  ThisNode, ThisNode->Child, ThisNode->Object));


    if (!ThisNode->Object)
    {
        /* No attached object, we are done */

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
        return (AE_OK);
    }

    switch (Type)
    {

    case ACPI_TYPE_METHOD:

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

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Method.Pcode,
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Method.PcodeLength));

        break;


    case ACPI_TYPE_INTEGER:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Integer.Value));
        break;


    case ACPI_TYPE_STRING:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->String.Pointer,
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->String.Length));
        break;


    case ACPI_TYPE_BUFFER:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Buffer.Pointer,
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Buffer.Length));
        break;


    default:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
        break;
    }

    /* If debug turned off, done */

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


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

    Value = ThisNode->Object;

    /* Dump attached objects */

    while (Value)
    {
        ObjType = INTERNAL_TYPE_INVALID;

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

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "        Attached Object %p: ", Value));

        if (AcpiTbSystemTablePointer (Value))
        {
            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to AML Code)\n"));
            BytesToDump = 16;
        }

        else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED))
        {
            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n"));
            BytesToDump = sizeof (ACPI_NAMESPACE_NODE);
        }


        else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_INTERNAL))
        {
            ObjDesc = (ACPI_OPERAND_OBJECT  *) Value;
            ObjType = ObjDesc->Common.Type;

            if (ObjType > INTERNAL_TYPE_MAX)
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", ObjType));
                BytesToDump = 32;
            }

            else
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [%s])\n",
                                    ObjType, AcpiUtGetTypeName (ObjType)));
                BytesToDump = sizeof (ACPI_OPERAND_OBJECT);
            }
        }

        else
        {
            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n", Value));
            BytesToDump = 16;
        }

        DUMP_BUFFER (Value, BytesToDump);

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

        if ((AcpiTbSystemTablePointer (Value)) ||
            (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED)))
        {
            goto Cleanup;
        }

        /*
         * Valid object, get the pointer to next level, if any
         */
        switch (ObjType)
        {
        case ACPI_TYPE_STRING:
            Value = (UINT8 *) ObjDesc->String.Pointer;
            break;

        case ACPI_TYPE_BUFFER:
            Value = (UINT8 *) ObjDesc->Buffer.Pointer;
            break;

        case ACPI_TYPE_BUFFER_FIELD:
            Value = (UINT8 *) ObjDesc->BufferField.BufferObj;
            break;

        case ACPI_TYPE_PACKAGE:
            Value = (UINT8 *) ObjDesc->Package.Elements;
            break;

        case ACPI_TYPE_METHOD:
            Value = (UINT8 *) ObjDesc->Method.Pcode;
            break;

        case INTERNAL_TYPE_REGION_FIELD:
            Value = (UINT8 *) ObjDesc->Field.RegionObj;
            break;

        case INTERNAL_TYPE_BANK_FIELD:
            Value = (UINT8 *) ObjDesc->BankField.RegionObj;
            break;

        case INTERNAL_TYPE_INDEX_FIELD:
            Value = (UINT8 *) ObjDesc->IndexField.IndexObj;
            break;

       default:
            goto Cleanup;
        }

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

Cleanup:
    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
    return (AE_OK);
}
Exemple #13
0
ACPI_STATUS
AcpiDsStoreObjectToLocal (
    UINT16                  Opcode,
    UINT32                  Index,
    ACPI_OPERAND_OBJECT     *SrcDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;
    ACPI_OPERAND_OBJECT     **Entry;


    FUNCTION_TRACE ("DsMethodDataSetValue");
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n",
                       Opcode, Index, SrcDesc));


    /* Parameter validation */

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


    /* Get a pointer to the requested method stack entry */

    Status = AcpiDsMethodDataGetEntry (Opcode, Index, WalkState, &Entry);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    if (*Entry == SrcDesc)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", SrcDesc));
        goto Cleanup;
    }


    /*
     * If there is an object already in this slot, we either
     * have to delete it, or if this is an argument and there
     * is an object reference stored there, we have to do
     * an indirect store!
     */
    if (*Entry)
    {
        /*
         * Check for an indirect store if an argument
         * contains an object reference (stored as an Node).
         * We don't allow this automatic dereferencing for
         * locals, since a store to a local should overwrite
         * anything there, including an object reference.
         *
         * If both Arg0 and Local0 contain RefOf (Local4):
         *
         * Store (1, Arg0)             - Causes indirect store to local4
         * Store (1, Local0)           - Stores 1 in local0, overwriting
         *                                  the reference to local4
         * Store (1, DeRefof (Local0)) - Causes indirect store to local4
         *
         * Weird, but true.
         */
        if ((Opcode == AML_ARG_OP) &&
                (VALID_DESCRIPTOR_TYPE (*Entry, ACPI_DESC_TYPE_NAMED)))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
                               "Arg (%p) is an ObjRef(Node), storing in %p\n",
                               SrcDesc, *Entry));

            /* Detach an existing object from the Node */

            AcpiNsDetachObject ((ACPI_NAMESPACE_NODE *) *Entry);

            /*
             * Store this object into the Node
             * (do the indirect store)
             */
            Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) *Entry, SrcDesc,
                                         SrcDesc->Common.Type);
            return_ACPI_STATUS (Status);
        }


#ifdef ACPI_ENABLE_IMPLICIT_CONVERSION
        /*
         * Perform "Implicit conversion" of the new object to the type of the
         * existing object
         */
        Status = AcpiExConvertToTargetType ((*Entry)->Common.Type, &SrcDesc, WalkState);
        if (ACPI_FAILURE (Status))
        {
            goto Cleanup;
        }
#endif

        /*
         * Delete the existing object
         * before storing the new one
         */
        AcpiDsMethodDataDeleteValue (Opcode, Index, WalkState);
    }


    /*
     * Install the ObjStack descriptor (*SrcDesc) into
     * the descriptor for the Arg or Local.
     * Install the new object in the stack entry
     * (increments the object reference count by one)
     */
    Status = AcpiDsMethodDataSetEntry (Opcode, Index, SrcDesc, WalkState);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Normal exit */

    return_ACPI_STATUS (AE_OK);


    /* Error exit */

Cleanup:

    return_ACPI_STATUS (Status);
}
Exemple #14
0
ACPI_STATUS
AcpiUtGetSimpleObjectSize (
    ACPI_OPERAND_OBJECT     *InternalObject,
    UINT32                  *ObjLength)
{
    UINT32                  Length;
    ACPI_STATUS             Status = AE_OK;


    FUNCTION_TRACE_PTR ("UtGetSimpleObjectSize", InternalObject);


    /* Handle a null object (Could be a uninitialized package element -- which is legal) */

    if (!InternalObject)
    {
        *ObjLength = 0;
        return_ACPI_STATUS (AE_OK);
    }


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

    Length = sizeof (ACPI_OBJECT);

    if (VALID_DESCRIPTOR_TYPE (InternalObject, ACPI_DESC_TYPE_NAMED))
    {
        /* Object is a named object (reference), just return the length */

        *ObjLength = (UINT32) 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 (InternalObject->Common.Type)
    {

    case ACPI_TYPE_STRING:

        Length += InternalObject->String.Length + 1;
        break;


    case ACPI_TYPE_BUFFER:

        Length += InternalObject->Buffer.Length;
        break;


    case ACPI_TYPE_INTEGER:
    case ACPI_TYPE_PROCESSOR:
    case ACPI_TYPE_POWER:

        /*
         * No extra data for these types
         */
        break;


    case INTERNAL_TYPE_REFERENCE:

        /*
         * The only type that should be here is internal opcode NAMEPATH_OP -- since
         * this means an object reference
         */
        if (InternalObject->Reference.Opcode != AML_INT_NAMEPATH_OP)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                "Unsupported Reference opcode=%X in object %p\n",
                InternalObject->Reference.Opcode, InternalObject));
            Status = AE_TYPE;
        }

        else
        {
            /*
             * Get the actual length of the full pathname to this object.
             * The reference will be converted to the pathname to the object
             */
            Length += ROUND_UP_TO_NATIVE_WORD (AcpiNsGetPathnameLength (InternalObject->Reference.Node));
        }
        break;


    default:

        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n",
            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 = (UINT32) ROUND_UP_TO_NATIVE_WORD (Length);

    return_ACPI_STATUS (Status);
}
Exemple #15
0
acpi_status
acpi_ds_store_object_to_local (
    u16                     opcode,
    u32                     index,
    acpi_operand_object     *src_desc,
    acpi_walk_state         *walk_state)
{
    acpi_status             status;
    acpi_operand_object     **entry;


    FUNCTION_TRACE ("Ds_method_data_set_value");
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n",
                       opcode, index, src_desc));


    /* Parameter validation */

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


    /* Get a pointer to the requested method stack entry */

    status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
    if (ACPI_FAILURE (status)) {
        goto cleanup;
    }

    if (*entry == src_desc) {
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", src_desc));
        goto cleanup;
    }


    /*
     * If there is an object already in this slot, we either
     * have to delete it, or if this is an argument and there
     * is an object reference stored there, we have to do
     * an indirect store!
     */
    if (*entry) {
        /*
         * Check for an indirect store if an argument
         * contains an object reference (stored as an Node).
         * We don't allow this automatic dereferencing for
         * locals, since a store to a local should overwrite
         * anything there, including an object reference.
         *
         * If both Arg0 and Local0 contain Ref_of (Local4):
         *
         * Store (1, Arg0)             - Causes indirect store to local4
         * Store (1, Local0)           - Stores 1 in local0, overwriting
         *                                  the reference to local4
         * Store (1, De_refof (Local0)) - Causes indirect store to local4
         *
         * Weird, but true.
         */
        if ((opcode == AML_ARG_OP) &&
                (VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED))) {
            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
                               "Arg (%p) is an Obj_ref(Node), storing in %p\n",
                               src_desc, *entry));

            /* Detach an existing object from the Node */

            acpi_ns_detach_object ((acpi_namespace_node *) *entry);

            /*
             * Store this object into the Node
             * (do the indirect store)
             */
            status = acpi_ns_attach_object ((acpi_namespace_node *) *entry, src_desc,
                                            src_desc->common.type);
            return_ACPI_STATUS (status);
        }


#ifdef ACPI_ENABLE_IMPLICIT_CONVERSION
        /*
         * Perform "Implicit conversion" of the new object to the type of the
         * existing object
         */
        status = acpi_ex_convert_to_target_type ((*entry)->common.type, &src_desc, walk_state);
        if (ACPI_FAILURE (status)) {
            goto cleanup;
        }
#endif

        /*
         * Delete the existing object
         * before storing the new one
         */
        acpi_ds_method_data_delete_value (opcode, index, walk_state);
    }


    /*
     * Install the Obj_stack descriptor (*Src_desc) into
     * the descriptor for the Arg or Local.
     * Install the new object in the stack entry
     * (increments the object reference count by one)
     */
    status = acpi_ds_method_data_set_entry (opcode, index, src_desc, walk_state);
    if (ACPI_FAILURE (status)) {
        goto cleanup;
    }

    /* Normal exit */

    return_ACPI_STATUS (AE_OK);


    /* Error exit */

cleanup:

    return_ACPI_STATUS (status);
}
Exemple #16
0
ACPI_STATUS
acpi_ds_method_data_set_value (
	u32                     type,
	u32                     index,
	ACPI_OPERAND_OBJECT     *src_desc,
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_STATUS             status;
	ACPI_OPERAND_OBJECT     **entry;


	/* Parameter validation */

	if (!src_desc) {
		return (AE_BAD_PARAMETER);
	}


	/* Get a pointer to the requested method stack entry */

	status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	if (*entry == src_desc) {
		goto cleanup;
	}


	/*
	 * If there is an object already in this slot, we either
	 * have to delete it, or if this is an argument and there
	 * is an object reference stored there, we have to do
	 * an indirect store!
	 */

	if (*entry) {
		/*
		 * Check for an indirect store if an argument
		 * contains an object reference (stored as an Node).
		 * We don't allow this automatic dereferencing for
		 * locals, since a store to a local should overwrite
		 * anything there, including an object reference.
		 *
		 * If both Arg0 and Local0 contain Ref_of (Local4):
		 *
		 * Store (1, Arg0)             - Causes indirect store to local4
		 * Store (1, Local0)           - Stores 1 in local0, overwriting
		 *                                  the reference to local4
		 * Store (1, De_refof (Local0)) - Causes indirect store to local4
		 *
		 * Weird, but true.
		 */

		if ((type == MTH_TYPE_ARG) &&
			(VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED)))
		{
			/* Detach an existing object from the Node */

			acpi_ns_detach_object ((ACPI_NAMESPACE_NODE *) *entry);

			/*
			 * Store this object into the Node
			 * (do the indirect store)
			 */

			status = acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) *entry, src_desc,
					   src_desc->common.type);
			return (status);
		}


		/*
		 * Otherwise, just delete the existing object
		 * before storing the new one
		 */

		acpi_ds_method_data_delete_value (type, index, walk_state);
	}


	/*
	 * Install the Obj_stack descriptor (*Src_desc) into
	 * the descriptor for the Arg or Local.
	 * Install the new object in the stack entry
	 * (increments the object reference count by one)
	 */

	status = acpi_ds_method_data_set_entry (type, index, src_desc, walk_state);
	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	/* Normal exit */

	return (AE_OK);


	/* Error exit */

cleanup:

	return (status);
}
Exemple #17
0
ACPI_STATUS
acpi_evaluate_object (
	ACPI_HANDLE             handle,
	ACPI_STRING             pathname,
	ACPI_OBJECT_LIST        *param_objects,
	ACPI_BUFFER             *return_buffer)
{
	ACPI_STATUS             status;
	ACPI_OPERAND_OBJECT     **param_ptr = NULL;
	ACPI_OPERAND_OBJECT     *return_obj = NULL;
	ACPI_OPERAND_OBJECT     *object_ptr = NULL;
	u32                     buffer_space_needed;
	u32                     user_buffer_length;
	u32                     count;
	u32                     i;
	u32                     param_length;
	u32                     object_length;


	/*
	 * 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 (param_objects && param_objects->count) {
		/*
		 * Allocate a new parameter block for the internal objects
		 * Add 1 to count to allow for null terminated internal list
		 */

		count           = param_objects->count;
		param_length    = (count + 1) * sizeof (void *);
		object_length   = count * sizeof (ACPI_OPERAND_OBJECT);

		param_ptr = acpi_cm_callocate (param_length + /* Parameter List part */
				  object_length); /* Actual objects */
		if (!param_ptr) {
			return (AE_NO_MEMORY);
		}

		object_ptr = (ACPI_OPERAND_OBJECT *) ((u8 *) param_ptr +
				  param_length);

		/*
		 * Init the param array of pointers and NULL terminate
		 * the list
		 */

		for (i = 0; i < count; i++) {
			param_ptr[i] = &object_ptr[i];
			acpi_cm_init_static_object (&object_ptr[i]);
		}
		param_ptr[count] = NULL;

		/*
		 * Convert each external object in the list to an
		 * internal object
		 */
		for (i = 0; i < count; i++) {
			status =
				acpi_cm_build_internal_object (&param_objects->pointer[i],
						  param_ptr[i]);

			if (ACPI_FAILURE (status)) {
				acpi_cm_delete_internal_object_list (param_ptr);
				return (status);
			}
		}
	}


	/*
	 * 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, param_ptr, &return_obj);
	}

	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
		 */



		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 (handle, param_ptr, &return_obj);
		}

		else {
		   /*
			* Both a Handle and a relative Pathname
			*/
			status = acpi_ns_evaluate_relative (handle, pathname, param_ptr,
					 &return_obj);
		}
	}


	/*
	 * If we are expecting a return value, and all went well above,
	 * copy the return value to an external object.
	 */

	if (return_buffer) {
		user_buffer_length = return_buffer->length;
		return_buffer->length = 0;

		if (return_obj) {
			if (VALID_DESCRIPTOR_TYPE (return_obj, ACPI_DESC_TYPE_NAMED)) {
				/*
				 * If we got an Node as a return object,
				 * this means 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;
				return_obj = NULL;  /* No need to delete an Node */
			}

			if (ACPI_SUCCESS (status)) {
				/*
				 * Find out how large a buffer is needed
				 * to contain the returned object
				 */
				status = acpi_cm_get_object_size (return_obj,
						   &buffer_space_needed);
				if (ACPI_SUCCESS (status)) {
					/*
					 * Check if there is enough room in the
					 * caller's buffer
					 */

					if (user_buffer_length < buffer_space_needed) {
						/*
						 * Caller's buffer is too small, can't
						 * give him partial results fail the call
						 * but return the buffer size needed
						 */

						return_buffer->length = buffer_space_needed;
						status = AE_BUFFER_OVERFLOW;
					}

					else {
						/*
						 *  We have enough space for the object, build it
						 */
						status = acpi_cm_build_external_object (return_obj,
								  return_buffer);
						return_buffer->length = buffer_space_needed;
					}
				}
			}
		}
	}


	/* Delete the return and parameter objects */

	if (return_obj) {
		/*
		 * Delete the internal return object. (Or at least
		 * decrement the reference count by one)
		 */
		acpi_cm_remove_reference (return_obj);
	}

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

	if (param_ptr) {
		/* Free the allocated parameter block */

		acpi_cm_delete_internal_object_list (param_ptr);
	}

	return (status);
}
Exemple #18
0
ACPI_STATUS
acpi_aml_resolve_operands (
	u16                     opcode,
	ACPI_OPERAND_OBJECT     **stack_ptr,
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_STATUS             status = AE_OK;
	u8                      object_type;
	ACPI_HANDLE             temp_handle;
	u32                     arg_types;
	ACPI_OPCODE_INFO        *op_info;
	u32                     this_arg_type;
	ACPI_OBJECT_TYPE        type_needed;


	op_info = acpi_ps_get_opcode_info (opcode);
	if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
		return (AE_AML_BAD_OPCODE);
	}


	arg_types = op_info->runtime_args;
	if (arg_types == ARGI_INVALID_OPCODE) {
		return (AE_AML_INTERNAL);
	}


   /*
	 * Normal exit is with *Types == '\0' at end of string.
	 * Function will return an exception from within the loop upon
	 * finding an entry which is not, and cannot be converted
	 * to, the required type; if stack underflows; or upon
	 * finding a NULL stack entry (which "should never happen").
	 */

	while (GET_CURRENT_ARG_TYPE (arg_types)) {
		if (!stack_ptr || !*stack_ptr) {
			return (AE_AML_INTERNAL);
		}

		/* Extract useful items */

		obj_desc = *stack_ptr;

		/* Decode the descriptor type */

		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
			/* Node */

			object_type = ((ACPI_NAMESPACE_NODE *) obj_desc)->type;
		}

		else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
			/* ACPI internal object */

			object_type = obj_desc->common.type;

			/* Check for bad ACPI_OBJECT_TYPE */

			if (!acpi_aml_validate_object_type (object_type)) {
				return (AE_AML_OPERAND_TYPE);
			}

			if (object_type == (u8) INTERNAL_TYPE_REFERENCE) {
				/*
				 * Decode the Reference
				 */

				op_info = acpi_ps_get_opcode_info (opcode);
				if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
					return (AE_AML_BAD_OPCODE);
				}


				switch (obj_desc->reference.op_code)
				{
				case AML_ZERO_OP:
				case AML_ONE_OP:
				case AML_ONES_OP:
				case AML_DEBUG_OP:
				case AML_NAME_OP:
				case AML_INDEX_OP:
				case AML_ARG_OP:
				case AML_LOCAL_OP:

					break;

				default:
					return (AE_AML_OPERAND_TYPE);
					break;
				}
			}
		}

		else {
			/* Invalid descriptor */

			return (AE_AML_OPERAND_TYPE);
		}


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

		this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
		INCREMENT_ARG_LIST (arg_types);


		/*
		 * Handle cases where the object does not need to be
		 * resolved to a value
		 */

		switch (this_arg_type)
		{

		case ARGI_REFERENCE:   /* Reference */
		case ARGI_TARGETREF:

			/* Need an operand of type INTERNAL_TYPE_REFERENCE */

			if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED))            /* direct name ptr OK as-is */ {
				goto next_operand;
			}

			status = acpi_aml_check_object_type (INTERNAL_TYPE_REFERENCE,
					  object_type, obj_desc);
			if (ACPI_FAILURE (status)) {
				return (status);
			}


			if (AML_NAME_OP == obj_desc->reference.op_code) {
				/*
				 * Convert an indirect name ptr to direct name ptr and put
				 * it on the stack
				 */

				temp_handle = obj_desc->reference.object;
				acpi_cm_remove_reference (obj_desc);
				(*stack_ptr) = temp_handle;
			}

			goto next_operand;
			break;


		case ARGI_ANYTYPE:

			/*
			 * We don't want to resolve Index_op reference objects during
			 * a store because this would be an implicit De_ref_of operation.
			 * Instead, we just want to store the reference object.
			 * -- All others must be resolved below.
			 */

			if ((opcode == AML_STORE_OP) &&
				((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
				((*stack_ptr)->reference.op_code == AML_INDEX_OP))
			{
				goto next_operand;
			}
			break;
		}


		/*
		 * Resolve this object to a value
		 */

		status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
		if (ACPI_FAILURE (status)) {
			return (status);
		}


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

			/* Need an operand of type ACPI_TYPE_NUMBER */

			type_needed = ACPI_TYPE_NUMBER;
			break;

		case ARGI_BUFFER:

			/* Need an operand of type ACPI_TYPE_BUFFER */

			type_needed = ACPI_TYPE_BUFFER;
			break;

		case ARGI_MUTEX:

			/* Need an operand of type ACPI_TYPE_MUTEX */

			type_needed = ACPI_TYPE_MUTEX;
			break;

		case ARGI_EVENT:

			/* Need an operand of type ACPI_TYPE_EVENT */

			type_needed = ACPI_TYPE_EVENT;
			break;

		case ARGI_REGION:

			/* Need an operand of type ACPI_TYPE_REGION */

			type_needed = ACPI_TYPE_REGION;
			break;

		case ARGI_IF:   /* If */

			/* Need an operand of type INTERNAL_TYPE_IF */

			type_needed = INTERNAL_TYPE_IF;
			break;

		case ARGI_PACKAGE:   /* Package */

			/* Need an operand of type ACPI_TYPE_PACKAGE */

			type_needed = ACPI_TYPE_PACKAGE;
			break;

		case ARGI_ANYTYPE:

			/* Any operand type will do */

			type_needed = ACPI_TYPE_ANY;
			break;


		/*
		 * The more complex cases allow multiple resolved object types
		 */

		case ARGI_STRING:

			/* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */

			if ((ACPI_TYPE_STRING != (*stack_ptr)->common.type) &&
				(ACPI_TYPE_BUFFER != (*stack_ptr)->common.type))
			{
				return (AE_AML_OPERAND_TYPE);
			}
			goto next_operand;
			break;


		case ARGI_DATAOBJECT:
			/*
			 * ARGI_DATAOBJECT is only used by the Size_of operator.
			 *
			 * The ACPI specification allows Size_of to return the size of
			 *  a Buffer, String or Package.  However, the MS ACPI.SYS AML
			 *  Interpreter also allows an Node reference to return without
			 *  error with a size of 4.
			 */

			/* Need a buffer, string, package or Node reference */

			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
				((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) &&
				((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE))
			{
				return (AE_AML_OPERAND_TYPE);
			}

			/*
			 * If this is a reference, only allow a reference to an Node.
			 */
			if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
				if (!(*stack_ptr)->reference.node) {
					return (AE_AML_OPERAND_TYPE);
				}
			}
			goto next_operand;
			break;


		case ARGI_COMPLEXOBJ:

			/* Need a buffer or package */

			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE))
			{
				return (AE_AML_OPERAND_TYPE);
			}
			goto next_operand;
			break;


		default:

			/* Unknown type */

			return (AE_BAD_PARAMETER);
		}


		/*
		 * Make sure that the original object was resolved to the
		 * required object type (Simple cases only).
		 */
		status = acpi_aml_check_object_type (type_needed,
				  (*stack_ptr)->common.type, *stack_ptr);
		if (ACPI_FAILURE (status)) {
			return (status);
		}


next_operand:
		/*
		 * If more operands needed, decrement Stack_ptr to point
		 * to next operand on stack
		 */
		if (GET_CURRENT_ARG_TYPE (arg_types)) {
			stack_ptr--;
		}

	}   /* while (*Types) */


	return (status);
}
Exemple #19
0
acpi_status
acpi_ut_walk_package_tree (
	acpi_operand_object     *source_object,
	void                    *target_object,
	ACPI_PKG_CALLBACK       walk_callback,
	void                    *context)
{
	acpi_status             status = AE_OK;
	acpi_generic_state      *state_list = NULL;
	acpi_generic_state      *state;
	u32                     this_index;
	acpi_operand_object     *this_source_obj;


	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) {
		this_index    = state->pkg.index;
		this_source_obj = (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) ||
			(!VALID_DESCRIPTOR_TYPE (
					this_source_obj, ACPI_DESC_TYPE_INTERNAL)) ||
			(!IS_THIS_OBJECT_TYPE (
					this_source_obj, ACPI_TYPE_PACKAGE))) {

			status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
					 state, context);
			if (ACPI_FAILURE (status)) {
				/* TBD: must delete package created up to this point */

				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 sub-object of type package */

			status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
					  state, context);
			if (ACPI_FAILURE (status)) {
				/* TBD: must delete package created up to this point */

				return_ACPI_STATUS (status);
			}


			/*
			 * The callback above returned a new target package object.
			 */

			/*
			 * Push the current state and create a new one
			 */
			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) {
				/* TBD: must delete package created up to this point */

				return_ACPI_STATUS (AE_NO_MEMORY);
			}
		}
	}

	/* We should never get here */

	return (AE_AML_INTERNAL);
}
acpi_status
acpi_ut_get_simple_object_size (
	acpi_operand_object     *internal_object,
	u32                     *obj_length)
{
	u32                     length;
	acpi_status             status = AE_OK;


	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 = 0;
		return_ACPI_STATUS (AE_OK);
	}


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

	length = sizeof (acpi_object);

	if (VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_NAMED)) {
		/* Object is a named object (reference), just return the length */

		*obj_length = (u32) 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 += internal_object->string.length + 1;
		break;


	case ACPI_TYPE_BUFFER:

		length += 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 INTERNAL_TYPE_REFERENCE:

		/*
		 * The only type that should be here is internal opcode NAMEPATH_OP -- since
		 * this means an object reference
		 */
		if (internal_object->reference.opcode != AML_INT_NAMEPATH_OP) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Unsupported Reference opcode=%X in object %p\n",
				internal_object->reference.opcode, internal_object));
			status = AE_TYPE;
		}

		else {
			/*
			 * Get the actual length of the full pathname to this object.
			 * The reference will be converted to the pathname to the object
			 */
			length += ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node));
		}
		break;


	default:

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n",
			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 = (u32) ROUND_UP_TO_NATIVE_WORD (length);

	return_ACPI_STATUS (status);
}