1*3446Smrj /******************************************************************************
2*3446Smrj  *
3*3446Smrj  * Module Name: utobject - ACPI object create/delete/size/cache routines
4*3446Smrj  *              $Revision: 1.103 $
5*3446Smrj  *
6*3446Smrj  *****************************************************************************/
7*3446Smrj 
8*3446Smrj /******************************************************************************
9*3446Smrj  *
10*3446Smrj  * 1. Copyright Notice
11*3446Smrj  *
12*3446Smrj  * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
13*3446Smrj  * All rights reserved.
14*3446Smrj  *
15*3446Smrj  * 2. License
16*3446Smrj  *
17*3446Smrj  * 2.1. This is your license from Intel Corp. under its intellectual property
18*3446Smrj  * rights.  You may have additional license terms from the party that provided
19*3446Smrj  * you this software, covering your right to use that party's intellectual
20*3446Smrj  * property rights.
21*3446Smrj  *
22*3446Smrj  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23*3446Smrj  * copy of the source code appearing in this file ("Covered Code") an
24*3446Smrj  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25*3446Smrj  * base code distributed originally by Intel ("Original Intel Code") to copy,
26*3446Smrj  * make derivatives, distribute, use and display any portion of the Covered
27*3446Smrj  * Code in any form, with the right to sublicense such rights; and
28*3446Smrj  *
29*3446Smrj  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30*3446Smrj  * license (with the right to sublicense), under only those claims of Intel
31*3446Smrj  * patents that are infringed by the Original Intel Code, to make, use, sell,
32*3446Smrj  * offer to sell, and import the Covered Code and derivative works thereof
33*3446Smrj  * solely to the minimum extent necessary to exercise the above copyright
34*3446Smrj  * license, and in no event shall the patent license extend to any additions
35*3446Smrj  * to or modifications of the Original Intel Code.  No other license or right
36*3446Smrj  * is granted directly or by implication, estoppel or otherwise;
37*3446Smrj  *
38*3446Smrj  * The above copyright and patent license is granted only if the following
39*3446Smrj  * conditions are met:
40*3446Smrj  *
41*3446Smrj  * 3. Conditions
42*3446Smrj  *
43*3446Smrj  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44*3446Smrj  * Redistribution of source code of any substantial portion of the Covered
45*3446Smrj  * Code or modification with rights to further distribute source must include
46*3446Smrj  * the above Copyright Notice, the above License, this list of Conditions,
47*3446Smrj  * and the following Disclaimer and Export Compliance provision.  In addition,
48*3446Smrj  * Licensee must cause all Covered Code to which Licensee contributes to
49*3446Smrj  * contain a file documenting the changes Licensee made to create that Covered
50*3446Smrj  * Code and the date of any change.  Licensee must include in that file the
51*3446Smrj  * documentation of any changes made by any predecessor Licensee.  Licensee
52*3446Smrj  * must include a prominent statement that the modification is derived,
53*3446Smrj  * directly or indirectly, from Original Intel Code.
54*3446Smrj  *
55*3446Smrj  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56*3446Smrj  * Redistribution of source code of any substantial portion of the Covered
57*3446Smrj  * Code or modification without rights to further distribute source must
58*3446Smrj  * include the following Disclaimer and Export Compliance provision in the
59*3446Smrj  * documentation and/or other materials provided with distribution.  In
60*3446Smrj  * addition, Licensee may not authorize further sublicense of source of any
61*3446Smrj  * portion of the Covered Code, and must include terms to the effect that the
62*3446Smrj  * license from Licensee to its licensee is limited to the intellectual
63*3446Smrj  * property embodied in the software Licensee provides to its licensee, and
64*3446Smrj  * not to intellectual property embodied in modifications its licensee may
65*3446Smrj  * make.
66*3446Smrj  *
67*3446Smrj  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68*3446Smrj  * substantial portion of the Covered Code or modification must reproduce the
69*3446Smrj  * above Copyright Notice, and the following Disclaimer and Export Compliance
70*3446Smrj  * provision in the documentation and/or other materials provided with the
71*3446Smrj  * distribution.
72*3446Smrj  *
73*3446Smrj  * 3.4. Intel retains all right, title, and interest in and to the Original
74*3446Smrj  * Intel Code.
75*3446Smrj  *
76*3446Smrj  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77*3446Smrj  * Intel shall be used in advertising or otherwise to promote the sale, use or
78*3446Smrj  * other dealings in products derived from or relating to the Covered Code
79*3446Smrj  * without prior written authorization from Intel.
80*3446Smrj  *
81*3446Smrj  * 4. Disclaimer and Export Compliance
82*3446Smrj  *
83*3446Smrj  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84*3446Smrj  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85*3446Smrj  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86*3446Smrj  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87*3446Smrj  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88*3446Smrj  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89*3446Smrj  * PARTICULAR PURPOSE.
90*3446Smrj  *
91*3446Smrj  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92*3446Smrj  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93*3446Smrj  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94*3446Smrj  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95*3446Smrj  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96*3446Smrj  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97*3446Smrj  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98*3446Smrj  * LIMITED REMEDY.
99*3446Smrj  *
100*3446Smrj  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101*3446Smrj  * software or system incorporating such software without first obtaining any
102*3446Smrj  * required license or other approval from the U. S. Department of Commerce or
103*3446Smrj  * any other agency or department of the United States Government.  In the
104*3446Smrj  * event Licensee exports any such software from the United States or
105*3446Smrj  * re-exports any such software from a foreign destination, Licensee shall
106*3446Smrj  * ensure that the distribution and export/re-export of the software is in
107*3446Smrj  * compliance with all laws, regulations, orders, or other restrictions of the
108*3446Smrj  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109*3446Smrj  * any of its subsidiaries will export/re-export any technical data, process,
110*3446Smrj  * software, or service, directly or indirectly, to any country for which the
111*3446Smrj  * United States government or any agency thereof requires an export license,
112*3446Smrj  * other governmental approval, or letter of assurance, without first obtaining
113*3446Smrj  * such license, approval or letter.
114*3446Smrj  *
115*3446Smrj  *****************************************************************************/
116*3446Smrj 
117*3446Smrj #define __UTOBJECT_C__
118*3446Smrj 
119*3446Smrj #include "acpi.h"
120*3446Smrj #include "acnamesp.h"
121*3446Smrj #include "amlcode.h"
122*3446Smrj 
123*3446Smrj 
124*3446Smrj #define _COMPONENT          ACPI_UTILITIES
125*3446Smrj         ACPI_MODULE_NAME    ("utobject")
126*3446Smrj 
127*3446Smrj /* Local prototypes */
128*3446Smrj 
129*3446Smrj static ACPI_STATUS
130*3446Smrj AcpiUtGetSimpleObjectSize (
131*3446Smrj     ACPI_OPERAND_OBJECT     *Obj,
132*3446Smrj     ACPI_SIZE               *ObjLength);
133*3446Smrj 
134*3446Smrj static ACPI_STATUS
135*3446Smrj AcpiUtGetPackageObjectSize (
136*3446Smrj     ACPI_OPERAND_OBJECT     *Obj,
137*3446Smrj     ACPI_SIZE               *ObjLength);
138*3446Smrj 
139*3446Smrj static ACPI_STATUS
140*3446Smrj AcpiUtGetElementLength (
141*3446Smrj     UINT8                   ObjectType,
142*3446Smrj     ACPI_OPERAND_OBJECT     *SourceObject,
143*3446Smrj     ACPI_GENERIC_STATE      *State,
144*3446Smrj     void                    *Context);
145*3446Smrj 
146*3446Smrj 
147*3446Smrj /*******************************************************************************
148*3446Smrj  *
149*3446Smrj  * FUNCTION:    AcpiUtCreateInternalObjectDbg
150*3446Smrj  *
151*3446Smrj  * PARAMETERS:  ModuleName          - Source file name of caller
152*3446Smrj  *              LineNumber          - Line number of caller
153*3446Smrj  *              ComponentId         - Component type of caller
154*3446Smrj  *              Type                - ACPI Type of the new object
155*3446Smrj  *
156*3446Smrj  * RETURN:      A new internal object, null on failure
157*3446Smrj  *
158*3446Smrj  * DESCRIPTION: Create and initialize a new internal object.
159*3446Smrj  *
160*3446Smrj  * NOTE:        We always allocate the worst-case object descriptor because
161*3446Smrj  *              these objects are cached, and we want them to be
162*3446Smrj  *              one-size-satisifies-any-request.  This in itself may not be
163*3446Smrj  *              the most memory efficient, but the efficiency of the object
164*3446Smrj  *              cache should more than make up for this!
165*3446Smrj  *
166*3446Smrj  ******************************************************************************/
167*3446Smrj 
168*3446Smrj ACPI_OPERAND_OBJECT  *
169*3446Smrj AcpiUtCreateInternalObjectDbg (
170*3446Smrj     char                    *ModuleName,
171*3446Smrj     UINT32                  LineNumber,
172*3446Smrj     UINT32                  ComponentId,
173*3446Smrj     ACPI_OBJECT_TYPE        Type)
174*3446Smrj {
175*3446Smrj     ACPI_OPERAND_OBJECT     *Object;
176*3446Smrj     ACPI_OPERAND_OBJECT     *SecondObject;
177*3446Smrj 
178*3446Smrj 
179*3446Smrj     ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg,
180*3446Smrj         AcpiUtGetTypeName (Type));
181*3446Smrj 
182*3446Smrj 
183*3446Smrj     /* Allocate the raw object descriptor */
184*3446Smrj 
185*3446Smrj     Object = AcpiUtAllocateObjectDescDbg (ModuleName, LineNumber, ComponentId);
186*3446Smrj     if (!Object)
187*3446Smrj     {
188*3446Smrj         return_PTR (NULL);
189*3446Smrj     }
190*3446Smrj 
191*3446Smrj     switch (Type)
192*3446Smrj     {
193*3446Smrj     case ACPI_TYPE_REGION:
194*3446Smrj     case ACPI_TYPE_BUFFER_FIELD:
195*3446Smrj 
196*3446Smrj         /* These types require a secondary object */
197*3446Smrj 
198*3446Smrj         SecondObject = AcpiUtAllocateObjectDescDbg (ModuleName,
199*3446Smrj                             LineNumber, ComponentId);
200*3446Smrj         if (!SecondObject)
201*3446Smrj         {
202*3446Smrj             AcpiUtDeleteObjectDesc (Object);
203*3446Smrj             return_PTR (NULL);
204*3446Smrj         }
205*3446Smrj 
206*3446Smrj         SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA;
207*3446Smrj         SecondObject->Common.ReferenceCount = 1;
208*3446Smrj 
209*3446Smrj         /* Link the second object to the first */
210*3446Smrj 
211*3446Smrj         Object->Common.NextObject = SecondObject;
212*3446Smrj         break;
213*3446Smrj 
214*3446Smrj     default:
215*3446Smrj         /* All others have no secondary object */
216*3446Smrj         break;
217*3446Smrj     }
218*3446Smrj 
219*3446Smrj     /* Save the object type in the object descriptor */
220*3446Smrj 
221*3446Smrj     Object->Common.Type = (UINT8) Type;
222*3446Smrj 
223*3446Smrj     /* Init the reference count */
224*3446Smrj 
225*3446Smrj     Object->Common.ReferenceCount = 1;
226*3446Smrj 
227*3446Smrj     /* Any per-type initialization should go here */
228*3446Smrj 
229*3446Smrj     return_PTR (Object);
230*3446Smrj }
231*3446Smrj 
232*3446Smrj 
233*3446Smrj /*******************************************************************************
234*3446Smrj  *
235*3446Smrj  * FUNCTION:    AcpiUtCreateBufferObject
236*3446Smrj  *
237*3446Smrj  * PARAMETERS:  BufferSize             - Size of buffer to be created
238*3446Smrj  *
239*3446Smrj  * RETURN:      Pointer to a new Buffer object, null on failure
240*3446Smrj  *
241*3446Smrj  * DESCRIPTION: Create a fully initialized buffer object
242*3446Smrj  *
243*3446Smrj  ******************************************************************************/
244*3446Smrj 
245*3446Smrj ACPI_OPERAND_OBJECT *
246*3446Smrj AcpiUtCreateBufferObject (
247*3446Smrj     ACPI_SIZE               BufferSize)
248*3446Smrj {
249*3446Smrj     ACPI_OPERAND_OBJECT     *BufferDesc;
250*3446Smrj     UINT8                   *Buffer = NULL;
251*3446Smrj 
252*3446Smrj 
253*3446Smrj     ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize);
254*3446Smrj 
255*3446Smrj 
256*3446Smrj     /* Create a new Buffer object */
257*3446Smrj 
258*3446Smrj     BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
259*3446Smrj     if (!BufferDesc)
260*3446Smrj     {
261*3446Smrj         return_PTR (NULL);
262*3446Smrj     }
263*3446Smrj 
264*3446Smrj     /* Create an actual buffer only if size > 0 */
265*3446Smrj 
266*3446Smrj     if (BufferSize > 0)
267*3446Smrj     {
268*3446Smrj         /* Allocate the actual buffer */
269*3446Smrj 
270*3446Smrj         Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
271*3446Smrj         if (!Buffer)
272*3446Smrj         {
273*3446Smrj             ACPI_ERROR ((AE_INFO, "Could not allocate size %X",
274*3446Smrj                 (UINT32) BufferSize));
275*3446Smrj             AcpiUtRemoveReference (BufferDesc);
276*3446Smrj             return_PTR (NULL);
277*3446Smrj         }
278*3446Smrj     }
279*3446Smrj 
280*3446Smrj     /* Complete buffer object initialization */
281*3446Smrj 
282*3446Smrj     BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
283*3446Smrj     BufferDesc->Buffer.Pointer = Buffer;
284*3446Smrj     BufferDesc->Buffer.Length = (UINT32) BufferSize;
285*3446Smrj 
286*3446Smrj     /* Return the new buffer descriptor */
287*3446Smrj 
288*3446Smrj     return_PTR (BufferDesc);
289*3446Smrj }
290*3446Smrj 
291*3446Smrj 
292*3446Smrj /*******************************************************************************
293*3446Smrj  *
294*3446Smrj  * FUNCTION:    AcpiUtCreateStringObject
295*3446Smrj  *
296*3446Smrj  * PARAMETERS:  StringSize          - Size of string to be created. Does not
297*3446Smrj  *                                    include NULL terminator, this is added
298*3446Smrj  *                                    automatically.
299*3446Smrj  *
300*3446Smrj  * RETURN:      Pointer to a new String object
301*3446Smrj  *
302*3446Smrj  * DESCRIPTION: Create a fully initialized string object
303*3446Smrj  *
304*3446Smrj  ******************************************************************************/
305*3446Smrj 
306*3446Smrj ACPI_OPERAND_OBJECT *
307*3446Smrj AcpiUtCreateStringObject (
308*3446Smrj     ACPI_SIZE               StringSize)
309*3446Smrj {
310*3446Smrj     ACPI_OPERAND_OBJECT     *StringDesc;
311*3446Smrj     char                    *String;
312*3446Smrj 
313*3446Smrj 
314*3446Smrj     ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize);
315*3446Smrj 
316*3446Smrj 
317*3446Smrj     /* Create a new String object */
318*3446Smrj 
319*3446Smrj     StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
320*3446Smrj     if (!StringDesc)
321*3446Smrj     {
322*3446Smrj         return_PTR (NULL);
323*3446Smrj     }
324*3446Smrj 
325*3446Smrj     /*
326*3446Smrj      * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
327*3446Smrj      * NOTE: Zero-length strings are NULL terminated
328*3446Smrj      */
329*3446Smrj     String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
330*3446Smrj     if (!String)
331*3446Smrj     {
332*3446Smrj         ACPI_ERROR ((AE_INFO, "Could not allocate size %X",
333*3446Smrj             (UINT32) StringSize));
334*3446Smrj         AcpiUtRemoveReference (StringDesc);
335*3446Smrj         return_PTR (NULL);
336*3446Smrj     }
337*3446Smrj 
338*3446Smrj     /* Complete string object initialization */
339*3446Smrj 
340*3446Smrj     StringDesc->String.Pointer = String;
341*3446Smrj     StringDesc->String.Length = (UINT32) StringSize;
342*3446Smrj 
343*3446Smrj     /* Return the new string descriptor */
344*3446Smrj 
345*3446Smrj     return_PTR (StringDesc);
346*3446Smrj }
347*3446Smrj 
348*3446Smrj 
349*3446Smrj /*******************************************************************************
350*3446Smrj  *
351*3446Smrj  * FUNCTION:    AcpiUtValidInternalObject
352*3446Smrj  *
353*3446Smrj  * PARAMETERS:  Object              - Object to be validated
354*3446Smrj  *
355*3446Smrj  * RETURN:      TRUE if object is valid, FALSE otherwise
356*3446Smrj  *
357*3446Smrj  * DESCRIPTION: Validate a pointer to be an ACPI_OPERAND_OBJECT
358*3446Smrj  *
359*3446Smrj  ******************************************************************************/
360*3446Smrj 
361*3446Smrj BOOLEAN
362*3446Smrj AcpiUtValidInternalObject (
363*3446Smrj     void                    *Object)
364*3446Smrj {
365*3446Smrj 
366*3446Smrj     ACPI_FUNCTION_NAME (UtValidInternalObject);
367*3446Smrj 
368*3446Smrj 
369*3446Smrj     /* Check for a null pointer */
370*3446Smrj 
371*3446Smrj     if (!Object)
372*3446Smrj     {
373*3446Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n"));
374*3446Smrj         return (FALSE);
375*3446Smrj     }
376*3446Smrj 
377*3446Smrj     /* Check the descriptor type field */
378*3446Smrj 
379*3446Smrj     switch (ACPI_GET_DESCRIPTOR_TYPE (Object))
380*3446Smrj     {
381*3446Smrj     case ACPI_DESC_TYPE_OPERAND:
382*3446Smrj 
383*3446Smrj         /* The object appears to be a valid ACPI_OPERAND_OBJECT  */
384*3446Smrj 
385*3446Smrj         return (TRUE);
386*3446Smrj 
387*3446Smrj     default:
388*3446Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
389*3446Smrj                 "%p is not not an ACPI operand obj [%s]\n",
390*3446Smrj                 Object, AcpiUtGetDescriptorName (Object)));
391*3446Smrj         break;
392*3446Smrj     }
393*3446Smrj 
394*3446Smrj     return (FALSE);
395*3446Smrj }
396*3446Smrj 
397*3446Smrj 
398*3446Smrj /*******************************************************************************
399*3446Smrj  *
400*3446Smrj  * FUNCTION:    AcpiUtAllocateObjectDescDbg
401*3446Smrj  *
402*3446Smrj  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
403*3446Smrj  *              LineNumber          - Caller's line number (for error output)
404*3446Smrj  *              ComponentId         - Caller's component ID (for error output)
405*3446Smrj  *
406*3446Smrj  * RETURN:      Pointer to newly allocated object descriptor.  Null on error
407*3446Smrj  *
408*3446Smrj  * DESCRIPTION: Allocate a new object descriptor.  Gracefully handle
409*3446Smrj  *              error conditions.
410*3446Smrj  *
411*3446Smrj  ******************************************************************************/
412*3446Smrj 
413*3446Smrj void *
414*3446Smrj AcpiUtAllocateObjectDescDbg (
415*3446Smrj     char                    *ModuleName,
416*3446Smrj     UINT32                  LineNumber,
417*3446Smrj     UINT32                  ComponentId)
418*3446Smrj {
419*3446Smrj     ACPI_OPERAND_OBJECT     *Object;
420*3446Smrj 
421*3446Smrj 
422*3446Smrj     ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg);
423*3446Smrj 
424*3446Smrj 
425*3446Smrj     Object = AcpiOsAcquireObject (AcpiGbl_OperandCache);
426*3446Smrj     if (!Object)
427*3446Smrj     {
428*3446Smrj         ACPI_ERROR ((ModuleName, LineNumber,
429*3446Smrj             "Could not allocate an object descriptor"));
430*3446Smrj 
431*3446Smrj         return_PTR (NULL);
432*3446Smrj     }
433*3446Smrj 
434*3446Smrj     /* Mark the descriptor type */
435*3446Smrj 
436*3446Smrj     ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND);
437*3446Smrj 
438*3446Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
439*3446Smrj             Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT)));
440*3446Smrj 
441*3446Smrj     return_PTR (Object);
442*3446Smrj }
443*3446Smrj 
444*3446Smrj 
445*3446Smrj /*******************************************************************************
446*3446Smrj  *
447*3446Smrj  * FUNCTION:    AcpiUtDeleteObjectDesc
448*3446Smrj  *
449*3446Smrj  * PARAMETERS:  Object          - An Acpi internal object to be deleted
450*3446Smrj  *
451*3446Smrj  * RETURN:      None.
452*3446Smrj  *
453*3446Smrj  * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
454*3446Smrj  *
455*3446Smrj  ******************************************************************************/
456*3446Smrj 
457*3446Smrj void
458*3446Smrj AcpiUtDeleteObjectDesc (
459*3446Smrj     ACPI_OPERAND_OBJECT     *Object)
460*3446Smrj {
461*3446Smrj     ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
462*3446Smrj 
463*3446Smrj 
464*3446Smrj     /* Object must be an ACPI_OPERAND_OBJECT  */
465*3446Smrj 
466*3446Smrj     if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
467*3446Smrj     {
468*3446Smrj         ACPI_ERROR ((AE_INFO,
469*3446Smrj             "%p is not an ACPI Operand object [%s]", Object,
470*3446Smrj             AcpiUtGetDescriptorName (Object)));
471*3446Smrj         return_VOID;
472*3446Smrj     }
473*3446Smrj 
474*3446Smrj     (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object);
475*3446Smrj     return_VOID;
476*3446Smrj }
477*3446Smrj 
478*3446Smrj 
479*3446Smrj /*******************************************************************************
480*3446Smrj  *
481*3446Smrj  * FUNCTION:    AcpiUtGetSimpleObjectSize
482*3446Smrj  *
483*3446Smrj  * PARAMETERS:  InternalObject     - An ACPI operand object
484*3446Smrj  *              ObjLength          - Where the length is returned
485*3446Smrj  *
486*3446Smrj  * RETURN:      Status
487*3446Smrj  *
488*3446Smrj  * DESCRIPTION: This function is called to determine the space required to
489*3446Smrj  *              contain a simple object for return to an external user.
490*3446Smrj  *
491*3446Smrj  *              The length includes the object structure plus any additional
492*3446Smrj  *              needed space.
493*3446Smrj  *
494*3446Smrj  ******************************************************************************/
495*3446Smrj 
496*3446Smrj static ACPI_STATUS
497*3446Smrj AcpiUtGetSimpleObjectSize (
498*3446Smrj     ACPI_OPERAND_OBJECT     *InternalObject,
499*3446Smrj     ACPI_SIZE               *ObjLength)
500*3446Smrj {
501*3446Smrj     ACPI_SIZE               Length;
502*3446Smrj     ACPI_STATUS             Status = AE_OK;
503*3446Smrj 
504*3446Smrj 
505*3446Smrj     ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject);
506*3446Smrj 
507*3446Smrj 
508*3446Smrj     /*
509*3446Smrj      * Handle a null object (Could be a uninitialized package
510*3446Smrj      * element -- which is legal)
511*3446Smrj      */
512*3446Smrj     if (!InternalObject)
513*3446Smrj     {
514*3446Smrj         *ObjLength = 0;
515*3446Smrj         return_ACPI_STATUS (AE_OK);
516*3446Smrj     }
517*3446Smrj 
518*3446Smrj     /* Start with the length of the Acpi object */
519*3446Smrj 
520*3446Smrj     Length = sizeof (ACPI_OBJECT);
521*3446Smrj 
522*3446Smrj     if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED)
523*3446Smrj     {
524*3446Smrj         /* Object is a named object (reference), just return the length */
525*3446Smrj 
526*3446Smrj         *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
527*3446Smrj         return_ACPI_STATUS (Status);
528*3446Smrj     }
529*3446Smrj 
530*3446Smrj     /*
531*3446Smrj      * The final length depends on the object type
532*3446Smrj      * Strings and Buffers are packed right up against the parent object and
533*3446Smrj      * must be accessed bytewise or there may be alignment problems on
534*3446Smrj      * certain processors
535*3446Smrj      */
536*3446Smrj     switch (ACPI_GET_OBJECT_TYPE (InternalObject))
537*3446Smrj     {
538*3446Smrj     case ACPI_TYPE_STRING:
539*3446Smrj 
540*3446Smrj         Length += (ACPI_SIZE) InternalObject->String.Length + 1;
541*3446Smrj         break;
542*3446Smrj 
543*3446Smrj 
544*3446Smrj     case ACPI_TYPE_BUFFER:
545*3446Smrj 
546*3446Smrj         Length += (ACPI_SIZE) InternalObject->Buffer.Length;
547*3446Smrj         break;
548*3446Smrj 
549*3446Smrj 
550*3446Smrj     case ACPI_TYPE_INTEGER:
551*3446Smrj     case ACPI_TYPE_PROCESSOR:
552*3446Smrj     case ACPI_TYPE_POWER:
553*3446Smrj 
554*3446Smrj         /*
555*3446Smrj          * No extra data for these types
556*3446Smrj          */
557*3446Smrj         break;
558*3446Smrj 
559*3446Smrj 
560*3446Smrj     case ACPI_TYPE_LOCAL_REFERENCE:
561*3446Smrj 
562*3446Smrj         switch (InternalObject->Reference.Opcode)
563*3446Smrj         {
564*3446Smrj         case AML_INT_NAMEPATH_OP:
565*3446Smrj 
566*3446Smrj             /*
567*3446Smrj              * Get the actual length of the full pathname to this object.
568*3446Smrj              * The reference will be converted to the pathname to the object
569*3446Smrj              */
570*3446Smrj             Length += ACPI_ROUND_UP_TO_NATIVE_WORD (
571*3446Smrj                         AcpiNsGetPathnameLength (InternalObject->Reference.Node));
572*3446Smrj             break;
573*3446Smrj 
574*3446Smrj         default:
575*3446Smrj 
576*3446Smrj             /*
577*3446Smrj              * No other reference opcodes are supported.
578*3446Smrj              * Notably, Locals and Args are not supported, but this may be
579*3446Smrj              * required eventually.
580*3446Smrj              */
581*3446Smrj             ACPI_ERROR ((AE_INFO,
582*3446Smrj                 "Unsupported Reference opcode=%X in object %p",
583*3446Smrj                 InternalObject->Reference.Opcode, InternalObject));
584*3446Smrj             Status = AE_TYPE;
585*3446Smrj             break;
586*3446Smrj         }
587*3446Smrj         break;
588*3446Smrj 
589*3446Smrj 
590*3446Smrj     default:
591*3446Smrj 
592*3446Smrj         ACPI_ERROR ((AE_INFO, "Unsupported type=%X in object %p",
593*3446Smrj             ACPI_GET_OBJECT_TYPE (InternalObject), InternalObject));
594*3446Smrj         Status = AE_TYPE;
595*3446Smrj         break;
596*3446Smrj     }
597*3446Smrj 
598*3446Smrj     /*
599*3446Smrj      * Account for the space required by the object rounded up to the next
600*3446Smrj      * multiple of the machine word size.  This keeps each object aligned
601*3446Smrj      * on a machine word boundary. (preventing alignment faults on some
602*3446Smrj      * machines.)
603*3446Smrj      */
604*3446Smrj     *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
605*3446Smrj     return_ACPI_STATUS (Status);
606*3446Smrj }
607*3446Smrj 
608*3446Smrj 
609*3446Smrj /*******************************************************************************
610*3446Smrj  *
611*3446Smrj  * FUNCTION:    AcpiUtGetElementLength
612*3446Smrj  *
613*3446Smrj  * PARAMETERS:  ACPI_PKG_CALLBACK
614*3446Smrj  *
615*3446Smrj  * RETURN:      Status
616*3446Smrj  *
617*3446Smrj  * DESCRIPTION: Get the length of one package element.
618*3446Smrj  *
619*3446Smrj  ******************************************************************************/
620*3446Smrj 
621*3446Smrj static ACPI_STATUS
622*3446Smrj AcpiUtGetElementLength (
623*3446Smrj     UINT8                   ObjectType,
624*3446Smrj     ACPI_OPERAND_OBJECT     *SourceObject,
625*3446Smrj     ACPI_GENERIC_STATE      *State,
626*3446Smrj     void                    *Context)
627*3446Smrj {
628*3446Smrj     ACPI_STATUS             Status = AE_OK;
629*3446Smrj     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
630*3446Smrj     ACPI_SIZE               ObjectSpace;
631*3446Smrj 
632*3446Smrj 
633*3446Smrj     switch (ObjectType)
634*3446Smrj     {
635*3446Smrj     case ACPI_COPY_TYPE_SIMPLE:
636*3446Smrj 
637*3446Smrj         /*
638*3446Smrj          * Simple object - just get the size (Null object/entry is handled
639*3446Smrj          * here also) and sum it into the running package length
640*3446Smrj          */
641*3446Smrj         Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace);
642*3446Smrj         if (ACPI_FAILURE (Status))
643*3446Smrj         {
644*3446Smrj             return (Status);
645*3446Smrj         }
646*3446Smrj 
647*3446Smrj         Info->Length += ObjectSpace;
648*3446Smrj         break;
649*3446Smrj 
650*3446Smrj 
651*3446Smrj     case ACPI_COPY_TYPE_PACKAGE:
652*3446Smrj 
653*3446Smrj         /* Package object - nothing much to do here, let the walk handle it */
654*3446Smrj 
655*3446Smrj         Info->NumPackages++;
656*3446Smrj         State->Pkg.ThisTargetObj = NULL;
657*3446Smrj         break;
658*3446Smrj 
659*3446Smrj 
660*3446Smrj     default:
661*3446Smrj 
662*3446Smrj         /* No other types allowed */
663*3446Smrj 
664*3446Smrj         return (AE_BAD_PARAMETER);
665*3446Smrj     }
666*3446Smrj 
667*3446Smrj     return (Status);
668*3446Smrj }
669*3446Smrj 
670*3446Smrj 
671*3446Smrj /*******************************************************************************
672*3446Smrj  *
673*3446Smrj  * FUNCTION:    AcpiUtGetPackageObjectSize
674*3446Smrj  *
675*3446Smrj  * PARAMETERS:  InternalObject      - An ACPI internal object
676*3446Smrj  *              ObjLength           - Where the length is returned
677*3446Smrj  *
678*3446Smrj  * RETURN:      Status
679*3446Smrj  *
680*3446Smrj  * DESCRIPTION: This function is called to determine the space required to
681*3446Smrj  *              contain a package object for return to an external user.
682*3446Smrj  *
683*3446Smrj  *              This is moderately complex since a package contains other
684*3446Smrj  *              objects including packages.
685*3446Smrj  *
686*3446Smrj  ******************************************************************************/
687*3446Smrj 
688*3446Smrj static ACPI_STATUS
689*3446Smrj AcpiUtGetPackageObjectSize (
690*3446Smrj     ACPI_OPERAND_OBJECT     *InternalObject,
691*3446Smrj     ACPI_SIZE               *ObjLength)
692*3446Smrj {
693*3446Smrj     ACPI_STATUS             Status;
694*3446Smrj     ACPI_PKG_INFO           Info;
695*3446Smrj 
696*3446Smrj 
697*3446Smrj     ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject);
698*3446Smrj 
699*3446Smrj 
700*3446Smrj     Info.Length      = 0;
701*3446Smrj     Info.ObjectSpace = 0;
702*3446Smrj     Info.NumPackages = 1;
703*3446Smrj 
704*3446Smrj     Status = AcpiUtWalkPackageTree (InternalObject, NULL,
705*3446Smrj                             AcpiUtGetElementLength, &Info);
706*3446Smrj     if (ACPI_FAILURE (Status))
707*3446Smrj     {
708*3446Smrj         return_ACPI_STATUS (Status);
709*3446Smrj     }
710*3446Smrj 
711*3446Smrj     /*
712*3446Smrj      * We have handled all of the objects in all levels of the package.
713*3446Smrj      * just add the length of the package objects themselves.
714*3446Smrj      * Round up to the next machine word.
715*3446Smrj      */
716*3446Smrj     Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
717*3446Smrj                     (ACPI_SIZE) Info.NumPackages;
718*3446Smrj 
719*3446Smrj     /* Return the total package length */
720*3446Smrj 
721*3446Smrj     *ObjLength = Info.Length;
722*3446Smrj     return_ACPI_STATUS (Status);
723*3446Smrj }
724*3446Smrj 
725*3446Smrj 
726*3446Smrj /*******************************************************************************
727*3446Smrj  *
728*3446Smrj  * FUNCTION:    AcpiUtGetObjectSize
729*3446Smrj  *
730*3446Smrj  * PARAMETERS:  InternalObject      - An ACPI internal object
731*3446Smrj  *              ObjLength           - Where the length will be returned
732*3446Smrj  *
733*3446Smrj  * RETURN:      Status
734*3446Smrj  *
735*3446Smrj  * DESCRIPTION: This function is called to determine the space required to
736*3446Smrj  *              contain an object for return to an API user.
737*3446Smrj  *
738*3446Smrj  ******************************************************************************/
739*3446Smrj 
740*3446Smrj ACPI_STATUS
741*3446Smrj AcpiUtGetObjectSize (
742*3446Smrj     ACPI_OPERAND_OBJECT     *InternalObject,
743*3446Smrj     ACPI_SIZE               *ObjLength)
744*3446Smrj {
745*3446Smrj     ACPI_STATUS             Status;
746*3446Smrj 
747*3446Smrj 
748*3446Smrj     ACPI_FUNCTION_ENTRY ();
749*3446Smrj 
750*3446Smrj 
751*3446Smrj     if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_OPERAND) &&
752*3446Smrj         (ACPI_GET_OBJECT_TYPE (InternalObject) == ACPI_TYPE_PACKAGE))
753*3446Smrj     {
754*3446Smrj         Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
755*3446Smrj     }
756*3446Smrj     else
757*3446Smrj     {
758*3446Smrj         Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
759*3446Smrj     }
760*3446Smrj 
761*3446Smrj     return (Status);
762*3446Smrj }
763*3446Smrj 
764*3446Smrj 
765