^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: exconcat - Concatenate-type AML operators
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "acinterp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "amlresrc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define _COMPONENT ACPI_EXECUTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) ACPI_MODULE_NAME("exconcat")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* Local Prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) union acpi_operand_object **result_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * FUNCTION: acpi_ex_do_concatenate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * PARAMETERS: operand0 - First source object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * operand1 - Second source object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * actual_return_desc - Where to place the return object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * walk_state - Current walk state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * DESCRIPTION: Concatenate two objects with the ACPI-defined conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * rules as necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Per the ACPI spec (up to 6.1), Concatenate only supports Integer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * String, and Buffer objects. However, we support all objects here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * as an extension. This improves the usefulness of both Concatenate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * and the Printf/Fprintf macros. The extension returns a string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * describing the object type for the other objects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * 02/2016.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) acpi_ex_do_concatenate(union acpi_operand_object *operand0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) union acpi_operand_object *operand1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) union acpi_operand_object **actual_return_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct acpi_walk_state *walk_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) union acpi_operand_object *local_operand0 = operand0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) union acpi_operand_object *local_operand1 = operand1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) union acpi_operand_object *temp_operand1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) union acpi_operand_object *return_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) acpi_object_type operand0_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) acpi_object_type operand1_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ACPI_FUNCTION_TRACE(ex_do_concatenate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Operand 0 preprocessing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) switch (operand0->common.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case ACPI_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case ACPI_TYPE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) operand0_type = operand0->common.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* For all other types, get the "object type" string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) acpi_ex_convert_to_object_type_string(operand0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) &local_operand0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) operand0_type = ACPI_TYPE_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Operand 1 preprocessing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) switch (operand1->common.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case ACPI_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case ACPI_TYPE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) operand1_type = operand1->common.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* For all other types, get the "object type" string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) acpi_ex_convert_to_object_type_string(operand1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) &local_operand1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) operand1_type = ACPI_TYPE_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * Convert the second operand if necessary. The first operand (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * determines the type of the second operand (1) (See the Data Types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * section of the ACPI specification). Both object types are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * guaranteed to be either Integer/String/Buffer by the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * resolution mechanism.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) switch (operand0_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) acpi_ex_convert_to_integer(local_operand1, &temp_operand1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ACPI_IMPLICIT_CONVERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case ACPI_TYPE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) acpi_ex_convert_to_buffer(local_operand1, &temp_operand1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case ACPI_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) switch (operand1_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case ACPI_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case ACPI_TYPE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Other types have already been converted to string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) acpi_ex_convert_to_string(local_operand1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) &temp_operand1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ACPI_IMPLICIT_CONVERT_HEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) operand0->common.type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) status = AE_AML_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Take care with any newly created operand objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if ((local_operand1 != operand1) && (local_operand1 != temp_operand1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) acpi_ut_remove_reference(local_operand1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) local_operand1 = temp_operand1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Both operands are now known to be the same object type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * (Both are Integer, String, or Buffer), and we can now perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * the concatenation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * There are three cases to handle, as per the ACPI spec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * 1) Two Integers concatenated to produce a new Buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * 2) Two Strings concatenated to produce a new String
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * 3) Two Buffers concatenated to produce a new Buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) switch (operand0_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Result of two Integers is a Buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Need enough buffer space for two integers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return_desc = acpi_ut_create_buffer_object((acpi_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ACPI_MUL_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) (acpi_gbl_integer_byte_width));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) buffer = (char *)return_desc->buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Copy the first integer, LSB first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) memcpy(buffer, &operand0->integer.value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) acpi_gbl_integer_byte_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Copy the second integer (LSB first) after the first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) memcpy(buffer + acpi_gbl_integer_byte_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) &local_operand1->integer.value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) acpi_gbl_integer_byte_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case ACPI_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* Result of two Strings is a String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return_desc = acpi_ut_create_string_object(((acpi_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) local_operand0->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) string.length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) local_operand1->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) string.length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) buffer = return_desc->string.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Concatenate the strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) strcpy(buffer, local_operand0->string.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) strcat(buffer, local_operand1->string.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case ACPI_TYPE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Result of two Buffers is a Buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return_desc = acpi_ut_create_buffer_object(((acpi_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) operand0->buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) local_operand1->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) buffer.length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) buffer = (char *)return_desc->buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Concatenate the buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) memcpy(buffer, operand0->buffer.pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) operand0->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) memcpy(buffer + operand0->buffer.length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) local_operand1->buffer.pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) local_operand1->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Invalid object type, should not happen here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) operand0->common.type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) status = AE_AML_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *actual_return_desc = return_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (local_operand0 != operand0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) acpi_ut_remove_reference(local_operand0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (local_operand1 != operand1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) acpi_ut_remove_reference(local_operand1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * FUNCTION: acpi_ex_convert_to_object_type_string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * PARAMETERS: obj_desc - Object to be converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * return_desc - Where to place the return object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * DESCRIPTION: Convert an object of arbitrary type to a string object that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * contains the namestring for the object. Used for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * concatenate operator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) union acpi_operand_object **result_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) union acpi_operand_object *return_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) const char *type_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) type_string = acpi_ut_get_type_name(obj_desc->common.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return_desc = acpi_ut_create_string_object(((acpi_size)strlen(type_string) + 9)); /* 9 For "[ Object]" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (!return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return (AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) strcpy(return_desc->string.pointer, "[");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) strcat(return_desc->string.pointer, type_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) strcat(return_desc->string.pointer, " Object]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) *result_desc = return_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * FUNCTION: acpi_ex_concat_template
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * PARAMETERS: operand0 - First source object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * operand1 - Second source object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * actual_return_desc - Where to place the return object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * walk_state - Current walk state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * DESCRIPTION: Concatenate two resource templates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) acpi_ex_concat_template(union acpi_operand_object *operand0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) union acpi_operand_object *operand1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) union acpi_operand_object **actual_return_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct acpi_walk_state *walk_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) union acpi_operand_object *return_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) u8 *new_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u8 *end_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) acpi_size length0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) acpi_size length1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) acpi_size new_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ACPI_FUNCTION_TRACE(ex_concat_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * Find the end_tag descriptor in each resource template.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Note1: returned pointers point TO the end_tag, not past it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Note2: zero-length buffers are allowed; treated like one end_tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Get the length of the first resource template */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* Get the length of the second resource template */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Combine both lengths, minimum size will be 2 for end_tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* Create a new buffer object for the result (with one end_tag) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return_desc = acpi_ut_create_buffer_object(new_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return_ACPI_STATUS(AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * Copy the templates to the new buffer, 0 first, then 1 follows. One
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * end_tag descriptor is copied from Operand1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) new_buf = return_desc->buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) memcpy(new_buf, operand0->buffer.pointer, length0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) memcpy(new_buf + length0, operand1->buffer.pointer, length1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Insert end_tag and set the checksum to zero, means "ignore checksum" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) new_buf[new_length - 1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* Return the completed resource template */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) *actual_return_desc = return_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }