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

📄 psparse.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
				 * 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--;		/* Close this Op (will result in parse subtree deletion) */		acpi_ps_complete_this_op (walk_state, op);		op = NULL;		if (pre_op) {			acpi_ps_free_op (pre_op);			pre_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);				acpi_ps_complete_this_op (walk_state, op);				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);			}			/* 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);			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,					&walk_state->arg_types, &walk_state->arg_count);			} while (op);			return_ACPI_STATUS (status);		default:  /* All other non-AE_OK status */			do {				if (op) {					acpi_ps_complete_this_op (walk_state, op);				}				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 */	/*	 * 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 = 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,							&walk_state->arg_types, &walk_state->arg_count);					} while (op);					return_ACPI_STATUS (status);				}				else if (ACPI_FAILURE (status)) {					acpi_ps_complete_this_op (walk_state, op);					return_ACPI_STATUS (status);				}			}			acpi_ps_complete_this_op (walk_state, op);		}		acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,			&walk_state->arg_count);	} while (op);	return_ACPI_STATUS (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_statusacpi_ps_parse_aml (	struct acpi_walk_state          *walk_state){	acpi_status                     status;	acpi_status                     terminate_status;	struct acpi_thread_state        *thread;	struct acpi_thread_state        *prev_walk_list = acpi_gbl_current_walk_list;	struct acpi_walk_state          *previous_walk_state;	ACPI_FUNCTION_TRACE ("ps_parse_aml");	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with walk_state=%p Aml=%p size=%X\n",		walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size));	/* Create and initialize a new thread state */	thread = acpi_ut_create_thread_state ();	if (!thread) {		return_ACPI_STATUS (AE_NO_MEMORY);	}	walk_state->thread = thread;	acpi_ds_push_walk_state (walk_state, thread);	/*	 * This global allows the AML debugger to get a handle to the currently	 * executing control method.	 */	acpi_gbl_current_walk_list = thread;	/*	 * Execute the walk loop as long as there is a valid Walk State.  This	 * handles nested control method invocations without recursion.	 */	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", walk_state));	status = AE_OK;	while (walk_state) {		if (ACPI_SUCCESS (status)) {			/*			 * The parse_loop executes AML until the method terminates			 * or calls another method.			 */			status = acpi_ps_parse_loop (walk_state);		}		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,			"Completed one call to walk loop, %s State=%p\n",			acpi_format_exception (status), 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 (thread, 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 (thread);			continue;		}		else if (status == AE_CTRL_TERMINATE) {			status = AE_OK;		}		else if ((status != AE_OK) && (walk_state->method_desc)) {			ACPI_REPORT_METHOD_ERROR ("Method execution failed",				walk_state->method_node, NULL, status);			/* Check for possible multi-thread reentrancy problem */			if ((status == AE_ALREADY_EXISTS) &&				(!walk_state->method_desc->method.semaphore)) {				/*				 * This method is marked not_serialized, but it tried to create a named				 * object, causing the second thread entrance to fail.  We will workaround				 * this by marking the method permanently as Serialized.				 */				walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED;				walk_state->method_desc->method.concurrency = 1;			}		}		if (walk_state->method_desc) {			/* Decrement the thread count on the method parse tree */			if (walk_state->method_desc->method.thread_count) {				walk_state->method_desc->method.thread_count--;			}		}		/* We are done with this walk, move on to the parent if any */		walk_state = acpi_ds_pop_walk_state (thread);		/* 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) {			terminate_status = acpi_ds_terminate_control_method (walk_state);			if (ACPI_FAILURE (terminate_status)) {				ACPI_REPORT_ERROR ((					"Could not terminate control method properly\n"));				/* Ignore error and continue */			}		}		/* Delete this walk state and all linked control states */		acpi_ps_cleanup_scope (&walk_state->parser_state);		previous_walk_state = walk_state;		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, State=%p\n",			walk_state->return_desc, walk_state));		/* Check if we have restarted a preempted walk */		walk_state = acpi_ds_get_current_walk_state (thread);		if (walk_state) {			if (ACPI_SUCCESS (status)) {				/*				 * There is another walk state, restart it.				 * If the method return value is not used by the parent,				 * The object is deleted				 */				status = acpi_ds_restart_control_method (walk_state,						 previous_walk_state->return_desc);				if (ACPI_SUCCESS (status)) {					walk_state->walk_type |= ACPI_WALK_METHOD_RESTART;				}			}			else {				/* On error, delete any return object */				acpi_ut_remove_reference (previous_walk_state->return_desc);			}		}		/*		 * Just completed a 1st-level method, save the final internal return		 * value (if any)		 */		else if (previous_walk_state->caller_return_desc) {			*(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc; /* NULL if no return value */		}		else if (previous_walk_state->return_desc) {			/* Caller doesn't want it, must delete it */			acpi_ut_remove_reference (previous_walk_state->return_desc);		}		acpi_ds_delete_walk_state (previous_walk_state);	}	/* Normal exit */	acpi_ex_release_all_mutexes (thread);	acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread));	acpi_gbl_current_walk_list = prev_walk_list;	return_ACPI_STATUS (status);}

⌨️ 快捷键说明

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