Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: exresop - AML Interpreter operand/object resolution
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "amlcode.h"
0013 #include "acparser.h"
0014 #include "acinterp.h"
0015 #include "acnamesp.h"
0016 
0017 #define _COMPONENT          ACPI_EXECUTER
0018 ACPI_MODULE_NAME("exresop")
0019 
0020 /* Local prototypes */
0021 static acpi_status
0022 acpi_ex_check_object_type(acpi_object_type type_needed,
0023               acpi_object_type this_type, void *object);
0024 
0025 /*******************************************************************************
0026  *
0027  * FUNCTION:    acpi_ex_check_object_type
0028  *
0029  * PARAMETERS:  type_needed         Object type needed
0030  *              this_type           Actual object type
0031  *              Object              Object pointer
0032  *
0033  * RETURN:      Status
0034  *
0035  * DESCRIPTION: Check required type against actual type
0036  *
0037  ******************************************************************************/
0038 
0039 static acpi_status
0040 acpi_ex_check_object_type(acpi_object_type type_needed,
0041               acpi_object_type this_type, void *object)
0042 {
0043     ACPI_FUNCTION_ENTRY();
0044 
0045     if (type_needed == ACPI_TYPE_ANY) {
0046 
0047         /* All types OK, so we don't perform any typechecks */
0048 
0049         return (AE_OK);
0050     }
0051 
0052     if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {
0053         /*
0054          * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
0055          * objects and thus allow them to be targets. (As per the ACPI
0056          * specification, a store to a constant is a noop.)
0057          */
0058         if ((this_type == ACPI_TYPE_INTEGER) &&
0059             (((union acpi_operand_object *)object)->common.flags &
0060              AOPOBJ_AML_CONSTANT)) {
0061             return (AE_OK);
0062         }
0063     }
0064 
0065     if (type_needed != this_type) {
0066         ACPI_ERROR((AE_INFO,
0067                 "Needed type [%s], found [%s] %p",
0068                 acpi_ut_get_type_name(type_needed),
0069                 acpi_ut_get_type_name(this_type), object));
0070 
0071         return (AE_AML_OPERAND_TYPE);
0072     }
0073 
0074     return (AE_OK);
0075 }
0076 
0077 /*******************************************************************************
0078  *
0079  * FUNCTION:    acpi_ex_resolve_operands
0080  *
0081  * PARAMETERS:  opcode              - Opcode being interpreted
0082  *              stack_ptr           - Pointer to the operand stack to be
0083  *                                    resolved
0084  *              walk_state          - Current state
0085  *
0086  * RETURN:      Status
0087  *
0088  * DESCRIPTION: Convert multiple input operands to the types required by the
0089  *              target operator.
0090  *
0091  *      Each 5-bit group in arg_types represents one required
0092  *      operand and indicates the required Type. The corresponding operand
0093  *      will be converted to the required type if possible, otherwise we
0094  *      abort with an exception.
0095  *
0096  ******************************************************************************/
0097 
0098 acpi_status
0099 acpi_ex_resolve_operands(u16 opcode,
0100              union acpi_operand_object **stack_ptr,
0101              struct acpi_walk_state *walk_state)
0102 {
0103     union acpi_operand_object *obj_desc;
0104     acpi_status status = AE_OK;
0105     u8 object_type;
0106     u32 arg_types;
0107     const struct acpi_opcode_info *op_info;
0108     u32 this_arg_type;
0109     acpi_object_type type_needed;
0110     u16 target_op = 0;
0111 
0112     ACPI_FUNCTION_TRACE_U32(ex_resolve_operands, opcode);
0113 
0114     op_info = acpi_ps_get_opcode_info(opcode);
0115     if (op_info->class == AML_CLASS_UNKNOWN) {
0116         return_ACPI_STATUS(AE_AML_BAD_OPCODE);
0117     }
0118 
0119     arg_types = op_info->runtime_args;
0120     if (arg_types == ARGI_INVALID_OPCODE) {
0121         ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", opcode));
0122 
0123         return_ACPI_STATUS(AE_AML_INTERNAL);
0124     }
0125 
0126     ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0127               "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",
0128               opcode, op_info->name, arg_types));
0129 
0130     /*
0131      * Normal exit is with (arg_types == 0) at end of argument list.
0132      * Function will return an exception from within the loop upon
0133      * finding an entry which is not (or cannot be converted
0134      * to) the required type; if stack underflows; or upon
0135      * finding a NULL stack entry (which should not happen).
0136      */
0137     while (GET_CURRENT_ARG_TYPE(arg_types)) {
0138         if (!stack_ptr || !*stack_ptr) {
0139             ACPI_ERROR((AE_INFO, "Null stack entry at %p",
0140                     stack_ptr));
0141 
0142             return_ACPI_STATUS(AE_AML_INTERNAL);
0143         }
0144 
0145         /* Extract useful items */
0146 
0147         obj_desc = *stack_ptr;
0148 
0149         /* Decode the descriptor type */
0150 
0151         switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
0152         case ACPI_DESC_TYPE_NAMED:
0153 
0154             /* Namespace Node */
0155 
0156             object_type =
0157                 ((struct acpi_namespace_node *)obj_desc)->type;
0158 
0159             /*
0160              * Resolve an alias object. The construction of these objects
0161              * guarantees that there is only one level of alias indirection;
0162              * thus, the attached object is always the aliased namespace node
0163              */
0164             if (object_type == ACPI_TYPE_LOCAL_ALIAS) {
0165                 obj_desc = acpi_ns_get_attached_object((struct
0166                                     acpi_namespace_node
0167                                     *)
0168                                        obj_desc);
0169                 *stack_ptr = obj_desc;
0170                 object_type =
0171                     ((struct acpi_namespace_node *)obj_desc)->
0172                     type;
0173             }
0174             break;
0175 
0176         case ACPI_DESC_TYPE_OPERAND:
0177 
0178             /* ACPI internal object */
0179 
0180             object_type = obj_desc->common.type;
0181 
0182             /* Check for bad acpi_object_type */
0183 
0184             if (!acpi_ut_valid_object_type(object_type)) {
0185                 ACPI_ERROR((AE_INFO,
0186                         "Bad operand object type [0x%X]",
0187                         object_type));
0188 
0189                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0190             }
0191 
0192             if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
0193 
0194                 /* Validate the Reference */
0195 
0196                 switch (obj_desc->reference.class) {
0197                 case ACPI_REFCLASS_DEBUG:
0198 
0199                     target_op = AML_DEBUG_OP;
0200 
0201                     ACPI_FALLTHROUGH;
0202 
0203                 case ACPI_REFCLASS_ARG:
0204                 case ACPI_REFCLASS_LOCAL:
0205                 case ACPI_REFCLASS_INDEX:
0206                 case ACPI_REFCLASS_REFOF:
0207                 case ACPI_REFCLASS_TABLE:   /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
0208                 case ACPI_REFCLASS_NAME:    /* Reference to a named object */
0209 
0210                     ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0211                               "Operand is a Reference, Class [%s] %2.2X\n",
0212                               acpi_ut_get_reference_name
0213                               (obj_desc),
0214                               obj_desc->reference.
0215                               class));
0216                     break;
0217 
0218                 default:
0219 
0220                     ACPI_ERROR((AE_INFO,
0221                             "Unknown Reference Class 0x%2.2X in %p",
0222                             obj_desc->reference.class,
0223                             obj_desc));
0224 
0225                     return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0226                 }
0227             }
0228             break;
0229 
0230         default:
0231 
0232             /* Invalid descriptor */
0233 
0234             ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]",
0235                     obj_desc,
0236                     acpi_ut_get_descriptor_name(obj_desc)));
0237 
0238             return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0239         }
0240 
0241         /* Get one argument type, point to the next */
0242 
0243         this_arg_type = GET_CURRENT_ARG_TYPE(arg_types);
0244         INCREMENT_ARG_LIST(arg_types);
0245 
0246         /*
0247          * Handle cases where the object does not need to be
0248          * resolved to a value
0249          */
0250         switch (this_arg_type) {
0251         case ARGI_REF_OR_STRING:    /* Can be a String or Reference */
0252 
0253             if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
0254                  ACPI_DESC_TYPE_OPERAND) &&
0255                 (obj_desc->common.type == ACPI_TYPE_STRING)) {
0256                 /*
0257                  * String found - the string references a named object and
0258                  * must be resolved to a node
0259                  */
0260                 goto next_operand;
0261             }
0262 
0263             /*
0264              * Else not a string - fall through to the normal Reference
0265              * case below
0266              */
0267             ACPI_FALLTHROUGH;
0268 
0269         case ARGI_REFERENCE:    /* References: */
0270         case ARGI_INTEGER_REF:
0271         case ARGI_OBJECT_REF:
0272         case ARGI_DEVICE_REF:
0273         case ARGI_TARGETREF:    /* Allows implicit conversion rules before store */
0274         case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
0275         case ARGI_SIMPLE_TARGET:    /* Name, Local, or arg - no implicit conversion  */
0276         case ARGI_STORE_TARGET:
0277 
0278             /*
0279              * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
0280              * A Namespace Node is OK as-is
0281              */
0282             if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
0283                 ACPI_DESC_TYPE_NAMED) {
0284                 goto next_operand;
0285             }
0286 
0287             status =
0288                 acpi_ex_check_object_type(ACPI_TYPE_LOCAL_REFERENCE,
0289                               object_type, obj_desc);
0290             if (ACPI_FAILURE(status)) {
0291                 return_ACPI_STATUS(status);
0292             }
0293             goto next_operand;
0294 
0295         case ARGI_DATAREFOBJ:   /* Store operator only */
0296             /*
0297              * We don't want to resolve index_op reference objects during
0298              * a store because this would be an implicit de_ref_of operation.
0299              * Instead, we just want to store the reference object.
0300              * -- All others must be resolved below.
0301              */
0302             if ((opcode == AML_STORE_OP) &&
0303                 ((*stack_ptr)->common.type ==
0304                  ACPI_TYPE_LOCAL_REFERENCE)
0305                 && ((*stack_ptr)->reference.class ==
0306                 ACPI_REFCLASS_INDEX)) {
0307                 goto next_operand;
0308             }
0309             break;
0310 
0311         default:
0312 
0313             /* All cases covered above */
0314 
0315             break;
0316         }
0317 
0318         /*
0319          * Resolve this object to a value
0320          */
0321         status = acpi_ex_resolve_to_value(stack_ptr, walk_state);
0322         if (ACPI_FAILURE(status)) {
0323             return_ACPI_STATUS(status);
0324         }
0325 
0326         /* Get the resolved object */
0327 
0328         obj_desc = *stack_ptr;
0329 
0330         /*
0331          * Check the resulting object (value) type
0332          */
0333         switch (this_arg_type) {
0334             /*
0335              * For the simple cases, only one type of resolved object
0336              * is allowed
0337              */
0338         case ARGI_MUTEX:
0339 
0340             /* Need an operand of type ACPI_TYPE_MUTEX */
0341 
0342             type_needed = ACPI_TYPE_MUTEX;
0343             break;
0344 
0345         case ARGI_EVENT:
0346 
0347             /* Need an operand of type ACPI_TYPE_EVENT */
0348 
0349             type_needed = ACPI_TYPE_EVENT;
0350             break;
0351 
0352         case ARGI_PACKAGE:  /* Package */
0353 
0354             /* Need an operand of type ACPI_TYPE_PACKAGE */
0355 
0356             type_needed = ACPI_TYPE_PACKAGE;
0357             break;
0358 
0359         case ARGI_ANYTYPE:
0360 
0361             /* Any operand type will do */
0362 
0363             type_needed = ACPI_TYPE_ANY;
0364             break;
0365 
0366         case ARGI_DDBHANDLE:
0367 
0368             /* Need an operand of type ACPI_TYPE_DDB_HANDLE */
0369 
0370             type_needed = ACPI_TYPE_LOCAL_REFERENCE;
0371             break;
0372 
0373             /*
0374              * The more complex cases allow multiple resolved object types
0375              */
0376         case ARGI_INTEGER:
0377 
0378             /*
0379              * Need an operand of type ACPI_TYPE_INTEGER, but we can
0380              * implicitly convert from a STRING or BUFFER.
0381              *
0382              * Known as "Implicit Source Operand Conversion"
0383              */
0384             status = acpi_ex_convert_to_integer(obj_desc, stack_ptr,
0385                                 ACPI_IMPLICIT_CONVERSION);
0386             if (ACPI_FAILURE(status)) {
0387                 if (status == AE_TYPE) {
0388                     ACPI_ERROR((AE_INFO,
0389                             "Needed [Integer/String/Buffer], found [%s] %p",
0390                             acpi_ut_get_object_type_name
0391                             (obj_desc), obj_desc));
0392 
0393                     return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0394                 }
0395 
0396                 return_ACPI_STATUS(status);
0397             }
0398 
0399             if (obj_desc != *stack_ptr) {
0400                 acpi_ut_remove_reference(obj_desc);
0401             }
0402             goto next_operand;
0403 
0404         case ARGI_BUFFER:
0405             /*
0406              * Need an operand of type ACPI_TYPE_BUFFER,
0407              * But we can implicitly convert from a STRING or INTEGER
0408              * aka - "Implicit Source Operand Conversion"
0409              */
0410             status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr);
0411             if (ACPI_FAILURE(status)) {
0412                 if (status == AE_TYPE) {
0413                     ACPI_ERROR((AE_INFO,
0414                             "Needed [Integer/String/Buffer], found [%s] %p",
0415                             acpi_ut_get_object_type_name
0416                             (obj_desc), obj_desc));
0417 
0418                     return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0419                 }
0420 
0421                 return_ACPI_STATUS(status);
0422             }
0423 
0424             if (obj_desc != *stack_ptr) {
0425                 acpi_ut_remove_reference(obj_desc);
0426             }
0427             goto next_operand;
0428 
0429         case ARGI_STRING:
0430             /*
0431              * Need an operand of type ACPI_TYPE_STRING,
0432              * But we can implicitly convert from a BUFFER or INTEGER
0433              * aka - "Implicit Source Operand Conversion"
0434              */
0435             status =
0436                 acpi_ex_convert_to_string(obj_desc, stack_ptr,
0437                               ACPI_IMPLICIT_CONVERT_HEX);
0438             if (ACPI_FAILURE(status)) {
0439                 if (status == AE_TYPE) {
0440                     ACPI_ERROR((AE_INFO,
0441                             "Needed [Integer/String/Buffer], found [%s] %p",
0442                             acpi_ut_get_object_type_name
0443                             (obj_desc), obj_desc));
0444 
0445                     return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0446                 }
0447 
0448                 return_ACPI_STATUS(status);
0449             }
0450 
0451             if (obj_desc != *stack_ptr) {
0452                 acpi_ut_remove_reference(obj_desc);
0453             }
0454             goto next_operand;
0455 
0456         case ARGI_COMPUTEDATA:
0457 
0458             /* Need an operand of type INTEGER, STRING or BUFFER */
0459 
0460             switch (obj_desc->common.type) {
0461             case ACPI_TYPE_INTEGER:
0462             case ACPI_TYPE_STRING:
0463             case ACPI_TYPE_BUFFER:
0464 
0465                 /* Valid operand */
0466                 break;
0467 
0468             default:
0469                 ACPI_ERROR((AE_INFO,
0470                         "Needed [Integer/String/Buffer], found [%s] %p",
0471                         acpi_ut_get_object_type_name
0472                         (obj_desc), obj_desc));
0473 
0474                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0475             }
0476             goto next_operand;
0477 
0478         case ARGI_BUFFER_OR_STRING:
0479 
0480             /* Need an operand of type STRING or BUFFER */
0481 
0482             switch (obj_desc->common.type) {
0483             case ACPI_TYPE_STRING:
0484             case ACPI_TYPE_BUFFER:
0485 
0486                 /* Valid operand */
0487                 break;
0488 
0489             case ACPI_TYPE_INTEGER:
0490 
0491                 /* Highest priority conversion is to type Buffer */
0492 
0493                 status =
0494                     acpi_ex_convert_to_buffer(obj_desc,
0495                                   stack_ptr);
0496                 if (ACPI_FAILURE(status)) {
0497                     return_ACPI_STATUS(status);
0498                 }
0499 
0500                 if (obj_desc != *stack_ptr) {
0501                     acpi_ut_remove_reference(obj_desc);
0502                 }
0503                 break;
0504 
0505             default:
0506                 ACPI_ERROR((AE_INFO,
0507                         "Needed [Integer/String/Buffer], found [%s] %p",
0508                         acpi_ut_get_object_type_name
0509                         (obj_desc), obj_desc));
0510 
0511                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0512             }
0513             goto next_operand;
0514 
0515         case ARGI_DATAOBJECT:
0516             /*
0517              * ARGI_DATAOBJECT is only used by the size_of operator.
0518              * Need a buffer, string, package, or ref_of reference.
0519              *
0520              * The only reference allowed here is a direct reference to
0521              * a namespace node.
0522              */
0523             switch (obj_desc->common.type) {
0524             case ACPI_TYPE_PACKAGE:
0525             case ACPI_TYPE_STRING:
0526             case ACPI_TYPE_BUFFER:
0527             case ACPI_TYPE_LOCAL_REFERENCE:
0528 
0529                 /* Valid operand */
0530                 break;
0531 
0532             default:
0533 
0534                 ACPI_ERROR((AE_INFO,
0535                         "Needed [Buffer/String/Package/Reference], found [%s] %p",
0536                         acpi_ut_get_object_type_name
0537                         (obj_desc), obj_desc));
0538 
0539                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0540             }
0541             goto next_operand;
0542 
0543         case ARGI_COMPLEXOBJ:
0544 
0545             /* Need a buffer or package or (ACPI 2.0) String */
0546 
0547             switch (obj_desc->common.type) {
0548             case ACPI_TYPE_PACKAGE:
0549             case ACPI_TYPE_STRING:
0550             case ACPI_TYPE_BUFFER:
0551 
0552                 /* Valid operand */
0553                 break;
0554 
0555             default:
0556 
0557                 ACPI_ERROR((AE_INFO,
0558                         "Needed [Buffer/String/Package], found [%s] %p",
0559                         acpi_ut_get_object_type_name
0560                         (obj_desc), obj_desc));
0561 
0562                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0563             }
0564             goto next_operand;
0565 
0566         case ARGI_REGION_OR_BUFFER: /* Used by Load() only */
0567 
0568             /*
0569              * Need an operand of type REGION or a BUFFER
0570              * (which could be a resolved region field)
0571              */
0572             switch (obj_desc->common.type) {
0573             case ACPI_TYPE_BUFFER:
0574             case ACPI_TYPE_REGION:
0575 
0576                 /* Valid operand */
0577                 break;
0578 
0579             default:
0580 
0581                 ACPI_ERROR((AE_INFO,
0582                         "Needed [Region/Buffer], found [%s] %p",
0583                         acpi_ut_get_object_type_name
0584                         (obj_desc), obj_desc));
0585 
0586                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0587             }
0588             goto next_operand;
0589 
0590         case ARGI_DATAREFOBJ:
0591 
0592             /* Used by the Store() operator only */
0593 
0594             switch (obj_desc->common.type) {
0595             case ACPI_TYPE_INTEGER:
0596             case ACPI_TYPE_PACKAGE:
0597             case ACPI_TYPE_STRING:
0598             case ACPI_TYPE_BUFFER:
0599             case ACPI_TYPE_BUFFER_FIELD:
0600             case ACPI_TYPE_LOCAL_REFERENCE:
0601             case ACPI_TYPE_LOCAL_REGION_FIELD:
0602             case ACPI_TYPE_LOCAL_BANK_FIELD:
0603             case ACPI_TYPE_LOCAL_INDEX_FIELD:
0604             case ACPI_TYPE_DDB_HANDLE:
0605 
0606                 /* Valid operand */
0607                 break;
0608 
0609             default:
0610 
0611                 if (acpi_gbl_enable_interpreter_slack) {
0612                     /*
0613                      * Enable original behavior of Store(), allowing any
0614                      * and all objects as the source operand. The ACPI
0615                      * spec does not allow this, however.
0616                      */
0617                     break;
0618                 }
0619 
0620                 if (target_op == AML_DEBUG_OP) {
0621 
0622                     /* Allow store of any object to the Debug object */
0623 
0624                     break;
0625                 }
0626 
0627                 ACPI_ERROR((AE_INFO,
0628                         "Needed Integer/Buffer/String/Package/Ref/Ddb]"
0629                         ", found [%s] %p",
0630                         acpi_ut_get_object_type_name
0631                         (obj_desc), obj_desc));
0632 
0633                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0634             }
0635             goto next_operand;
0636 
0637         default:
0638 
0639             /* Unknown type */
0640 
0641             ACPI_ERROR((AE_INFO,
0642                     "Internal - Unknown ARGI (required operand) type 0x%X",
0643                     this_arg_type));
0644 
0645             return_ACPI_STATUS(AE_BAD_PARAMETER);
0646         }
0647 
0648         /*
0649          * Make sure that the original object was resolved to the
0650          * required object type (Simple cases only).
0651          */
0652         status =
0653             acpi_ex_check_object_type(type_needed,
0654                           (*stack_ptr)->common.type,
0655                           *stack_ptr);
0656         if (ACPI_FAILURE(status)) {
0657             return_ACPI_STATUS(status);
0658         }
0659 
0660 next_operand:
0661         /*
0662          * If more operands needed, decrement stack_ptr to point
0663          * to next operand on stack
0664          */
0665         if (GET_CURRENT_ARG_TYPE(arg_types)) {
0666             stack_ptr--;
0667         }
0668     }
0669 
0670     ACPI_DUMP_OPERANDS(walk_state->operands,
0671                acpi_ps_get_opcode_name(opcode),
0672                walk_state->num_operands);
0673 
0674     return_ACPI_STATUS(status);
0675 }