exstore.c revision 102550
138032Speter 238032Speter/****************************************************************************** 364562Sgshapiro * 464562Sgshapiro * Module Name: exstore - AML Interpreter object store support 538032Speter * $Revision: 169 $ 638032Speter * 738032Speter *****************************************************************************/ 838032Speter 938032Speter/****************************************************************************** 1038032Speter * 1138032Speter * 1. Copyright Notice 1238032Speter * 1338032Speter * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 1438032Speter * All rights reserved. 1538032Speter * 1638032Speter * 2. License 1738032Speter * 1838032Speter * 2.1. This is your license from Intel Corp. under its intellectual property 1998121Sgshapiro * rights. You may have additional license terms from the party that provided 2038032Speter * you this software, covering your right to use that party's intellectual 2138032Speter * property rights. 2238032Speter * 2338032Speter * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2438032Speter * copy of the source code appearing in this file ("Covered Code") an 2538032Speter * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118#define __EXSTORE_C__ 119 120#include "acpi.h" 121#include "acdispat.h" 122#include "acinterp.h" 123#include "amlcode.h" 124#include "acnamesp.h" 125 126 127#define _COMPONENT ACPI_EXECUTER 128 ACPI_MODULE_NAME ("exstore") 129 130 131/******************************************************************************* 132 * 133 * FUNCTION: AcpiExStore 134 * 135 * PARAMETERS: *SourceDesc - Value to be stored 136 * *DestDesc - Where to store it. Must be an NS node 137 * or an ACPI_OPERAND_OBJECT of type 138 * Reference; 139 * WalkState - Current walk state 140 * 141 * RETURN: Status 142 * 143 * DESCRIPTION: Store the value described by SourceDesc into the location 144 * described by DestDesc. Called by various interpreter 145 * functions to store the result of an operation into 146 * the destination operand -- not just simply the actual "Store" 147 * ASL operator. 148 * 149 ******************************************************************************/ 150 151ACPI_STATUS 152AcpiExStore ( 153 ACPI_OPERAND_OBJECT *SourceDesc, 154 ACPI_OPERAND_OBJECT *DestDesc, 155 ACPI_WALK_STATE *WalkState) 156{ 157 ACPI_STATUS Status = AE_OK; 158 ACPI_OPERAND_OBJECT *RefDesc = DestDesc; 159 160 161 ACPI_FUNCTION_TRACE_PTR ("ExStore", DestDesc); 162 163 164 /* Validate parameters */ 165 166 if (!SourceDesc || !DestDesc) 167 { 168 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null parameter\n")); 169 return_ACPI_STATUS (AE_AML_NO_OPERAND); 170 } 171 172 /* DestDesc can be either a namespace node or an ACPI object */ 173 174 if (ACPI_GET_DESCRIPTOR_TYPE (DestDesc) == ACPI_DESC_TYPE_NAMED) 175 { 176 /* 177 * Dest is a namespace node, 178 * Storing an object into a Name "container" 179 */ 180 Status = AcpiExStoreObjectToNode (SourceDesc, 181 (ACPI_NAMESPACE_NODE *) DestDesc, WalkState); 182 183 return_ACPI_STATUS (Status); 184 } 185 186 /* Destination object must be a Reference or a Constant object */ 187 188 switch (ACPI_GET_OBJECT_TYPE (DestDesc)) 189 { 190 case INTERNAL_TYPE_REFERENCE: 191 break; 192 193 case ACPI_TYPE_INTEGER: 194 195 /* Allow stores to Constants -- a Noop as per ACPI spec */ 196 197 if (DestDesc->Common.Flags & AOPOBJ_AML_CONSTANT) 198 { 199 return_ACPI_STATUS (AE_OK); 200 } 201 202 /*lint: -fallthrough */ 203 204 default: 205 206 /* Destination is not an Reference */ 207 208 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 209 "Destination is not a Reference or Constant object [%p]\n", DestDesc)); 210 211 ACPI_DUMP_STACK_ENTRY (SourceDesc); 212 ACPI_DUMP_STACK_ENTRY (DestDesc); 213 ACPI_DUMP_OPERANDS (&DestDesc, ACPI_IMODE_EXECUTE, "ExStore", 214 2, "Target is not a Reference or Constant object"); 215 216 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 217 } 218 219 /* 220 * Examine the Reference opcode. These cases are handled: 221 * 222 * 1) Store to Name (Change the object associated with a name) 223 * 2) Store to an indexed area of a Buffer or Package 224 * 3) Store to a Method Local or Arg 225 * 4) Store to the debug object 226 */ 227 switch (RefDesc->Reference.Opcode) 228 { 229 case AML_NAME_OP: 230 case AML_REF_OF_OP: 231 232 /* Storing an object into a Name "container" */ 233 234 Status = AcpiExStoreObjectToNode (SourceDesc, RefDesc->Reference.Object, 235 WalkState); 236 break; 237 238 239 case AML_INDEX_OP: 240 241 /* Storing to an Index (pointer into a packager or buffer) */ 242 243 Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState); 244 break; 245 246 247 case AML_LOCAL_OP: 248 case AML_ARG_OP: 249 250 /* Store to a method local/arg */ 251 252 Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Opcode, 253 RefDesc->Reference.Offset, SourceDesc, WalkState); 254 break; 255 256 257 case AML_DEBUG_OP: 258 259 /* 260 * Storing to the Debug object causes the value stored to be 261 * displayed and otherwise has no effect -- see ACPI Specification 262 */ 263 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Write to Debug Object: ****:\n\n")); 264 265 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ", 266 AcpiUtGetObjectTypeName (SourceDesc))); 267 268 switch (ACPI_GET_OBJECT_TYPE (SourceDesc)) 269 { 270 case ACPI_TYPE_INTEGER: 271 272 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%8.8X%8.8X\n", 273 ACPI_HIWORD (SourceDesc->Integer.Value), 274 ACPI_LOWORD (SourceDesc->Integer.Value))); 275 break; 276 277 278 case ACPI_TYPE_BUFFER: 279 280 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length %.2X\n", 281 (UINT32) SourceDesc->Buffer.Length)); 282 break; 283 284 285 case ACPI_TYPE_STRING: 286 287 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s\n", SourceDesc->String.Pointer)); 288 break; 289 290 291 case ACPI_TYPE_PACKAGE: 292 293 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements Ptr - %p\n", 294 SourceDesc->Package.Elements)); 295 break; 296 297 298 default: 299 300 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Type %s %p\n", 301 AcpiUtGetObjectTypeName (SourceDesc), SourceDesc)); 302 break; 303 } 304 305 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n")); 306 break; 307 308 309 default: 310 311 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X\n", 312 RefDesc->Reference.Opcode)); 313 ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_ERROR); 314 315 Status = AE_AML_INTERNAL; 316 break; 317 } 318 319 return_ACPI_STATUS (Status); 320} 321 322 323/******************************************************************************* 324 * 325 * FUNCTION: AcpiExStoreObjectToIndex 326 * 327 * PARAMETERS: *SourceDesc - Value to be stored 328 * *DestDesc - Named object to receive the value 329 * WalkState - Current walk state 330 * 331 * RETURN: Status 332 * 333 * DESCRIPTION: Store the object to indexed Buffer or Package element 334 * 335 ******************************************************************************/ 336 337ACPI_STATUS 338AcpiExStoreObjectToIndex ( 339 ACPI_OPERAND_OBJECT *SourceDesc, 340 ACPI_OPERAND_OBJECT *IndexDesc, 341 ACPI_WALK_STATE *WalkState) 342{ 343 ACPI_STATUS Status = AE_OK; 344 ACPI_OPERAND_OBJECT *ObjDesc; 345 ACPI_OPERAND_OBJECT *NewDesc; 346 UINT8 Value = 0; 347 348 349 ACPI_FUNCTION_TRACE ("ExStoreObjectToIndex"); 350 351 352 /* 353 * Destination must be a reference pointer, and 354 * must point to either a buffer or a package 355 */ 356 switch (IndexDesc->Reference.TargetType) 357 { 358 case ACPI_TYPE_PACKAGE: 359 /* 360 * Storing to a package element is not simple. The source must be 361 * evaluated and converted to the type of the destination and then the 362 * source is copied into the destination - we can't just point to the 363 * source object. 364 */ 365 /* 366 * The object at *(IndexDesc->Reference.Where) is the 367 * element within the package that is to be modified. 368 */ 369 ObjDesc = *(IndexDesc->Reference.Where); 370 371 /* Do the conversion/store */ 372 373 Status = AcpiExStoreObjectToObject (SourceDesc, ObjDesc, &NewDesc, 374 WalkState); 375 if (ACPI_FAILURE (Status)) 376 { 377 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 378 "Could not store object to indexed package element\n")); 379 return_ACPI_STATUS (Status); 380 } 381 382 /* 383 * If a new object was created, we must install it as the new 384 * package element 385 */ 386 if (NewDesc != ObjDesc) 387 { 388 AcpiUtRemoveReference (ObjDesc); 389 *(IndexDesc->Reference.Where) = NewDesc; 390 } 391 break; 392 393 394 case ACPI_TYPE_BUFFER_FIELD: 395 396 /* 397 * Store into a Buffer (not actually a real BufferField) at a 398 * location defined by an Index. 399 * 400 * The first 8-bit element of the source object is written to the 401 * 8-bit Buffer location defined by the Index destination object, 402 * according to the ACPI 2.0 specification. 403 */ 404 405 /* 406 * Make sure the target is a Buffer 407 */ 408 ObjDesc = IndexDesc->Reference.Object; 409 if (ACPI_GET_OBJECT_TYPE (ObjDesc) != ACPI_TYPE_BUFFER) 410 { 411 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 412 } 413 414 /* 415 * The assignment of the individual elements will be slightly 416 * different for each source type. 417 */ 418 switch (ACPI_GET_OBJECT_TYPE (SourceDesc)) 419 { 420 case ACPI_TYPE_INTEGER: 421 422 /* Use the least-significant byte of the integer */ 423 424 Value = (UINT8) (SourceDesc->Integer.Value); 425 break; 426 427 case ACPI_TYPE_BUFFER: 428 429 Value = SourceDesc->Buffer.Pointer[0]; 430 break; 431 432 case ACPI_TYPE_STRING: 433 434 Value = (UINT8) SourceDesc->String.Pointer[0]; 435 break; 436 437 default: 438 439 /* All other types are invalid */ 440 441 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 442 "Source must be Integer/Buffer/String type, not %s\n", 443 AcpiUtGetObjectTypeName (SourceDesc))); 444 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 445 } 446 447 /* Store the source value into the target buffer byte */ 448 449 ObjDesc->Buffer.Pointer[IndexDesc->Reference.Offset] = Value; 450 break; 451 452 453 default: 454 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 455 "Target is not a Package or BufferField\n")); 456 Status = AE_AML_OPERAND_TYPE; 457 break; 458 } 459 460 return_ACPI_STATUS (Status); 461} 462 463 464/******************************************************************************* 465 * 466 * FUNCTION: AcpiExStoreObjectToNode 467 * 468 * PARAMETERS: SourceDesc - Value to be stored 469 * Node - Named object to receive the value 470 * WalkState - Current walk state 471 * 472 * RETURN: Status 473 * 474 * DESCRIPTION: Store the object to the named object. 475 * 476 * The Assignment of an object to a named object is handled here 477 * The value passed in will replace the current value (if any) 478 * with the input value. 479 * 480 * When storing into an object the data is converted to the 481 * target object type then stored in the object. This means 482 * that the target object type (for an initialized target) will 483 * not be changed by a store operation. 484 * 485 * Assumes parameters are already validated. 486 * 487 ******************************************************************************/ 488 489ACPI_STATUS 490AcpiExStoreObjectToNode ( 491 ACPI_OPERAND_OBJECT *SourceDesc, 492 ACPI_NAMESPACE_NODE *Node, 493 ACPI_WALK_STATE *WalkState) 494{ 495 ACPI_STATUS Status = AE_OK; 496 ACPI_OPERAND_OBJECT *TargetDesc; 497 ACPI_OPERAND_OBJECT *NewDesc; 498 ACPI_OBJECT_TYPE TargetType; 499 500 501 ACPI_FUNCTION_TRACE_PTR ("ExStoreObjectToNode", SourceDesc); 502 503 504 /* 505 * Get current type of the node, and object attached to Node 506 */ 507 TargetType = AcpiNsGetType (Node); 508 TargetDesc = AcpiNsGetAttachedObject (Node); 509 510 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", 511 SourceDesc, AcpiUtGetObjectTypeName (SourceDesc), 512 Node, AcpiUtGetTypeName (TargetType))); 513 514 /* 515 * Resolve the source object to an actual value 516 * (If it is a reference object) 517 */ 518 Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState); 519 if (ACPI_FAILURE (Status)) 520 { 521 return_ACPI_STATUS (Status); 522 } 523 524 /* 525 * Do the actual store operation 526 */ 527 switch (TargetType) 528 { 529 case ACPI_TYPE_BUFFER_FIELD: 530 case INTERNAL_TYPE_REGION_FIELD: 531 case INTERNAL_TYPE_BANK_FIELD: 532 case INTERNAL_TYPE_INDEX_FIELD: 533 534 /* 535 * For fields, copy the source data to the target field. 536 */ 537 Status = AcpiExWriteDataToField (SourceDesc, TargetDesc); 538 break; 539 540 541 case ACPI_TYPE_INTEGER: 542 case ACPI_TYPE_STRING: 543 case ACPI_TYPE_BUFFER: 544 545 /* 546 * These target types are all of type Integer/String/Buffer, and 547 * therefore support implicit conversion before the store. 548 * 549 * Copy and/or convert the source object to a new target object 550 */ 551 Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc, &NewDesc, WalkState); 552 if (ACPI_FAILURE (Status)) 553 { 554 return_ACPI_STATUS (Status); 555 } 556 557 if (NewDesc != TargetDesc) 558 { 559 /* 560 * Store the new NewDesc as the new value of the Name, and set 561 * the Name's type to that of the value being stored in it. 562 * SourceDesc reference count is incremented by AttachObject. 563 */ 564 Status = AcpiNsAttachObject (Node, NewDesc, TargetType); 565 566 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 567 "Store %s into %s via Convert/Attach\n", 568 AcpiUtGetObjectTypeName (SourceDesc), 569 AcpiUtGetObjectTypeName (NewDesc))); 570 } 571 break; 572 573 574 default: 575 576 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 577 "Storing %s (%p) directly into node (%p), no implicit conversion\n", 578 AcpiUtGetObjectTypeName (SourceDesc), SourceDesc, Node)); 579 580 /* No conversions for all other types. Just attach the source object */ 581 582 Status = AcpiNsAttachObject (Node, SourceDesc, ACPI_GET_OBJECT_TYPE (SourceDesc)); 583 break; 584 } 585 586 return_ACPI_STATUS (Status); 587} 588 589 590