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

📄 psparse.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines * *****************************************************************************//* * Copyright (C) 2000 - 2005, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions, and the following disclaimer, *    without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer *    substantially similar to the "NO WARRANTY" disclaimer below *    ("Disclaimer") and any redistribution must be conditioned upon *    including a substantially similar Disclaimer requirement for further *    binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names *    of any contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. *//* * Parse the AML and build an operation tree as most interpreters, * like Perl, do.  Parsing is done by hand rather than with a YACC * generated parser to tightly constrain stack and dynamic memory * usage.  At the same time, parsing is kept flexible and the code * fairly compact by parsing based on a list of AML opcode * templates in aml_op_info[] */#include <acpi/acpi.h>#include <acpi/acparser.h>#include <acpi/acdispat.h>#include <acpi/amlcode.h>#include <acpi/acnamesp.h>#include <acpi/acinterp.h>#define _COMPONENT          ACPI_PARSERACPI_MODULE_NAME("psparse")/******************************************************************************* * * FUNCTION:    acpi_ps_get_opcode_size * * PARAMETERS:  Opcode          - An AML opcode * * RETURN:      Size of the opcode, in bytes (1 or 2) * * DESCRIPTION: Get the size of the current opcode. * ******************************************************************************/u32 acpi_ps_get_opcode_size(u32 opcode){	/* Extended (2-byte) opcode if > 255 */	if (opcode > 0x00FF) {		return (2);	}	/* Otherwise, just a single byte opcode */	return (1);}/******************************************************************************* * * FUNCTION:    acpi_ps_peek_opcode * * PARAMETERS:  parser_state        - A parser state object * * RETURN:      Next AML opcode * * DESCRIPTION: Get next AML opcode (without incrementing AML pointer) * ******************************************************************************/u16 acpi_ps_peek_opcode(struct acpi_parse_state * parser_state){	u8 *aml;	u16 opcode;	aml = parser_state->aml;	opcode = (u16) ACPI_GET8(aml);	if (opcode == AML_EXTENDED_OP_PREFIX) {		/* Extended opcode, get the second opcode byte */		aml++;		opcode = (u16) ((opcode << 8) | ACPI_GET8(aml));	}	return (opcode);}/******************************************************************************* * * FUNCTION:    acpi_ps_complete_this_op * * PARAMETERS:  walk_state      - Current State *              Op              - Op to complete * * RETURN:      Status * * DESCRIPTION: Perform any cleanup at the completion of an Op. * ******************************************************************************/acpi_statusacpi_ps_complete_this_op(struct acpi_walk_state * walk_state,			 union acpi_parse_object * op){	union acpi_parse_object *prev;	union acpi_parse_object *next;	const struct acpi_opcode_info *parent_info;	union acpi_parse_object *replacement_op = NULL;	ACPI_FUNCTION_TRACE_PTR("ps_complete_this_op", op);	/* Check for null Op, can happen if AML code is corrupt */	if (!op) {		return_ACPI_STATUS(AE_OK);	/* OK for now */	}	/* Delete this op and the subtree below it if asked to */	if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) !=	     ACPI_PARSE_DELETE_TREE)	    || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {		return_ACPI_STATUS(AE_OK);	}	/* Make sure that we only delete this subtree */	if (op->common.parent) {		prev = op->common.parent->common.value.arg;		if (!prev) {			/* Nothing more to do */			goto cleanup;		}		/*		 * Check if we need to replace the operator and its subtree		 * with a return value op (placeholder op)		 */		parent_info =		    acpi_ps_get_opcode_info(op->common.parent->common.					    aml_opcode);		switch (parent_info->class) {		case AML_CLASS_CONTROL:			break;		case AML_CLASS_CREATE:			/*			 * These opcodes contain term_arg operands. The current			 * op must be replaced by a placeholder return op			 */			replacement_op =			    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);			if (!replacement_op) {				goto allocate_error;			}			break;		case AML_CLASS_NAMED_OBJECT:			/*			 * These opcodes contain term_arg operands. The current			 * op must be replaced by a placeholder return op			 */			if ((op->common.parent->common.aml_opcode ==			     AML_REGION_OP)			    || (op->common.parent->common.aml_opcode ==				AML_DATA_REGION_OP)			    || (op->common.parent->common.aml_opcode ==				AML_BUFFER_OP)			    || (op->common.parent->common.aml_opcode ==				AML_PACKAGE_OP)			    || (op->common.parent->common.aml_opcode ==				AML_VAR_PACKAGE_OP)) {				replacement_op =				    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);				if (!replacement_op) {					goto allocate_error;				}			} else			    if ((op->common.parent->common.aml_opcode ==				 AML_NAME_OP)				&& (walk_state->pass_number <=				    ACPI_IMODE_LOAD_PASS2)) {				if ((op->common.aml_opcode == AML_BUFFER_OP)				    || (op->common.aml_opcode == AML_PACKAGE_OP)				    || (op->common.aml_opcode ==					AML_VAR_PACKAGE_OP)) {					replacement_op =					    acpi_ps_alloc_op(op->common.							     aml_opcode);					if (!replacement_op) {						goto allocate_error;					}					replacement_op->named.data =					    op->named.data;					replacement_op->named.length =					    op->named.length;				}			}			break;		default:			replacement_op =			    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);			if (!replacement_op) {				goto allocate_error;			}		}		/* We must unlink this op from the parent tree */		if (prev == op) {			/* This op is the first in the list */			if (replacement_op) {				replacement_op->common.parent =				    op->common.parent;				replacement_op->common.value.arg = NULL;				replacement_op->common.node = op->common.node;				op->common.parent->common.value.arg =				    replacement_op;				replacement_op->common.next = op->common.next;			} else {				op->common.parent->common.value.arg =				    op->common.next;			}		}		/* Search the parent list */		else			while (prev) {				/* Traverse all siblings in the parent's argument list */				next = prev->common.next;				if (next == op) {					if (replacement_op) {						replacement_op->common.parent =						    op->common.parent;						replacement_op->common.value.						    arg = NULL;						replacement_op->common.node =						    op->common.node;						prev->common.next =						    replacement_op;						replacement_op->common.next =						    op->common.next;						next = NULL;					} else {						prev->common.next =						    op->common.next;						next = NULL;					}				}				prev = next;			}	}      cleanup:	/* Now we can actually delete the subtree rooted at Op */	acpi_ps_delete_parse_tree(op);	return_ACPI_STATUS(AE_OK);      allocate_error:	/* Always delete the subtree, even on error */	acpi_ps_delete_parse_tree(op);	return_ACPI_STATUS(AE_NO_MEMORY);}/******************************************************************************* * * FUNCTION:    acpi_ps_next_parse_state * * PARAMETERS:  walk_state          - Current state *              Op                  - Current parse op *              callback_status     - Status from previous operation * * RETURN:      Status * * DESCRIPTION: Update the parser state based upon the return exception from *              the parser callback. * ******************************************************************************/

⌨️ 快捷键说明

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