Example #1
0
static acpi_status
acpi_db_integrity_walk(acpi_handle obj_handle,
		       u32 nesting_level, void *context, void **return_value)
{
	struct acpi_integrity_info *info =
	    (struct acpi_integrity_info *)context;
	struct acpi_namespace_node *node =
	    (struct acpi_namespace_node *)obj_handle;
	union acpi_operand_object *object;
	u8 alias = TRUE;

	info->nodes++;

	/* Verify the NS node, and dereference aliases */

	while (alias) {
		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
			acpi_os_printf
			    ("Invalid Descriptor Type for Node %p [%s] - "
			     "is %2.2X should be %2.2X\n", node,
			     acpi_ut_get_descriptor_name(node),
			     ACPI_GET_DESCRIPTOR_TYPE(node),
			     ACPI_DESC_TYPE_NAMED);
			return (AE_OK);
		}

		if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
		    (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
			node = (struct acpi_namespace_node *)node->object;
		} else {
			alias = FALSE;
		}
	}

	if (node->type > ACPI_TYPE_LOCAL_MAX) {
		acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
			       node, node->type);
		return (AE_OK);
	}

	if (!acpi_ut_valid_nameseg(node->name.ascii)) {
		acpi_os_printf("Invalid AcpiName for Node %p\n", node);
		return (AE_OK);
	}

	object = acpi_ns_get_attached_object(node);
	if (object) {
		info->objects++;
		if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
			acpi_os_printf
			    ("Invalid Descriptor Type for Object %p [%s]\n",
			     object, acpi_ut_get_descriptor_name(object));
		}
	}

	return (AE_OK);
}
Example #2
0
u8 acpi_ut_valid_internal_object(void *object)
{

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

	switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
	case ACPI_DESC_TYPE_OPERAND:

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

		return (TRUE);

	default:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "%p is not not an ACPI operand obj [%s]\n",
				  object, acpi_ut_get_descriptor_name(object)));
		break;
	}

	return (FALSE);
}
Example #3
0
u8 acpi_ut_valid_internal_object(void *object)
{

	ACPI_FUNCTION_NAME(ut_valid_internal_object);

	

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

	

	switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
	case ACPI_DESC_TYPE_OPERAND:

		

		return (TRUE);

	default:
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "%p is not not an ACPI operand obj [%s]\n",
				  object, acpi_ut_get_descriptor_name(object)));
		break;
	}

	return (FALSE);
}
Example #4
0
void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
{
	u32 i;

	if (!obj_desc) {
		acpi_os_printf(" Uninitialized");
		return;
	}

	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
		acpi_os_printf(" %p [%s]", obj_desc,
			       acpi_ut_get_descriptor_name(obj_desc));
		return;
	}

	acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc));

	switch (obj_desc->common.type) {
	case ACPI_TYPE_INTEGER:

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

	case ACPI_TYPE_STRING:

		acpi_os_printf("(%u) \"%.24s",
			       obj_desc->string.length,
			       obj_desc->string.pointer);

		if (obj_desc->string.length > 24) {
			acpi_os_printf("...");
		} else {
			acpi_os_printf("\"");
		}
		break;

	case ACPI_TYPE_BUFFER:

		acpi_os_printf("(%u)", obj_desc->buffer.length);
		for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
			acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]);
		}
		break;

	default:

		acpi_os_printf(" %p", obj_desc);
		break;
	}
}
Example #5
0
void
acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags)
{
	ACPI_FUNCTION_TRACE(ex_dump_object_descriptor);

	if (!obj_desc) {
		return_VOID;
	}

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

	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
		acpi_ex_dump_namespace_node((struct acpi_namespace_node *)
					    obj_desc, flags);

		acpi_os_printf("\nAttached Object (%p):\n",
			       ((struct acpi_namespace_node *)obj_desc)->
			       object);

		acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *)
						obj_desc)->object, flags);
		return_VOID;
	}

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

	if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
		return_VOID;
	}

	/* Common Fields */

	acpi_ex_dump_object(obj_desc, acpi_ex_dump_common);

	/* Object-specific fields */

	acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]);
	return_VOID;
}
Example #6
0
void acpi_ut_delete_object_desc(union acpi_operand_object *object)
{
	ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);

	

	if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
		ACPI_ERROR((AE_INFO,
			    "%p is not an ACPI Operand object [%s]", object,
			    acpi_ut_get_descriptor_name(object)));
		return_VOID;
	}

	(void)acpi_os_release_object(acpi_gbl_operand_cache, object);
	return_VOID;
}
void acpi_ut_delete_object_desc(union acpi_operand_object *object)
{
	ACPI_FUNCTION_TRACE_PTR("ut_delete_object_desc", object);

	/* Object must be an union acpi_operand_object    */

	if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "%p is not an ACPI Operand object [%s]\n",
				  object, acpi_ut_get_descriptor_name(object)));
		return_VOID;
	}

	(void)acpi_os_release_object(acpi_gbl_operand_cache, object);
	return_VOID;
}
Example #8
0
struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
{
	struct acpi_namespace_node *node;
	acpi_size address;

	if ((*in_string >= 0x30) && (*in_string <= 0x39)) {

		/* Numeric argument, convert */

		address = strtoul(in_string, NULL, 16);
		node = ACPI_TO_POINTER(address);
		if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
			acpi_os_printf("Address %p is invalid", node);
			return (NULL);
		}

		/* Make sure pointer is valid NS node */

		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
			acpi_os_printf
			    ("Address %p is not a valid namespace node [%s]\n",
			     node, acpi_ut_get_descriptor_name(node));
			return (NULL);
		}
	} else {
		/*
		 * Alpha argument: The parameter is a name string that must be
		 * resolved to a Namespace object.
		 */
		node = acpi_db_local_ns_lookup(in_string);
		if (!node) {
			acpi_os_printf
			    ("Could not find [%s] in namespace, defaulting to root node\n",
			     in_string);
			node = acpi_gbl_root_node;
		}
	}

	return (node);
}
Example #9
0
void
acpi_db_display_internal_object(union acpi_operand_object *obj_desc,
				struct acpi_walk_state *walk_state)
{
	u8 type;

	acpi_os_printf("%p ", obj_desc);

	if (!obj_desc) {
		acpi_os_printf("<Null Object>\n");
		return;
	}

	/* Decode the object type */

	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
	case ACPI_DESC_TYPE_PARSER:

		acpi_os_printf("<Parser> ");
		break;

	case ACPI_DESC_TYPE_NAMED:

		acpi_db_decode_node((struct acpi_namespace_node *)obj_desc);
		break;

	case ACPI_DESC_TYPE_OPERAND:

		type = obj_desc->common.type;
		if (type > ACPI_TYPE_LOCAL_MAX) {
			acpi_os_printf(" Type %X [Invalid Type]", (u32)type);
			return;
		}

		/* Decode the ACPI object type */

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

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

			/* Decode the refererence */

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

				acpi_os_printf("%X ",
					       obj_desc->reference.value);
				if (walk_state) {
					obj_desc = walk_state->local_variables
					    [obj_desc->reference.value].object;
					acpi_os_printf("%p", obj_desc);
					acpi_db_decode_internal_object
					    (obj_desc);
				}
				break;

			case ACPI_REFCLASS_ARG:

				acpi_os_printf("%X ",
					       obj_desc->reference.value);
				if (walk_state) {
					obj_desc = walk_state->arguments
					    [obj_desc->reference.value].object;
					acpi_os_printf("%p", obj_desc);
					acpi_db_decode_internal_object
					    (obj_desc);
				}
				break;

			case ACPI_REFCLASS_INDEX:

				switch (obj_desc->reference.target_type) {
				case ACPI_TYPE_BUFFER_FIELD:

					acpi_os_printf("%p",
						       obj_desc->reference.
						       object);
					acpi_db_decode_internal_object
					    (obj_desc->reference.object);
					break;

				case ACPI_TYPE_PACKAGE:

					acpi_os_printf("%p",
						       obj_desc->reference.
						       where);
					if (!obj_desc->reference.where) {
						acpi_os_printf
						    (" Uninitialized WHERE pointer");
					} else {
						acpi_db_decode_internal_object(*
									       (obj_desc->
										reference.
										where));
					}
					break;

				default:

					acpi_os_printf
					    ("Unknown index target type");
					break;
				}
				break;

			case ACPI_REFCLASS_REFOF:

				if (!obj_desc->reference.object) {
					acpi_os_printf
					    ("Uninitialized reference subobject pointer");
					break;
				}

				/* Reference can be to a Node or an Operand object */

				switch (ACPI_GET_DESCRIPTOR_TYPE
					(obj_desc->reference.object)) {
				case ACPI_DESC_TYPE_NAMED:

					acpi_db_decode_node(obj_desc->reference.
							    object);
					break;

				case ACPI_DESC_TYPE_OPERAND:

					acpi_db_decode_internal_object
					    (obj_desc->reference.object);
					break;

				default:
					break;
				}
				break;

			case ACPI_REFCLASS_NAME:

				acpi_db_decode_node(obj_desc->reference.node);
				break;

			case ACPI_REFCLASS_DEBUG:
			case ACPI_REFCLASS_TABLE:

				acpi_os_printf("\n");
				break;

			default:	/* Unknown reference class */

				acpi_os_printf("%2.2X\n",
					       obj_desc->reference.class);
				break;
			}
			break;

		default:

			acpi_os_printf("<Obj>          ");
			acpi_db_decode_internal_object(obj_desc);
			break;
		}
		break;

	default:

		acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
			       acpi_ut_get_descriptor_name(obj_desc));
		break;
	}

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

	ACPI_FUNCTION_TRACE(ns_lookup);

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

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

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

	/*
	 * Get the prefix scope.
	 * A null scope means use the root scope
	 */
	if ((!scope_info) || (!scope_info->scope.node)) {
		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
				  "Null scope prefix, using root node (%p)\n",
				  acpi_gbl_root_node));

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

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

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

	type_to_check_for = type;

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

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

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

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

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

			this_node = acpi_gbl_root_node;
			search_parent_flag = ACPI_NS_NO_UPSEARCH;

			/* Point to name segment part */

			path++;

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

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

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

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

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

				/* Backup to the parent node */

				num_carats++;
				this_node = acpi_ns_get_parent_node(this_node);
				if (!this_node) {

					/* Current scope has no parent scope */

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

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

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

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

		case AML_DUAL_NAME_PREFIX:

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

			search_parent_flag = ACPI_NS_NO_UPSEARCH;

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

			num_segments = 2;
			path++;

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

		case AML_MULTI_NAME_PREFIX_OP:

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

			search_parent_flag = ACPI_NS_NO_UPSEARCH;

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

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

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

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

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

		ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
	}

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

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

			/* Set error flag according to caller */

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

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

		ACPI_MOVE_32_TO_32(&simple_name, path);

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

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

				/* Name not found in ACPI namespace */

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

			*return_node = this_node;
			return_ACPI_STATUS(status);
		}

		/* More segments to follow? */

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

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

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

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

				/* Complain about a type mismatch */

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

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

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

		path += ACPI_NAME_SIZE;
		current_node = this_node;
	}
Example #11
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_ns_attach_object
 *
 * PARAMETERS:  node                - Parent Node
 *              object              - Object to be attached
 *              type                - Type of object, or ACPI_TYPE_ANY if not
 *                                    known
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Record the given object as the value associated with the
 *              name whose acpi_handle is passed. If Object is NULL
 *              and Type is ACPI_TYPE_ANY, set the name as having no value.
 *              Note: Future may require that the Node->Flags field be passed
 *              as a parameter.
 *
 * MUTEX:       Assumes namespace is locked
 *
 ******************************************************************************/
acpi_status
acpi_ns_attach_object(struct acpi_namespace_node *node,
		      union acpi_operand_object *object, acpi_object_type type)
{
	union acpi_operand_object *obj_desc;
	union acpi_operand_object *last_obj_desc;
	acpi_object_type object_type = ACPI_TYPE_ANY;

	ACPI_FUNCTION_TRACE(ns_attach_object);

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

		/* Invalid handle */

		ACPI_ERROR((AE_INFO, "Null NamedObj handle"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (!object && (ACPI_TYPE_ANY != type)) {

		/* Null object */

		ACPI_ERROR((AE_INFO,
			    "Null object, but type not ACPI_TYPE_ANY"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {

		/* Not a name handle */

		ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
			    node, acpi_ut_get_descriptor_name(node)));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/* Check if this object is already attached */

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

		return_ACPI_STATUS(AE_OK);
	}

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

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

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

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

		/* Use the given type */

		object_type = type;
	}

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

	/* Detach an existing attached object if present */

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

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

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

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

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

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

	return_ACPI_STATUS(AE_OK);
}
Example #12
0
void acpi_ut_dump_allocations(u32 component, const char *module)
{
	struct acpi_debug_mem_block *element;
	union acpi_descriptor *descriptor;
	u32 num_outstanding = 0;
	u8 descriptor_type;

	ACPI_FUNCTION_TRACE(ut_dump_allocations);

	if (acpi_gbl_disable_mem_tracking) {
		return_VOID;
	}

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

	element = acpi_gbl_global_list->list_head;
	while (element) {
		if ((element->component & component) &&
		    ((module == NULL)
		     || (0 == strcmp(module, element->module)))) {
			descriptor =
			    ACPI_CAST_PTR(union acpi_descriptor,
					  &element->user_space);

			if (element->size <
			    sizeof(struct acpi_common_descriptor)) {
				acpi_os_printf("%p Length 0x%04X %9.9s-%u "
					       "[Not a Descriptor - too small]\n",
					       descriptor, element->size,
					       element->module, element->line);
			} else {
				/* Ignore allocated objects that are in a cache */

				if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) !=
				    ACPI_DESC_TYPE_CACHED) {
					acpi_os_printf
					    ("%p Length 0x%04X %9.9s-%u [%s] ",
					     descriptor, element->size,
					     element->module, element->line,
					     acpi_ut_get_descriptor_name
					     (descriptor));

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

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

					switch (ACPI_GET_DESCRIPTOR_TYPE
						(descriptor)) {
					case ACPI_DESC_TYPE_OPERAND:

						if (element->size ==
						    sizeof(union
							   acpi_operand_object))
						{
							descriptor_type =
							    ACPI_DESC_TYPE_OPERAND;
						}
						break;

					case ACPI_DESC_TYPE_PARSER:

						if (element->size ==
						    sizeof(union
							   acpi_parse_object)) {
							descriptor_type =
							    ACPI_DESC_TYPE_PARSER;
						}
						break;

					case ACPI_DESC_TYPE_NAMED:

						if (element->size ==
						    sizeof(struct
							   acpi_namespace_node))
						{
							descriptor_type =
							    ACPI_DESC_TYPE_NAMED;
						}
						break;

					default:

						break;
					}

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

					switch (descriptor_type) {
					case ACPI_DESC_TYPE_OPERAND:

						acpi_os_printf
						    ("%12.12s RefCount 0x%04X\n",
						     acpi_ut_get_type_name
						     (descriptor->object.common.
						      type),
						     descriptor->object.common.
						     reference_count);
						break;

					case ACPI_DESC_TYPE_PARSER:

						acpi_os_printf
						    ("AmlOpcode 0x%04hX\n",
						     descriptor->op.asl.
						     aml_opcode);
						break;

					case ACPI_DESC_TYPE_NAMED:

						acpi_os_printf("%4.4s\n",
							       acpi_ut_get_node_name
							       (&descriptor->
								node));
						break;

					default:

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

			num_outstanding++;
		}

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

	ACPI_FUNCTION_TRACE(ns_lookup);

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

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

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

	

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

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

		if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
			while (!acpi_ns_opens_scope(prefix_node->type) &&
			       prefix_node->type != ACPI_TYPE_ANY) {
				prefix_node = prefix_node->parent;
			}
		}
	}

	

	type_to_check_for = type;

	if (!pathname) {

		

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

		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
				  "Null Pathname (Zero segments), Flags=%X\n",
				  flags));
	} else {
		if (*path == (u8) AML_ROOT_PREFIX) {

			

			this_node = acpi_gbl_root_node;
			search_parent_flag = ACPI_NS_NO_UPSEARCH;

			

			path++;

			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
					  "Path is absolute from root [%p]\n",
					  this_node));
		} else {
			

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

			this_node = prefix_node;
			num_carats = 0;
			while (*path == (u8) AML_PARENT_PREFIX) {

				

				search_parent_flag = ACPI_NS_NO_UPSEARCH;

				path++;

				

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

					

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

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

		switch (*path) {
		case 0:
			num_segments = 0;
			type = this_node->type;

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

		case AML_DUAL_NAME_PREFIX:

			

			search_parent_flag = ACPI_NS_NO_UPSEARCH;

			

			num_segments = 2;
			path++;

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

		case AML_MULTI_NAME_PREFIX_OP:

			

			search_parent_flag = ACPI_NS_NO_UPSEARCH;

			

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

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

		default:
			num_segments = 1;

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

		ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
	}

	this_search_type = ACPI_TYPE_ANY;
	current_node = this_node;
	while (num_segments && current_node) {
		num_segments--;
		if (!num_segments) {

			

			this_search_type = type;

			if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
			    (flags & ACPI_NS_SEARCH_PARENT)) {
				local_flags |= ACPI_NS_SEARCH_PARENT;
			}

			

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

		

		ACPI_MOVE_32_TO_32(&simple_name, path);

		

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

				

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

			*return_node = this_node;
			return_ACPI_STATUS(status);
		}

		

		if (num_segments > 0) {
			if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
				if (!this_node->object) {
					return_ACPI_STATUS(AE_NOT_EXIST);
				}

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

		

		else {
			if ((type_to_check_for != ACPI_TYPE_ANY) &&
			    (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
			    (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
			    && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
			    && (this_node->type != ACPI_TYPE_ANY)
			    && (this_node->type != type_to_check_for)) {

				

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

			if (type == ACPI_TYPE_ANY) {
				type = this_node->type;
			}
		}

		

		path += ACPI_NAME_SIZE;
		current_node = this_node;
	}
Example #14
0
void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
{
	u32 length;
	u32 index;

	ACPI_FUNCTION_NAME(ex_dump_operand)

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

	if (!obj_desc) {

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

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

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

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

	/* obj_desc is a valid object */

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

	/* Decode object type */

	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
	case ACPI_TYPE_LOCAL_REFERENCE:

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

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

		case AML_NAME_OP:

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

		case AML_INDEX_OP:

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

		case AML_REF_OF_OP:

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

		case AML_ARG_OP:

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

			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {

				/* Value is an Integer */

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

			acpi_os_printf("\n");
			break;

		case AML_LOCAL_OP:

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

			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {

				/* Value is an Integer */

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

			acpi_os_printf("\n");
			break;

		case AML_INT_NAMEPATH_OP:

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

		default:

			/* Unknown opcode */

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

		}
		break;

	case ACPI_TYPE_BUFFER:

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

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

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

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

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

	case ACPI_TYPE_INTEGER:

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

	case ACPI_TYPE_PACKAGE:

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

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

	case ACPI_TYPE_REGION:

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

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

	case ACPI_TYPE_STRING:

		acpi_os_printf("String length %X @ %p ",
			       obj_desc->string.length,
			       obj_desc->string.pointer);

		acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
		acpi_os_printf("\n");
		break;

	case ACPI_TYPE_LOCAL_BANK_FIELD:

		acpi_os_printf("BankField\n");
		break;

	case ACPI_TYPE_LOCAL_REGION_FIELD:

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

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

	case ACPI_TYPE_LOCAL_INDEX_FIELD:

		acpi_os_printf("IndexField\n");
		break;

	case ACPI_TYPE_BUFFER_FIELD:

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

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

	case ACPI_TYPE_EVENT:

		acpi_os_printf("Event\n");
		break;

	case ACPI_TYPE_METHOD:

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

	case ACPI_TYPE_MUTEX:

		acpi_os_printf("Mutex\n");
		break;

	case ACPI_TYPE_DEVICE:

		acpi_os_printf("Device\n");
		break;

	case ACPI_TYPE_POWER:

		acpi_os_printf("Power\n");
		break;

	case ACPI_TYPE_PROCESSOR:

		acpi_os_printf("Processor\n");
		break;

	case ACPI_TYPE_THERMAL:

		acpi_os_printf("Thermal\n");
		break;

	default:
		/* Unknown Type */

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

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


	ACPI_FUNCTION_NAME ("ns_dump_one_object");


	/* Is output enabled? */

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

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

	this_node = acpi_ns_map_handle_to_node (obj_handle);
	type = this_node->type;

	/* Check if the owner matches */

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

	/* Indent the object according to the level */

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

	/* Check the node type and name */

	if (type > ACPI_TYPE_LOCAL_MAX) {
		ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", type));
	}

	if (!acpi_ut_valid_acpi_name (this_node->name.integer)) {
		ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n", this_node->name.integer));
	}

	/*
	 * Now we can print out the pertinent information
	 */
	acpi_os_printf ("%4.4s %-12s %p ",
			acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node);

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

	switch (info->display_type) {
	case ACPI_DISPLAY_SUMMARY:

		if (!obj_desc) {
			/* No attached object, we are done */

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

		switch (type) {
		case ACPI_TYPE_PROCESSOR:

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


		case ACPI_TYPE_DEVICE:

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


		case ACPI_TYPE_METHOD:

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


		case ACPI_TYPE_INTEGER:

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


		case ACPI_TYPE_PACKAGE:

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


		case ACPI_TYPE_BUFFER:

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

				/* Dump some of the buffer */

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


		case ACPI_TYPE_STRING:

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


		case ACPI_TYPE_REGION:

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


		case ACPI_TYPE_LOCAL_REFERENCE:

			acpi_os_printf ("[%s]\n",
					acpi_ps_get_opcode_name (obj_desc->reference.opcode));
			break;


		case ACPI_TYPE_BUFFER_FIELD:

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


		case ACPI_TYPE_LOCAL_REGION_FIELD:

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


		case ACPI_TYPE_LOCAL_BANK_FIELD:

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


		case ACPI_TYPE_LOCAL_INDEX_FIELD:

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


		case ACPI_TYPE_LOCAL_ALIAS:
		case ACPI_TYPE_LOCAL_METHOD_ALIAS:

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

		default:

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

		/* Common field handling */

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

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

		default:
			break;
		}
		break;


	case ACPI_DISPLAY_OBJECTS:

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

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

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

		switch (type) {
		case ACPI_TYPE_METHOD:

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

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

		case ACPI_TYPE_INTEGER:

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

		case ACPI_TYPE_STRING:

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

		case ACPI_TYPE_BUFFER:

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

		default:

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


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

	/* If debug turned off, done */

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


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

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

	/* Dump attached objects */

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

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

		switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
		case ACPI_DESC_TYPE_NAMED:

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


		case ACPI_DESC_TYPE_OPERAND:

			obj_type = ACPI_GET_OBJECT_TYPE (obj_desc);

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


		default:

			acpi_os_printf ("(String or Buffer ptr - not an object descriptor) [%s]\n",
					acpi_ut_get_descriptor_name (obj_desc));
			bytes_to_dump = 16;
			break;
		}

		ACPI_DUMP_BUFFER (obj_desc, bytes_to_dump);

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

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

		/*
		 * Valid object, get the pointer to next level, if any
		 */
		switch (obj_type) {
		case ACPI_TYPE_STRING:
			obj_desc = (void *) obj_desc->string.pointer;
			break;

		case ACPI_TYPE_BUFFER:
			obj_desc = (void *) obj_desc->buffer.pointer;
			break;

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

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

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

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

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

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

		default:
			goto cleanup;
		}

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

cleanup:
	acpi_os_printf ("\n");
	return (AE_OK);
}
Example #16
0
void
acpi_ex_dump_object_descriptor (
	union acpi_operand_object       *obj_desc,
	u32                             flags)
{
	u32                             i;


	ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor");


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

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

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

	/* Common Fields */

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

	/* Object-specific Fields */

	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
	case ACPI_TYPE_INTEGER:

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


	case ACPI_TYPE_STRING:

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

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


	case ACPI_TYPE_BUFFER:

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


	case ACPI_TYPE_PACKAGE:

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

		/* Dump the package contents */

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


	case ACPI_TYPE_DEVICE:

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


	case ACPI_TYPE_EVENT:

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


	case ACPI_TYPE_METHOD:

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


	case ACPI_TYPE_MUTEX:

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


	case ACPI_TYPE_REGION:

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


	case ACPI_TYPE_POWER:

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


	case ACPI_TYPE_PROCESSOR:

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


	case ACPI_TYPE_THERMAL:

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


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

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

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

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

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

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

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


	case ACPI_TYPE_LOCAL_REFERENCE:

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


	case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:

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


	case ACPI_TYPE_LOCAL_NOTIFY:

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


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

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

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

	ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);

	/* Host object must be a Buffer */

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

		status = AE_AML_OPERAND_TYPE;
		goto cleanup;
	}

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

		status = AE_AML_OPERAND_TYPE;
		goto cleanup;
	}

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

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

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

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

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

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

	case AML_CREATE_BIT_FIELD_OP:

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

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

	case AML_CREATE_BYTE_FIELD_OP:

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

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

	case AML_CREATE_WORD_FIELD_OP:

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

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

	case AML_CREATE_DWORD_FIELD_OP:

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

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

	case AML_CREATE_QWORD_FIELD_OP:

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

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

	default:

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

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

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

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

	obj_desc->buffer_field.buffer_obj = buffer_desc;

	/* Reference count for buffer_desc inherits obj_desc count */

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

cleanup:

	/* Always delete the operands */

	acpi_ut_remove_reference(offset_desc);
	acpi_ut_remove_reference(buffer_desc);

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

	/* On failure, delete the result descriptor */

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

		obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
	}

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

	ACPI_FUNCTION_NAME(ex_dump_operand)

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

	if (!obj_desc) {

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

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

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

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

	/* obj_desc is a valid object */

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

	/* Decode object type */

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

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

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

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

		case ACPI_REFCLASS_INDEX:

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

		case ACPI_REFCLASS_TABLE:

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

		case ACPI_REFCLASS_REFOF:

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

		case ACPI_REFCLASS_NAME:

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

		case ACPI_REFCLASS_ARG:
		case ACPI_REFCLASS_LOCAL:

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

		default:	/* Unknown reference class */

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

	case ACPI_TYPE_BUFFER:

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

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

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

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

	case ACPI_TYPE_INTEGER:

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

#if 0
	case ACPI_TYPE_PACKAGE:

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

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

	case ACPI_TYPE_REGION:

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

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

	case ACPI_TYPE_STRING:

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

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

	case ACPI_TYPE_LOCAL_BANK_FIELD:

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

	case ACPI_TYPE_LOCAL_REGION_FIELD:

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

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

	case ACPI_TYPE_LOCAL_INDEX_FIELD:

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

	case ACPI_TYPE_BUFFER_FIELD:

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

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

	case ACPI_TYPE_EVENT:

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

	case ACPI_TYPE_METHOD:

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

	case ACPI_TYPE_MUTEX:

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

	case ACPI_TYPE_DEVICE:

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

	case ACPI_TYPE_POWER:

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

	case ACPI_TYPE_PROCESSOR:

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

	case ACPI_TYPE_THERMAL:

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

	default:
		/* Unknown Type */

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

	return str_len;
}
acpi_status
acpi_ns_attach_object(struct acpi_namespace_node *node,
		      union acpi_operand_object *object, acpi_object_type type)
{
	union acpi_operand_object *obj_desc;
	union acpi_operand_object *last_obj_desc;
	acpi_object_type object_type = ACPI_TYPE_ANY;

	ACPI_FUNCTION_TRACE(ns_attach_object);

	if (!node) {

		

		ACPI_ERROR((AE_INFO, "Null NamedObj handle"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (!object && (ACPI_TYPE_ANY != type)) {

		

		ACPI_ERROR((AE_INFO,
			    "Null object, but type not ACPI_TYPE_ANY"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {

		

		ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
			    node, acpi_ut_get_descriptor_name(node)));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	

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

		return_ACPI_STATUS(AE_OK);
	}

	

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

	else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) &&
		 ((struct acpi_namespace_node *)object)->object) {
		obj_desc = ((struct acpi_namespace_node *)object)->object;
		object_type = ((struct acpi_namespace_node *)object)->type;
	}

	else {
		obj_desc = (union acpi_operand_object *)object;

		

		object_type = type;
	}

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

	

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

	if (obj_desc) {
		acpi_ut_add_reference(obj_desc);

		last_obj_desc = obj_desc;
		while (last_obj_desc->common.next_object) {
			last_obj_desc = last_obj_desc->common.next_object;
		}

		

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

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

	return_ACPI_STATUS(AE_OK);
}
Example #20
0
acpi_status
acpi_ds_store_object_to_local (
	u16                             opcode,
	u32                             index,
	union acpi_operand_object       *obj_desc,
	struct acpi_walk_state          *walk_state)
{
	acpi_status                     status;
	struct acpi_namespace_node      *node;
	union acpi_operand_object       *current_obj_desc;
	union acpi_operand_object       *new_obj_desc;


	ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
		opcode, index, obj_desc));

	/* Parameter validation */

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

	/* Get the namespace node for the arg/local */

	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	current_obj_desc = acpi_ns_get_attached_object (node);
	if (current_obj_desc == obj_desc) {
		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
			obj_desc));
		return_ACPI_STATUS (status);
	}

	/*
	 * If the reference count on the object is more than one, we must
	 * take a copy of the object before we store.  A reference count
	 * of exactly 1 means that the object was just created during the
	 * evaluation of an expression, and we can safely use it since it
	 * is not used anywhere else.
	 */
	new_obj_desc = obj_desc;
	if (obj_desc->common.reference_count > 1) {
		status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
		if (ACPI_FAILURE (status)) {
			return_ACPI_STATUS (status);
		}
	}

	/*
	 * 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 (current_obj_desc) {
		/*
		 * 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) {
			/*
			 * Make sure that the object is the correct type.  This may be overkill, but
			 * it is here because references were NS nodes in the past.  Now they are
			 * operand objects of type Reference.
			 */
			if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
				ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
						acpi_ut_get_descriptor_name (current_obj_desc)));
				return_ACPI_STATUS (AE_AML_INTERNAL);
			}

			/*
			 * If we have a valid reference object that came from ref_of(), do the
			 * indirect store
			 */
			if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
				(current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
						"Arg (%p) is an obj_ref(Node), storing in node %p\n",
						new_obj_desc, current_obj_desc));

				/*
				 * Store this object to the Node (perform the indirect store)
				 * NOTE: No implicit conversion is performed, as per the ACPI
				 * specification rules on storing to Locals/Args.
				 */
				status = acpi_ex_store_object_to_node (new_obj_desc,
						 current_obj_desc->reference.object, walk_state,
						 ACPI_NO_IMPLICIT_CONVERSION);

				/* Remove local reference if we copied the object above */

				if (new_obj_desc != obj_desc) {
					acpi_ut_remove_reference (new_obj_desc);
				}
				return_ACPI_STATUS (status);
			}
		}

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

	/*
	 * Install the Obj descriptor (*new_obj_desc) into
	 * the descriptor for the Arg or Local.
	 * (increments the object reference count by one)
	 */
	status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);

	/* Remove local reference if we copied the object above */

	if (new_obj_desc != obj_desc) {
		acpi_ut_remove_reference (new_obj_desc);
	}

	return_ACPI_STATUS (status);
}