1 /****************************************************************************** 2 * 3 * Module Name: utcopy - Internal to external object translation utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2011, 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 #define __UTCOPY_C__ 45 46 #include "acpi.h" 47 #include "accommon.h" 48 #include "acnamesp.h" 49 50 51 #define _COMPONENT ACPI_UTILITIES 52 ACPI_MODULE_NAME ("utcopy") 53 54 /* Local prototypes */ 55 56 static ACPI_STATUS 57 AcpiUtCopyIsimpleToEsimple ( 58 ACPI_OPERAND_OBJECT *InternalObject, 59 ACPI_OBJECT *ExternalObject, 60 UINT8 *DataSpace, 61 ACPI_SIZE *BufferSpaceUsed); 62 63 static ACPI_STATUS 64 AcpiUtCopyIelementToIelement ( 65 UINT8 ObjectType, 66 ACPI_OPERAND_OBJECT *SourceObject, 67 ACPI_GENERIC_STATE *State, 68 void *Context); 69 70 static ACPI_STATUS 71 AcpiUtCopyIpackageToEpackage ( 72 ACPI_OPERAND_OBJECT *InternalObject, 73 UINT8 *Buffer, 74 ACPI_SIZE *SpaceUsed); 75 76 static ACPI_STATUS 77 AcpiUtCopyEsimpleToIsimple( 78 ACPI_OBJECT *UserObj, 79 ACPI_OPERAND_OBJECT **ReturnObj); 80 81 static ACPI_STATUS 82 AcpiUtCopyEpackageToIpackage ( 83 ACPI_OBJECT *ExternalObject, 84 ACPI_OPERAND_OBJECT **InternalObject); 85 86 static ACPI_STATUS 87 AcpiUtCopySimpleObject ( 88 ACPI_OPERAND_OBJECT *SourceDesc, 89 ACPI_OPERAND_OBJECT *DestDesc); 90 91 static ACPI_STATUS 92 AcpiUtCopyIelementToEelement ( 93 UINT8 ObjectType, 94 ACPI_OPERAND_OBJECT *SourceObject, 95 ACPI_GENERIC_STATE *State, 96 void *Context); 97 98 static ACPI_STATUS 99 AcpiUtCopyIpackageToIpackage ( 100 ACPI_OPERAND_OBJECT *SourceObj, 101 ACPI_OPERAND_OBJECT *DestObj, 102 ACPI_WALK_STATE *WalkState); 103 104 105 /******************************************************************************* 106 * 107 * FUNCTION: AcpiUtCopyIsimpleToEsimple 108 * 109 * PARAMETERS: InternalObject - Source object to be copied 110 * ExternalObject - Where to return the copied object 111 * DataSpace - Where object data is returned (such as 112 * buffer and string data) 113 * BufferSpaceUsed - Length of DataSpace that was used 114 * 115 * RETURN: Status 116 * 117 * DESCRIPTION: This function is called to copy a simple internal object to 118 * an external object. 119 * 120 * The DataSpace buffer is assumed to have sufficient space for 121 * the object. 122 * 123 ******************************************************************************/ 124 125 static ACPI_STATUS 126 AcpiUtCopyIsimpleToEsimple ( 127 ACPI_OPERAND_OBJECT *InternalObject, 128 ACPI_OBJECT *ExternalObject, 129 UINT8 *DataSpace, 130 ACPI_SIZE *BufferSpaceUsed) 131 { 132 ACPI_STATUS Status = AE_OK; 133 134 135 ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple); 136 137 138 *BufferSpaceUsed = 0; 139 140 /* 141 * Check for NULL object case (could be an uninitialized 142 * package element) 143 */ 144 if (!InternalObject) 145 { 146 return_ACPI_STATUS (AE_OK); 147 } 148 149 /* Always clear the external object */ 150 151 ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT)); 152 153 /* 154 * In general, the external object will be the same type as 155 * the internal object 156 */ 157 ExternalObject->Type = InternalObject->Common.Type; 158 159 /* However, only a limited number of external types are supported */ 160 161 switch (InternalObject->Common.Type) 162 { 163 case ACPI_TYPE_STRING: 164 165 ExternalObject->String.Pointer = (char *) DataSpace; 166 ExternalObject->String.Length = InternalObject->String.Length; 167 *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD ( 168 (ACPI_SIZE) InternalObject->String.Length + 1); 169 170 ACPI_MEMCPY ((void *) DataSpace, 171 (void *) InternalObject->String.Pointer, 172 (ACPI_SIZE) InternalObject->String.Length + 1); 173 break; 174 175 176 case ACPI_TYPE_BUFFER: 177 178 ExternalObject->Buffer.Pointer = DataSpace; 179 ExternalObject->Buffer.Length = InternalObject->Buffer.Length; 180 *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD ( 181 InternalObject->String.Length); 182 183 ACPI_MEMCPY ((void *) DataSpace, 184 (void *) InternalObject->Buffer.Pointer, 185 InternalObject->Buffer.Length); 186 break; 187 188 189 case ACPI_TYPE_INTEGER: 190 191 ExternalObject->Integer.Value = InternalObject->Integer.Value; 192 break; 193 194 195 case ACPI_TYPE_LOCAL_REFERENCE: 196 197 /* This is an object reference. */ 198 199 switch (InternalObject->Reference.Class) 200 { 201 case ACPI_REFCLASS_NAME: 202 203 /* 204 * For namepath, return the object handle ("reference") 205 * We are referring to the namespace node 206 */ 207 ExternalObject->Reference.Handle = 208 InternalObject->Reference.Node; 209 ExternalObject->Reference.ActualType = 210 AcpiNsGetType (InternalObject->Reference.Node); 211 break; 212 213 default: 214 215 /* All other reference types are unsupported */ 216 217 return_ACPI_STATUS (AE_TYPE); 218 } 219 break; 220 221 222 case ACPI_TYPE_PROCESSOR: 223 224 ExternalObject->Processor.ProcId = 225 InternalObject->Processor.ProcId; 226 ExternalObject->Processor.PblkAddress = 227 InternalObject->Processor.Address; 228 ExternalObject->Processor.PblkLength = 229 InternalObject->Processor.Length; 230 break; 231 232 233 case ACPI_TYPE_POWER: 234 235 ExternalObject->PowerResource.SystemLevel = 236 InternalObject->PowerResource.SystemLevel; 237 238 ExternalObject->PowerResource.ResourceOrder = 239 InternalObject->PowerResource.ResourceOrder; 240 break; 241 242 243 default: 244 /* 245 * There is no corresponding external object type 246 */ 247 ACPI_ERROR ((AE_INFO, 248 "Unsupported object type, cannot convert to external object: %s", 249 AcpiUtGetTypeName (InternalObject->Common.Type))); 250 251 return_ACPI_STATUS (AE_SUPPORT); 252 } 253 254 return_ACPI_STATUS (Status); 255 } 256 257 258 /******************************************************************************* 259 * 260 * FUNCTION: AcpiUtCopyIelementToEelement 261 * 262 * PARAMETERS: ACPI_PKG_CALLBACK 263 * 264 * RETURN: Status 265 * 266 * DESCRIPTION: Copy one package element to another package element 267 * 268 ******************************************************************************/ 269 270 static ACPI_STATUS 271 AcpiUtCopyIelementToEelement ( 272 UINT8 ObjectType, 273 ACPI_OPERAND_OBJECT *SourceObject, 274 ACPI_GENERIC_STATE *State, 275 void *Context) 276 { 277 ACPI_STATUS Status = AE_OK; 278 ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context; 279 ACPI_SIZE ObjectSpace; 280 UINT32 ThisIndex; 281 ACPI_OBJECT *TargetObject; 282 283 284 ACPI_FUNCTION_ENTRY (); 285 286 287 ThisIndex = State->Pkg.Index; 288 TargetObject = (ACPI_OBJECT *) 289 &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex]; 290 291 switch (ObjectType) 292 { 293 case ACPI_COPY_TYPE_SIMPLE: 294 295 /* 296 * This is a simple or null object 297 */ 298 Status = AcpiUtCopyIsimpleToEsimple (SourceObject, 299 TargetObject, Info->FreeSpace, &ObjectSpace); 300 if (ACPI_FAILURE (Status)) 301 { 302 return (Status); 303 } 304 break; 305 306 307 case ACPI_COPY_TYPE_PACKAGE: 308 309 /* 310 * Build the package object 311 */ 312 TargetObject->Type = ACPI_TYPE_PACKAGE; 313 TargetObject->Package.Count = SourceObject->Package.Count; 314 TargetObject->Package.Elements = 315 ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace); 316 317 /* 318 * Pass the new package object back to the package walk routine 319 */ 320 State->Pkg.ThisTargetObj = TargetObject; 321 322 /* 323 * Save space for the array of objects (Package elements) 324 * update the buffer length counter 325 */ 326 ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD ( 327 (ACPI_SIZE) TargetObject->Package.Count * 328 sizeof (ACPI_OBJECT)); 329 break; 330 331 332 default: 333 return (AE_BAD_PARAMETER); 334 } 335 336 Info->FreeSpace += ObjectSpace; 337 Info->Length += ObjectSpace; 338 return (Status); 339 } 340 341 342 /******************************************************************************* 343 * 344 * FUNCTION: AcpiUtCopyIpackageToEpackage 345 * 346 * PARAMETERS: InternalObject - Pointer to the object we are returning 347 * Buffer - Where the object is returned 348 * SpaceUsed - Where the object length is returned 349 * 350 * RETURN: Status 351 * 352 * DESCRIPTION: This function is called to place a package object in a user 353 * buffer. A package object by definition contains other objects. 354 * 355 * The buffer is assumed to have sufficient space for the object. 356 * The caller must have verified the buffer length needed using 357 * the AcpiUtGetObjectSize function before calling this function. 358 * 359 ******************************************************************************/ 360 361 static ACPI_STATUS 362 AcpiUtCopyIpackageToEpackage ( 363 ACPI_OPERAND_OBJECT *InternalObject, 364 UINT8 *Buffer, 365 ACPI_SIZE *SpaceUsed) 366 { 367 ACPI_OBJECT *ExternalObject; 368 ACPI_STATUS Status; 369 ACPI_PKG_INFO Info; 370 371 372 ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage); 373 374 375 /* 376 * First package at head of the buffer 377 */ 378 ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer); 379 380 /* 381 * Free space begins right after the first package 382 */ 383 Info.Length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 384 Info.FreeSpace = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD ( 385 sizeof (ACPI_OBJECT)); 386 Info.ObjectSpace = 0; 387 Info.NumPackages = 1; 388 389 ExternalObject->Type = InternalObject->Common.Type; 390 ExternalObject->Package.Count = InternalObject->Package.Count; 391 ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT, 392 Info.FreeSpace); 393 394 /* 395 * Leave room for an array of ACPI_OBJECTS in the buffer 396 * and move the free space past it 397 */ 398 Info.Length += (ACPI_SIZE) ExternalObject->Package.Count * 399 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 400 Info.FreeSpace += ExternalObject->Package.Count * 401 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 402 403 Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject, 404 AcpiUtCopyIelementToEelement, &Info); 405 406 *SpaceUsed = Info.Length; 407 return_ACPI_STATUS (Status); 408 } 409 410 411 /******************************************************************************* 412 * 413 * FUNCTION: AcpiUtCopyIobjectToEobject 414 * 415 * PARAMETERS: InternalObject - The internal object to be converted 416 * RetBuffer - Where the object is returned 417 * 418 * RETURN: Status 419 * 420 * DESCRIPTION: This function is called to build an API object to be returned 421 * to the caller. 422 * 423 ******************************************************************************/ 424 425 ACPI_STATUS 426 AcpiUtCopyIobjectToEobject ( 427 ACPI_OPERAND_OBJECT *InternalObject, 428 ACPI_BUFFER *RetBuffer) 429 { 430 ACPI_STATUS Status; 431 432 433 ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject); 434 435 436 if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE) 437 { 438 /* 439 * Package object: Copy all subobjects (including 440 * nested packages) 441 */ 442 Status = AcpiUtCopyIpackageToEpackage (InternalObject, 443 RetBuffer->Pointer, &RetBuffer->Length); 444 } 445 else 446 { 447 /* 448 * Build a simple object (no nested objects) 449 */ 450 Status = AcpiUtCopyIsimpleToEsimple (InternalObject, 451 ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer), 452 ACPI_ADD_PTR (UINT8, RetBuffer->Pointer, 453 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))), 454 &RetBuffer->Length); 455 /* 456 * build simple does not include the object size in the length 457 * so we add it in here 458 */ 459 RetBuffer->Length += sizeof (ACPI_OBJECT); 460 } 461 462 return_ACPI_STATUS (Status); 463 } 464 465 466 /******************************************************************************* 467 * 468 * FUNCTION: AcpiUtCopyEsimpleToIsimple 469 * 470 * PARAMETERS: ExternalObject - The external object to be converted 471 * RetInternalObject - Where the internal object is returned 472 * 473 * RETURN: Status 474 * 475 * DESCRIPTION: This function copies an external object to an internal one. 476 * NOTE: Pointers can be copied, we don't need to copy data. 477 * (The pointers have to be valid in our address space no matter 478 * what we do with them!) 479 * 480 ******************************************************************************/ 481 482 static ACPI_STATUS 483 AcpiUtCopyEsimpleToIsimple ( 484 ACPI_OBJECT *ExternalObject, 485 ACPI_OPERAND_OBJECT **RetInternalObject) 486 { 487 ACPI_OPERAND_OBJECT *InternalObject; 488 489 490 ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple); 491 492 493 /* 494 * Simple types supported are: String, Buffer, Integer 495 */ 496 switch (ExternalObject->Type) 497 { 498 case ACPI_TYPE_STRING: 499 case ACPI_TYPE_BUFFER: 500 case ACPI_TYPE_INTEGER: 501 case ACPI_TYPE_LOCAL_REFERENCE: 502 503 InternalObject = AcpiUtCreateInternalObject ( 504 (UINT8) ExternalObject->Type); 505 if (!InternalObject) 506 { 507 return_ACPI_STATUS (AE_NO_MEMORY); 508 } 509 break; 510 511 case ACPI_TYPE_ANY: /* This is the case for a NULL object */ 512 513 *RetInternalObject = NULL; 514 return_ACPI_STATUS (AE_OK); 515 516 default: 517 /* All other types are not supported */ 518 519 ACPI_ERROR ((AE_INFO, 520 "Unsupported object type, cannot convert to internal object: %s", 521 AcpiUtGetTypeName (ExternalObject->Type))); 522 523 return_ACPI_STATUS (AE_SUPPORT); 524 } 525 526 527 /* Must COPY string and buffer contents */ 528 529 switch (ExternalObject->Type) 530 { 531 case ACPI_TYPE_STRING: 532 533 InternalObject->String.Pointer = 534 ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) 535 ExternalObject->String.Length + 1); 536 537 if (!InternalObject->String.Pointer) 538 { 539 goto ErrorExit; 540 } 541 542 ACPI_MEMCPY (InternalObject->String.Pointer, 543 ExternalObject->String.Pointer, 544 ExternalObject->String.Length); 545 546 InternalObject->String.Length = ExternalObject->String.Length; 547 break; 548 549 550 case ACPI_TYPE_BUFFER: 551 552 InternalObject->Buffer.Pointer = 553 ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length); 554 if (!InternalObject->Buffer.Pointer) 555 { 556 goto ErrorExit; 557 } 558 559 ACPI_MEMCPY (InternalObject->Buffer.Pointer, 560 ExternalObject->Buffer.Pointer, 561 ExternalObject->Buffer.Length); 562 563 InternalObject->Buffer.Length = ExternalObject->Buffer.Length; 564 565 /* Mark buffer data valid */ 566 567 InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID; 568 break; 569 570 571 case ACPI_TYPE_INTEGER: 572 573 InternalObject->Integer.Value = ExternalObject->Integer.Value; 574 break; 575 576 case ACPI_TYPE_LOCAL_REFERENCE: 577 578 /* TBD: should validate incoming handle */ 579 580 InternalObject->Reference.Class = ACPI_REFCLASS_NAME; 581 InternalObject->Reference.Node = ExternalObject->Reference.Handle; 582 break; 583 584 default: 585 /* Other types can't get here */ 586 break; 587 } 588 589 *RetInternalObject = InternalObject; 590 return_ACPI_STATUS (AE_OK); 591 592 593 ErrorExit: 594 AcpiUtRemoveReference (InternalObject); 595 return_ACPI_STATUS (AE_NO_MEMORY); 596 } 597 598 599 /******************************************************************************* 600 * 601 * FUNCTION: AcpiUtCopyEpackageToIpackage 602 * 603 * PARAMETERS: ExternalObject - The external object to be converted 604 * InternalObject - Where the internal object is returned 605 * 606 * RETURN: Status 607 * 608 * DESCRIPTION: Copy an external package object to an internal package. 609 * Handles nested packages. 610 * 611 ******************************************************************************/ 612 613 static ACPI_STATUS 614 AcpiUtCopyEpackageToIpackage ( 615 ACPI_OBJECT *ExternalObject, 616 ACPI_OPERAND_OBJECT **InternalObject) 617 { 618 ACPI_STATUS Status = AE_OK; 619 ACPI_OPERAND_OBJECT *PackageObject; 620 ACPI_OPERAND_OBJECT **PackageElements; 621 UINT32 i; 622 623 624 ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage); 625 626 627 /* Create the package object */ 628 629 PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count); 630 if (!PackageObject) 631 { 632 return_ACPI_STATUS (AE_NO_MEMORY); 633 } 634 635 PackageElements = PackageObject->Package.Elements; 636 637 /* 638 * Recursive implementation. Probably ok, since nested external packages 639 * as parameters should be very rare. 640 */ 641 for (i = 0; i < ExternalObject->Package.Count; i++) 642 { 643 Status = AcpiUtCopyEobjectToIobject ( 644 &ExternalObject->Package.Elements[i], 645 &PackageElements[i]); 646 if (ACPI_FAILURE (Status)) 647 { 648 /* Truncate package and delete it */ 649 650 PackageObject->Package.Count = i; 651 PackageElements[i] = NULL; 652 AcpiUtRemoveReference (PackageObject); 653 return_ACPI_STATUS (Status); 654 } 655 } 656 657 /* Mark package data valid */ 658 659 PackageObject->Package.Flags |= AOPOBJ_DATA_VALID; 660 661 *InternalObject = PackageObject; 662 return_ACPI_STATUS (Status); 663 } 664 665 666 /******************************************************************************* 667 * 668 * FUNCTION: AcpiUtCopyEobjectToIobject 669 * 670 * PARAMETERS: ExternalObject - The external object to be converted 671 * InternalObject - Where the internal object is returned 672 * 673 * RETURN: Status 674 * 675 * DESCRIPTION: Converts an external object to an internal object. 676 * 677 ******************************************************************************/ 678 679 ACPI_STATUS 680 AcpiUtCopyEobjectToIobject ( 681 ACPI_OBJECT *ExternalObject, 682 ACPI_OPERAND_OBJECT **InternalObject) 683 { 684 ACPI_STATUS Status; 685 686 687 ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject); 688 689 690 if (ExternalObject->Type == ACPI_TYPE_PACKAGE) 691 { 692 Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject); 693 } 694 else 695 { 696 /* 697 * Build a simple object (no nested objects) 698 */ 699 Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject); 700 } 701 702 return_ACPI_STATUS (Status); 703 } 704 705 706 /******************************************************************************* 707 * 708 * FUNCTION: AcpiUtCopySimpleObject 709 * 710 * PARAMETERS: SourceDesc - The internal object to be copied 711 * DestDesc - New target object 712 * 713 * RETURN: Status 714 * 715 * DESCRIPTION: Simple copy of one internal object to another. Reference count 716 * of the destination object is preserved. 717 * 718 ******************************************************************************/ 719 720 static ACPI_STATUS 721 AcpiUtCopySimpleObject ( 722 ACPI_OPERAND_OBJECT *SourceDesc, 723 ACPI_OPERAND_OBJECT *DestDesc) 724 { 725 UINT16 ReferenceCount; 726 ACPI_OPERAND_OBJECT *NextObject; 727 ACPI_STATUS Status; 728 ACPI_SIZE CopySize; 729 730 731 /* Save fields from destination that we don't want to overwrite */ 732 733 ReferenceCount = DestDesc->Common.ReferenceCount; 734 NextObject = DestDesc->Common.NextObject; 735 736 /* 737 * Copy the entire source object over the destination object. 738 * Note: Source can be either an operand object or namespace node. 739 */ 740 CopySize = sizeof (ACPI_OPERAND_OBJECT); 741 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED) 742 { 743 CopySize = sizeof (ACPI_NAMESPACE_NODE); 744 } 745 746 ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc), 747 ACPI_CAST_PTR (char, SourceDesc), CopySize); 748 749 /* Restore the saved fields */ 750 751 DestDesc->Common.ReferenceCount = ReferenceCount; 752 DestDesc->Common.NextObject = NextObject; 753 754 /* New object is not static, regardless of source */ 755 756 DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 757 758 /* Handle the objects with extra data */ 759 760 switch (DestDesc->Common.Type) 761 { 762 case ACPI_TYPE_BUFFER: 763 /* 764 * Allocate and copy the actual buffer if and only if: 765 * 1) There is a valid buffer pointer 766 * 2) The buffer has a length > 0 767 */ 768 if ((SourceDesc->Buffer.Pointer) && 769 (SourceDesc->Buffer.Length)) 770 { 771 DestDesc->Buffer.Pointer = 772 ACPI_ALLOCATE (SourceDesc->Buffer.Length); 773 if (!DestDesc->Buffer.Pointer) 774 { 775 return (AE_NO_MEMORY); 776 } 777 778 /* Copy the actual buffer data */ 779 780 ACPI_MEMCPY (DestDesc->Buffer.Pointer, 781 SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length); 782 } 783 break; 784 785 case ACPI_TYPE_STRING: 786 /* 787 * Allocate and copy the actual string if and only if: 788 * 1) There is a valid string pointer 789 * (Pointer to a NULL string is allowed) 790 */ 791 if (SourceDesc->String.Pointer) 792 { 793 DestDesc->String.Pointer = 794 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1); 795 if (!DestDesc->String.Pointer) 796 { 797 return (AE_NO_MEMORY); 798 } 799 800 /* Copy the actual string data */ 801 802 ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer, 803 (ACPI_SIZE) SourceDesc->String.Length + 1); 804 } 805 break; 806 807 case ACPI_TYPE_LOCAL_REFERENCE: 808 /* 809 * We copied the reference object, so we now must add a reference 810 * to the object pointed to by the reference 811 * 812 * DDBHandle reference (from Load/LoadTable) is a special reference, 813 * it does not have a Reference.Object, so does not need to 814 * increase the reference count 815 */ 816 if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE) 817 { 818 break; 819 } 820 821 AcpiUtAddReference (SourceDesc->Reference.Object); 822 break; 823 824 case ACPI_TYPE_REGION: 825 /* 826 * We copied the Region Handler, so we now must add a reference 827 */ 828 if (DestDesc->Region.Handler) 829 { 830 AcpiUtAddReference (DestDesc->Region.Handler); 831 } 832 break; 833 834 /* 835 * For Mutex and Event objects, we cannot simply copy the underlying 836 * OS object. We must create a new one. 837 */ 838 case ACPI_TYPE_MUTEX: 839 840 Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex); 841 if (ACPI_FAILURE (Status)) 842 { 843 return (Status); 844 } 845 break; 846 847 case ACPI_TYPE_EVENT: 848 849 Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, 850 &DestDesc->Event.OsSemaphore); 851 if (ACPI_FAILURE (Status)) 852 { 853 return (Status); 854 } 855 break; 856 857 default: 858 /* Nothing to do for other simple objects */ 859 break; 860 } 861 862 return (AE_OK); 863 } 864 865 866 /******************************************************************************* 867 * 868 * FUNCTION: AcpiUtCopyIelementToIelement 869 * 870 * PARAMETERS: ACPI_PKG_CALLBACK 871 * 872 * RETURN: Status 873 * 874 * DESCRIPTION: Copy one package element to another package element 875 * 876 ******************************************************************************/ 877 878 static ACPI_STATUS 879 AcpiUtCopyIelementToIelement ( 880 UINT8 ObjectType, 881 ACPI_OPERAND_OBJECT *SourceObject, 882 ACPI_GENERIC_STATE *State, 883 void *Context) 884 { 885 ACPI_STATUS Status = AE_OK; 886 UINT32 ThisIndex; 887 ACPI_OPERAND_OBJECT **ThisTargetPtr; 888 ACPI_OPERAND_OBJECT *TargetObject; 889 890 891 ACPI_FUNCTION_ENTRY (); 892 893 894 ThisIndex = State->Pkg.Index; 895 ThisTargetPtr = (ACPI_OPERAND_OBJECT **) 896 &State->Pkg.DestObject->Package.Elements[ThisIndex]; 897 898 switch (ObjectType) 899 { 900 case ACPI_COPY_TYPE_SIMPLE: 901 902 /* A null source object indicates a (legal) null package element */ 903 904 if (SourceObject) 905 { 906 /* 907 * This is a simple object, just copy it 908 */ 909 TargetObject = AcpiUtCreateInternalObject ( 910 SourceObject->Common.Type); 911 if (!TargetObject) 912 { 913 return (AE_NO_MEMORY); 914 } 915 916 Status = AcpiUtCopySimpleObject (SourceObject, TargetObject); 917 if (ACPI_FAILURE (Status)) 918 { 919 goto ErrorExit; 920 } 921 922 *ThisTargetPtr = TargetObject; 923 } 924 else 925 { 926 /* Pass through a null element */ 927 928 *ThisTargetPtr = NULL; 929 } 930 break; 931 932 933 case ACPI_COPY_TYPE_PACKAGE: 934 935 /* 936 * This object is a package - go down another nesting level 937 * Create and build the package object 938 */ 939 TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count); 940 if (!TargetObject) 941 { 942 return (AE_NO_MEMORY); 943 } 944 945 TargetObject->Common.Flags = SourceObject->Common.Flags; 946 947 /* Pass the new package object back to the package walk routine */ 948 949 State->Pkg.ThisTargetObj = TargetObject; 950 951 /* Store the object pointer in the parent package object */ 952 953 *ThisTargetPtr = TargetObject; 954 break; 955 956 957 default: 958 return (AE_BAD_PARAMETER); 959 } 960 961 return (Status); 962 963 ErrorExit: 964 AcpiUtRemoveReference (TargetObject); 965 return (Status); 966 } 967 968 969 /******************************************************************************* 970 * 971 * FUNCTION: AcpiUtCopyIpackageToIpackage 972 * 973 * PARAMETERS: SourceObj - Pointer to the source package object 974 * DestObj - Where the internal object is returned 975 * WalkState - Current Walk state descriptor 976 * 977 * RETURN: Status 978 * 979 * DESCRIPTION: This function is called to copy an internal package object 980 * into another internal package object. 981 * 982 ******************************************************************************/ 983 984 static ACPI_STATUS 985 AcpiUtCopyIpackageToIpackage ( 986 ACPI_OPERAND_OBJECT *SourceObj, 987 ACPI_OPERAND_OBJECT *DestObj, 988 ACPI_WALK_STATE *WalkState) 989 { 990 ACPI_STATUS Status = AE_OK; 991 992 993 ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage); 994 995 996 DestObj->Common.Type = SourceObj->Common.Type; 997 DestObj->Common.Flags = SourceObj->Common.Flags; 998 DestObj->Package.Count = SourceObj->Package.Count; 999 1000 /* 1001 * Create the object array and walk the source package tree 1002 */ 1003 DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED ( 1004 ((ACPI_SIZE) SourceObj->Package.Count + 1) * 1005 sizeof (void *)); 1006 if (!DestObj->Package.Elements) 1007 { 1008 ACPI_ERROR ((AE_INFO, "Package allocation failure")); 1009 return_ACPI_STATUS (AE_NO_MEMORY); 1010 } 1011 1012 /* 1013 * Copy the package element-by-element by walking the package "tree". 1014 * This handles nested packages of arbitrary depth. 1015 */ 1016 Status = AcpiUtWalkPackageTree (SourceObj, DestObj, 1017 AcpiUtCopyIelementToIelement, WalkState); 1018 if (ACPI_FAILURE (Status)) 1019 { 1020 /* On failure, delete the destination package object */ 1021 1022 AcpiUtRemoveReference (DestObj); 1023 } 1024 1025 return_ACPI_STATUS (Status); 1026 } 1027 1028 1029 /******************************************************************************* 1030 * 1031 * FUNCTION: AcpiUtCopyIobjectToIobject 1032 * 1033 * PARAMETERS: SourceDesc - The internal object to be copied 1034 * DestDesc - Where the copied object is returned 1035 * WalkState - Current walk state 1036 * 1037 * RETURN: Status 1038 * 1039 * DESCRIPTION: Copy an internal object to a new internal object 1040 * 1041 ******************************************************************************/ 1042 1043 ACPI_STATUS 1044 AcpiUtCopyIobjectToIobject ( 1045 ACPI_OPERAND_OBJECT *SourceDesc, 1046 ACPI_OPERAND_OBJECT **DestDesc, 1047 ACPI_WALK_STATE *WalkState) 1048 { 1049 ACPI_STATUS Status = AE_OK; 1050 1051 1052 ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject); 1053 1054 1055 /* Create the top level object */ 1056 1057 *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type); 1058 if (!*DestDesc) 1059 { 1060 return_ACPI_STATUS (AE_NO_MEMORY); 1061 } 1062 1063 /* Copy the object and possible subobjects */ 1064 1065 if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE) 1066 { 1067 Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc, 1068 WalkState); 1069 } 1070 else 1071 { 1072 Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc); 1073 } 1074 1075 return_ACPI_STATUS (Status); 1076 } 1077 1078