brintos

brintos / linux-shallow public Read only

0
0
Text · 16.2 KiB · 3a437e6 Raw
676 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: exresop - AML Interpreter operand/object resolution5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "amlcode.h"13#include "acparser.h"14#include "acinterp.h"15#include "acnamesp.h"16 17#define _COMPONENT          ACPI_EXECUTER18ACPI_MODULE_NAME("exresop")19 20/* Local prototypes */21static acpi_status22acpi_ex_check_object_type(acpi_object_type type_needed,23			  acpi_object_type this_type, void *object);24 25/*******************************************************************************26 *27 * FUNCTION:    acpi_ex_check_object_type28 *29 * PARAMETERS:  type_needed         Object type needed30 *              this_type           Actual object type31 *              Object              Object pointer32 *33 * RETURN:      Status34 *35 * DESCRIPTION: Check required type against actual type36 *37 ******************************************************************************/38 39static acpi_status40acpi_ex_check_object_type(acpi_object_type type_needed,41			  acpi_object_type this_type, void *object)42{43	ACPI_FUNCTION_ENTRY();44 45	if (type_needed == ACPI_TYPE_ANY) {46 47		/* All types OK, so we don't perform any typechecks */48 49		return (AE_OK);50	}51 52	if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {53		/*54		 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference55		 * objects and thus allow them to be targets. (As per the ACPI56		 * specification, a store to a constant is a noop.)57		 */58		if ((this_type == ACPI_TYPE_INTEGER) &&59		    (((union acpi_operand_object *)object)->common.flags &60		     AOPOBJ_AML_CONSTANT)) {61			return (AE_OK);62		}63	}64 65	if (type_needed != this_type) {66		ACPI_ERROR((AE_INFO,67			    "Needed type [%s], found [%s] %p",68			    acpi_ut_get_type_name(type_needed),69			    acpi_ut_get_type_name(this_type), object));70 71		return (AE_AML_OPERAND_TYPE);72	}73 74	return (AE_OK);75}76 77/*******************************************************************************78 *79 * FUNCTION:    acpi_ex_resolve_operands80 *81 * PARAMETERS:  opcode              - Opcode being interpreted82 *              stack_ptr           - Pointer to the operand stack to be83 *                                    resolved84 *              walk_state          - Current state85 *86 * RETURN:      Status87 *88 * DESCRIPTION: Convert multiple input operands to the types required by the89 *              target operator.90 *91 *      Each 5-bit group in arg_types represents one required92 *      operand and indicates the required Type. The corresponding operand93 *      will be converted to the required type if possible, otherwise we94 *      abort with an exception.95 *96 ******************************************************************************/97 98acpi_status99acpi_ex_resolve_operands(u16 opcode,100			 union acpi_operand_object **stack_ptr,101			 struct acpi_walk_state *walk_state)102{103	union acpi_operand_object *obj_desc;104	acpi_status status = AE_OK;105	u8 object_type;106	u32 arg_types;107	const struct acpi_opcode_info *op_info;108	u32 this_arg_type;109	acpi_object_type type_needed;110	u16 target_op = 0;111 112	ACPI_FUNCTION_TRACE_U32(ex_resolve_operands, opcode);113 114	op_info = acpi_ps_get_opcode_info(opcode);115	if (op_info->class == AML_CLASS_UNKNOWN) {116		return_ACPI_STATUS(AE_AML_BAD_OPCODE);117	}118 119	arg_types = op_info->runtime_args;120	if (arg_types == ARGI_INVALID_OPCODE) {121		ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", opcode));122 123		return_ACPI_STATUS(AE_AML_INTERNAL);124	}125 126	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,127			  "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",128			  opcode, op_info->name, arg_types));129 130	/*131	 * Normal exit is with (arg_types == 0) at end of argument list.132	 * Function will return an exception from within the loop upon133	 * finding an entry which is not (or cannot be converted134	 * to) the required type; if stack underflows; or upon135	 * finding a NULL stack entry (which should not happen).136	 */137	while (GET_CURRENT_ARG_TYPE(arg_types)) {138		if (!stack_ptr || !*stack_ptr) {139			ACPI_ERROR((AE_INFO, "Null stack entry at %p",140				    stack_ptr));141 142			return_ACPI_STATUS(AE_AML_INTERNAL);143		}144 145		/* Extract useful items */146 147		obj_desc = *stack_ptr;148 149		/* Decode the descriptor type */150 151		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {152		case ACPI_DESC_TYPE_NAMED:153 154			/* Namespace Node */155 156			object_type =157			    ((struct acpi_namespace_node *)obj_desc)->type;158 159			/*160			 * Resolve an alias object. The construction of these objects161			 * guarantees that there is only one level of alias indirection;162			 * thus, the attached object is always the aliased namespace node163			 */164			if (object_type == ACPI_TYPE_LOCAL_ALIAS) {165				obj_desc = acpi_ns_get_attached_object((struct166									acpi_namespace_node167									*)168								       obj_desc);169				*stack_ptr = obj_desc;170				object_type =171				    ((struct acpi_namespace_node *)obj_desc)->172				    type;173			}174			break;175 176		case ACPI_DESC_TYPE_OPERAND:177 178			/* ACPI internal object */179 180			object_type = obj_desc->common.type;181 182			/* Check for bad acpi_object_type */183 184			if (!acpi_ut_valid_object_type(object_type)) {185				ACPI_ERROR((AE_INFO,186					    "Bad operand object type [0x%X]",187					    object_type));188 189				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);190			}191 192			if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {193 194				/* Validate the Reference */195 196				switch (obj_desc->reference.class) {197				case ACPI_REFCLASS_DEBUG:198 199					target_op = AML_DEBUG_OP;200 201					ACPI_FALLTHROUGH;202 203				case ACPI_REFCLASS_ARG:204				case ACPI_REFCLASS_LOCAL:205				case ACPI_REFCLASS_INDEX:206				case ACPI_REFCLASS_REFOF:207				case ACPI_REFCLASS_TABLE:	/* ddb_handle from LOAD_OP or LOAD_TABLE_OP */208				case ACPI_REFCLASS_NAME:	/* Reference to a named object */209 210					ACPI_DEBUG_PRINT((ACPI_DB_EXEC,211							  "Operand is a Reference, Class [%s] %2.2X\n",212							  acpi_ut_get_reference_name213							  (obj_desc),214							  obj_desc->reference.215							  class));216					break;217 218				default:219 220					ACPI_ERROR((AE_INFO,221						    "Unknown Reference Class 0x%2.2X in %p",222						    obj_desc->reference.class,223						    obj_desc));224 225					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);226				}227			}228			break;229 230		default:231 232			/* Invalid descriptor */233 234			ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]",235				    obj_desc,236				    acpi_ut_get_descriptor_name(obj_desc)));237 238			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);239		}240 241		/* Get one argument type, point to the next */242 243		this_arg_type = GET_CURRENT_ARG_TYPE(arg_types);244		INCREMENT_ARG_LIST(arg_types);245 246		/*247		 * Handle cases where the object does not need to be248		 * resolved to a value249		 */250		switch (this_arg_type) {251		case ARGI_REF_OR_STRING:	/* Can be a String or Reference */252 253			if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==254			     ACPI_DESC_TYPE_OPERAND) &&255			    (obj_desc->common.type == ACPI_TYPE_STRING)) {256				/*257				 * String found - the string references a named object and258				 * must be resolved to a node259				 */260				goto next_operand;261			}262 263			/*264			 * Else not a string - fall through to the normal Reference265			 * case below266			 */267			ACPI_FALLTHROUGH;268 269		case ARGI_REFERENCE:	/* References: */270		case ARGI_INTEGER_REF:271		case ARGI_OBJECT_REF:272		case ARGI_DEVICE_REF:273		case ARGI_TARGETREF:	/* Allows implicit conversion rules before store */274		case ARGI_FIXED_TARGET:	/* No implicit conversion before store to target */275		case ARGI_SIMPLE_TARGET:	/* Name, Local, or arg - no implicit conversion  */276		case ARGI_STORE_TARGET:277 278			/*279			 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE280			 * A Namespace Node is OK as-is281			 */282			if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==283			    ACPI_DESC_TYPE_NAMED) {284				goto next_operand;285			}286 287			status =288			    acpi_ex_check_object_type(ACPI_TYPE_LOCAL_REFERENCE,289						      object_type, obj_desc);290			if (ACPI_FAILURE(status)) {291				return_ACPI_STATUS(status);292			}293			goto next_operand;294 295		case ARGI_DATAREFOBJ:	/* Store operator only */296			/*297			 * We don't want to resolve index_op reference objects during298			 * a store because this would be an implicit de_ref_of operation.299			 * Instead, we just want to store the reference object.300			 * -- All others must be resolved below.301			 */302			if ((opcode == AML_STORE_OP) &&303			    ((*stack_ptr)->common.type ==304			     ACPI_TYPE_LOCAL_REFERENCE)305			    && ((*stack_ptr)->reference.class ==306				ACPI_REFCLASS_INDEX)) {307				goto next_operand;308			}309			break;310 311		default:312 313			/* All cases covered above */314 315			break;316		}317 318		/*319		 * Resolve this object to a value320		 */321		status = acpi_ex_resolve_to_value(stack_ptr, walk_state);322		if (ACPI_FAILURE(status)) {323			return_ACPI_STATUS(status);324		}325 326		/* Get the resolved object */327 328		obj_desc = *stack_ptr;329 330		/*331		 * Check the resulting object (value) type332		 */333		switch (this_arg_type) {334			/*335			 * For the simple cases, only one type of resolved object336			 * is allowed337			 */338		case ARGI_MUTEX:339 340			/* Need an operand of type ACPI_TYPE_MUTEX */341 342			type_needed = ACPI_TYPE_MUTEX;343			break;344 345		case ARGI_EVENT:346 347			/* Need an operand of type ACPI_TYPE_EVENT */348 349			type_needed = ACPI_TYPE_EVENT;350			break;351 352		case ARGI_PACKAGE:	/* Package */353 354			/* Need an operand of type ACPI_TYPE_PACKAGE */355 356			type_needed = ACPI_TYPE_PACKAGE;357			break;358 359		case ARGI_ANYTYPE:360 361			/* Any operand type will do */362 363			type_needed = ACPI_TYPE_ANY;364			break;365 366		case ARGI_DDBHANDLE:367 368			/* Need an operand of type ACPI_TYPE_DDB_HANDLE */369 370			type_needed = ACPI_TYPE_LOCAL_REFERENCE;371			break;372 373			/*374			 * The more complex cases allow multiple resolved object types375			 */376		case ARGI_INTEGER:377 378			/*379			 * Need an operand of type ACPI_TYPE_INTEGER, but we can380			 * implicitly convert from a STRING or BUFFER.381			 *382			 * Known as "Implicit Source Operand Conversion"383			 */384			status = acpi_ex_convert_to_integer(obj_desc, stack_ptr,385							    ACPI_IMPLICIT_CONVERSION);386			if (ACPI_FAILURE(status)) {387				if (status == AE_TYPE) {388					ACPI_ERROR((AE_INFO,389						    "Needed [Integer/String/Buffer], found [%s] %p",390						    acpi_ut_get_object_type_name391						    (obj_desc), obj_desc));392 393					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);394				}395 396				return_ACPI_STATUS(status);397			}398 399			if (obj_desc != *stack_ptr) {400				acpi_ut_remove_reference(obj_desc);401			}402			goto next_operand;403 404		case ARGI_BUFFER:405			/*406			 * Need an operand of type ACPI_TYPE_BUFFER,407			 * But we can implicitly convert from a STRING or INTEGER408			 * aka - "Implicit Source Operand Conversion"409			 */410			status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr);411			if (ACPI_FAILURE(status)) {412				if (status == AE_TYPE) {413					ACPI_ERROR((AE_INFO,414						    "Needed [Integer/String/Buffer], found [%s] %p",415						    acpi_ut_get_object_type_name416						    (obj_desc), obj_desc));417 418					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);419				}420 421				return_ACPI_STATUS(status);422			}423 424			if (obj_desc != *stack_ptr) {425				acpi_ut_remove_reference(obj_desc);426			}427			goto next_operand;428 429		case ARGI_STRING:430			/*431			 * Need an operand of type ACPI_TYPE_STRING,432			 * But we can implicitly convert from a BUFFER or INTEGER433			 * aka - "Implicit Source Operand Conversion"434			 */435			status =436			    acpi_ex_convert_to_string(obj_desc, stack_ptr,437						      ACPI_IMPLICIT_CONVERT_HEX);438			if (ACPI_FAILURE(status)) {439				if (status == AE_TYPE) {440					ACPI_ERROR((AE_INFO,441						    "Needed [Integer/String/Buffer], found [%s] %p",442						    acpi_ut_get_object_type_name443						    (obj_desc), obj_desc));444 445					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);446				}447 448				return_ACPI_STATUS(status);449			}450 451			if (obj_desc != *stack_ptr) {452				acpi_ut_remove_reference(obj_desc);453			}454			goto next_operand;455 456		case ARGI_COMPUTEDATA:457 458			/* Need an operand of type INTEGER, STRING or BUFFER */459 460			switch (obj_desc->common.type) {461			case ACPI_TYPE_INTEGER:462			case ACPI_TYPE_STRING:463			case ACPI_TYPE_BUFFER:464 465				/* Valid operand */466				break;467 468			default:469				ACPI_ERROR((AE_INFO,470					    "Needed [Integer/String/Buffer], found [%s] %p",471					    acpi_ut_get_object_type_name472					    (obj_desc), obj_desc));473 474				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);475			}476			goto next_operand;477 478		case ARGI_BUFFER_OR_STRING:479 480			/* Need an operand of type STRING or BUFFER */481 482			switch (obj_desc->common.type) {483			case ACPI_TYPE_STRING:484			case ACPI_TYPE_BUFFER:485 486				/* Valid operand */487				break;488 489			case ACPI_TYPE_INTEGER:490 491				/* Highest priority conversion is to type Buffer */492 493				status =494				    acpi_ex_convert_to_buffer(obj_desc,495							      stack_ptr);496				if (ACPI_FAILURE(status)) {497					return_ACPI_STATUS(status);498				}499 500				if (obj_desc != *stack_ptr) {501					acpi_ut_remove_reference(obj_desc);502				}503				break;504 505			default:506				ACPI_ERROR((AE_INFO,507					    "Needed [Integer/String/Buffer], found [%s] %p",508					    acpi_ut_get_object_type_name509					    (obj_desc), obj_desc));510 511				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);512			}513			goto next_operand;514 515		case ARGI_DATAOBJECT:516			/*517			 * ARGI_DATAOBJECT is only used by the size_of operator.518			 * Need a buffer, string, package, or ref_of reference.519			 *520			 * The only reference allowed here is a direct reference to521			 * a namespace node.522			 */523			switch (obj_desc->common.type) {524			case ACPI_TYPE_PACKAGE:525			case ACPI_TYPE_STRING:526			case ACPI_TYPE_BUFFER:527			case ACPI_TYPE_LOCAL_REFERENCE:528 529				/* Valid operand */530				break;531 532			default:533 534				ACPI_ERROR((AE_INFO,535					    "Needed [Buffer/String/Package/Reference], found [%s] %p",536					    acpi_ut_get_object_type_name537					    (obj_desc), obj_desc));538 539				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);540			}541			goto next_operand;542 543		case ARGI_COMPLEXOBJ:544 545			/* Need a buffer or package or (ACPI 2.0) String */546 547			switch (obj_desc->common.type) {548			case ACPI_TYPE_PACKAGE:549			case ACPI_TYPE_STRING:550			case ACPI_TYPE_BUFFER:551 552				/* Valid operand */553				break;554 555			default:556 557				ACPI_ERROR((AE_INFO,558					    "Needed [Buffer/String/Package], found [%s] %p",559					    acpi_ut_get_object_type_name560					    (obj_desc), obj_desc));561 562				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);563			}564			goto next_operand;565 566		case ARGI_REGION_OR_BUFFER:	/* Used by Load() only */567 568			/*569			 * Need an operand of type REGION or a BUFFER570			 * (which could be a resolved region field)571			 */572			switch (obj_desc->common.type) {573			case ACPI_TYPE_BUFFER:574			case ACPI_TYPE_REGION:575 576				/* Valid operand */577				break;578 579			default:580 581				ACPI_ERROR((AE_INFO,582					    "Needed [Region/Buffer], found [%s] %p",583					    acpi_ut_get_object_type_name584					    (obj_desc), obj_desc));585 586				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);587			}588			goto next_operand;589 590		case ARGI_DATAREFOBJ:591 592			/* Used by the Store() operator only */593 594			switch (obj_desc->common.type) {595			case ACPI_TYPE_INTEGER:596			case ACPI_TYPE_PACKAGE:597			case ACPI_TYPE_STRING:598			case ACPI_TYPE_BUFFER:599			case ACPI_TYPE_BUFFER_FIELD:600			case ACPI_TYPE_LOCAL_REFERENCE:601			case ACPI_TYPE_LOCAL_REGION_FIELD:602			case ACPI_TYPE_LOCAL_BANK_FIELD:603			case ACPI_TYPE_LOCAL_INDEX_FIELD:604			case ACPI_TYPE_DDB_HANDLE:605 606				/* Valid operand */607				break;608 609			default:610 611				if (acpi_gbl_enable_interpreter_slack) {612					/*613					 * Enable original behavior of Store(), allowing any614					 * and all objects as the source operand. The ACPI615					 * spec does not allow this, however.616					 */617					break;618				}619 620				if (target_op == AML_DEBUG_OP) {621 622					/* Allow store of any object to the Debug object */623 624					break;625				}626 627				ACPI_ERROR((AE_INFO,628					    "Needed Integer/Buffer/String/Package/Ref/Ddb]"629					    ", found [%s] %p",630					    acpi_ut_get_object_type_name631					    (obj_desc), obj_desc));632 633				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);634			}635			goto next_operand;636 637		default:638 639			/* Unknown type */640 641			ACPI_ERROR((AE_INFO,642				    "Internal - Unknown ARGI (required operand) type 0x%X",643				    this_arg_type));644 645			return_ACPI_STATUS(AE_BAD_PARAMETER);646		}647 648		/*649		 * Make sure that the original object was resolved to the650		 * required object type (Simple cases only).651		 */652		status =653		    acpi_ex_check_object_type(type_needed,654					      (*stack_ptr)->common.type,655					      *stack_ptr);656		if (ACPI_FAILURE(status)) {657			return_ACPI_STATUS(status);658		}659 660next_operand:661		/*662		 * If more operands needed, decrement stack_ptr to point663		 * to next operand on stack664		 */665		if (GET_CURRENT_ARG_TYPE(arg_types)) {666			stack_ptr--;667		}668	}669 670	ACPI_DUMP_OPERANDS(walk_state->operands,671			   acpi_ps_get_opcode_name(opcode),672			   walk_state->num_operands);673 674	return_ACPI_STATUS(status);675}676