exstore.c revision 70243
12786Ssos 22786Ssos/****************************************************************************** 32786Ssos * 42786Ssos * Module Name: amstore - AML Interpreter object store support 52786Ssos * $Revision: 118 $ 62786Ssos * 72786Ssos *****************************************************************************/ 82786Ssos 92786Ssos/****************************************************************************** 102786Ssos * 112786Ssos * 1. Copyright Notice 122786Ssos * 132786Ssos * Some or all of this work - Copyright (c) 1999, 2000, Intel Corp. 142786Ssos * All rights reserved. 152786Ssos * 162786Ssos * 2. License 172786Ssos * 182786Ssos * 2.1. This is your license from Intel Corp. under its intellectual property 192786Ssos * rights. You may have additional license terms from the party that provided 202786Ssos * you this software, covering your right to use that party's intellectual 212786Ssos * property rights. 222786Ssos * 232786Ssos * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 242786Ssos * copy of the source code appearing in this file ("Covered Code") an 252786Ssos * irrevocable, perpetual, worldwide license under Intel's copyrights in the 262786Ssos * base code distributed originally by Intel ("Original Intel Code") to copy, 272786Ssos * make derivatives, distribute, use and display any portion of the Covered 282786Ssos * Code in any form, with the right to sublicense such rights; and 292786Ssos * 302786Ssos * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 312786Ssos * license (with the right to sublicense), under only those claims of Intel 322786Ssos * patents that are infringed by the Original Intel Code, to make, use, sell, 332786Ssos * offer to sell, and import the Covered Code and derivative works thereof 342786Ssos * solely to the minimum extent necessary to exercise the above copyright 352786Ssos * license, and in no event shall the patent license extend to any additions 362786Ssos * to or modifications of the Original Intel Code. No other license or right 372786Ssos * is granted directly or by implication, estoppel or otherwise; 382786Ssos * 392786Ssos * The above copyright and patent license is granted only if the following 402786Ssos * conditions are met: 412786Ssos * 422786Ssos * 3. Conditions 432786Ssos * 442786Ssos * 3.1. Redistribution of Source with Rights to Further Distribute Source. 452786Ssos * Redistribution of source code of any substantial portion of the Covered 462786Ssos * Code or modification with rights to further distribute source must include 472786Ssos * the above Copyright Notice, the above License, this list of Conditions, 482786Ssos * and the following Disclaimer and Export Compliance provision. In addition, 492786Ssos * Licensee must cause all Covered Code to which Licensee contributes to 502786Ssos * contain a file documenting the changes Licensee made to create that Covered 512786Ssos * Code and the date of any change. Licensee must include in that file the 522786Ssos * documentation of any changes made by any predecessor Licensee. Licensee 532786Ssos * must include a prominent statement that the modification is derived, 542786Ssos * directly or indirectly, from Original Intel Code. 552786Ssos * 562786Ssos * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 572786Ssos * Redistribution of source code of any substantial portion of the Covered 582786Ssos * Code or modification without rights to further distribute source must 592786Ssos * include the following Disclaimer and Export Compliance provision in the 602786Ssos * documentation and/or other materials provided with distribution. In 612786Ssos * addition, Licensee may not authorize further sublicense of source of any 622786Ssos * portion of the Covered Code, and must include terms to the effect that the 632786Ssos * license from Licensee to its licensee is limited to the intellectual 642786Ssos * property embodied in the software Licensee provides to its licensee, and 652786Ssos * not to intellectual property embodied in modifications its licensee may 662786Ssos * make. 672786Ssos * 682786Ssos * 3.3. Redistribution of Executable. Redistribution in executable form of any 692786Ssos * substantial portion of the Covered Code or modification must reproduce the 702786Ssos * above Copyright Notice, and the following Disclaimer and Export Compliance 712786Ssos * provision in the documentation and/or other materials provided with the 722786Ssos * distribution. 732786Ssos * 742786Ssos * 3.4. Intel retains all right, title, and interest in and to the Original 752786Ssos * Intel Code. 762786Ssos * 772786Ssos * 3.5. Neither the name Intel nor any other trademark owned or controlled by 782786Ssos * Intel shall be used in advertising or otherwise to promote the sale, use or 792786Ssos * other dealings in products derived from or relating to the Covered Code 802786Ssos * without prior written authorization from Intel. 815994Ssos * 822786Ssos * 4. Disclaimer and Export Compliance 832786Ssos * 842786Ssos * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 852786Ssos * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 862786Ssos * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 872786Ssos * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 885994Ssos * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 892786Ssos * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 902786Ssos * PARTICULAR PURPOSE. 912786Ssos * 922786Ssos * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 932786Ssos * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 942786Ssos * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 952786Ssos * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 962786Ssos * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 972786Ssos * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 982786Ssos * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 992786Ssos * LIMITED REMEDY. 1002786Ssos * 1012786Ssos * 4.3. Licensee shall not export, either directly or indirectly, any of this 1022786Ssos * software or system incorporating such software without first obtaining any 1032786Ssos * required license or other approval from the U. S. Department of Commerce or 1042786Ssos * any other agency or department of the United States Government. In the 1052786Ssos * event Licensee exports any such software from the United States or 1062786Ssos * re-exports any such software from a foreign destination, Licensee shall 1072786Ssos * ensure that the distribution and export/re-export of the software is in 1085994Ssos * compliance with all laws, regulations, orders, or other restrictions of the 1092786Ssos * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1105994Ssos * any of its subsidiaries will export/re-export any technical data, process, 1115994Ssos * software, or service, directly or indirectly, to any country for which the 1125994Ssos * 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 __AMSTORE_C__ 119 120#include "acpi.h" 121#include "acparser.h" 122#include "acdispat.h" 123#include "acinterp.h" 124#include "amlcode.h" 125#include "acnamesp.h" 126#include "actables.h" 127 128 129#define _COMPONENT INTERPRETER 130 MODULE_NAME ("amstore") 131 132 133/******************************************************************************* 134 * 135 * FUNCTION: AcpiAmlExecStore 136 * 137 * PARAMETERS: *ValDesc - Value to be stored 138 * *DestDesc - Where to store it 0 Must be (ACPI_HANDLE) 139 * or an ACPI_OPERAND_OBJECT of type 140 * Reference; if the latter the descriptor 141 * will be either reused or deleted. 142 * 143 * RETURN: Status 144 * 145 * DESCRIPTION: Store the value described by ValDesc into the location 146 * described by DestDesc. Called by various interpreter 147 * functions to store the result of an operation into 148 * the destination operand. 149 * 150 ******************************************************************************/ 151 152ACPI_STATUS 153AcpiAmlExecStore ( 154 ACPI_OPERAND_OBJECT *ValDesc, 155 ACPI_OPERAND_OBJECT *DestDesc, 156 ACPI_WALK_STATE *WalkState) 157{ 158 ACPI_STATUS Status = AE_OK; 159 ACPI_OPERAND_OBJECT *DeleteDestDesc = NULL; 160 ACPI_OPERAND_OBJECT *TmpDesc; 161 ACPI_NAMESPACE_NODE *Node = NULL; 162 UINT8 Value = 0; 163 UINT32 Length; 164 UINT32 i; 165 166 167 FUNCTION_TRACE ("AmlExecStore"); 168 169 DEBUG_PRINT (ACPI_INFO, ("entered AcpiAmlExecStore: Val=%p, Dest=%p\n", 170 ValDesc, DestDesc)); 171 172 173 /* Validate parameters */ 174 175 if (!ValDesc || !DestDesc) 176 { 177 DEBUG_PRINT (ACPI_ERROR, 178 ("AmlExecStore: Internal error - null pointer\n")); 179 return_ACPI_STATUS (AE_AML_NO_OPERAND); 180 } 181 182 /* Examine the datatype of the DestDesc */ 183 184 if (VALID_DESCRIPTOR_TYPE (DestDesc, ACPI_DESC_TYPE_NAMED)) 185 { 186 /* Dest is an ACPI_HANDLE, create a new object */ 187 188 Node = (ACPI_NAMESPACE_NODE *) DestDesc; 189 DestDesc = AcpiCmCreateInternalObject (INTERNAL_TYPE_REFERENCE); 190 if (!DestDesc) 191 { 192 /* Allocation failure */ 193 194 return_ACPI_STATUS (AE_NO_MEMORY); 195 } 196 197 /* Build a new Reference wrapper around the handle */ 198 199 DestDesc->Reference.OpCode = AML_NAME_OP; 200 DestDesc->Reference.Object = Node; 201 } 202 203 else 204 { 205 DEBUG_PRINT (ACPI_INFO, 206 ("AmlExecStore: Dest is object (not handle) - may be deleted!\n")); 207 } 208 209 /* Destination object must be of type Reference */ 210 211 if (DestDesc->Common.Type != INTERNAL_TYPE_REFERENCE) 212 { 213 /* Destination is not an Reference */ 214 215 DEBUG_PRINT (ACPI_ERROR, 216 ("AmlExecStore: Destination is not an Reference [%p]\n", DestDesc)); 217 218 DUMP_STACK_ENTRY (ValDesc); 219 DUMP_STACK_ENTRY (DestDesc); 220 DUMP_OPERANDS (&DestDesc, IMODE_EXECUTE, "AmlExecStore", 221 2, "target not Reference"); 222 223 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 224 } 225 226 /* Examine the Reference opcode */ 227 228 switch (DestDesc->Reference.OpCode) 229 { 230 231 case AML_NAME_OP: 232 233 /* 234 * Storing into a Name 235 */ 236 DeleteDestDesc = DestDesc; 237 Status = AcpiAmlStoreObjectToNode (ValDesc, DestDesc->Reference.Object, 238 WalkState); 239 240 break; /* Case NameOp */ 241 242 243 case AML_INDEX_OP: 244 245 DeleteDestDesc = DestDesc; 246 247 /* 248 * Valid source value and destination reference pointer. 249 * 250 * ACPI Specification 1.0B section 15.2.3.4.2.13: 251 * Destination should point to either a buffer or a package 252 */ 253 254 /* 255 * Actually, storing to a package is not so simple. The source must be 256 * evaluated and converted to the type of the destination and then the 257 * source is copied into the destination - we can't just point to the 258 * source object. 259 */ 260 if (DestDesc->Reference.TargetType == ACPI_TYPE_PACKAGE) 261 { 262 /* 263 * The object at *(DestDesc->Reference.Where) is the 264 * element within the package that is to be modified. 265 */ 266 TmpDesc = *(DestDesc->Reference.Where); 267 if (TmpDesc) 268 { 269 /* 270 * If the Destination element is a package, we will delete 271 * that object and construct a new one. 272 * 273 * TBD: [Investigate] Should both the src and dest be required 274 * to be packages? 275 * && (ValDesc->Common.Type == ACPI_TYPE_PACKAGE) 276 */ 277 if (TmpDesc->Common.Type == ACPI_TYPE_PACKAGE) 278 { 279 /* 280 * Take away the reference for being part of a package and 281 * delete 282 */ 283 AcpiCmRemoveReference (TmpDesc); 284 AcpiCmRemoveReference (TmpDesc); 285 286 TmpDesc = NULL; 287 } 288 } 289 290 if (!TmpDesc) 291 { 292 /* 293 * If the TmpDesc is NULL, that means an uninitialized package 294 * has been used as a destination, therefore, we must create 295 * the destination element to match the type of the source 296 * element NOTE: ValDesc can be of any type. 297 */ 298 TmpDesc = AcpiCmCreateInternalObject (ValDesc->Common.Type); 299 if (!TmpDesc) 300 { 301 Status = AE_NO_MEMORY; 302 goto Cleanup; 303 } 304 305 /* 306 * If the source is a package, copy the source to the new dest 307 */ 308 if (ACPI_TYPE_PACKAGE == TmpDesc->Common.Type) 309 { 310 Status = AcpiAmlBuildCopyInternalPackageObject ( 311 ValDesc, TmpDesc, WalkState); 312 if (ACPI_FAILURE (Status)) 313 { 314 AcpiCmRemoveReference (TmpDesc); 315 TmpDesc = NULL; 316 goto Cleanup; 317 } 318 } 319 320 /* 321 * Install the new descriptor into the package and add a 322 * reference to the newly created descriptor for now being 323 * part of the parent package 324 */ 325 326 *(DestDesc->Reference.Where) = TmpDesc; 327 AcpiCmAddReference (TmpDesc); 328 } 329 330 if (ACPI_TYPE_PACKAGE != TmpDesc->Common.Type) 331 { 332 /* 333 * The destination element is not a package, so we need to 334 * convert the contents of the source (ValDesc) and copy into 335 * the destination (TmpDesc) 336 */ 337 Status = AcpiAmlStoreObjectToObject (ValDesc, TmpDesc, 338 WalkState); 339 if (ACPI_FAILURE (Status)) 340 { 341 /* 342 * An error occurrered when copying the internal object 343 * so delete the reference. 344 */ 345 DEBUG_PRINT (ACPI_ERROR, 346 ("AmlExecStore/Index: Unable to copy the internal object\n")); 347 Status = AE_AML_OPERAND_TYPE; 348 } 349 } 350 351 break; 352 } 353 354 /* 355 * Check that the destination is a Buffer Field type 356 */ 357 if (DestDesc->Reference.TargetType != ACPI_TYPE_BUFFER_FIELD) 358 { 359 Status = AE_AML_OPERAND_TYPE; 360 break; 361 } 362 363 /* 364 * Storing into a buffer at a location defined by an Index. 365 * 366 * Each 8-bit element of the source object is written to the 367 * 8-bit Buffer Field of the Index destination object. 368 */ 369 370 /* 371 * Set the TmpDesc to the destination object and type check. 372 */ 373 TmpDesc = DestDesc->Reference.Object; 374 375 if (TmpDesc->Common.Type != ACPI_TYPE_BUFFER) 376 { 377 Status = AE_AML_OPERAND_TYPE; 378 break; 379 } 380 381 /* 382 * The assignment of the individual elements will be slightly 383 * different for each source type. 384 */ 385 386 switch (ValDesc->Common.Type) 387 { 388 /* 389 * If the type is Integer, the Length is 4. 390 * This loop to assign each of the elements is somewhat 391 * backward because of the Big Endian-ness of IA-64 392 */ 393 case ACPI_TYPE_NUMBER: 394 Length = 4; 395 for (i = Length; i != 0; i--) 396 { 397 Value = (UINT8)(ValDesc->Number.Value >> (MUL_8 (i - 1))); 398 TmpDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; 399 } 400 break; 401 402 /* 403 * If the type is Buffer, the Length is in the structure. 404 * Just loop through the elements and assign each one in turn. 405 */ 406 case ACPI_TYPE_BUFFER: 407 Length = ValDesc->Buffer.Length; 408 for (i = 0; i < Length; i++) 409 { 410 Value = *(ValDesc->Buffer.Pointer + i); 411 TmpDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; 412 } 413 break; 414 415 /* 416 * If the type is String, the Length is in the structure. 417 * Just loop through the elements and assign each one in turn. 418 */ 419 case ACPI_TYPE_STRING: 420 Length = ValDesc->String.Length; 421 for (i = 0; i < Length; i++) 422 { 423 Value = *(ValDesc->String.Pointer + i); 424 TmpDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; 425 } 426 break; 427 428 /* 429 * If source is not a valid type so return an error. 430 */ 431 default: 432 DEBUG_PRINT (ACPI_ERROR, 433 ("AmlExecStore/Index: Source must be Number/Buffer/String type, not %X\n", 434 ValDesc->Common.Type)); 435 Status = AE_AML_OPERAND_TYPE; 436 break; 437 } 438 439 /* 440 * If we had an error, break out of this case statement. 441 */ 442 if (ACPI_FAILURE (Status)) 443 { 444 break; 445 } 446 447 /* 448 * Set the return pointer 449 */ 450 DestDesc = TmpDesc; 451 452 break; 453 454 case AML_ZERO_OP: 455 case AML_ONE_OP: 456 case AML_ONES_OP: 457 458 /* 459 * Storing to a constant is a no-op -- see ACPI Specification 460 * Delete the result descriptor. 461 */ 462 463 DeleteDestDesc = DestDesc; 464 break; 465 466 467 case AML_LOCAL_OP: 468 469 Status = AcpiDsMethodDataSetValue (MTH_TYPE_LOCAL, 470 (DestDesc->Reference.Offset), ValDesc, WalkState); 471 DeleteDestDesc = DestDesc; 472 break; 473 474 475 case AML_ARG_OP: 476 477 Status = AcpiDsMethodDataSetValue (MTH_TYPE_ARG, 478 (DestDesc->Reference.Offset), ValDesc, WalkState); 479 DeleteDestDesc = DestDesc; 480 break; 481 482 483 case AML_DEBUG_OP: 484 485 /* 486 * Storing to the Debug object causes the value stored to be 487 * displayed and otherwise has no effect -- see ACPI Specification 488 */ 489 DEBUG_PRINT (ACPI_INFO, ("**** Write to Debug Object: ****: \n")); 490 if (ValDesc->Common.Type == ACPI_TYPE_STRING) 491 { 492 DEBUG_PRINT (ACPI_INFO, ("%s\n", ValDesc->String.Pointer)); 493 } 494 else 495 { 496 DUMP_STACK_ENTRY (ValDesc); 497 } 498 499 DeleteDestDesc = DestDesc; 500 break; 501 502 503 default: 504 505 DEBUG_PRINT (ACPI_ERROR, 506 ("AmlExecStore: Internal error - Unknown Reference subtype %02x\n", 507 DestDesc->Reference.OpCode)); 508 509 /* TBD: [Restructure] use object dump routine !! */ 510 511 DUMP_BUFFER (DestDesc, sizeof (ACPI_OPERAND_OBJECT)); 512 513 DeleteDestDesc = DestDesc; 514 Status = AE_AML_INTERNAL; 515 516 } /* switch(DestDesc->Reference.OpCode) */ 517 518 519Cleanup: 520 521 /* Cleanup and exit*/ 522 523 if (DeleteDestDesc) 524 { 525 AcpiCmRemoveReference (DeleteDestDesc); 526 } 527 528 return_ACPI_STATUS (Status); 529} 530 531 532