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