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 - 2009, 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 the 429 * 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 * BufferPtr - Where the object is returned 489 * 490 * RETURN: Status 491 * 492 * DESCRIPTION: This function is called to build an API object to be returned to 493 * 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 - the status of the call 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 801 802 /* Save fields from destination that we don't want to overwrite */ 803 804 ReferenceCount = DestDesc->Common.ReferenceCount; 805 NextObject = DestDesc->Common.NextObject; 806 807 /* Copy the entire source object over the destination object*/ 808 809 ACPI_MEMCPY ((char *) DestDesc, (char *) SourceDesc, 810 sizeof (ACPI_OPERAND_OBJECT)); 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, 845 SourceDesc->Buffer.Length); 846 } 847 break; 848 849 case ACPI_TYPE_STRING: 850 /* 851 * Allocate and copy the actual string if and only if: 852 * 1) There is a valid string pointer 853 * (Pointer to a NULL string is allowed) 854 */ 855 if (SourceDesc->String.Pointer) 856 { 857 DestDesc->String.Pointer = 858 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1); 859 if (!DestDesc->String.Pointer) 860 { 861 return (AE_NO_MEMORY); 862 } 863 864 /* Copy the actual string data */ 865 866 ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer, 867 (ACPI_SIZE) SourceDesc->String.Length + 1); 868 } 869 break; 870 871 case ACPI_TYPE_LOCAL_REFERENCE: 872 /* 873 * We copied the reference object, so we now must add a reference 874 * to the object pointed to by the reference 875 * 876 * DDBHandle reference (from Load/LoadTable) is a special reference, 877 * it does not have a Reference.Object, so does not need to 878 * increase the reference count 879 */ 880 if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE) 881 { 882 break; 883 } 884 885 AcpiUtAddReference (SourceDesc->Reference.Object); 886 break; 887 888 case ACPI_TYPE_REGION: 889 /* 890 * We copied the Region Handler, so we now must add a reference 891 */ 892 if (DestDesc->Region.Handler) 893 { 894 AcpiUtAddReference (DestDesc->Region.Handler); 895 } 896 break; 897 898 /* 899 * For Mutex and Event objects, we cannot simply copy the underlying 900 * OS object. We must create a new one. 901 */ 902 case ACPI_TYPE_MUTEX: 903 904 Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex); 905 if (ACPI_FAILURE (Status)) 906 { 907 return (Status); 908 } 909 break; 910 911 case ACPI_TYPE_EVENT: 912 913 Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, 914 &DestDesc->Event.OsSemaphore); 915 if (ACPI_FAILURE (Status)) 916 { 917 return (Status); 918 } 919 break; 920 921 default: 922 /* Nothing to do for other simple objects */ 923 break; 924 } 925 926 return (AE_OK); 927 } 928 929 930 /******************************************************************************* 931 * 932 * FUNCTION: AcpiUtCopyIelementToIelement 933 * 934 * PARAMETERS: ACPI_PKG_CALLBACK 935 * 936 * RETURN: Status 937 * 938 * DESCRIPTION: Copy one package element to another package element 939 * 940 ******************************************************************************/ 941 942 static ACPI_STATUS 943 AcpiUtCopyIelementToIelement ( 944 UINT8 ObjectType, 945 ACPI_OPERAND_OBJECT *SourceObject, 946 ACPI_GENERIC_STATE *State, 947 void *Context) 948 { 949 ACPI_STATUS Status = AE_OK; 950 UINT32 ThisIndex; 951 ACPI_OPERAND_OBJECT **ThisTargetPtr; 952 ACPI_OPERAND_OBJECT *TargetObject; 953 954 955 ACPI_FUNCTION_ENTRY (); 956 957 958 ThisIndex = State->Pkg.Index; 959 ThisTargetPtr = (ACPI_OPERAND_OBJECT **) 960 &State->Pkg.DestObject->Package.Elements[ThisIndex]; 961 962 switch (ObjectType) 963 { 964 case ACPI_COPY_TYPE_SIMPLE: 965 966 /* A null source object indicates a (legal) null package element */ 967 968 if (SourceObject) 969 { 970 /* 971 * This is a simple object, just copy it 972 */ 973 TargetObject = AcpiUtCreateInternalObject ( 974 SourceObject->Common.Type); 975 if (!TargetObject) 976 { 977 return (AE_NO_MEMORY); 978 } 979 980 Status = AcpiUtCopySimpleObject (SourceObject, TargetObject); 981 if (ACPI_FAILURE (Status)) 982 { 983 goto ErrorExit; 984 } 985 986 *ThisTargetPtr = TargetObject; 987 } 988 else 989 { 990 /* Pass through a null element */ 991 992 *ThisTargetPtr = NULL; 993 } 994 break; 995 996 997 case ACPI_COPY_TYPE_PACKAGE: 998 999 /* 1000 * This object is a package - go down another nesting level 1001 * Create and build the package object 1002 */ 1003 TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count); 1004 if (!TargetObject) 1005 { 1006 return (AE_NO_MEMORY); 1007 } 1008 1009 TargetObject->Common.Flags = SourceObject->Common.Flags; 1010 1011 /* Pass the new package object back to the package walk routine */ 1012 1013 State->Pkg.ThisTargetObj = TargetObject; 1014 1015 /* Store the object pointer in the parent package object */ 1016 1017 *ThisTargetPtr = TargetObject; 1018 break; 1019 1020 1021 default: 1022 return (AE_BAD_PARAMETER); 1023 } 1024 1025 return (Status); 1026 1027 ErrorExit: 1028 AcpiUtRemoveReference (TargetObject); 1029 return (Status); 1030 } 1031 1032 1033 /******************************************************************************* 1034 * 1035 * FUNCTION: AcpiUtCopyIpackageToIpackage 1036 * 1037 * PARAMETERS: *SourceObj - Pointer to the source package object 1038 * *DestObj - Where the internal object is returned 1039 * 1040 * RETURN: Status - the status of the call 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: WalkState - Current walk state 1097 * SourceDesc - The internal object to be copied 1098 * DestDesc - Where the copied object is returned 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 return_ACPI_STATUS (Status); 1139 } 1140 1141 1142