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