⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
			}

			if ((op->opcode == AML_CREATE_FIELD_OP) ||
				(op->opcode == AML_BIT_FIELD_OP)    ||
				(op->opcode == AML_BYTE_FIELD_OP)   ||
				(op->opcode == AML_WORD_FIELD_OP)   ||
				(op->opcode == AML_DWORD_FIELD_OP)  ||
				(op->opcode == AML_QWORD_FIELD_OP)) {
				/*
				 * Backup to beginning of Create_xXXfield declaration (1 for
				 * Opcode)
				 *
				 * Body_length is unknown until we parse the body
				 */
				deferred_op = (ACPI_PARSE2_OBJECT *) op;
				deferred_op->length = parser_state->aml - deferred_op->data;
			}

			/* This op complete, notify the dispatcher */

			if (walk_state->ascending_callback != NULL) {
				status = walk_state->ascending_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;
				}
			}


close_this_op:

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

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

			if (acpi_ps_complete_this_op (walk_state, op)) {
				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 = arg_types;
				return (status);
				break;


			case AE_CTRL_END:

				acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);

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

				acpi_ps_complete_this_op (walk_state, op);
				op = NULL;
				status = AE_OK;
				break;


			case AE_CTRL_TERMINATE:

				status = AE_OK;

				/* Clean up */
				do {
					if (op) {
						acpi_ps_complete_this_op (walk_state, op);
					}

					acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
				} while (op);

				return (status);
				break;


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

				if (op == NULL) {
					acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
				}
				walk_state->prev_op = op;
				walk_state->prev_arg_types = arg_types;

				/*
				 * TEMP:
				 */

				return (status);
				break;
			}


			/* This scope complete? */

			if (acpi_ps_has_completed_scope (parser_state)) {
				acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
			}

			else {
				op = NULL;
			}

		}


		/* Arg_count is non-zero */

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

			acpi_ps_push_scope (parser_state, op, arg_types, arg_count);
			op = NULL;
		}

	} /* while Parser_state->Aml */


	/*
	 * Complete the last Op (if not completed), and clear the scope stack.
	 * It is easily possible to end an AML "package" with an unbounded number
	 * of open scopes (such as when several AML blocks are closed with
	 * sequential closing braces).  We want to terminate each one cleanly.
	 */

	do {
		if (op) {
			if (walk_state->ascending_callback != NULL) {
				status = walk_state->ascending_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 (status == AE_CTRL_TERMINATE) {
					status = AE_OK;

					/* Clean up */
					do {
						if (op) {
							acpi_ps_complete_this_op (walk_state, op);
						}

						acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);

					} while (op);

					return (status);
				}

				else if (ACPI_FAILURE (status)) {
					acpi_ps_complete_this_op (walk_state, op);
					return (status);
				}
			}

			acpi_ps_complete_this_op (walk_state, op);
		}

		acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);

	} while (op);

	return (status);
}


/*******************************************************************************
 *
 * FUNCTION:    Acpi_ps_parse_aml
 *
 * PARAMETERS:  Start_scope     - The starting point of the parse.  Becomes the
 *                                root of the parsed op tree.
 *              Aml             - Pointer to the raw AML code to parse
 *              Aml_size        - Length of the AML to parse
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Parse raw AML and return a tree of ops
 *
 ******************************************************************************/

ACPI_STATUS
acpi_ps_parse_aml (
	ACPI_PARSE_OBJECT       *start_scope,
	u8                      *aml,
	u32                     aml_size,
	u32                     parse_flags,
	ACPI_NAMESPACE_NODE     *method_node,
	ACPI_OPERAND_OBJECT     **params,
	ACPI_OPERAND_OBJECT     **caller_return_desc,
	ACPI_PARSE_DOWNWARDS    descending_callback,
	ACPI_PARSE_UPWARDS      ascending_callback)
{
	ACPI_STATUS             status;
	ACPI_PARSE_STATE        *parser_state;
	ACPI_WALK_STATE         *walk_state;
	ACPI_WALK_LIST          walk_list;
	ACPI_NAMESPACE_NODE     *node = NULL;
	ACPI_WALK_LIST          *prev_walk_list = acpi_gbl_current_walk_list;
	ACPI_OPERAND_OBJECT     *return_desc;
	ACPI_OPERAND_OBJECT     *mth_desc = NULL;


	/* Create and initialize a new parser state */

	parser_state = acpi_ps_create_state (aml, aml_size);
	if (!parser_state) {
		return (AE_NO_MEMORY);
	}

	acpi_ps_init_scope (parser_state, start_scope);

	if (method_node) {
		mth_desc = acpi_ns_get_attached_object (method_node);
	}

	/* Create and initialize a new walk list */

	walk_list.walk_state = NULL;
	walk_list.acquired_mutex_list.prev = NULL;
	walk_list.acquired_mutex_list.next = NULL;

	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, parser_state->start_op, mth_desc, &walk_list);
	if (!walk_state) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	walk_state->method_node         = method_node;
	walk_state->parser_state        = parser_state;
	walk_state->parse_flags         = parse_flags;
	walk_state->descending_callback = descending_callback;
	walk_state->ascending_callback  = ascending_callback;

	/* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter
	 */
	acpi_gbl_current_walk_list = &walk_list;


	if (method_node) {
		parser_state->start_node = method_node;
		walk_state->walk_type   = WALK_METHOD;

		/* Push start scope on scope stack and make it current  */

		status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
		if (ACPI_FAILURE (status)) {
			return (status);
		}

		/* Init arguments if this is a control method */
		/* TBD: [Restructure] add walkstate as a param */

		acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
	}

	else {
		/* Setup the current scope */

		node = parser_state->start_op->node;
		parser_state->start_node = node;

		if (node) {
			/* Push start scope on scope stack and make it current  */

			status = acpi_ds_scope_stack_push (node, node->type,
					   walk_state);
			if (ACPI_FAILURE (status)) {
				goto cleanup;
			}

		}
	}


	status = AE_OK;

	/*
	 * Execute the walk loop as long as there is a valid Walk State.  This
	 * handles nested control method invocations without recursion.
	 */

	while (walk_state) {
		if (ACPI_SUCCESS (status)) {
			status = acpi_ps_parse_loop (walk_state);
		}

		if (status == AE_CTRL_TRANSFER) {
			/*
			 * A method call was detected.
			 * Transfer control to the called control method
			 */

			status = acpi_ds_call_control_method (&walk_list, walk_state, NULL);

			/*
			 * If the transfer to the new method method call worked, a new walk
			 * state was created -- get it
			 */

			walk_state = acpi_ds_get_current_walk_state (&walk_list);
			continue;
		}

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

		/* We are done with this walk, move on to the parent if any */


		walk_state = acpi_ds_pop_walk_state (&walk_list);

		/* Extract return value before we delete Walk_state */

		return_desc = walk_state->return_desc;

		/* Reset the current scope to the beginning of scope stack */

		acpi_ds_scope_stack_clear (walk_state);

		/*
		 * If we just returned from the execution of a control method,
		 * there's lots of cleanup to do
		 */

		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
			acpi_ds_terminate_control_method (walk_state);
		}

		 /* Delete this walk state and all linked control states */

		acpi_ps_cleanup_scope (walk_state->parser_state);
		acpi_cm_free (walk_state->parser_state);
		acpi_ds_delete_walk_state (walk_state);

	   /* Check if we have restarted a preempted walk */

		walk_state = acpi_ds_get_current_walk_state (&walk_list);
		if (walk_state &&
			ACPI_SUCCESS (status)) {
			/* There is another walk state, restart it */

			/*
			 * If the method returned value is not used by the parent,
			 * The object is deleted
			 */

			acpi_ds_restart_control_method (walk_state, return_desc);
			walk_state->walk_type |= WALK_METHOD_RESTART;
		}

		/*
		 * Just completed a 1st-level method, save the final internal return
		 * value (if any)
		 */

		else if (caller_return_desc) {
			*caller_return_desc = return_desc; /* NULL if no return value */
		}

		else if (return_desc) {
			/* Caller doesn't want it, must delete it */

			acpi_cm_remove_reference (return_desc);
		}
	}


	/* Normal exit */

	acpi_aml_release_all_mutexes ((ACPI_OPERAND_OBJECT *) &walk_list.acquired_mutex_list);
	acpi_gbl_current_walk_list = prev_walk_list;
	return (status);


cleanup:

	/* Cleanup */

	acpi_ds_delete_walk_state (walk_state);
	acpi_ps_cleanup_scope (parser_state);
	acpi_cm_free (parser_state);

	acpi_aml_release_all_mutexes ((ACPI_OPERAND_OBJECT *)&walk_list.acquired_mutex_list);
	acpi_gbl_current_walk_list = prev_walk_list;

	return (status);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -