1 /****************************************************************************** 2 * 3 * Module Name: utcopy - Internal to external object translation utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 *) 280 &((ACPI_OBJECT *)(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 + ACPI_ROUND_UP_TO_NATIVE_WORD ( 373 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 = ACPI_CAST_PTR (ACPI_OBJECT, 380 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 (ExternalObject->Package.Count); 619 if (!PackageObject) 620 { 621 return_ACPI_STATUS (AE_NO_MEMORY); 622 } 623 624 PackageElements = PackageObject->Package.Elements; 625 626 /* 627 * Recursive implementation. Probably ok, since nested external packages 628 * as parameters should be very rare. 629 */ 630 for (i = 0; i < ExternalObject->Package.Count; i++) 631 { 632 Status = AcpiUtCopyEobjectToIobject ( 633 &ExternalObject->Package.Elements[i], 634 &PackageElements[i]); 635 if (ACPI_FAILURE (Status)) 636 { 637 /* Truncate package and delete it */ 638 639 PackageObject->Package.Count = i; 640 PackageElements[i] = NULL; 641 AcpiUtRemoveReference (PackageObject); 642 return_ACPI_STATUS (Status); 643 } 644 } 645 646 /* Mark package data valid */ 647 648 PackageObject->Package.Flags |= AOPOBJ_DATA_VALID; 649 650 *InternalObject = PackageObject; 651 return_ACPI_STATUS (Status); 652 } 653 654 655 /******************************************************************************* 656 * 657 * FUNCTION: AcpiUtCopyEobjectToIobject 658 * 659 * PARAMETERS: ExternalObject - The external object to be converted 660 * InternalObject - Where the internal object is returned 661 * 662 * RETURN: Status 663 * 664 * DESCRIPTION: Converts an external object to an internal object. 665 * 666 ******************************************************************************/ 667 668 ACPI_STATUS 669 AcpiUtCopyEobjectToIobject ( 670 ACPI_OBJECT *ExternalObject, 671 ACPI_OPERAND_OBJECT **InternalObject) 672 { 673 ACPI_STATUS Status; 674 675 676 ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject); 677 678 679 if (ExternalObject->Type == ACPI_TYPE_PACKAGE) 680 { 681 Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject); 682 } 683 else 684 { 685 /* 686 * Build a simple object (no nested objects) 687 */ 688 Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject); 689 } 690 691 return_ACPI_STATUS (Status); 692 } 693 694 695 /******************************************************************************* 696 * 697 * FUNCTION: AcpiUtCopySimpleObject 698 * 699 * PARAMETERS: SourceDesc - The internal object to be copied 700 * DestDesc - New target object 701 * 702 * RETURN: Status 703 * 704 * DESCRIPTION: Simple copy of one internal object to another. Reference count 705 * of the destination object is preserved. 706 * 707 ******************************************************************************/ 708 709 static ACPI_STATUS 710 AcpiUtCopySimpleObject ( 711 ACPI_OPERAND_OBJECT *SourceDesc, 712 ACPI_OPERAND_OBJECT *DestDesc) 713 { 714 UINT16 ReferenceCount; 715 ACPI_OPERAND_OBJECT *NextObject; 716 ACPI_STATUS Status; 717 ACPI_SIZE CopySize; 718 719 720 /* Save fields from destination that we don't want to overwrite */ 721 722 ReferenceCount = DestDesc->Common.ReferenceCount; 723 NextObject = DestDesc->Common.NextObject; 724 725 /* 726 * Copy the entire source object over the destination object. 727 * Note: Source can be either an operand object or namespace node. 728 */ 729 CopySize = sizeof (ACPI_OPERAND_OBJECT); 730 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED) 731 { 732 CopySize = sizeof (ACPI_NAMESPACE_NODE); 733 } 734 735 memcpy (ACPI_CAST_PTR (char, DestDesc), 736 ACPI_CAST_PTR (char, SourceDesc), CopySize); 737 738 /* Restore the saved fields */ 739 740 DestDesc->Common.ReferenceCount = ReferenceCount; 741 DestDesc->Common.NextObject = NextObject; 742 743 /* New object is not static, regardless of source */ 744 745 DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 746 747 /* Handle the objects with extra data */ 748 749 switch (DestDesc->Common.Type) 750 { 751 case ACPI_TYPE_BUFFER: 752 /* 753 * Allocate and copy the actual buffer if and only if: 754 * 1) There is a valid buffer pointer 755 * 2) The buffer has a length > 0 756 */ 757 if ((SourceDesc->Buffer.Pointer) && 758 (SourceDesc->Buffer.Length)) 759 { 760 DestDesc->Buffer.Pointer = 761 ACPI_ALLOCATE (SourceDesc->Buffer.Length); 762 if (!DestDesc->Buffer.Pointer) 763 { 764 return (AE_NO_MEMORY); 765 } 766 767 /* Copy the actual buffer data */ 768 769 memcpy (DestDesc->Buffer.Pointer, 770 SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length); 771 } 772 break; 773 774 case ACPI_TYPE_STRING: 775 /* 776 * Allocate and copy the actual string if and only if: 777 * 1) There is a valid string pointer 778 * (Pointer to a NULL string is allowed) 779 */ 780 if (SourceDesc->String.Pointer) 781 { 782 DestDesc->String.Pointer = 783 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1); 784 if (!DestDesc->String.Pointer) 785 { 786 return (AE_NO_MEMORY); 787 } 788 789 /* Copy the actual string data */ 790 791 memcpy (DestDesc->String.Pointer, SourceDesc->String.Pointer, 792 (ACPI_SIZE) SourceDesc->String.Length + 1); 793 } 794 break; 795 796 case ACPI_TYPE_LOCAL_REFERENCE: 797 /* 798 * We copied the reference object, so we now must add a reference 799 * to the object pointed to by the reference 800 * 801 * DDBHandle reference (from Load/LoadTable) is a special reference, 802 * it does not have a Reference.Object, so does not need to 803 * increase the reference count 804 */ 805 if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE) 806 { 807 break; 808 } 809 810 AcpiUtAddReference (SourceDesc->Reference.Object); 811 break; 812 813 case ACPI_TYPE_REGION: 814 /* 815 * We copied the Region Handler, so we now must add a reference 816 */ 817 if (DestDesc->Region.Handler) 818 { 819 AcpiUtAddReference (DestDesc->Region.Handler); 820 } 821 break; 822 823 /* 824 * For Mutex and Event objects, we cannot simply copy the underlying 825 * OS object. We must create a new one. 826 */ 827 case ACPI_TYPE_MUTEX: 828 829 Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex); 830 if (ACPI_FAILURE (Status)) 831 { 832 return (Status); 833 } 834 break; 835 836 case ACPI_TYPE_EVENT: 837 838 Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, 839 &DestDesc->Event.OsSemaphore); 840 if (ACPI_FAILURE (Status)) 841 { 842 return (Status); 843 } 844 break; 845 846 default: 847 848 /* Nothing to do for other simple objects */ 849 850 break; 851 } 852 853 return (AE_OK); 854 } 855 856 857 /******************************************************************************* 858 * 859 * FUNCTION: AcpiUtCopyIelementToIelement 860 * 861 * PARAMETERS: ACPI_PKG_CALLBACK 862 * 863 * RETURN: Status 864 * 865 * DESCRIPTION: Copy one package element to another package element 866 * 867 ******************************************************************************/ 868 869 static ACPI_STATUS 870 AcpiUtCopyIelementToIelement ( 871 UINT8 ObjectType, 872 ACPI_OPERAND_OBJECT *SourceObject, 873 ACPI_GENERIC_STATE *State, 874 void *Context) 875 { 876 ACPI_STATUS Status = AE_OK; 877 UINT32 ThisIndex; 878 ACPI_OPERAND_OBJECT **ThisTargetPtr; 879 ACPI_OPERAND_OBJECT *TargetObject; 880 881 882 ACPI_FUNCTION_ENTRY (); 883 884 885 ThisIndex = State->Pkg.Index; 886 ThisTargetPtr = (ACPI_OPERAND_OBJECT **) 887 &State->Pkg.DestObject->Package.Elements[ThisIndex]; 888 889 switch (ObjectType) 890 { 891 case ACPI_COPY_TYPE_SIMPLE: 892 893 /* A null source object indicates a (legal) null package element */ 894 895 if (SourceObject) 896 { 897 /* 898 * This is a simple object, just copy it 899 */ 900 TargetObject = AcpiUtCreateInternalObject ( 901 SourceObject->Common.Type); 902 if (!TargetObject) 903 { 904 return (AE_NO_MEMORY); 905 } 906 907 Status = AcpiUtCopySimpleObject (SourceObject, TargetObject); 908 if (ACPI_FAILURE (Status)) 909 { 910 goto ErrorExit; 911 } 912 913 *ThisTargetPtr = TargetObject; 914 } 915 else 916 { 917 /* Pass through a null element */ 918 919 *ThisTargetPtr = NULL; 920 } 921 break; 922 923 case ACPI_COPY_TYPE_PACKAGE: 924 /* 925 * This object is a package - go down another nesting level 926 * Create and build the package object 927 */ 928 TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count); 929 if (!TargetObject) 930 { 931 return (AE_NO_MEMORY); 932 } 933 934 TargetObject->Common.Flags = SourceObject->Common.Flags; 935 936 /* Pass the new package object back to the package walk routine */ 937 938 State->Pkg.ThisTargetObj = TargetObject; 939 940 /* Store the object pointer in the parent package object */ 941 942 *ThisTargetPtr = TargetObject; 943 break; 944 945 default: 946 947 return (AE_BAD_PARAMETER); 948 } 949 950 return (Status); 951 952 ErrorExit: 953 AcpiUtRemoveReference (TargetObject); 954 return (Status); 955 } 956 957 958 /******************************************************************************* 959 * 960 * FUNCTION: AcpiUtCopyIpackageToIpackage 961 * 962 * PARAMETERS: SourceObj - Pointer to the source package object 963 * DestObj - Where the internal object is returned 964 * WalkState - Current Walk state descriptor 965 * 966 * RETURN: Status 967 * 968 * DESCRIPTION: This function is called to copy an internal package object 969 * into another internal package object. 970 * 971 ******************************************************************************/ 972 973 static ACPI_STATUS 974 AcpiUtCopyIpackageToIpackage ( 975 ACPI_OPERAND_OBJECT *SourceObj, 976 ACPI_OPERAND_OBJECT *DestObj, 977 ACPI_WALK_STATE *WalkState) 978 { 979 ACPI_STATUS Status = AE_OK; 980 981 982 ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage); 983 984 985 DestObj->Common.Type = SourceObj->Common.Type; 986 DestObj->Common.Flags = SourceObj->Common.Flags; 987 DestObj->Package.Count = SourceObj->Package.Count; 988 989 /* 990 * Create the object array and walk the source package tree 991 */ 992 DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED ( 993 ((ACPI_SIZE) SourceObj->Package.Count + 1) * 994 sizeof (void *)); 995 if (!DestObj->Package.Elements) 996 { 997 ACPI_ERROR ((AE_INFO, "Package allocation failure")); 998 return_ACPI_STATUS (AE_NO_MEMORY); 999 } 1000 1001 /* 1002 * Copy the package element-by-element by walking the package "tree". 1003 * This handles nested packages of arbitrary depth. 1004 */ 1005 Status = AcpiUtWalkPackageTree (SourceObj, DestObj, 1006 AcpiUtCopyIelementToIelement, WalkState); 1007 if (ACPI_FAILURE (Status)) 1008 { 1009 /* On failure, delete the destination package object */ 1010 1011 AcpiUtRemoveReference (DestObj); 1012 } 1013 1014 return_ACPI_STATUS (Status); 1015 } 1016 1017 1018 /******************************************************************************* 1019 * 1020 * FUNCTION: AcpiUtCopyIobjectToIobject 1021 * 1022 * PARAMETERS: SourceDesc - The internal object to be copied 1023 * DestDesc - Where the copied object is returned 1024 * WalkState - Current walk state 1025 * 1026 * RETURN: Status 1027 * 1028 * DESCRIPTION: Copy an internal object to a new internal object 1029 * 1030 ******************************************************************************/ 1031 1032 ACPI_STATUS 1033 AcpiUtCopyIobjectToIobject ( 1034 ACPI_OPERAND_OBJECT *SourceDesc, 1035 ACPI_OPERAND_OBJECT **DestDesc, 1036 ACPI_WALK_STATE *WalkState) 1037 { 1038 ACPI_STATUS Status = AE_OK; 1039 1040 1041 ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject); 1042 1043 1044 /* Create the top level object */ 1045 1046 *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type); 1047 if (!*DestDesc) 1048 { 1049 return_ACPI_STATUS (AE_NO_MEMORY); 1050 } 1051 1052 /* Copy the object and possible subobjects */ 1053 1054 if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE) 1055 { 1056 Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc, 1057 WalkState); 1058 } 1059 else 1060 { 1061 Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc); 1062 } 1063 1064 /* Delete the allocated object if copy failed */ 1065 1066 if (ACPI_FAILURE (Status)) 1067 { 1068 AcpiUtRemoveReference(*DestDesc); 1069 } 1070 1071 return_ACPI_STATUS (Status); 1072 } 1073