Example #1
0
void
AcpiUtInitStaticObject (
    ACPI_OPERAND_OBJECT     *ObjDesc)
{

    FUNCTION_TRACE_PTR ("UtInitStaticObject", ObjDesc);


    if (!ObjDesc)
    {
        return_VOID;
    }


    /*
     * Clear the entire descriptor
     */
    MEMSET ((void *) ObjDesc, 0, sizeof (ACPI_OPERAND_OBJECT));


    /*
     * Initialize the header fields
     * 1) This is an ACPI_OPERAND_OBJECT  descriptor
     * 2) The size is the full object (worst case)
     * 3) The flags field indicates static allocation
     * 4) Reference count starts at one (not really necessary since the
     *    object can't be deleted, but keeps everything sane)
     */

    ObjDesc->Common.DataType        = ACPI_DESC_TYPE_INTERNAL;
    ObjDesc->Common.Flags           = AOPOBJ_STATIC_ALLOCATION;
    ObjDesc->Common.ReferenceCount  = 1;

    return_VOID;
}
Example #2
0
ACPI_GENERIC_STATE *
AcpiUtCreateUpdateState (
    ACPI_OPERAND_OBJECT     *Object,
    UINT16                  Action)
{
    ACPI_GENERIC_STATE      *State;


    FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object);


    /* Create the generic state object */

    State = AcpiUtCreateGenericState ();
    if (!State)
    {
        return (NULL);
    }

    /* Init fields specific to the update struct */

    State->Update.Object = Object;
    State->Update.Value  = Action;

    return_PTR (State);
}
Example #3
0
acpi_generic_state *
acpi_ut_create_pkg_state (
	void                    *internal_object,
	void                    *external_object,
	u16                     index)
{
	acpi_generic_state      *state;


	FUNCTION_TRACE_PTR ("Ut_create_pkg_state", internal_object);


	/* Create the generic state object */

	state = acpi_ut_create_generic_state ();
	if (!state) {
		return (NULL);
	}

	/* Init fields specific to the update struct */

	state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE;
	state->pkg.source_object = (acpi_operand_object *) internal_object;
	state->pkg.dest_object  = external_object;
	state->pkg.index        = index;
	state->pkg.num_packages = 1;

	return_PTR (state);
}
Example #4
0
void
AcpiUtFree (
    void                    *Address,
    UINT32                  Component,
    NATIVE_CHAR             *Module,
    UINT32                  Line)
{
    ACPI_DEBUG_MEM_BLOCK    *DebugBlock;


    FUNCTION_TRACE_PTR ("UtFree", Address);


    if (NULL == Address)
    {
        _REPORT_ERROR (Module, Line, Component,
            ("AcpiUtFree: Trying to delete a NULL address\n"));

        return_VOID;
    }

    DebugBlock = (ACPI_DEBUG_MEM_BLOCK *)
                    (((char *) Address) - sizeof (ACPI_DEBUG_MEM_HEADER));

    AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].TotalFreed++;
    AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].CurrentTotalSize -= DebugBlock->Size;

    AcpiUtDeleteElementFromAllocList (ACPI_MEM_LIST_GLOBAL, DebugBlock,
            Component, Module, Line);
    AcpiOsFree (DebugBlock);

    ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", Address));

    return_VOID;
}
Example #5
0
acpi_generic_state *
acpi_ut_create_update_state (
	acpi_operand_object     *object,
	u16                     action)
{
	acpi_generic_state      *state;


	FUNCTION_TRACE_PTR ("Ut_create_update_state", object);


	/* Create the generic state object */

	state = acpi_ut_create_generic_state ();
	if (!state) {
		return (NULL);
	}

	/* Init fields specific to the update struct */

	state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE;
	state->update.object = object;
	state->update.value  = action;

	return_PTR (state);
}
acpi_status
acpi_ut_get_package_object_size (
	acpi_operand_object     *internal_object,
	u32                     *obj_length)
{
	acpi_status             status;
	acpi_pkg_info           info;


	FUNCTION_TRACE_PTR ("Ut_get_package_object_size", internal_object);


	info.length      = 0;
	info.object_space = 0;
	info.num_packages = 1;

	status = acpi_ut_walk_package_tree (internal_object, NULL,
			 acpi_ut_get_element_length, &info);

	/*
	 * We have handled all of the objects in all levels of the package.
	 * just add the length of the package objects themselves.
	 * Round up to the next machine word.
	 */
	info.length += ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object)) *
			  info.num_packages;

	/* Return the total package length */

	*obj_length = info.length;
	return_ACPI_STATUS (status);
}
Example #7
0
ACPI_GENERIC_STATE *
AcpiUtCreatePkgState (
    void                    *InternalObject,
    void                    *ExternalObject,
    UINT16                  Index)
{
    ACPI_GENERIC_STATE      *State;


    FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject);


    /* Create the generic state object */

    State = AcpiUtCreateGenericState ();
    if (!State)
    {
        return (NULL);
    }

    /* Init fields specific to the update struct */

    State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
    State->Pkg.DestObject   = ExternalObject;
    State->Pkg.Index        = Index;
    State->Pkg.NumPackages  = 1;

    return_PTR (State);
}
Example #8
0
ACPI_STATUS
AcpiUtGetPackageObjectSize (
    ACPI_OPERAND_OBJECT     *InternalObject,
    UINT32                  *ObjLength)
{
    ACPI_STATUS             Status;
    ACPI_PKG_INFO           Info;


    FUNCTION_TRACE_PTR ("UtGetPackageObjectSize", InternalObject);


    Info.Length      = 0;
    Info.ObjectSpace = 0;
    Info.NumPackages = 1;

    Status = AcpiUtWalkPackageTree (InternalObject, NULL,
                            AcpiUtGetElementLength, &Info);

    /*
     * We have handled all of the objects in all levels of the package.
     * just add the length of the package objects themselves.
     * Round up to the next machine word.
     */
    Info.Length += ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
                    Info.NumPackages;

    /* Return the total package length */

    *ObjLength = Info.Length;
    return_ACPI_STATUS (Status);
}
Example #9
0
void
acpi_tb_free_acpi_tables_of_type (
    acpi_table_desc         *list_head)
{
    acpi_table_desc         *table_desc;
    u32                     count;
    u32                     i;


    FUNCTION_TRACE_PTR ("Tb_free_acpi_tables_of_type", list_head);


    /* Get the head of the list */

    table_desc  = list_head;
    count       = list_head->count;

    /*
     * Walk the entire list, deleting both the allocated tables
     * and the table descriptors
     */
    for (i = 0; i < count; i++) {
        table_desc = acpi_tb_uninstall_table (table_desc);
    }

    return_VOID;
}
Example #10
0
acpi_status
acpi_ns_get_node (
	NATIVE_CHAR             *pathname,
	acpi_namespace_node     *start_node,
	acpi_namespace_node     **return_node)
{
	acpi_generic_state      scope_info;
	acpi_status             status;
	NATIVE_CHAR             *internal_path = NULL;


	FUNCTION_TRACE_PTR ("Ns_get_node", pathname);


	/* Ensure that the namespace has been initialized */

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

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


	/* Convert path to internal representation */

	status = acpi_ns_internalize_name (pathname, &internal_path);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}


	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);

	/* Setup lookup scope (search starting point) */

	scope_info.scope.node = start_node;

	/* Lookup the name in the namespace */

	status = acpi_ns_lookup (&scope_info, internal_path,
			 ACPI_TYPE_ANY, IMODE_EXECUTE,
			 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
			 NULL, return_node);

	if (ACPI_FAILURE (status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n",
				internal_path, acpi_format_exception (status)));
	}


	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);

	/* Cleanup */

	ACPI_MEM_FREE (internal_path);
	return_ACPI_STATUS (status);
}
Example #11
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);
}
Example #12
0
acpi_table_desc *
acpi_tb_uninstall_table (
    acpi_table_desc         *table_desc)
{
    acpi_table_desc         *next_desc;


    FUNCTION_TRACE_PTR ("Tb_delete_single_table", table_desc);


    if (!table_desc) {
        return_PTR (NULL);
    }


    /* Unlink the descriptor */

    if (table_desc->prev) {
        table_desc->prev->next = table_desc->next;
    }

    if (table_desc->next) {
        table_desc->next->prev = table_desc->prev;
    }


    /* Free the memory allocated for the table itself */

    acpi_tb_delete_single_table (table_desc);


    /* Free the table descriptor (Don't delete the list head, tho) */

    if ((table_desc->prev) == (table_desc->next)) {

        next_desc = NULL;

        /* Clear the list head */

        table_desc->pointer  = NULL;
        table_desc->length   = 0;
        table_desc->count    = 0;

    }

    else {
        /* Free the table descriptor */

        next_desc = table_desc->next;
        ACPI_MEM_FREE (table_desc);
    }


    return_PTR (next_desc);
}
Example #13
0
acpi_status
acpi_ex_acquire_mutex (
	acpi_operand_object     *time_desc,
	acpi_operand_object     *obj_desc,
	acpi_walk_state         *walk_state)
{
	acpi_status             status;


	FUNCTION_TRACE_PTR ("Ex_acquire_mutex", obj_desc);

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

	/*
	 * Current Sync must be less than or equal to the sync level of the
	 * mutex.  This mechanism provides some deadlock prevention
	 */
	if (walk_state->current_sync_level > obj_desc->mutex.sync_level) {
		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
	}

	/*
	 * If the mutex is already owned by this thread,
	 * just increment the acquisition depth
	 */
	if (obj_desc->mutex.owner == walk_state) {
		obj_desc->mutex.acquisition_depth++;
		return_ACPI_STATUS (AE_OK);
	}

	/* Acquire the mutex, wait if necessary */

	status = acpi_ex_system_acquire_mutex (time_desc, obj_desc);
	if (ACPI_FAILURE (status)) {
		/* Includes failure from a timeout on Time_desc */

		return_ACPI_STATUS (status);
	}

	/* Have the mutex, update mutex and walk info */

	obj_desc->mutex.owner = walk_state;
	obj_desc->mutex.acquisition_depth = 1;
	walk_state->current_sync_level = obj_desc->mutex.sync_level;

	/* Link the mutex to the walk state for force-unlock at method exit */

	acpi_ex_link_mutex (obj_desc, (acpi_operand_object *)
			 &(walk_state->walk_list->acquired_mutex_list));

	return_ACPI_STATUS (AE_OK);
}
Example #14
0
ACPI_STATUS
AcpiDsMethodDataInitArgs (
    ACPI_OPERAND_OBJECT     **Params,
    UINT32                  MaxParamCount,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;
    UINT32                  Mindex;
    UINT32                  Pindex;


    FUNCTION_TRACE_PTR ("DsMethodDataInitArgs", Params);


    if (!Params)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
        return_ACPI_STATUS (AE_OK);
    }

    /* Copy passed parameters into the new method stack frame  */

    for (Pindex = Mindex = 0;
            (Mindex < MTH_NUM_ARGS) && (Pindex < MaxParamCount);
            Mindex++)
    {
        if (Params[Pindex])
        {
            /*
             * A valid parameter.
             * Set the current method argument to the
             * Params[Pindex++] argument object descriptor
             */
            Status = AcpiDsStoreObjectToLocal (AML_ARG_OP, Mindex,
                                               Params[Pindex], WalkState);
            if (ACPI_FAILURE (Status))
            {
                break;
            }

            Pindex++;
        }

        else
        {
            break;
        }
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Pindex));
    return_ACPI_STATUS (AE_OK);
}
Example #15
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);
}
Example #16
0
acpi_status
acpi_ds_method_data_init_args (
    acpi_operand_object     **params,
    u32                     max_param_count,
    acpi_walk_state         *walk_state)
{
    acpi_status             status;
    u32                     mindex;
    u32                     pindex;


    FUNCTION_TRACE_PTR ("Ds_method_data_init_args", params);


    if (!params) {
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
        return_ACPI_STATUS (AE_OK);
    }

    /* Copy passed parameters into the new method stack frame  */

    for (pindex = mindex = 0;
            (mindex < MTH_NUM_ARGS) && (pindex < max_param_count);
            mindex++) {
        if (params[pindex]) {
            /*
             * A valid parameter.
             * Set the current method argument to the
             * Params[Pindex++] argument object descriptor
             */
            status = acpi_ds_store_object_to_local (AML_ARG_OP, mindex,
                                                    params[pindex], walk_state);
            if (ACPI_FAILURE (status)) {
                break;
            }

            pindex++;
        }

        else {
            break;
        }
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", pindex));
    return_ACPI_STATUS (AE_OK);
}
void
acpi_ut_delete_object_desc (
	acpi_operand_object     *object)
{
	FUNCTION_TRACE_PTR ("Ut_delete_object_desc", object);


	/* Object must be an acpi_operand_object  */

	if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Obj %p is not an ACPI object\n", object));
		return_VOID;
	}

	acpi_ut_release_to_cache (ACPI_MEM_LIST_OPERAND, object);

	return_VOID;
}
Example #18
0
void
AcpiUtDeleteObjectDesc (
    ACPI_OPERAND_OBJECT     *Object)
{
    FUNCTION_TRACE_PTR ("UtDeleteObjectDesc", Object);


    /* Object must be an ACPI_OPERAND_OBJECT  */

    if (Object->Common.DataType != ACPI_DESC_TYPE_INTERNAL)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
            "Obj %p is not an ACPI object\n", Object));
        return_VOID;
    }

    AcpiUtReleaseToCache (ACPI_MEM_LIST_OPERAND, Object);

    return_VOID;
}
Example #19
0
ACPI_PARSE_OBJECT *
AcpiPsGetNextArg (
    ACPI_PARSE_STATE        *ParserState,
    UINT32                  ArgType,
    UINT32                  *ArgCount)
{
    ACPI_PARSE_OBJECT       *Arg = NULL;
    ACPI_PARSE_OBJECT       *Prev = NULL;
    ACPI_PARSE_OBJECT       *Field;
    UINT32                  Subop;


    FUNCTION_TRACE_PTR ("PsGetNextArg", ParserState);


    switch (ArgType)
    {
    case ARGP_BYTEDATA:
    case ARGP_WORDDATA:
    case ARGP_DWORDDATA:
    case ARGP_CHARLIST:
    case ARGP_NAME:
    case ARGP_NAMESTRING:

        /* constants, strings, and namestrings are all the same size */

        Arg = AcpiPsAllocOp (AML_BYTE_OP);
        if (Arg)
        {
            AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
        }
        break;


    case ARGP_PKGLENGTH:

        /* package length, nothing returned */

        ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
        break;


    case ARGP_FIELDLIST:

        if (ParserState->Aml < ParserState->PkgEnd)
        {
            /* non-empty list */

            while (ParserState->Aml < ParserState->PkgEnd)
            {
                Field = AcpiPsGetNextField (ParserState);
                if (!Field)
                {
                    break;
                }

                if (Prev)
                {
                    Prev->Next = Field;
                }

                else
                {
                    Arg = Field;
                }

                Prev = Field;
            }

            /* skip to End of byte data */

            ParserState->Aml = ParserState->PkgEnd;
        }
        break;


    case ARGP_BYTELIST:

        if (ParserState->Aml < ParserState->PkgEnd)
        {
            /* non-empty list */

            Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
            if (Arg)
            {
                /* fill in bytelist data */

                Arg->Value.Size = (ParserState->PkgEnd - ParserState->Aml);
                ((ACPI_PARSE2_OBJECT *) Arg)->Data = ParserState->Aml;
            }

            /* skip to End of byte data */

            ParserState->Aml = ParserState->PkgEnd;
        }
        break;


    case ARGP_TARGET:
    case ARGP_SUPERNAME:
        {
            Subop = AcpiPsPeekOpcode (ParserState);
            if (Subop == 0              ||
                AcpiPsIsLeadingChar (Subop) ||
                AcpiPsIsPrefixChar (Subop))
            {
                /* NullName or NameString */

                Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
                if (Arg)
                {
                    AcpiPsGetNextNamepath (ParserState, Arg, ArgCount, 0);
                }
            }

            else
            {
                /* single complex argument, nothing returned */

                *ArgCount = 1;
            }
        }
        break;


    case ARGP_DATAOBJ:
    case ARGP_TERMARG:

        /* single complex argument, nothing returned */

        *ArgCount = 1;
        break;


    case ARGP_DATAOBJLIST:
    case ARGP_TERMLIST:
    case ARGP_OBJLIST:

        if (ParserState->Aml < ParserState->PkgEnd)
        {
            /* non-empty list of variable arguments, nothing returned */

            *ArgCount = ACPI_VAR_ARGS;
        }
        break;
    }

    return_PTR (Arg);
}
Example #20
0
static ACPI_STATUS
AcpiPsNextParseState (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op,
    ACPI_STATUS             CallbackStatus)
{
    ACPI_PARSE_STATE        *ParserState = WalkState->ParserState;
    ACPI_STATUS             Status = AE_CTRL_PENDING;
    UINT8                   *Start;
    UINT32                  PackageLength;


    FUNCTION_TRACE_PTR ("PsNextParseState", Op);


    switch (CallbackStatus)
    {
    case AE_CTRL_TERMINATE:

        /*
         * A control method was terminated via a RETURN statement.
         * The walk of this method is complete.
         */
        ParserState->Aml = ParserState->AmlEnd;
        Status = AE_CTRL_TERMINATE;
        break;


    case AE_CTRL_PENDING:

        /*
         * Predicate of a WHILE was true and the loop just completed an
         * execution.  Go back to the start of the loop and reevaluate the
         * predicate.
         */

        /* TBD: How to handle a break within a while. */
        /* This code attempts it */

        ParserState->Aml = WalkState->AmlLastWhile;
        break;


    case AE_CTRL_TRUE:
        /*
         * Predicate of an IF was true, and we are at the matching ELSE.
         * Just close out this package
         *
         * Note: ParserState->Aml is modified by the package length procedure
         * TBD: [Investigate] perhaps it shouldn't, too much trouble
         */
        Start = ParserState->Aml;
        PackageLength = AcpiPsGetNextPackageLength (ParserState);
        ParserState->Aml = Start + PackageLength;
        break;


    case AE_CTRL_FALSE:

        /*
         * Either an IF/WHILE Predicate was false or we encountered a BREAK
         * opcode.  In both cases, we do not execute the rest of the
         * package;  We simply close out the parent (finishing the walk of
         * this branch of the tree) and continue execution at the parent
         * level.
         */
        ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;

        /* In the case of a BREAK, just force a predicate (if any) to FALSE */

        WalkState->ControlState->Common.Value = FALSE;
        Status = AE_CTRL_END;
        break;


    case AE_CTRL_TRANSFER:

        /*
         * A method call (invocation) -- transfer control
         */
        Status = AE_CTRL_TRANSFER;
        WalkState->PrevOp = Op;
        WalkState->MethodCallOp = Op;
        WalkState->MethodCallNode = (Op->Value.Arg)->Node;

        /* Will return value (if any) be used by the caller? */

        WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState);
        break;


    default:
        Status = CallbackStatus;
        if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL)
        {
            Status = AE_OK;
        }
        break;
    }

    return_ACPI_STATUS (Status);
}
Example #21
0
NATIVE_CHAR *
acpi_ns_get_table_pathname (
	acpi_namespace_node     *node)
{
	NATIVE_CHAR             *name_buffer;
	u32                     size;
	acpi_name               name;
	acpi_namespace_node     *child_node;
	acpi_namespace_node     *parent_node;


	FUNCTION_TRACE_PTR ("Ns_get_table_pathname", node);


	if (!acpi_gbl_root_node || !node) {
		/*
		 * If the name space has not been initialized,
		 * this function should not have been called.
		 */
		return_PTR (NULL);
	}

	child_node = node->child;


	/* Calculate required buffer size based on depth below root */

	size = 1;
	parent_node = child_node;
	while (parent_node) {
		parent_node = acpi_ns_get_parent_object (parent_node);
		if (parent_node) {
			size += ACPI_NAME_SIZE;
		}
	}


	/* Allocate a buffer to be returned to caller */

	name_buffer = ACPI_MEM_CALLOCATE (size + 1);
	if (!name_buffer) {
		REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n"));
		return_PTR (NULL);
	}


	/* Store terminator byte, then build name backwards */

	name_buffer[size] = '\0';
	while ((size > ACPI_NAME_SIZE) &&
		acpi_ns_get_parent_object (child_node)) {
		size -= ACPI_NAME_SIZE;
		name = acpi_ns_find_parent_name (child_node);

		/* Put the name into the buffer */

		MOVE_UNALIGNED32_TO_32 ((name_buffer + size), &name);
		child_node = acpi_ns_get_parent_object (child_node);
	}

	name_buffer[--size] = AML_ROOT_PREFIX;

	if (size != 0) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad pointer returned; size=%X\n", size));
	}

	return_PTR (name_buffer);
}
Example #22
0
acpi_status
acpi_ns_handle_to_pathname (
	acpi_handle             target_handle,
	u32                     *buf_size,
	NATIVE_CHAR             *user_buffer)
{
	acpi_status             status = AE_OK;
	acpi_namespace_node     *node;
	u32                     path_length;
	u32                     user_buf_size;
	acpi_name               name;
	u32                     size;


	FUNCTION_TRACE_PTR ("Ns_handle_to_pathname", target_handle);


	if (!acpi_gbl_root_node) {
		/*
		 * If the name space has not been initialized,
		 * this function should not have been called.
		 */
		return_ACPI_STATUS (AE_NO_NAMESPACE);
	}

	node = acpi_ns_map_handle_to_node (target_handle);
	if (!node) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}


	/* Set return length to the required path length */

	path_length = acpi_ns_get_pathname_length (node);
	size = path_length - 1;

	user_buf_size = *buf_size;
	*buf_size = path_length;

	/* Check if the user buffer is sufficiently large */

	if (path_length > user_buf_size) {
		status = AE_BUFFER_OVERFLOW;
		goto exit;
	}

	/* Store null terminator */

	user_buffer[size] = 0;
	size -= ACPI_NAME_SIZE;

	/* Put the original ACPI name at the end of the path */

	MOVE_UNALIGNED32_TO_32 ((user_buffer + size),
			 &node->name);

	user_buffer[--size] = PATH_SEPARATOR;

	/* Build name backwards, putting "." between segments */

	while ((size > ACPI_NAME_SIZE) && node) {
		size -= ACPI_NAME_SIZE;
		name = acpi_ns_find_parent_name (node);
		MOVE_UNALIGNED32_TO_32 ((user_buffer + size), &name);

		user_buffer[--size] = PATH_SEPARATOR;
		node = acpi_ns_get_parent_object (node);
	}

	/*
	 * Overlay the "." preceding the first segment with
	 * the root name "\"
	 */
	user_buffer[size] = '\\';

	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Len=%X, %s \n", path_length, user_buffer));

exit:
	return_ACPI_STATUS (status);
}
Example #23
0
ACPI_STATUS
AcpiPsParseLoop (
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_PARSE_OBJECT       *Op = NULL;     /* current op */
    const ACPI_OPCODE_INFO  *OpInfo;
    ACPI_PARSE_OBJECT       *Arg = NULL;
    ACPI_PARSE2_OBJECT      *DeferredOp;
    UINT32                  ArgCount;       /* push for fixed or var args */
    UINT32                  ArgTypes = 0;
    UINT32                  AmlOffset;
    UINT16                  Opcode;
    ACPI_PARSE_OBJECT       PreOp;
    ACPI_PARSE_STATE        *ParserState;
    UINT8                   *AmlOpStart;


    FUNCTION_TRACE_PTR ("PsParseLoop", WalkState);


    ParserState = WalkState->ParserState;

#ifndef PARSER_ONLY
    if (WalkState->WalkType & WALK_METHOD_RESTART)
    {
        /* We are restarting a preempted control method */

        if (AcpiPsHasCompletedScope (ParserState))
        {
            /*
             * We must check if a predicate to an IF or WHILE statement
             * was just completed
             */
            if ((ParserState->Scope->ParseScope.Op) &&
                ((ParserState->Scope->ParseScope.Op->Opcode == AML_IF_OP) ||
                (ParserState->Scope->ParseScope.Op->Opcode == AML_WHILE_OP)) &&
                (WalkState->ControlState) &&
                (WalkState->ControlState->Common.State ==
                    CONTROL_PREDICATE_EXECUTING))
            {

                /*
                 * A predicate was just completed, get the value of the
                 * predicate and branch based on that value
                 */
                Status = AcpiDsGetPredicateValue (WalkState, NULL, TRUE);
                if (ACPI_FAILURE (Status) &&
                    ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
                {
                    if (Status == AE_AML_NO_RETURN_VALUE)
                    {
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                            "Invoked method did not return a value, %s\n",
                            AcpiFormatException (Status)));

                    }
                    ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GetPredicate Failed, %s\n",
                        AcpiFormatException (Status)));
                    return_ACPI_STATUS (Status);
                }

                Status = AcpiPsNextParseState (WalkState, Op, Status);
            }

            AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
            ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
        }

        else if (WalkState->PrevOp)
        {
            /* We were in the middle of an op */

            Op = WalkState->PrevOp;
            ArgTypes = WalkState->PrevArgTypes;
        }
    }
#endif

    /*
     * Iterative parsing loop, while there is more aml to process:
     */
    while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
    {
        if (!Op)
        {
            /* Get the next opcode from the AML stream */

            AmlOpStart = ParserState->Aml;
            AmlOffset  = ParserState->Aml - ParserState->AmlStart;
            Opcode     = AcpiPsPeekOpcode (ParserState);

            /*
             * First cut to determine what we have found:
             * 1) A valid AML opcode
             * 2) A name string
             * 3) An unknown/invalid opcode
             */
            OpInfo = AcpiPsGetOpcodeInfo (Opcode);
            switch (ACPI_GET_OP_TYPE (OpInfo))
            {
            case ACPI_OP_TYPE_OPCODE:

                /* Found opcode info, this is a normal opcode */

                ParserState->Aml += AcpiPsGetOpcodeSize (Opcode);
                ArgTypes = OpInfo->ParseArgs;
                break;

            case ACPI_OP_TYPE_ASCII:
            case ACPI_OP_TYPE_PREFIX:
                /*
                 * Starts with a valid prefix or ASCII char, this is a name
                 * string.  Convert the bare name string to a namepath.
                 */
                Opcode = AML_INT_NAMEPATH_OP;
                ArgTypes = ARGP_NAMESTRING;
                break;

            case ACPI_OP_TYPE_UNKNOWN:

                /* The opcode is unrecognized.  Just skip unknown opcodes */

                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                    "Found unknown opcode %lX at AML offset %X, ignoring\n",
                    Opcode, AmlOffset));

                DUMP_BUFFER (ParserState->Aml, 128);

                /* Assume one-byte bad opcode */

                ParserState->Aml++;
                continue;
            }


            /* Create Op structure and append to parent's argument list */

            if (OpInfo->Flags & AML_NAMED)
            {
                PreOp.Value.Arg = NULL;
                PreOp.Opcode = Opcode;

                while (GET_CURRENT_ARG_TYPE (ArgTypes) != ARGP_NAME)
                {
                    Arg = AcpiPsGetNextArg (ParserState,
                                            GET_CURRENT_ARG_TYPE (ArgTypes),
                                            &ArgCount);
                    AcpiPsAppendArg (&PreOp, Arg);
                    INCREMENT_ARG_LIST (ArgTypes);
                }


                /* We know that this arg is a name, move to next arg */

                INCREMENT_ARG_LIST (ArgTypes);

                if (WalkState->DescendingCallback != NULL)
                {
                    /*
                     * Find the object.  This will either insert the object into
                     * the namespace or simply look it up
                     */
                    Status = WalkState->DescendingCallback (Opcode, NULL, WalkState, &Op);
                    if (Op == NULL)
                    {
                        continue;
                    }
                    Status = AcpiPsNextParseState (WalkState, Op, Status);
                    if (Status == AE_CTRL_PENDING)
                    {
                        Status = AE_OK;
                        goto CloseThisOp;
                    }

                    if (ACPI_FAILURE (Status))
                    {
                        goto CloseThisOp;
                    }
                }

                AcpiPsAppendArg (Op, PreOp.Value.Arg);
                AcpiGbl_Depth++;


                if (Op->Opcode == AML_REGION_OP)
                {
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    /*
                     * Defer final parsing of an OperationRegion body,
                     * because we don't have enough info in the first pass
                     * to parse it correctly (i.e., there may be method
                     * calls within the TermArg elements of the body.
                     *
                     * However, we must continue parsing because
                     * the opregion is not a standalone package --
                     * we don't know where the end is at this point.
                     *
                     * (Length is unknown until parse of the body complete)
                     */
                    DeferredOp->Data    = AmlOpStart;
                    DeferredOp->Length  = 0;
                }
            }


            else
            {
                /* Not a named opcode, just allocate Op and append to parent */

                OpInfo = AcpiPsGetOpcodeInfo (Opcode);
                Op = AcpiPsAllocOp (Opcode);
                if (!Op)
                {
                    return_ACPI_STATUS (AE_NO_MEMORY);
                }


                if (OpInfo->Flags & AML_CREATE)
                {
                    /*
                     * Backup to beginning of CreateXXXfield declaration
                     * BodyLength is unknown until we parse the body
                     */
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    DeferredOp->Data    = AmlOpStart;
                    DeferredOp->Length  = 0;
                }

                AcpiPsAppendArg (AcpiPsGetParentScope (ParserState), Op);

                if ((WalkState->DescendingCallback != NULL))
                {
                    /*
                     * Find the object.  This will either insert the object into
                     * the namespace or simply look it up
                     */
                    Status = WalkState->DescendingCallback (Opcode, Op, WalkState, &Op);
                    Status = AcpiPsNextParseState (WalkState, Op, Status);
                    if (Status == AE_CTRL_PENDING)
                    {
                        Status = AE_OK;
                        goto CloseThisOp;
                    }

                    if (ACPI_FAILURE (Status))
                    {
                        goto CloseThisOp;
                    }
                }
            }

            Op->AmlOffset = AmlOffset;

            if (OpInfo)
            {
                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
                    "Op=%p Opcode=%4.4lX Aml %p Oft=%5.5lX\n",
                     Op, Op->Opcode, ParserState->Aml, Op->AmlOffset));
            }
        }


        /* Start ArgCount at zero because we don't know if there are any args yet */

        ArgCount  = 0;


        if (ArgTypes)   /* Are there any arguments that must be processed? */
        {
            /* get arguments */

            switch (Op->Opcode)
            {
            case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
            case AML_WORD_OP:       /* AML_WORDDATA_ARG */
            case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
            case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
            case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */

                /* fill in constant or string argument directly */

                AcpiPsGetNextSimpleArg (ParserState,
                                        GET_CURRENT_ARG_TYPE (ArgTypes), Op);
                break;

            case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */

                AcpiPsGetNextNamepath (ParserState, Op, &ArgCount, 1);
                ArgTypes = 0;
                break;


            default:

                /* Op is not a constant or string, append each argument */

                while (GET_CURRENT_ARG_TYPE (ArgTypes) && !ArgCount)
                {
                    AmlOffset = ParserState->Aml - ParserState->AmlStart;
                    Arg = AcpiPsGetNextArg (ParserState,
                                            GET_CURRENT_ARG_TYPE (ArgTypes),
                                            &ArgCount);
                    if (Arg)
                    {
                        Arg->AmlOffset = AmlOffset;
                        AcpiPsAppendArg (Op, Arg);
                    }

                    INCREMENT_ARG_LIST (ArgTypes);
                }


                /* For a method, save the length and address of the body */

                if (Op->Opcode == AML_METHOD_OP)
                {
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    /*
                     * Skip parsing of control method or opregion body,
                     * because we don't have enough info in the first pass
                     * to parse them correctly.
                     */
                    DeferredOp->Data    = ParserState->Aml;
                    DeferredOp->Length  = (UINT32) (ParserState->PkgEnd -
                                                    ParserState->Aml);

                    /*
                     * Skip body of method.  For OpRegions, we must continue
                     * parsing because the opregion is not a standalone
                     * package (We don't know where the end is).
                     */
                    ParserState->Aml    = ParserState->PkgEnd;
                    ArgCount            = 0;
                }

                break;
            }
        }


        /*
         * Zero ArgCount means that all arguments for this op have been processed
         */
        if (!ArgCount)
        {
            /* completed Op, prepare for next */

            OpInfo = AcpiPsGetOpcodeInfo (Op->Opcode);
            if (OpInfo->Flags & AML_NAMED)
            {
                if (AcpiGbl_Depth)
                {
                    AcpiGbl_Depth--;
                }

                if (Op->Opcode == AML_REGION_OP)
                {
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    /*
                     * Skip parsing of control method or opregion body,
                     * because we don't have enough info in the first pass
                     * to parse them correctly.
                     *
                     * Completed parsing an OpRegion declaration, we now
                     * know the length.
                     */
                    DeferredOp->Length = (UINT32) (ParserState->Aml -
                                                    DeferredOp->Data);
                }
            }

            if (OpInfo->Flags & AML_CREATE)
            {
                /*
                 * Backup to beginning of CreateXXXfield declaration (1 for
                 * Opcode)
                 *
                 * BodyLength is unknown until we parse the body
                 */
                DeferredOp = (ACPI_PARSE2_OBJECT *) Op;
                DeferredOp->Length = (UINT32) (ParserState->Aml -
                                               DeferredOp->Data);
            }

            /* This op complete, notify the dispatcher */

            if (WalkState->AscendingCallback != NULL)
            {
                Status = WalkState->AscendingCallback (WalkState, Op);
                Status = AcpiPsNextParseState (WalkState, Op, Status);
                if (Status == AE_CTRL_PENDING)
                {
                    Status = AE_OK;
                    goto CloseThisOp;
                }
            }


CloseThisOp:

            /*
             * Finished one argument of the containing scope
             */
            ParserState->Scope->ParseScope.ArgCount--;

            /* Close this Op (may result in parse subtree deletion) */

            if (AcpiPsCompleteThisOp (WalkState, Op))
            {
                Op = NULL;
            }


            switch (Status)
            {
            case AE_OK:
                break;


            case AE_CTRL_TRANSFER:

                /*
                 * We are about to transfer to a called method.
                 */
                WalkState->PrevOp = Op;
                WalkState->PrevArgTypes = ArgTypes;
                return_ACPI_STATUS (Status);
                break;


            case AE_CTRL_END:

                AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);

                Status = WalkState->AscendingCallback (WalkState, Op);
                Status = AcpiPsNextParseState (WalkState, Op, Status);

                AcpiPsCompleteThisOp (WalkState, Op);
                Op = NULL;
                Status = AE_OK;
                break;


            case AE_CTRL_TERMINATE:

                Status = AE_OK;

                /* Clean up */
                do
                {
                    if (Op)
                    {
                        AcpiPsCompleteThisOp (WalkState, Op);
                    }

                    AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
                } while (Op);

                return_ACPI_STATUS (Status);
                break;


            default:  /* All other non-AE_OK status */

                if (Op == NULL)
                {
                    AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
                }
                WalkState->PrevOp = Op;
                WalkState->PrevArgTypes = ArgTypes;

                /*
                 * TEMP:
                 */

                return_ACPI_STATUS (Status);
                break;
            }

            /* This scope complete? */

            if (AcpiPsHasCompletedScope (ParserState))
            {
                AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
            }

            else
            {
                Op = NULL;
            }

        }


        /* ArgCount is non-zero */

        else
        {
            /* complex argument, push Op and prepare for argument */

            AcpiPsPushScope (ParserState, Op, ArgTypes, ArgCount);
            Op = NULL;
        }

    } /* while ParserState->Aml */


    /*
     * Complete the last Op (if not completed), and clear the scope stack.
     * It is easily possible to end an AML "package" with an unbounded number
     * of open scopes (such as when several AML blocks are closed with
     * sequential closing braces).  We want to terminate each one cleanly.
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Package complete at Op %p\n", Op));
    do
    {
        if (Op)
        {
            if (WalkState->AscendingCallback != NULL)
            {
                Status = WalkState->AscendingCallback (WalkState, Op);
                Status = AcpiPsNextParseState (WalkState, Op, Status);
                if (Status == AE_CTRL_PENDING)
                {
                    Status = AE_OK;
                    goto CloseThisOp;
                }

                if (Status == AE_CTRL_TERMINATE)
                {
                    Status = AE_OK;

                    /* Clean up */
                    do
                    {
                        if (Op)
                        {
                            AcpiPsCompleteThisOp (WalkState, Op);
                        }

                        AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);

                    } while (Op);

                    return_ACPI_STATUS (Status);
                }

                else if (ACPI_FAILURE (Status))
                {
                    AcpiPsCompleteThisOp (WalkState, Op);
                    return_ACPI_STATUS (Status);
                }
            }

            AcpiPsCompleteThisOp (WalkState, Op);
        }

        AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);

    } while (Op);

    return_ACPI_STATUS (Status);
}
Example #24
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);
}
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);
}
Example #26
0
static BOOLEAN
AcpiPsCompleteThisOp (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
#ifndef PARSER_ONLY
    ACPI_PARSE_OBJECT       *Prev;
    ACPI_PARSE_OBJECT       *Next;
    const ACPI_OPCODE_INFO  *OpInfo;
    const ACPI_OPCODE_INFO  *ParentInfo;
    UINT32                  OpcodeClass;
    ACPI_PARSE_OBJECT       *ReplacementOp = NULL;


    FUNCTION_TRACE_PTR ("PsCompleteThisOp", Op);


    OpInfo      = AcpiPsGetOpcodeInfo (Op->Opcode);
    OpcodeClass = ACPI_GET_OP_CLASS (OpInfo);


    /* Delete this op and the subtree below it if asked to */

    if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
        (OpcodeClass != OPTYPE_CONSTANT)        &&
        (OpcodeClass != OPTYPE_LITERAL)         &&
        (OpcodeClass != OPTYPE_LOCAL_VARIABLE)  &&
        (OpcodeClass != OPTYPE_METHOD_ARGUMENT) &&
        (OpcodeClass != OPTYPE_DATA_TERM)       &&
        (Op->Opcode  != AML_INT_NAMEPATH_OP))
    {
        /* Make sure that we only delete this subtree */

        if (Op->Parent)
        {
            /*
             * Check if we need to replace the operator and its subtree
             * with a return value op (placeholder op)
             */
            ParentInfo  = AcpiPsGetOpcodeInfo (Op->Parent->Opcode);

            switch (ACPI_GET_OP_CLASS (ParentInfo))
            {
            case OPTYPE_CONTROL:        /* IF, ELSE, WHILE only */
                break;

            case OPTYPE_NAMED_OBJECT:   /* Scope, method, etc. */

                /*
                 * These opcodes contain TermArg operands.  The current
                 * op must be replace by a placeholder return op
                 */
                if ((Op->Parent->Opcode == AML_REGION_OP)               ||
                    (Op->Parent->Opcode == AML_CREATE_FIELD_OP)         ||
                    (Op->Parent->Opcode == AML_CREATE_BIT_FIELD_OP)     ||
                    (Op->Parent->Opcode == AML_CREATE_BYTE_FIELD_OP)    ||
                    (Op->Parent->Opcode == AML_CREATE_WORD_FIELD_OP)    ||
                    (Op->Parent->Opcode == AML_CREATE_DWORD_FIELD_OP)   ||
                    (Op->Parent->Opcode == AML_CREATE_QWORD_FIELD_OP))
                {
                    ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
                    if (!ReplacementOp)
                    {
                        return_VALUE (FALSE);
                    }
                }

                break;

            default:
                ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
                if (!ReplacementOp)
                {
                    return_VALUE (FALSE);
                }
            }

            /* We must unlink this op from the parent tree */

            Prev = Op->Parent->Value.Arg;
            if (Prev == Op)
            {
                /* This op is the first in the list */

                if (ReplacementOp)
                {
                    ReplacementOp->Parent    = Op->Parent;
                    ReplacementOp->Value.Arg = NULL;
                    Op->Parent->Value.Arg    = ReplacementOp;
                    ReplacementOp->Next      = Op->Next;
                }
                else
                {
                    Op->Parent->Value.Arg    = Op->Next;
                }
            }

            /* Search the parent list */

            else while (Prev)
            {
                /* Traverse all siblings in the parent's argument list */

                Next = Prev->Next;
                if (Next == Op)
                {
                    if (ReplacementOp)
                    {
                        ReplacementOp->Parent = Op->Parent;
                        ReplacementOp->Value.Arg = NULL;
                        Prev->Next = ReplacementOp;
                        ReplacementOp->Next = Op->Next;
                        Next = NULL;
                    }
                    else
                    {
                        Prev->Next = Op->Next;
                        Next = NULL;
                    }
                }

                Prev = Next;
            }

        }

        /* Now we can actually delete the subtree rooted at op */

        AcpiPsDeleteParseTree (Op);

        return_VALUE (TRUE);
    }

    return_VALUE (FALSE);

#else
    return (FALSE);
#endif
}
Example #27
0
ACPI_STATUS
AcpiNsHandleToPathname (
    ACPI_HANDLE             TargetHandle,
    UINT32                  *BufSize,
    NATIVE_CHAR             *UserBuffer)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_NAMESPACE_NODE     *Node;
    UINT32                  PathLength;
    UINT32                  UserBufSize;
    ACPI_NAME               Name;
    UINT32                  Size;


    FUNCTION_TRACE_PTR ("NsHandleToPathname", TargetHandle);


    if (!AcpiGbl_RootNode)
    {
        /*
         * If the name space has not been initialized,
         * this function should not have been called.
         */
        return_ACPI_STATUS (AE_NO_NAMESPACE);
    }

    Node = AcpiNsConvertHandleToEntry (TargetHandle);
    if (!Node)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }


    /* Set return length to the required path length */

    PathLength = AcpiNsGetPathnameLength (Node);
    Size = PathLength - 1;

    UserBufSize = *BufSize;
    *BufSize = PathLength;

    /* Check if the user buffer is sufficiently large */

    if (PathLength > UserBufSize)
    {
        Status = AE_BUFFER_OVERFLOW;
        goto Exit;
    }

    /* Store null terminator */

    UserBuffer[Size] = 0;
    Size -= ACPI_NAME_SIZE;

    /* Put the original ACPI name at the end of the path */

    MOVE_UNALIGNED32_TO_32 ((UserBuffer + Size),
                            &Node->Name);

    UserBuffer[--Size] = PATH_SEPARATOR;

    /* Build name backwards, putting "." between segments */

    while ((Size > ACPI_NAME_SIZE) && Node)
    {
        Size -= ACPI_NAME_SIZE;
        Name = AcpiNsFindParentName (Node);
        MOVE_UNALIGNED32_TO_32 ((UserBuffer + Size), &Name);

        UserBuffer[--Size] = PATH_SEPARATOR;
        Node = AcpiNsGetParentObject (Node);
    }

    /*
     * Overlay the "." preceding the first segment with
     * the root name "\"
     */
    UserBuffer[Size] = '\\';

    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Len=%X, %s \n", PathLength, UserBuffer));

Exit:
    return_ACPI_STATUS (Status);
}
Example #28
0
NATIVE_CHAR *
AcpiNsGetTablePathname (
    ACPI_NAMESPACE_NODE     *Node)
{
    NATIVE_CHAR             *NameBuffer;
    UINT32                  Size;
    ACPI_NAME               Name;
    ACPI_NAMESPACE_NODE     *ChildNode;
    ACPI_NAMESPACE_NODE     *ParentNode;


    FUNCTION_TRACE_PTR ("NsGetTablePathname", Node);


    if (!AcpiGbl_RootNode || !Node)
    {
        /*
         * If the name space has not been initialized,
         * this function should not have been called.
         */
        return_PTR (NULL);
    }

    ChildNode = Node->Child;


    /* Calculate required buffer size based on depth below root */

    Size = 1;
    ParentNode = ChildNode;
    while (ParentNode)
    {
        ParentNode = AcpiNsGetParentObject (ParentNode);
        if (ParentNode)
        {
            Size += ACPI_NAME_SIZE;
        }
    }


    /* Allocate a buffer to be returned to caller */

    NameBuffer = ACPI_MEM_CALLOCATE (Size + 1);
    if (!NameBuffer)
    {
        REPORT_ERROR (("NsGetTablePathname: allocation failure\n"));
        return_PTR (NULL);
    }


    /* Store terminator byte, then build name backwards */

    NameBuffer[Size] = '\0';
    while ((Size > ACPI_NAME_SIZE) &&
        AcpiNsGetParentObject (ChildNode))
    {
        Size -= ACPI_NAME_SIZE;
        Name = AcpiNsFindParentName (ChildNode);

        /* Put the name into the buffer */

        MOVE_UNALIGNED32_TO_32 ((NameBuffer + Size), &Name);
        ChildNode = AcpiNsGetParentObject (ChildNode);
    }

    NameBuffer[--Size] = AML_ROOT_PREFIX;

    if (Size != 0)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad pointer returned; size=%X\n", Size));
    }

    return_PTR (NameBuffer);
}
Example #29
0
ACPI_STATUS
AcpiUtAddElementToAllocList (
    UINT32                  ListId,
    ACPI_DEBUG_MEM_BLOCK    *Address,
    UINT32                  Size,
    UINT8                   AllocType,
    UINT32                  Component,
    NATIVE_CHAR             *Module,
    UINT32                  Line)
{
    ACPI_MEMORY_LIST        *MemList;
    ACPI_DEBUG_MEM_BLOCK    *Element;
    ACPI_STATUS             Status = AE_OK;


    FUNCTION_TRACE_PTR ("UtAddElementToAllocList", Address);


    if (ListId > ACPI_MEM_LIST_MAX)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    MemList = &AcpiGbl_MemoryLists[ListId];
    AcpiUtAcquireMutex (ACPI_MTX_MEMORY);

    /*
     * Search list for this address to make sure it is not already on the list.
     * This will catch several kinds of problems.
     */

    Element = AcpiUtSearchAllocList (ListId, Address);
    if (Element)
    {
        REPORT_ERROR (("UtAddElementToAllocList: Address already present in list! (%p)\n",
            Address));

        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", Element, Address));

        goto UnlockAndExit;
    }

    /* Fill in the instance data. */

    Address->Size      = Size;
    Address->AllocType = AllocType;
    Address->Component = Component;
    Address->Line      = Line;

    STRNCPY (Address->Module, Module, MAX_MODULE_NAME);

    /* Insert at list head */

    if (MemList->ListHead)
    {
        ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Address;
    }

    Address->Next = MemList->ListHead;
    Address->Previous = NULL;

    MemList->ListHead = Address;


UnlockAndExit:
    AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
    return_ACPI_STATUS (Status);
}
Example #30
0
acpi_status
acpi_ex_get_name_string (
	acpi_object_type8       data_type,
	u8                      *in_aml_address,
	NATIVE_CHAR             **out_name_string,
	u32                     *out_name_length)
{
	acpi_status             status = AE_OK;
	u8                      *aml_address = in_aml_address;
	NATIVE_CHAR             *name_string = NULL;
	u32                     num_segments;
	u32                     prefix_count = 0;
	u8                      prefix = 0;
	u8                      has_prefix = FALSE;


	FUNCTION_TRACE_PTR ("Ex_get_name_string", aml_address);


	if (INTERNAL_TYPE_REGION_FIELD == data_type  ||
		INTERNAL_TYPE_BANK_FIELD == data_type    ||
		INTERNAL_TYPE_INDEX_FIELD == data_type) {
		/* Disallow prefixes for types associated with Field_unit names */

		name_string = acpi_ex_allocate_name_string (0, 1);
		if (!name_string) {
			status = AE_NO_MEMORY;
		}
		else {
			status = acpi_ex_name_segment (&aml_address, name_string);
		}
	}

	else {
		/*
		 * Data_type is not a field name.
		 * Examine first character of name for root or parent prefix operators
		 */
		switch (*aml_address) {

		case AML_ROOT_PREFIX:

			prefix = *aml_address++;
			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Root_prefix: %x\n", prefix));

			/*
			 * Remember that we have a Root_prefix --
			 * see comment in Acpi_ex_allocate_name_string()
			 */
			prefix_count = (u32) -1;
			has_prefix = TRUE;
			break;


		case AML_PARENT_PREFIX:

			/* Increment past possibly multiple parent prefixes */

			do {
				prefix = *aml_address++;
				ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Parent_prefix: %x\n", prefix));

				++prefix_count;

			} while (*aml_address == AML_PARENT_PREFIX);
			has_prefix = TRUE;
			break;


		default:

			break;
		}


		/* Examine first character of name for name segment prefix operator */

		switch (*aml_address) {

		case AML_DUAL_NAME_PREFIX:

			prefix = *aml_address++;
			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Dual_name_prefix: %x\n", prefix));

			name_string = acpi_ex_allocate_name_string (prefix_count, 2);
			if (!name_string) {
				status = AE_NO_MEMORY;
				break;
			}

			/* Indicate that we processed a prefix */

			has_prefix = TRUE;

			status = acpi_ex_name_segment (&aml_address, name_string);
			if (ACPI_SUCCESS (status)) {
				status = acpi_ex_name_segment (&aml_address, name_string);
			}
			break;


		case AML_MULTI_NAME_PREFIX_OP:

			prefix = *aml_address++;
			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Multi_name_prefix: %x\n", prefix));

			/* Fetch count of segments remaining in name path */

			num_segments = *aml_address++;

			name_string = acpi_ex_allocate_name_string (prefix_count, num_segments);
			if (!name_string) {
				status = AE_NO_MEMORY;
				break;
			}

			/* Indicate that we processed a prefix */

			has_prefix = TRUE;

			while (num_segments &&
					(status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
				--num_segments;
			}

			break;


		case 0:

			/* Null_name valid as of 8-12-98 ASL/AML Grammar Update */

			if (-1 == prefix_count) {
				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Name_seg is \"\\\" followed by NULL\n"));
			}

			/* Consume the NULL byte */

			aml_address++;
			name_string = acpi_ex_allocate_name_string (prefix_count, 0);
			if (!name_string) {
				status = AE_NO_MEMORY;
				break;
			}

			break;


		default:

			/* Name segment string */

			name_string = acpi_ex_allocate_name_string (prefix_count, 1);
			if (!name_string) {
				status = AE_NO_MEMORY;
				break;
			}

			status = acpi_ex_name_segment (&aml_address, name_string);
			break;

		}   /* Switch (Peek_op ())   */
	}


	if (AE_CTRL_PENDING == status && has_prefix) {
		/* Ran out of segments after processing a prefix */

		REPORT_ERROR (
			("Ex_do_name: Malformed Name at %p\n", name_string));
		status = AE_AML_BAD_NAME;
	}


	*out_name_string = name_string;
	*out_name_length = (u32) (aml_address - in_aml_address);

	return_ACPI_STATUS (status);
}