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

📄 psparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
		parser_state->aml = walk_state->aml_last_while;
		break;


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


	case AE_CTRL_FALSE:

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

		parser_state->aml = parser_state->scope->parse_scope.pkg_end;

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

		walk_state->control_state->common.value = FALSE;
		status = AE_CTRL_END;
		break;


	case AE_CTRL_TRANSFER:

		/*
		 * A method call (invocation) -- transfer control
		 */
		status = AE_CTRL_TRANSFER;
		walk_state->prev_op = op;
		walk_state->method_call_op = op;
		walk_state->method_call_node = (op->value.arg)->node;

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

		walk_state->return_used = acpi_ds_is_result_used (op, walk_state);
		break;


	default:
		status = callback_status;
		if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
			status = AE_OK;
		}
		break;
	}


	return (status);
}


/*******************************************************************************
 *
 * FUNCTION:    Acpi_ps_parse_loop
 *
 * PARAMETERS:  Parser_state        - Current parser state object
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
 *              a tree of ops.
 *
 ******************************************************************************/

ACPI_STATUS
acpi_ps_parse_loop (
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_STATUS             status = AE_OK;
	ACPI_PARSE_OBJECT       *op = NULL;     /* current op */
	ACPI_OPCODE_INFO        *op_info;
	ACPI_PARSE_OBJECT       *arg = NULL;
	ACPI_PARSE2_OBJECT      *deferred_op;
	u32                     arg_count;      /* push for fixed or var args */
	u32                     arg_types = 0;
	ACPI_PTRDIFF            aml_offset;
	u16                     opcode;
	ACPI_PARSE_OBJECT       pre_op;
	ACPI_PARSE_STATE        *parser_state;
	u8                      *aml_op_start;


	parser_state = walk_state->parser_state;

#ifndef PARSER_ONLY
	if (walk_state->walk_type & 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->opcode == AML_IF_OP) ||
				(parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) &&
				(walk_state->control_state) &&
				(walk_state->control_state->common.state ==
					CONTROL_PREDICATE_EXECUTING)) {

				/*
				 * A predicate was just completed, get the value of the
				 * predicate and branch based on that value
				 */

				status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE);
				if (ACPI_FAILURE (status) &&
					((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
					return (status);
				}

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

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

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

			op = walk_state->prev_op;
			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)) {
		if (!op) {
			/* Get the next opcode from the AML stream */

			aml_op_start = parser_state->aml;
			aml_offset = parser_state->aml - parser_state->aml_start;
			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
			 */

			op_info = acpi_ps_get_opcode_info (opcode);
			switch (ACPI_GET_OP_TYPE (op_info)) {
			case ACPI_OP_TYPE_OPCODE:

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

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

			case ACPI_OP_TYPE_ASCII:
			case ACPI_OP_TYPE_PREFIX:
				/*
				 * Starts with a valid prefix or ASCII char, this is a name
				 * string.  Convert the bare name string to a namepath.
				 */

				opcode = AML_NAMEPATH_OP;
				arg_types = ARGP_NAMESTRING;
				break;

			case ACPI_OP_TYPE_UNKNOWN:

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

				/* Assume one-byte bad opcode */

				parser_state->aml++;
				continue;
			}


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

			if (acpi_ps_is_named_op (opcode)) {
				pre_op.value.arg = NULL;
				pre_op.opcode = opcode;

				while (GET_CURRENT_ARG_TYPE (arg_types) != ARGP_NAME) {
					arg = acpi_ps_get_next_arg (parser_state,
							 GET_CURRENT_ARG_TYPE (arg_types),
							 &arg_count);
					acpi_ps_append_arg (&pre_op, arg);
					INCREMENT_ARG_LIST (arg_types);
				}


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

				INCREMENT_ARG_LIST (arg_types);

				if (walk_state->descending_callback != NULL) {
					/*
					 * Find the object.  This will either insert the object into
					 * the namespace or simply look it up
					 */
					status = walk_state->descending_callback (opcode, NULL, walk_state, &op);
					if (op == NULL) {
						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.value.arg);
				acpi_gbl_depth++;


				if (op->opcode == AML_REGION_OP) {
					deferred_op = acpi_ps_to_extended_op (op);
					if (deferred_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)
						 */

						deferred_op->data   = aml_op_start;
						deferred_op->length = 0;
					}
				}
			}


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

				op = acpi_ps_alloc_op (opcode);
				if (!op) {
					return (AE_NO_MEMORY);
				}


				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)) {
					/*
					 * Backup to beginning of Create_xXXfield declaration
					 * Body_length is unknown until we parse the body
					 */
					deferred_op = (ACPI_PARSE2_OBJECT *) op;

					deferred_op->data   = aml_op_start;
					deferred_op->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
					 */
					status = walk_state->descending_callback (opcode, op, 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->aml_offset = aml_offset;

		}


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

		arg_count = 0;


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

			switch (op->opcode) {
			case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
			case AML_WORD_OP:       /* AML_WORDDATA_ARG */
			case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
			case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */

				/* fill in constant or string argument directly */

				acpi_ps_get_next_simple_arg (parser_state,
						 GET_CURRENT_ARG_TYPE (arg_types), op);
				break;

			case AML_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */

				acpi_ps_get_next_namepath (parser_state, op, &arg_count, 1);
				arg_types = 0;
				break;


			default:

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

				while (GET_CURRENT_ARG_TYPE (arg_types) && !arg_count) {
					aml_offset = parser_state->aml - parser_state->aml_start;
					arg = acpi_ps_get_next_arg (parser_state,
							 GET_CURRENT_ARG_TYPE (arg_types),
							 &arg_count);
					if (arg) {
						arg->aml_offset = aml_offset;
						acpi_ps_append_arg (op, arg);
					}

					INCREMENT_ARG_LIST (arg_types);
				}


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

				if (op->opcode == AML_METHOD_OP) {
					deferred_op = acpi_ps_to_extended_op (op);
					if (deferred_op) {
						/*
						 * Skip parsing of control method or opregion body,
						 * because we don't have enough info in the first pass
						 * to parse them correctly.
						 */

						deferred_op->data   = parser_state->aml;
						deferred_op->length = parser_state->pkg_end -
								  parser_state->aml;

						/*
						 * Skip body of method.  For Op_regions, we must continue
						 * parsing because the opregion is not a standalone
						 * package (We don't know where the end is).
						 */
						parser_state->aml   = parser_state->pkg_end;
						arg_count           = 0;
					}
				}

				break;
			}
		}


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

			if (acpi_ps_is_named_op (op->opcode)) {
				if (acpi_gbl_depth) {
					acpi_gbl_depth--;
				}

				if (op->opcode == AML_REGION_OP) {
					deferred_op = acpi_ps_to_extended_op (op);
					if (deferred_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.
						 */

						deferred_op->length = parser_state->aml -
								 deferred_op->data;
					}
				}

⌨️ 快捷键说明

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