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 - 2023, 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 ACPI_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 ACPI_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 } 590