Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit defba1d8 authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

[ACPI] ACPICA 20051216



Implemented optional support to allow unresolved names
within ASL Package objects. A null object is inserted in
the package when a named reference cannot be located in
the current namespace. Enabled via the interpreter slack
flag which Linux has enabled by default (acpi=strict
to disable slack).  This should eliminate AE_NOT_FOUND
exceptions seen on machines that contain such code.

Implemented an optimization to the initialization
sequence that can improve boot time. During ACPI device
initialization, the _STA method is now run if and only
if the _INI method exists. The _STA method is used to
determine if the device is present; An _INI can only be
run if _STA returns present, but it is a waste of time to
run the _STA method if the _INI does not exist. (Prototype
and assistance from Dong Wei)

Implemented use of the C99 uintptr_t for the pointer
casting macros if it is available in the current
compiler. Otherwise, the default (void *) cast is used
as before.

Fixed some possible memory leaks found within the
execution path of the Break, Continue, If, and CreateField
operators. (Valery Podrezov)

Fixed a problem introduced in the 20051202 release where
an exception is generated during method execution if a
control method attempts to declare another method.

Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent cb654695
Loading
Loading
Loading
Loading
+62 −3
Original line number Diff line number Diff line
@@ -47,10 +47,68 @@
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
#include <acpi/acdisasm.h>

#define _COMPONENT          ACPI_DISPATCHER
ACPI_MODULE_NAME("dsmethod")

/*******************************************************************************
 *
 * FUNCTION:    acpi_ds_method_error
 *
 * PARAMETERS:  Status          - Execution status
 *              walk_state      - Current state
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Called on method error. Invoke the global exception handler if
 *              present, dump the method data if the disassembler is configured
 *
 *              Note: Allows the exception handler to change the status code
 *
 ******************************************************************************/
acpi_status
acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
{
	ACPI_FUNCTION_ENTRY();

	/* Ignore AE_OK and control exception codes */

	if (ACPI_SUCCESS(status) || (status & AE_CODE_CONTROL)) {
		return (status);
	}

	/* Invoke the global exception handler */

	if (acpi_gbl_exception_handler) {
		/* Exit the interpreter, allow handler to execute methods */

		acpi_ex_exit_interpreter();

		/*
		 * Handler can map the exception code to anything it wants, including
		 * AE_OK, in which case the executing method will not be aborted.
		 */
		status = acpi_gbl_exception_handler(status,
						    walk_state->method_node ?
						    walk_state->method_node->
						    name.integer : 0,
						    walk_state->opcode,
						    walk_state->aml_offset,
						    NULL);
		(void)acpi_ex_enter_interpreter();
	}
#ifdef ACPI_DISASSEMBLER
	if (ACPI_FAILURE(status)) {
		/* Display method locals/args if disassembler is present */

		acpi_dm_dump_method_info(status, walk_state, walk_state->op);
	}
#endif

	return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ds_begin_method_execution
@@ -66,6 +124,7 @@ ACPI_MODULE_NAME("dsmethod")
 *              for clearance to execute.
 *
 ******************************************************************************/

acpi_status
acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node,
			       union acpi_operand_object * obj_desc,
+53 −28
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
#define _COMPONENT          ACPI_DISPATCHER
ACPI_MODULE_NAME("dsobject")

/* Local prototypes */
static acpi_status
acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
			      union acpi_parse_object *op,
@@ -85,7 +86,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
	*obj_desc_ptr = NULL;
	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
		/*
		 * This is an named object reference.  If this name was
		 * This is a 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
		 */
@@ -96,18 +97,48 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
						ACPI_IMODE_EXECUTE,
						ACPI_NS_SEARCH_PARENT |
						ACPI_NS_DONT_OPEN_SCOPE, NULL,
						(struct acpi_namespace_node **)
						&(op->common.node));

						ACPI_CAST_INDIRECT_PTR(struct
								       acpi_namespace_node,
								       &(op->
									 common.
									 node)));
			if (ACPI_FAILURE(status)) {
				ACPI_REPORT_NSERROR(op->common.value.string,
						    status);
				/* Check if we are resolving a named reference within a package */

				if ((status == AE_NOT_FOUND)
				    && (acpi_gbl_enable_interpreter_slack)
				    &&
				    ((op->common.parent->common.aml_opcode ==
				      AML_PACKAGE_OP)
				     || (op->common.parent->common.aml_opcode ==
					 AML_VAR_PACKAGE_OP))) {
					/*
					 * We didn't find the target and we are populating elements
					 * of a package - ignore if slack enabled. Some ASL code
					 * contains dangling invalid references in packages and
					 * expects that no exception will be issued. Leave the
					 * element as a null element. It cannot be used, but it
					 * can be overwritten by subsequent ASL code - this is
					 * typically the case.
					 */
					ACPI_DEBUG_PRINT((ACPI_DB_INFO,
							  "Ignoring unresolved reference in package [%4.4s]\n",
							  walk_state->
							  scope_info->scope.
							  node->name.ascii));

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

				return_ACPI_STATUS(status);
			}
		}
	}

	/* Create and init the internal ACPI object */
	/* Create and init a new internal ACPI object */

	obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info
						   (op->common.aml_opcode))->
@@ -157,13 +188,13 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,

	ACPI_FUNCTION_TRACE("ds_build_internal_buffer_obj");

	obj_desc = *obj_desc_ptr;
	if (obj_desc) {
	/*
		 * We are evaluating a Named buffer object "Name (xxxx, Buffer)".
		 * The buffer object already exists (from the NS node)
	 * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
	 * The buffer object already exists (from the NS node), otherwise it must
	 * be created.
	 */
	} else {
	obj_desc = *obj_desc_ptr;
	if (!obj_desc) {
		/* Create a new buffer object */

		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
@@ -259,7 +290,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
	union acpi_operand_object *obj_desc = NULL;
	u32 package_list_length;
	acpi_status status = AE_OK;
	u32 i;
	acpi_native_uint i;

	ACPI_FUNCTION_TRACE("ds_build_internal_package_obj");

@@ -271,13 +302,12 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
		parent = parent->common.parent;
	}

	obj_desc = *obj_desc_ptr;
	if (obj_desc) {
	/*
		 * We are evaluating a Named package object "Name (xxxx, Package)".
		 * Get the existing package object from the NS node
	 * If we are evaluating a Named package object "Name (xxxx, Package)",
	 * the package object already exists, otherwise it must be created.
	 */
	} else {
	obj_desc = *obj_desc_ptr;
	if (!obj_desc) {
		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
		*obj_desc_ptr = obj_desc;
		if (!obj_desc) {
@@ -291,11 +321,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,

	/* Count the number of items in the package list */

	package_list_length = 0;
	arg = op->common.value.arg;
	arg = arg->common.next;
	while (arg) {
		package_list_length++;
	for (package_list_length = 0; arg; package_list_length++) {
		arg = arg->common.next;
	}

@@ -322,12 +350,11 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
	}

	/*
	 * Now init the elements of the package
	 * Initialize all elements of the package
	 */
	i = 0;
	arg = op->common.value.arg;
	arg = arg->common.next;
	while (arg) {
	for (i = 0; arg; i++) {
		if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
			/* Object (package or buffer) is already built */

@@ -340,8 +367,6 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
							       package.
							       elements[i]);
		}

		i++;
		arg = arg->common.next;
	}

+8 −25
Original line number Diff line number Diff line
@@ -314,12 +314,13 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,

	case AML_CLASS_EXECUTE:
	case AML_CLASS_CREATE:

		/*
		 * Most operators with arguments.
		 * Start a new result/operand state
		 */
		if (walk_state->opcode != AML_CREATE_FIELD_OP) {
			status = acpi_ds_result_stack_push(walk_state);
		}
		break;

	default:
@@ -723,20 +724,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)

      cleanup:

	/* Invoke exception handler on error */

	if (ACPI_FAILURE(status) &&
	    acpi_gbl_exception_handler && !(status & AE_CODE_CONTROL)) {
		acpi_ex_exit_interpreter();
		status = acpi_gbl_exception_handler(status,
						    walk_state->method_node->
						    name.integer,
						    walk_state->opcode,
						    walk_state->aml_offset,
						    NULL);
		(void)acpi_ex_enter_interpreter();
	}

	if (walk_state->result_obj) {
		/* Break to debugger to display result */

@@ -758,18 +745,14 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
	}
#endif

	/* Always clear the object stack */

	walk_state->num_operands = 0;

#ifdef ACPI_DISASSEMBLER

	/* On error, display method locals/args */
	/* Invoke exception handler on error */

	if (ACPI_FAILURE(status)) {
		acpi_dm_dump_method_info(status, walk_state, op);
		status = acpi_ds_method_error(status, walk_state);
	}
#endif

	/* Always clear the object stack */

	walk_state->num_operands = 0;
	return_ACPI_STATUS(status);
}
+80 −30
Original line number Diff line number Diff line
@@ -428,6 +428,11 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
		}
	}

	/*
	 * 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
@@ -442,15 +447,20 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
					  walk_state, op, op->named.node));

			if (!acpi_ns_get_attached_object(op->named.node)) {
			walk_state->operands[0] = (void *)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);
							    op->common.value.
							    arg);
				if (ACPI_SUCCESS(status)) {
				status = acpi_ex_create_method(op->named.data,
							       op->named.length,
					status =
					    acpi_ex_create_method(op->named.
								  data,
								  op->named.
								  length,
								  walk_state);
				}
				walk_state->operands[0] = NULL;
@@ -461,10 +471,11 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
				}
			}
		}
	}

	/* Pop the scope stack */
	/* Pop the scope stack (only if loading a table) */

	if (acpi_ns_opens_scope(object_type)) {
	if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) {
		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
				  "(%s): Popping scope for Op %p\n",
				  acpi_ut_get_type_name(object_type), op));
@@ -1015,11 +1026,50 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)

			status = acpi_ds_create_node(walk_state, node, op);
			break;

		case 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 named_obj=%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);
				}
			}
			break;

#endif				/* ACPI_NO_METHOD_EXECUTION */

		default:
			/* All NAMED_COMPLEX opcodes must be handled above */
			/* Note: Method objects were already created in Pass 1 */
			break;
		}
		break;
+2 −2
Original line number Diff line number Diff line
@@ -223,8 +223,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
			goto cleanup;
		}

		if (length > 0) {
			/* Copy the portion requested */
		if (buffer) {
			/* We have a buffer, copy the portion requested */

			ACPI_MEMCPY(buffer, operand[0]->string.pointer + index,
				    length);
Loading