1 /******************************************************************************
   2  *
   3  * Module Name: utobject - ACPI object create/delete/size/cache routines
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #define __UTOBJECT_C__
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 #include "acnamesp.h"
  49 
  50 
  51 #define _COMPONENT          ACPI_UTILITIES
  52         ACPI_MODULE_NAME    ("utobject")
  53 
  54 /* Local prototypes */
  55 
  56 static ACPI_STATUS
  57 AcpiUtGetSimpleObjectSize (
  58     ACPI_OPERAND_OBJECT     *Obj,
  59     ACPI_SIZE               *ObjLength);
  60 
  61 static ACPI_STATUS
  62 AcpiUtGetPackageObjectSize (
  63     ACPI_OPERAND_OBJECT     *Obj,
  64     ACPI_SIZE               *ObjLength);
  65 
  66 static ACPI_STATUS
  67 AcpiUtGetElementLength (
  68     UINT8                   ObjectType,
  69     ACPI_OPERAND_OBJECT     *SourceObject,
  70     ACPI_GENERIC_STATE      *State,
  71     void                    *Context);
  72 
  73 
  74 /*******************************************************************************
  75  *
  76  * FUNCTION:    AcpiUtCreateInternalObjectDbg
  77  *
  78  * PARAMETERS:  ModuleName          - Source file name of caller
  79  *              LineNumber          - Line number of caller
  80  *              ComponentId         - Component type of caller
  81  *              Type                - ACPI Type of the new object
  82  *
  83  * RETURN:      A new internal object, null on failure
  84  *
  85  * DESCRIPTION: Create and initialize a new internal object.
  86  *
  87  * NOTE:        We always allocate the worst-case object descriptor because
  88  *              these objects are cached, and we want them to be
  89  *              one-size-satisifies-any-request. This in itself may not be
  90  *              the most memory efficient, but the efficiency of the object
  91  *              cache should more than make up for this!
  92  *
  93  ******************************************************************************/
  94 
  95 ACPI_OPERAND_OBJECT  *
  96 AcpiUtCreateInternalObjectDbg (
  97     const char              *ModuleName,
  98     UINT32                  LineNumber,
  99     UINT32                  ComponentId,
 100     ACPI_OBJECT_TYPE        Type)
 101 {
 102     ACPI_OPERAND_OBJECT     *Object;
 103     ACPI_OPERAND_OBJECT     *SecondObject;
 104 
 105 
 106     ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg,
 107         AcpiUtGetTypeName (Type));
 108 
 109 
 110     /* Allocate the raw object descriptor */
 111 
 112     Object = AcpiUtAllocateObjectDescDbg (ModuleName, LineNumber, ComponentId);
 113     if (!Object)
 114     {
 115         return_PTR (NULL);
 116     }
 117 
 118     switch (Type)
 119     {
 120     case ACPI_TYPE_REGION:
 121     case ACPI_TYPE_BUFFER_FIELD:
 122     case ACPI_TYPE_LOCAL_BANK_FIELD:
 123 
 124         /* These types require a secondary object */
 125 
 126         SecondObject = AcpiUtAllocateObjectDescDbg (ModuleName,
 127                             LineNumber, ComponentId);
 128         if (!SecondObject)
 129         {
 130             AcpiUtDeleteObjectDesc (Object);
 131             return_PTR (NULL);
 132         }
 133 
 134         SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA;
 135         SecondObject->Common.ReferenceCount = 1;
 136 
 137         /* Link the second object to the first */
 138 
 139         Object->Common.NextObject = SecondObject;
 140         break;
 141 
 142     default:
 143 
 144         /* All others have no secondary object */
 145         break;
 146     }
 147 
 148     /* Save the object type in the object descriptor */
 149 
 150     Object->Common.Type = (UINT8) Type;
 151 
 152     /* Init the reference count */
 153 
 154     Object->Common.ReferenceCount = 1;
 155 
 156     /* Any per-type initialization should go here */
 157 
 158     return_PTR (Object);
 159 }
 160 
 161 
 162 /*******************************************************************************
 163  *
 164  * FUNCTION:    AcpiUtCreatePackageObject
 165  *
 166  * PARAMETERS:  Count               - Number of package elements
 167  *
 168  * RETURN:      Pointer to a new Package object, null on failure
 169  *
 170  * DESCRIPTION: Create a fully initialized package object
 171  *
 172  ******************************************************************************/
 173 
 174 ACPI_OPERAND_OBJECT *
 175 AcpiUtCreatePackageObject (
 176     UINT32                  Count)
 177 {
 178     ACPI_OPERAND_OBJECT     *PackageDesc;
 179     ACPI_OPERAND_OBJECT     **PackageElements;
 180 
 181 
 182     ACPI_FUNCTION_TRACE_U32 (UtCreatePackageObject, Count);
 183 
 184 
 185     /* Create a new Package object */
 186 
 187     PackageDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
 188     if (!PackageDesc)
 189     {
 190         return_PTR (NULL);
 191     }
 192 
 193     /*
 194      * Create the element array. Count+1 allows the array to be null
 195      * terminated.
 196      */
 197     PackageElements = ACPI_ALLOCATE_ZEROED (
 198                         ((ACPI_SIZE) Count + 1) * sizeof (void *));
 199     if (!PackageElements)
 200     {
 201         ACPI_FREE (PackageDesc);
 202         return_PTR (NULL);
 203     }
 204 
 205     PackageDesc->Package.Count = Count;
 206     PackageDesc->Package.Elements = PackageElements;
 207     return_PTR (PackageDesc);
 208 }
 209 
 210 
 211 /*******************************************************************************
 212  *
 213  * FUNCTION:    AcpiUtCreateIntegerObject
 214  *
 215  * PARAMETERS:  InitialValue        - Initial value for the integer
 216  *
 217  * RETURN:      Pointer to a new Integer object, null on failure
 218  *
 219  * DESCRIPTION: Create an initialized integer object
 220  *
 221  ******************************************************************************/
 222 
 223 ACPI_OPERAND_OBJECT *
 224 AcpiUtCreateIntegerObject (
 225     UINT64                  InitialValue)
 226 {
 227     ACPI_OPERAND_OBJECT     *IntegerDesc;
 228 
 229 
 230     ACPI_FUNCTION_TRACE (UtCreateIntegerObject);
 231 
 232 
 233     /* Create and initialize a new integer object */
 234 
 235     IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
 236     if (!IntegerDesc)
 237     {
 238         return_PTR (NULL);
 239     }
 240 
 241     IntegerDesc->Integer.Value = InitialValue;
 242     return_PTR (IntegerDesc);
 243 }
 244 
 245 
 246 /*******************************************************************************
 247  *
 248  * FUNCTION:    AcpiUtCreateBufferObject
 249  *
 250  * PARAMETERS:  BufferSize             - Size of buffer to be created
 251  *
 252  * RETURN:      Pointer to a new Buffer object, null on failure
 253  *
 254  * DESCRIPTION: Create a fully initialized buffer object
 255  *
 256  ******************************************************************************/
 257 
 258 ACPI_OPERAND_OBJECT *
 259 AcpiUtCreateBufferObject (
 260     ACPI_SIZE               BufferSize)
 261 {
 262     ACPI_OPERAND_OBJECT     *BufferDesc;
 263     UINT8                   *Buffer = NULL;
 264 
 265 
 266     ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize);
 267 
 268 
 269     /* Create a new Buffer object */
 270 
 271     BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
 272     if (!BufferDesc)
 273     {
 274         return_PTR (NULL);
 275     }
 276 
 277     /* Create an actual buffer only if size > 0 */
 278 
 279     if (BufferSize > 0)
 280     {
 281         /* Allocate the actual buffer */
 282 
 283         Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
 284         if (!Buffer)
 285         {
 286             ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
 287                 (UINT32) BufferSize));
 288             AcpiUtRemoveReference (BufferDesc);
 289             return_PTR (NULL);
 290         }
 291     }
 292 
 293     /* Complete buffer object initialization */
 294 
 295     BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
 296     BufferDesc->Buffer.Pointer = Buffer;
 297     BufferDesc->Buffer.Length = (UINT32) BufferSize;
 298 
 299     /* Return the new buffer descriptor */
 300 
 301     return_PTR (BufferDesc);
 302 }
 303 
 304 
 305 /*******************************************************************************
 306  *
 307  * FUNCTION:    AcpiUtCreateStringObject
 308  *
 309  * PARAMETERS:  StringSize          - Size of string to be created. Does not
 310  *                                    include NULL terminator, this is added
 311  *                                    automatically.
 312  *
 313  * RETURN:      Pointer to a new String object
 314  *
 315  * DESCRIPTION: Create a fully initialized string object
 316  *
 317  ******************************************************************************/
 318 
 319 ACPI_OPERAND_OBJECT *
 320 AcpiUtCreateStringObject (
 321     ACPI_SIZE               StringSize)
 322 {
 323     ACPI_OPERAND_OBJECT     *StringDesc;
 324     char                    *String;
 325 
 326 
 327     ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize);
 328 
 329 
 330     /* Create a new String object */
 331 
 332     StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
 333     if (!StringDesc)
 334     {
 335         return_PTR (NULL);
 336     }
 337 
 338     /*
 339      * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
 340      * NOTE: Zero-length strings are NULL terminated
 341      */
 342     String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
 343     if (!String)
 344     {
 345         ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
 346             (UINT32) StringSize));
 347         AcpiUtRemoveReference (StringDesc);
 348         return_PTR (NULL);
 349     }
 350 
 351     /* Complete string object initialization */
 352 
 353     StringDesc->String.Pointer = String;
 354     StringDesc->String.Length = (UINT32) StringSize;
 355 
 356     /* Return the new string descriptor */
 357 
 358     return_PTR (StringDesc);
 359 }
 360 
 361 
 362 /*******************************************************************************
 363  *
 364  * FUNCTION:    AcpiUtValidInternalObject
 365  *
 366  * PARAMETERS:  Object              - Object to be validated
 367  *
 368  * RETURN:      TRUE if object is valid, FALSE otherwise
 369  *
 370  * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT
 371  *
 372  ******************************************************************************/
 373 
 374 BOOLEAN
 375 AcpiUtValidInternalObject (
 376     void                    *Object)
 377 {
 378 
 379     ACPI_FUNCTION_NAME (UtValidInternalObject);
 380 
 381 
 382     /* Check for a null pointer */
 383 
 384     if (!Object)
 385     {
 386         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
 387         return (FALSE);
 388     }
 389 
 390     /* Check the descriptor type field */
 391 
 392     switch (ACPI_GET_DESCRIPTOR_TYPE (Object))
 393     {
 394     case ACPI_DESC_TYPE_OPERAND:
 395 
 396         /* The object appears to be a valid ACPI_OPERAND_OBJECT */
 397 
 398         return (TRUE);
 399 
 400     default:
 401 
 402         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 403                 "%p is not not an ACPI operand obj [%s]\n",
 404                 Object, AcpiUtGetDescriptorName (Object)));
 405         break;
 406     }
 407 
 408     return (FALSE);
 409 }
 410 
 411 
 412 /*******************************************************************************
 413  *
 414  * FUNCTION:    AcpiUtAllocateObjectDescDbg
 415  *
 416  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
 417  *              LineNumber          - Caller's line number (for error output)
 418  *              ComponentId         - Caller's component ID (for error output)
 419  *
 420  * RETURN:      Pointer to newly allocated object descriptor. Null on error
 421  *
 422  * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
 423  *              error conditions.
 424  *
 425  ******************************************************************************/
 426 
 427 void *
 428 AcpiUtAllocateObjectDescDbg (
 429     const char              *ModuleName,
 430     UINT32                  LineNumber,
 431     UINT32                  ComponentId)
 432 {
 433     ACPI_OPERAND_OBJECT     *Object;
 434 
 435 
 436     ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg);
 437 
 438 
 439     Object = AcpiOsAcquireObject (AcpiGbl_OperandCache);
 440     if (!Object)
 441     {
 442         ACPI_ERROR ((ModuleName, LineNumber,
 443             "Could not allocate an object descriptor"));
 444 
 445         return_PTR (NULL);
 446     }
 447 
 448     /* Mark the descriptor type */
 449 
 450     ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND);
 451 
 452     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
 453             Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT)));
 454 
 455     return_PTR (Object);
 456 }
 457 
 458 
 459 /*******************************************************************************
 460  *
 461  * FUNCTION:    AcpiUtDeleteObjectDesc
 462  *
 463  * PARAMETERS:  Object          - An Acpi internal object to be deleted
 464  *
 465  * RETURN:      None.
 466  *
 467  * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
 468  *
 469  ******************************************************************************/
 470 
 471 void
 472 AcpiUtDeleteObjectDesc (
 473     ACPI_OPERAND_OBJECT     *Object)
 474 {
 475     ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
 476 
 477 
 478     /* Object must be of type ACPI_OPERAND_OBJECT */
 479 
 480     if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
 481     {
 482         ACPI_ERROR ((AE_INFO,
 483             "%p is not an ACPI Operand object [%s]", Object,
 484             AcpiUtGetDescriptorName (Object)));
 485         return_VOID;
 486     }
 487 
 488     (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object);
 489     return_VOID;
 490 }
 491 
 492 
 493 /*******************************************************************************
 494  *
 495  * FUNCTION:    AcpiUtGetSimpleObjectSize
 496  *
 497  * PARAMETERS:  InternalObject     - An ACPI operand object
 498  *              ObjLength          - Where the length is returned
 499  *
 500  * RETURN:      Status
 501  *
 502  * DESCRIPTION: This function is called to determine the space required to
 503  *              contain a simple object for return to an external user.
 504  *
 505  *              The length includes the object structure plus any additional
 506  *              needed space.
 507  *
 508  ******************************************************************************/
 509 
 510 static ACPI_STATUS
 511 AcpiUtGetSimpleObjectSize (
 512     ACPI_OPERAND_OBJECT     *InternalObject,
 513     ACPI_SIZE               *ObjLength)
 514 {
 515     ACPI_SIZE               Length;
 516     ACPI_SIZE               Size;
 517     ACPI_STATUS             Status = AE_OK;
 518 
 519 
 520     ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject);
 521 
 522 
 523     /* Start with the length of the (external) Acpi object */
 524 
 525     Length = sizeof (ACPI_OBJECT);
 526 
 527     /* A NULL object is allowed, can be a legal uninitialized package element */
 528 
 529     if (!InternalObject)
 530     {
 531         /*
 532          * Object is NULL, just return the length of ACPI_OBJECT
 533          * (A NULL ACPI_OBJECT is an object of all zeroes.)
 534          */
 535         *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
 536         return_ACPI_STATUS (AE_OK);
 537     }
 538 
 539     /* A Namespace Node should never appear here */
 540 
 541     if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED)
 542     {
 543         /* A namespace node should never get here */
 544 
 545         return_ACPI_STATUS (AE_AML_INTERNAL);
 546     }
 547 
 548     /*
 549      * The final length depends on the object type
 550      * Strings and Buffers are packed right up against the parent object and
 551      * must be accessed bytewise or there may be alignment problems on
 552      * certain processors
 553      */
 554     switch (InternalObject->Common.Type)
 555     {
 556     case ACPI_TYPE_STRING:
 557 
 558         Length += (ACPI_SIZE) InternalObject->String.Length + 1;
 559         break;
 560 
 561     case ACPI_TYPE_BUFFER:
 562 
 563         Length += (ACPI_SIZE) InternalObject->Buffer.Length;
 564         break;
 565 
 566     case ACPI_TYPE_INTEGER:
 567     case ACPI_TYPE_PROCESSOR:
 568     case ACPI_TYPE_POWER:
 569 
 570         /* No extra data for these types */
 571 
 572         break;
 573 
 574     case ACPI_TYPE_LOCAL_REFERENCE:
 575 
 576         switch (InternalObject->Reference.Class)
 577         {
 578         case ACPI_REFCLASS_NAME:
 579             /*
 580              * Get the actual length of the full pathname to this object.
 581              * The reference will be converted to the pathname to the object
 582              */
 583             Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node);
 584             if (!Size)
 585             {
 586                 return_ACPI_STATUS (AE_BAD_PARAMETER);
 587             }
 588 
 589             Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size);
 590             break;
 591 
 592         default:
 593             /*
 594              * No other reference opcodes are supported.
 595              * Notably, Locals and Args are not supported, but this may be
 596              * required eventually.
 597              */
 598             ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
 599                 "unsupported Reference Class [%s] 0x%X in object %p",
 600                 AcpiUtGetReferenceName (InternalObject),
 601                 InternalObject->Reference.Class, InternalObject));
 602             Status = AE_TYPE;
 603             break;
 604         }
 605         break;
 606 
 607     default:
 608 
 609         ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
 610             "unsupported type [%s] 0x%X in object %p",
 611             AcpiUtGetObjectTypeName (InternalObject),
 612             InternalObject->Common.Type, InternalObject));
 613         Status = AE_TYPE;
 614         break;
 615     }
 616 
 617     /*
 618      * Account for the space required by the object rounded up to the next
 619      * multiple of the machine word size. This keeps each object aligned
 620      * on a machine word boundary. (preventing alignment faults on some
 621      * machines.)
 622      */
 623     *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
 624     return_ACPI_STATUS (Status);
 625 }
 626 
 627 
 628 /*******************************************************************************
 629  *
 630  * FUNCTION:    AcpiUtGetElementLength
 631  *
 632  * PARAMETERS:  ACPI_PKG_CALLBACK
 633  *
 634  * RETURN:      Status
 635  *
 636  * DESCRIPTION: Get the length of one package element.
 637  *
 638  ******************************************************************************/
 639 
 640 static ACPI_STATUS
 641 AcpiUtGetElementLength (
 642     UINT8                   ObjectType,
 643     ACPI_OPERAND_OBJECT     *SourceObject,
 644     ACPI_GENERIC_STATE      *State,
 645     void                    *Context)
 646 {
 647     ACPI_STATUS             Status = AE_OK;
 648     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
 649     ACPI_SIZE               ObjectSpace;
 650 
 651 
 652     switch (ObjectType)
 653     {
 654     case ACPI_COPY_TYPE_SIMPLE:
 655         /*
 656          * Simple object - just get the size (Null object/entry is handled
 657          * here also) and sum it into the running package length
 658          */
 659         Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace);
 660         if (ACPI_FAILURE (Status))
 661         {
 662             return (Status);
 663         }
 664 
 665         Info->Length += ObjectSpace;
 666         break;
 667 
 668     case ACPI_COPY_TYPE_PACKAGE:
 669 
 670         /* Package object - nothing much to do here, let the walk handle it */
 671 
 672         Info->NumPackages++;
 673         State->Pkg.ThisTargetObj = NULL;
 674         break;
 675 
 676     default:
 677 
 678         /* No other types allowed */
 679 
 680         return (AE_BAD_PARAMETER);
 681     }
 682 
 683     return (Status);
 684 }
 685 
 686 
 687 /*******************************************************************************
 688  *
 689  * FUNCTION:    AcpiUtGetPackageObjectSize
 690  *
 691  * PARAMETERS:  InternalObject      - An ACPI internal object
 692  *              ObjLength           - Where the length is returned
 693  *
 694  * RETURN:      Status
 695  *
 696  * DESCRIPTION: This function is called to determine the space required to
 697  *              contain a package object for return to an external user.
 698  *
 699  *              This is moderately complex since a package contains other
 700  *              objects including packages.
 701  *
 702  ******************************************************************************/
 703 
 704 static ACPI_STATUS
 705 AcpiUtGetPackageObjectSize (
 706     ACPI_OPERAND_OBJECT     *InternalObject,
 707     ACPI_SIZE               *ObjLength)
 708 {
 709     ACPI_STATUS             Status;
 710     ACPI_PKG_INFO           Info;
 711 
 712 
 713     ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject);
 714 
 715 
 716     Info.Length      = 0;
 717     Info.ObjectSpace = 0;
 718     Info.NumPackages = 1;
 719 
 720     Status = AcpiUtWalkPackageTree (InternalObject, NULL,
 721         AcpiUtGetElementLength, &Info);
 722     if (ACPI_FAILURE (Status))
 723     {
 724         return_ACPI_STATUS (Status);
 725     }
 726 
 727     /*
 728      * We have handled all of the objects in all levels of the package.
 729      * just add the length of the package objects themselves.
 730      * Round up to the next machine word.
 731      */
 732     Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
 733                     (ACPI_SIZE) Info.NumPackages;
 734 
 735     /* Return the total package length */
 736 
 737     *ObjLength = Info.Length;
 738     return_ACPI_STATUS (Status);
 739 }
 740 
 741 
 742 /*******************************************************************************
 743  *
 744  * FUNCTION:    AcpiUtGetObjectSize
 745  *
 746  * PARAMETERS:  InternalObject      - An ACPI internal object
 747  *              ObjLength           - Where the length will be returned
 748  *
 749  * RETURN:      Status
 750  *
 751  * DESCRIPTION: This function is called to determine the space required to
 752  *              contain an object for return to an API user.
 753  *
 754  ******************************************************************************/
 755 
 756 ACPI_STATUS
 757 AcpiUtGetObjectSize (
 758     ACPI_OPERAND_OBJECT     *InternalObject,
 759     ACPI_SIZE               *ObjLength)
 760 {
 761     ACPI_STATUS             Status;
 762 
 763 
 764     ACPI_FUNCTION_ENTRY ();
 765 
 766 
 767     if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_OPERAND) &&
 768         (InternalObject->Common.Type == ACPI_TYPE_PACKAGE))
 769     {
 770         Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
 771     }
 772     else
 773     {
 774         Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
 775     }
 776 
 777     return (Status);
 778 }