xref: /minix3/minix/drivers/power/acpi/utilities/utcopy.c (revision 29492bb71c7148a089a5afafa0c99409161218df)
1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc  *
3433d6423SLionel Sambuc  * Module Name: utcopy - Internal to external object translation utilities
4433d6423SLionel Sambuc  *
5433d6423SLionel Sambuc  *****************************************************************************/
6433d6423SLionel Sambuc 
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek  * Copyright (C) 2000 - 2014, Intel Corp.
9433d6423SLionel Sambuc  * All rights reserved.
10433d6423SLionel Sambuc  *
11*29492bb7SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek  * are met:
14*29492bb7SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek  *    notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek  *    without modification.
17*29492bb7SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek  *    substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek  *    ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek  *    including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek  *    binary redistribution.
22*29492bb7SDavid van Moolenbroek  * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek  *    of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek  *    from this software without specific prior written permission.
25433d6423SLionel Sambuc  *
26*29492bb7SDavid van Moolenbroek  * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek  * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek  * Software Foundation.
29433d6423SLionel Sambuc  *
30*29492bb7SDavid van Moolenbroek  * NO WARRANTY
31*29492bb7SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek  */
43433d6423SLionel Sambuc 
44433d6423SLionel Sambuc #include "acpi.h"
45433d6423SLionel Sambuc #include "accommon.h"
46433d6423SLionel Sambuc #include "acnamesp.h"
47433d6423SLionel Sambuc 
48433d6423SLionel Sambuc 
49433d6423SLionel Sambuc #define _COMPONENT          ACPI_UTILITIES
50433d6423SLionel Sambuc         ACPI_MODULE_NAME    ("utcopy")
51433d6423SLionel Sambuc 
52433d6423SLionel Sambuc /* Local prototypes */
53433d6423SLionel Sambuc 
54433d6423SLionel Sambuc static ACPI_STATUS
55433d6423SLionel Sambuc AcpiUtCopyIsimpleToEsimple (
56433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *InternalObject,
57433d6423SLionel Sambuc     ACPI_OBJECT             *ExternalObject,
58433d6423SLionel Sambuc     UINT8                   *DataSpace,
59433d6423SLionel Sambuc     ACPI_SIZE               *BufferSpaceUsed);
60433d6423SLionel Sambuc 
61433d6423SLionel Sambuc static ACPI_STATUS
62433d6423SLionel Sambuc AcpiUtCopyIelementToIelement (
63433d6423SLionel Sambuc     UINT8                   ObjectType,
64433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceObject,
65433d6423SLionel Sambuc     ACPI_GENERIC_STATE      *State,
66433d6423SLionel Sambuc     void                    *Context);
67433d6423SLionel Sambuc 
68433d6423SLionel Sambuc static ACPI_STATUS
69433d6423SLionel Sambuc AcpiUtCopyIpackageToEpackage (
70433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *InternalObject,
71433d6423SLionel Sambuc     UINT8                   *Buffer,
72433d6423SLionel Sambuc     ACPI_SIZE               *SpaceUsed);
73433d6423SLionel Sambuc 
74433d6423SLionel Sambuc static ACPI_STATUS
75433d6423SLionel Sambuc AcpiUtCopyEsimpleToIsimple(
76433d6423SLionel Sambuc     ACPI_OBJECT             *UserObj,
77433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **ReturnObj);
78433d6423SLionel Sambuc 
79433d6423SLionel Sambuc static ACPI_STATUS
80433d6423SLionel Sambuc AcpiUtCopyEpackageToIpackage (
81433d6423SLionel Sambuc     ACPI_OBJECT             *ExternalObject,
82433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **InternalObject);
83433d6423SLionel Sambuc 
84433d6423SLionel Sambuc static ACPI_STATUS
85433d6423SLionel Sambuc AcpiUtCopySimpleObject (
86433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceDesc,
87433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *DestDesc);
88433d6423SLionel Sambuc 
89433d6423SLionel Sambuc static ACPI_STATUS
90433d6423SLionel Sambuc AcpiUtCopyIelementToEelement (
91433d6423SLionel Sambuc     UINT8                   ObjectType,
92433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceObject,
93433d6423SLionel Sambuc     ACPI_GENERIC_STATE      *State,
94433d6423SLionel Sambuc     void                    *Context);
95433d6423SLionel Sambuc 
96433d6423SLionel Sambuc static ACPI_STATUS
97433d6423SLionel Sambuc AcpiUtCopyIpackageToIpackage (
98433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceObj,
99433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *DestObj,
100433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState);
101433d6423SLionel Sambuc 
102433d6423SLionel Sambuc 
103433d6423SLionel Sambuc /*******************************************************************************
104433d6423SLionel Sambuc  *
105433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyIsimpleToEsimple
106433d6423SLionel Sambuc  *
107433d6423SLionel Sambuc  * PARAMETERS:  InternalObject      - Source object to be copied
108433d6423SLionel Sambuc  *              ExternalObject      - Where to return the copied object
109433d6423SLionel Sambuc  *              DataSpace           - Where object data is returned (such as
110433d6423SLionel Sambuc  *                                    buffer and string data)
111433d6423SLionel Sambuc  *              BufferSpaceUsed     - Length of DataSpace that was used
112433d6423SLionel Sambuc  *
113433d6423SLionel Sambuc  * RETURN:      Status
114433d6423SLionel Sambuc  *
115433d6423SLionel Sambuc  * DESCRIPTION: This function is called to copy a simple internal object to
116433d6423SLionel Sambuc  *              an external object.
117433d6423SLionel Sambuc  *
118433d6423SLionel Sambuc  *              The DataSpace buffer is assumed to have sufficient space for
119433d6423SLionel Sambuc  *              the object.
120433d6423SLionel Sambuc  *
121433d6423SLionel Sambuc  ******************************************************************************/
122433d6423SLionel Sambuc 
123433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopyIsimpleToEsimple(ACPI_OPERAND_OBJECT * InternalObject,ACPI_OBJECT * ExternalObject,UINT8 * DataSpace,ACPI_SIZE * BufferSpaceUsed)124433d6423SLionel Sambuc AcpiUtCopyIsimpleToEsimple (
125433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *InternalObject,
126433d6423SLionel Sambuc     ACPI_OBJECT             *ExternalObject,
127433d6423SLionel Sambuc     UINT8                   *DataSpace,
128433d6423SLionel Sambuc     ACPI_SIZE               *BufferSpaceUsed)
129433d6423SLionel Sambuc {
130433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
131433d6423SLionel Sambuc 
132433d6423SLionel Sambuc 
133433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple);
134433d6423SLionel Sambuc 
135433d6423SLionel Sambuc 
136433d6423SLionel Sambuc     *BufferSpaceUsed = 0;
137433d6423SLionel Sambuc 
138433d6423SLionel Sambuc     /*
139433d6423SLionel Sambuc      * Check for NULL object case (could be an uninitialized
140433d6423SLionel Sambuc      * package element)
141433d6423SLionel Sambuc      */
142433d6423SLionel Sambuc     if (!InternalObject)
143433d6423SLionel Sambuc     {
144433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
145433d6423SLionel Sambuc     }
146433d6423SLionel Sambuc 
147433d6423SLionel Sambuc     /* Always clear the external object */
148433d6423SLionel Sambuc 
149433d6423SLionel Sambuc     ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT));
150433d6423SLionel Sambuc 
151433d6423SLionel Sambuc     /*
152433d6423SLionel Sambuc      * In general, the external object will be the same type as
153433d6423SLionel Sambuc      * the internal object
154433d6423SLionel Sambuc      */
155433d6423SLionel Sambuc     ExternalObject->Type = InternalObject->Common.Type;
156433d6423SLionel Sambuc 
157433d6423SLionel Sambuc     /* However, only a limited number of external types are supported */
158433d6423SLionel Sambuc 
159433d6423SLionel Sambuc     switch (InternalObject->Common.Type)
160433d6423SLionel Sambuc     {
161433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
162433d6423SLionel Sambuc 
163433d6423SLionel Sambuc         ExternalObject->String.Pointer = (char *) DataSpace;
164433d6423SLionel Sambuc         ExternalObject->String.Length  = InternalObject->String.Length;
165433d6423SLionel Sambuc         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
166433d6423SLionel Sambuc                             (ACPI_SIZE) InternalObject->String.Length + 1);
167433d6423SLionel Sambuc 
168433d6423SLionel Sambuc         ACPI_MEMCPY ((void *) DataSpace,
169433d6423SLionel Sambuc             (void *) InternalObject->String.Pointer,
170433d6423SLionel Sambuc             (ACPI_SIZE) InternalObject->String.Length + 1);
171433d6423SLionel Sambuc         break;
172433d6423SLionel Sambuc 
173433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
174433d6423SLionel Sambuc 
175433d6423SLionel Sambuc         ExternalObject->Buffer.Pointer = DataSpace;
176433d6423SLionel Sambuc         ExternalObject->Buffer.Length  = InternalObject->Buffer.Length;
177433d6423SLionel Sambuc         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
178433d6423SLionel Sambuc                             InternalObject->String.Length);
179433d6423SLionel Sambuc 
180433d6423SLionel Sambuc         ACPI_MEMCPY ((void *) DataSpace,
181433d6423SLionel Sambuc             (void *) InternalObject->Buffer.Pointer,
182433d6423SLionel Sambuc             InternalObject->Buffer.Length);
183433d6423SLionel Sambuc         break;
184433d6423SLionel Sambuc 
185433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
186433d6423SLionel Sambuc 
187433d6423SLionel Sambuc         ExternalObject->Integer.Value = InternalObject->Integer.Value;
188433d6423SLionel Sambuc         break;
189433d6423SLionel Sambuc 
190433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_REFERENCE:
191433d6423SLionel Sambuc 
192433d6423SLionel Sambuc         /* This is an object reference. */
193433d6423SLionel Sambuc 
194433d6423SLionel Sambuc         switch (InternalObject->Reference.Class)
195433d6423SLionel Sambuc         {
196433d6423SLionel Sambuc         case ACPI_REFCLASS_NAME:
197433d6423SLionel Sambuc             /*
198433d6423SLionel Sambuc              * For namepath, return the object handle ("reference")
199433d6423SLionel Sambuc              * We are referring to the namespace node
200433d6423SLionel Sambuc              */
201433d6423SLionel Sambuc             ExternalObject->Reference.Handle =
202433d6423SLionel Sambuc                 InternalObject->Reference.Node;
203433d6423SLionel Sambuc             ExternalObject->Reference.ActualType =
204433d6423SLionel Sambuc                 AcpiNsGetType (InternalObject->Reference.Node);
205433d6423SLionel Sambuc             break;
206433d6423SLionel Sambuc 
207433d6423SLionel Sambuc         default:
208433d6423SLionel Sambuc 
209433d6423SLionel Sambuc             /* All other reference types are unsupported */
210433d6423SLionel Sambuc 
211433d6423SLionel Sambuc             return_ACPI_STATUS (AE_TYPE);
212433d6423SLionel Sambuc         }
213433d6423SLionel Sambuc         break;
214433d6423SLionel Sambuc 
215433d6423SLionel Sambuc     case ACPI_TYPE_PROCESSOR:
216433d6423SLionel Sambuc 
217433d6423SLionel Sambuc         ExternalObject->Processor.ProcId =
218433d6423SLionel Sambuc             InternalObject->Processor.ProcId;
219433d6423SLionel Sambuc         ExternalObject->Processor.PblkAddress =
220433d6423SLionel Sambuc             InternalObject->Processor.Address;
221433d6423SLionel Sambuc         ExternalObject->Processor.PblkLength =
222433d6423SLionel Sambuc             InternalObject->Processor.Length;
223433d6423SLionel Sambuc         break;
224433d6423SLionel Sambuc 
225433d6423SLionel Sambuc     case ACPI_TYPE_POWER:
226433d6423SLionel Sambuc 
227433d6423SLionel Sambuc         ExternalObject->PowerResource.SystemLevel =
228433d6423SLionel Sambuc             InternalObject->PowerResource.SystemLevel;
229433d6423SLionel Sambuc 
230433d6423SLionel Sambuc         ExternalObject->PowerResource.ResourceOrder =
231433d6423SLionel Sambuc             InternalObject->PowerResource.ResourceOrder;
232433d6423SLionel Sambuc         break;
233433d6423SLionel Sambuc 
234433d6423SLionel Sambuc     default:
235433d6423SLionel Sambuc         /*
236433d6423SLionel Sambuc          * There is no corresponding external object type
237433d6423SLionel Sambuc          */
238433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
239433d6423SLionel Sambuc             "Unsupported object type, cannot convert to external object: %s",
240433d6423SLionel Sambuc             AcpiUtGetTypeName (InternalObject->Common.Type)));
241433d6423SLionel Sambuc 
242433d6423SLionel Sambuc         return_ACPI_STATUS (AE_SUPPORT);
243433d6423SLionel Sambuc     }
244433d6423SLionel Sambuc 
245433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
246433d6423SLionel Sambuc }
247433d6423SLionel Sambuc 
248433d6423SLionel Sambuc 
249433d6423SLionel Sambuc /*******************************************************************************
250433d6423SLionel Sambuc  *
251433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyIelementToEelement
252433d6423SLionel Sambuc  *
253433d6423SLionel Sambuc  * PARAMETERS:  ACPI_PKG_CALLBACK
254433d6423SLionel Sambuc  *
255433d6423SLionel Sambuc  * RETURN:      Status
256433d6423SLionel Sambuc  *
257433d6423SLionel Sambuc  * DESCRIPTION: Copy one package element to another package element
258433d6423SLionel Sambuc  *
259433d6423SLionel Sambuc  ******************************************************************************/
260433d6423SLionel Sambuc 
261433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopyIelementToEelement(UINT8 ObjectType,ACPI_OPERAND_OBJECT * SourceObject,ACPI_GENERIC_STATE * State,void * Context)262433d6423SLionel Sambuc AcpiUtCopyIelementToEelement (
263433d6423SLionel Sambuc     UINT8                   ObjectType,
264433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceObject,
265433d6423SLionel Sambuc     ACPI_GENERIC_STATE      *State,
266433d6423SLionel Sambuc     void                    *Context)
267433d6423SLionel Sambuc {
268433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
269433d6423SLionel Sambuc     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
270433d6423SLionel Sambuc     ACPI_SIZE               ObjectSpace;
271433d6423SLionel Sambuc     UINT32                  ThisIndex;
272433d6423SLionel Sambuc     ACPI_OBJECT             *TargetObject;
273433d6423SLionel Sambuc 
274433d6423SLionel Sambuc 
275433d6423SLionel Sambuc     ACPI_FUNCTION_ENTRY ();
276433d6423SLionel Sambuc 
277433d6423SLionel Sambuc 
278433d6423SLionel Sambuc     ThisIndex    = State->Pkg.Index;
279433d6423SLionel Sambuc     TargetObject = (ACPI_OBJECT *)
280433d6423SLionel Sambuc         &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex];
281433d6423SLionel Sambuc 
282433d6423SLionel Sambuc     switch (ObjectType)
283433d6423SLionel Sambuc     {
284433d6423SLionel Sambuc     case ACPI_COPY_TYPE_SIMPLE:
285433d6423SLionel Sambuc         /*
286433d6423SLionel Sambuc          * This is a simple or null object
287433d6423SLionel Sambuc          */
288433d6423SLionel Sambuc         Status = AcpiUtCopyIsimpleToEsimple (SourceObject,
289433d6423SLionel Sambuc                         TargetObject, Info->FreeSpace, &ObjectSpace);
290433d6423SLionel Sambuc         if (ACPI_FAILURE (Status))
291433d6423SLionel Sambuc         {
292433d6423SLionel Sambuc             return (Status);
293433d6423SLionel Sambuc         }
294433d6423SLionel Sambuc         break;
295433d6423SLionel Sambuc 
296433d6423SLionel Sambuc     case ACPI_COPY_TYPE_PACKAGE:
297433d6423SLionel Sambuc         /*
298433d6423SLionel Sambuc          * Build the package object
299433d6423SLionel Sambuc          */
300433d6423SLionel Sambuc         TargetObject->Type              = ACPI_TYPE_PACKAGE;
301433d6423SLionel Sambuc         TargetObject->Package.Count     = SourceObject->Package.Count;
302433d6423SLionel Sambuc         TargetObject->Package.Elements  =
303433d6423SLionel Sambuc             ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace);
304433d6423SLionel Sambuc 
305433d6423SLionel Sambuc         /*
306433d6423SLionel Sambuc          * Pass the new package object back to the package walk routine
307433d6423SLionel Sambuc          */
308433d6423SLionel Sambuc         State->Pkg.ThisTargetObj = TargetObject;
309433d6423SLionel Sambuc 
310433d6423SLionel Sambuc         /*
311433d6423SLionel Sambuc          * Save space for the array of objects (Package elements)
312433d6423SLionel Sambuc          * update the buffer length counter
313433d6423SLionel Sambuc          */
314433d6423SLionel Sambuc         ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD (
315433d6423SLionel Sambuc                             (ACPI_SIZE) TargetObject->Package.Count *
316433d6423SLionel Sambuc                             sizeof (ACPI_OBJECT));
317433d6423SLionel Sambuc         break;
318433d6423SLionel Sambuc 
319433d6423SLionel Sambuc     default:
320*29492bb7SDavid van Moolenbroek 
321433d6423SLionel Sambuc         return (AE_BAD_PARAMETER);
322433d6423SLionel Sambuc     }
323433d6423SLionel Sambuc 
324433d6423SLionel Sambuc     Info->FreeSpace   += ObjectSpace;
325433d6423SLionel Sambuc     Info->Length      += ObjectSpace;
326433d6423SLionel Sambuc     return (Status);
327433d6423SLionel Sambuc }
328433d6423SLionel Sambuc 
329433d6423SLionel Sambuc 
330433d6423SLionel Sambuc /*******************************************************************************
331433d6423SLionel Sambuc  *
332433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyIpackageToEpackage
333433d6423SLionel Sambuc  *
334433d6423SLionel Sambuc  * PARAMETERS:  InternalObject      - Pointer to the object we are returning
335433d6423SLionel Sambuc  *              Buffer              - Where the object is returned
336433d6423SLionel Sambuc  *              SpaceUsed           - Where the object length is returned
337433d6423SLionel Sambuc  *
338433d6423SLionel Sambuc  * RETURN:      Status
339433d6423SLionel Sambuc  *
340433d6423SLionel Sambuc  * DESCRIPTION: This function is called to place a package object in a user
341433d6423SLionel Sambuc  *              buffer. A package object by definition contains other objects.
342433d6423SLionel Sambuc  *
343433d6423SLionel Sambuc  *              The buffer is assumed to have sufficient space for the object.
344433d6423SLionel Sambuc  *              The caller must have verified the buffer length needed using
345433d6423SLionel Sambuc  *              the AcpiUtGetObjectSize function before calling this function.
346433d6423SLionel Sambuc  *
347433d6423SLionel Sambuc  ******************************************************************************/
348433d6423SLionel Sambuc 
349433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopyIpackageToEpackage(ACPI_OPERAND_OBJECT * InternalObject,UINT8 * Buffer,ACPI_SIZE * SpaceUsed)350433d6423SLionel Sambuc AcpiUtCopyIpackageToEpackage (
351433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *InternalObject,
352433d6423SLionel Sambuc     UINT8                   *Buffer,
353433d6423SLionel Sambuc     ACPI_SIZE               *SpaceUsed)
354433d6423SLionel Sambuc {
355433d6423SLionel Sambuc     ACPI_OBJECT             *ExternalObject;
356433d6423SLionel Sambuc     ACPI_STATUS             Status;
357433d6423SLionel Sambuc     ACPI_PKG_INFO           Info;
358433d6423SLionel Sambuc 
359433d6423SLionel Sambuc 
360433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage);
361433d6423SLionel Sambuc 
362433d6423SLionel Sambuc 
363433d6423SLionel Sambuc     /*
364433d6423SLionel Sambuc      * First package at head of the buffer
365433d6423SLionel Sambuc      */
366433d6423SLionel Sambuc     ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer);
367433d6423SLionel Sambuc 
368433d6423SLionel Sambuc     /*
369433d6423SLionel Sambuc      * Free space begins right after the first package
370433d6423SLionel Sambuc      */
371433d6423SLionel Sambuc     Info.Length      = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
372433d6423SLionel Sambuc     Info.FreeSpace   = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
373433d6423SLionel Sambuc                                     sizeof (ACPI_OBJECT));
374433d6423SLionel Sambuc     Info.ObjectSpace = 0;
375433d6423SLionel Sambuc     Info.NumPackages = 1;
376433d6423SLionel Sambuc 
377433d6423SLionel Sambuc     ExternalObject->Type             = InternalObject->Common.Type;
378433d6423SLionel Sambuc     ExternalObject->Package.Count    = InternalObject->Package.Count;
379433d6423SLionel Sambuc     ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT,
380433d6423SLionel Sambuc                                             Info.FreeSpace);
381433d6423SLionel Sambuc 
382433d6423SLionel Sambuc     /*
383433d6423SLionel Sambuc      * Leave room for an array of ACPI_OBJECTS in the buffer
384433d6423SLionel Sambuc      * and move the free space past it
385433d6423SLionel Sambuc      */
386433d6423SLionel Sambuc     Info.Length    += (ACPI_SIZE) ExternalObject->Package.Count *
387433d6423SLionel Sambuc                             ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
388433d6423SLionel Sambuc     Info.FreeSpace += ExternalObject->Package.Count *
389433d6423SLionel Sambuc                             ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
390433d6423SLionel Sambuc 
391433d6423SLionel Sambuc     Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject,
392433d6423SLionel Sambuc                 AcpiUtCopyIelementToEelement, &Info);
393433d6423SLionel Sambuc 
394433d6423SLionel Sambuc     *SpaceUsed = Info.Length;
395433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
396433d6423SLionel Sambuc }
397433d6423SLionel Sambuc 
398433d6423SLionel Sambuc 
399433d6423SLionel Sambuc /*******************************************************************************
400433d6423SLionel Sambuc  *
401433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyIobjectToEobject
402433d6423SLionel Sambuc  *
403433d6423SLionel Sambuc  * PARAMETERS:  InternalObject      - The internal object to be converted
404433d6423SLionel Sambuc  *              RetBuffer           - Where the object is returned
405433d6423SLionel Sambuc  *
406433d6423SLionel Sambuc  * RETURN:      Status
407433d6423SLionel Sambuc  *
408433d6423SLionel Sambuc  * DESCRIPTION: This function is called to build an API object to be returned
409433d6423SLionel Sambuc  *              to the caller.
410433d6423SLionel Sambuc  *
411433d6423SLionel Sambuc  ******************************************************************************/
412433d6423SLionel Sambuc 
413433d6423SLionel Sambuc ACPI_STATUS
AcpiUtCopyIobjectToEobject(ACPI_OPERAND_OBJECT * InternalObject,ACPI_BUFFER * RetBuffer)414433d6423SLionel Sambuc AcpiUtCopyIobjectToEobject (
415433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *InternalObject,
416433d6423SLionel Sambuc     ACPI_BUFFER             *RetBuffer)
417433d6423SLionel Sambuc {
418433d6423SLionel Sambuc     ACPI_STATUS             Status;
419433d6423SLionel Sambuc 
420433d6423SLionel Sambuc 
421433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject);
422433d6423SLionel Sambuc 
423433d6423SLionel Sambuc 
424433d6423SLionel Sambuc     if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)
425433d6423SLionel Sambuc     {
426433d6423SLionel Sambuc         /*
427433d6423SLionel Sambuc          * Package object:  Copy all subobjects (including
428433d6423SLionel Sambuc          * nested packages)
429433d6423SLionel Sambuc          */
430433d6423SLionel Sambuc         Status = AcpiUtCopyIpackageToEpackage (InternalObject,
431433d6423SLionel Sambuc                         RetBuffer->Pointer, &RetBuffer->Length);
432433d6423SLionel Sambuc     }
433433d6423SLionel Sambuc     else
434433d6423SLionel Sambuc     {
435433d6423SLionel Sambuc         /*
436433d6423SLionel Sambuc          * Build a simple object (no nested objects)
437433d6423SLionel Sambuc          */
438433d6423SLionel Sambuc         Status = AcpiUtCopyIsimpleToEsimple (InternalObject,
439433d6423SLionel Sambuc                     ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer),
440433d6423SLionel Sambuc                     ACPI_ADD_PTR (UINT8, RetBuffer->Pointer,
441433d6423SLionel Sambuc                         ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
442433d6423SLionel Sambuc                     &RetBuffer->Length);
443433d6423SLionel Sambuc         /*
444433d6423SLionel Sambuc          * build simple does not include the object size in the length
445433d6423SLionel Sambuc          * so we add it in here
446433d6423SLionel Sambuc          */
447433d6423SLionel Sambuc         RetBuffer->Length += sizeof (ACPI_OBJECT);
448433d6423SLionel Sambuc     }
449433d6423SLionel Sambuc 
450433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
451433d6423SLionel Sambuc }
452433d6423SLionel Sambuc 
453433d6423SLionel Sambuc 
454433d6423SLionel Sambuc /*******************************************************************************
455433d6423SLionel Sambuc  *
456433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyEsimpleToIsimple
457433d6423SLionel Sambuc  *
458433d6423SLionel Sambuc  * PARAMETERS:  ExternalObject      - The external object to be converted
459433d6423SLionel Sambuc  *              RetInternalObject   - Where the internal object is returned
460433d6423SLionel Sambuc  *
461433d6423SLionel Sambuc  * RETURN:      Status
462433d6423SLionel Sambuc  *
463433d6423SLionel Sambuc  * DESCRIPTION: This function copies an external object to an internal one.
464433d6423SLionel Sambuc  *              NOTE: Pointers can be copied, we don't need to copy data.
465433d6423SLionel Sambuc  *              (The pointers have to be valid in our address space no matter
466433d6423SLionel Sambuc  *              what we do with them!)
467433d6423SLionel Sambuc  *
468433d6423SLionel Sambuc  ******************************************************************************/
469433d6423SLionel Sambuc 
470433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopyEsimpleToIsimple(ACPI_OBJECT * ExternalObject,ACPI_OPERAND_OBJECT ** RetInternalObject)471433d6423SLionel Sambuc AcpiUtCopyEsimpleToIsimple (
472433d6423SLionel Sambuc     ACPI_OBJECT             *ExternalObject,
473433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **RetInternalObject)
474433d6423SLionel Sambuc {
475433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *InternalObject;
476433d6423SLionel Sambuc 
477433d6423SLionel Sambuc 
478433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple);
479433d6423SLionel Sambuc 
480433d6423SLionel Sambuc 
481433d6423SLionel Sambuc     /*
482433d6423SLionel Sambuc      * Simple types supported are: String, Buffer, Integer
483433d6423SLionel Sambuc      */
484433d6423SLionel Sambuc     switch (ExternalObject->Type)
485433d6423SLionel Sambuc     {
486433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
487433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
488433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
489433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_REFERENCE:
490433d6423SLionel Sambuc 
491433d6423SLionel Sambuc         InternalObject = AcpiUtCreateInternalObject (
492433d6423SLionel Sambuc                             (UINT8) ExternalObject->Type);
493433d6423SLionel Sambuc         if (!InternalObject)
494433d6423SLionel Sambuc         {
495433d6423SLionel Sambuc             return_ACPI_STATUS (AE_NO_MEMORY);
496433d6423SLionel Sambuc         }
497433d6423SLionel Sambuc         break;
498433d6423SLionel Sambuc 
499433d6423SLionel Sambuc     case ACPI_TYPE_ANY: /* This is the case for a NULL object */
500433d6423SLionel Sambuc 
501433d6423SLionel Sambuc         *RetInternalObject = NULL;
502433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
503433d6423SLionel Sambuc 
504433d6423SLionel Sambuc     default:
505*29492bb7SDavid van Moolenbroek 
506433d6423SLionel Sambuc         /* All other types are not supported */
507433d6423SLionel Sambuc 
508433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
509433d6423SLionel Sambuc             "Unsupported object type, cannot convert to internal object: %s",
510433d6423SLionel Sambuc             AcpiUtGetTypeName (ExternalObject->Type)));
511433d6423SLionel Sambuc 
512433d6423SLionel Sambuc         return_ACPI_STATUS (AE_SUPPORT);
513433d6423SLionel Sambuc     }
514433d6423SLionel Sambuc 
515433d6423SLionel Sambuc 
516433d6423SLionel Sambuc     /* Must COPY string and buffer contents */
517433d6423SLionel Sambuc 
518433d6423SLionel Sambuc     switch (ExternalObject->Type)
519433d6423SLionel Sambuc     {
520433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
521433d6423SLionel Sambuc 
522433d6423SLionel Sambuc         InternalObject->String.Pointer =
523433d6423SLionel Sambuc             ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
524433d6423SLionel Sambuc                 ExternalObject->String.Length + 1);
525433d6423SLionel Sambuc 
526433d6423SLionel Sambuc         if (!InternalObject->String.Pointer)
527433d6423SLionel Sambuc         {
528433d6423SLionel Sambuc             goto ErrorExit;
529433d6423SLionel Sambuc         }
530433d6423SLionel Sambuc 
531433d6423SLionel Sambuc         ACPI_MEMCPY (InternalObject->String.Pointer,
532433d6423SLionel Sambuc                      ExternalObject->String.Pointer,
533433d6423SLionel Sambuc                      ExternalObject->String.Length);
534433d6423SLionel Sambuc 
535433d6423SLionel Sambuc         InternalObject->String.Length  = ExternalObject->String.Length;
536433d6423SLionel Sambuc         break;
537433d6423SLionel Sambuc 
538433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
539433d6423SLionel Sambuc 
540433d6423SLionel Sambuc         InternalObject->Buffer.Pointer =
541433d6423SLionel Sambuc             ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length);
542433d6423SLionel Sambuc         if (!InternalObject->Buffer.Pointer)
543433d6423SLionel Sambuc         {
544433d6423SLionel Sambuc             goto ErrorExit;
545433d6423SLionel Sambuc         }
546433d6423SLionel Sambuc 
547433d6423SLionel Sambuc         ACPI_MEMCPY (InternalObject->Buffer.Pointer,
548433d6423SLionel Sambuc                      ExternalObject->Buffer.Pointer,
549433d6423SLionel Sambuc                      ExternalObject->Buffer.Length);
550433d6423SLionel Sambuc 
551433d6423SLionel Sambuc         InternalObject->Buffer.Length  = ExternalObject->Buffer.Length;
552433d6423SLionel Sambuc 
553433d6423SLionel Sambuc         /* Mark buffer data valid */
554433d6423SLionel Sambuc 
555433d6423SLionel Sambuc         InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID;
556433d6423SLionel Sambuc         break;
557433d6423SLionel Sambuc 
558433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
559433d6423SLionel Sambuc 
560433d6423SLionel Sambuc         InternalObject->Integer.Value   = ExternalObject->Integer.Value;
561433d6423SLionel Sambuc         break;
562433d6423SLionel Sambuc 
563433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_REFERENCE:
564433d6423SLionel Sambuc 
565*29492bb7SDavid van Moolenbroek         /* An incoming reference is defined to be a namespace node */
566433d6423SLionel Sambuc 
567*29492bb7SDavid van Moolenbroek         InternalObject->Reference.Class = ACPI_REFCLASS_REFOF;
568*29492bb7SDavid van Moolenbroek         InternalObject->Reference.Object = ExternalObject->Reference.Handle;
569433d6423SLionel Sambuc         break;
570433d6423SLionel Sambuc 
571433d6423SLionel Sambuc     default:
572*29492bb7SDavid van Moolenbroek 
573433d6423SLionel Sambuc         /* Other types can't get here */
574*29492bb7SDavid van Moolenbroek 
575433d6423SLionel Sambuc         break;
576433d6423SLionel Sambuc     }
577433d6423SLionel Sambuc 
578433d6423SLionel Sambuc     *RetInternalObject = InternalObject;
579433d6423SLionel Sambuc     return_ACPI_STATUS (AE_OK);
580433d6423SLionel Sambuc 
581433d6423SLionel Sambuc 
582433d6423SLionel Sambuc ErrorExit:
583433d6423SLionel Sambuc     AcpiUtRemoveReference (InternalObject);
584433d6423SLionel Sambuc     return_ACPI_STATUS (AE_NO_MEMORY);
585433d6423SLionel Sambuc }
586433d6423SLionel Sambuc 
587433d6423SLionel Sambuc 
588433d6423SLionel Sambuc /*******************************************************************************
589433d6423SLionel Sambuc  *
590433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyEpackageToIpackage
591433d6423SLionel Sambuc  *
592433d6423SLionel Sambuc  * PARAMETERS:  ExternalObject      - The external object to be converted
593433d6423SLionel Sambuc  *              InternalObject      - Where the internal object is returned
594433d6423SLionel Sambuc  *
595433d6423SLionel Sambuc  * RETURN:      Status
596433d6423SLionel Sambuc  *
597433d6423SLionel Sambuc  * DESCRIPTION: Copy an external package object to an internal package.
598433d6423SLionel Sambuc  *              Handles nested packages.
599433d6423SLionel Sambuc  *
600433d6423SLionel Sambuc  ******************************************************************************/
601433d6423SLionel Sambuc 
602433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopyEpackageToIpackage(ACPI_OBJECT * ExternalObject,ACPI_OPERAND_OBJECT ** InternalObject)603433d6423SLionel Sambuc AcpiUtCopyEpackageToIpackage (
604433d6423SLionel Sambuc     ACPI_OBJECT             *ExternalObject,
605433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **InternalObject)
606433d6423SLionel Sambuc {
607433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
608433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *PackageObject;
609433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **PackageElements;
610433d6423SLionel Sambuc     UINT32                  i;
611433d6423SLionel Sambuc 
612433d6423SLionel Sambuc 
613433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage);
614433d6423SLionel Sambuc 
615433d6423SLionel Sambuc 
616433d6423SLionel Sambuc     /* Create the package object */
617433d6423SLionel Sambuc 
618433d6423SLionel Sambuc     PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count);
619433d6423SLionel Sambuc     if (!PackageObject)
620433d6423SLionel Sambuc     {
621433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
622433d6423SLionel Sambuc     }
623433d6423SLionel Sambuc 
624433d6423SLionel Sambuc     PackageElements = PackageObject->Package.Elements;
625433d6423SLionel Sambuc 
626433d6423SLionel Sambuc     /*
627433d6423SLionel Sambuc      * Recursive implementation. Probably ok, since nested external packages
628433d6423SLionel Sambuc      * as parameters should be very rare.
629433d6423SLionel Sambuc      */
630433d6423SLionel Sambuc     for (i = 0; i < ExternalObject->Package.Count; i++)
631433d6423SLionel Sambuc     {
632433d6423SLionel Sambuc         Status = AcpiUtCopyEobjectToIobject (
633433d6423SLionel Sambuc                     &ExternalObject->Package.Elements[i],
634433d6423SLionel Sambuc                     &PackageElements[i]);
635433d6423SLionel Sambuc         if (ACPI_FAILURE (Status))
636433d6423SLionel Sambuc         {
637433d6423SLionel Sambuc             /* Truncate package and delete it */
638433d6423SLionel Sambuc 
639433d6423SLionel Sambuc             PackageObject->Package.Count = i;
640433d6423SLionel Sambuc             PackageElements[i] = NULL;
641433d6423SLionel Sambuc             AcpiUtRemoveReference (PackageObject);
642433d6423SLionel Sambuc             return_ACPI_STATUS (Status);
643433d6423SLionel Sambuc         }
644433d6423SLionel Sambuc     }
645433d6423SLionel Sambuc 
646433d6423SLionel Sambuc     /* Mark package data valid */
647433d6423SLionel Sambuc 
648433d6423SLionel Sambuc     PackageObject->Package.Flags |= AOPOBJ_DATA_VALID;
649433d6423SLionel Sambuc 
650433d6423SLionel Sambuc     *InternalObject = PackageObject;
651433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
652433d6423SLionel Sambuc }
653433d6423SLionel Sambuc 
654433d6423SLionel Sambuc 
655433d6423SLionel Sambuc /*******************************************************************************
656433d6423SLionel Sambuc  *
657433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyEobjectToIobject
658433d6423SLionel Sambuc  *
659433d6423SLionel Sambuc  * PARAMETERS:  ExternalObject      - The external object to be converted
660433d6423SLionel Sambuc  *              InternalObject      - Where the internal object is returned
661433d6423SLionel Sambuc  *
662433d6423SLionel Sambuc  * RETURN:      Status
663433d6423SLionel Sambuc  *
664433d6423SLionel Sambuc  * DESCRIPTION: Converts an external object to an internal object.
665433d6423SLionel Sambuc  *
666433d6423SLionel Sambuc  ******************************************************************************/
667433d6423SLionel Sambuc 
668433d6423SLionel Sambuc ACPI_STATUS
AcpiUtCopyEobjectToIobject(ACPI_OBJECT * ExternalObject,ACPI_OPERAND_OBJECT ** InternalObject)669433d6423SLionel Sambuc AcpiUtCopyEobjectToIobject (
670433d6423SLionel Sambuc     ACPI_OBJECT             *ExternalObject,
671433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **InternalObject)
672433d6423SLionel Sambuc {
673433d6423SLionel Sambuc     ACPI_STATUS             Status;
674433d6423SLionel Sambuc 
675433d6423SLionel Sambuc 
676433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject);
677433d6423SLionel Sambuc 
678433d6423SLionel Sambuc 
679433d6423SLionel Sambuc     if (ExternalObject->Type == ACPI_TYPE_PACKAGE)
680433d6423SLionel Sambuc     {
681433d6423SLionel Sambuc         Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject);
682433d6423SLionel Sambuc     }
683433d6423SLionel Sambuc     else
684433d6423SLionel Sambuc     {
685433d6423SLionel Sambuc         /*
686433d6423SLionel Sambuc          * Build a simple object (no nested objects)
687433d6423SLionel Sambuc          */
688433d6423SLionel Sambuc         Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject);
689433d6423SLionel Sambuc     }
690433d6423SLionel Sambuc 
691433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
692433d6423SLionel Sambuc }
693433d6423SLionel Sambuc 
694433d6423SLionel Sambuc 
695433d6423SLionel Sambuc /*******************************************************************************
696433d6423SLionel Sambuc  *
697433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopySimpleObject
698433d6423SLionel Sambuc  *
699433d6423SLionel Sambuc  * PARAMETERS:  SourceDesc          - The internal object to be copied
700433d6423SLionel Sambuc  *              DestDesc            - New target object
701433d6423SLionel Sambuc  *
702433d6423SLionel Sambuc  * RETURN:      Status
703433d6423SLionel Sambuc  *
704433d6423SLionel Sambuc  * DESCRIPTION: Simple copy of one internal object to another. Reference count
705433d6423SLionel Sambuc  *              of the destination object is preserved.
706433d6423SLionel Sambuc  *
707433d6423SLionel Sambuc  ******************************************************************************/
708433d6423SLionel Sambuc 
709433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopySimpleObject(ACPI_OPERAND_OBJECT * SourceDesc,ACPI_OPERAND_OBJECT * DestDesc)710433d6423SLionel Sambuc AcpiUtCopySimpleObject (
711433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceDesc,
712433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *DestDesc)
713433d6423SLionel Sambuc {
714433d6423SLionel Sambuc     UINT16                  ReferenceCount;
715433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *NextObject;
716433d6423SLionel Sambuc     ACPI_STATUS             Status;
717433d6423SLionel Sambuc     ACPI_SIZE               CopySize;
718433d6423SLionel Sambuc 
719433d6423SLionel Sambuc 
720433d6423SLionel Sambuc     /* Save fields from destination that we don't want to overwrite */
721433d6423SLionel Sambuc 
722433d6423SLionel Sambuc     ReferenceCount = DestDesc->Common.ReferenceCount;
723433d6423SLionel Sambuc     NextObject = DestDesc->Common.NextObject;
724433d6423SLionel Sambuc 
725433d6423SLionel Sambuc     /*
726433d6423SLionel Sambuc      * Copy the entire source object over the destination object.
727433d6423SLionel Sambuc      * Note: Source can be either an operand object or namespace node.
728433d6423SLionel Sambuc      */
729433d6423SLionel Sambuc     CopySize = sizeof (ACPI_OPERAND_OBJECT);
730433d6423SLionel Sambuc     if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
731433d6423SLionel Sambuc     {
732433d6423SLionel Sambuc         CopySize = sizeof (ACPI_NAMESPACE_NODE);
733433d6423SLionel Sambuc     }
734433d6423SLionel Sambuc 
735433d6423SLionel Sambuc     ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc),
736433d6423SLionel Sambuc         ACPI_CAST_PTR (char, SourceDesc), CopySize);
737433d6423SLionel Sambuc 
738433d6423SLionel Sambuc     /* Restore the saved fields */
739433d6423SLionel Sambuc 
740433d6423SLionel Sambuc     DestDesc->Common.ReferenceCount = ReferenceCount;
741433d6423SLionel Sambuc     DestDesc->Common.NextObject = NextObject;
742433d6423SLionel Sambuc 
743433d6423SLionel Sambuc     /* New object is not static, regardless of source */
744433d6423SLionel Sambuc 
745433d6423SLionel Sambuc     DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
746433d6423SLionel Sambuc 
747433d6423SLionel Sambuc     /* Handle the objects with extra data */
748433d6423SLionel Sambuc 
749433d6423SLionel Sambuc     switch (DestDesc->Common.Type)
750433d6423SLionel Sambuc     {
751433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
752433d6423SLionel Sambuc         /*
753433d6423SLionel Sambuc          * Allocate and copy the actual buffer if and only if:
754433d6423SLionel Sambuc          * 1) There is a valid buffer pointer
755433d6423SLionel Sambuc          * 2) The buffer has a length > 0
756433d6423SLionel Sambuc          */
757433d6423SLionel Sambuc         if ((SourceDesc->Buffer.Pointer) &&
758433d6423SLionel Sambuc             (SourceDesc->Buffer.Length))
759433d6423SLionel Sambuc         {
760433d6423SLionel Sambuc             DestDesc->Buffer.Pointer =
761433d6423SLionel Sambuc                 ACPI_ALLOCATE (SourceDesc->Buffer.Length);
762433d6423SLionel Sambuc             if (!DestDesc->Buffer.Pointer)
763433d6423SLionel Sambuc             {
764433d6423SLionel Sambuc                 return (AE_NO_MEMORY);
765433d6423SLionel Sambuc             }
766433d6423SLionel Sambuc 
767433d6423SLionel Sambuc             /* Copy the actual buffer data */
768433d6423SLionel Sambuc 
769433d6423SLionel Sambuc             ACPI_MEMCPY (DestDesc->Buffer.Pointer,
770433d6423SLionel Sambuc                 SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
771433d6423SLionel Sambuc         }
772433d6423SLionel Sambuc         break;
773433d6423SLionel Sambuc 
774433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
775433d6423SLionel Sambuc         /*
776433d6423SLionel Sambuc          * Allocate and copy the actual string if and only if:
777433d6423SLionel Sambuc          * 1) There is a valid string pointer
778433d6423SLionel Sambuc          * (Pointer to a NULL string is allowed)
779433d6423SLionel Sambuc          */
780433d6423SLionel Sambuc         if (SourceDesc->String.Pointer)
781433d6423SLionel Sambuc         {
782433d6423SLionel Sambuc             DestDesc->String.Pointer =
783433d6423SLionel Sambuc                 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
784433d6423SLionel Sambuc             if (!DestDesc->String.Pointer)
785433d6423SLionel Sambuc             {
786433d6423SLionel Sambuc                 return (AE_NO_MEMORY);
787433d6423SLionel Sambuc             }
788433d6423SLionel Sambuc 
789433d6423SLionel Sambuc             /* Copy the actual string data */
790433d6423SLionel Sambuc 
791433d6423SLionel Sambuc             ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer,
792433d6423SLionel Sambuc                 (ACPI_SIZE) SourceDesc->String.Length + 1);
793433d6423SLionel Sambuc         }
794433d6423SLionel Sambuc         break;
795433d6423SLionel Sambuc 
796433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_REFERENCE:
797433d6423SLionel Sambuc         /*
798433d6423SLionel Sambuc          * We copied the reference object, so we now must add a reference
799433d6423SLionel Sambuc          * to the object pointed to by the reference
800433d6423SLionel Sambuc          *
801433d6423SLionel Sambuc          * DDBHandle reference (from Load/LoadTable) is a special reference,
802433d6423SLionel Sambuc          * it does not have a Reference.Object, so does not need to
803433d6423SLionel Sambuc          * increase the reference count
804433d6423SLionel Sambuc          */
805433d6423SLionel Sambuc         if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
806433d6423SLionel Sambuc         {
807433d6423SLionel Sambuc             break;
808433d6423SLionel Sambuc         }
809433d6423SLionel Sambuc 
810433d6423SLionel Sambuc         AcpiUtAddReference (SourceDesc->Reference.Object);
811433d6423SLionel Sambuc         break;
812433d6423SLionel Sambuc 
813433d6423SLionel Sambuc     case ACPI_TYPE_REGION:
814433d6423SLionel Sambuc         /*
815433d6423SLionel Sambuc          * We copied the Region Handler, so we now must add a reference
816433d6423SLionel Sambuc          */
817433d6423SLionel Sambuc         if (DestDesc->Region.Handler)
818433d6423SLionel Sambuc         {
819433d6423SLionel Sambuc             AcpiUtAddReference (DestDesc->Region.Handler);
820433d6423SLionel Sambuc         }
821433d6423SLionel Sambuc         break;
822433d6423SLionel Sambuc 
823433d6423SLionel Sambuc     /*
824433d6423SLionel Sambuc      * For Mutex and Event objects, we cannot simply copy the underlying
825433d6423SLionel Sambuc      * OS object. We must create a new one.
826433d6423SLionel Sambuc      */
827433d6423SLionel Sambuc     case ACPI_TYPE_MUTEX:
828433d6423SLionel Sambuc 
829433d6423SLionel Sambuc         Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
830433d6423SLionel Sambuc         if (ACPI_FAILURE (Status))
831433d6423SLionel Sambuc         {
832433d6423SLionel Sambuc             return (Status);
833433d6423SLionel Sambuc         }
834433d6423SLionel Sambuc         break;
835433d6423SLionel Sambuc 
836433d6423SLionel Sambuc     case ACPI_TYPE_EVENT:
837433d6423SLionel Sambuc 
838433d6423SLionel Sambuc         Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
839433d6423SLionel Sambuc                     &DestDesc->Event.OsSemaphore);
840433d6423SLionel Sambuc         if (ACPI_FAILURE (Status))
841433d6423SLionel Sambuc         {
842433d6423SLionel Sambuc             return (Status);
843433d6423SLionel Sambuc         }
844433d6423SLionel Sambuc         break;
845433d6423SLionel Sambuc 
846433d6423SLionel Sambuc     default:
847*29492bb7SDavid van Moolenbroek 
848433d6423SLionel Sambuc         /* Nothing to do for other simple objects */
849*29492bb7SDavid van Moolenbroek 
850433d6423SLionel Sambuc         break;
851433d6423SLionel Sambuc     }
852433d6423SLionel Sambuc 
853433d6423SLionel Sambuc     return (AE_OK);
854433d6423SLionel Sambuc }
855433d6423SLionel Sambuc 
856433d6423SLionel Sambuc 
857433d6423SLionel Sambuc /*******************************************************************************
858433d6423SLionel Sambuc  *
859433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyIelementToIelement
860433d6423SLionel Sambuc  *
861433d6423SLionel Sambuc  * PARAMETERS:  ACPI_PKG_CALLBACK
862433d6423SLionel Sambuc  *
863433d6423SLionel Sambuc  * RETURN:      Status
864433d6423SLionel Sambuc  *
865433d6423SLionel Sambuc  * DESCRIPTION: Copy one package element to another package element
866433d6423SLionel Sambuc  *
867433d6423SLionel Sambuc  ******************************************************************************/
868433d6423SLionel Sambuc 
869433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopyIelementToIelement(UINT8 ObjectType,ACPI_OPERAND_OBJECT * SourceObject,ACPI_GENERIC_STATE * State,void * Context)870433d6423SLionel Sambuc AcpiUtCopyIelementToIelement (
871433d6423SLionel Sambuc     UINT8                   ObjectType,
872433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceObject,
873433d6423SLionel Sambuc     ACPI_GENERIC_STATE      *State,
874433d6423SLionel Sambuc     void                    *Context)
875433d6423SLionel Sambuc {
876433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
877433d6423SLionel Sambuc     UINT32                  ThisIndex;
878433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **ThisTargetPtr;
879433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *TargetObject;
880433d6423SLionel Sambuc 
881433d6423SLionel Sambuc 
882433d6423SLionel Sambuc     ACPI_FUNCTION_ENTRY ();
883433d6423SLionel Sambuc 
884433d6423SLionel Sambuc 
885433d6423SLionel Sambuc     ThisIndex     = State->Pkg.Index;
886433d6423SLionel Sambuc     ThisTargetPtr = (ACPI_OPERAND_OBJECT **)
887433d6423SLionel Sambuc                         &State->Pkg.DestObject->Package.Elements[ThisIndex];
888433d6423SLionel Sambuc 
889433d6423SLionel Sambuc     switch (ObjectType)
890433d6423SLionel Sambuc     {
891433d6423SLionel Sambuc     case ACPI_COPY_TYPE_SIMPLE:
892433d6423SLionel Sambuc 
893433d6423SLionel Sambuc         /* A null source object indicates a (legal) null package element */
894433d6423SLionel Sambuc 
895433d6423SLionel Sambuc         if (SourceObject)
896433d6423SLionel Sambuc         {
897433d6423SLionel Sambuc             /*
898433d6423SLionel Sambuc              * This is a simple object, just copy it
899433d6423SLionel Sambuc              */
900433d6423SLionel Sambuc             TargetObject = AcpiUtCreateInternalObject (
901433d6423SLionel Sambuc                                 SourceObject->Common.Type);
902433d6423SLionel Sambuc             if (!TargetObject)
903433d6423SLionel Sambuc             {
904433d6423SLionel Sambuc                 return (AE_NO_MEMORY);
905433d6423SLionel Sambuc             }
906433d6423SLionel Sambuc 
907433d6423SLionel Sambuc             Status = AcpiUtCopySimpleObject (SourceObject, TargetObject);
908433d6423SLionel Sambuc             if (ACPI_FAILURE (Status))
909433d6423SLionel Sambuc             {
910433d6423SLionel Sambuc                 goto ErrorExit;
911433d6423SLionel Sambuc             }
912433d6423SLionel Sambuc 
913433d6423SLionel Sambuc             *ThisTargetPtr = TargetObject;
914433d6423SLionel Sambuc         }
915433d6423SLionel Sambuc         else
916433d6423SLionel Sambuc         {
917433d6423SLionel Sambuc             /* Pass through a null element */
918433d6423SLionel Sambuc 
919433d6423SLionel Sambuc             *ThisTargetPtr = NULL;
920433d6423SLionel Sambuc         }
921433d6423SLionel Sambuc         break;
922433d6423SLionel Sambuc 
923433d6423SLionel Sambuc     case ACPI_COPY_TYPE_PACKAGE:
924433d6423SLionel Sambuc         /*
925433d6423SLionel Sambuc          * This object is a package - go down another nesting level
926433d6423SLionel Sambuc          * Create and build the package object
927433d6423SLionel Sambuc          */
928433d6423SLionel Sambuc         TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count);
929433d6423SLionel Sambuc         if (!TargetObject)
930433d6423SLionel Sambuc         {
931433d6423SLionel Sambuc             return (AE_NO_MEMORY);
932433d6423SLionel Sambuc         }
933433d6423SLionel Sambuc 
934433d6423SLionel Sambuc         TargetObject->Common.Flags = SourceObject->Common.Flags;
935433d6423SLionel Sambuc 
936433d6423SLionel Sambuc         /* Pass the new package object back to the package walk routine */
937433d6423SLionel Sambuc 
938433d6423SLionel Sambuc         State->Pkg.ThisTargetObj = TargetObject;
939433d6423SLionel Sambuc 
940433d6423SLionel Sambuc         /* Store the object pointer in the parent package object */
941433d6423SLionel Sambuc 
942433d6423SLionel Sambuc         *ThisTargetPtr = TargetObject;
943433d6423SLionel Sambuc         break;
944433d6423SLionel Sambuc 
945433d6423SLionel Sambuc     default:
946*29492bb7SDavid van Moolenbroek 
947433d6423SLionel Sambuc         return (AE_BAD_PARAMETER);
948433d6423SLionel Sambuc     }
949433d6423SLionel Sambuc 
950433d6423SLionel Sambuc     return (Status);
951433d6423SLionel Sambuc 
952433d6423SLionel Sambuc ErrorExit:
953433d6423SLionel Sambuc     AcpiUtRemoveReference (TargetObject);
954433d6423SLionel Sambuc     return (Status);
955433d6423SLionel Sambuc }
956433d6423SLionel Sambuc 
957433d6423SLionel Sambuc 
958433d6423SLionel Sambuc /*******************************************************************************
959433d6423SLionel Sambuc  *
960433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyIpackageToIpackage
961433d6423SLionel Sambuc  *
962433d6423SLionel Sambuc  * PARAMETERS:  SourceObj       - Pointer to the source package object
963433d6423SLionel Sambuc  *              DestObj         - Where the internal object is returned
964433d6423SLionel Sambuc  *              WalkState       - Current Walk state descriptor
965433d6423SLionel Sambuc  *
966433d6423SLionel Sambuc  * RETURN:      Status
967433d6423SLionel Sambuc  *
968433d6423SLionel Sambuc  * DESCRIPTION: This function is called to copy an internal package object
969433d6423SLionel Sambuc  *              into another internal package object.
970433d6423SLionel Sambuc  *
971433d6423SLionel Sambuc  ******************************************************************************/
972433d6423SLionel Sambuc 
973433d6423SLionel Sambuc static ACPI_STATUS
AcpiUtCopyIpackageToIpackage(ACPI_OPERAND_OBJECT * SourceObj,ACPI_OPERAND_OBJECT * DestObj,ACPI_WALK_STATE * WalkState)974433d6423SLionel Sambuc AcpiUtCopyIpackageToIpackage (
975433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceObj,
976433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *DestObj,
977433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState)
978433d6423SLionel Sambuc {
979433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
980433d6423SLionel Sambuc 
981433d6423SLionel Sambuc 
982433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage);
983433d6423SLionel Sambuc 
984433d6423SLionel Sambuc 
985433d6423SLionel Sambuc     DestObj->Common.Type    = SourceObj->Common.Type;
986433d6423SLionel Sambuc     DestObj->Common.Flags   = SourceObj->Common.Flags;
987433d6423SLionel Sambuc     DestObj->Package.Count  = SourceObj->Package.Count;
988433d6423SLionel Sambuc 
989433d6423SLionel Sambuc     /*
990433d6423SLionel Sambuc      * Create the object array and walk the source package tree
991433d6423SLionel Sambuc      */
992433d6423SLionel Sambuc     DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED (
993433d6423SLionel Sambuc                                     ((ACPI_SIZE) SourceObj->Package.Count + 1) *
994433d6423SLionel Sambuc                                     sizeof (void *));
995433d6423SLionel Sambuc     if (!DestObj->Package.Elements)
996433d6423SLionel Sambuc     {
997433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "Package allocation failure"));
998433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
999433d6423SLionel Sambuc     }
1000433d6423SLionel Sambuc 
1001433d6423SLionel Sambuc     /*
1002433d6423SLionel Sambuc      * Copy the package element-by-element by walking the package "tree".
1003433d6423SLionel Sambuc      * This handles nested packages of arbitrary depth.
1004433d6423SLionel Sambuc      */
1005433d6423SLionel Sambuc     Status = AcpiUtWalkPackageTree (SourceObj, DestObj,
1006433d6423SLionel Sambuc                 AcpiUtCopyIelementToIelement, WalkState);
1007433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1008433d6423SLionel Sambuc     {
1009433d6423SLionel Sambuc         /* On failure, delete the destination package object */
1010433d6423SLionel Sambuc 
1011433d6423SLionel Sambuc         AcpiUtRemoveReference (DestObj);
1012433d6423SLionel Sambuc     }
1013433d6423SLionel Sambuc 
1014433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
1015433d6423SLionel Sambuc }
1016433d6423SLionel Sambuc 
1017433d6423SLionel Sambuc 
1018433d6423SLionel Sambuc /*******************************************************************************
1019433d6423SLionel Sambuc  *
1020433d6423SLionel Sambuc  * FUNCTION:    AcpiUtCopyIobjectToIobject
1021433d6423SLionel Sambuc  *
1022433d6423SLionel Sambuc  * PARAMETERS:  SourceDesc          - The internal object to be copied
1023433d6423SLionel Sambuc  *              DestDesc            - Where the copied object is returned
1024433d6423SLionel Sambuc  *              WalkState           - Current walk state
1025433d6423SLionel Sambuc  *
1026433d6423SLionel Sambuc  * RETURN:      Status
1027433d6423SLionel Sambuc  *
1028433d6423SLionel Sambuc  * DESCRIPTION: Copy an internal object to a new internal object
1029433d6423SLionel Sambuc  *
1030433d6423SLionel Sambuc  ******************************************************************************/
1031433d6423SLionel Sambuc 
1032433d6423SLionel Sambuc ACPI_STATUS
AcpiUtCopyIobjectToIobject(ACPI_OPERAND_OBJECT * SourceDesc,ACPI_OPERAND_OBJECT ** DestDesc,ACPI_WALK_STATE * WalkState)1033433d6423SLionel Sambuc AcpiUtCopyIobjectToIobject (
1034433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceDesc,
1035433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **DestDesc,
1036433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState)
1037433d6423SLionel Sambuc {
1038433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
1039433d6423SLionel Sambuc 
1040433d6423SLionel Sambuc 
1041433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject);
1042433d6423SLionel Sambuc 
1043433d6423SLionel Sambuc 
1044433d6423SLionel Sambuc     /* Create the top level object */
1045433d6423SLionel Sambuc 
1046433d6423SLionel Sambuc     *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type);
1047433d6423SLionel Sambuc     if (!*DestDesc)
1048433d6423SLionel Sambuc     {
1049433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
1050433d6423SLionel Sambuc     }
1051433d6423SLionel Sambuc 
1052433d6423SLionel Sambuc     /* Copy the object and possible subobjects */
1053433d6423SLionel Sambuc 
1054433d6423SLionel Sambuc     if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE)
1055433d6423SLionel Sambuc     {
1056433d6423SLionel Sambuc         Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc,
1057433d6423SLionel Sambuc                         WalkState);
1058433d6423SLionel Sambuc     }
1059433d6423SLionel Sambuc     else
1060433d6423SLionel Sambuc     {
1061433d6423SLionel Sambuc         Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc);
1062433d6423SLionel Sambuc     }
1063433d6423SLionel Sambuc 
1064*29492bb7SDavid van Moolenbroek     /* Delete the allocated object if copy failed */
1065*29492bb7SDavid van Moolenbroek 
1066*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
1067*29492bb7SDavid van Moolenbroek     {
1068*29492bb7SDavid van Moolenbroek         AcpiUtRemoveReference(*DestDesc);
1069433d6423SLionel Sambuc     }
1070433d6423SLionel Sambuc 
1071*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
1072*29492bb7SDavid van Moolenbroek }
1073