Пример #1
0
acpi_parse_object*
acpi_ps_alloc_op (
	u16                     opcode)
{
	acpi_parse_object       *op = NULL;
	u32                     size;
	u8                      flags;
	const acpi_opcode_info  *op_info;


	FUNCTION_ENTRY ();


	op_info = acpi_ps_get_opcode_info (opcode);

	/* Allocate the minimum required size object */

	if (op_info->flags & AML_DEFER) {
		size = sizeof (acpi_parse2_object);
		flags = PARSEOP_DEFERRED;
	}

	else if (op_info->flags & AML_NAMED) {
		size = sizeof (acpi_parse2_object);
		flags = PARSEOP_NAMED;
	}

	else if (opcode == AML_INT_BYTELIST_OP) {
		size = sizeof (acpi_parse2_object);
		flags = PARSEOP_BYTELIST;
	}

	else {
		size = sizeof (acpi_parse_object);
		flags = PARSEOP_GENERIC;
	}


	if (size == sizeof (acpi_parse_object)) {
		/*
		 * The generic op is by far the most common (16 to 1)
		 */
		op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE);
	}

	else {
		op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT);
	}

	/* Initialize the Op */

	if (op) {
		acpi_ps_init_op (op, opcode);
		op->flags = flags;
	}

	return (op);
}
Пример #2
0
void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode)
{
	ACPI_FUNCTION_ENTRY();

	op->common.descriptor_type = ACPI_DESC_TYPE_PARSER;
	op->common.aml_opcode = opcode;

	ACPI_DISASM_ONLY_MEMBERS(strncpy(op->common.aml_op_name,
					 (acpi_ps_get_opcode_info(opcode))->
					 name, sizeof(op->common.aml_op_name)));
}
Пример #3
0
acpi_status
acpi_ds_build_internal_object (
	struct acpi_walk_state          *walk_state,
	union acpi_parse_object         *op,
	union acpi_operand_object       **obj_desc_ptr)
{
	union acpi_operand_object       *obj_desc;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ds_build_internal_object");


	*obj_desc_ptr = NULL;
	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
		/*
		 * This is an named object reference.  If this name was
		 * previously looked up in the namespace, it was stored in this op.
		 * Otherwise, go ahead and look it up now
		 */
		if (!op->common.node) {
			status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string,
					  ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
					  ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
					  (struct acpi_namespace_node **) &(op->common.node));

			if (ACPI_FAILURE (status)) {
				ACPI_REPORT_NSERROR (op->common.value.string, status);
				return_ACPI_STATUS (status);
			}
		}
	}

	/* Create and init the internal ACPI object */

	obj_desc = acpi_ut_create_internal_object ((acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
	if (!obj_desc) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc);
	if (ACPI_FAILURE (status)) {
		acpi_ut_remove_reference (obj_desc);
		return_ACPI_STATUS (status);
	}

	*obj_desc_ptr = obj_desc;
	return_ACPI_STATUS (AE_OK);
}
Пример #4
0
static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op)
{
	const struct acpi_opcode_info *info;

	info = acpi_ps_get_opcode_info(op->common.aml_opcode);

	acpi_os_printf("Parser Op Descriptor:\n");
	acpi_os_printf("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode);

	ACPI_DEBUG_ONLY_MEMBERS(acpi_os_printf("%20.20s : %s\n", "Opcode Name",
					       info->name));

	acpi_os_printf("%20.20s : %p\n", "Value/ArgList", op->common.value.arg);
	acpi_os_printf("%20.20s : %p\n", "Parent", op->common.parent);
	acpi_os_printf("%20.20s : %p\n", "NextOp", op->common.next);
}
Пример #5
0
char *acpi_ps_get_opcode_name(u16 opcode)
{
#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)

	const struct acpi_opcode_info *op;

	op = acpi_ps_get_opcode_info(opcode);

	/* Always guaranteed to return a valid pointer */

	return (op->name);

#else
	return ("OpcodeName unavailable");

#endif
}
Пример #6
0
union acpi_parse_object *acpi_ps_alloc_op(u16 opcode, u8 *aml)
{
	union acpi_parse_object *op;
	const struct acpi_opcode_info *op_info;
	u8 flags = ACPI_PARSEOP_GENERIC;

	ACPI_FUNCTION_ENTRY();

	op_info = acpi_ps_get_opcode_info(opcode);

	/* Determine type of parse_op required */

	if (op_info->flags & AML_DEFER) {
		flags = ACPI_PARSEOP_DEFERRED;
	} else if (op_info->flags & AML_NAMED) {
		flags = ACPI_PARSEOP_NAMED_OBJECT;
	} else if (opcode == AML_INT_BYTELIST_OP) {
		flags = ACPI_PARSEOP_BYTELIST;
	}

	/* Allocate the minimum required size object */

	if (flags == ACPI_PARSEOP_GENERIC) {

		/* The generic op (default) is by far the most common (16 to 1) */

		op = acpi_os_acquire_object(acpi_gbl_ps_node_cache);
	} else {
		/* Extended parseop */

		op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache);
	}

	/* Initialize the Op */

	if (op) {
		acpi_ps_init_op(op, opcode);
		op->common.aml = aml;
		op->common.flags = flags;
	}

	return (op);
}
Пример #7
0
void
acpi_ps_init_op (
	acpi_parse_object       *op,
	u16                     opcode)
{
	const acpi_opcode_info  *aml_op;


	FUNCTION_ENTRY ();


	op->data_type = ACPI_DESC_TYPE_PARSER;
	op->opcode = opcode;

	aml_op = acpi_ps_get_opcode_info (opcode);

	DEBUG_ONLY_MEMBERS (STRNCPY (op->op_name, aml_op->name,
			   sizeof (op->op_name)));
}
Пример #8
0
union acpi_parse_object *acpi_ps_alloc_op(u16 opcode)
{
	union acpi_parse_object *op;
	const struct acpi_opcode_info *op_info;
	u8 flags = ACPI_PARSEOP_GENERIC;

	ACPI_FUNCTION_ENTRY();

	op_info = acpi_ps_get_opcode_info(opcode);

	

	if (op_info->flags & AML_DEFER) {
		flags = ACPI_PARSEOP_DEFERRED;
	} else if (op_info->flags & AML_NAMED) {
		flags = ACPI_PARSEOP_NAMED;
	} else if (opcode == AML_INT_BYTELIST_OP) {
		flags = ACPI_PARSEOP_BYTELIST;
	}

	

	if (flags == ACPI_PARSEOP_GENERIC) {

		

		op = acpi_os_acquire_object(acpi_gbl_ps_node_cache);
	} else {
		

		op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache);
	}

	

	if (op) {
		acpi_ps_init_op(op, opcode);
		op->common.flags = flags;
	}

	return (op);
}
Пример #9
0
static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
{
	u32 aml_offset;

	ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);

	walk_state->aml = walk_state->parser_state.aml;
	walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));

	/*
	 * First cut to determine what we have found:
	 * 1) A valid AML opcode
	 * 2) A name string
	 * 3) An unknown/invalid opcode
	 */
	walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);

	switch (walk_state->op_info->class) {
	case AML_CLASS_ASCII:
	case AML_CLASS_PREFIX:
		/*
		 * Starts with a valid prefix or ASCII char, this is a name
		 * string. Convert the bare name string to a namepath.
		 */
		walk_state->opcode = AML_INT_NAMEPATH_OP;
		walk_state->arg_types = ARGP_NAMESTRING;
		break;

	case AML_CLASS_UNKNOWN:

		/* The opcode is unrecognized. Complain and skip unknown opcodes */

		if (walk_state->pass_number == 2) {
			aml_offset = (u32)ACPI_PTR_DIFF(walk_state->aml,
							walk_state->
							parser_state.aml_start);

			ACPI_ERROR((AE_INFO,
				    "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
				    walk_state->opcode,
				    (u32)(aml_offset +
					  sizeof(struct acpi_table_header))));

			ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
					 48);

#ifdef ACPI_ASL_COMPILER
			/*
			 * This is executed for the disassembler only. Output goes
			 * to the disassembled ASL output file.
			 */
			acpi_os_printf
			    ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
			     walk_state->opcode,
			     (u32)(aml_offset +
				   sizeof(struct acpi_table_header)));

			ACPI_ERROR((AE_INFO,
				    "Aborting disassembly, AML byte code is corrupt"));

			/* Dump the context surrounding the invalid opcode */

			acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
					     aml - 16), 48, DB_BYTE_DISPLAY,
					    (aml_offset +
					     sizeof(struct acpi_table_header) -
					     16));
			acpi_os_printf(" */\n");

			/*
			 * Just abort the disassembly, cannot continue because the
			 * parser is essentially lost. The disassembler can then
			 * randomly fail because an ill-constructed parse tree
			 * can result.
			 */
			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
#endif
		}

		/* Increment past one-byte or two-byte opcode */

		walk_state->parser_state.aml++;
		if (walk_state->opcode > 0xFF) {	/* Can only happen if first byte is 0x5B */
			walk_state->parser_state.aml++;
		}

		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);

	default:

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

		walk_state->parser_state.aml +=
		    acpi_ps_get_opcode_size(walk_state->opcode);
		walk_state->arg_types = walk_state->op_info->parse_args;
		break;
	}

	return_ACPI_STATUS(AE_OK);
}
Пример #10
0
acpi_status
acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
			  union acpi_parse_object *op, acpi_status status)
{
	acpi_status status2;

	ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);

	/*
	 * 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 ASL blocks are closed with
	 * sequential closing braces). We want to terminate each one cleanly.
	 */
	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
			  op));
	do {
		if (op) {
			if (walk_state->ascending_callback != NULL) {
				walk_state->op = op;
				walk_state->op_info =
				    acpi_ps_get_opcode_info(op->common.
							    aml_opcode);
				walk_state->opcode = op->common.aml_opcode;

				status =
				    walk_state->ascending_callback(walk_state);
				status =
				    acpi_ps_next_parse_state(walk_state, op,
							     status);
				if (status == AE_CTRL_PENDING) {
					status =
					    acpi_ps_complete_op(walk_state, &op,
								AE_OK);
					if (ACPI_FAILURE(status)) {
						return_ACPI_STATUS(status);
					}
				}

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

					/* Clean up */
					do {
						if (op) {
							status2 =
							    acpi_ps_complete_this_op
							    (walk_state, op);
							if (ACPI_FAILURE
							    (status2)) {
								return_ACPI_STATUS
								    (status2);
							}
						}

						acpi_ps_pop_scope(&
								  (walk_state->
								   parser_state),
								  &op,
								  &walk_state->
								  arg_types,
								  &walk_state->
								  arg_count);

					} while (op);

					return_ACPI_STATUS(status);
				}

				else if (ACPI_FAILURE(status)) {

					/* First error is most important */

					(void)
					    acpi_ps_complete_this_op(walk_state,
								     op);
					return_ACPI_STATUS(status);
				}
			}

			status2 = acpi_ps_complete_this_op(walk_state, op);
			if (ACPI_FAILURE(status2)) {
				return_ACPI_STATUS(status2);
			}
		}

		acpi_ps_pop_scope(&(walk_state->parser_state), &op,
				  &walk_state->arg_types,
				  &walk_state->arg_count);

	} while (op);

	return_ACPI_STATUS(status);
}
Пример #11
0
acpi_status
acpi_ps_complete_op(struct acpi_walk_state *walk_state,
		    union acpi_parse_object **op, acpi_status status)
{
	acpi_status status2;

	ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);

	/*
	 * Finished one argument of the containing scope
	 */
	walk_state->parser_state.scope->parse_scope.arg_count--;

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

	status2 = acpi_ps_complete_this_op(walk_state, *op);
	if (ACPI_FAILURE(status2)) {
		return_ACPI_STATUS(status2);
	}

	*op = NULL;

	switch (status) {
	case AE_OK:

		break;

	case AE_CTRL_TRANSFER:

		/* We are about to transfer to a called method */

		walk_state->prev_op = NULL;
		walk_state->prev_arg_types = walk_state->arg_types;
		return_ACPI_STATUS(status);

	case AE_CTRL_END:

		acpi_ps_pop_scope(&(walk_state->parser_state), op,
				  &walk_state->arg_types,
				  &walk_state->arg_count);

		if (*op) {
			walk_state->op = *op;
			walk_state->op_info =
			    acpi_ps_get_opcode_info((*op)->common.aml_opcode);
			walk_state->opcode = (*op)->common.aml_opcode;

			status = walk_state->ascending_callback(walk_state);
			status =
			    acpi_ps_next_parse_state(walk_state, *op, status);

			status2 = acpi_ps_complete_this_op(walk_state, *op);
			if (ACPI_FAILURE(status2)) {
				return_ACPI_STATUS(status2);
			}
		}

		status = AE_OK;
		break;

	case AE_CTRL_BREAK:
	case AE_CTRL_CONTINUE:

		/* Pop off scopes until we find the While */

		while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
			acpi_ps_pop_scope(&(walk_state->parser_state), op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);
		}

		/* Close this iteration of the While loop */

		walk_state->op = *op;
		walk_state->op_info =
		    acpi_ps_get_opcode_info((*op)->common.aml_opcode);
		walk_state->opcode = (*op)->common.aml_opcode;

		status = walk_state->ascending_callback(walk_state);
		status = acpi_ps_next_parse_state(walk_state, *op, status);

		status2 = acpi_ps_complete_this_op(walk_state, *op);
		if (ACPI_FAILURE(status2)) {
			return_ACPI_STATUS(status2);
		}

		status = AE_OK;
		break;

	case AE_CTRL_TERMINATE:

		/* Clean up */
		do {
			if (*op) {
				status2 =
				    acpi_ps_complete_this_op(walk_state, *op);
				if (ACPI_FAILURE(status2)) {
					return_ACPI_STATUS(status2);
				}

				acpi_ut_delete_generic_state
				    (acpi_ut_pop_generic_state
				     (&walk_state->control_state));
			}

			acpi_ps_pop_scope(&(walk_state->parser_state), op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);

		} while (*op);

		return_ACPI_STATUS(AE_OK);

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

		do {
			if (*op) {
				status2 =
				    acpi_ps_complete_this_op(walk_state, *op);
				if (ACPI_FAILURE(status2)) {
					return_ACPI_STATUS(status2);
				}
			}

			acpi_ps_pop_scope(&(walk_state->parser_state), op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);

		} while (*op);

#if 0
		/*
		 * TBD: Cleanup parse ops on error
		 */
		if (*op == NULL) {
			acpi_ps_pop_scope(parser_state, op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);
		}
#endif
		walk_state->prev_op = NULL;
		walk_state->prev_arg_types = walk_state->arg_types;
		return_ACPI_STATUS(status);
	}

	/* This scope complete? */

	if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
		acpi_ps_pop_scope(&(walk_state->parser_state), op,
				  &walk_state->arg_types,
				  &walk_state->arg_count);
		ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
	} else {
		*op = NULL;
	}

	return_ACPI_STATUS(AE_OK);
}
Пример #12
0
acpi_status
acpi_ps_create_op(struct acpi_walk_state *walk_state,
		  u8 *aml_op_start, union acpi_parse_object **new_op)
{
	acpi_status status = AE_OK;
	union acpi_parse_object *op;
	union acpi_parse_object *named_op = NULL;
	union acpi_parse_object *parent_scope;
	u8 argument_count;
	const struct acpi_opcode_info *op_info;

	ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);

	status = acpi_ps_get_aml_opcode(walk_state);
	if (status == AE_CTRL_PARSE_CONTINUE) {
		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
	}
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

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

	walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
	op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start);
	if (!op) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	if (walk_state->op_info->flags & AML_NAMED) {
		status =
		    acpi_ps_build_named_op(walk_state, aml_op_start, op,
					   &named_op);
		acpi_ps_free_op(op);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		*new_op = named_op;
		return_ACPI_STATUS(AE_OK);
	}

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

	if (walk_state->op_info->flags & AML_CREATE) {
		/*
		 * Backup to beginning of create_XXXfield declaration
		 * body_length is unknown until we parse the body
		 */
		op->named.data = aml_op_start;
		op->named.length = 0;
	}

	if (walk_state->opcode == AML_BANK_FIELD_OP) {
		/*
		 * Backup to beginning of bank_field declaration
		 * body_length is unknown until we parse the body
		 */
		op->named.data = aml_op_start;
		op->named.length = 0;
	}

	parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
	acpi_ps_append_arg(parent_scope, op);

	if (parent_scope) {
		op_info =
		    acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
		if (op_info->flags & AML_HAS_TARGET) {
			argument_count =
			    acpi_ps_get_argument_count(op_info->type);
			if (parent_scope->common.arg_list_length >
			    argument_count) {
				op->common.flags |= ACPI_PARSEOP_TARGET;
			}
		}

		/*
		 * Special case for both Increment() and Decrement(), where
		 * the lone argument is both a source and a target.
		 */
		else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
			 || (parent_scope->common.aml_opcode ==
			     AML_DECREMENT_OP)) {
			op->common.flags |= ACPI_PARSEOP_TARGET;
		}
	}

	if (walk_state->descending_callback != NULL) {
		/*
		 * Find the object. This will either insert the object into
		 * the namespace or simply look it up
		 */
		walk_state->op = *new_op = op;

		status = walk_state->descending_callback(walk_state, &op);
		status = acpi_ps_next_parse_state(walk_state, op, status);
		if (status == AE_CTRL_PENDING) {
			status = AE_CTRL_PARSE_PENDING;
		}
	}

	return_ACPI_STATUS(status);
}
Пример #13
0
static void
acpi_ex_dump_object(union acpi_operand_object *obj_desc,
		    struct acpi_exdump_info *info)
{
	u8 *target;
	char *name;
	u8 count;

	if (!info) {
		acpi_os_printf
		    ("ExDumpObject: Display not implemented for object type %s\n",
		     acpi_ut_get_object_type_name(obj_desc));
		return;
	}

	/* First table entry must contain the table length (# of table entries) */

	count = info->offset;

	while (count) {
		target = ACPI_ADD_PTR(u8, obj_desc, info->offset);
		name = info->name;

		switch (info->opcode) {
		case ACPI_EXD_INIT:
			break;

		case ACPI_EXD_TYPE:
			acpi_ex_out_string("Type",
					   acpi_ut_get_object_type_name
					   (obj_desc));
			break;

		case ACPI_EXD_UINT8:

			acpi_os_printf("%20s : %2.2X\n", name, *target);
			break;

		case ACPI_EXD_UINT16:

			acpi_os_printf("%20s : %4.4X\n", name,
				       ACPI_GET16(target));
			break;

		case ACPI_EXD_UINT32:

			acpi_os_printf("%20s : %8.8X\n", name,
				       ACPI_GET32(target));
			break;

		case ACPI_EXD_UINT64:

			acpi_os_printf("%20s : %8.8X%8.8X\n", "Value",
				       ACPI_FORMAT_UINT64(ACPI_GET64(target)));
			break;

		case ACPI_EXD_POINTER:

			acpi_ex_out_pointer(name,
					    *ACPI_CAST_PTR(void *, target));
			break;

		case ACPI_EXD_ADDRESS:

			acpi_ex_out_address(name,
					    *ACPI_CAST_PTR
					    (acpi_physical_address, target));
			break;

		case ACPI_EXD_STRING:

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

		case ACPI_EXD_BUFFER:

			ACPI_DUMP_BUFFER(obj_desc->buffer.pointer,
					 obj_desc->buffer.length);
			break;

		case ACPI_EXD_PACKAGE:

			/* Dump the package contents */

			acpi_os_printf("\nPackage Contents:\n");
			acpi_ex_dump_package_obj(obj_desc, 0, 0);
			break;

		case ACPI_EXD_FIELD:

			acpi_ex_dump_object(obj_desc,
					    acpi_ex_dump_field_common);
			break;

		case ACPI_EXD_REFERENCE:

			acpi_ex_out_string("Opcode",
					   (acpi_ps_get_opcode_info
					    (obj_desc->reference.opcode))->
					   name);
			acpi_ex_dump_reference_obj(obj_desc);
			break;

		default:
			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
				       info->opcode);
			return;
		}

		info++;
		count--;
	}
}
Пример #14
0
void
acpi_db_display_path (
	acpi_parse_object       *op)
{
	acpi_parse_object       *prev;
	acpi_parse_object       *search;
	u32                     name;
	u8                      do_dot = FALSE;
	acpi_parse_object       *name_path;
	const acpi_opcode_info  *op_info;


	/* We are only interested in named objects */

	op_info = acpi_ps_get_opcode_info (op->opcode);
	if (!(op_info->flags & AML_NSNODE)) {
		return;
	}


	if (op_info->flags & AML_CREATE) {
		/* Field creation - check for a fully qualified namepath */

		if (op->opcode == AML_CREATE_FIELD_OP) {
			name_path = acpi_ps_get_arg (op, 3);
		}
		else {
			name_path = acpi_ps_get_arg (op, 2);
		}

		if ((name_path) &&
			(name_path->value.string) &&
			(name_path->value.string[0] == '\\')) {
			acpi_db_display_namestring (name_path->value.string);
			return;
		}
	}

	prev = NULL;            /* Start with Root Node */

	while (prev != op) {
		/* Search upwards in the tree to find scope with "prev" as its parent */

		search = op;
		for (; ;) {
			if (search->parent == prev) {
				break;
			}

			/* Go up one level */

			search = search->parent;
		}

		if (prev) {
			op_info = acpi_ps_get_opcode_info (search->opcode);
			if (!(op_info->flags & AML_FIELD)) {
				/* below root scope, append scope name */

				if (do_dot) {
					/* append dot */

					acpi_os_printf (".");
				}

				if (op_info->flags & AML_CREATE) {
					if (op->opcode == AML_CREATE_FIELD_OP) {
						name_path = acpi_ps_get_arg (op, 3);
					}
					else {
						name_path = acpi_ps_get_arg (op, 2);
					}

					if ((name_path) &&
						(name_path->value.string)) {
						acpi_os_printf ("%4.4s", name_path->value.string);
					}
				}

				else {
					name = acpi_ps_get_name (search);
					acpi_os_printf ("%4.4s", &name);
				}

				do_dot = TRUE;
			}
		}

		prev = search;
	}
}
Пример #15
0
acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
{
	acpi_status status = AE_OK;
	acpi_status status2;
	union acpi_parse_object *op = NULL;	/* current op */
	union acpi_parse_object *arg = NULL;
	union acpi_parse_object *pre_op = NULL;
	struct acpi_parse_state *parser_state;
	u8 *aml_op_start = NULL;

	ACPI_FUNCTION_TRACE_PTR("ps_parse_loop", walk_state);

	if (walk_state->descending_callback == NULL) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	parser_state = &walk_state->parser_state;
	walk_state->arg_types = 0;

#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))

	if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
		/* We are restarting a preempted control method */

		if (acpi_ps_has_completed_scope(parser_state)) {
			/*
			 * We must check if a predicate to an IF or WHILE statement
			 * was just completed
			 */
			if ((parser_state->scope->parse_scope.op) &&
			    ((parser_state->scope->parse_scope.op->common.
			      aml_opcode == AML_IF_OP)
			     || (parser_state->scope->parse_scope.op->common.
				 aml_opcode == AML_WHILE_OP))
			    && (walk_state->control_state)
			    && (walk_state->control_state->common.state ==
				ACPI_CONTROL_PREDICATE_EXECUTING)) {
				/*
				 * A predicate was just completed, get the value of the
				 * predicate and branch based on that value
				 */
				walk_state->op = NULL;
				status =
				    acpi_ds_get_predicate_value(walk_state,
								ACPI_TO_POINTER
								(TRUE));
				if (ACPI_FAILURE(status)
				    && ((status & AE_CODE_MASK) !=
					AE_CODE_CONTROL)) {
					if (status == AE_AML_NO_RETURN_VALUE) {
						ACPI_EXCEPTION((AE_INFO, status,
								"Invoked method did not return a value"));

					}
					ACPI_EXCEPTION((AE_INFO, status,
							"get_predicate Failed"));
					return_ACPI_STATUS(status);
				}

				status =
				    acpi_ps_next_parse_state(walk_state, op,
							     status);
			}

			acpi_ps_pop_scope(parser_state, &op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);
			ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
					  "Popped scope, Op=%p\n", op));
		} else if (walk_state->prev_op) {
			/* We were in the middle of an op */

			op = walk_state->prev_op;
			walk_state->arg_types = walk_state->prev_arg_types;
		}
	}
#endif

	/* Iterative parsing loop, while there is more AML to process: */

	while ((parser_state->aml < parser_state->aml_end) || (op)) {
		aml_op_start = parser_state->aml;
		if (!op) {
			/* Get the next opcode from the AML stream */

			walk_state->aml_offset =
			    (u32) ACPI_PTR_DIFF(parser_state->aml,
						parser_state->aml_start);
			walk_state->opcode = acpi_ps_peek_opcode(parser_state);

			/*
			 * First cut to determine what we have found:
			 * 1) A valid AML opcode
			 * 2) A name string
			 * 3) An unknown/invalid opcode
			 */
			walk_state->op_info =
			    acpi_ps_get_opcode_info(walk_state->opcode);
			switch (walk_state->op_info->class) {
			case AML_CLASS_ASCII:
			case AML_CLASS_PREFIX:
				/*
				 * Starts with a valid prefix or ASCII char, this is a name
				 * string.  Convert the bare name string to a namepath.
				 */
				walk_state->opcode = AML_INT_NAMEPATH_OP;
				walk_state->arg_types = ARGP_NAMESTRING;
				break;

			case AML_CLASS_UNKNOWN:

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

				ACPI_ERROR((AE_INFO,
					    "Found unknown opcode %X at AML address %p offset %X, ignoring",
					    walk_state->opcode,
					    parser_state->aml,
					    walk_state->aml_offset));

				ACPI_DUMP_BUFFER(parser_state->aml, 128);

				/* Assume one-byte bad opcode */

				parser_state->aml++;
				continue;

			default:

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

				parser_state->aml +=
				    acpi_ps_get_opcode_size(walk_state->opcode);
				walk_state->arg_types =
				    walk_state->op_info->parse_args;
				break;
			}

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

			if (walk_state->op_info->flags & AML_NAMED) {
				/* Allocate a new pre_op if necessary */

				if (!pre_op) {
					pre_op =
					    acpi_ps_alloc_op(walk_state->
							     opcode);
					if (!pre_op) {
						status = AE_NO_MEMORY;
						goto close_this_op;
					}
				}

				pre_op->common.value.arg = NULL;
				pre_op->common.aml_opcode = walk_state->opcode;

				/*
				 * Get and append arguments until we find the node that contains
				 * the name (the type ARGP_NAME).
				 */
				while (GET_CURRENT_ARG_TYPE
				       (walk_state->arg_types)
				       &&
				       (GET_CURRENT_ARG_TYPE
					(walk_state->arg_types) != ARGP_NAME)) {
					status =
					    acpi_ps_get_next_arg(walk_state,
								 parser_state,
								 GET_CURRENT_ARG_TYPE
								 (walk_state->
								  arg_types),
								 &arg);
					if (ACPI_FAILURE(status)) {
						goto close_this_op;
					}

					acpi_ps_append_arg(pre_op, arg);
					INCREMENT_ARG_LIST(walk_state->
							   arg_types);
				}

				/*
				 * Make sure that we found a NAME and didn't run out of
				 * arguments
				 */
				if (!GET_CURRENT_ARG_TYPE
				    (walk_state->arg_types)) {
					status = AE_AML_NO_OPERAND;
					goto close_this_op;
				}

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

				INCREMENT_ARG_LIST(walk_state->arg_types);

				/*
				 * Find the object.  This will either insert the object into
				 * the namespace or simply look it up
				 */
				walk_state->op = NULL;

				status =
				    walk_state->descending_callback(walk_state,
								    &op);
				if (ACPI_FAILURE(status)) {
					ACPI_EXCEPTION((AE_INFO, status,
							"During name lookup/catalog"));
					goto close_this_op;
				}

				if (!op) {
					continue;
				}

				status =
				    acpi_ps_next_parse_state(walk_state, op,
							     status);
				if (status == AE_CTRL_PENDING) {
					status = AE_OK;
					goto close_this_op;
				}

				if (ACPI_FAILURE(status)) {
					goto close_this_op;
				}

				acpi_ps_append_arg(op,
						   pre_op->common.value.arg);
				acpi_gbl_depth++;

				if (op->common.aml_opcode == AML_REGION_OP) {
					/*
					 * Defer final parsing of an operation_region 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 term_arg 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)
					 */
					op->named.data = aml_op_start;
					op->named.length = 0;
				}
			} else {
				/* Not a named opcode, just allocate Op and append to parent */

				walk_state->op_info =
				    acpi_ps_get_opcode_info(walk_state->opcode);
				op = acpi_ps_alloc_op(walk_state->opcode);
				if (!op) {
					status = AE_NO_MEMORY;
					goto close_this_op;
				}

				if (walk_state->op_info->flags & AML_CREATE) {
					/*
					 * Backup to beginning of create_xXXfield declaration
					 * body_length is unknown until we parse the body
					 */
					op->named.data = aml_op_start;
					op->named.length = 0;
				}

				acpi_ps_append_arg(acpi_ps_get_parent_scope
						   (parser_state), op);

				if ((walk_state->descending_callback != NULL)) {
					/*
					 * Find the object. This will either insert the object into
					 * the namespace or simply look it up
					 */
					walk_state->op = op;

					status =
					    walk_state->
					    descending_callback(walk_state,
								&op);
					status =
					    acpi_ps_next_parse_state(walk_state,
								     op,
								     status);
					if (status == AE_CTRL_PENDING) {
						status = AE_OK;
						goto close_this_op;
					}

					if (ACPI_FAILURE(status)) {
						goto close_this_op;
					}
				}
			}

			op->common.aml_offset = walk_state->aml_offset;

			if (walk_state->op_info) {
				ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
						  "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n",
						  (u32) op->common.aml_opcode,
						  walk_state->op_info->name, op,
						  parser_state->aml,
						  op->common.aml_offset));
			}
		}

		/*
		 * Start arg_count at zero because we don't know if there are
		 * any args yet
		 */
		walk_state->arg_count = 0;

		/* Are there any arguments that must be processed? */

		if (walk_state->arg_types) {
			/* Get arguments */

			switch (op->common.aml_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 */

				acpi_ps_get_next_simple_arg(parser_state,
							    GET_CURRENT_ARG_TYPE
							    (walk_state->
							     arg_types), op);
				break;

			case AML_INT_NAMEPATH_OP:	/* AML_NAMESTRING_ARG */

				status =
				    acpi_ps_get_next_namepath(walk_state,
							      parser_state, op,
							      1);
				if (ACPI_FAILURE(status)) {
					goto close_this_op;
				}

				walk_state->arg_types = 0;
				break;

			default:
				/*
				 * Op is not a constant or string, append each argument
				 * to the Op
				 */
				while (GET_CURRENT_ARG_TYPE
				       (walk_state->arg_types)
				       && !walk_state->arg_count) {
					walk_state->aml_offset = (u32)
					    ACPI_PTR_DIFF(parser_state->aml,
							  parser_state->
							  aml_start);

					status =
					    acpi_ps_get_next_arg(walk_state,
								 parser_state,
								 GET_CURRENT_ARG_TYPE
								 (walk_state->
								  arg_types),
								 &arg);
					if (ACPI_FAILURE(status)) {
						goto close_this_op;
					}

					if (arg) {
						arg->common.aml_offset =
						    walk_state->aml_offset;
						acpi_ps_append_arg(op, arg);
					}
					INCREMENT_ARG_LIST(walk_state->
							   arg_types);
				}

				/* Special processing for certain opcodes */

				/* TBD (remove): Temporary mechanism to disable this code if needed */

#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE

				if ((walk_state->pass_number <=
				     ACPI_IMODE_LOAD_PASS1)
				    &&
				    ((walk_state->
				      parse_flags & ACPI_PARSE_DISASSEMBLE) ==
				     0)) {
					/*
					 * We want to skip If/Else/While constructs during Pass1
					 * because we want to actually conditionally execute the
					 * code during Pass2.
					 *
					 * Except for disassembly, where we always want to
					 * walk the If/Else/While packages
					 */
					switch (op->common.aml_opcode) {
					case AML_IF_OP:
					case AML_ELSE_OP:
					case AML_WHILE_OP:

						ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
								  "Pass1: Skipping an If/Else/While body\n"));

						/* Skip body of if/else/while in pass 1 */

						parser_state->aml =
						    parser_state->pkg_end;
						walk_state->arg_count = 0;
						break;

					default:
						break;
					}
				}
#endif
				switch (op->common.aml_opcode) {
				case AML_METHOD_OP:

					/*
					 * Skip parsing of control method
					 * because we don't have enough info in the first pass
					 * to parse it correctly.
					 *
					 * Save the length and address of the body
					 */
					op->named.data = parser_state->aml;
					op->named.length =
					    (u32) (parser_state->pkg_end -
						   parser_state->aml);

					/* Skip body of method */

					parser_state->aml =
					    parser_state->pkg_end;
					walk_state->arg_count = 0;
					break;

				case AML_BUFFER_OP:
				case AML_PACKAGE_OP:
				case AML_VAR_PACKAGE_OP:

					if ((op->common.parent) &&
					    (op->common.parent->common.
					     aml_opcode == AML_NAME_OP)
					    && (walk_state->pass_number <=
						ACPI_IMODE_LOAD_PASS2)) {
						/*
						 * Skip parsing of Buffers and Packages
						 * because we don't have enough info in the first pass
						 * to parse them correctly.
						 */
						op->named.data = aml_op_start;
						op->named.length =
						    (u32) (parser_state->
							   pkg_end -
							   aml_op_start);

						/* Skip body */

						parser_state->aml =
						    parser_state->pkg_end;
						walk_state->arg_count = 0;
					}
					break;

				case AML_WHILE_OP:

					if (walk_state->control_state) {
						walk_state->control_state->
						    control.package_end =
						    parser_state->pkg_end;
					}
					break;

				default:

					/* No action for all other opcodes */
					break;
				}
				break;
			}
		}

		/* Check for arguments that need to be processed */

		if (walk_state->arg_count) {
			/*
			 * There are arguments (complex ones), push Op and
			 * prepare for argument
			 */
			status = acpi_ps_push_scope(parser_state, op,
						    walk_state->arg_types,
						    walk_state->arg_count);
			if (ACPI_FAILURE(status)) {
				goto close_this_op;
			}
			op = NULL;
			continue;
		}

		/*
		 * All arguments have been processed -- Op is complete,
		 * prepare for next
		 */
		walk_state->op_info =
		    acpi_ps_get_opcode_info(op->common.aml_opcode);
		if (walk_state->op_info->flags & AML_NAMED) {
			if (acpi_gbl_depth) {
				acpi_gbl_depth--;
			}

			if (op->common.aml_opcode == AML_REGION_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 op_region declaration, we now
				 * know the length.
				 */
				op->named.length =
				    (u32) (parser_state->aml - op->named.data);
			}
		}

		if (walk_state->op_info->flags & AML_CREATE) {
			/*
			 * Backup to beginning of create_xXXfield declaration (1 for
			 * Opcode)
			 *
			 * body_length is unknown until we parse the body
			 */
			op->named.length =
			    (u32) (parser_state->aml - op->named.data);
		}

		/* This op complete, notify the dispatcher */

		if (walk_state->ascending_callback != NULL) {
			walk_state->op = op;
			walk_state->opcode = op->common.aml_opcode;

			status = walk_state->ascending_callback(walk_state);
			status =
			    acpi_ps_next_parse_state(walk_state, op, status);
			if (status == AE_CTRL_PENDING) {
				status = AE_OK;
				goto close_this_op;
			}
		}

	      close_this_op:
		/*
		 * Finished one argument of the containing scope
		 */
		parser_state->scope->parse_scope.arg_count--;

		/* Finished with pre_op */

		if (pre_op) {
			acpi_ps_free_op(pre_op);
			pre_op = NULL;
		}

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

		status2 = acpi_ps_complete_this_op(walk_state, op);
		if (ACPI_FAILURE(status2)) {
			return_ACPI_STATUS(status2);
		}
		op = NULL;

		switch (status) {
		case AE_OK:
			break;

		case AE_CTRL_TRANSFER:

			/* We are about to transfer to a called method. */

			walk_state->prev_op = op;
			walk_state->prev_arg_types = walk_state->arg_types;
			return_ACPI_STATUS(status);

		case AE_CTRL_END:

			acpi_ps_pop_scope(parser_state, &op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);

			if (op) {
				walk_state->op = op;
				walk_state->op_info =
				    acpi_ps_get_opcode_info(op->common.
							    aml_opcode);
				walk_state->opcode = op->common.aml_opcode;

				status =
				    walk_state->ascending_callback(walk_state);
				status =
				    acpi_ps_next_parse_state(walk_state, op,
							     status);

				status2 =
				    acpi_ps_complete_this_op(walk_state, op);
				if (ACPI_FAILURE(status2)) {
					return_ACPI_STATUS(status2);
				}
				op = NULL;
			}
			status = AE_OK;
			break;

		case AE_CTRL_BREAK:
		case AE_CTRL_CONTINUE:

			/* Pop off scopes until we find the While */

			while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
				acpi_ps_pop_scope(parser_state, &op,
						  &walk_state->arg_types,
						  &walk_state->arg_count);

				if (op->common.aml_opcode != AML_WHILE_OP) {
					status2 =
					    acpi_ds_result_stack_pop
					    (walk_state);
					if (ACPI_FAILURE(status2)) {
						return_ACPI_STATUS(status2);
					}
				}
			}

			/* Close this iteration of the While loop */

			walk_state->op = op;
			walk_state->op_info =
			    acpi_ps_get_opcode_info(op->common.aml_opcode);
			walk_state->opcode = op->common.aml_opcode;

			status = walk_state->ascending_callback(walk_state);
			status =
			    acpi_ps_next_parse_state(walk_state, op, status);

			status2 = acpi_ps_complete_this_op(walk_state, op);
			if (ACPI_FAILURE(status2)) {
				return_ACPI_STATUS(status2);
			}
			op = NULL;

			status = AE_OK;
			break;

		case AE_CTRL_TERMINATE:

			status = AE_OK;

			/* Clean up */
			do {
				if (op) {
					status2 =
					    acpi_ps_complete_this_op(walk_state,
								     op);
					if (ACPI_FAILURE(status2)) {
						return_ACPI_STATUS(status2);
					}
				}
				acpi_ps_pop_scope(parser_state, &op,
						  &walk_state->arg_types,
						  &walk_state->arg_count);

			} while (op);

			return_ACPI_STATUS(status);

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

			do {
				if (op) {
					status2 =
					    acpi_ps_complete_this_op(walk_state,
								     op);
					if (ACPI_FAILURE(status2)) {
						return_ACPI_STATUS(status2);
					}
				}
				acpi_ps_pop_scope(parser_state, &op,
						  &walk_state->arg_types,
						  &walk_state->arg_count);

			} while (op);

			/*
			 * TBD: Cleanup parse ops on error
			 */
#if 0
			if (op == NULL) {
				acpi_ps_pop_scope(parser_state, &op,
						  &walk_state->arg_types,
						  &walk_state->arg_count);
			}
#endif
			walk_state->prev_op = op;
			walk_state->prev_arg_types = walk_state->arg_types;
			return_ACPI_STATUS(status);
		}

		/* This scope complete? */

		if (acpi_ps_has_completed_scope(parser_state)) {
			acpi_ps_pop_scope(parser_state, &op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);
			ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
					  "Popped scope, Op=%p\n", op));
		} else {
			op = NULL;
		}

	}			/* while parser_state->Aml */
Пример #16
0
acpi_status
acpi_ps_complete_op(struct acpi_walk_state *walk_state,
		    union acpi_parse_object **op, acpi_status status)
{
	acpi_status status2;

	ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);

	/*
	 * Finished one argument of the containing scope
	 */
	walk_state->parser_state.scope->parse_scope.arg_count--;

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

	status2 = acpi_ps_complete_this_op(walk_state, *op);
	if (ACPI_FAILURE(status2)) {
		return_ACPI_STATUS(status2);
	}

	*op = NULL;

	switch (status) {
	case AE_OK:

		break;

	case AE_CTRL_TRANSFER:

		/* We are about to transfer to a called method */

		walk_state->prev_op = NULL;
		walk_state->prev_arg_types = walk_state->arg_types;
		return_ACPI_STATUS(status);

	case AE_CTRL_END:

		acpi_ps_pop_scope(&(walk_state->parser_state), op,
				  &walk_state->arg_types,
				  &walk_state->arg_count);

		if (*op) {
			walk_state->op = *op;
			walk_state->op_info =
			    acpi_ps_get_opcode_info((*op)->common.aml_opcode);
			walk_state->opcode = (*op)->common.aml_opcode;

			status = walk_state->ascending_callback(walk_state);
			status =
			    acpi_ps_next_parse_state(walk_state, *op, status);

			status2 = acpi_ps_complete_this_op(walk_state, *op);
			if (ACPI_FAILURE(status2)) {
				return_ACPI_STATUS(status2);
			}
		}

		status = AE_OK;
		break;

	case AE_CTRL_BREAK:
	case AE_CTRL_CONTINUE:

		/* Pop off scopes until we find the While */

		while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
			acpi_ps_pop_scope(&(walk_state->parser_state), op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);
		}

		/* Close this iteration of the While loop */

		walk_state->op = *op;
		walk_state->op_info =
		    acpi_ps_get_opcode_info((*op)->common.aml_opcode);
		walk_state->opcode = (*op)->common.aml_opcode;

		status = walk_state->ascending_callback(walk_state);
		status = acpi_ps_next_parse_state(walk_state, *op, status);

		status2 = acpi_ps_complete_this_op(walk_state, *op);
		if (ACPI_FAILURE(status2)) {
			return_ACPI_STATUS(status2);
		}

		status = AE_OK;
		break;

	case AE_CTRL_TERMINATE:

		/* Clean up */
		do {
			if (*op) {
				status2 =
				    acpi_ps_complete_this_op(walk_state, *op);
				if (ACPI_FAILURE(status2)) {
					return_ACPI_STATUS(status2);
				}

				acpi_ut_delete_generic_state
				    (acpi_ut_pop_generic_state
				     (&walk_state->control_state));
			}

			acpi_ps_pop_scope(&(walk_state->parser_state), op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);

		} while (*op);

		return_ACPI_STATUS(AE_OK);

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

		do {
			if (*op) {
				/*
				 * These Opcodes need to be removed from the namespace because they
				 * get created even if these opcodes cannot be created due to
				 * errors.
				 */
				if (((*op)->common.aml_opcode == AML_REGION_OP)
				    || ((*op)->common.aml_opcode ==
					AML_DATA_REGION_OP)) {
					acpi_ns_delete_children((*op)->common.
								node);
					acpi_ns_remove_node((*op)->common.node);
					(*op)->common.node = NULL;
					acpi_ps_delete_parse_tree(*op);
				}

				status2 =
				    acpi_ps_complete_this_op(walk_state, *op);
				if (ACPI_FAILURE(status2)) {
					return_ACPI_STATUS(status2);
				}
			}

			acpi_ps_pop_scope(&(walk_state->parser_state), op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);

		} while (*op);

#if 0
		/*
		 * TBD: Cleanup parse ops on error
		 */
		if (*op == NULL) {
			acpi_ps_pop_scope(parser_state, op,
					  &walk_state->arg_types,
					  &walk_state->arg_count);
		}
#endif
		walk_state->prev_op = NULL;
		walk_state->prev_arg_types = walk_state->arg_types;

		if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
			/*
			 * There was something that went wrong while executing code at the
			 * module-level. We need to skip parsing whatever caused the
			 * error and keep going. One runtime error during the table load
			 * should not cause the entire table to not be loaded. This is
			 * because there could be correct AML beyond the parts that caused
			 * the runtime error.
			 */
			ACPI_INFO(("Ignoring error and continuing table load"));
			return_ACPI_STATUS(AE_OK);
		}
		return_ACPI_STATUS(status);
	}

	/* This scope complete? */

	if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
		acpi_ps_pop_scope(&(walk_state->parser_state), op,
				  &walk_state->arg_types,
				  &walk_state->arg_count);
		ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
	} else {
		*op = NULL;
	}

	return_ACPI_STATUS(AE_OK);
}
Пример #17
0
acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
{
    union acpi_parse_object *op;
    acpi_object_type object_type;
    acpi_status status = AE_OK;

    ACPI_FUNCTION_TRACE(ds_load1_end_op);

    op = walk_state->op;
    ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
              walk_state));

    /* We are only interested in opcodes that have an associated name */

    if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
        return_ACPI_STATUS(AE_OK);
    }

    /* Get the object type to determine if we should pop the scope */

    object_type = walk_state->op_info->object_type;

#ifndef ACPI_NO_METHOD_EXECUTION
    if (walk_state->op_info->flags & AML_FIELD) {
        /*
         * If we are executing a method, do not create any namespace objects
         * during the load phase, only during execution.
         */
        if (!walk_state->method_node) {
            if (walk_state->opcode == AML_FIELD_OP ||
                walk_state->opcode == AML_BANK_FIELD_OP ||
                walk_state->opcode == AML_INDEX_FIELD_OP) {
                status =
                    acpi_ds_init_field_objects(op, walk_state);
            }
        }
        return_ACPI_STATUS(status);
    }

    /*
     * If we are executing a method, do not create any namespace objects
     * during the load phase, only during execution.
     */
    if (!walk_state->method_node) {
        if (op->common.aml_opcode == AML_REGION_OP) {
            status =
                acpi_ex_create_region(op->named.data,
                          op->named.length,
                          (acpi_adr_space_type) ((op->
                                      common.
                                      value.
                                      arg)->
                                     common.
                                     value.
                                     integer),
                          walk_state);
            if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
            }
        } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
            status =
                acpi_ex_create_region(op->named.data,
                          op->named.length,
                          REGION_DATA_TABLE,
                          walk_state);
            if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
            }
        }
    }
#endif

    if (op->common.aml_opcode == AML_NAME_OP) {

        /* For Name opcode, get the object type from the argument */

        if (op->common.value.arg) {
            object_type = (acpi_ps_get_opcode_info((op->common.
                                value.arg)->
                                   common.
                                   aml_opcode))->
                object_type;

            /* Set node type if we have a namespace node */

            if (op->common.node) {
                op->common.node->type = (u8) object_type;
            }
        }
    }

    /*
     * If we are executing a method, do not create any namespace objects
     * during the load phase, only during execution.
     */
    if (!walk_state->method_node) {
        if (op->common.aml_opcode == AML_METHOD_OP) {
            /*
             * method_op pkg_length name_string method_flags term_list
             *
             * Note: We must create the method node/object pair as soon as we
             * see the method declaration. This allows later pass1 parsing
             * of invocations of the method (need to know the number of
             * arguments.)
             */
            ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
                      "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
                      walk_state, op, op->named.node));

            if (!acpi_ns_get_attached_object(op->named.node)) {
                walk_state->operands[0] =
                    ACPI_CAST_PTR(void, op->named.node);
                walk_state->num_operands = 1;

                status =
                    acpi_ds_create_operands(walk_state,
                                op->common.value.
                                arg);
                if (ACPI_SUCCESS(status)) {
                    status =
                        acpi_ex_create_method(op->named.
                                  data,
                                  op->named.
                                  length,
                                  walk_state);
                }

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

                if (ACPI_FAILURE(status)) {
                    return_ACPI_STATUS(status);
                }
            }
        }
Пример #18
0
void acpi_db_display_method_info(union acpi_parse_object *start_op)
{
	struct acpi_walk_state *walk_state;
	union acpi_operand_object *obj_desc;
	struct acpi_namespace_node *node;
	union acpi_parse_object *root_op;
	union acpi_parse_object *op;
	const struct acpi_opcode_info *op_info;
	u32 num_ops = 0;
	u32 num_operands = 0;
	u32 num_operators = 0;
	u32 num_remaining_ops = 0;
	u32 num_remaining_operands = 0;
	u32 num_remaining_operators = 0;
	u8 count_remaining = FALSE;

	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
	if (!walk_state) {
		acpi_os_printf("There is no method currently executing\n");
		return;
	}

	obj_desc = walk_state->method_desc;
	node = walk_state->method_node;

	acpi_os_printf("Currently executing control method is [%4.4s]\n",
		       acpi_ut_get_node_name(node));
	acpi_os_printf("%X Arguments, SyncLevel = %X\n",
		       (u32)obj_desc->method.param_count,
		       (u32)obj_desc->method.sync_level);

	root_op = start_op;
	while (root_op->common.parent) {
		root_op = root_op->common.parent;
	}

	op = root_op;

	while (op) {
		if (op == start_op) {
			count_remaining = TRUE;
		}

		num_ops++;
		if (count_remaining) {
			num_remaining_ops++;
		}

		/* Decode the opcode */

		op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
		switch (op_info->class) {
		case AML_CLASS_ARGUMENT:

			if (count_remaining) {
				num_remaining_operands++;
			}

			num_operands++;
			break;

		case AML_CLASS_UNKNOWN:

			/* Bad opcode or ASCII character */

			continue;

		default:

			if (count_remaining) {
				num_remaining_operators++;
			}

			num_operators++;
			break;
		}

		op = acpi_ps_get_depth_next(start_op, op);
	}

	acpi_os_printf
	    ("Method contains:       %X AML Opcodes - %X Operators, %X Operands\n",
	     num_ops, num_operators, num_operands);

	acpi_os_printf
	    ("Remaining to execute:  %X AML Opcodes - %X Operators, %X Operands\n",
	     num_remaining_ops, num_remaining_operators,
	     num_remaining_operands);
}
Пример #19
0
void
acpi_db_display_opcode (
	acpi_walk_state         *walk_state,
	acpi_parse_object       *op)
{
	u8                      *byte_data;
	u32                     byte_count;
	u32                     i;
	const acpi_opcode_info  *op_info = NULL;
	u32                     name;


	if (!op) {
		acpi_os_printf ("<NULL OP PTR>");
	}


	/* op and arguments */

	switch (op->opcode) {

	case AML_BYTE_OP:

		if (acpi_gbl_db_opt_verbose) {
			acpi_os_printf ("(u8) 0x%2.2X", op->value.integer8);
		}

		else {
			acpi_os_printf ("0x%2.2X", op->value.integer8);
		}

		break;


	case AML_WORD_OP:

		if (acpi_gbl_db_opt_verbose) {
			acpi_os_printf ("(u16) 0x%4.4X", op->value.integer16);
		}

		else {
			acpi_os_printf ("0x%4.4X", op->value.integer16);
		}

		break;


	case AML_DWORD_OP:

		if (acpi_gbl_db_opt_verbose) {
			acpi_os_printf ("(u32) 0x%8.8X", op->value.integer32);
		}

		else {
			acpi_os_printf ("0x%8.8X", op->value.integer32);
		}

		break;


	case AML_QWORD_OP:

		if (acpi_gbl_db_opt_verbose) {
			acpi_os_printf ("(u64) 0x%8.8X%8.8X", op->value.integer64.hi,
					 op->value.integer64.lo);
		}

		else {
			acpi_os_printf ("0x%8.8X%8.8X", op->value.integer64.hi,
					 op->value.integer64.lo);
		}

		break;


	case AML_STRING_OP:

		if (op->value.string) {
			acpi_os_printf ("\"%s\"", op->value.string);
		}

		else {
			acpi_os_printf ("<\"NULL STRING PTR\">");
		}

		break;


	case AML_INT_STATICSTRING_OP:

		if (op->value.string) {
			acpi_os_printf ("\"%s\"", op->value.string);
		}

		else {
			acpi_os_printf ("\"<NULL STATIC STRING PTR>\"");
		}

		break;


	case AML_INT_NAMEPATH_OP:

		acpi_db_display_namestring (op->value.name);
		break;


	case AML_INT_NAMEDFIELD_OP:

		acpi_os_printf ("Named_field (Length 0x%8.8X)  ", op->value.integer32);
		break;


	case AML_INT_RESERVEDFIELD_OP:

		acpi_os_printf ("Reserved_field (Length 0x%8.8X) ", op->value.integer32);
		break;


	case AML_INT_ACCESSFIELD_OP:

		acpi_os_printf ("Access_field (Length 0x%8.8X) ", op->value.integer32);
		break;


	case AML_INT_BYTELIST_OP:

		if (acpi_gbl_db_opt_verbose) {
			acpi_os_printf ("Byte_list   (Length 0x%8.8X)  ", op->value.integer32);
		}

		else {
			acpi_os_printf ("0x%2.2X", op->value.integer32);

			byte_count = op->value.integer32;
			byte_data = ((acpi_parse2_object *) op)->data;

			for (i = 0; i < byte_count; i++) {
				acpi_os_printf (", 0x%2.2X", byte_data[i]);
			}
		}

		break;


	default:

		/* Just get the opcode name and print it */

		op_info = acpi_ps_get_opcode_info (op->opcode);
		acpi_os_printf ("%s", op_info->name);


#ifndef PARSER_ONLY
		if ((op->opcode == AML_INT_RETURN_VALUE_OP) &&
			(walk_state->results) &&
			(walk_state->results->results.num_results)) {
			acpi_db_decode_internal_object (walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]);
		}
#endif

		break;
	}

	if (!op_info) {
		/* If there is another element in the list, add a comma */

		if (op->next) {
			acpi_os_printf (",");
		}
	}

	/*
	 * If this is a named opcode, print the associated name value
	 */
	op_info = acpi_ps_get_opcode_info (op->opcode);
	if (op && (op_info->flags & AML_NAMED)) {
		name = acpi_ps_get_name (op);
		acpi_os_printf (" %4.4s", &name);

		if (acpi_gbl_db_opt_verbose) {
			acpi_os_printf (" (Path \\");
			acpi_db_display_path (op);
			acpi_os_printf (")");
		}
	}
}
Пример #20
0
ACPI_STATUS
acpi_aml_resolve_operands (
	u16                     opcode,
	ACPI_OPERAND_OBJECT     **stack_ptr,
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_STATUS             status = AE_OK;
	u8                      object_type;
	ACPI_HANDLE             temp_handle;
	u32                     arg_types;
	ACPI_OPCODE_INFO        *op_info;
	u32                     this_arg_type;
	ACPI_OBJECT_TYPE        type_needed;


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


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


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

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

		/* Extract useful items */

		obj_desc = *stack_ptr;

		/* Decode the descriptor type */

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

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

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

			object_type = obj_desc->common.type;

			/* Check for bad ACPI_OBJECT_TYPE */

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

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

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


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

					break;

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

		else {
			/* Invalid descriptor */

			return (AE_AML_OPERAND_TYPE);
		}


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

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


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

		switch (this_arg_type)
		{

		case ARGI_REFERENCE:   /* Reference */
		case ARGI_TARGETREF:

			/* Need an operand of type INTERNAL_TYPE_REFERENCE */

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

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


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

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

			goto next_operand;
			break;


		case ARGI_ANYTYPE:

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

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


		/*
		 * Resolve this object to a value
		 */

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


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

			/* Need an operand of type ACPI_TYPE_NUMBER */

			type_needed = ACPI_TYPE_NUMBER;
			break;

		case ARGI_BUFFER:

			/* Need an operand of type ACPI_TYPE_BUFFER */

			type_needed = ACPI_TYPE_BUFFER;
			break;

		case ARGI_MUTEX:

			/* Need an operand of type ACPI_TYPE_MUTEX */

			type_needed = ACPI_TYPE_MUTEX;
			break;

		case ARGI_EVENT:

			/* Need an operand of type ACPI_TYPE_EVENT */

			type_needed = ACPI_TYPE_EVENT;
			break;

		case ARGI_REGION:

			/* Need an operand of type ACPI_TYPE_REGION */

			type_needed = ACPI_TYPE_REGION;
			break;

		case ARGI_IF:   /* If */

			/* Need an operand of type INTERNAL_TYPE_IF */

			type_needed = INTERNAL_TYPE_IF;
			break;

		case ARGI_PACKAGE:   /* Package */

			/* Need an operand of type ACPI_TYPE_PACKAGE */

			type_needed = ACPI_TYPE_PACKAGE;
			break;

		case ARGI_ANYTYPE:

			/* Any operand type will do */

			type_needed = ACPI_TYPE_ANY;
			break;


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

		case ARGI_STRING:

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

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


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

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

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

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


		case ARGI_COMPLEXOBJ:

			/* Need a buffer or package */

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


		default:

			/* Unknown type */

			return (AE_BAD_PARAMETER);
		}


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


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

	}   /* while (*Types) */


	return (status);
}
Пример #21
0
acpi_status
acpi_ps_get_next_walk_op (
	struct acpi_walk_state          *walk_state,
	union acpi_parse_object         *op,
	acpi_parse_upwards              ascending_callback)
{
	union acpi_parse_object         *next;
	union acpi_parse_object         *parent;
	union acpi_parse_object         *grand_parent;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE_PTR ("ps_get_next_walk_op", op);


	/* Check for a argument only if we are descending in the tree */

	if (walk_state->next_op_info != ACPI_NEXT_OP_UPWARD) {
		/* Look for an argument or child of the current op */

		next = acpi_ps_get_arg (op, 0);
		if (next) {
			/* Still going downward in tree (Op is not completed yet) */

			walk_state->prev_op     = op;
			walk_state->next_op     = next;
			walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;

			return_ACPI_STATUS (AE_OK);
		}

		/*
		 * No more children, this Op is complete.  Save Next and Parent
		 * in case the Op object gets deleted by the callback routine
		 */
		next    = op->common.next;
		parent  = op->common.parent;

		walk_state->op    = op;
		walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
		walk_state->opcode = op->common.aml_opcode;

		status = ascending_callback (walk_state);

		/*
		 * If we are back to the starting point, the walk is complete.
		 */
		if (op == walk_state->origin) {
			/* Reached the point of origin, the walk is complete */

			walk_state->prev_op     = op;
			walk_state->next_op     = NULL;

			return_ACPI_STATUS (status);
		}

		/*
		 * Check for a sibling to the current op.  A sibling means
		 * we are still going "downward" in the tree.
		 */
		if (next) {
			/* There is a sibling, it will be next */

			walk_state->prev_op     = op;
			walk_state->next_op     = next;
			walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;

			/* Continue downward */

			return_ACPI_STATUS (status);
		}

		/*
		 * Drop into the loop below because we are moving upwards in
		 * the tree
		 */
	}
	else {
		/*
		 * We are resuming a walk, and we were (are) going upward in the tree.
		 * So, we want to drop into the parent loop below.
		 */
		parent = op;
	}

	/*
	 * Look for a sibling of the current Op's parent
	 * Continue moving up the tree until we find a node that has not been
	 * visited, or we get back to where we started.
	 */
	while (parent) {
		/* We are moving up the tree, therefore this parent Op is complete */

		grand_parent = parent->common.parent;
		next        = parent->common.next;

		walk_state->op    = parent;
		walk_state->op_info = acpi_ps_get_opcode_info (parent->common.aml_opcode);
		walk_state->opcode = parent->common.aml_opcode;

		status = ascending_callback (walk_state);

		/*
		 * If we are back to the starting point, the walk is complete.
		 */
		if (parent == walk_state->origin) {
			/* Reached the point of origin, the walk is complete */

			walk_state->prev_op     = parent;
			walk_state->next_op     = NULL;

			return_ACPI_STATUS (status);
		}

		/*
		 * If there is a sibling to this parent (it is not the starting point
		 * Op), then we will visit it.
		 */
		if (next) {
			/* found sibling of parent */

			walk_state->prev_op     = parent;
			walk_state->next_op     = next;
			walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;

			return_ACPI_STATUS (status);
		}

		/* No siblings, no errors, just move up one more level in the tree */

		op                  = parent;
		parent              = grand_parent;
		walk_state->prev_op = op;
	}


	/*
	 * Got all the way to the top of the tree, we must be done!
	 * However, the code should have terminated in the loop above
	 */
	walk_state->next_op     = NULL;

	return_ACPI_STATUS (AE_OK);
}
Пример #22
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;
}
Пример #23
0
acpi_status
acpi_ps_create_op(struct acpi_walk_state *walk_state,
		  u8 *aml_op_start, union acpi_parse_object **new_op)
{
	acpi_status status = AE_OK;
	union acpi_parse_object *op;
	union acpi_parse_object *named_op = NULL;
	union acpi_parse_object *parent_scope;
	u8 argument_count;
	const struct acpi_opcode_info *op_info;

	ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);

	status = acpi_ps_get_aml_opcode(walk_state);
	if (status == AE_CTRL_PARSE_CONTINUE) {
		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
	}
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

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

	walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
	op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start);
	if (!op) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	if (walk_state->op_info->flags & AML_NAMED) {
		status =
		    acpi_ps_build_named_op(walk_state, aml_op_start, op,
					   &named_op);
		acpi_ps_free_op(op);

#ifdef ACPI_ASL_COMPILER
		if (acpi_gbl_disasm_flag
		    && walk_state->opcode == AML_EXTERNAL_OP
		    && status == AE_NOT_FOUND) {
			/*
			 * If parsing of AML_EXTERNAL_OP's name path fails, then skip
			 * past this opcode and keep parsing. This is a much better
			 * alternative than to abort the entire disassembler. At this
			 * point, the parser_state is at the end of the namepath of the
			 * external declaration opcode. Setting walk_state->Aml to
			 * walk_state->parser_state.Aml + 2 moves increments the
			 * walk_state->Aml past the object type and the paramcount of the
			 * external opcode.
			 */
			walk_state->aml = walk_state->parser_state.aml + 2;
			walk_state->parser_state.aml = walk_state->aml;
			return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
		}
#endif
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		*new_op = named_op;
		return_ACPI_STATUS(AE_OK);
	}

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

	if (walk_state->op_info->flags & AML_CREATE) {
		/*
		 * Backup to beginning of create_XXXfield declaration
		 * body_length is unknown until we parse the body
		 */
		op->named.data = aml_op_start;
		op->named.length = 0;
	}

	if (walk_state->opcode == AML_BANK_FIELD_OP) {
		/*
		 * Backup to beginning of bank_field declaration
		 * body_length is unknown until we parse the body
		 */
		op->named.data = aml_op_start;
		op->named.length = 0;
	}

	parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
	acpi_ps_append_arg(parent_scope, op);

	if (parent_scope) {
		op_info =
		    acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
		if (op_info->flags & AML_HAS_TARGET) {
			argument_count =
			    acpi_ps_get_argument_count(op_info->type);
			if (parent_scope->common.arg_list_length >
			    argument_count) {
				op->common.flags |= ACPI_PARSEOP_TARGET;
			}
		}

		/*
		 * Special case for both Increment() and Decrement(), where
		 * the lone argument is both a source and a target.
		 */
		else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
			 || (parent_scope->common.aml_opcode ==
			     AML_DECREMENT_OP)) {
			op->common.flags |= ACPI_PARSEOP_TARGET;
		}
	}

	if (walk_state->descending_callback != NULL) {
		/*
		 * Find the object. This will either insert the object into
		 * the namespace or simply look it up
		 */
		walk_state->op = *new_op = op;

		status = walk_state->descending_callback(walk_state, &op);
		status = acpi_ps_next_parse_state(walk_state, op, status);
		if (status == AE_CTRL_PENDING) {
			status = AE_CTRL_PARSE_PENDING;
		}
	}

	return_ACPI_STATUS(status);
}