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