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