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