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