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