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: utcopy - Internal to external object translation utilities
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 __UTCOPY_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    ("utcopy")
125
 
126
/* Local prototypes */
127
 
128
static ACPI_STATUS
129
AcpiUtCopyIsimpleToEsimple (
130
    ACPI_OPERAND_OBJECT     *InternalObject,
131
    ACPI_OBJECT             *ExternalObject,
132
    UINT8                   *DataSpace,
133
    ACPI_SIZE               *BufferSpaceUsed);
134
 
135
static ACPI_STATUS
136
AcpiUtCopyIelementToIelement (
137
    UINT8                   ObjectType,
138
    ACPI_OPERAND_OBJECT     *SourceObject,
139
    ACPI_GENERIC_STATE      *State,
140
    void                    *Context);
141
 
142
static ACPI_STATUS
143
AcpiUtCopyIpackageToEpackage (
144
    ACPI_OPERAND_OBJECT     *InternalObject,
145
    UINT8                   *Buffer,
146
    ACPI_SIZE               *SpaceUsed);
147
 
148
static ACPI_STATUS
149
AcpiUtCopyEsimpleToIsimple(
150
    ACPI_OBJECT             *UserObj,
151
    ACPI_OPERAND_OBJECT     **ReturnObj);
152
 
153
static ACPI_STATUS
154
AcpiUtCopyEpackageToIpackage (
155
    ACPI_OBJECT             *ExternalObject,
156
    ACPI_OPERAND_OBJECT     **InternalObject);
157
 
158
static ACPI_STATUS
159
AcpiUtCopySimpleObject (
160
    ACPI_OPERAND_OBJECT     *SourceDesc,
161
    ACPI_OPERAND_OBJECT     *DestDesc);
162
 
163
static ACPI_STATUS
164
AcpiUtCopyIelementToEelement (
165
    UINT8                   ObjectType,
166
    ACPI_OPERAND_OBJECT     *SourceObject,
167
    ACPI_GENERIC_STATE      *State,
168
    void                    *Context);
169
 
170
static ACPI_STATUS
171
AcpiUtCopyIpackageToIpackage (
172
    ACPI_OPERAND_OBJECT     *SourceObj,
173
    ACPI_OPERAND_OBJECT     *DestObj,
174
    ACPI_WALK_STATE         *WalkState);
175
 
176
 
177
/*******************************************************************************
178
 *
179
 * FUNCTION:    AcpiUtCopyIsimpleToEsimple
180
 *
181
 * PARAMETERS:  InternalObject      - Source object to be copied
182
 *              ExternalObject      - Where to return the copied object
183
 *              DataSpace           - Where object data is returned (such as
184
 *                                    buffer and string data)
185
 *              BufferSpaceUsed     - Length of DataSpace that was used
186
 *
187
 * RETURN:      Status
188
 *
189
 * DESCRIPTION: This function is called to copy a simple internal object to
190
 *              an external object.
191
 *
192
 *              The DataSpace buffer is assumed to have sufficient space for
193
 *              the object.
194
 *
195
 ******************************************************************************/
196
 
197
static ACPI_STATUS
198
AcpiUtCopyIsimpleToEsimple (
199
    ACPI_OPERAND_OBJECT     *InternalObject,
200
    ACPI_OBJECT             *ExternalObject,
201
    UINT8                   *DataSpace,
202
    ACPI_SIZE               *BufferSpaceUsed)
203
{
204
    ACPI_STATUS             Status = AE_OK;
205
 
206
 
207
    ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple);
208
 
209
 
210
    *BufferSpaceUsed = 0;
211
 
212
    /*
213
     * Check for NULL object case (could be an uninitialized
214
     * package element)
215
     */
216
    if (!InternalObject)
217
    {
218
        return_ACPI_STATUS (AE_OK);
219
    }
220
 
221
    /* Always clear the external object */
222
 
223
    ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT));
224
 
225
    /*
226
     * In general, the external object will be the same type as
227
     * the internal object
228
     */
229
    ExternalObject->Type = InternalObject->Common.Type;
230
 
231
    /* However, only a limited number of external types are supported */
232
 
233
    switch (InternalObject->Common.Type)
234
    {
235
    case ACPI_TYPE_STRING:
236
 
237
        ExternalObject->String.Pointer = (char *) DataSpace;
238
        ExternalObject->String.Length  = InternalObject->String.Length;
239
        *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
240
                            (ACPI_SIZE) InternalObject->String.Length + 1);
241
 
242
        ACPI_MEMCPY ((void *) DataSpace,
243
            (void *) InternalObject->String.Pointer,
244
            (ACPI_SIZE) InternalObject->String.Length + 1);
245
        break;
246
 
247
 
248
    case ACPI_TYPE_BUFFER:
249
 
250
        ExternalObject->Buffer.Pointer = DataSpace;
251
        ExternalObject->Buffer.Length  = InternalObject->Buffer.Length;
252
        *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
253
                            InternalObject->String.Length);
254
 
255
        ACPI_MEMCPY ((void *) DataSpace,
256
            (void *) InternalObject->Buffer.Pointer,
257
            InternalObject->Buffer.Length);
258
        break;
259
 
260
 
261
    case ACPI_TYPE_INTEGER:
262
 
263
        ExternalObject->Integer.Value = InternalObject->Integer.Value;
264
        break;
265
 
266
 
267
    case ACPI_TYPE_LOCAL_REFERENCE:
268
 
269
        /* This is an object reference. */
270
 
271
        switch (InternalObject->Reference.Class)
272
        {
273
        case ACPI_REFCLASS_NAME:
274
 
275
            /*
276
             * For namepath, return the object handle ("reference")
277
             * We are referring to the namespace node
278
             */
279
            ExternalObject->Reference.Handle =
280
                InternalObject->Reference.Node;
281
            ExternalObject->Reference.ActualType =
282
                AcpiNsGetType (InternalObject->Reference.Node);
283
            break;
284
 
285
        default:
286
 
287
            /* All other reference types are unsupported */
288
 
289
            return_ACPI_STATUS (AE_TYPE);
290
        }
291
        break;
292
 
293
 
294
    case ACPI_TYPE_PROCESSOR:
295
 
296
        ExternalObject->Processor.ProcId =
297
            InternalObject->Processor.ProcId;
298
        ExternalObject->Processor.PblkAddress =
299
            InternalObject->Processor.Address;
300
        ExternalObject->Processor.PblkLength =
301
            InternalObject->Processor.Length;
302
        break;
303
 
304
 
305
    case ACPI_TYPE_POWER:
306
 
307
        ExternalObject->PowerResource.SystemLevel =
308
            InternalObject->PowerResource.SystemLevel;
309
 
310
        ExternalObject->PowerResource.ResourceOrder =
311
            InternalObject->PowerResource.ResourceOrder;
312
        break;
313
 
314
 
315
    default:
316
        /*
317
         * There is no corresponding external object type
318
         */
319
        ACPI_ERROR ((AE_INFO,
320
            "Unsupported object type, cannot convert to external object: %s",
321
            AcpiUtGetTypeName (InternalObject->Common.Type)));
322
 
323
        return_ACPI_STATUS (AE_SUPPORT);
324
    }
325
 
326
    return_ACPI_STATUS (Status);
327
}
328
 
329
 
330
/*******************************************************************************
331
 *
332
 * FUNCTION:    AcpiUtCopyIelementToEelement
333
 *
334
 * PARAMETERS:  ACPI_PKG_CALLBACK
335
 *
336
 * RETURN:      Status
337
 *
338
 * DESCRIPTION: Copy one package element to another package element
339
 *
340
 ******************************************************************************/
341
 
342
static ACPI_STATUS
343
AcpiUtCopyIelementToEelement (
344
    UINT8                   ObjectType,
345
    ACPI_OPERAND_OBJECT     *SourceObject,
346
    ACPI_GENERIC_STATE      *State,
347
    void                    *Context)
348
{
349
    ACPI_STATUS             Status = AE_OK;
350
    ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
351
    ACPI_SIZE               ObjectSpace;
352
    UINT32                  ThisIndex;
353
    ACPI_OBJECT             *TargetObject;
354
 
355
 
356
    ACPI_FUNCTION_ENTRY ();
357
 
358
 
359
    ThisIndex    = State->Pkg.Index;
360
    TargetObject = (ACPI_OBJECT *)
361
        &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex];
362
 
363
    switch (ObjectType)
364
    {
365
    case ACPI_COPY_TYPE_SIMPLE:
366
 
367
        /*
368
         * This is a simple or null object
369
         */
370
        Status = AcpiUtCopyIsimpleToEsimple (SourceObject,
371
                        TargetObject, Info->FreeSpace, &ObjectSpace);
372
        if (ACPI_FAILURE (Status))
373
        {
374
            return (Status);
375
        }
376
        break;
377
 
378
 
379
    case ACPI_COPY_TYPE_PACKAGE:
380
 
381
        /*
382
         * Build the package object
383
         */
384
        TargetObject->Type              = ACPI_TYPE_PACKAGE;
385
        TargetObject->Package.Count     = SourceObject->Package.Count;
386
        TargetObject->Package.Elements  =
387
            ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace);
388
 
389
        /*
390
         * Pass the new package object back to the package walk routine
391
         */
392
        State->Pkg.ThisTargetObj = TargetObject;
393
 
394
        /*
395
         * Save space for the array of objects (Package elements)
396
         * update the buffer length counter
397
         */
398
        ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD (
399
                            (ACPI_SIZE) TargetObject->Package.Count *
400
                            sizeof (ACPI_OBJECT));
401
        break;
402
 
403
 
404
    default:
405
        return (AE_BAD_PARAMETER);
406
    }
407
 
408
    Info->FreeSpace   += ObjectSpace;
409
    Info->Length      += ObjectSpace;
410
    return (Status);
411
}
412
 
413
 
414
/*******************************************************************************
415
 *
416
 * FUNCTION:    AcpiUtCopyIpackageToEpackage
417
 *
418
 * PARAMETERS:  InternalObject      - Pointer to the object we are returning
419
 *              Buffer              - Where the object is returned
420
 *              SpaceUsed           - Where the object length is returned
421
 *
422
 * RETURN:      Status
423
 *
424
 * DESCRIPTION: This function is called to place a package object in a user
425
 *              buffer. A package object by definition contains other objects.
426
 *
427
 *              The buffer is assumed to have sufficient space for the object.
428
 *              The caller must have verified the buffer length needed using
429
 *              the AcpiUtGetObjectSize function before calling this function.
430
 *
431
 ******************************************************************************/
432
 
433
static ACPI_STATUS
434
AcpiUtCopyIpackageToEpackage (
435
    ACPI_OPERAND_OBJECT     *InternalObject,
436
    UINT8                   *Buffer,
437
    ACPI_SIZE               *SpaceUsed)
438
{
439
    ACPI_OBJECT             *ExternalObject;
440
    ACPI_STATUS             Status;
441
    ACPI_PKG_INFO           Info;
442
 
443
 
444
    ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage);
445
 
446
 
447
    /*
448
     * First package at head of the buffer
449
     */
450
    ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer);
451
 
452
    /*
453
     * Free space begins right after the first package
454
     */
455
    Info.Length      = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
456
    Info.FreeSpace   = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
457
                                    sizeof (ACPI_OBJECT));
458
    Info.ObjectSpace = 0;
459
    Info.NumPackages = 1;
460
 
461
    ExternalObject->Type             = InternalObject->Common.Type;
462
    ExternalObject->Package.Count    = InternalObject->Package.Count;
463
    ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT,
464
                                            Info.FreeSpace);
465
 
466
    /*
467
     * Leave room for an array of ACPI_OBJECTS in the buffer
468
     * and move the free space past it
469
     */
470
    Info.Length    += (ACPI_SIZE) ExternalObject->Package.Count *
471
                            ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
472
    Info.FreeSpace += ExternalObject->Package.Count *
473
                            ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
474
 
475
    Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject,
476
                AcpiUtCopyIelementToEelement, &Info);
477
 
478
    *SpaceUsed = Info.Length;
479
    return_ACPI_STATUS (Status);
480
}
481
 
482
 
483
/*******************************************************************************
484
 *
485
 * FUNCTION:    AcpiUtCopyIobjectToEobject
486
 *
487
 * PARAMETERS:  InternalObject      - The internal object to be converted
488
 *              RetBuffer           - Where the object is returned
489
 *
490
 * RETURN:      Status
491
 *
492
 * DESCRIPTION: This function is called to build an API object to be returned
493
 *              to the caller.
494
 *
495
 ******************************************************************************/
496
 
497
ACPI_STATUS
498
AcpiUtCopyIobjectToEobject (
499
    ACPI_OPERAND_OBJECT     *InternalObject,
500
    ACPI_BUFFER             *RetBuffer)
501
{
502
    ACPI_STATUS             Status;
503
 
504
 
505
    ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject);
506
 
507
 
508
    if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)
509
    {
510
        /*
511
         * Package object:  Copy all subobjects (including
512
         * nested packages)
513
         */
514
        Status = AcpiUtCopyIpackageToEpackage (InternalObject,
515
                        RetBuffer->Pointer, &RetBuffer->Length);
516
    }
517
    else
518
    {
519
        /*
520
         * Build a simple object (no nested objects)
521
         */
522
        Status = AcpiUtCopyIsimpleToEsimple (InternalObject,
523
                    ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer),
524
                    ACPI_ADD_PTR (UINT8, RetBuffer->Pointer,
525
                        ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
526
                    &RetBuffer->Length);
527
        /*
528
         * build simple does not include the object size in the length
529
         * so we add it in here
530
         */
531
        RetBuffer->Length += sizeof (ACPI_OBJECT);
532
    }
533
 
534
    return_ACPI_STATUS (Status);
535
}
536
 
537
 
538
/*******************************************************************************
539
 *
540
 * FUNCTION:    AcpiUtCopyEsimpleToIsimple
541
 *
542
 * PARAMETERS:  ExternalObject      - The external object to be converted
543
 *              RetInternalObject   - Where the internal object is returned
544
 *
545
 * RETURN:      Status
546
 *
547
 * DESCRIPTION: This function copies an external object to an internal one.
548
 *              NOTE: Pointers can be copied, we don't need to copy data.
549
 *              (The pointers have to be valid in our address space no matter
550
 *              what we do with them!)
551
 *
552
 ******************************************************************************/
553
 
554
static ACPI_STATUS
555
AcpiUtCopyEsimpleToIsimple (
556
    ACPI_OBJECT             *ExternalObject,
557
    ACPI_OPERAND_OBJECT     **RetInternalObject)
558
{
559
    ACPI_OPERAND_OBJECT     *InternalObject;
560
 
561
 
562
    ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple);
563
 
564
 
565
    /*
566
     * Simple types supported are: String, Buffer, Integer
567
     */
568
    switch (ExternalObject->Type)
569
    {
570
    case ACPI_TYPE_STRING:
571
    case ACPI_TYPE_BUFFER:
572
    case ACPI_TYPE_INTEGER:
573
    case ACPI_TYPE_LOCAL_REFERENCE:
574
 
575
        InternalObject = AcpiUtCreateInternalObject (
576
                            (UINT8) ExternalObject->Type);
577
        if (!InternalObject)
578
        {
579
            return_ACPI_STATUS (AE_NO_MEMORY);
580
        }
581
        break;
582
 
583
    case ACPI_TYPE_ANY: /* This is the case for a NULL object */
584
 
585
        *RetInternalObject = NULL;
586
        return_ACPI_STATUS (AE_OK);
587
 
588
    default:
589
        /* All other types are not supported */
590
 
591
        ACPI_ERROR ((AE_INFO,
592
            "Unsupported object type, cannot convert to internal object: %s",
593
            AcpiUtGetTypeName (ExternalObject->Type)));
594
 
595
        return_ACPI_STATUS (AE_SUPPORT);
596
    }
597
 
598
 
599
    /* Must COPY string and buffer contents */
600
 
601
    switch (ExternalObject->Type)
602
    {
603
    case ACPI_TYPE_STRING:
604
 
605
        InternalObject->String.Pointer =
606
            ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
607
                ExternalObject->String.Length + 1);
608
 
609
        if (!InternalObject->String.Pointer)
610
        {
611
            goto ErrorExit;
612
        }
613
 
614
        ACPI_MEMCPY (InternalObject->String.Pointer,
615
                     ExternalObject->String.Pointer,
616
                     ExternalObject->String.Length);
617
 
618
        InternalObject->String.Length  = ExternalObject->String.Length;
619
        break;
620
 
621
 
622
    case ACPI_TYPE_BUFFER:
623
 
624
        InternalObject->Buffer.Pointer =
625
            ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length);
626
        if (!InternalObject->Buffer.Pointer)
627
        {
628
            goto ErrorExit;
629
        }
630
 
631
        ACPI_MEMCPY (InternalObject->Buffer.Pointer,
632
                     ExternalObject->Buffer.Pointer,
633
                     ExternalObject->Buffer.Length);
634
 
635
        InternalObject->Buffer.Length  = ExternalObject->Buffer.Length;
636
 
637
        /* Mark buffer data valid */
638
 
639
        InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID;
640
        break;
641
 
642
 
643
    case ACPI_TYPE_INTEGER:
644
 
645
        InternalObject->Integer.Value   = ExternalObject->Integer.Value;
646
        break;
647
 
648
    case ACPI_TYPE_LOCAL_REFERENCE:
649
 
650
        /* TBD: should validate incoming handle */
651
 
652
        InternalObject->Reference.Class = ACPI_REFCLASS_NAME;
653
        InternalObject->Reference.Node = ExternalObject->Reference.Handle;
654
        break;
655
 
656
    default:
657
        /* Other types can't get here */
658
        break;
659
    }
660
 
661
    *RetInternalObject = InternalObject;
662
    return_ACPI_STATUS (AE_OK);
663
 
664
 
665
ErrorExit:
666
    AcpiUtRemoveReference (InternalObject);
667
    return_ACPI_STATUS (AE_NO_MEMORY);
668
}
669
 
670
 
671
/*******************************************************************************
672
 *
673
 * FUNCTION:    AcpiUtCopyEpackageToIpackage
674
 *
675
 * PARAMETERS:  ExternalObject      - The external object to be converted
676
 *              InternalObject      - Where the internal object is returned
677
 *
678
 * RETURN:      Status
679
 *
680
 * DESCRIPTION: Copy an external package object to an internal package.
681
 *              Handles nested packages.
682
 *
683
 ******************************************************************************/
684
 
685
static ACPI_STATUS
686
AcpiUtCopyEpackageToIpackage (
687
    ACPI_OBJECT             *ExternalObject,
688
    ACPI_OPERAND_OBJECT     **InternalObject)
689
{
690
    ACPI_STATUS             Status = AE_OK;
691
    ACPI_OPERAND_OBJECT     *PackageObject;
692
    ACPI_OPERAND_OBJECT     **PackageElements;
693
    UINT32                  i;
694
 
695
 
696
    ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage);
697
 
698
 
699
    /* Create the package object */
700
 
701
    PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count);
702
    if (!PackageObject)
703
    {
704
        return_ACPI_STATUS (AE_NO_MEMORY);
705
    }
706
 
707
    PackageElements = PackageObject->Package.Elements;
708
 
709
    /*
710
     * Recursive implementation. Probably ok, since nested external packages
711
     * as parameters should be very rare.
712
     */
713
    for (i = 0; i < ExternalObject->Package.Count; i++)
714
    {
715
        Status = AcpiUtCopyEobjectToIobject (
716
                    &ExternalObject->Package.Elements[i],
717
                    &PackageElements[i]);
718
        if (ACPI_FAILURE (Status))
719
        {
720
            /* Truncate package and delete it */
721
 
722
            PackageObject->Package.Count = i;
723
            PackageElements[i] = NULL;
724
            AcpiUtRemoveReference (PackageObject);
725
            return_ACPI_STATUS (Status);
726
        }
727
    }
728
 
729
    /* Mark package data valid */
730
 
731
    PackageObject->Package.Flags |= AOPOBJ_DATA_VALID;
732
 
733
    *InternalObject = PackageObject;
734
    return_ACPI_STATUS (Status);
735
}
736
 
737
 
738
/*******************************************************************************
739
 *
740
 * FUNCTION:    AcpiUtCopyEobjectToIobject
741
 *
742
 * PARAMETERS:  ExternalObject      - The external object to be converted
743
 *              InternalObject      - Where the internal object is returned
744
 *
745
 * RETURN:      Status
746
 *
747
 * DESCRIPTION: Converts an external object to an internal object.
748
 *
749
 ******************************************************************************/
750
 
751
ACPI_STATUS
752
AcpiUtCopyEobjectToIobject (
753
    ACPI_OBJECT             *ExternalObject,
754
    ACPI_OPERAND_OBJECT     **InternalObject)
755
{
756
    ACPI_STATUS             Status;
757
 
758
 
759
    ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject);
760
 
761
 
762
    if (ExternalObject->Type == ACPI_TYPE_PACKAGE)
763
    {
764
        Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject);
765
    }
766
    else
767
    {
768
        /*
769
         * Build a simple object (no nested objects)
770
         */
771
        Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject);
772
    }
773
 
774
    return_ACPI_STATUS (Status);
775
}
776
 
777
 
778
/*******************************************************************************
779
 *
780
 * FUNCTION:    AcpiUtCopySimpleObject
781
 *
782
 * PARAMETERS:  SourceDesc          - The internal object to be copied
783
 *              DestDesc            - New target object
784
 *
785
 * RETURN:      Status
786
 *
787
 * DESCRIPTION: Simple copy of one internal object to another. Reference count
788
 *              of the destination object is preserved.
789
 *
790
 ******************************************************************************/
791
 
792
static ACPI_STATUS
793
AcpiUtCopySimpleObject (
794
    ACPI_OPERAND_OBJECT     *SourceDesc,
795
    ACPI_OPERAND_OBJECT     *DestDesc)
796
{
797
    UINT16                  ReferenceCount;
798
    ACPI_OPERAND_OBJECT     *NextObject;
799
    ACPI_STATUS             Status;
800
    ACPI_SIZE               CopySize;
801
 
802
 
803
    /* Save fields from destination that we don't want to overwrite */
804
 
805
    ReferenceCount = DestDesc->Common.ReferenceCount;
806
    NextObject = DestDesc->Common.NextObject;
807
 
808
    /*
809
     * Copy the entire source object over the destination object.
810
     * Note: Source can be either an operand object or namespace node.
811
     */
812
    CopySize = sizeof (ACPI_OPERAND_OBJECT);
813
    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
814
    {
815
        CopySize = sizeof (ACPI_NAMESPACE_NODE);
816
    }
817
 
818
    ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc),
819
        ACPI_CAST_PTR (char, SourceDesc), CopySize);
820
 
821
    /* Restore the saved fields */
822
 
823
    DestDesc->Common.ReferenceCount = ReferenceCount;
824
    DestDesc->Common.NextObject = NextObject;
825
 
826
    /* New object is not static, regardless of source */
827
 
828
    DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
829
 
830
    /* Handle the objects with extra data */
831
 
832
    switch (DestDesc->Common.Type)
833
    {
834
    case ACPI_TYPE_BUFFER:
835
        /*
836
         * Allocate and copy the actual buffer if and only if:
837
         * 1) There is a valid buffer pointer
838
         * 2) The buffer has a length > 0
839
         */
840
        if ((SourceDesc->Buffer.Pointer) &&
841
            (SourceDesc->Buffer.Length))
842
        {
843
            DestDesc->Buffer.Pointer =
844
                ACPI_ALLOCATE (SourceDesc->Buffer.Length);
845
            if (!DestDesc->Buffer.Pointer)
846
            {
847
                return (AE_NO_MEMORY);
848
            }
849
 
850
            /* Copy the actual buffer data */
851
 
852
            ACPI_MEMCPY (DestDesc->Buffer.Pointer,
853
                SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
854
        }
855
        break;
856
 
857
    case ACPI_TYPE_STRING:
858
        /*
859
         * Allocate and copy the actual string if and only if:
860
         * 1) There is a valid string pointer
861
         * (Pointer to a NULL string is allowed)
862
         */
863
        if (SourceDesc->String.Pointer)
864
        {
865
            DestDesc->String.Pointer =
866
                ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
867
            if (!DestDesc->String.Pointer)
868
            {
869
                return (AE_NO_MEMORY);
870
            }
871
 
872
            /* Copy the actual string data */
873
 
874
            ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer,
875
                (ACPI_SIZE) SourceDesc->String.Length + 1);
876
        }
877
        break;
878
 
879
    case ACPI_TYPE_LOCAL_REFERENCE:
880
        /*
881
         * We copied the reference object, so we now must add a reference
882
         * to the object pointed to by the reference
883
         *
884
         * DDBHandle reference (from Load/LoadTable) is a special reference,
885
         * it does not have a Reference.Object, so does not need to
886
         * increase the reference count
887
         */
888
        if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
889
        {
890
            break;
891
        }
892
 
893
        AcpiUtAddReference (SourceDesc->Reference.Object);
894
        break;
895
 
896
    case ACPI_TYPE_REGION:
897
        /*
898
         * We copied the Region Handler, so we now must add a reference
899
         */
900
        if (DestDesc->Region.Handler)
901
        {
902
            AcpiUtAddReference (DestDesc->Region.Handler);
903
        }
904
        break;
905
 
906
    /*
907
     * For Mutex and Event objects, we cannot simply copy the underlying
908
     * OS object. We must create a new one.
909
     */
910
    case ACPI_TYPE_MUTEX:
911
 
912
        Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
913
        if (ACPI_FAILURE (Status))
914
        {
915
            return (Status);
916
        }
917
        break;
918
 
919
    case ACPI_TYPE_EVENT:
920
 
921
        Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
922
                    &DestDesc->Event.OsSemaphore);
923
        if (ACPI_FAILURE (Status))
924
        {
925
            return (Status);
926
        }
927
        break;
928
 
929
    default:
930
        /* Nothing to do for other simple objects */
931
        break;
932
    }
933
 
934
    return (AE_OK);
935
}
936
 
937
 
938
/*******************************************************************************
939
 *
940
 * FUNCTION:    AcpiUtCopyIelementToIelement
941
 *
942
 * PARAMETERS:  ACPI_PKG_CALLBACK
943
 *
944
 * RETURN:      Status
945
 *
946
 * DESCRIPTION: Copy one package element to another package element
947
 *
948
 ******************************************************************************/
949
 
950
static ACPI_STATUS
951
AcpiUtCopyIelementToIelement (
952
    UINT8                   ObjectType,
953
    ACPI_OPERAND_OBJECT     *SourceObject,
954
    ACPI_GENERIC_STATE      *State,
955
    void                    *Context)
956
{
957
    ACPI_STATUS             Status = AE_OK;
958
    UINT32                  ThisIndex;
959
    ACPI_OPERAND_OBJECT     **ThisTargetPtr;
960
    ACPI_OPERAND_OBJECT     *TargetObject;
961
 
962
 
963
    ACPI_FUNCTION_ENTRY ();
964
 
965
 
966
    ThisIndex     = State->Pkg.Index;
967
    ThisTargetPtr = (ACPI_OPERAND_OBJECT **)
968
                        &State->Pkg.DestObject->Package.Elements[ThisIndex];
969
 
970
    switch (ObjectType)
971
    {
972
    case ACPI_COPY_TYPE_SIMPLE:
973
 
974
        /* A null source object indicates a (legal) null package element */
975
 
976
        if (SourceObject)
977
        {
978
            /*
979
             * This is a simple object, just copy it
980
             */
981
            TargetObject = AcpiUtCreateInternalObject (
982
                                SourceObject->Common.Type);
983
            if (!TargetObject)
984
            {
985
                return (AE_NO_MEMORY);
986
            }
987
 
988
            Status = AcpiUtCopySimpleObject (SourceObject, TargetObject);
989
            if (ACPI_FAILURE (Status))
990
            {
991
                goto ErrorExit;
992
            }
993
 
994
            *ThisTargetPtr = TargetObject;
995
        }
996
        else
997
        {
998
            /* Pass through a null element */
999
 
1000
            *ThisTargetPtr = NULL;
1001
        }
1002
        break;
1003
 
1004
 
1005
    case ACPI_COPY_TYPE_PACKAGE:
1006
 
1007
        /*
1008
         * This object is a package - go down another nesting level
1009
         * Create and build the package object
1010
         */
1011
        TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count);
1012
        if (!TargetObject)
1013
        {
1014
            return (AE_NO_MEMORY);
1015
        }
1016
 
1017
        TargetObject->Common.Flags = SourceObject->Common.Flags;
1018
 
1019
        /* Pass the new package object back to the package walk routine */
1020
 
1021
        State->Pkg.ThisTargetObj = TargetObject;
1022
 
1023
        /* Store the object pointer in the parent package object */
1024
 
1025
        *ThisTargetPtr = TargetObject;
1026
        break;
1027
 
1028
 
1029
    default:
1030
        return (AE_BAD_PARAMETER);
1031
    }
1032
 
1033
    return (Status);
1034
 
1035
ErrorExit:
1036
    AcpiUtRemoveReference (TargetObject);
1037
    return (Status);
1038
}
1039
 
1040
 
1041
/*******************************************************************************
1042
 *
1043
 * FUNCTION:    AcpiUtCopyIpackageToIpackage
1044
 *
1045
 * PARAMETERS:  SourceObj       - Pointer to the source package object
1046
 *              DestObj         - Where the internal object is returned
1047
 *              WalkState       - Current Walk state descriptor
1048
 *
1049
 * RETURN:      Status
1050
 *
1051
 * DESCRIPTION: This function is called to copy an internal package object
1052
 *              into another internal package object.
1053
 *
1054
 ******************************************************************************/
1055
 
1056
static ACPI_STATUS
1057
AcpiUtCopyIpackageToIpackage (
1058
    ACPI_OPERAND_OBJECT     *SourceObj,
1059
    ACPI_OPERAND_OBJECT     *DestObj,
1060
    ACPI_WALK_STATE         *WalkState)
1061
{
1062
    ACPI_STATUS             Status = AE_OK;
1063
 
1064
 
1065
    ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage);
1066
 
1067
 
1068
    DestObj->Common.Type    = SourceObj->Common.Type;
1069
    DestObj->Common.Flags   = SourceObj->Common.Flags;
1070
    DestObj->Package.Count  = SourceObj->Package.Count;
1071
 
1072
    /*
1073
     * Create the object array and walk the source package tree
1074
     */
1075
    DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED (
1076
                                    ((ACPI_SIZE) SourceObj->Package.Count + 1) *
1077
                                    sizeof (void *));
1078
    if (!DestObj->Package.Elements)
1079
    {
1080
        ACPI_ERROR ((AE_INFO, "Package allocation failure"));
1081
        return_ACPI_STATUS (AE_NO_MEMORY);
1082
    }
1083
 
1084
    /*
1085
     * Copy the package element-by-element by walking the package "tree".
1086
     * This handles nested packages of arbitrary depth.
1087
     */
1088
    Status = AcpiUtWalkPackageTree (SourceObj, DestObj,
1089
                AcpiUtCopyIelementToIelement, WalkState);
1090
    if (ACPI_FAILURE (Status))
1091
    {
1092
        /* On failure, delete the destination package object */
1093
 
1094
        AcpiUtRemoveReference (DestObj);
1095
    }
1096
 
1097
    return_ACPI_STATUS (Status);
1098
}
1099
 
1100
 
1101
/*******************************************************************************
1102
 *
1103
 * FUNCTION:    AcpiUtCopyIobjectToIobject
1104
 *
1105
 * PARAMETERS:  SourceDesc          - The internal object to be copied
1106
 *              DestDesc            - Where the copied object is returned
1107
 *              WalkState           - Current walk state
1108
 *
1109
 * RETURN:      Status
1110
 *
1111
 * DESCRIPTION: Copy an internal object to a new internal object
1112
 *
1113
 ******************************************************************************/
1114
 
1115
ACPI_STATUS
1116
AcpiUtCopyIobjectToIobject (
1117
    ACPI_OPERAND_OBJECT     *SourceDesc,
1118
    ACPI_OPERAND_OBJECT     **DestDesc,
1119
    ACPI_WALK_STATE         *WalkState)
1120
{
1121
    ACPI_STATUS             Status = AE_OK;
1122
 
1123
 
1124
    ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject);
1125
 
1126
 
1127
    /* Create the top level object */
1128
 
1129
    *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type);
1130
    if (!*DestDesc)
1131
    {
1132
        return_ACPI_STATUS (AE_NO_MEMORY);
1133
    }
1134
 
1135
    /* Copy the object and possible subobjects */
1136
 
1137
    if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE)
1138
    {
1139
        Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc,
1140
                        WalkState);
1141
    }
1142
    else
1143
    {
1144
        Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc);
1145
    }
1146
 
1147
    return_ACPI_STATUS (Status);
1148
}
1149