1 /****************************************************************************** 2 * 3 * Module Name: exstore - AML Interpreter object store support 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acdispat.h" 47 #include "acinterp.h" 48 #include "amlcode.h" 49 #include "acnamesp.h" 50 51 #define _COMPONENT ACPI_EXECUTER 52 ACPI_MODULE_NAME("exstore") 53 54 /* Local prototypes */ 55 static acpi_status 56 acpi_ex_store_object_to_index(union acpi_operand_object *val_desc, 57 union acpi_operand_object *dest_desc, 58 struct acpi_walk_state *walk_state); 59 60 /******************************************************************************* 61 * 62 * FUNCTION: acpi_ex_store 63 * 64 * PARAMETERS: *source_desc - Value to be stored 65 * *dest_desc - Where to store it. Must be an NS node 66 * or union acpi_operand_object of type 67 * Reference; 68 * walk_state - Current walk state 69 * 70 * RETURN: Status 71 * 72 * DESCRIPTION: Store the value described by source_desc into the location 73 * described by dest_desc. Called by various interpreter 74 * functions to store the result of an operation into 75 * the destination operand -- not just simply the actual "Store" 76 * ASL operator. 77 * 78 ******************************************************************************/ 79 80 acpi_status 81 acpi_ex_store(union acpi_operand_object *source_desc, 82 union acpi_operand_object *dest_desc, 83 struct acpi_walk_state *walk_state) 84 { 85 acpi_status status = AE_OK; 86 union acpi_operand_object *ref_desc = dest_desc; 87 88 ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc); 89 90 /* Validate parameters */ 91 92 if (!source_desc || !dest_desc) { 93 ACPI_ERROR((AE_INFO, "Null parameter")); 94 return_ACPI_STATUS(AE_AML_NO_OPERAND); 95 } 96 97 /* dest_desc can be either a namespace node or an ACPI object */ 98 99 if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) { 100 /* 101 * Dest is a namespace node, 102 * Storing an object into a Named node. 103 */ 104 status = acpi_ex_store_object_to_node(source_desc, 105 (struct 106 acpi_namespace_node *) 107 dest_desc, walk_state, 108 ACPI_IMPLICIT_CONVERSION); 109 110 return_ACPI_STATUS(status); 111 } 112 113 /* Destination object must be a Reference or a Constant object */ 114 115 switch (dest_desc->common.type) { 116 case ACPI_TYPE_LOCAL_REFERENCE: 117 118 break; 119 120 case ACPI_TYPE_INTEGER: 121 122 /* Allow stores to Constants -- a Noop as per ACPI spec */ 123 124 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) { 125 return_ACPI_STATUS(AE_OK); 126 } 127 128 /*lint -fallthrough */ 129 130 default: 131 132 /* Destination is not a Reference object */ 133 134 ACPI_ERROR((AE_INFO, 135 "Target is not a Reference or Constant object - %s [%p]", 136 acpi_ut_get_object_type_name(dest_desc), 137 dest_desc)); 138 139 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 140 } 141 142 /* 143 * Examine the Reference class. These cases are handled: 144 * 145 * 1) Store to Name (Change the object associated with a name) 146 * 2) Store to an indexed area of a Buffer or Package 147 * 3) Store to a Method Local or Arg 148 * 4) Store to the debug object 149 */ 150 switch (ref_desc->reference.class) { 151 case ACPI_REFCLASS_REFOF: 152 153 /* Storing an object into a Name "container" */ 154 155 status = acpi_ex_store_object_to_node(source_desc, 156 ref_desc->reference. 157 object, walk_state, 158 ACPI_IMPLICIT_CONVERSION); 159 break; 160 161 case ACPI_REFCLASS_INDEX: 162 163 /* Storing to an Index (pointer into a packager or buffer) */ 164 165 status = 166 acpi_ex_store_object_to_index(source_desc, ref_desc, 167 walk_state); 168 break; 169 170 case ACPI_REFCLASS_LOCAL: 171 case ACPI_REFCLASS_ARG: 172 173 /* Store to a method local/arg */ 174 175 status = 176 acpi_ds_store_object_to_local(ref_desc->reference.class, 177 ref_desc->reference.value, 178 source_desc, walk_state); 179 break; 180 181 case ACPI_REFCLASS_DEBUG: 182 /* 183 * Storing to the Debug object causes the value stored to be 184 * displayed and otherwise has no effect -- see ACPI Specification 185 */ 186 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 187 "**** Write to Debug Object: Object %p %s ****:\n\n", 188 source_desc, 189 acpi_ut_get_object_type_name(source_desc))); 190 191 ACPI_DEBUG_OBJECT(source_desc, 0, 0); 192 break; 193 194 default: 195 196 ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X", 197 ref_desc->reference.class)); 198 ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO); 199 200 status = AE_AML_INTERNAL; 201 break; 202 } 203 204 return_ACPI_STATUS(status); 205 } 206 207 /******************************************************************************* 208 * 209 * FUNCTION: acpi_ex_store_object_to_index 210 * 211 * PARAMETERS: *source_desc - Value to be stored 212 * *dest_desc - Named object to receive the value 213 * walk_state - Current walk state 214 * 215 * RETURN: Status 216 * 217 * DESCRIPTION: Store the object to indexed Buffer or Package element 218 * 219 ******************************************************************************/ 220 221 static acpi_status 222 acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, 223 union acpi_operand_object *index_desc, 224 struct acpi_walk_state *walk_state) 225 { 226 acpi_status status = AE_OK; 227 union acpi_operand_object *obj_desc; 228 union acpi_operand_object *new_desc; 229 u8 value = 0; 230 u32 i; 231 232 ACPI_FUNCTION_TRACE(ex_store_object_to_index); 233 234 /* 235 * Destination must be a reference pointer, and 236 * must point to either a buffer or a package 237 */ 238 switch (index_desc->reference.target_type) { 239 case ACPI_TYPE_PACKAGE: 240 /* 241 * Storing to a package element. Copy the object and replace 242 * any existing object with the new object. No implicit 243 * conversion is performed. 244 * 245 * The object at *(index_desc->Reference.Where) is the 246 * element within the package that is to be modified. 247 * The parent package object is at index_desc->Reference.Object 248 */ 249 obj_desc = *(index_desc->reference.where); 250 251 if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE && 252 source_desc->reference.class == ACPI_REFCLASS_TABLE) { 253 254 /* This is a DDBHandle, just add a reference to it */ 255 256 acpi_ut_add_reference(source_desc); 257 new_desc = source_desc; 258 } else { 259 /* Normal object, copy it */ 260 261 status = 262 acpi_ut_copy_iobject_to_iobject(source_desc, 263 &new_desc, 264 walk_state); 265 if (ACPI_FAILURE(status)) { 266 return_ACPI_STATUS(status); 267 } 268 } 269 270 if (obj_desc) { 271 272 /* Decrement reference count by the ref count of the parent package */ 273 274 for (i = 0; i < ((union acpi_operand_object *) 275 index_desc->reference.object)->common. 276 reference_count; i++) { 277 acpi_ut_remove_reference(obj_desc); 278 } 279 } 280 281 *(index_desc->reference.where) = new_desc; 282 283 /* Increment ref count by the ref count of the parent package-1 */ 284 285 for (i = 1; i < ((union acpi_operand_object *) 286 index_desc->reference.object)->common. 287 reference_count; i++) { 288 acpi_ut_add_reference(new_desc); 289 } 290 291 break; 292 293 case ACPI_TYPE_BUFFER_FIELD: 294 /* 295 * Store into a Buffer or String (not actually a real buffer_field) 296 * at a location defined by an Index. 297 * 298 * The first 8-bit element of the source object is written to the 299 * 8-bit Buffer location defined by the Index destination object, 300 * according to the ACPI 2.0 specification. 301 */ 302 303 /* 304 * Make sure the target is a Buffer or String. An error should 305 * not happen here, since the reference_object was constructed 306 * by the INDEX_OP code. 307 */ 308 obj_desc = index_desc->reference.object; 309 if ((obj_desc->common.type != ACPI_TYPE_BUFFER) && 310 (obj_desc->common.type != ACPI_TYPE_STRING)) { 311 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 312 } 313 314 /* 315 * The assignment of the individual elements will be slightly 316 * different for each source type. 317 */ 318 switch (source_desc->common.type) { 319 case ACPI_TYPE_INTEGER: 320 321 /* Use the least-significant byte of the integer */ 322 323 value = (u8) (source_desc->integer.value); 324 break; 325 326 case ACPI_TYPE_BUFFER: 327 case ACPI_TYPE_STRING: 328 329 /* Note: Takes advantage of common string/buffer fields */ 330 331 value = source_desc->buffer.pointer[0]; 332 break; 333 334 default: 335 336 /* All other types are invalid */ 337 338 ACPI_ERROR((AE_INFO, 339 "Source must be Integer/Buffer/String type, not %s", 340 acpi_ut_get_object_type_name(source_desc))); 341 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 342 } 343 344 /* Store the source value into the target buffer byte */ 345 346 obj_desc->buffer.pointer[index_desc->reference.value] = value; 347 break; 348 349 default: 350 ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField")); 351 status = AE_AML_OPERAND_TYPE; 352 break; 353 } 354 355 return_ACPI_STATUS(status); 356 } 357 358 /******************************************************************************* 359 * 360 * FUNCTION: acpi_ex_store_object_to_node 361 * 362 * PARAMETERS: source_desc - Value to be stored 363 * node - Named object to receive the value 364 * walk_state - Current walk state 365 * implicit_conversion - Perform implicit conversion (yes/no) 366 * 367 * RETURN: Status 368 * 369 * DESCRIPTION: Store the object to the named object. 370 * 371 * The Assignment of an object to a named object is handled here 372 * The value passed in will replace the current value (if any) 373 * with the input value. 374 * 375 * When storing into an object the data is converted to the 376 * target object type then stored in the object. This means 377 * that the target object type (for an initialized target) will 378 * not be changed by a store operation. 379 * 380 * Assumes parameters are already validated. 381 * 382 ******************************************************************************/ 383 384 acpi_status 385 acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, 386 struct acpi_namespace_node *node, 387 struct acpi_walk_state *walk_state, 388 u8 implicit_conversion) 389 { 390 acpi_status status = AE_OK; 391 union acpi_operand_object *target_desc; 392 union acpi_operand_object *new_desc; 393 acpi_object_type target_type; 394 395 ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc); 396 397 /* Get current type of the node, and object attached to Node */ 398 399 target_type = acpi_ns_get_type(node); 400 target_desc = acpi_ns_get_attached_object(node); 401 402 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", 403 source_desc, 404 acpi_ut_get_object_type_name(source_desc), node, 405 acpi_ut_get_type_name(target_type))); 406 407 /* 408 * Resolve the source object to an actual value 409 * (If it is a reference object) 410 */ 411 status = acpi_ex_resolve_object(&source_desc, target_type, walk_state); 412 if (ACPI_FAILURE(status)) { 413 return_ACPI_STATUS(status); 414 } 415 416 /* If no implicit conversion, drop into the default case below */ 417 418 if ((!implicit_conversion) || 419 ((walk_state->opcode == AML_COPY_OP) && 420 (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) && 421 (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) && 422 (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) { 423 /* 424 * Force execution of default (no implicit conversion). Note: 425 * copy_object does not perform an implicit conversion, as per the ACPI 426 * spec -- except in case of region/bank/index fields -- because these 427 * objects must retain their original type permanently. 428 */ 429 target_type = ACPI_TYPE_ANY; 430 } 431 432 /* Do the actual store operation */ 433 434 switch (target_type) { 435 case ACPI_TYPE_BUFFER_FIELD: 436 case ACPI_TYPE_LOCAL_REGION_FIELD: 437 case ACPI_TYPE_LOCAL_BANK_FIELD: 438 case ACPI_TYPE_LOCAL_INDEX_FIELD: 439 440 /* For fields, copy the source data to the target field. */ 441 442 status = acpi_ex_write_data_to_field(source_desc, target_desc, 443 &walk_state->result_obj); 444 break; 445 446 case ACPI_TYPE_INTEGER: 447 case ACPI_TYPE_STRING: 448 case ACPI_TYPE_BUFFER: 449 /* 450 * These target types are all of type Integer/String/Buffer, and 451 * therefore support implicit conversion before the store. 452 * 453 * Copy and/or convert the source object to a new target object 454 */ 455 status = 456 acpi_ex_store_object_to_object(source_desc, target_desc, 457 &new_desc, walk_state); 458 if (ACPI_FAILURE(status)) { 459 return_ACPI_STATUS(status); 460 } 461 462 if (new_desc != target_desc) { 463 /* 464 * Store the new new_desc as the new value of the Name, and set 465 * the Name's type to that of the value being stored in it. 466 * source_desc reference count is incremented by attach_object. 467 * 468 * Note: This may change the type of the node if an explicit store 469 * has been performed such that the node/object type has been 470 * changed. 471 */ 472 status = 473 acpi_ns_attach_object(node, new_desc, 474 new_desc->common.type); 475 476 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 477 "Store %s into %s via Convert/Attach\n", 478 acpi_ut_get_object_type_name 479 (source_desc), 480 acpi_ut_get_object_type_name 481 (new_desc))); 482 } 483 break; 484 485 default: 486 487 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 488 "Storing [%s] (%p) directly into node [%s] (%p)" 489 " with no implicit conversion\n", 490 acpi_ut_get_object_type_name(source_desc), 491 source_desc, 492 acpi_ut_get_object_type_name(target_desc), 493 node)); 494 495 /* 496 * No conversions for all other types. Directly store a copy of 497 * the source object. NOTE: This is a departure from the ACPI 498 * spec, which states "If conversion is impossible, abort the 499 * running control method". 500 * 501 * This code implements "If conversion is impossible, treat the 502 * Store operation as a CopyObject". 503 */ 504 status = 505 acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, 506 walk_state); 507 if (ACPI_FAILURE(status)) { 508 return_ACPI_STATUS(status); 509 } 510 511 status = 512 acpi_ns_attach_object(node, new_desc, 513 new_desc->common.type); 514 acpi_ut_remove_reference(new_desc); 515 break; 516 } 517 518 return_ACPI_STATUS(status); 519 } 520