Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

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