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