root/drivers/acpi/acpica/exstore.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ex_store_object_to_index
  3. acpi_ex_store_object_to_node
  4. acpi_ex_store_direct_to_node

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: exstore - AML Interpreter object store support
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acdispat.h"
  13 #include "acinterp.h"
  14 #include "amlcode.h"
  15 #include "acnamesp.h"
  16 
  17 #define _COMPONENT          ACPI_EXECUTER
  18 ACPI_MODULE_NAME("exstore")
  19 
  20 /* Local prototypes */
  21 static acpi_status
  22 acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
  23                               union acpi_operand_object *dest_desc,
  24                               struct acpi_walk_state *walk_state);
  25 
  26 static acpi_status
  27 acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
  28                              struct acpi_namespace_node *node,
  29                              struct acpi_walk_state *walk_state);
  30 
  31 /*******************************************************************************
  32  *
  33  * FUNCTION:    acpi_ex_store
  34  *
  35  * PARAMETERS:  *source_desc        - Value to be stored
  36  *              *dest_desc          - Where to store it. Must be an NS node
  37  *                                    or union acpi_operand_object of type
  38  *                                    Reference;
  39  *              walk_state          - Current walk state
  40  *
  41  * RETURN:      Status
  42  *
  43  * DESCRIPTION: Store the value described by source_desc into the location
  44  *              described by dest_desc. Called by various interpreter
  45  *              functions to store the result of an operation into
  46  *              the destination operand -- not just simply the actual "Store"
  47  *              ASL operator.
  48  *
  49  ******************************************************************************/
  50 
  51 acpi_status
  52 acpi_ex_store(union acpi_operand_object *source_desc,
  53               union acpi_operand_object *dest_desc,
  54               struct acpi_walk_state *walk_state)
  55 {
  56         acpi_status status = AE_OK;
  57         union acpi_operand_object *ref_desc = dest_desc;
  58 
  59         ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
  60 
  61         /* Validate parameters */
  62 
  63         if (!source_desc || !dest_desc) {
  64                 ACPI_ERROR((AE_INFO, "Null parameter"));
  65                 return_ACPI_STATUS(AE_AML_NO_OPERAND);
  66         }
  67 
  68         /* dest_desc can be either a namespace node or an ACPI object */
  69 
  70         if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
  71                 /*
  72                  * Dest is a namespace node,
  73                  * Storing an object into a Named node.
  74                  */
  75                 status = acpi_ex_store_object_to_node(source_desc,
  76                                                       (struct
  77                                                        acpi_namespace_node *)
  78                                                       dest_desc, walk_state,
  79                                                       ACPI_IMPLICIT_CONVERSION);
  80 
  81                 return_ACPI_STATUS(status);
  82         }
  83 
  84         /* Destination object must be a Reference or a Constant object */
  85 
  86         switch (dest_desc->common.type) {
  87         case ACPI_TYPE_LOCAL_REFERENCE:
  88 
  89                 break;
  90 
  91         case ACPI_TYPE_INTEGER:
  92 
  93                 /* Allow stores to Constants -- a Noop as per ACPI spec */
  94 
  95                 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
  96                         return_ACPI_STATUS(AE_OK);
  97                 }
  98 
  99                 /*lint -fallthrough */
 100 
 101         default:
 102 
 103                 /* Destination is not a Reference object */
 104 
 105                 ACPI_ERROR((AE_INFO,
 106                             "Target is not a Reference or Constant object - [%s] %p",
 107                             acpi_ut_get_object_type_name(dest_desc),
 108                             dest_desc));
 109 
 110                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 111         }
 112 
 113         /*
 114          * Examine the Reference class. These cases are handled:
 115          *
 116          * 1) Store to Name (Change the object associated with a name)
 117          * 2) Store to an indexed area of a Buffer or Package
 118          * 3) Store to a Method Local or Arg
 119          * 4) Store to the debug object
 120          */
 121         switch (ref_desc->reference.class) {
 122         case ACPI_REFCLASS_REFOF:
 123 
 124                 /* Storing an object into a Name "container" */
 125 
 126                 status = acpi_ex_store_object_to_node(source_desc,
 127                                                       ref_desc->reference.
 128                                                       object, walk_state,
 129                                                       ACPI_IMPLICIT_CONVERSION);
 130                 break;
 131 
 132         case ACPI_REFCLASS_INDEX:
 133 
 134                 /* Storing to an Index (pointer into a packager or buffer) */
 135 
 136                 status =
 137                     acpi_ex_store_object_to_index(source_desc, ref_desc,
 138                                                   walk_state);
 139                 break;
 140 
 141         case ACPI_REFCLASS_LOCAL:
 142         case ACPI_REFCLASS_ARG:
 143 
 144                 /* Store to a method local/arg  */
 145 
 146                 status =
 147                     acpi_ds_store_object_to_local(ref_desc->reference.class,
 148                                                   ref_desc->reference.value,
 149                                                   source_desc, walk_state);
 150                 break;
 151 
 152         case ACPI_REFCLASS_DEBUG:
 153                 /*
 154                  * Storing to the Debug object causes the value stored to be
 155                  * displayed and otherwise has no effect -- see ACPI Specification
 156                  */
 157                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 158                                   "**** Write to Debug Object: Object %p [%s] ****:\n\n",
 159                                   source_desc,
 160                                   acpi_ut_get_object_type_name(source_desc)));
 161 
 162                 ACPI_DEBUG_OBJECT(source_desc, 0, 0);
 163                 break;
 164 
 165         default:
 166 
 167                 ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
 168                             ref_desc->reference.class));
 169                 ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
 170 
 171                 status = AE_AML_INTERNAL;
 172                 break;
 173         }
 174 
 175         return_ACPI_STATUS(status);
 176 }
 177 
 178 /*******************************************************************************
 179  *
 180  * FUNCTION:    acpi_ex_store_object_to_index
 181  *
 182  * PARAMETERS:  *source_desc            - Value to be stored
 183  *              *dest_desc              - Named object to receive the value
 184  *              walk_state              - Current walk state
 185  *
 186  * RETURN:      Status
 187  *
 188  * DESCRIPTION: Store the object to indexed Buffer or Package element
 189  *
 190  ******************************************************************************/
 191 
 192 static acpi_status
 193 acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
 194                               union acpi_operand_object *index_desc,
 195                               struct acpi_walk_state *walk_state)
 196 {
 197         acpi_status status = AE_OK;
 198         union acpi_operand_object *obj_desc;
 199         union acpi_operand_object *new_desc;
 200         u8 value = 0;
 201         u32 i;
 202 
 203         ACPI_FUNCTION_TRACE(ex_store_object_to_index);
 204 
 205         /*
 206          * Destination must be a reference pointer, and
 207          * must point to either a buffer or a package
 208          */
 209         switch (index_desc->reference.target_type) {
 210         case ACPI_TYPE_PACKAGE:
 211                 /*
 212                  * Storing to a package element. Copy the object and replace
 213                  * any existing object with the new object. No implicit
 214                  * conversion is performed.
 215                  *
 216                  * The object at *(index_desc->Reference.Where) is the
 217                  * element within the package that is to be modified.
 218                  * The parent package object is at index_desc->Reference.Object
 219                  */
 220                 obj_desc = *(index_desc->reference.where);
 221 
 222                 if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
 223                     source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 224 
 225                         /* This is a DDBHandle, just add a reference to it */
 226 
 227                         acpi_ut_add_reference(source_desc);
 228                         new_desc = source_desc;
 229                 } else {
 230                         /* Normal object, copy it */
 231 
 232                         status =
 233                             acpi_ut_copy_iobject_to_iobject(source_desc,
 234                                                             &new_desc,
 235                                                             walk_state);
 236                         if (ACPI_FAILURE(status)) {
 237                                 return_ACPI_STATUS(status);
 238                         }
 239                 }
 240 
 241                 if (obj_desc) {
 242 
 243                         /* Decrement reference count by the ref count of the parent package */
 244 
 245                         for (i = 0; i < ((union acpi_operand_object *)
 246                                          index_desc->reference.object)->common.
 247                              reference_count; i++) {
 248                                 acpi_ut_remove_reference(obj_desc);
 249                         }
 250                 }
 251 
 252                 *(index_desc->reference.where) = new_desc;
 253 
 254                 /* Increment ref count by the ref count of the parent package-1 */
 255 
 256                 for (i = 1; i < ((union acpi_operand_object *)
 257                                  index_desc->reference.object)->common.
 258                      reference_count; i++) {
 259                         acpi_ut_add_reference(new_desc);
 260                 }
 261 
 262                 break;
 263 
 264         case ACPI_TYPE_BUFFER_FIELD:
 265                 /*
 266                  * Store into a Buffer or String (not actually a real buffer_field)
 267                  * at a location defined by an Index.
 268                  *
 269                  * The first 8-bit element of the source object is written to the
 270                  * 8-bit Buffer location defined by the Index destination object,
 271                  * according to the ACPI 2.0 specification.
 272                  */
 273 
 274                 /*
 275                  * Make sure the target is a Buffer or String. An error should
 276                  * not happen here, since the reference_object was constructed
 277                  * by the INDEX_OP code.
 278                  */
 279                 obj_desc = index_desc->reference.object;
 280                 if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
 281                     (obj_desc->common.type != ACPI_TYPE_STRING)) {
 282                         return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 283                 }
 284 
 285                 /*
 286                  * The assignment of the individual elements will be slightly
 287                  * different for each source type.
 288                  */
 289                 switch (source_desc->common.type) {
 290                 case ACPI_TYPE_INTEGER:
 291 
 292                         /* Use the least-significant byte of the integer */
 293 
 294                         value = (u8) (source_desc->integer.value);
 295                         break;
 296 
 297                 case ACPI_TYPE_BUFFER:
 298                 case ACPI_TYPE_STRING:
 299 
 300                         /* Note: Takes advantage of common string/buffer fields */
 301 
 302                         value = source_desc->buffer.pointer[0];
 303                         break;
 304 
 305                 default:
 306 
 307                         /* All other types are invalid */
 308 
 309                         ACPI_ERROR((AE_INFO,
 310                                     "Source must be type [Integer/Buffer/String], found [%s]",
 311                                     acpi_ut_get_object_type_name(source_desc)));
 312                         return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 313                 }
 314 
 315                 /* Store the source value into the target buffer byte */
 316 
 317                 obj_desc->buffer.pointer[index_desc->reference.value] = value;
 318                 break;
 319 
 320         default:
 321                 ACPI_ERROR((AE_INFO,
 322                             "Target is not of type [Package/BufferField]"));
 323                 status = AE_AML_TARGET_TYPE;
 324                 break;
 325         }
 326 
 327         return_ACPI_STATUS(status);
 328 }
 329 
 330 /*******************************************************************************
 331  *
 332  * FUNCTION:    acpi_ex_store_object_to_node
 333  *
 334  * PARAMETERS:  source_desc             - Value to be stored
 335  *              node                    - Named object to receive the value
 336  *              walk_state              - Current walk state
 337  *              implicit_conversion     - Perform implicit conversion (yes/no)
 338  *
 339  * RETURN:      Status
 340  *
 341  * DESCRIPTION: Store the object to the named object.
 342  *
 343  * The assignment of an object to a named object is handled here.
 344  * The value passed in will replace the current value (if any)
 345  * with the input value.
 346  *
 347  * When storing into an object the data is converted to the
 348  * target object type then stored in the object. This means
 349  * that the target object type (for an initialized target) will
 350  * not be changed by a store operation. A copy_object can change
 351  * the target type, however.
 352  *
 353  * The implicit_conversion flag is set to NO/FALSE only when
 354  * storing to an arg_x -- as per the rules of the ACPI spec.
 355  *
 356  * Assumes parameters are already validated.
 357  *
 358  ******************************************************************************/
 359 
 360 acpi_status
 361 acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
 362                              struct acpi_namespace_node *node,
 363                              struct acpi_walk_state *walk_state,
 364                              u8 implicit_conversion)
 365 {
 366         acpi_status status = AE_OK;
 367         union acpi_operand_object *target_desc;
 368         union acpi_operand_object *new_desc;
 369         acpi_object_type target_type;
 370 
 371         ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
 372 
 373         /* Get current type of the node, and object attached to Node */
 374 
 375         target_type = acpi_ns_get_type(node);
 376         target_desc = acpi_ns_get_attached_object(node);
 377 
 378         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
 379                           source_desc,
 380                           acpi_ut_get_object_type_name(source_desc), node,
 381                           acpi_ut_get_type_name(target_type)));
 382 
 383         /* Only limited target types possible for everything except copy_object */
 384 
 385         if (walk_state->opcode != AML_COPY_OBJECT_OP) {
 386                 /*
 387                  * Only copy_object allows all object types to be overwritten. For
 388                  * target_ref(s), there are restrictions on the object types that
 389                  * are allowed.
 390                  *
 391                  * Allowable operations/typing for Store:
 392                  *
 393                  * 1) Simple Store
 394                  *      Integer     --> Integer (Named/Local/Arg)
 395                  *      String      --> String  (Named/Local/Arg)
 396                  *      Buffer      --> Buffer  (Named/Local/Arg)
 397                  *      Package     --> Package (Named/Local/Arg)
 398                  *
 399                  * 2) Store with implicit conversion
 400                  *      Integer     --> String or Buffer  (Named)
 401                  *      String      --> Integer or Buffer (Named)
 402                  *      Buffer      --> Integer or String (Named)
 403                  */
 404                 switch (target_type) {
 405                 case ACPI_TYPE_PACKAGE:
 406                         /*
 407                          * Here, can only store a package to an existing package.
 408                          * Storing a package to a Local/Arg is OK, and handled
 409                          * elsewhere.
 410                          */
 411                         if (walk_state->opcode == AML_STORE_OP) {
 412                                 if (source_desc->common.type !=
 413                                     ACPI_TYPE_PACKAGE) {
 414                                         ACPI_ERROR((AE_INFO,
 415                                                     "Cannot assign type [%s] to [Package] "
 416                                                     "(source must be type Pkg)",
 417                                                     acpi_ut_get_object_type_name
 418                                                     (source_desc)));
 419 
 420                                         return_ACPI_STATUS(AE_AML_TARGET_TYPE);
 421                                 }
 422                                 break;
 423                         }
 424 
 425                         /* Fallthrough */
 426 
 427                 case ACPI_TYPE_DEVICE:
 428                 case ACPI_TYPE_EVENT:
 429                 case ACPI_TYPE_MUTEX:
 430                 case ACPI_TYPE_REGION:
 431                 case ACPI_TYPE_POWER:
 432                 case ACPI_TYPE_PROCESSOR:
 433                 case ACPI_TYPE_THERMAL:
 434 
 435                         ACPI_ERROR((AE_INFO,
 436                                     "Target must be [Buffer/Integer/String/Reference]"
 437                                     ", found [%s] (%4.4s)",
 438                                     acpi_ut_get_type_name(node->type),
 439                                     node->name.ascii));
 440 
 441                         return_ACPI_STATUS(AE_AML_TARGET_TYPE);
 442 
 443                 default:
 444                         break;
 445                 }
 446         }
 447 
 448         /*
 449          * Resolve the source object to an actual value
 450          * (If it is a reference object)
 451          */
 452         status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
 453         if (ACPI_FAILURE(status)) {
 454                 return_ACPI_STATUS(status);
 455         }
 456 
 457         /* Do the actual store operation */
 458 
 459         switch (target_type) {
 460                 /*
 461                  * The simple data types all support implicit source operand
 462                  * conversion before the store.
 463                  */
 464         case ACPI_TYPE_INTEGER:
 465         case ACPI_TYPE_STRING:
 466         case ACPI_TYPE_BUFFER:
 467 
 468                 if ((walk_state->opcode == AML_COPY_OBJECT_OP) ||
 469                     !implicit_conversion) {
 470                         /*
 471                          * However, copy_object and Stores to arg_x do not perform
 472                          * an implicit conversion, as per the ACPI specification.
 473                          * A direct store is performed instead.
 474                          */
 475                         status =
 476                             acpi_ex_store_direct_to_node(source_desc, node,
 477                                                          walk_state);
 478                         break;
 479                 }
 480 
 481                 /* Store with implicit source operand conversion support */
 482 
 483                 status =
 484                     acpi_ex_store_object_to_object(source_desc, target_desc,
 485                                                    &new_desc, walk_state);
 486                 if (ACPI_FAILURE(status)) {
 487                         return_ACPI_STATUS(status);
 488                 }
 489 
 490                 if (new_desc != target_desc) {
 491                         /*
 492                          * Store the new new_desc as the new value of the Name, and set
 493                          * the Name's type to that of the value being stored in it.
 494                          * source_desc reference count is incremented by attach_object.
 495                          *
 496                          * Note: This may change the type of the node if an explicit
 497                          * store has been performed such that the node/object type
 498                          * has been changed.
 499                          */
 500                         status =
 501                             acpi_ns_attach_object(node, new_desc,
 502                                                   new_desc->common.type);
 503 
 504                         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 505                                           "Store type [%s] into [%s] via Convert/Attach\n",
 506                                           acpi_ut_get_object_type_name
 507                                           (source_desc),
 508                                           acpi_ut_get_object_type_name
 509                                           (new_desc)));
 510                 }
 511                 break;
 512 
 513         case ACPI_TYPE_BUFFER_FIELD:
 514         case ACPI_TYPE_LOCAL_REGION_FIELD:
 515         case ACPI_TYPE_LOCAL_BANK_FIELD:
 516         case ACPI_TYPE_LOCAL_INDEX_FIELD:
 517                 /*
 518                  * For all fields, always write the source data to the target
 519                  * field. Any required implicit source operand conversion is
 520                  * performed in the function below as necessary. Note, field
 521                  * objects must retain their original type permanently.
 522                  */
 523                 status = acpi_ex_write_data_to_field(source_desc, target_desc,
 524                                                      &walk_state->result_obj);
 525                 break;
 526 
 527         default:
 528                 /*
 529                  * copy_object operator: No conversions for all other types.
 530                  * Instead, directly store a copy of the source object.
 531                  *
 532                  * This is the ACPI spec-defined behavior for the copy_object
 533                  * operator. (Note, for this default case, all normal
 534                  * Store/Target operations exited above with an error).
 535                  */
 536                 status =
 537                     acpi_ex_store_direct_to_node(source_desc, node, walk_state);
 538                 break;
 539         }
 540 
 541         return_ACPI_STATUS(status);
 542 }
 543 
 544 /*******************************************************************************
 545  *
 546  * FUNCTION:    acpi_ex_store_direct_to_node
 547  *
 548  * PARAMETERS:  source_desc             - Value to be stored
 549  *              node                    - Named object to receive the value
 550  *              walk_state              - Current walk state
 551  *
 552  * RETURN:      Status
 553  *
 554  * DESCRIPTION: "Store" an object directly to a node. This involves a copy
 555  *              and an attach.
 556  *
 557  ******************************************************************************/
 558 
 559 static acpi_status
 560 acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
 561                              struct acpi_namespace_node *node,
 562                              struct acpi_walk_state *walk_state)
 563 {
 564         acpi_status status;
 565         union acpi_operand_object *new_desc;
 566 
 567         ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
 568 
 569         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 570                           "Storing [%s] (%p) directly into node [%s] (%p)"
 571                           " with no implicit conversion\n",
 572                           acpi_ut_get_object_type_name(source_desc),
 573                           source_desc, acpi_ut_get_type_name(node->type),
 574                           node));
 575 
 576         /* Copy the source object to a new object */
 577 
 578         status =
 579             acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
 580         if (ACPI_FAILURE(status)) {
 581                 return_ACPI_STATUS(status);
 582         }
 583 
 584         /* Attach the new object to the node */
 585 
 586         status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
 587         acpi_ut_remove_reference(new_desc);
 588         return_ACPI_STATUS(status);
 589 }

/* [<][>][^][v][top][bottom][index][help] */