1 /****************************************************************************** 2 * 3 * Module Name: utcopy - Internal to external object translation utilities 4 * $Revision: 1.137 $ 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 #define __UTCOPY_C__ 118 119 #include "acpi.h" 120 #include "acnamesp.h" 121 122 123 #define _COMPONENT ACPI_UTILITIES 124 ACPI_MODULE_NAME ("utcopy") 125 126 /* Local prototypes */ 127 128 static ACPI_STATUS 129 AcpiUtCopyIsimpleToEsimple ( 130 ACPI_OPERAND_OBJECT *InternalObject, 131 ACPI_OBJECT *ExternalObject, 132 UINT8 *DataSpace, 133 ACPI_SIZE *BufferSpaceUsed); 134 135 static ACPI_STATUS 136 AcpiUtCopyIelementToIelement ( 137 UINT8 ObjectType, 138 ACPI_OPERAND_OBJECT *SourceObject, 139 ACPI_GENERIC_STATE *State, 140 void *Context); 141 142 static ACPI_STATUS 143 AcpiUtCopyIpackageToEpackage ( 144 ACPI_OPERAND_OBJECT *InternalObject, 145 UINT8 *Buffer, 146 ACPI_SIZE *SpaceUsed); 147 148 static ACPI_STATUS 149 AcpiUtCopyEsimpleToIsimple( 150 ACPI_OBJECT *UserObj, 151 ACPI_OPERAND_OBJECT **ReturnObj); 152 153 static ACPI_STATUS 154 AcpiUtCopyEpackageToIpackage ( 155 ACPI_OBJECT *ExternalObject, 156 ACPI_OPERAND_OBJECT **InternalObject); 157 158 static ACPI_STATUS 159 AcpiUtCopySimpleObject ( 160 ACPI_OPERAND_OBJECT *SourceDesc, 161 ACPI_OPERAND_OBJECT *DestDesc); 162 163 static ACPI_STATUS 164 AcpiUtCopyIelementToEelement ( 165 UINT8 ObjectType, 166 ACPI_OPERAND_OBJECT *SourceObject, 167 ACPI_GENERIC_STATE *State, 168 void *Context); 169 170 static ACPI_STATUS 171 AcpiUtCopyIpackageToIpackage ( 172 ACPI_OPERAND_OBJECT *SourceObj, 173 ACPI_OPERAND_OBJECT *DestObj, 174 ACPI_WALK_STATE *WalkState); 175 176 177 /******************************************************************************* 178 * 179 * FUNCTION: AcpiUtCopyIsimpleToEsimple 180 * 181 * PARAMETERS: InternalObject - Source object to be copied 182 * ExternalObject - Where to return the copied object 183 * DataSpace - Where object data is returned (such as 184 * buffer and string data) 185 * BufferSpaceUsed - Length of DataSpace that was used 186 * 187 * RETURN: Status 188 * 189 * DESCRIPTION: This function is called to copy a simple internal object to 190 * an external object. 191 * 192 * The DataSpace buffer is assumed to have sufficient space for 193 * the object. 194 * 195 ******************************************************************************/ 196 197 static ACPI_STATUS 198 AcpiUtCopyIsimpleToEsimple ( 199 ACPI_OPERAND_OBJECT *InternalObject, 200 ACPI_OBJECT *ExternalObject, 201 UINT8 *DataSpace, 202 ACPI_SIZE *BufferSpaceUsed) 203 { 204 ACPI_STATUS Status = AE_OK; 205 206 207 ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple); 208 209 210 *BufferSpaceUsed = 0; 211 212 /* 213 * Check for NULL object case (could be an uninitialized 214 * package element) 215 */ 216 if (!InternalObject) 217 { 218 return_ACPI_STATUS (AE_OK); 219 } 220 221 /* Always clear the external object */ 222 223 ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT)); 224 225 /* 226 * In general, the external object will be the same type as 227 * the internal object 228 */ 229 ExternalObject->Type = ACPI_GET_OBJECT_TYPE (InternalObject); 230 231 /* However, only a limited number of external types are supported */ 232 233 switch (ACPI_GET_OBJECT_TYPE (InternalObject)) 234 { 235 case ACPI_TYPE_STRING: 236 237 ExternalObject->String.Pointer = (char *) DataSpace; 238 ExternalObject->String.Length = InternalObject->String.Length; 239 *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD ( 240 (ACPI_SIZE) InternalObject->String.Length + 1); 241 242 ACPI_MEMCPY ((void *) DataSpace, 243 (void *) InternalObject->String.Pointer, 244 (ACPI_SIZE) InternalObject->String.Length + 1); 245 break; 246 247 248 case ACPI_TYPE_BUFFER: 249 250 ExternalObject->Buffer.Pointer = DataSpace; 251 ExternalObject->Buffer.Length = InternalObject->Buffer.Length; 252 *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD ( 253 InternalObject->String.Length); 254 255 ACPI_MEMCPY ((void *) DataSpace, 256 (void *) InternalObject->Buffer.Pointer, 257 InternalObject->Buffer.Length); 258 break; 259 260 261 case ACPI_TYPE_INTEGER: 262 263 ExternalObject->Integer.Value = InternalObject->Integer.Value; 264 break; 265 266 267 case ACPI_TYPE_LOCAL_REFERENCE: 268 269 /* This is an object reference. */ 270 271 switch (InternalObject->Reference.Class) 272 { 273 case ACPI_REFCLASS_NAME: 274 275 /* 276 * For namepath, return the object handle ("reference") 277 * We are referring to the namespace node 278 */ 279 ExternalObject->Reference.Handle = 280 InternalObject->Reference.Node; 281 ExternalObject->Reference.ActualType = 282 AcpiNsGetType (InternalObject->Reference.Node); 283 break; 284 285 default: 286 287 /* All other reference types are unsupported */ 288 289 return_ACPI_STATUS (AE_TYPE); 290 } 291 break; 292 293 294 case ACPI_TYPE_PROCESSOR: 295 296 ExternalObject->Processor.ProcId = 297 InternalObject->Processor.ProcId; 298 ExternalObject->Processor.PblkAddress = 299 InternalObject->Processor.Address; 300 ExternalObject->Processor.PblkLength = 301 InternalObject->Processor.Length; 302 break; 303 304 305 case ACPI_TYPE_POWER: 306 307 ExternalObject->PowerResource.SystemLevel = 308 InternalObject->PowerResource.SystemLevel; 309 310 ExternalObject->PowerResource.ResourceOrder = 311 InternalObject->PowerResource.ResourceOrder; 312 break; 313 314 315 default: 316 /* 317 * There is no corresponding external object type 318 */ 319 ACPI_ERROR ((AE_INFO, 320 "Unsupported object type, cannot convert to external object: %s", 321 AcpiUtGetTypeName (ACPI_GET_OBJECT_TYPE (InternalObject)))); 322 323 return_ACPI_STATUS (AE_SUPPORT); 324 } 325 326 return_ACPI_STATUS (Status); 327 } 328 329 330 /******************************************************************************* 331 * 332 * FUNCTION: AcpiUtCopyIelementToEelement 333 * 334 * PARAMETERS: ACPI_PKG_CALLBACK 335 * 336 * RETURN: Status 337 * 338 * DESCRIPTION: Copy one package element to another package element 339 * 340 ******************************************************************************/ 341 342 static ACPI_STATUS 343 AcpiUtCopyIelementToEelement ( 344 UINT8 ObjectType, 345 ACPI_OPERAND_OBJECT *SourceObject, 346 ACPI_GENERIC_STATE *State, 347 void *Context) 348 { 349 ACPI_STATUS Status = AE_OK; 350 ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context; 351 ACPI_SIZE ObjectSpace; 352 UINT32 ThisIndex; 353 ACPI_OBJECT *TargetObject; 354 355 356 ACPI_FUNCTION_ENTRY (); 357 358 359 ThisIndex = State->Pkg.Index; 360 TargetObject = (ACPI_OBJECT *) 361 &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex]; 362 363 switch (ObjectType) 364 { 365 case ACPI_COPY_TYPE_SIMPLE: 366 367 /* 368 * This is a simple or null object 369 */ 370 Status = AcpiUtCopyIsimpleToEsimple (SourceObject, 371 TargetObject, Info->FreeSpace, &ObjectSpace); 372 if (ACPI_FAILURE (Status)) 373 { 374 return (Status); 375 } 376 break; 377 378 379 case ACPI_COPY_TYPE_PACKAGE: 380 381 /* 382 * Build the package object 383 */ 384 TargetObject->Type = ACPI_TYPE_PACKAGE; 385 TargetObject->Package.Count = SourceObject->Package.Count; 386 TargetObject->Package.Elements = 387 ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace); 388 389 /* 390 * Pass the new package object back to the package walk routine 391 */ 392 State->Pkg.ThisTargetObj = TargetObject; 393 394 /* 395 * Save space for the array of objects (Package elements) 396 * update the buffer length counter 397 */ 398 ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD ( 399 (ACPI_SIZE) TargetObject->Package.Count * 400 sizeof (ACPI_OBJECT)); 401 break; 402 403 404 default: 405 return (AE_BAD_PARAMETER); 406 } 407 408 Info->FreeSpace += ObjectSpace; 409 Info->Length += ObjectSpace; 410 return (Status); 411 } 412 413 414 /******************************************************************************* 415 * 416 * FUNCTION: AcpiUtCopyIpackageToEpackage 417 * 418 * PARAMETERS: InternalObject - Pointer to the object we are returning 419 * Buffer - Where the object is returned 420 * SpaceUsed - Where the object length is returned 421 * 422 * RETURN: Status 423 * 424 * DESCRIPTION: This function is called to place a package object in a user 425 * buffer. A package object by definition contains other objects. 426 * 427 * The buffer is assumed to have sufficient space for the object. 428 * The caller must have verified the buffer length needed using the 429 * AcpiUtGetObjectSize function before calling this function. 430 * 431 ******************************************************************************/ 432 433 static ACPI_STATUS 434 AcpiUtCopyIpackageToEpackage ( 435 ACPI_OPERAND_OBJECT *InternalObject, 436 UINT8 *Buffer, 437 ACPI_SIZE *SpaceUsed) 438 { 439 ACPI_OBJECT *ExternalObject; 440 ACPI_STATUS Status; 441 ACPI_PKG_INFO Info; 442 443 444 ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage); 445 446 447 /* 448 * First package at head of the buffer 449 */ 450 ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer); 451 452 /* 453 * Free space begins right after the first package 454 */ 455 Info.Length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 456 Info.FreeSpace = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD ( 457 sizeof (ACPI_OBJECT)); 458 Info.ObjectSpace = 0; 459 Info.NumPackages = 1; 460 461 ExternalObject->Type = ACPI_GET_OBJECT_TYPE (InternalObject); 462 ExternalObject->Package.Count = InternalObject->Package.Count; 463 ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT, 464 Info.FreeSpace); 465 466 /* 467 * Leave room for an array of ACPI_OBJECTS in the buffer 468 * and move the free space past it 469 */ 470 Info.Length += (ACPI_SIZE) ExternalObject->Package.Count * 471 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 472 Info.FreeSpace += ExternalObject->Package.Count * 473 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 474 475 Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject, 476 AcpiUtCopyIelementToEelement, &Info); 477 478 *SpaceUsed = Info.Length; 479 return_ACPI_STATUS (Status); 480 } 481 482 483 /******************************************************************************* 484 * 485 * FUNCTION: AcpiUtCopyIobjectToEobject 486 * 487 * PARAMETERS: InternalObject - The internal object to be converted 488 * BufferPtr - Where the object is returned 489 * 490 * RETURN: Status 491 * 492 * DESCRIPTION: This function is called to build an API object to be returned to 493 * the caller. 494 * 495 ******************************************************************************/ 496 497 ACPI_STATUS 498 AcpiUtCopyIobjectToEobject ( 499 ACPI_OPERAND_OBJECT *InternalObject, 500 ACPI_BUFFER *RetBuffer) 501 { 502 ACPI_STATUS Status; 503 504 505 ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject); 506 507 508 if (ACPI_GET_OBJECT_TYPE (InternalObject) == ACPI_TYPE_PACKAGE) 509 { 510 /* 511 * Package object: Copy all subobjects (including 512 * nested packages) 513 */ 514 Status = AcpiUtCopyIpackageToEpackage (InternalObject, 515 RetBuffer->Pointer, &RetBuffer->Length); 516 } 517 else 518 { 519 /* 520 * Build a simple object (no nested objects) 521 */ 522 Status = AcpiUtCopyIsimpleToEsimple (InternalObject, 523 ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer), 524 ACPI_ADD_PTR (UINT8, RetBuffer->Pointer, 525 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))), 526 &RetBuffer->Length); 527 /* 528 * build simple does not include the object size in the length 529 * so we add it in here 530 */ 531 RetBuffer->Length += sizeof (ACPI_OBJECT); 532 } 533 534 return_ACPI_STATUS (Status); 535 } 536 537 538 /******************************************************************************* 539 * 540 * FUNCTION: AcpiUtCopyEsimpleToIsimple 541 * 542 * PARAMETERS: ExternalObject - The external object to be converted 543 * RetInternalObject - Where the internal object is returned 544 * 545 * RETURN: Status 546 * 547 * DESCRIPTION: This function copies an external object to an internal one. 548 * NOTE: Pointers can be copied, we don't need to copy data. 549 * (The pointers have to be valid in our address space no matter 550 * what we do with them!) 551 * 552 ******************************************************************************/ 553 554 static ACPI_STATUS 555 AcpiUtCopyEsimpleToIsimple ( 556 ACPI_OBJECT *ExternalObject, 557 ACPI_OPERAND_OBJECT **RetInternalObject) 558 { 559 ACPI_OPERAND_OBJECT *InternalObject; 560 561 562 ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple); 563 564 565 /* 566 * Simple types supported are: String, Buffer, Integer 567 */ 568 switch (ExternalObject->Type) 569 { 570 case ACPI_TYPE_STRING: 571 case ACPI_TYPE_BUFFER: 572 case ACPI_TYPE_INTEGER: 573 case ACPI_TYPE_LOCAL_REFERENCE: 574 575 InternalObject = AcpiUtCreateInternalObject ( 576 (UINT8) ExternalObject->Type); 577 if (!InternalObject) 578 { 579 return_ACPI_STATUS (AE_NO_MEMORY); 580 } 581 break; 582 583 case ACPI_TYPE_ANY: /* This is the case for a NULL object */ 584 585 *RetInternalObject = NULL; 586 return_ACPI_STATUS (AE_OK); 587 588 default: 589 /* All other types are not supported */ 590 591 ACPI_ERROR ((AE_INFO, "Unsupported object type, cannot convert to internal object: %s", 592 AcpiUtGetTypeName (ExternalObject->Type))); 593 594 return_ACPI_STATUS (AE_SUPPORT); 595 } 596 597 598 /* Must COPY string and buffer contents */ 599 600 switch (ExternalObject->Type) 601 { 602 case ACPI_TYPE_STRING: 603 604 InternalObject->String.Pointer = 605 ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) ExternalObject->String.Length + 1); 606 if (!InternalObject->String.Pointer) 607 { 608 goto ErrorExit; 609 } 610 611 ACPI_MEMCPY (InternalObject->String.Pointer, 612 ExternalObject->String.Pointer, 613 ExternalObject->String.Length); 614 615 InternalObject->String.Length = ExternalObject->String.Length; 616 break; 617 618 619 case ACPI_TYPE_BUFFER: 620 621 InternalObject->Buffer.Pointer = 622 ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length); 623 if (!InternalObject->Buffer.Pointer) 624 { 625 goto ErrorExit; 626 } 627 628 ACPI_MEMCPY (InternalObject->Buffer.Pointer, 629 ExternalObject->Buffer.Pointer, 630 ExternalObject->Buffer.Length); 631 632 InternalObject->Buffer.Length = ExternalObject->Buffer.Length; 633 634 /* Mark buffer data valid */ 635 636 InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID; 637 break; 638 639 640 case ACPI_TYPE_INTEGER: 641 642 InternalObject->Integer.Value = ExternalObject->Integer.Value; 643 break; 644 645 case ACPI_TYPE_LOCAL_REFERENCE: 646 647 /* TBD: should validate incoming handle */ 648 649 InternalObject->Reference.Class = ACPI_REFCLASS_NAME; 650 InternalObject->Reference.Node = ExternalObject->Reference.Handle; 651 break; 652 653 default: 654 /* Other types can't get here */ 655 break; 656 } 657 658 *RetInternalObject = InternalObject; 659 return_ACPI_STATUS (AE_OK); 660 661 662 ErrorExit: 663 AcpiUtRemoveReference (InternalObject); 664 return_ACPI_STATUS (AE_NO_MEMORY); 665 } 666 667 668 /******************************************************************************* 669 * 670 * FUNCTION: AcpiUtCopyEpackageToIpackage 671 * 672 * PARAMETERS: ExternalObject - The external object to be converted 673 * InternalObject - Where the internal object is returned 674 * 675 * RETURN: Status 676 * 677 * DESCRIPTION: Copy an external package object to an internal package. 678 * Handles nested packages. 679 * 680 ******************************************************************************/ 681 682 static ACPI_STATUS 683 AcpiUtCopyEpackageToIpackage ( 684 ACPI_OBJECT *ExternalObject, 685 ACPI_OPERAND_OBJECT **InternalObject) 686 { 687 ACPI_STATUS Status = AE_OK; 688 ACPI_OPERAND_OBJECT *PackageObject; 689 ACPI_OPERAND_OBJECT **PackageElements; 690 UINT32 i; 691 692 693 ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage); 694 695 696 /* Create the package object */ 697 698 PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count); 699 if (!PackageObject) 700 { 701 return_ACPI_STATUS (AE_NO_MEMORY); 702 } 703 704 PackageElements = PackageObject->Package.Elements; 705 706 /* 707 * Recursive implementation. Probably ok, since nested external packages 708 * as parameters should be very rare. 709 */ 710 for (i = 0; i < ExternalObject->Package.Count; i++) 711 { 712 Status = AcpiUtCopyEobjectToIobject ( 713 &ExternalObject->Package.Elements[i], 714 &PackageElements[i]); 715 if (ACPI_FAILURE (Status)) 716 { 717 /* Truncate package and delete it */ 718 719 PackageObject->Package.Count = i; 720 PackageElements[i] = NULL; 721 AcpiUtRemoveReference (PackageObject); 722 return_ACPI_STATUS (Status); 723 } 724 } 725 726 /* Mark package data valid */ 727 728 PackageObject->Package.Flags |= AOPOBJ_DATA_VALID; 729 730 *InternalObject = PackageObject; 731 return_ACPI_STATUS (Status); 732 } 733 734 735 /******************************************************************************* 736 * 737 * FUNCTION: AcpiUtCopyEobjectToIobject 738 * 739 * PARAMETERS: ExternalObject - The external object to be converted 740 * InternalObject - Where the internal object is returned 741 * 742 * RETURN: Status - the status of the call 743 * 744 * DESCRIPTION: Converts an external object to an internal object. 745 * 746 ******************************************************************************/ 747 748 ACPI_STATUS 749 AcpiUtCopyEobjectToIobject ( 750 ACPI_OBJECT *ExternalObject, 751 ACPI_OPERAND_OBJECT **InternalObject) 752 { 753 ACPI_STATUS Status; 754 755 756 ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject); 757 758 759 if (ExternalObject->Type == ACPI_TYPE_PACKAGE) 760 { 761 Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject); 762 } 763 else 764 { 765 /* 766 * Build a simple object (no nested objects) 767 */ 768 Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject); 769 } 770 771 return_ACPI_STATUS (Status); 772 } 773 774 775 /******************************************************************************* 776 * 777 * FUNCTION: AcpiUtCopySimpleObject 778 * 779 * PARAMETERS: SourceDesc - The internal object to be copied 780 * DestDesc - New target object 781 * 782 * RETURN: Status 783 * 784 * DESCRIPTION: Simple copy of one internal object to another. Reference count 785 * of the destination object is preserved. 786 * 787 ******************************************************************************/ 788 789 static ACPI_STATUS 790 AcpiUtCopySimpleObject ( 791 ACPI_OPERAND_OBJECT *SourceDesc, 792 ACPI_OPERAND_OBJECT *DestDesc) 793 { 794 UINT16 ReferenceCount; 795 ACPI_OPERAND_OBJECT *NextObject; 796 797 798 /* Save fields from destination that we don't want to overwrite */ 799 800 ReferenceCount = DestDesc->Common.ReferenceCount; 801 NextObject = DestDesc->Common.NextObject; 802 803 /* Copy the entire source object over the destination object*/ 804 805 ACPI_MEMCPY ((char *) DestDesc, (char *) SourceDesc, 806 sizeof (ACPI_OPERAND_OBJECT)); 807 808 /* Restore the saved fields */ 809 810 DestDesc->Common.ReferenceCount = ReferenceCount; 811 DestDesc->Common.NextObject = NextObject; 812 813 /* New object is not static, regardless of source */ 814 815 DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 816 817 /* Handle the objects with extra data */ 818 819 switch (ACPI_GET_OBJECT_TYPE (DestDesc)) 820 { 821 case ACPI_TYPE_BUFFER: 822 /* 823 * Allocate and copy the actual buffer if and only if: 824 * 1) There is a valid buffer pointer 825 * 2) The buffer has a length > 0 826 */ 827 if ((SourceDesc->Buffer.Pointer) && 828 (SourceDesc->Buffer.Length)) 829 { 830 DestDesc->Buffer.Pointer = 831 ACPI_ALLOCATE (SourceDesc->Buffer.Length); 832 if (!DestDesc->Buffer.Pointer) 833 { 834 return (AE_NO_MEMORY); 835 } 836 837 /* Copy the actual buffer data */ 838 839 ACPI_MEMCPY (DestDesc->Buffer.Pointer, 840 SourceDesc->Buffer.Pointer, 841 SourceDesc->Buffer.Length); 842 } 843 break; 844 845 case ACPI_TYPE_STRING: 846 /* 847 * Allocate and copy the actual string if and only if: 848 * 1) There is a valid string pointer 849 * (Pointer to a NULL string is allowed) 850 */ 851 if (SourceDesc->String.Pointer) 852 { 853 DestDesc->String.Pointer = 854 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1); 855 if (!DestDesc->String.Pointer) 856 { 857 return (AE_NO_MEMORY); 858 } 859 860 /* Copy the actual string data */ 861 862 ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer, 863 (ACPI_SIZE) SourceDesc->String.Length + 1); 864 } 865 break; 866 867 case ACPI_TYPE_LOCAL_REFERENCE: 868 /* 869 * We copied the reference object, so we now must add a reference 870 * to the object pointed to by the reference 871 * 872 * DDBHandle reference (from Load/LoadTable) is a special reference, 873 * it does not have a Reference.Object, so does not need to 874 * increase the reference count 875 */ 876 if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE) 877 { 878 break; 879 } 880 881 AcpiUtAddReference (SourceDesc->Reference.Object); 882 break; 883 884 case ACPI_TYPE_REGION: 885 /* 886 * We copied the Region Handler, so we now must add a reference 887 */ 888 if (DestDesc->Region.Handler) 889 { 890 AcpiUtAddReference (DestDesc->Region.Handler); 891 } 892 break; 893 894 default: 895 /* Nothing to do for other simple objects */ 896 break; 897 } 898 899 return (AE_OK); 900 } 901 902 903 /******************************************************************************* 904 * 905 * FUNCTION: AcpiUtCopyIelementToIelement 906 * 907 * PARAMETERS: ACPI_PKG_CALLBACK 908 * 909 * RETURN: Status 910 * 911 * DESCRIPTION: Copy one package element to another package element 912 * 913 ******************************************************************************/ 914 915 static ACPI_STATUS 916 AcpiUtCopyIelementToIelement ( 917 UINT8 ObjectType, 918 ACPI_OPERAND_OBJECT *SourceObject, 919 ACPI_GENERIC_STATE *State, 920 void *Context) 921 { 922 ACPI_STATUS Status = AE_OK; 923 UINT32 ThisIndex; 924 ACPI_OPERAND_OBJECT **ThisTargetPtr; 925 ACPI_OPERAND_OBJECT *TargetObject; 926 927 928 ACPI_FUNCTION_ENTRY (); 929 930 931 ThisIndex = State->Pkg.Index; 932 ThisTargetPtr = (ACPI_OPERAND_OBJECT **) 933 &State->Pkg.DestObject->Package.Elements[ThisIndex]; 934 935 switch (ObjectType) 936 { 937 case ACPI_COPY_TYPE_SIMPLE: 938 939 /* A null source object indicates a (legal) null package element */ 940 941 if (SourceObject) 942 { 943 /* 944 * This is a simple object, just copy it 945 */ 946 TargetObject = AcpiUtCreateInternalObject ( 947 ACPI_GET_OBJECT_TYPE (SourceObject)); 948 if (!TargetObject) 949 { 950 return (AE_NO_MEMORY); 951 } 952 953 Status = AcpiUtCopySimpleObject (SourceObject, TargetObject); 954 if (ACPI_FAILURE (Status)) 955 { 956 goto ErrorExit; 957 } 958 959 *ThisTargetPtr = TargetObject; 960 } 961 else 962 { 963 /* Pass through a null element */ 964 965 *ThisTargetPtr = NULL; 966 } 967 break; 968 969 970 case ACPI_COPY_TYPE_PACKAGE: 971 972 /* 973 * This object is a package - go down another nesting level 974 * Create and build the package object 975 */ 976 TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count); 977 if (!TargetObject) 978 { 979 return (AE_NO_MEMORY); 980 } 981 982 TargetObject->Common.Flags = SourceObject->Common.Flags; 983 984 /* Pass the new package object back to the package walk routine */ 985 986 State->Pkg.ThisTargetObj = TargetObject; 987 988 /* Store the object pointer in the parent package object */ 989 990 *ThisTargetPtr = TargetObject; 991 break; 992 993 994 default: 995 return (AE_BAD_PARAMETER); 996 } 997 998 return (Status); 999 1000 ErrorExit: 1001 AcpiUtRemoveReference (TargetObject); 1002 return (Status); 1003 } 1004 1005 1006 /******************************************************************************* 1007 * 1008 * FUNCTION: AcpiUtCopyIpackageToIpackage 1009 * 1010 * PARAMETERS: *SourceObj - Pointer to the source package object 1011 * *DestObj - Where the internal object is returned 1012 * 1013 * RETURN: Status - the status of the call 1014 * 1015 * DESCRIPTION: This function is called to copy an internal package object 1016 * into another internal package object. 1017 * 1018 ******************************************************************************/ 1019 1020 static ACPI_STATUS 1021 AcpiUtCopyIpackageToIpackage ( 1022 ACPI_OPERAND_OBJECT *SourceObj, 1023 ACPI_OPERAND_OBJECT *DestObj, 1024 ACPI_WALK_STATE *WalkState) 1025 { 1026 ACPI_STATUS Status = AE_OK; 1027 1028 1029 ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage); 1030 1031 1032 DestObj->Common.Type = ACPI_GET_OBJECT_TYPE (SourceObj); 1033 DestObj->Common.Flags = SourceObj->Common.Flags; 1034 DestObj->Package.Count = SourceObj->Package.Count; 1035 1036 /* 1037 * Create the object array and walk the source package tree 1038 */ 1039 DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED ( 1040 ((ACPI_SIZE) SourceObj->Package.Count + 1) * 1041 sizeof (void *)); 1042 if (!DestObj->Package.Elements) 1043 { 1044 ACPI_ERROR ((AE_INFO, "Package allocation failure")); 1045 return_ACPI_STATUS (AE_NO_MEMORY); 1046 } 1047 1048 /* 1049 * Copy the package element-by-element by walking the package "tree". 1050 * This handles nested packages of arbitrary depth. 1051 */ 1052 Status = AcpiUtWalkPackageTree (SourceObj, DestObj, 1053 AcpiUtCopyIelementToIelement, WalkState); 1054 if (ACPI_FAILURE (Status)) 1055 { 1056 /* On failure, delete the destination package object */ 1057 1058 AcpiUtRemoveReference (DestObj); 1059 } 1060 1061 return_ACPI_STATUS (Status); 1062 } 1063 1064 1065 /******************************************************************************* 1066 * 1067 * FUNCTION: AcpiUtCopyIobjectToIobject 1068 * 1069 * PARAMETERS: WalkState - Current walk state 1070 * SourceDesc - The internal object to be copied 1071 * DestDesc - Where the copied object is returned 1072 * 1073 * RETURN: Status 1074 * 1075 * DESCRIPTION: Copy an internal object to a new internal object 1076 * 1077 ******************************************************************************/ 1078 1079 ACPI_STATUS 1080 AcpiUtCopyIobjectToIobject ( 1081 ACPI_OPERAND_OBJECT *SourceDesc, 1082 ACPI_OPERAND_OBJECT **DestDesc, 1083 ACPI_WALK_STATE *WalkState) 1084 { 1085 ACPI_STATUS Status = AE_OK; 1086 1087 1088 ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject); 1089 1090 1091 /* Create the top level object */ 1092 1093 *DestDesc = AcpiUtCreateInternalObject (ACPI_GET_OBJECT_TYPE (SourceDesc)); 1094 if (!*DestDesc) 1095 { 1096 return_ACPI_STATUS (AE_NO_MEMORY); 1097 } 1098 1099 /* Copy the object and possible subobjects */ 1100 1101 if (ACPI_GET_OBJECT_TYPE (SourceDesc) == ACPI_TYPE_PACKAGE) 1102 { 1103 Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc, 1104 WalkState); 1105 } 1106 else 1107 { 1108 Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc); 1109 } 1110 1111 return_ACPI_STATUS (Status); 1112 } 1113 1114 1115