174ffd18dSFredrik Holmqvist /******************************************************************************
274ffd18dSFredrik Holmqvist *
374ffd18dSFredrik Holmqvist * Module Name: exconcat - Concatenate-type AML operators
474ffd18dSFredrik Holmqvist *
574ffd18dSFredrik Holmqvist *****************************************************************************/
674ffd18dSFredrik Holmqvist
774ffd18dSFredrik Holmqvist /******************************************************************************
874ffd18dSFredrik Holmqvist *
974ffd18dSFredrik Holmqvist * 1. Copyright Notice
1074ffd18dSFredrik Holmqvist *
11*6dde014fSPulkoMandy * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
1274ffd18dSFredrik Holmqvist * All rights reserved.
1374ffd18dSFredrik Holmqvist *
1474ffd18dSFredrik Holmqvist * 2. License
1574ffd18dSFredrik Holmqvist *
1674ffd18dSFredrik Holmqvist * 2.1. This is your license from Intel Corp. under its intellectual property
1774ffd18dSFredrik Holmqvist * rights. You may have additional license terms from the party that provided
1874ffd18dSFredrik Holmqvist * you this software, covering your right to use that party's intellectual
1974ffd18dSFredrik Holmqvist * property rights.
2074ffd18dSFredrik Holmqvist *
2174ffd18dSFredrik Holmqvist * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2274ffd18dSFredrik Holmqvist * copy of the source code appearing in this file ("Covered Code") an
2374ffd18dSFredrik Holmqvist * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2474ffd18dSFredrik Holmqvist * base code distributed originally by Intel ("Original Intel Code") to copy,
2574ffd18dSFredrik Holmqvist * make derivatives, distribute, use and display any portion of the Covered
2674ffd18dSFredrik Holmqvist * Code in any form, with the right to sublicense such rights; and
2774ffd18dSFredrik Holmqvist *
2874ffd18dSFredrik Holmqvist * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2974ffd18dSFredrik Holmqvist * license (with the right to sublicense), under only those claims of Intel
3074ffd18dSFredrik Holmqvist * patents that are infringed by the Original Intel Code, to make, use, sell,
3174ffd18dSFredrik Holmqvist * offer to sell, and import the Covered Code and derivative works thereof
3274ffd18dSFredrik Holmqvist * solely to the minimum extent necessary to exercise the above copyright
3374ffd18dSFredrik Holmqvist * license, and in no event shall the patent license extend to any additions
3474ffd18dSFredrik Holmqvist * to or modifications of the Original Intel Code. No other license or right
3574ffd18dSFredrik Holmqvist * is granted directly or by implication, estoppel or otherwise;
3674ffd18dSFredrik Holmqvist *
3774ffd18dSFredrik Holmqvist * The above copyright and patent license is granted only if the following
3874ffd18dSFredrik Holmqvist * conditions are met:
3974ffd18dSFredrik Holmqvist *
4074ffd18dSFredrik Holmqvist * 3. Conditions
4174ffd18dSFredrik Holmqvist *
4274ffd18dSFredrik Holmqvist * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4374ffd18dSFredrik Holmqvist * Redistribution of source code of any substantial portion of the Covered
4474ffd18dSFredrik Holmqvist * Code or modification with rights to further distribute source must include
4574ffd18dSFredrik Holmqvist * the above Copyright Notice, the above License, this list of Conditions,
4674ffd18dSFredrik Holmqvist * and the following Disclaimer and Export Compliance provision. In addition,
4774ffd18dSFredrik Holmqvist * Licensee must cause all Covered Code to which Licensee contributes to
4874ffd18dSFredrik Holmqvist * contain a file documenting the changes Licensee made to create that Covered
4974ffd18dSFredrik Holmqvist * Code and the date of any change. Licensee must include in that file the
5074ffd18dSFredrik Holmqvist * documentation of any changes made by any predecessor Licensee. Licensee
5174ffd18dSFredrik Holmqvist * must include a prominent statement that the modification is derived,
5274ffd18dSFredrik Holmqvist * directly or indirectly, from Original Intel Code.
5374ffd18dSFredrik Holmqvist *
5474ffd18dSFredrik Holmqvist * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5574ffd18dSFredrik Holmqvist * Redistribution of source code of any substantial portion of the Covered
5674ffd18dSFredrik Holmqvist * Code or modification without rights to further distribute source must
5774ffd18dSFredrik Holmqvist * include the following Disclaimer and Export Compliance provision in the
5874ffd18dSFredrik Holmqvist * documentation and/or other materials provided with distribution. In
5974ffd18dSFredrik Holmqvist * addition, Licensee may not authorize further sublicense of source of any
6074ffd18dSFredrik Holmqvist * portion of the Covered Code, and must include terms to the effect that the
6174ffd18dSFredrik Holmqvist * license from Licensee to its licensee is limited to the intellectual
6274ffd18dSFredrik Holmqvist * property embodied in the software Licensee provides to its licensee, and
6374ffd18dSFredrik Holmqvist * not to intellectual property embodied in modifications its licensee may
6474ffd18dSFredrik Holmqvist * make.
6574ffd18dSFredrik Holmqvist *
6674ffd18dSFredrik Holmqvist * 3.3. Redistribution of Executable. Redistribution in executable form of any
6774ffd18dSFredrik Holmqvist * substantial portion of the Covered Code or modification must reproduce the
6874ffd18dSFredrik Holmqvist * above Copyright Notice, and the following Disclaimer and Export Compliance
6974ffd18dSFredrik Holmqvist * provision in the documentation and/or other materials provided with the
7074ffd18dSFredrik Holmqvist * distribution.
7174ffd18dSFredrik Holmqvist *
7274ffd18dSFredrik Holmqvist * 3.4. Intel retains all right, title, and interest in and to the Original
7374ffd18dSFredrik Holmqvist * Intel Code.
7474ffd18dSFredrik Holmqvist *
7574ffd18dSFredrik Holmqvist * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7674ffd18dSFredrik Holmqvist * Intel shall be used in advertising or otherwise to promote the sale, use or
7774ffd18dSFredrik Holmqvist * other dealings in products derived from or relating to the Covered Code
7874ffd18dSFredrik Holmqvist * without prior written authorization from Intel.
7974ffd18dSFredrik Holmqvist *
8074ffd18dSFredrik Holmqvist * 4. Disclaimer and Export Compliance
8174ffd18dSFredrik Holmqvist *
8274ffd18dSFredrik Holmqvist * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8374ffd18dSFredrik Holmqvist * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8474ffd18dSFredrik Holmqvist * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
8574ffd18dSFredrik Holmqvist * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
8674ffd18dSFredrik Holmqvist
8774ffd18dSFredrik Holmqvist * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
8874ffd18dSFredrik Holmqvist * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8974ffd18dSFredrik Holmqvist * PARTICULAR PURPOSE.
9074ffd18dSFredrik Holmqvist *
9174ffd18dSFredrik Holmqvist * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9274ffd18dSFredrik Holmqvist * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9374ffd18dSFredrik Holmqvist * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9474ffd18dSFredrik Holmqvist * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9574ffd18dSFredrik Holmqvist * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9674ffd18dSFredrik Holmqvist * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
9774ffd18dSFredrik Holmqvist * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9874ffd18dSFredrik Holmqvist * LIMITED REMEDY.
9974ffd18dSFredrik Holmqvist *
10074ffd18dSFredrik Holmqvist * 4.3. Licensee shall not export, either directly or indirectly, any of this
10174ffd18dSFredrik Holmqvist * software or system incorporating such software without first obtaining any
10274ffd18dSFredrik Holmqvist * required license or other approval from the U. S. Department of Commerce or
10374ffd18dSFredrik Holmqvist * any other agency or department of the United States Government. In the
10474ffd18dSFredrik Holmqvist * event Licensee exports any such software from the United States or
10574ffd18dSFredrik Holmqvist * re-exports any such software from a foreign destination, Licensee shall
10674ffd18dSFredrik Holmqvist * ensure that the distribution and export/re-export of the software is in
10774ffd18dSFredrik Holmqvist * compliance with all laws, regulations, orders, or other restrictions of the
10874ffd18dSFredrik Holmqvist * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10974ffd18dSFredrik Holmqvist * any of its subsidiaries will export/re-export any technical data, process,
11074ffd18dSFredrik Holmqvist * software, or service, directly or indirectly, to any country for which the
11174ffd18dSFredrik Holmqvist * United States government or any agency thereof requires an export license,
11274ffd18dSFredrik Holmqvist * other governmental approval, or letter of assurance, without first obtaining
11374ffd18dSFredrik Holmqvist * such license, approval or letter.
11474ffd18dSFredrik Holmqvist *
115ff2e2f81SFredrik Holmqvist *****************************************************************************
116ff2e2f81SFredrik Holmqvist *
117ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
118ff2e2f81SFredrik Holmqvist * following license:
119ff2e2f81SFredrik Holmqvist *
120ff2e2f81SFredrik Holmqvist * Redistribution and use in source and binary forms, with or without
121ff2e2f81SFredrik Holmqvist * modification, are permitted provided that the following conditions
122ff2e2f81SFredrik Holmqvist * are met:
123ff2e2f81SFredrik Holmqvist * 1. Redistributions of source code must retain the above copyright
124ff2e2f81SFredrik Holmqvist * notice, this list of conditions, and the following disclaimer,
125ff2e2f81SFredrik Holmqvist * without modification.
126ff2e2f81SFredrik Holmqvist * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127ff2e2f81SFredrik Holmqvist * substantially similar to the "NO WARRANTY" disclaimer below
128ff2e2f81SFredrik Holmqvist * ("Disclaimer") and any redistribution must be conditioned upon
129ff2e2f81SFredrik Holmqvist * including a substantially similar Disclaimer requirement for further
130ff2e2f81SFredrik Holmqvist * binary redistribution.
131ff2e2f81SFredrik Holmqvist * 3. Neither the names of the above-listed copyright holders nor the names
132ff2e2f81SFredrik Holmqvist * of any contributors may be used to endorse or promote products derived
133ff2e2f81SFredrik Holmqvist * from this software without specific prior written permission.
134ff2e2f81SFredrik Holmqvist *
135ff2e2f81SFredrik Holmqvist * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136ff2e2f81SFredrik Holmqvist * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137ff2e2f81SFredrik Holmqvist * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138ff2e2f81SFredrik Holmqvist * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139ff2e2f81SFredrik Holmqvist * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140ff2e2f81SFredrik Holmqvist * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141ff2e2f81SFredrik Holmqvist * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142ff2e2f81SFredrik Holmqvist * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143ff2e2f81SFredrik Holmqvist * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144ff2e2f81SFredrik Holmqvist * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145ff2e2f81SFredrik Holmqvist * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146ff2e2f81SFredrik Holmqvist *
147ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
148ff2e2f81SFredrik Holmqvist * GNU General Public License ("GPL") version 2 as published by the Free
149ff2e2f81SFredrik Holmqvist * Software Foundation.
150ff2e2f81SFredrik Holmqvist *
15174ffd18dSFredrik Holmqvist *****************************************************************************/
15274ffd18dSFredrik Holmqvist
15374ffd18dSFredrik Holmqvist #include "acpi.h"
15474ffd18dSFredrik Holmqvist #include "accommon.h"
15574ffd18dSFredrik Holmqvist #include "acinterp.h"
15674ffd18dSFredrik Holmqvist #include "amlresrc.h"
15774ffd18dSFredrik Holmqvist
15874ffd18dSFredrik Holmqvist
15974ffd18dSFredrik Holmqvist #define _COMPONENT ACPI_EXECUTER
16074ffd18dSFredrik Holmqvist ACPI_MODULE_NAME ("exconcat")
16174ffd18dSFredrik Holmqvist
16274ffd18dSFredrik Holmqvist /* Local Prototypes */
16374ffd18dSFredrik Holmqvist
16474ffd18dSFredrik Holmqvist static ACPI_STATUS
16574ffd18dSFredrik Holmqvist AcpiExConvertToObjectTypeString (
16674ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *ObjDesc,
16774ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT **ResultDesc);
16874ffd18dSFredrik Holmqvist
16974ffd18dSFredrik Holmqvist
17074ffd18dSFredrik Holmqvist /*******************************************************************************
17174ffd18dSFredrik Holmqvist *
17274ffd18dSFredrik Holmqvist * FUNCTION: AcpiExDoConcatenate
17374ffd18dSFredrik Holmqvist *
17474ffd18dSFredrik Holmqvist * PARAMETERS: Operand0 - First source object
17574ffd18dSFredrik Holmqvist * Operand1 - Second source object
17674ffd18dSFredrik Holmqvist * ActualReturnDesc - Where to place the return object
17774ffd18dSFredrik Holmqvist * WalkState - Current walk state
17874ffd18dSFredrik Holmqvist *
17974ffd18dSFredrik Holmqvist * RETURN: Status
18074ffd18dSFredrik Holmqvist *
18174ffd18dSFredrik Holmqvist * DESCRIPTION: Concatenate two objects with the ACPI-defined conversion
18274ffd18dSFredrik Holmqvist * rules as necessary.
18374ffd18dSFredrik Holmqvist * NOTE:
18474ffd18dSFredrik Holmqvist * Per the ACPI spec (up to 6.1), Concatenate only supports Integer,
18574ffd18dSFredrik Holmqvist * String, and Buffer objects. However, we support all objects here
18674ffd18dSFredrik Holmqvist * as an extension. This improves the usefulness of both Concatenate
18774ffd18dSFredrik Holmqvist * and the Printf/Fprintf macros. The extension returns a string
18874ffd18dSFredrik Holmqvist * describing the object type for the other objects.
18974ffd18dSFredrik Holmqvist * 02/2016.
19074ffd18dSFredrik Holmqvist *
19174ffd18dSFredrik Holmqvist ******************************************************************************/
19274ffd18dSFredrik Holmqvist
19374ffd18dSFredrik Holmqvist ACPI_STATUS
AcpiExDoConcatenate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)19474ffd18dSFredrik Holmqvist AcpiExDoConcatenate (
19574ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *Operand0,
19674ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *Operand1,
19774ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT **ActualReturnDesc,
19874ffd18dSFredrik Holmqvist ACPI_WALK_STATE *WalkState)
19974ffd18dSFredrik Holmqvist {
20074ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *LocalOperand0 = Operand0;
20174ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1;
20274ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *TempOperand1 = NULL;
20374ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *ReturnDesc;
20474ffd18dSFredrik Holmqvist char *Buffer;
20574ffd18dSFredrik Holmqvist ACPI_OBJECT_TYPE Operand0Type;
20674ffd18dSFredrik Holmqvist ACPI_OBJECT_TYPE Operand1Type;
20774ffd18dSFredrik Holmqvist ACPI_STATUS Status;
20874ffd18dSFredrik Holmqvist
20974ffd18dSFredrik Holmqvist
21074ffd18dSFredrik Holmqvist ACPI_FUNCTION_TRACE (ExDoConcatenate);
21174ffd18dSFredrik Holmqvist
21274ffd18dSFredrik Holmqvist
21374ffd18dSFredrik Holmqvist /* Operand 0 preprocessing */
21474ffd18dSFredrik Holmqvist
21574ffd18dSFredrik Holmqvist switch (Operand0->Common.Type)
21674ffd18dSFredrik Holmqvist {
21774ffd18dSFredrik Holmqvist case ACPI_TYPE_INTEGER:
21874ffd18dSFredrik Holmqvist case ACPI_TYPE_STRING:
21974ffd18dSFredrik Holmqvist case ACPI_TYPE_BUFFER:
22074ffd18dSFredrik Holmqvist
22174ffd18dSFredrik Holmqvist Operand0Type = Operand0->Common.Type;
22274ffd18dSFredrik Holmqvist break;
22374ffd18dSFredrik Holmqvist
22474ffd18dSFredrik Holmqvist default:
22574ffd18dSFredrik Holmqvist
22674ffd18dSFredrik Holmqvist /* For all other types, get the "object type" string */
22774ffd18dSFredrik Holmqvist
22874ffd18dSFredrik Holmqvist Status = AcpiExConvertToObjectTypeString (
22974ffd18dSFredrik Holmqvist Operand0, &LocalOperand0);
23074ffd18dSFredrik Holmqvist if (ACPI_FAILURE (Status))
23174ffd18dSFredrik Holmqvist {
23274ffd18dSFredrik Holmqvist goto Cleanup;
23374ffd18dSFredrik Holmqvist }
23474ffd18dSFredrik Holmqvist
23574ffd18dSFredrik Holmqvist Operand0Type = ACPI_TYPE_STRING;
23674ffd18dSFredrik Holmqvist break;
23774ffd18dSFredrik Holmqvist }
23874ffd18dSFredrik Holmqvist
23974ffd18dSFredrik Holmqvist /* Operand 1 preprocessing */
24074ffd18dSFredrik Holmqvist
24174ffd18dSFredrik Holmqvist switch (Operand1->Common.Type)
24274ffd18dSFredrik Holmqvist {
24374ffd18dSFredrik Holmqvist case ACPI_TYPE_INTEGER:
24474ffd18dSFredrik Holmqvist case ACPI_TYPE_STRING:
24574ffd18dSFredrik Holmqvist case ACPI_TYPE_BUFFER:
24674ffd18dSFredrik Holmqvist
24774ffd18dSFredrik Holmqvist Operand1Type = Operand1->Common.Type;
24874ffd18dSFredrik Holmqvist break;
24974ffd18dSFredrik Holmqvist
25074ffd18dSFredrik Holmqvist default:
25174ffd18dSFredrik Holmqvist
25274ffd18dSFredrik Holmqvist /* For all other types, get the "object type" string */
25374ffd18dSFredrik Holmqvist
25474ffd18dSFredrik Holmqvist Status = AcpiExConvertToObjectTypeString (
25574ffd18dSFredrik Holmqvist Operand1, &LocalOperand1);
25674ffd18dSFredrik Holmqvist if (ACPI_FAILURE (Status))
25774ffd18dSFredrik Holmqvist {
25874ffd18dSFredrik Holmqvist goto Cleanup;
25974ffd18dSFredrik Holmqvist }
26074ffd18dSFredrik Holmqvist
26174ffd18dSFredrik Holmqvist Operand1Type = ACPI_TYPE_STRING;
26274ffd18dSFredrik Holmqvist break;
26374ffd18dSFredrik Holmqvist }
26474ffd18dSFredrik Holmqvist
26574ffd18dSFredrik Holmqvist /*
26674ffd18dSFredrik Holmqvist * Convert the second operand if necessary. The first operand (0)
26774ffd18dSFredrik Holmqvist * determines the type of the second operand (1) (See the Data Types
26874ffd18dSFredrik Holmqvist * section of the ACPI specification). Both object types are
26974ffd18dSFredrik Holmqvist * guaranteed to be either Integer/String/Buffer by the operand
27074ffd18dSFredrik Holmqvist * resolution mechanism.
27174ffd18dSFredrik Holmqvist */
27274ffd18dSFredrik Holmqvist switch (Operand0Type)
27374ffd18dSFredrik Holmqvist {
27474ffd18dSFredrik Holmqvist case ACPI_TYPE_INTEGER:
27574ffd18dSFredrik Holmqvist
276ff2e2f81SFredrik Holmqvist Status = AcpiExConvertToInteger (LocalOperand1, &TempOperand1,
277ff2e2f81SFredrik Holmqvist ACPI_IMPLICIT_CONVERSION);
27874ffd18dSFredrik Holmqvist break;
27974ffd18dSFredrik Holmqvist
28074ffd18dSFredrik Holmqvist case ACPI_TYPE_BUFFER:
28174ffd18dSFredrik Holmqvist
28274ffd18dSFredrik Holmqvist Status = AcpiExConvertToBuffer (LocalOperand1, &TempOperand1);
28374ffd18dSFredrik Holmqvist break;
28474ffd18dSFredrik Holmqvist
28574ffd18dSFredrik Holmqvist case ACPI_TYPE_STRING:
28674ffd18dSFredrik Holmqvist
28774ffd18dSFredrik Holmqvist switch (Operand1Type)
28874ffd18dSFredrik Holmqvist {
28974ffd18dSFredrik Holmqvist case ACPI_TYPE_INTEGER:
29074ffd18dSFredrik Holmqvist case ACPI_TYPE_STRING:
29174ffd18dSFredrik Holmqvist case ACPI_TYPE_BUFFER:
29274ffd18dSFredrik Holmqvist
29374ffd18dSFredrik Holmqvist /* Other types have already been converted to string */
29474ffd18dSFredrik Holmqvist
29574ffd18dSFredrik Holmqvist Status = AcpiExConvertToString (
29674ffd18dSFredrik Holmqvist LocalOperand1, &TempOperand1, ACPI_IMPLICIT_CONVERT_HEX);
29774ffd18dSFredrik Holmqvist break;
29874ffd18dSFredrik Holmqvist
29974ffd18dSFredrik Holmqvist default:
30074ffd18dSFredrik Holmqvist
30174ffd18dSFredrik Holmqvist Status = AE_OK;
30274ffd18dSFredrik Holmqvist break;
30374ffd18dSFredrik Holmqvist }
30474ffd18dSFredrik Holmqvist break;
30574ffd18dSFredrik Holmqvist
30674ffd18dSFredrik Holmqvist default:
30774ffd18dSFredrik Holmqvist
30874ffd18dSFredrik Holmqvist ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
30974ffd18dSFredrik Holmqvist Operand0->Common.Type));
31074ffd18dSFredrik Holmqvist Status = AE_AML_INTERNAL;
31174ffd18dSFredrik Holmqvist }
31274ffd18dSFredrik Holmqvist
31374ffd18dSFredrik Holmqvist if (ACPI_FAILURE (Status))
31474ffd18dSFredrik Holmqvist {
31574ffd18dSFredrik Holmqvist goto Cleanup;
31674ffd18dSFredrik Holmqvist }
31774ffd18dSFredrik Holmqvist
31874ffd18dSFredrik Holmqvist /* Take care with any newly created operand objects */
31974ffd18dSFredrik Holmqvist
32074ffd18dSFredrik Holmqvist if ((LocalOperand1 != Operand1) &&
32174ffd18dSFredrik Holmqvist (LocalOperand1 != TempOperand1))
32274ffd18dSFredrik Holmqvist {
32374ffd18dSFredrik Holmqvist AcpiUtRemoveReference (LocalOperand1);
32474ffd18dSFredrik Holmqvist }
32574ffd18dSFredrik Holmqvist
32674ffd18dSFredrik Holmqvist LocalOperand1 = TempOperand1;
32774ffd18dSFredrik Holmqvist
32874ffd18dSFredrik Holmqvist /*
32974ffd18dSFredrik Holmqvist * Both operands are now known to be the same object type
33074ffd18dSFredrik Holmqvist * (Both are Integer, String, or Buffer), and we can now perform
33174ffd18dSFredrik Holmqvist * the concatenation.
33274ffd18dSFredrik Holmqvist *
33374ffd18dSFredrik Holmqvist * There are three cases to handle, as per the ACPI spec:
33474ffd18dSFredrik Holmqvist *
33574ffd18dSFredrik Holmqvist * 1) Two Integers concatenated to produce a new Buffer
33674ffd18dSFredrik Holmqvist * 2) Two Strings concatenated to produce a new String
33774ffd18dSFredrik Holmqvist * 3) Two Buffers concatenated to produce a new Buffer
33874ffd18dSFredrik Holmqvist */
33974ffd18dSFredrik Holmqvist switch (Operand0Type)
34074ffd18dSFredrik Holmqvist {
34174ffd18dSFredrik Holmqvist case ACPI_TYPE_INTEGER:
34274ffd18dSFredrik Holmqvist
34374ffd18dSFredrik Holmqvist /* Result of two Integers is a Buffer */
34474ffd18dSFredrik Holmqvist /* Need enough buffer space for two integers */
34574ffd18dSFredrik Holmqvist
34674ffd18dSFredrik Holmqvist ReturnDesc = AcpiUtCreateBufferObject (
34774ffd18dSFredrik Holmqvist (ACPI_SIZE) ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
34874ffd18dSFredrik Holmqvist if (!ReturnDesc)
34974ffd18dSFredrik Holmqvist {
35074ffd18dSFredrik Holmqvist Status = AE_NO_MEMORY;
35174ffd18dSFredrik Holmqvist goto Cleanup;
35274ffd18dSFredrik Holmqvist }
35374ffd18dSFredrik Holmqvist
35474ffd18dSFredrik Holmqvist Buffer = (char *) ReturnDesc->Buffer.Pointer;
35574ffd18dSFredrik Holmqvist
35674ffd18dSFredrik Holmqvist /* Copy the first integer, LSB first */
35774ffd18dSFredrik Holmqvist
35874ffd18dSFredrik Holmqvist memcpy (Buffer, &Operand0->Integer.Value,
35974ffd18dSFredrik Holmqvist AcpiGbl_IntegerByteWidth);
36074ffd18dSFredrik Holmqvist
36174ffd18dSFredrik Holmqvist /* Copy the second integer (LSB first) after the first */
36274ffd18dSFredrik Holmqvist
36374ffd18dSFredrik Holmqvist memcpy (Buffer + AcpiGbl_IntegerByteWidth,
36474ffd18dSFredrik Holmqvist &LocalOperand1->Integer.Value, AcpiGbl_IntegerByteWidth);
36574ffd18dSFredrik Holmqvist break;
36674ffd18dSFredrik Holmqvist
36774ffd18dSFredrik Holmqvist case ACPI_TYPE_STRING:
36874ffd18dSFredrik Holmqvist
36974ffd18dSFredrik Holmqvist /* Result of two Strings is a String */
37074ffd18dSFredrik Holmqvist
37174ffd18dSFredrik Holmqvist ReturnDesc = AcpiUtCreateStringObject (
37274ffd18dSFredrik Holmqvist ((ACPI_SIZE) LocalOperand0->String.Length +
37374ffd18dSFredrik Holmqvist LocalOperand1->String.Length));
37474ffd18dSFredrik Holmqvist if (!ReturnDesc)
37574ffd18dSFredrik Holmqvist {
37674ffd18dSFredrik Holmqvist Status = AE_NO_MEMORY;
37774ffd18dSFredrik Holmqvist goto Cleanup;
37874ffd18dSFredrik Holmqvist }
37974ffd18dSFredrik Holmqvist
38074ffd18dSFredrik Holmqvist Buffer = ReturnDesc->String.Pointer;
38174ffd18dSFredrik Holmqvist
38274ffd18dSFredrik Holmqvist /* Concatenate the strings */
38374ffd18dSFredrik Holmqvist
38474ffd18dSFredrik Holmqvist strcpy (Buffer, LocalOperand0->String.Pointer);
38574ffd18dSFredrik Holmqvist strcat (Buffer, LocalOperand1->String.Pointer);
38674ffd18dSFredrik Holmqvist break;
38774ffd18dSFredrik Holmqvist
38874ffd18dSFredrik Holmqvist case ACPI_TYPE_BUFFER:
38974ffd18dSFredrik Holmqvist
39074ffd18dSFredrik Holmqvist /* Result of two Buffers is a Buffer */
39174ffd18dSFredrik Holmqvist
39274ffd18dSFredrik Holmqvist ReturnDesc = AcpiUtCreateBufferObject (
39374ffd18dSFredrik Holmqvist ((ACPI_SIZE) Operand0->Buffer.Length +
39474ffd18dSFredrik Holmqvist LocalOperand1->Buffer.Length));
39574ffd18dSFredrik Holmqvist if (!ReturnDesc)
39674ffd18dSFredrik Holmqvist {
39774ffd18dSFredrik Holmqvist Status = AE_NO_MEMORY;
39874ffd18dSFredrik Holmqvist goto Cleanup;
39974ffd18dSFredrik Holmqvist }
40074ffd18dSFredrik Holmqvist
40174ffd18dSFredrik Holmqvist Buffer = (char *) ReturnDesc->Buffer.Pointer;
40274ffd18dSFredrik Holmqvist
40374ffd18dSFredrik Holmqvist /* Concatenate the buffers */
40474ffd18dSFredrik Holmqvist
40574ffd18dSFredrik Holmqvist memcpy (Buffer, Operand0->Buffer.Pointer,
40674ffd18dSFredrik Holmqvist Operand0->Buffer.Length);
40774ffd18dSFredrik Holmqvist memcpy (Buffer + Operand0->Buffer.Length,
40874ffd18dSFredrik Holmqvist LocalOperand1->Buffer.Pointer,
40974ffd18dSFredrik Holmqvist LocalOperand1->Buffer.Length);
41074ffd18dSFredrik Holmqvist break;
41174ffd18dSFredrik Holmqvist
41274ffd18dSFredrik Holmqvist default:
41374ffd18dSFredrik Holmqvist
41474ffd18dSFredrik Holmqvist /* Invalid object type, should not happen here */
41574ffd18dSFredrik Holmqvist
41674ffd18dSFredrik Holmqvist ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
41774ffd18dSFredrik Holmqvist Operand0->Common.Type));
41874ffd18dSFredrik Holmqvist Status = AE_AML_INTERNAL;
41974ffd18dSFredrik Holmqvist goto Cleanup;
42074ffd18dSFredrik Holmqvist }
42174ffd18dSFredrik Holmqvist
42274ffd18dSFredrik Holmqvist *ActualReturnDesc = ReturnDesc;
42374ffd18dSFredrik Holmqvist
42474ffd18dSFredrik Holmqvist Cleanup:
42574ffd18dSFredrik Holmqvist if (LocalOperand0 != Operand0)
42674ffd18dSFredrik Holmqvist {
42774ffd18dSFredrik Holmqvist AcpiUtRemoveReference (LocalOperand0);
42874ffd18dSFredrik Holmqvist }
42974ffd18dSFredrik Holmqvist
43074ffd18dSFredrik Holmqvist if (LocalOperand1 != Operand1)
43174ffd18dSFredrik Holmqvist {
43274ffd18dSFredrik Holmqvist AcpiUtRemoveReference (LocalOperand1);
43374ffd18dSFredrik Holmqvist }
43474ffd18dSFredrik Holmqvist
43574ffd18dSFredrik Holmqvist return_ACPI_STATUS (Status);
43674ffd18dSFredrik Holmqvist }
43774ffd18dSFredrik Holmqvist
43874ffd18dSFredrik Holmqvist
43974ffd18dSFredrik Holmqvist /*******************************************************************************
44074ffd18dSFredrik Holmqvist *
44174ffd18dSFredrik Holmqvist * FUNCTION: AcpiExConvertToObjectTypeString
44274ffd18dSFredrik Holmqvist *
44374ffd18dSFredrik Holmqvist * PARAMETERS: ObjDesc - Object to be converted
44474ffd18dSFredrik Holmqvist * ReturnDesc - Where to place the return object
44574ffd18dSFredrik Holmqvist *
44674ffd18dSFredrik Holmqvist * RETURN: Status
44774ffd18dSFredrik Holmqvist *
44874ffd18dSFredrik Holmqvist * DESCRIPTION: Convert an object of arbitrary type to a string object that
44974ffd18dSFredrik Holmqvist * contains the namestring for the object. Used for the
45074ffd18dSFredrik Holmqvist * concatenate operator.
45174ffd18dSFredrik Holmqvist *
45274ffd18dSFredrik Holmqvist ******************************************************************************/
45374ffd18dSFredrik Holmqvist
45474ffd18dSFredrik Holmqvist static ACPI_STATUS
AcpiExConvertToObjectTypeString(ACPI_OPERAND_OBJECT * ObjDesc,ACPI_OPERAND_OBJECT ** ResultDesc)45574ffd18dSFredrik Holmqvist AcpiExConvertToObjectTypeString (
45674ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *ObjDesc,
45774ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT **ResultDesc)
45874ffd18dSFredrik Holmqvist {
45974ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *ReturnDesc;
46074ffd18dSFredrik Holmqvist const char *TypeString;
46174ffd18dSFredrik Holmqvist
46274ffd18dSFredrik Holmqvist
46374ffd18dSFredrik Holmqvist TypeString = AcpiUtGetTypeName (ObjDesc->Common.Type);
46474ffd18dSFredrik Holmqvist
46574ffd18dSFredrik Holmqvist ReturnDesc = AcpiUtCreateStringObject (
46674ffd18dSFredrik Holmqvist ((ACPI_SIZE) strlen (TypeString) + 9)); /* 9 For "[ Object]" */
46774ffd18dSFredrik Holmqvist if (!ReturnDesc)
46874ffd18dSFredrik Holmqvist {
46974ffd18dSFredrik Holmqvist return (AE_NO_MEMORY);
47074ffd18dSFredrik Holmqvist }
47174ffd18dSFredrik Holmqvist
47274ffd18dSFredrik Holmqvist strcpy (ReturnDesc->String.Pointer, "[");
47374ffd18dSFredrik Holmqvist strcat (ReturnDesc->String.Pointer, TypeString);
47474ffd18dSFredrik Holmqvist strcat (ReturnDesc->String.Pointer, " Object]");
47574ffd18dSFredrik Holmqvist
47674ffd18dSFredrik Holmqvist *ResultDesc = ReturnDesc;
47774ffd18dSFredrik Holmqvist return (AE_OK);
47874ffd18dSFredrik Holmqvist }
47974ffd18dSFredrik Holmqvist
48074ffd18dSFredrik Holmqvist
48174ffd18dSFredrik Holmqvist /*******************************************************************************
48274ffd18dSFredrik Holmqvist *
48374ffd18dSFredrik Holmqvist * FUNCTION: AcpiExConcatTemplate
48474ffd18dSFredrik Holmqvist *
48574ffd18dSFredrik Holmqvist * PARAMETERS: Operand0 - First source object
48674ffd18dSFredrik Holmqvist * Operand1 - Second source object
48774ffd18dSFredrik Holmqvist * ActualReturnDesc - Where to place the return object
48874ffd18dSFredrik Holmqvist * WalkState - Current walk state
48974ffd18dSFredrik Holmqvist *
49074ffd18dSFredrik Holmqvist * RETURN: Status
49174ffd18dSFredrik Holmqvist *
49274ffd18dSFredrik Holmqvist * DESCRIPTION: Concatenate two resource templates
49374ffd18dSFredrik Holmqvist *
49474ffd18dSFredrik Holmqvist ******************************************************************************/
49574ffd18dSFredrik Holmqvist
49674ffd18dSFredrik Holmqvist ACPI_STATUS
AcpiExConcatTemplate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)49774ffd18dSFredrik Holmqvist AcpiExConcatTemplate (
49874ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *Operand0,
49974ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *Operand1,
50074ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT **ActualReturnDesc,
50174ffd18dSFredrik Holmqvist ACPI_WALK_STATE *WalkState)
50274ffd18dSFredrik Holmqvist {
50374ffd18dSFredrik Holmqvist ACPI_STATUS Status;
50474ffd18dSFredrik Holmqvist ACPI_OPERAND_OBJECT *ReturnDesc;
50574ffd18dSFredrik Holmqvist UINT8 *NewBuf;
50674ffd18dSFredrik Holmqvist UINT8 *EndTag;
50774ffd18dSFredrik Holmqvist ACPI_SIZE Length0;
50874ffd18dSFredrik Holmqvist ACPI_SIZE Length1;
50974ffd18dSFredrik Holmqvist ACPI_SIZE NewLength;
51074ffd18dSFredrik Holmqvist
51174ffd18dSFredrik Holmqvist
51274ffd18dSFredrik Holmqvist ACPI_FUNCTION_TRACE (ExConcatTemplate);
51374ffd18dSFredrik Holmqvist
51474ffd18dSFredrik Holmqvist
51574ffd18dSFredrik Holmqvist /*
51674ffd18dSFredrik Holmqvist * Find the EndTag descriptor in each resource template.
51774ffd18dSFredrik Holmqvist * Note1: returned pointers point TO the EndTag, not past it.
51874ffd18dSFredrik Holmqvist * Note2: zero-length buffers are allowed; treated like one EndTag
51974ffd18dSFredrik Holmqvist */
52074ffd18dSFredrik Holmqvist
52174ffd18dSFredrik Holmqvist /* Get the length of the first resource template */
52274ffd18dSFredrik Holmqvist
52374ffd18dSFredrik Holmqvist Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
52474ffd18dSFredrik Holmqvist if (ACPI_FAILURE (Status))
52574ffd18dSFredrik Holmqvist {
52674ffd18dSFredrik Holmqvist return_ACPI_STATUS (Status);
52774ffd18dSFredrik Holmqvist }
52874ffd18dSFredrik Holmqvist
52974ffd18dSFredrik Holmqvist Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
53074ffd18dSFredrik Holmqvist
53174ffd18dSFredrik Holmqvist /* Get the length of the second resource template */
53274ffd18dSFredrik Holmqvist
53374ffd18dSFredrik Holmqvist Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
53474ffd18dSFredrik Holmqvist if (ACPI_FAILURE (Status))
53574ffd18dSFredrik Holmqvist {
53674ffd18dSFredrik Holmqvist return_ACPI_STATUS (Status);
53774ffd18dSFredrik Holmqvist }
53874ffd18dSFredrik Holmqvist
53974ffd18dSFredrik Holmqvist Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
54074ffd18dSFredrik Holmqvist
54174ffd18dSFredrik Holmqvist /* Combine both lengths, minimum size will be 2 for EndTag */
54274ffd18dSFredrik Holmqvist
54374ffd18dSFredrik Holmqvist NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
54474ffd18dSFredrik Holmqvist
54574ffd18dSFredrik Holmqvist /* Create a new buffer object for the result (with one EndTag) */
54674ffd18dSFredrik Holmqvist
54774ffd18dSFredrik Holmqvist ReturnDesc = AcpiUtCreateBufferObject (NewLength);
54874ffd18dSFredrik Holmqvist if (!ReturnDesc)
54974ffd18dSFredrik Holmqvist {
55074ffd18dSFredrik Holmqvist return_ACPI_STATUS (AE_NO_MEMORY);
55174ffd18dSFredrik Holmqvist }
55274ffd18dSFredrik Holmqvist
55374ffd18dSFredrik Holmqvist /*
55474ffd18dSFredrik Holmqvist * Copy the templates to the new buffer, 0 first, then 1 follows. One
55574ffd18dSFredrik Holmqvist * EndTag descriptor is copied from Operand1.
55674ffd18dSFredrik Holmqvist */
55774ffd18dSFredrik Holmqvist NewBuf = ReturnDesc->Buffer.Pointer;
55874ffd18dSFredrik Holmqvist memcpy (NewBuf, Operand0->Buffer.Pointer, Length0);
55974ffd18dSFredrik Holmqvist memcpy (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
56074ffd18dSFredrik Holmqvist
56174ffd18dSFredrik Holmqvist /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
56274ffd18dSFredrik Holmqvist
56374ffd18dSFredrik Holmqvist NewBuf[NewLength - 1] = 0;
56474ffd18dSFredrik Holmqvist NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
56574ffd18dSFredrik Holmqvist
56674ffd18dSFredrik Holmqvist /* Return the completed resource template */
56774ffd18dSFredrik Holmqvist
56874ffd18dSFredrik Holmqvist *ActualReturnDesc = ReturnDesc;
56974ffd18dSFredrik Holmqvist return_ACPI_STATUS (AE_OK);
57074ffd18dSFredrik Holmqvist }
571