xref: /freebsd/sys/contrib/dev/acpica/components/executer/exconcat.c (revision 493deb390baef09f40125589cbdb714cb274ab04)
1f8146b88SJung-uk Kim /******************************************************************************
2f8146b88SJung-uk Kim  *
3f8146b88SJung-uk Kim  * Module Name: exconcat - Concatenate-type AML operators
4f8146b88SJung-uk Kim  *
5f8146b88SJung-uk Kim  *****************************************************************************/
6f8146b88SJung-uk Kim 
7f8146b88SJung-uk Kim /*
8f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, Intel Corp.
9f8146b88SJung-uk Kim  * All rights reserved.
10f8146b88SJung-uk Kim  *
11f8146b88SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12f8146b88SJung-uk Kim  * modification, are permitted provided that the following conditions
13f8146b88SJung-uk Kim  * are met:
14f8146b88SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15f8146b88SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16f8146b88SJung-uk Kim  *    without modification.
17f8146b88SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18f8146b88SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19f8146b88SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20f8146b88SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21f8146b88SJung-uk Kim  *    binary redistribution.
22f8146b88SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23f8146b88SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24f8146b88SJung-uk Kim  *    from this software without specific prior written permission.
25f8146b88SJung-uk Kim  *
26f8146b88SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27f8146b88SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28f8146b88SJung-uk Kim  * Software Foundation.
29f8146b88SJung-uk Kim  *
30f8146b88SJung-uk Kim  * NO WARRANTY
31f8146b88SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32f8146b88SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33f8146b88SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34f8146b88SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35f8146b88SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36f8146b88SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37f8146b88SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38f8146b88SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39f8146b88SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40f8146b88SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41f8146b88SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42f8146b88SJung-uk Kim  */
43f8146b88SJung-uk Kim 
44f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
45f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
46f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/acinterp.h>
47f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/amlresrc.h>
48f8146b88SJung-uk Kim 
49f8146b88SJung-uk Kim 
50f8146b88SJung-uk Kim #define _COMPONENT          ACPI_EXECUTER
51f8146b88SJung-uk Kim         ACPI_MODULE_NAME    ("exconcat")
52f8146b88SJung-uk Kim 
53f8146b88SJung-uk Kim /* Local Prototypes */
54f8146b88SJung-uk Kim 
55f8146b88SJung-uk Kim static ACPI_STATUS
56f8146b88SJung-uk Kim AcpiExConvertToObjectTypeString (
57f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc,
58f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ResultDesc);
59f8146b88SJung-uk Kim 
60f8146b88SJung-uk Kim 
61f8146b88SJung-uk Kim /*******************************************************************************
62f8146b88SJung-uk Kim  *
63f8146b88SJung-uk Kim  * FUNCTION:    AcpiExDoConcatenate
64f8146b88SJung-uk Kim  *
65f8146b88SJung-uk Kim  * PARAMETERS:  Operand0            - First source object
66f8146b88SJung-uk Kim  *              Operand1            - Second source object
67f8146b88SJung-uk Kim  *              ActualReturnDesc    - Where to place the return object
68f8146b88SJung-uk Kim  *              WalkState           - Current walk state
69f8146b88SJung-uk Kim  *
70f8146b88SJung-uk Kim  * RETURN:      Status
71f8146b88SJung-uk Kim  *
72f8146b88SJung-uk Kim  * DESCRIPTION: Concatenate two objects with the ACPI-defined conversion
73f8146b88SJung-uk Kim  *              rules as necessary.
74f8146b88SJung-uk Kim  * NOTE:
75f8146b88SJung-uk Kim  * Per the ACPI spec (up to 6.1), Concatenate only supports Integer,
76f8146b88SJung-uk Kim  * String, and Buffer objects. However, we support all objects here
77f8146b88SJung-uk Kim  * as an extension. This improves the usefulness of both Concatenate
78f8146b88SJung-uk Kim  * and the Printf/Fprintf macros. The extension returns a string
79f8146b88SJung-uk Kim  * describing the object type for the other objects.
80f8146b88SJung-uk Kim  * 02/2016.
81f8146b88SJung-uk Kim  *
82f8146b88SJung-uk Kim  ******************************************************************************/
83f8146b88SJung-uk Kim 
84f8146b88SJung-uk Kim ACPI_STATUS
85f8146b88SJung-uk Kim AcpiExDoConcatenate (
86f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand0,
87f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand1,
88f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
89f8146b88SJung-uk Kim     ACPI_WALK_STATE         *WalkState)
90f8146b88SJung-uk Kim {
91f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *LocalOperand0 = Operand0;
92f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
93f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *TempOperand1 = NULL;
94f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
95f8146b88SJung-uk Kim     char                    *Buffer;
96f8146b88SJung-uk Kim     ACPI_OBJECT_TYPE        Operand0Type;
97f8146b88SJung-uk Kim     ACPI_OBJECT_TYPE        Operand1Type;
98f8146b88SJung-uk Kim     ACPI_STATUS             Status;
99f8146b88SJung-uk Kim 
100f8146b88SJung-uk Kim 
101f8146b88SJung-uk Kim     ACPI_FUNCTION_TRACE (ExDoConcatenate);
102f8146b88SJung-uk Kim 
103f8146b88SJung-uk Kim 
104f8146b88SJung-uk Kim     /* Operand 0 preprocessing */
105f8146b88SJung-uk Kim 
106f8146b88SJung-uk Kim     switch (Operand0->Common.Type)
107f8146b88SJung-uk Kim     {
108f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
109f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
110f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
111f8146b88SJung-uk Kim 
112f8146b88SJung-uk Kim         Operand0Type = Operand0->Common.Type;
113f8146b88SJung-uk Kim         break;
114f8146b88SJung-uk Kim 
115f8146b88SJung-uk Kim     default:
116f8146b88SJung-uk Kim 
117f8146b88SJung-uk Kim         /* For all other types, get the "object type" string */
118f8146b88SJung-uk Kim 
119f8146b88SJung-uk Kim         Status = AcpiExConvertToObjectTypeString (
120f8146b88SJung-uk Kim             Operand0, &LocalOperand0);
121f8146b88SJung-uk Kim         if (ACPI_FAILURE (Status))
122f8146b88SJung-uk Kim         {
123f8146b88SJung-uk Kim             goto Cleanup;
124f8146b88SJung-uk Kim         }
125f8146b88SJung-uk Kim 
126f8146b88SJung-uk Kim         Operand0Type = ACPI_TYPE_STRING;
127f8146b88SJung-uk Kim         break;
128f8146b88SJung-uk Kim     }
129f8146b88SJung-uk Kim 
130f8146b88SJung-uk Kim     /* Operand 1 preprocessing */
131f8146b88SJung-uk Kim 
132f8146b88SJung-uk Kim     switch (Operand1->Common.Type)
133f8146b88SJung-uk Kim     {
134f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
135f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
136f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
137f8146b88SJung-uk Kim 
138f8146b88SJung-uk Kim         Operand1Type = Operand1->Common.Type;
139f8146b88SJung-uk Kim         break;
140f8146b88SJung-uk Kim 
141f8146b88SJung-uk Kim     default:
142f8146b88SJung-uk Kim 
143f8146b88SJung-uk Kim         /* For all other types, get the "object type" string */
144f8146b88SJung-uk Kim 
145f8146b88SJung-uk Kim         Status = AcpiExConvertToObjectTypeString (
146f8146b88SJung-uk Kim             Operand1, &LocalOperand1);
147f8146b88SJung-uk Kim         if (ACPI_FAILURE (Status))
148f8146b88SJung-uk Kim         {
149f8146b88SJung-uk Kim             goto Cleanup;
150f8146b88SJung-uk Kim         }
151f8146b88SJung-uk Kim 
152f8146b88SJung-uk Kim         Operand1Type = ACPI_TYPE_STRING;
153f8146b88SJung-uk Kim         break;
154f8146b88SJung-uk Kim     }
155f8146b88SJung-uk Kim 
156f8146b88SJung-uk Kim     /*
157f8146b88SJung-uk Kim      * Convert the second operand if necessary. The first operand (0)
158f8146b88SJung-uk Kim      * determines the type of the second operand (1) (See the Data Types
159f8146b88SJung-uk Kim      * section of the ACPI specification). Both object types are
160f8146b88SJung-uk Kim      * guaranteed to be either Integer/String/Buffer by the operand
161f8146b88SJung-uk Kim      * resolution mechanism.
162f8146b88SJung-uk Kim      */
163f8146b88SJung-uk Kim     switch (Operand0Type)
164f8146b88SJung-uk Kim     {
165f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
166f8146b88SJung-uk Kim 
167*493deb39SJung-uk Kim         Status = AcpiExConvertToInteger (LocalOperand1, &TempOperand1,
168*493deb39SJung-uk Kim             ACPI_STRTOUL_BASE16);
169f8146b88SJung-uk Kim         break;
170f8146b88SJung-uk Kim 
171f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
172f8146b88SJung-uk Kim 
173f8146b88SJung-uk Kim         Status = AcpiExConvertToBuffer (LocalOperand1, &TempOperand1);
174f8146b88SJung-uk Kim         break;
175f8146b88SJung-uk Kim 
176f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
177f8146b88SJung-uk Kim 
178f8146b88SJung-uk Kim         switch (Operand1Type)
179f8146b88SJung-uk Kim         {
180f8146b88SJung-uk Kim         case ACPI_TYPE_INTEGER:
181f8146b88SJung-uk Kim         case ACPI_TYPE_STRING:
182f8146b88SJung-uk Kim         case ACPI_TYPE_BUFFER:
183f8146b88SJung-uk Kim 
184f8146b88SJung-uk Kim             /* Other types have already been converted to string */
185f8146b88SJung-uk Kim 
186f8146b88SJung-uk Kim             Status = AcpiExConvertToString (
187f8146b88SJung-uk Kim                 LocalOperand1, &TempOperand1, ACPI_IMPLICIT_CONVERT_HEX);
188f8146b88SJung-uk Kim             break;
189f8146b88SJung-uk Kim 
190f8146b88SJung-uk Kim         default:
191f8146b88SJung-uk Kim 
192f8146b88SJung-uk Kim             Status = AE_OK;
193f8146b88SJung-uk Kim             break;
194f8146b88SJung-uk Kim         }
195f8146b88SJung-uk Kim         break;
196f8146b88SJung-uk Kim 
197f8146b88SJung-uk Kim     default:
198f8146b88SJung-uk Kim 
199f8146b88SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
200f8146b88SJung-uk Kim             Operand0->Common.Type));
201f8146b88SJung-uk Kim         Status = AE_AML_INTERNAL;
202f8146b88SJung-uk Kim     }
203f8146b88SJung-uk Kim 
204f8146b88SJung-uk Kim     if (ACPI_FAILURE (Status))
205f8146b88SJung-uk Kim     {
206f8146b88SJung-uk Kim         goto Cleanup;
207f8146b88SJung-uk Kim     }
208f8146b88SJung-uk Kim 
209f8146b88SJung-uk Kim     /* Take care with any newly created operand objects */
210f8146b88SJung-uk Kim 
211f8146b88SJung-uk Kim     if ((LocalOperand1 != Operand1) &&
212f8146b88SJung-uk Kim         (LocalOperand1 != TempOperand1))
213f8146b88SJung-uk Kim     {
214f8146b88SJung-uk Kim         AcpiUtRemoveReference (LocalOperand1);
215f8146b88SJung-uk Kim     }
216f8146b88SJung-uk Kim 
217f8146b88SJung-uk Kim     LocalOperand1 = TempOperand1;
218f8146b88SJung-uk Kim 
219f8146b88SJung-uk Kim     /*
220f8146b88SJung-uk Kim      * Both operands are now known to be the same object type
221f8146b88SJung-uk Kim      * (Both are Integer, String, or Buffer), and we can now perform
222f8146b88SJung-uk Kim      * the concatenation.
223f8146b88SJung-uk Kim      *
224f8146b88SJung-uk Kim      * There are three cases to handle, as per the ACPI spec:
225f8146b88SJung-uk Kim      *
226f8146b88SJung-uk Kim      * 1) Two Integers concatenated to produce a new Buffer
227f8146b88SJung-uk Kim      * 2) Two Strings concatenated to produce a new String
228f8146b88SJung-uk Kim      * 3) Two Buffers concatenated to produce a new Buffer
229f8146b88SJung-uk Kim      */
230f8146b88SJung-uk Kim     switch (Operand0Type)
231f8146b88SJung-uk Kim     {
232f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
233f8146b88SJung-uk Kim 
234f8146b88SJung-uk Kim         /* Result of two Integers is a Buffer */
235f8146b88SJung-uk Kim         /* Need enough buffer space for two integers */
236f8146b88SJung-uk Kim 
237f8146b88SJung-uk Kim         ReturnDesc = AcpiUtCreateBufferObject (
238f8146b88SJung-uk Kim             (ACPI_SIZE) ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
239f8146b88SJung-uk Kim         if (!ReturnDesc)
240f8146b88SJung-uk Kim         {
241f8146b88SJung-uk Kim             Status = AE_NO_MEMORY;
242f8146b88SJung-uk Kim             goto Cleanup;
243f8146b88SJung-uk Kim         }
244f8146b88SJung-uk Kim 
245f8146b88SJung-uk Kim         Buffer = (char *) ReturnDesc->Buffer.Pointer;
246f8146b88SJung-uk Kim 
247f8146b88SJung-uk Kim         /* Copy the first integer, LSB first */
248f8146b88SJung-uk Kim 
249f8146b88SJung-uk Kim         memcpy (Buffer, &Operand0->Integer.Value,
250f8146b88SJung-uk Kim             AcpiGbl_IntegerByteWidth);
251f8146b88SJung-uk Kim 
252f8146b88SJung-uk Kim         /* Copy the second integer (LSB first) after the first */
253f8146b88SJung-uk Kim 
254f8146b88SJung-uk Kim         memcpy (Buffer + AcpiGbl_IntegerByteWidth,
255f8146b88SJung-uk Kim             &LocalOperand1->Integer.Value, AcpiGbl_IntegerByteWidth);
256f8146b88SJung-uk Kim         break;
257f8146b88SJung-uk Kim 
258f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
259f8146b88SJung-uk Kim 
260f8146b88SJung-uk Kim         /* Result of two Strings is a String */
261f8146b88SJung-uk Kim 
262f8146b88SJung-uk Kim         ReturnDesc = AcpiUtCreateStringObject (
263f8146b88SJung-uk Kim             ((ACPI_SIZE) LocalOperand0->String.Length +
264f8146b88SJung-uk Kim             LocalOperand1->String.Length));
265f8146b88SJung-uk Kim         if (!ReturnDesc)
266f8146b88SJung-uk Kim         {
267f8146b88SJung-uk Kim             Status = AE_NO_MEMORY;
268f8146b88SJung-uk Kim             goto Cleanup;
269f8146b88SJung-uk Kim         }
270f8146b88SJung-uk Kim 
271f8146b88SJung-uk Kim         Buffer = ReturnDesc->String.Pointer;
272f8146b88SJung-uk Kim 
273f8146b88SJung-uk Kim         /* Concatenate the strings */
274f8146b88SJung-uk Kim 
275f8146b88SJung-uk Kim         strcpy (Buffer, LocalOperand0->String.Pointer);
276f8146b88SJung-uk Kim         strcat (Buffer, LocalOperand1->String.Pointer);
277f8146b88SJung-uk Kim         break;
278f8146b88SJung-uk Kim 
279f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
280f8146b88SJung-uk Kim 
281f8146b88SJung-uk Kim         /* Result of two Buffers is a Buffer */
282f8146b88SJung-uk Kim 
283f8146b88SJung-uk Kim         ReturnDesc = AcpiUtCreateBufferObject (
284f8146b88SJung-uk Kim             ((ACPI_SIZE) Operand0->Buffer.Length +
285f8146b88SJung-uk Kim             LocalOperand1->Buffer.Length));
286f8146b88SJung-uk Kim         if (!ReturnDesc)
287f8146b88SJung-uk Kim         {
288f8146b88SJung-uk Kim             Status = AE_NO_MEMORY;
289f8146b88SJung-uk Kim             goto Cleanup;
290f8146b88SJung-uk Kim         }
291f8146b88SJung-uk Kim 
292f8146b88SJung-uk Kim         Buffer = (char *) ReturnDesc->Buffer.Pointer;
293f8146b88SJung-uk Kim 
294f8146b88SJung-uk Kim         /* Concatenate the buffers */
295f8146b88SJung-uk Kim 
296f8146b88SJung-uk Kim         memcpy (Buffer, Operand0->Buffer.Pointer,
297f8146b88SJung-uk Kim             Operand0->Buffer.Length);
298f8146b88SJung-uk Kim         memcpy (Buffer + Operand0->Buffer.Length,
299f8146b88SJung-uk Kim             LocalOperand1->Buffer.Pointer,
300f8146b88SJung-uk Kim             LocalOperand1->Buffer.Length);
301f8146b88SJung-uk Kim         break;
302f8146b88SJung-uk Kim 
303f8146b88SJung-uk Kim     default:
304f8146b88SJung-uk Kim 
305f8146b88SJung-uk Kim         /* Invalid object type, should not happen here */
306f8146b88SJung-uk Kim 
307f8146b88SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
308f8146b88SJung-uk Kim             Operand0->Common.Type));
309f8146b88SJung-uk Kim         Status = AE_AML_INTERNAL;
310f8146b88SJung-uk Kim         goto Cleanup;
311f8146b88SJung-uk Kim     }
312f8146b88SJung-uk Kim 
313f8146b88SJung-uk Kim     *ActualReturnDesc = ReturnDesc;
314f8146b88SJung-uk Kim 
315f8146b88SJung-uk Kim Cleanup:
316f8146b88SJung-uk Kim     if (LocalOperand0 != Operand0)
317f8146b88SJung-uk Kim     {
318f8146b88SJung-uk Kim         AcpiUtRemoveReference (LocalOperand0);
319f8146b88SJung-uk Kim     }
320f8146b88SJung-uk Kim 
321f8146b88SJung-uk Kim     if (LocalOperand1 != Operand1)
322f8146b88SJung-uk Kim     {
323f8146b88SJung-uk Kim         AcpiUtRemoveReference (LocalOperand1);
324f8146b88SJung-uk Kim     }
325f8146b88SJung-uk Kim 
326f8146b88SJung-uk Kim     return_ACPI_STATUS (Status);
327f8146b88SJung-uk Kim }
328f8146b88SJung-uk Kim 
329f8146b88SJung-uk Kim 
330f8146b88SJung-uk Kim /*******************************************************************************
331f8146b88SJung-uk Kim  *
332f8146b88SJung-uk Kim  * FUNCTION:    AcpiExConvertToObjectTypeString
333f8146b88SJung-uk Kim  *
334f8146b88SJung-uk Kim  * PARAMETERS:  ObjDesc             - Object to be converted
335f8146b88SJung-uk Kim  *              ReturnDesc          - Where to place the return object
336f8146b88SJung-uk Kim  *
337f8146b88SJung-uk Kim  * RETURN:      Status
338f8146b88SJung-uk Kim  *
339f8146b88SJung-uk Kim  * DESCRIPTION: Convert an object of arbitrary type to a string object that
340f8146b88SJung-uk Kim  *              contains the namestring for the object. Used for the
341f8146b88SJung-uk Kim  *              concatenate operator.
342f8146b88SJung-uk Kim  *
343f8146b88SJung-uk Kim  ******************************************************************************/
344f8146b88SJung-uk Kim 
345f8146b88SJung-uk Kim static ACPI_STATUS
346f8146b88SJung-uk Kim AcpiExConvertToObjectTypeString (
347f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc,
348f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ResultDesc)
349f8146b88SJung-uk Kim {
350f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
351f8146b88SJung-uk Kim     const char              *TypeString;
352f8146b88SJung-uk Kim 
353f8146b88SJung-uk Kim 
354f8146b88SJung-uk Kim     TypeString = AcpiUtGetTypeName (ObjDesc->Common.Type);
355f8146b88SJung-uk Kim 
356f8146b88SJung-uk Kim     ReturnDesc = AcpiUtCreateStringObject (
357f8146b88SJung-uk Kim         ((ACPI_SIZE) strlen (TypeString) + 9)); /* 9 For "[ Object]" */
358f8146b88SJung-uk Kim     if (!ReturnDesc)
359f8146b88SJung-uk Kim     {
360f8146b88SJung-uk Kim         return (AE_NO_MEMORY);
361f8146b88SJung-uk Kim     }
362f8146b88SJung-uk Kim 
363f8146b88SJung-uk Kim     strcpy (ReturnDesc->String.Pointer, "[");
364f8146b88SJung-uk Kim     strcat (ReturnDesc->String.Pointer, TypeString);
365f8146b88SJung-uk Kim     strcat (ReturnDesc->String.Pointer, " Object]");
366f8146b88SJung-uk Kim 
367f8146b88SJung-uk Kim     *ResultDesc = ReturnDesc;
368f8146b88SJung-uk Kim     return (AE_OK);
369f8146b88SJung-uk Kim }
370f8146b88SJung-uk Kim 
371f8146b88SJung-uk Kim 
372f8146b88SJung-uk Kim /*******************************************************************************
373f8146b88SJung-uk Kim  *
374f8146b88SJung-uk Kim  * FUNCTION:    AcpiExConcatTemplate
375f8146b88SJung-uk Kim  *
376f8146b88SJung-uk Kim  * PARAMETERS:  Operand0            - First source object
377f8146b88SJung-uk Kim  *              Operand1            - Second source object
378f8146b88SJung-uk Kim  *              ActualReturnDesc    - Where to place the return object
379f8146b88SJung-uk Kim  *              WalkState           - Current walk state
380f8146b88SJung-uk Kim  *
381f8146b88SJung-uk Kim  * RETURN:      Status
382f8146b88SJung-uk Kim  *
383f8146b88SJung-uk Kim  * DESCRIPTION: Concatenate two resource templates
384f8146b88SJung-uk Kim  *
385f8146b88SJung-uk Kim  ******************************************************************************/
386f8146b88SJung-uk Kim 
387f8146b88SJung-uk Kim ACPI_STATUS
388f8146b88SJung-uk Kim AcpiExConcatTemplate (
389f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand0,
390f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand1,
391f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
392f8146b88SJung-uk Kim     ACPI_WALK_STATE         *WalkState)
393f8146b88SJung-uk Kim {
394f8146b88SJung-uk Kim     ACPI_STATUS             Status;
395f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
396f8146b88SJung-uk Kim     UINT8                   *NewBuf;
397f8146b88SJung-uk Kim     UINT8                   *EndTag;
398f8146b88SJung-uk Kim     ACPI_SIZE               Length0;
399f8146b88SJung-uk Kim     ACPI_SIZE               Length1;
400f8146b88SJung-uk Kim     ACPI_SIZE               NewLength;
401f8146b88SJung-uk Kim 
402f8146b88SJung-uk Kim 
403f8146b88SJung-uk Kim     ACPI_FUNCTION_TRACE (ExConcatTemplate);
404f8146b88SJung-uk Kim 
405f8146b88SJung-uk Kim 
406f8146b88SJung-uk Kim     /*
407f8146b88SJung-uk Kim      * Find the EndTag descriptor in each resource template.
408f8146b88SJung-uk Kim      * Note1: returned pointers point TO the EndTag, not past it.
409f8146b88SJung-uk Kim      * Note2: zero-length buffers are allowed; treated like one EndTag
410f8146b88SJung-uk Kim      */
411f8146b88SJung-uk Kim 
412f8146b88SJung-uk Kim     /* Get the length of the first resource template */
413f8146b88SJung-uk Kim 
414f8146b88SJung-uk Kim     Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
415f8146b88SJung-uk Kim     if (ACPI_FAILURE (Status))
416f8146b88SJung-uk Kim     {
417f8146b88SJung-uk Kim         return_ACPI_STATUS (Status);
418f8146b88SJung-uk Kim     }
419f8146b88SJung-uk Kim 
420f8146b88SJung-uk Kim     Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
421f8146b88SJung-uk Kim 
422f8146b88SJung-uk Kim     /* Get the length of the second resource template */
423f8146b88SJung-uk Kim 
424f8146b88SJung-uk Kim     Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
425f8146b88SJung-uk Kim     if (ACPI_FAILURE (Status))
426f8146b88SJung-uk Kim     {
427f8146b88SJung-uk Kim         return_ACPI_STATUS (Status);
428f8146b88SJung-uk Kim     }
429f8146b88SJung-uk Kim 
430f8146b88SJung-uk Kim     Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
431f8146b88SJung-uk Kim 
432f8146b88SJung-uk Kim     /* Combine both lengths, minimum size will be 2 for EndTag */
433f8146b88SJung-uk Kim 
434f8146b88SJung-uk Kim     NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
435f8146b88SJung-uk Kim 
436f8146b88SJung-uk Kim     /* Create a new buffer object for the result (with one EndTag) */
437f8146b88SJung-uk Kim 
438f8146b88SJung-uk Kim     ReturnDesc = AcpiUtCreateBufferObject (NewLength);
439f8146b88SJung-uk Kim     if (!ReturnDesc)
440f8146b88SJung-uk Kim     {
441f8146b88SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
442f8146b88SJung-uk Kim     }
443f8146b88SJung-uk Kim 
444f8146b88SJung-uk Kim     /*
445f8146b88SJung-uk Kim      * Copy the templates to the new buffer, 0 first, then 1 follows. One
446f8146b88SJung-uk Kim      * EndTag descriptor is copied from Operand1.
447f8146b88SJung-uk Kim      */
448f8146b88SJung-uk Kim     NewBuf = ReturnDesc->Buffer.Pointer;
449f8146b88SJung-uk Kim     memcpy (NewBuf, Operand0->Buffer.Pointer, Length0);
450f8146b88SJung-uk Kim     memcpy (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
451f8146b88SJung-uk Kim 
452f8146b88SJung-uk Kim     /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
453f8146b88SJung-uk Kim 
454f8146b88SJung-uk Kim     NewBuf[NewLength - 1] = 0;
455f8146b88SJung-uk Kim     NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
456f8146b88SJung-uk Kim 
457f8146b88SJung-uk Kim     /* Return the completed resource template */
458f8146b88SJung-uk Kim 
459f8146b88SJung-uk Kim     *ActualReturnDesc = ReturnDesc;
460f8146b88SJung-uk Kim     return_ACPI_STATUS (AE_OK);
461f8146b88SJung-uk Kim }
462