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