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

📄 ammonad.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Module Name: ammonad - ACPI AML (p-code) execution for monadic operators *              $Revision: 88 $ * *****************************************************************************//* *  Copyright (C) 2000 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 "acdispat.h"#include "acinterp.h"#include "amlcode.h"#include "acnamesp.h"#define _COMPONENT          INTERPRETER	 MODULE_NAME         ("ammonad")/******************************************************************************* * * FUNCTION:    Acpi_aml_get_object_reference * * PARAMETERS:  Obj_desc        - Create a reference to this object *              Ret_desc        - Where to store the reference * * RETURN:      Status * * DESCRIPTION: Obtain and return a "reference" to the target object *              Common code for the Ref_of_op and the Cond_ref_of_op. * ******************************************************************************/static ACPI_STATUSacpi_aml_get_object_reference (	ACPI_OPERAND_OBJECT     *obj_desc,	ACPI_OPERAND_OBJECT     **ret_desc,	ACPI_WALK_STATE         *walk_state){	ACPI_STATUS             status = AE_OK;	if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {		if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) {			*ret_desc = NULL;			status = AE_TYPE;			goto cleanup;		}		/*		 * Not a Name -- an indirect name pointer would have		 * been converted to a direct name pointer in Acpi_aml_resolve_operands		 */		switch (obj_desc->reference.op_code)		{		case AML_LOCAL_OP:			*ret_desc = (void *) acpi_ds_method_data_get_nte (MTH_TYPE_LOCAL,					  (obj_desc->reference.offset), walk_state);			break;		case AML_ARG_OP:			*ret_desc = (void *) acpi_ds_method_data_get_nte (MTH_TYPE_ARG,					  (obj_desc->reference.offset), walk_state);			break;		default:			*ret_desc = NULL;			status = AE_AML_INTERNAL;			goto cleanup;		}	}	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {		/* Must be a named object;  Just return the Node */		*ret_desc = obj_desc;	}	else {		*ret_desc = NULL;		status = AE_TYPE;	}cleanup:	return (status);}/******************************************************************************* * * FUNCTION:    Acpi_aml_exec_monadic1 * * PARAMETERS:  Opcode              - The opcode to be executed * * RETURN:      Status * * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on *              object stack * ******************************************************************************/ACPI_STATUSacpi_aml_exec_monadic1 (	u16                     opcode,	ACPI_WALK_STATE         *walk_state){	ACPI_OPERAND_OBJECT     *obj_desc;	ACPI_STATUS             status;	/* Resolve all operands */	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);	/* Get all operands */	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);	if (ACPI_FAILURE (status)) {		goto cleanup;	}	/* Examine the opcode */	switch (opcode)	{	/*  Def_release :=  Release_op  Mutex_object */	case AML_RELEASE_OP:		status = acpi_aml_system_release_mutex (obj_desc);		break;	/*  Def_reset   :=  Reset_op    Acpi_event_object */	case AML_RESET_OP:		status = acpi_aml_system_reset_event (obj_desc);		break;	/*  Def_signal  :=  Signal_op   Acpi_event_object */	case AML_SIGNAL_OP:		status = acpi_aml_system_signal_event (obj_desc);		break;	/*  Def_sleep   :=  Sleep_op    Msec_time   */	case AML_SLEEP_OP:		acpi_aml_system_do_suspend ((u32) obj_desc->number.value);		break;	/*  Def_stall   :=  Stall_op    Usec_time   */	case AML_STALL_OP:		acpi_aml_system_do_stall ((u32) obj_desc->number.value);		break;	/*  Unknown opcode  */	default:		REPORT_ERROR (("Acpi_aml_exec_monadic1: Unknown monadic opcode %X\n",			opcode));		status = AE_AML_BAD_OPCODE;		break;	} /* switch */cleanup:	/* Always delete the operand */	acpi_cm_remove_reference (obj_desc);	return (AE_OK);}/******************************************************************************* * * FUNCTION:    Acpi_aml_exec_monadic2_r * * PARAMETERS:  Opcode              - The opcode to be executed * * RETURN:      Status * * DESCRIPTION: Execute Type 2 monadic operator with numeric operand and *              result operand on operand stack * ******************************************************************************/ACPI_STATUSacpi_aml_exec_monadic2_r (	u16                     opcode,	ACPI_WALK_STATE         *walk_state,	ACPI_OPERAND_OBJECT     **return_desc){	ACPI_OPERAND_OBJECT     *obj_desc;	ACPI_OPERAND_OBJECT     *res_desc;	ACPI_OPERAND_OBJECT     *ret_desc = NULL;	ACPI_OPERAND_OBJECT     *ret_desc2 = NULL;	u32                     res_val;	ACPI_STATUS             status;	u32                     i;	u32                     j;	ACPI_INTEGER            digit;	/* Resolve all operands */	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);	/* Get all operands */	status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);	if (ACPI_FAILURE (status)) {		goto cleanup;	}	/* Create a return object of type NUMBER for most opcodes */	switch (opcode)	{	case AML_BIT_NOT_OP:	case AML_FIND_SET_LEFT_BIT_OP:	case AML_FIND_SET_RIGHT_BIT_OP:	case AML_FROM_BCD_OP:	case AML_TO_BCD_OP:	case AML_COND_REF_OF_OP:		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER);		if (!ret_desc) {			status = AE_NO_MEMORY;			goto cleanup;		}		break;	}	switch (opcode)	{	/*  Def_not :=  Not_op  Operand Result  */	case AML_BIT_NOT_OP:		ret_desc->number.value = ~obj_desc->number.value;		break;	/*  Def_find_set_left_bit := Find_set_left_bit_op Operand Result */	case AML_FIND_SET_LEFT_BIT_OP:		ret_desc->number.value = obj_desc->number.value;		/*		 * Acpi specification describes Integer type as a little		 * endian unsigned value, so this boundry condition is valid.		 */		for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {			ret_desc->number.value >>= 1;		}		ret_desc->number.value = res_val;		break;	/*  Def_find_set_right_bit := Find_set_right_bit_op Operand Result */	case AML_FIND_SET_RIGHT_BIT_OP:		ret_desc->number.value = obj_desc->number.value;		/*		 * Acpi specification describes Integer type as a little		 * endian unsigned value, so this boundry condition is valid.		 */		for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {			ret_desc->number.value <<= 1;		}		/* Since returns must be 1-based, subtract from 33 (65) */		ret_desc->number.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val;		break;	/*  Def_from_bDC := From_bCDOp  BCDValue    Result  */	case AML_FROM_BCD_OP:		/*		 * The 64-bit ACPI integer can hold 16 4-bit BCD integers		 */		ret_desc->number.value = 0;		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {			/* Get one BCD digit */			digit = (ACPI_INTEGER) ((obj_desc->number.value >> (i * 4)) & 0xF);			/* Check the range of the digit */			if (digit > 9) {				status = AE_AML_NUMERIC_OVERFLOW;				goto cleanup;			}			if (digit > 0) {				/* Sum into the result with the appropriate power of 10 */				for (j = 0; j < i; j++) {					digit *= 10;				}				ret_desc->number.value += digit;			}		}		break;	/*  Def_to_bDC  :=  To_bCDOp Operand Result */	case AML_TO_BCD_OP:		if (obj_desc->number.value > ACPI_MAX_BCD_VALUE) {			status = AE_AML_NUMERIC_OVERFLOW;			goto cleanup;		}		ret_desc->number.value = 0;		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {			/* Divide by nth factor of 10 */			digit = obj_desc->number.value;			for (j = 0; j < i; j++) {				digit /= 10;			}			/* Create the BCD digit */			if (digit > 0) {				ret_desc->number.value += (ACPI_MODULO (digit, 10) << (i * 4));			}		}		break;	/*  Def_cond_ref_of     :=  Cond_ref_of_op  Source_object   Result  */	case AML_COND_REF_OF_OP:		/*		 * This op is a little strange because the internal return value is		 * different than the return value stored in the result descriptor		 * (There are really two return values)		 */		if ((ACPI_NAMESPACE_NODE *) obj_desc == acpi_gbl_root_node) {			/*			 * This means that the object does not exist in the namespace,			 * return FALSE			 */			ret_desc->number.value = 0;			/*			 * Must delete the result descriptor since there is no reference			 * being returned			 */			acpi_cm_remove_reference (res_desc);			goto cleanup;		}		/* Get the object reference and store it */		status = acpi_aml_get_object_reference (obj_desc, &ret_desc2, walk_state);		if (ACPI_FAILURE (status)) {			goto cleanup;		}		status = acpi_aml_exec_store (ret_desc2, res_desc, walk_state);		/* The object exists in the namespace, return TRUE */		ret_desc->number.value = ACPI_INTEGER_MAX;		goto cleanup;		break;	case AML_STORE_OP:		/*		 * A store operand is typically a number, string, buffer or lvalue		 * TBD: [Unhandled] What about a store to a package?		 */		/*		 * Do the store, and be careful about deleting the source object,		 * since the object itself may have been stored.		 */		status = acpi_aml_exec_store (obj_desc, res_desc, walk_state);		if (ACPI_FAILURE (status)) {			/* On failure, just delete the Obj_desc */			acpi_cm_remove_reference (obj_desc);		}		else {			/*			 * Normally, we would remove a reference on the Obj_desc parameter;			 * But since it is being used as the internal return object			 * (meaning we would normally increment it), the two cancel out,			 * and we simply don't do anything.			 */			*return_desc = obj_desc;		}		obj_desc = NULL;		return (status);		break;	case AML_DEBUG_OP:		/* Reference, returning an Reference */		return (AE_OK);		break;	/*	 * These are obsolete opcodes	 */	/*  Def_shift_left_bit  :=  Shift_left_bit_op   Source          Bit_num */	/*  Def_shift_right_bit :=  Shift_right_bit_op  Source          Bit_num */	case AML_SHIFT_LEFT_BIT_OP:	case AML_SHIFT_RIGHT_BIT_OP:		status = AE_SUPPORT;		goto cleanup;		break;	default:		REPORT_ERROR (("Acpi_aml_exec_monadic2_r: Unknown monadic opcode %X\n",			opcode));		status = AE_AML_BAD_OPCODE;		goto cleanup;	}	status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);

⌨️ 快捷键说明

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