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

📄 psparse.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* Create Op structure and append to parent's argument list */			if (walk_state->op_info->flags & AML_NAMED) {				pre_op.value.arg = NULL;				pre_op.opcode = walk_state->opcode;				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME) {					arg = acpi_ps_get_next_arg (parser_state,							 GET_CURRENT_ARG_TYPE (walk_state->arg_types),							 &walk_state->arg_count);					acpi_ps_append_arg (&pre_op, arg);					INCREMENT_ARG_LIST (walk_state->arg_types);				}				/* We know that this arg is a name, move to next arg */				INCREMENT_ARG_LIST (walk_state->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					 */					walk_state->op = NULL;					status = walk_state->descending_callback (walk_state, &op);					/* TBD: check status here? */					if (ACPI_FAILURE (status)) {						ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n",								acpi_format_exception (status)));						goto close_this_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) {					/*					 * 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)					 */					((acpi_parse2_object * ) op)->data    = aml_op_start;					((acpi_parse2_object * ) op)->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) {					return_ACPI_STATUS (AE_NO_MEMORY);				}				if (walk_state->op_info->flags & AML_CREATE) {					/*					 * Backup to beginning of Create_xXXfield declaration					 * Body_length is unknown until we parse the body					 */					((acpi_parse2_object * ) op)->data    = aml_op_start;					((acpi_parse2_object * ) 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					 */					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->aml_offset = walk_state->aml_offset;			if (walk_state->op_info) {				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,					"Op=%p Opcode=%4.4X Aml %p Oft=%5.5X\n",					 op, op->opcode, parser_state->aml, op->aml_offset));			}		}		/* Start Arg_count at zero because we don't know if there are any args yet */		walk_state->arg_count = 0;		if (walk_state->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_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 */				acpi_ps_get_next_namepath (parser_state, op, &walk_state->arg_count, 1);				walk_state->arg_types = 0;				break;			default:				/* Op is not a constant or string, append each argument */				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && !walk_state->arg_count) {					walk_state->aml_offset = parser_state->aml - parser_state->aml_start;					arg = acpi_ps_get_next_arg (parser_state,							 GET_CURRENT_ARG_TYPE (walk_state->arg_types),							 &walk_state->arg_count);					if (arg) {						arg->aml_offset = walk_state->aml_offset;						acpi_ps_append_arg (op, arg);					}					INCREMENT_ARG_LIST (walk_state->arg_types);				}				/* For a method, save the length and address of the body */				if (op->opcode == AML_METHOD_OP) {					/*					 * Skip parsing of control method or opregion body,					 * because we don't have enough info in the first pass					 * to parse them correctly.					 */					((acpi_parse2_object * ) op)->data    = parser_state->aml;					((acpi_parse2_object * ) op)->length  = (u32) (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;					walk_state->arg_count          = 0;				}				break;			}		}		/*		 * Zero Arg_count means that all arguments for this op have been processed		 */		if (!walk_state->arg_count) {			/* completed Op, prepare for next */			walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);			if (walk_state->op_info->flags & AML_NAMED) {				if (acpi_gbl_depth) {					acpi_gbl_depth--;				}				if (op->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.					 */					((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml -							   ((acpi_parse2_object * ) op)->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				 */				((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml -						   ((acpi_parse2_object * ) op)->data);			}			/* This op complete, notify the dispatcher */			if (walk_state->ascending_callback != NULL) {				walk_state->op    = op;				walk_state->opcode = op->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 (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 = walk_state->arg_types;				return_ACPI_STATUS (status);				break;			case AE_CTRL_END:				acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);				walk_state->op    = op;				walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);				walk_state->opcode = op->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);				break;			default:  /* All other non-AE_OK status */				if (op == NULL) {					acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);				}				walk_state->prev_op = op;				walk_state->prev_arg_types = walk_state->arg_types;				/*				 * TEMP:				 */				return_ACPI_STATUS (status);				break;			}			/* 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;			}		}		/* Arg_count is non-zero */		else {			/* complex argument, push Op and prepare for argument */			acpi_ps_push_scope (parser_state, op, walk_state->arg_types, walk_state->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 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->opcode);				walk_state->opcode = op->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 (	acpi_walk_state         *walk_state){	acpi_status             status;	acpi_walk_list          walk_list;	acpi_walk_list          *prev_walk_list = acpi_gbl_current_walk_list;	acpi_walk_state         *previous_walk_state;	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 walk list */	walk_list.walk_state            = NULL;	walk_list.acquired_mutex_list.prev = NULL;	walk_list.acquired_mutex_list.next = NULL;	walk_state->walk_list = &walk_list;	acpi_ds_push_walk_state (walk_state, &walk_list);	/* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter	 */	acpi_gbl_current_walk_list = &walk_list;	/*	 * 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, State=%p\n", 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);		/* 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);		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 (&walk_list);		if (walk_state) {			if (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, previous_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 (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 ((acpi_operand_object *) &walk_list.acquired_mutex_list);	acpi_gbl_current_walk_list = prev_walk_list;	return_ACPI_STATUS (status);}

⌨️ 快捷键说明

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