dsopcode.c

来自「是关于linux2.5.1的完全源码」· C语言 代码 · 共 1,094 行 · 第 1/2 页

C
1,094
字号
/****************************************************************************** * * Module Name: dsopcode - Dispatcher Op Region support and handling of *                         "control" opcodes *              $Revision: 74 $ * *****************************************************************************//* *  Copyright (C) 2000 - 2002, R. Byron Moore * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "acpi.h"#include "acparser.h"#include "amlcode.h"#include "acdispat.h"#include "acinterp.h"#include "acnamesp.h"#include "acevents.h"#include "actables.h"#define _COMPONENT          ACPI_DISPATCHER	 ACPI_MODULE_NAME    ("dsopcode")/***************************************************************************** * * FUNCTION:    Acpi_ds_execute_arguments * * PARAMETERS:  Node                - Parent NS node *              Extra_desc          - Has AML pointer and length * * RETURN:      Status. * * DESCRIPTION: Late execution of region or field arguments * ****************************************************************************/acpi_statusacpi_ds_execute_arguments (	acpi_namespace_node     *node,	acpi_namespace_node     *scope_node,	u32                     aml_length,	u8                      *aml_start){	acpi_status             status;	acpi_parse_object       *op;	acpi_walk_state         *walk_state;	acpi_parse_object       *arg;	ACPI_FUNCTION_TRACE ("Acpi_ds_execute_arguments");	/*	 * Allocate a new parser op to be the root of the parsed tree	 */	op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);	if (!op) {		return_ACPI_STATUS (AE_NO_MEMORY);	}	/* Save the Node for use in Acpi_ps_parse_aml */	op->node = scope_node;	/* Create and initialize a new parser state */	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);	if (!walk_state) {		return_ACPI_STATUS (AE_NO_MEMORY);	}	status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,			  aml_length, NULL, NULL, 1);	if (ACPI_FAILURE (status)) {		acpi_ds_delete_walk_state (walk_state);		return_ACPI_STATUS (status);	}	walk_state->parse_flags = 0;	/* Pass1: Parse the entire declaration */	status = acpi_ps_parse_aml (walk_state);	if (ACPI_FAILURE (status)) {		acpi_ps_delete_parse_tree (op);		return_ACPI_STATUS (status);	}	/* Get and init the Op created above */	arg = op->value.arg;	op->node = node;	arg->node = node;	acpi_ps_delete_parse_tree (op);	/* Evaluate the address and length arguments for the Buffer Field */	op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);	if (!op) {		return_ACPI_STATUS (AE_NO_MEMORY);	}	op->node = scope_node;	/* Create and initialize a new parser state */	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);	if (!walk_state) {		return_ACPI_STATUS (AE_NO_MEMORY);	}	status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,			  aml_length, NULL, NULL, 3);	if (ACPI_FAILURE (status)) {		acpi_ds_delete_walk_state (walk_state);		return_ACPI_STATUS (status);	}	status = acpi_ps_parse_aml (walk_state);	acpi_ps_delete_parse_tree (op);	return_ACPI_STATUS (status);}/***************************************************************************** * * FUNCTION:    Acpi_ds_get_buffer_field_arguments * * PARAMETERS:  Obj_desc        - A valid Buffer_field object * * RETURN:      Status. * * DESCRIPTION: Get Buffer_field Buffer and Index. This implements the late *              evaluation of these field attributes. * ****************************************************************************/acpi_statusacpi_ds_get_buffer_field_arguments (	acpi_operand_object     *obj_desc){	acpi_operand_object     *extra_desc;	acpi_namespace_node     *node;	acpi_status             status;	ACPI_FUNCTION_TRACE_PTR ("Ds_get_buffer_field_arguments", obj_desc);	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {		return_ACPI_STATUS (AE_OK);	}	/* Get the AML pointer (method object) and Buffer_field node */	extra_desc = acpi_ns_get_secondary_object (obj_desc);	node = obj_desc->buffer_field.node;	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (node, " [Field]"));	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] Buffer_field JIT Init\n",		(char *) &node->name));	/* Execute the AML code for the Term_arg arguments */	status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),			 extra_desc->extra.aml_length, extra_desc->extra.aml_start);	return_ACPI_STATUS (status);}/***************************************************************************** * * FUNCTION:    Acpi_ds_get_buffer_arguments * * PARAMETERS:  Obj_desc        - A valid Bufferobject * * RETURN:      Status. * * DESCRIPTION: Get Buffer length and initializer byte list.  This implements *              the late evaluation of these attributes. * ****************************************************************************/acpi_statusacpi_ds_get_buffer_arguments (	acpi_operand_object     *obj_desc){	acpi_namespace_node     *node;	acpi_status             status;	ACPI_FUNCTION_TRACE_PTR ("Ds_get_buffer_arguments", obj_desc);	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {		return_ACPI_STATUS (AE_OK);	}	/* Get the Buffer node */	node = obj_desc->buffer.node;	if (!node) {		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,				"No pointer back to NS node in buffer %p\n", obj_desc));		return_ACPI_STATUS (AE_AML_INTERNAL);	}	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer JIT Init\n"));	/* Execute the AML code for the Term_arg arguments */	status = acpi_ds_execute_arguments (node, node,			 obj_desc->buffer.aml_length, obj_desc->buffer.aml_start);	return_ACPI_STATUS (status);}/***************************************************************************** * * FUNCTION:    Acpi_ds_get_package_arguments * * PARAMETERS:  Obj_desc        - A valid Packageobject * * RETURN:      Status. * * DESCRIPTION: Get Package length and initializer byte list.  This implements *              the late evaluation of these attributes. * ****************************************************************************/acpi_statusacpi_ds_get_package_arguments (	acpi_operand_object     *obj_desc){	acpi_namespace_node     *node;	acpi_status             status;	ACPI_FUNCTION_TRACE_PTR ("Ds_get_package_arguments", obj_desc);	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {		return_ACPI_STATUS (AE_OK);	}	/* Get the Package node */	node = obj_desc->package.node;	if (!node) {		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,				"No pointer back to NS node in package %p\n", obj_desc));		return_ACPI_STATUS (AE_AML_INTERNAL);	}	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package JIT Init\n"));	/* Execute the AML code for the Term_arg arguments */	status = acpi_ds_execute_arguments (node, node,			 obj_desc->package.aml_length, obj_desc->package.aml_start);	return_ACPI_STATUS (status);}/***************************************************************************** * * FUNCTION:    Acpi_ds_get_region_arguments * * PARAMETERS:  Obj_desc        - A valid region object * * RETURN:      Status. * * DESCRIPTION: Get region address and length.  This implements the late *              evaluation of these region attributes. * ****************************************************************************/acpi_statusacpi_ds_get_region_arguments (	acpi_operand_object     *obj_desc){	acpi_namespace_node     *node;	acpi_status             status;	acpi_operand_object     *extra_desc;	ACPI_FUNCTION_TRACE_PTR ("Ds_get_region_arguments", obj_desc);	if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {		return_ACPI_STATUS (AE_OK);	}	extra_desc = acpi_ns_get_secondary_object (obj_desc);	if (!extra_desc) {		return_ACPI_STATUS (AE_NOT_EXIST);	}	/* Get the Region node */	node = obj_desc->region.node;	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (node, " [Operation Region]"));	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] Op_region Init at AML %p\n",		(char *) &node->name, extra_desc->extra.aml_start));	status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),			 extra_desc->extra.aml_length, extra_desc->extra.aml_start);	return_ACPI_STATUS (status);}/***************************************************************************** * * FUNCTION:    Acpi_ds_initialize_region * * PARAMETERS:  Op              - A valid region Op object * * RETURN:      Status * * DESCRIPTION: * ****************************************************************************/acpi_statusacpi_ds_initialize_region (	acpi_handle             obj_handle){	acpi_operand_object     *obj_desc;	acpi_status             status;	obj_desc = acpi_ns_get_attached_object (obj_handle);	/* Namespace is NOT locked */	status = acpi_ev_initialize_region (obj_desc, FALSE);	return (status);}/***************************************************************************** * * FUNCTION:    Acpi_ds_eval_buffer_field_operands * * PARAMETERS:  Op              - A valid Buffer_field Op object * * RETURN:      Status * * DESCRIPTION: Get Buffer_field Buffer and Index *              Called from Acpi_ds_exec_end_op during Buffer_field parse tree walk * ****************************************************************************/acpi_statusacpi_ds_eval_buffer_field_operands (	acpi_walk_state         *walk_state,	acpi_parse_object       *op){	acpi_status             status;	acpi_operand_object     *obj_desc;	acpi_namespace_node     *node;	acpi_parse_object       *next_op;	u32                     offset;	u32                     bit_offset;	u32                     bit_count;	u8                      field_flags;	acpi_operand_object     *res_desc = NULL;	acpi_operand_object     *cnt_desc = NULL;	acpi_operand_object     *off_desc = NULL;	acpi_operand_object     *src_desc = NULL;	ACPI_FUNCTION_TRACE_PTR ("Ds_eval_buffer_field_operands", op);	/*	 * This is where we evaluate the address and length fields of the	 * Create_xxx_field declaration	 */	node =  op->node;	/* Next_op points to the op that holds the Buffer */	next_op = op->value.arg;	/* Evaluate/create the address and length operands */	status = acpi_ds_create_operands (walk_state, next_op);	if (ACPI_FAILURE (status)) {		return_ACPI_STATUS (status);	}	obj_desc = acpi_ns_get_attached_object (node);	if (!obj_desc) {		return_ACPI_STATUS (AE_NOT_EXIST);	}	/* Resolve the operands */	status = acpi_ex_resolve_operands (op->opcode, ACPI_WALK_OPERANDS, walk_state);	ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, acpi_ps_get_opcode_name (op->opcode),			  walk_state->num_operands, "after Acpi_ex_resolve_operands");	if (ACPI_FAILURE (status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",			acpi_ps_get_opcode_name (op->opcode), status));		goto cleanup;	}	/* Get the operands */	if (AML_CREATE_FIELD_OP == op->opcode) {		res_desc = walk_state->operands[3];		cnt_desc = walk_state->operands[2];	}	else {		res_desc = walk_state->operands[2];	}	off_desc = walk_state->operands[1];	src_desc = walk_state->operands[0];	offset  = (u32) off_desc->integer.value;	/*	 * If Res_desc is a Name, it will be a direct name pointer after	 * Acpi_ex_resolve_operands()	 */	if (ACPI_GET_DESCRIPTOR_TYPE (res_desc) != ACPI_DESC_TYPE_NAMED) {		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a NS Node\n",			acpi_ps_get_opcode_name (op->opcode)));		status = AE_AML_OPERAND_TYPE;		goto cleanup;	}	/*	 * Setup the Bit offsets and counts, according to the opcode	 */	switch (op->opcode) {	case AML_CREATE_FIELD_OP:		/* Offset is in bits, count is in bits */		bit_offset  = offset;		bit_count   = (u32) cnt_desc->integer.value;		field_flags = AML_FIELD_ACCESS_BYTE;		break;	case AML_CREATE_BIT_FIELD_OP:		/* Offset is in bits, Field is one bit */		bit_offset  = offset;		bit_count   = 1;		field_flags = AML_FIELD_ACCESS_BYTE;		break;	case AML_CREATE_BYTE_FIELD_OP:		/* Offset is in bytes, field is one byte */		bit_offset  = 8 * offset;		bit_count   = 8;		field_flags = AML_FIELD_ACCESS_BYTE;		break;	case AML_CREATE_WORD_FIELD_OP:		/* Offset is in bytes, field is one word */		bit_offset  = 8 * offset;		bit_count   = 16;		field_flags = AML_FIELD_ACCESS_WORD;		break;	case AML_CREATE_DWORD_FIELD_OP:		/* Offset is in bytes, field is one dword */		bit_offset  = 8 * offset;		bit_count   = 32;		field_flags = AML_FIELD_ACCESS_DWORD;		break;	case AML_CREATE_QWORD_FIELD_OP:		/* Offset is in bytes, field is one qword */		bit_offset  = 8 * offset;		bit_count   = 64;		field_flags = AML_FIELD_ACCESS_QWORD;		break;	default:		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,			"Internal error - unknown field creation opcode %02x\n",			op->opcode));		status = AE_AML_BAD_OPCODE;		goto cleanup;	}	/*	 * Setup field according to the object type	 */	switch (src_desc->common.type) {	/* Source_buff :=  Term_arg=>Buffer */	case ACPI_TYPE_BUFFER:		if ((bit_offset + bit_count) >			(8 * (u32) src_desc->buffer.length)) {			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,				"Field size %d exceeds Buffer size %d (bits)\n",				 bit_offset + bit_count, 8 * (u32) src_desc->buffer.length));			status = AE_AML_BUFFER_LIMIT;			goto cleanup;		}		/*		 * Initialize areas of the field object that are common to all fields		 * For Field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)		 */		status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,				  bit_offset, bit_count);

⌨️ 快捷键说明

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