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*58308fadSJung-uk Kim * Some or all of this work - Copyright (c) 1999 - 2025, 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
AcpiExDoConcatenate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)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
AcpiExConvertToObjectTypeString(ACPI_OPERAND_OBJECT * ObjDesc,ACPI_OPERAND_OBJECT ** ResultDesc)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
AcpiExConcatTemplate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)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