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