xref: /freebsd-src/sys/contrib/dev/acpica/components/executer/exconcat.c (revision 804fe2660352e090f4481f2c1d646b508859e79a)
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 
70d84335fSJung-uk Kim /******************************************************************************
80d84335fSJung-uk Kim  *
90d84335fSJung-uk Kim  * 1. Copyright Notice
100d84335fSJung-uk Kim  *
11*804fe266SJung-uk Kim  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
12f8146b88SJung-uk Kim  * All rights reserved.
13f8146b88SJung-uk Kim  *
140d84335fSJung-uk Kim  * 2. License
150d84335fSJung-uk Kim  *
160d84335fSJung-uk Kim  * 2.1. This is your license from Intel Corp. under its intellectual property
170d84335fSJung-uk Kim  * rights. You may have additional license terms from the party that provided
180d84335fSJung-uk Kim  * you this software, covering your right to use that party's intellectual
190d84335fSJung-uk Kim  * property rights.
200d84335fSJung-uk Kim  *
210d84335fSJung-uk Kim  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
220d84335fSJung-uk Kim  * copy of the source code appearing in this file ("Covered Code") an
230d84335fSJung-uk Kim  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
240d84335fSJung-uk Kim  * base code distributed originally by Intel ("Original Intel Code") to copy,
250d84335fSJung-uk Kim  * make derivatives, distribute, use and display any portion of the Covered
260d84335fSJung-uk Kim  * Code in any form, with the right to sublicense such rights; and
270d84335fSJung-uk Kim  *
280d84335fSJung-uk Kim  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
290d84335fSJung-uk Kim  * license (with the right to sublicense), under only those claims of Intel
300d84335fSJung-uk Kim  * patents that are infringed by the Original Intel Code, to make, use, sell,
310d84335fSJung-uk Kim  * offer to sell, and import the Covered Code and derivative works thereof
320d84335fSJung-uk Kim  * solely to the minimum extent necessary to exercise the above copyright
330d84335fSJung-uk Kim  * license, and in no event shall the patent license extend to any additions
340d84335fSJung-uk Kim  * to or modifications of the Original Intel Code. No other license or right
350d84335fSJung-uk Kim  * is granted directly or by implication, estoppel or otherwise;
360d84335fSJung-uk Kim  *
370d84335fSJung-uk Kim  * The above copyright and patent license is granted only if the following
380d84335fSJung-uk Kim  * conditions are met:
390d84335fSJung-uk Kim  *
400d84335fSJung-uk Kim  * 3. Conditions
410d84335fSJung-uk Kim  *
420d84335fSJung-uk Kim  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
430d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
440d84335fSJung-uk Kim  * Code or modification with rights to further distribute source must include
450d84335fSJung-uk Kim  * the above Copyright Notice, the above License, this list of Conditions,
460d84335fSJung-uk Kim  * and the following Disclaimer and Export Compliance provision. In addition,
470d84335fSJung-uk Kim  * Licensee must cause all Covered Code to which Licensee contributes to
480d84335fSJung-uk Kim  * contain a file documenting the changes Licensee made to create that Covered
490d84335fSJung-uk Kim  * Code and the date of any change. Licensee must include in that file the
500d84335fSJung-uk Kim  * documentation of any changes made by any predecessor Licensee. Licensee
510d84335fSJung-uk Kim  * must include a prominent statement that the modification is derived,
520d84335fSJung-uk Kim  * directly or indirectly, from Original Intel Code.
530d84335fSJung-uk Kim  *
540d84335fSJung-uk Kim  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
550d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
560d84335fSJung-uk Kim  * Code or modification without rights to further distribute source must
570d84335fSJung-uk Kim  * include the following Disclaimer and Export Compliance provision in the
580d84335fSJung-uk Kim  * documentation and/or other materials provided with distribution. In
590d84335fSJung-uk Kim  * addition, Licensee may not authorize further sublicense of source of any
600d84335fSJung-uk Kim  * portion of the Covered Code, and must include terms to the effect that the
610d84335fSJung-uk Kim  * license from Licensee to its licensee is limited to the intellectual
620d84335fSJung-uk Kim  * property embodied in the software Licensee provides to its licensee, and
630d84335fSJung-uk Kim  * not to intellectual property embodied in modifications its licensee may
640d84335fSJung-uk Kim  * make.
650d84335fSJung-uk Kim  *
660d84335fSJung-uk Kim  * 3.3. Redistribution of Executable. Redistribution in executable form of any
670d84335fSJung-uk Kim  * substantial portion of the Covered Code or modification must reproduce the
680d84335fSJung-uk Kim  * above Copyright Notice, and the following Disclaimer and Export Compliance
690d84335fSJung-uk Kim  * provision in the documentation and/or other materials provided with the
700d84335fSJung-uk Kim  * distribution.
710d84335fSJung-uk Kim  *
720d84335fSJung-uk Kim  * 3.4. Intel retains all right, title, and interest in and to the Original
730d84335fSJung-uk Kim  * Intel Code.
740d84335fSJung-uk Kim  *
750d84335fSJung-uk Kim  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
760d84335fSJung-uk Kim  * Intel shall be used in advertising or otherwise to promote the sale, use or
770d84335fSJung-uk Kim  * other dealings in products derived from or relating to the Covered Code
780d84335fSJung-uk Kim  * without prior written authorization from Intel.
790d84335fSJung-uk Kim  *
800d84335fSJung-uk Kim  * 4. Disclaimer and Export Compliance
810d84335fSJung-uk Kim  *
820d84335fSJung-uk Kim  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
830d84335fSJung-uk Kim  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
840d84335fSJung-uk Kim  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
850d84335fSJung-uk Kim  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
860d84335fSJung-uk Kim 
870d84335fSJung-uk Kim  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
880d84335fSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
890d84335fSJung-uk Kim  * PARTICULAR PURPOSE.
900d84335fSJung-uk Kim  *
910d84335fSJung-uk Kim  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
920d84335fSJung-uk Kim  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
930d84335fSJung-uk Kim  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
940d84335fSJung-uk Kim  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
950d84335fSJung-uk Kim  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
960d84335fSJung-uk Kim  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
970d84335fSJung-uk Kim  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
980d84335fSJung-uk Kim  * LIMITED REMEDY.
990d84335fSJung-uk Kim  *
1000d84335fSJung-uk Kim  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1010d84335fSJung-uk Kim  * software or system incorporating such software without first obtaining any
1020d84335fSJung-uk Kim  * required license or other approval from the U. S. Department of Commerce or
1030d84335fSJung-uk Kim  * any other agency or department of the United States Government. In the
1040d84335fSJung-uk Kim  * event Licensee exports any such software from the United States or
1050d84335fSJung-uk Kim  * re-exports any such software from a foreign destination, Licensee shall
1060d84335fSJung-uk Kim  * ensure that the distribution and export/re-export of the software is in
1070d84335fSJung-uk Kim  * compliance with all laws, regulations, orders, or other restrictions of the
1080d84335fSJung-uk Kim  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1090d84335fSJung-uk Kim  * any of its subsidiaries will export/re-export any technical data, process,
1100d84335fSJung-uk Kim  * software, or service, directly or indirectly, to any country for which the
1110d84335fSJung-uk Kim  * United States government or any agency thereof requires an export license,
1120d84335fSJung-uk Kim  * other governmental approval, or letter of assurance, without first obtaining
1130d84335fSJung-uk Kim  * such license, approval or letter.
1140d84335fSJung-uk Kim  *
1150d84335fSJung-uk Kim  *****************************************************************************
1160d84335fSJung-uk Kim  *
1170d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
1180d84335fSJung-uk Kim  * following license:
1190d84335fSJung-uk Kim  *
120f8146b88SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
121f8146b88SJung-uk Kim  * modification, are permitted provided that the following conditions
122f8146b88SJung-uk Kim  * are met:
123f8146b88SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
124f8146b88SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
125f8146b88SJung-uk Kim  *    without modification.
126f8146b88SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127f8146b88SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
128f8146b88SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
129f8146b88SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
130f8146b88SJung-uk Kim  *    binary redistribution.
131f8146b88SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
132f8146b88SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
133f8146b88SJung-uk Kim  *    from this software without specific prior written permission.
134f8146b88SJung-uk Kim  *
1350d84335fSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1360d84335fSJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1370d84335fSJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1380d84335fSJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1390d84335fSJung-uk Kim  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1400d84335fSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1410d84335fSJung-uk Kim  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1420d84335fSJung-uk Kim  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1430d84335fSJung-uk Kim  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1440d84335fSJung-uk Kim  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1450d84335fSJung-uk Kim  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1460d84335fSJung-uk Kim  *
1470d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
148f8146b88SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
149f8146b88SJung-uk Kim  * Software Foundation.
150f8146b88SJung-uk Kim  *
1510d84335fSJung-uk Kim  *****************************************************************************/
152f8146b88SJung-uk Kim 
153f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
154f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
155f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/acinterp.h>
156f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/amlresrc.h>
157f8146b88SJung-uk Kim 
158f8146b88SJung-uk Kim 
159f8146b88SJung-uk Kim #define _COMPONENT          ACPI_EXECUTER
160f8146b88SJung-uk Kim         ACPI_MODULE_NAME    ("exconcat")
161f8146b88SJung-uk Kim 
162f8146b88SJung-uk Kim /* Local Prototypes */
163f8146b88SJung-uk Kim 
164f8146b88SJung-uk Kim static ACPI_STATUS
165f8146b88SJung-uk Kim AcpiExConvertToObjectTypeString (
166f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc,
167f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ResultDesc);
168f8146b88SJung-uk Kim 
169f8146b88SJung-uk Kim 
170f8146b88SJung-uk Kim /*******************************************************************************
171f8146b88SJung-uk Kim  *
172f8146b88SJung-uk Kim  * FUNCTION:    AcpiExDoConcatenate
173f8146b88SJung-uk Kim  *
174f8146b88SJung-uk Kim  * PARAMETERS:  Operand0            - First source object
175f8146b88SJung-uk Kim  *              Operand1            - Second source object
176f8146b88SJung-uk Kim  *              ActualReturnDesc    - Where to place the return object
177f8146b88SJung-uk Kim  *              WalkState           - Current walk state
178f8146b88SJung-uk Kim  *
179f8146b88SJung-uk Kim  * RETURN:      Status
180f8146b88SJung-uk Kim  *
181f8146b88SJung-uk Kim  * DESCRIPTION: Concatenate two objects with the ACPI-defined conversion
182f8146b88SJung-uk Kim  *              rules as necessary.
183f8146b88SJung-uk Kim  * NOTE:
184f8146b88SJung-uk Kim  * Per the ACPI spec (up to 6.1), Concatenate only supports Integer,
185f8146b88SJung-uk Kim  * String, and Buffer objects. However, we support all objects here
186f8146b88SJung-uk Kim  * as an extension. This improves the usefulness of both Concatenate
187f8146b88SJung-uk Kim  * and the Printf/Fprintf macros. The extension returns a string
188f8146b88SJung-uk Kim  * describing the object type for the other objects.
189f8146b88SJung-uk Kim  * 02/2016.
190f8146b88SJung-uk Kim  *
191f8146b88SJung-uk Kim  ******************************************************************************/
192f8146b88SJung-uk Kim 
193f8146b88SJung-uk Kim ACPI_STATUS
194f8146b88SJung-uk Kim AcpiExDoConcatenate (
195f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand0,
196f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand1,
197f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
198f8146b88SJung-uk Kim     ACPI_WALK_STATE         *WalkState)
199f8146b88SJung-uk Kim {
200f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *LocalOperand0 = Operand0;
201f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
202f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *TempOperand1 = NULL;
203f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
204f8146b88SJung-uk Kim     char                    *Buffer;
205f8146b88SJung-uk Kim     ACPI_OBJECT_TYPE        Operand0Type;
206f8146b88SJung-uk Kim     ACPI_OBJECT_TYPE        Operand1Type;
207f8146b88SJung-uk Kim     ACPI_STATUS             Status;
208f8146b88SJung-uk Kim 
209f8146b88SJung-uk Kim 
210f8146b88SJung-uk Kim     ACPI_FUNCTION_TRACE (ExDoConcatenate);
211f8146b88SJung-uk Kim 
212f8146b88SJung-uk Kim 
213f8146b88SJung-uk Kim     /* Operand 0 preprocessing */
214f8146b88SJung-uk Kim 
215f8146b88SJung-uk Kim     switch (Operand0->Common.Type)
216f8146b88SJung-uk Kim     {
217f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
218f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
219f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
220f8146b88SJung-uk Kim 
221f8146b88SJung-uk Kim         Operand0Type = Operand0->Common.Type;
222f8146b88SJung-uk Kim         break;
223f8146b88SJung-uk Kim 
224f8146b88SJung-uk Kim     default:
225f8146b88SJung-uk Kim 
226f8146b88SJung-uk Kim         /* For all other types, get the "object type" string */
227f8146b88SJung-uk Kim 
228f8146b88SJung-uk Kim         Status = AcpiExConvertToObjectTypeString (
229f8146b88SJung-uk Kim             Operand0, &LocalOperand0);
230f8146b88SJung-uk Kim         if (ACPI_FAILURE (Status))
231f8146b88SJung-uk Kim         {
232f8146b88SJung-uk Kim             goto Cleanup;
233f8146b88SJung-uk Kim         }
234f8146b88SJung-uk Kim 
235f8146b88SJung-uk Kim         Operand0Type = ACPI_TYPE_STRING;
236f8146b88SJung-uk Kim         break;
237f8146b88SJung-uk Kim     }
238f8146b88SJung-uk Kim 
239f8146b88SJung-uk Kim     /* Operand 1 preprocessing */
240f8146b88SJung-uk Kim 
241f8146b88SJung-uk Kim     switch (Operand1->Common.Type)
242f8146b88SJung-uk Kim     {
243f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
244f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
245f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
246f8146b88SJung-uk Kim 
247f8146b88SJung-uk Kim         Operand1Type = Operand1->Common.Type;
248f8146b88SJung-uk Kim         break;
249f8146b88SJung-uk Kim 
250f8146b88SJung-uk Kim     default:
251f8146b88SJung-uk Kim 
252f8146b88SJung-uk Kim         /* For all other types, get the "object type" string */
253f8146b88SJung-uk Kim 
254f8146b88SJung-uk Kim         Status = AcpiExConvertToObjectTypeString (
255f8146b88SJung-uk Kim             Operand1, &LocalOperand1);
256f8146b88SJung-uk Kim         if (ACPI_FAILURE (Status))
257f8146b88SJung-uk Kim         {
258f8146b88SJung-uk Kim             goto Cleanup;
259f8146b88SJung-uk Kim         }
260f8146b88SJung-uk Kim 
261f8146b88SJung-uk Kim         Operand1Type = ACPI_TYPE_STRING;
262f8146b88SJung-uk Kim         break;
263f8146b88SJung-uk Kim     }
264f8146b88SJung-uk Kim 
265f8146b88SJung-uk Kim     /*
266f8146b88SJung-uk Kim      * Convert the second operand if necessary. The first operand (0)
267f8146b88SJung-uk Kim      * determines the type of the second operand (1) (See the Data Types
268f8146b88SJung-uk Kim      * section of the ACPI specification). Both object types are
269f8146b88SJung-uk Kim      * guaranteed to be either Integer/String/Buffer by the operand
270f8146b88SJung-uk Kim      * resolution mechanism.
271f8146b88SJung-uk Kim      */
272f8146b88SJung-uk Kim     switch (Operand0Type)
273f8146b88SJung-uk Kim     {
274f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
275f8146b88SJung-uk Kim 
276493deb39SJung-uk Kim         Status = AcpiExConvertToInteger (LocalOperand1, &TempOperand1,
2772f6a1a81SJung-uk Kim             ACPI_IMPLICIT_CONVERSION);
278f8146b88SJung-uk Kim         break;
279f8146b88SJung-uk Kim 
280f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
281f8146b88SJung-uk Kim 
282f8146b88SJung-uk Kim         Status = AcpiExConvertToBuffer (LocalOperand1, &TempOperand1);
283f8146b88SJung-uk Kim         break;
284f8146b88SJung-uk Kim 
285f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
286f8146b88SJung-uk Kim 
287f8146b88SJung-uk Kim         switch (Operand1Type)
288f8146b88SJung-uk Kim         {
289f8146b88SJung-uk Kim         case ACPI_TYPE_INTEGER:
290f8146b88SJung-uk Kim         case ACPI_TYPE_STRING:
291f8146b88SJung-uk Kim         case ACPI_TYPE_BUFFER:
292f8146b88SJung-uk Kim 
293f8146b88SJung-uk Kim             /* Other types have already been converted to string */
294f8146b88SJung-uk Kim 
295f8146b88SJung-uk Kim             Status = AcpiExConvertToString (
296f8146b88SJung-uk Kim                 LocalOperand1, &TempOperand1, ACPI_IMPLICIT_CONVERT_HEX);
297f8146b88SJung-uk Kim             break;
298f8146b88SJung-uk Kim 
299f8146b88SJung-uk Kim         default:
300f8146b88SJung-uk Kim 
301f8146b88SJung-uk Kim             Status = AE_OK;
302f8146b88SJung-uk Kim             break;
303f8146b88SJung-uk Kim         }
304f8146b88SJung-uk Kim         break;
305f8146b88SJung-uk Kim 
306f8146b88SJung-uk Kim     default:
307f8146b88SJung-uk Kim 
308f8146b88SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
309f8146b88SJung-uk Kim             Operand0->Common.Type));
310f8146b88SJung-uk Kim         Status = AE_AML_INTERNAL;
311f8146b88SJung-uk Kim     }
312f8146b88SJung-uk Kim 
313f8146b88SJung-uk Kim     if (ACPI_FAILURE (Status))
314f8146b88SJung-uk Kim     {
315f8146b88SJung-uk Kim         goto Cleanup;
316f8146b88SJung-uk Kim     }
317f8146b88SJung-uk Kim 
318f8146b88SJung-uk Kim     /* Take care with any newly created operand objects */
319f8146b88SJung-uk Kim 
320f8146b88SJung-uk Kim     if ((LocalOperand1 != Operand1) &&
321f8146b88SJung-uk Kim         (LocalOperand1 != TempOperand1))
322f8146b88SJung-uk Kim     {
323f8146b88SJung-uk Kim         AcpiUtRemoveReference (LocalOperand1);
324f8146b88SJung-uk Kim     }
325f8146b88SJung-uk Kim 
326f8146b88SJung-uk Kim     LocalOperand1 = TempOperand1;
327f8146b88SJung-uk Kim 
328f8146b88SJung-uk Kim     /*
329f8146b88SJung-uk Kim      * Both operands are now known to be the same object type
330f8146b88SJung-uk Kim      * (Both are Integer, String, or Buffer), and we can now perform
331f8146b88SJung-uk Kim      * the concatenation.
332f8146b88SJung-uk Kim      *
333f8146b88SJung-uk Kim      * There are three cases to handle, as per the ACPI spec:
334f8146b88SJung-uk Kim      *
335f8146b88SJung-uk Kim      * 1) Two Integers concatenated to produce a new Buffer
336f8146b88SJung-uk Kim      * 2) Two Strings concatenated to produce a new String
337f8146b88SJung-uk Kim      * 3) Two Buffers concatenated to produce a new Buffer
338f8146b88SJung-uk Kim      */
339f8146b88SJung-uk Kim     switch (Operand0Type)
340f8146b88SJung-uk Kim     {
341f8146b88SJung-uk Kim     case ACPI_TYPE_INTEGER:
342f8146b88SJung-uk Kim 
343f8146b88SJung-uk Kim         /* Result of two Integers is a Buffer */
344f8146b88SJung-uk Kim         /* Need enough buffer space for two integers */
345f8146b88SJung-uk Kim 
346f8146b88SJung-uk Kim         ReturnDesc = AcpiUtCreateBufferObject (
347f8146b88SJung-uk Kim             (ACPI_SIZE) ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
348f8146b88SJung-uk Kim         if (!ReturnDesc)
349f8146b88SJung-uk Kim         {
350f8146b88SJung-uk Kim             Status = AE_NO_MEMORY;
351f8146b88SJung-uk Kim             goto Cleanup;
352f8146b88SJung-uk Kim         }
353f8146b88SJung-uk Kim 
354f8146b88SJung-uk Kim         Buffer = (char *) ReturnDesc->Buffer.Pointer;
355f8146b88SJung-uk Kim 
356f8146b88SJung-uk Kim         /* Copy the first integer, LSB first */
357f8146b88SJung-uk Kim 
358f8146b88SJung-uk Kim         memcpy (Buffer, &Operand0->Integer.Value,
359f8146b88SJung-uk Kim             AcpiGbl_IntegerByteWidth);
360f8146b88SJung-uk Kim 
361f8146b88SJung-uk Kim         /* Copy the second integer (LSB first) after the first */
362f8146b88SJung-uk Kim 
363f8146b88SJung-uk Kim         memcpy (Buffer + AcpiGbl_IntegerByteWidth,
364f8146b88SJung-uk Kim             &LocalOperand1->Integer.Value, AcpiGbl_IntegerByteWidth);
365f8146b88SJung-uk Kim         break;
366f8146b88SJung-uk Kim 
367f8146b88SJung-uk Kim     case ACPI_TYPE_STRING:
368f8146b88SJung-uk Kim 
369f8146b88SJung-uk Kim         /* Result of two Strings is a String */
370f8146b88SJung-uk Kim 
371f8146b88SJung-uk Kim         ReturnDesc = AcpiUtCreateStringObject (
372f8146b88SJung-uk Kim             ((ACPI_SIZE) LocalOperand0->String.Length +
373f8146b88SJung-uk Kim             LocalOperand1->String.Length));
374f8146b88SJung-uk Kim         if (!ReturnDesc)
375f8146b88SJung-uk Kim         {
376f8146b88SJung-uk Kim             Status = AE_NO_MEMORY;
377f8146b88SJung-uk Kim             goto Cleanup;
378f8146b88SJung-uk Kim         }
379f8146b88SJung-uk Kim 
380f8146b88SJung-uk Kim         Buffer = ReturnDesc->String.Pointer;
381f8146b88SJung-uk Kim 
382f8146b88SJung-uk Kim         /* Concatenate the strings */
383f8146b88SJung-uk Kim 
384f8146b88SJung-uk Kim         strcpy (Buffer, LocalOperand0->String.Pointer);
385f8146b88SJung-uk Kim         strcat (Buffer, LocalOperand1->String.Pointer);
386f8146b88SJung-uk Kim         break;
387f8146b88SJung-uk Kim 
388f8146b88SJung-uk Kim     case ACPI_TYPE_BUFFER:
389f8146b88SJung-uk Kim 
390f8146b88SJung-uk Kim         /* Result of two Buffers is a Buffer */
391f8146b88SJung-uk Kim 
392f8146b88SJung-uk Kim         ReturnDesc = AcpiUtCreateBufferObject (
393f8146b88SJung-uk Kim             ((ACPI_SIZE) Operand0->Buffer.Length +
394f8146b88SJung-uk Kim             LocalOperand1->Buffer.Length));
395f8146b88SJung-uk Kim         if (!ReturnDesc)
396f8146b88SJung-uk Kim         {
397f8146b88SJung-uk Kim             Status = AE_NO_MEMORY;
398f8146b88SJung-uk Kim             goto Cleanup;
399f8146b88SJung-uk Kim         }
400f8146b88SJung-uk Kim 
401f8146b88SJung-uk Kim         Buffer = (char *) ReturnDesc->Buffer.Pointer;
402f8146b88SJung-uk Kim 
403f8146b88SJung-uk Kim         /* Concatenate the buffers */
404f8146b88SJung-uk Kim 
405f8146b88SJung-uk Kim         memcpy (Buffer, Operand0->Buffer.Pointer,
406f8146b88SJung-uk Kim             Operand0->Buffer.Length);
407f8146b88SJung-uk Kim         memcpy (Buffer + Operand0->Buffer.Length,
408f8146b88SJung-uk Kim             LocalOperand1->Buffer.Pointer,
409f8146b88SJung-uk Kim             LocalOperand1->Buffer.Length);
410f8146b88SJung-uk Kim         break;
411f8146b88SJung-uk Kim 
412f8146b88SJung-uk Kim     default:
413f8146b88SJung-uk Kim 
414f8146b88SJung-uk Kim         /* Invalid object type, should not happen here */
415f8146b88SJung-uk Kim 
416f8146b88SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
417f8146b88SJung-uk Kim             Operand0->Common.Type));
418f8146b88SJung-uk Kim         Status = AE_AML_INTERNAL;
419f8146b88SJung-uk Kim         goto Cleanup;
420f8146b88SJung-uk Kim     }
421f8146b88SJung-uk Kim 
422f8146b88SJung-uk Kim     *ActualReturnDesc = ReturnDesc;
423f8146b88SJung-uk Kim 
424f8146b88SJung-uk Kim Cleanup:
425f8146b88SJung-uk Kim     if (LocalOperand0 != Operand0)
426f8146b88SJung-uk Kim     {
427f8146b88SJung-uk Kim         AcpiUtRemoveReference (LocalOperand0);
428f8146b88SJung-uk Kim     }
429f8146b88SJung-uk Kim 
430f8146b88SJung-uk Kim     if (LocalOperand1 != Operand1)
431f8146b88SJung-uk Kim     {
432f8146b88SJung-uk Kim         AcpiUtRemoveReference (LocalOperand1);
433f8146b88SJung-uk Kim     }
434f8146b88SJung-uk Kim 
435f8146b88SJung-uk Kim     return_ACPI_STATUS (Status);
436f8146b88SJung-uk Kim }
437f8146b88SJung-uk Kim 
438f8146b88SJung-uk Kim 
439f8146b88SJung-uk Kim /*******************************************************************************
440f8146b88SJung-uk Kim  *
441f8146b88SJung-uk Kim  * FUNCTION:    AcpiExConvertToObjectTypeString
442f8146b88SJung-uk Kim  *
443f8146b88SJung-uk Kim  * PARAMETERS:  ObjDesc             - Object to be converted
444f8146b88SJung-uk Kim  *              ReturnDesc          - Where to place the return object
445f8146b88SJung-uk Kim  *
446f8146b88SJung-uk Kim  * RETURN:      Status
447f8146b88SJung-uk Kim  *
448f8146b88SJung-uk Kim  * DESCRIPTION: Convert an object of arbitrary type to a string object that
449f8146b88SJung-uk Kim  *              contains the namestring for the object. Used for the
450f8146b88SJung-uk Kim  *              concatenate operator.
451f8146b88SJung-uk Kim  *
452f8146b88SJung-uk Kim  ******************************************************************************/
453f8146b88SJung-uk Kim 
454f8146b88SJung-uk Kim static ACPI_STATUS
455f8146b88SJung-uk Kim AcpiExConvertToObjectTypeString (
456f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc,
457f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ResultDesc)
458f8146b88SJung-uk Kim {
459f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
460f8146b88SJung-uk Kim     const char              *TypeString;
461f8146b88SJung-uk Kim 
462f8146b88SJung-uk Kim 
463f8146b88SJung-uk Kim     TypeString = AcpiUtGetTypeName (ObjDesc->Common.Type);
464f8146b88SJung-uk Kim 
465f8146b88SJung-uk Kim     ReturnDesc = AcpiUtCreateStringObject (
466f8146b88SJung-uk Kim         ((ACPI_SIZE) strlen (TypeString) + 9)); /* 9 For "[ Object]" */
467f8146b88SJung-uk Kim     if (!ReturnDesc)
468f8146b88SJung-uk Kim     {
469f8146b88SJung-uk Kim         return (AE_NO_MEMORY);
470f8146b88SJung-uk Kim     }
471f8146b88SJung-uk Kim 
472f8146b88SJung-uk Kim     strcpy (ReturnDesc->String.Pointer, "[");
473f8146b88SJung-uk Kim     strcat (ReturnDesc->String.Pointer, TypeString);
474f8146b88SJung-uk Kim     strcat (ReturnDesc->String.Pointer, " Object]");
475f8146b88SJung-uk Kim 
476f8146b88SJung-uk Kim     *ResultDesc = ReturnDesc;
477f8146b88SJung-uk Kim     return (AE_OK);
478f8146b88SJung-uk Kim }
479f8146b88SJung-uk Kim 
480f8146b88SJung-uk Kim 
481f8146b88SJung-uk Kim /*******************************************************************************
482f8146b88SJung-uk Kim  *
483f8146b88SJung-uk Kim  * FUNCTION:    AcpiExConcatTemplate
484f8146b88SJung-uk Kim  *
485f8146b88SJung-uk Kim  * PARAMETERS:  Operand0            - First source object
486f8146b88SJung-uk Kim  *              Operand1            - Second source object
487f8146b88SJung-uk Kim  *              ActualReturnDesc    - Where to place the return object
488f8146b88SJung-uk Kim  *              WalkState           - Current walk state
489f8146b88SJung-uk Kim  *
490f8146b88SJung-uk Kim  * RETURN:      Status
491f8146b88SJung-uk Kim  *
492f8146b88SJung-uk Kim  * DESCRIPTION: Concatenate two resource templates
493f8146b88SJung-uk Kim  *
494f8146b88SJung-uk Kim  ******************************************************************************/
495f8146b88SJung-uk Kim 
496f8146b88SJung-uk Kim ACPI_STATUS
497f8146b88SJung-uk Kim AcpiExConcatTemplate (
498f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand0,
499f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand1,
500f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
501f8146b88SJung-uk Kim     ACPI_WALK_STATE         *WalkState)
502f8146b88SJung-uk Kim {
503f8146b88SJung-uk Kim     ACPI_STATUS             Status;
504f8146b88SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
505f8146b88SJung-uk Kim     UINT8                   *NewBuf;
506f8146b88SJung-uk Kim     UINT8                   *EndTag;
507f8146b88SJung-uk Kim     ACPI_SIZE               Length0;
508f8146b88SJung-uk Kim     ACPI_SIZE               Length1;
509f8146b88SJung-uk Kim     ACPI_SIZE               NewLength;
510f8146b88SJung-uk Kim 
511f8146b88SJung-uk Kim 
512f8146b88SJung-uk Kim     ACPI_FUNCTION_TRACE (ExConcatTemplate);
513f8146b88SJung-uk Kim 
514f8146b88SJung-uk Kim 
515f8146b88SJung-uk Kim     /*
516f8146b88SJung-uk Kim      * Find the EndTag descriptor in each resource template.
517f8146b88SJung-uk Kim      * Note1: returned pointers point TO the EndTag, not past it.
518f8146b88SJung-uk Kim      * Note2: zero-length buffers are allowed; treated like one EndTag
519f8146b88SJung-uk Kim      */
520f8146b88SJung-uk Kim 
521f8146b88SJung-uk Kim     /* Get the length of the first resource template */
522f8146b88SJung-uk Kim 
523f8146b88SJung-uk Kim     Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
524f8146b88SJung-uk Kim     if (ACPI_FAILURE (Status))
525f8146b88SJung-uk Kim     {
526f8146b88SJung-uk Kim         return_ACPI_STATUS (Status);
527f8146b88SJung-uk Kim     }
528f8146b88SJung-uk Kim 
529f8146b88SJung-uk Kim     Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
530f8146b88SJung-uk Kim 
531f8146b88SJung-uk Kim     /* Get the length of the second resource template */
532f8146b88SJung-uk Kim 
533f8146b88SJung-uk Kim     Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
534f8146b88SJung-uk Kim     if (ACPI_FAILURE (Status))
535f8146b88SJung-uk Kim     {
536f8146b88SJung-uk Kim         return_ACPI_STATUS (Status);
537f8146b88SJung-uk Kim     }
538f8146b88SJung-uk Kim 
539f8146b88SJung-uk Kim     Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
540f8146b88SJung-uk Kim 
541f8146b88SJung-uk Kim     /* Combine both lengths, minimum size will be 2 for EndTag */
542f8146b88SJung-uk Kim 
543f8146b88SJung-uk Kim     NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
544f8146b88SJung-uk Kim 
545f8146b88SJung-uk Kim     /* Create a new buffer object for the result (with one EndTag) */
546f8146b88SJung-uk Kim 
547f8146b88SJung-uk Kim     ReturnDesc = AcpiUtCreateBufferObject (NewLength);
548f8146b88SJung-uk Kim     if (!ReturnDesc)
549f8146b88SJung-uk Kim     {
550f8146b88SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
551f8146b88SJung-uk Kim     }
552f8146b88SJung-uk Kim 
553f8146b88SJung-uk Kim     /*
554f8146b88SJung-uk Kim      * Copy the templates to the new buffer, 0 first, then 1 follows. One
555f8146b88SJung-uk Kim      * EndTag descriptor is copied from Operand1.
556f8146b88SJung-uk Kim      */
557f8146b88SJung-uk Kim     NewBuf = ReturnDesc->Buffer.Pointer;
558f8146b88SJung-uk Kim     memcpy (NewBuf, Operand0->Buffer.Pointer, Length0);
559f8146b88SJung-uk Kim     memcpy (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
560f8146b88SJung-uk Kim 
561f8146b88SJung-uk Kim     /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
562f8146b88SJung-uk Kim 
563f8146b88SJung-uk Kim     NewBuf[NewLength - 1] = 0;
564f8146b88SJung-uk Kim     NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
565f8146b88SJung-uk Kim 
566f8146b88SJung-uk Kim     /* Return the completed resource template */
567f8146b88SJung-uk Kim 
568f8146b88SJung-uk Kim     *ActualReturnDesc = ReturnDesc;
569f8146b88SJung-uk Kim     return_ACPI_STATUS (AE_OK);
570f8146b88SJung-uk Kim }
571