OSDN Git Service

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