0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acinterp.h"
0013 #include "amlresrc.h"
0014
0015 #define _COMPONENT ACPI_EXECUTER
0016 ACPI_MODULE_NAME("exconcat")
0017
0018
0019 static acpi_status
0020 acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
0021 union acpi_operand_object **result_desc);
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 acpi_status
0047 acpi_ex_do_concatenate(union acpi_operand_object *operand0,
0048 union acpi_operand_object *operand1,
0049 union acpi_operand_object **actual_return_desc,
0050 struct acpi_walk_state *walk_state)
0051 {
0052 union acpi_operand_object *local_operand0 = operand0;
0053 union acpi_operand_object *local_operand1 = operand1;
0054 union acpi_operand_object *temp_operand1 = NULL;
0055 union acpi_operand_object *return_desc;
0056 char *buffer;
0057 acpi_object_type operand0_type;
0058 acpi_object_type operand1_type;
0059 acpi_status status;
0060
0061 ACPI_FUNCTION_TRACE(ex_do_concatenate);
0062
0063
0064
0065 switch (operand0->common.type) {
0066 case ACPI_TYPE_INTEGER:
0067 case ACPI_TYPE_STRING:
0068 case ACPI_TYPE_BUFFER:
0069
0070 operand0_type = operand0->common.type;
0071 break;
0072
0073 default:
0074
0075
0076
0077 status =
0078 acpi_ex_convert_to_object_type_string(operand0,
0079 &local_operand0);
0080 if (ACPI_FAILURE(status)) {
0081 goto cleanup;
0082 }
0083
0084 operand0_type = ACPI_TYPE_STRING;
0085 break;
0086 }
0087
0088
0089
0090 switch (operand1->common.type) {
0091 case ACPI_TYPE_INTEGER:
0092 case ACPI_TYPE_STRING:
0093 case ACPI_TYPE_BUFFER:
0094
0095 operand1_type = operand1->common.type;
0096 break;
0097
0098 default:
0099
0100
0101
0102 status =
0103 acpi_ex_convert_to_object_type_string(operand1,
0104 &local_operand1);
0105 if (ACPI_FAILURE(status)) {
0106 goto cleanup;
0107 }
0108
0109 operand1_type = ACPI_TYPE_STRING;
0110 break;
0111 }
0112
0113
0114
0115
0116
0117
0118
0119
0120 switch (operand0_type) {
0121 case ACPI_TYPE_INTEGER:
0122
0123 status =
0124 acpi_ex_convert_to_integer(local_operand1, &temp_operand1,
0125 ACPI_IMPLICIT_CONVERSION);
0126 break;
0127
0128 case ACPI_TYPE_BUFFER:
0129
0130 status =
0131 acpi_ex_convert_to_buffer(local_operand1, &temp_operand1);
0132 break;
0133
0134 case ACPI_TYPE_STRING:
0135
0136 switch (operand1_type) {
0137 case ACPI_TYPE_INTEGER:
0138 case ACPI_TYPE_STRING:
0139 case ACPI_TYPE_BUFFER:
0140
0141
0142
0143 status =
0144 acpi_ex_convert_to_string(local_operand1,
0145 &temp_operand1,
0146 ACPI_IMPLICIT_CONVERT_HEX);
0147 break;
0148
0149 default:
0150
0151 status = AE_OK;
0152 break;
0153 }
0154 break;
0155
0156 default:
0157
0158 ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
0159 operand0->common.type));
0160 status = AE_AML_INTERNAL;
0161 }
0162
0163 if (ACPI_FAILURE(status)) {
0164 goto cleanup;
0165 }
0166
0167
0168
0169 if ((local_operand1 != operand1) && (local_operand1 != temp_operand1)) {
0170 acpi_ut_remove_reference(local_operand1);
0171 }
0172
0173 local_operand1 = temp_operand1;
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186 switch (operand0_type) {
0187 case ACPI_TYPE_INTEGER:
0188
0189
0190
0191
0192 return_desc = acpi_ut_create_buffer_object((acpi_size)
0193 ACPI_MUL_2
0194 (acpi_gbl_integer_byte_width));
0195 if (!return_desc) {
0196 status = AE_NO_MEMORY;
0197 goto cleanup;
0198 }
0199
0200 buffer = (char *)return_desc->buffer.pointer;
0201
0202
0203
0204 memcpy(buffer, &operand0->integer.value,
0205 acpi_gbl_integer_byte_width);
0206
0207
0208
0209 memcpy(buffer + acpi_gbl_integer_byte_width,
0210 &local_operand1->integer.value,
0211 acpi_gbl_integer_byte_width);
0212 break;
0213
0214 case ACPI_TYPE_STRING:
0215
0216
0217
0218 return_desc = acpi_ut_create_string_object(((acpi_size)
0219 local_operand0->
0220 string.length +
0221 local_operand1->
0222 string.length));
0223 if (!return_desc) {
0224 status = AE_NO_MEMORY;
0225 goto cleanup;
0226 }
0227
0228 buffer = return_desc->string.pointer;
0229
0230
0231
0232 strcpy(buffer, local_operand0->string.pointer);
0233 strcat(buffer, local_operand1->string.pointer);
0234 break;
0235
0236 case ACPI_TYPE_BUFFER:
0237
0238
0239
0240 return_desc = acpi_ut_create_buffer_object(((acpi_size)
0241 operand0->buffer.
0242 length +
0243 local_operand1->
0244 buffer.length));
0245 if (!return_desc) {
0246 status = AE_NO_MEMORY;
0247 goto cleanup;
0248 }
0249
0250 buffer = (char *)return_desc->buffer.pointer;
0251
0252
0253
0254 memcpy(buffer, operand0->buffer.pointer,
0255 operand0->buffer.length);
0256 memcpy(buffer + operand0->buffer.length,
0257 local_operand1->buffer.pointer,
0258 local_operand1->buffer.length);
0259 break;
0260
0261 default:
0262
0263
0264
0265 ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
0266 operand0->common.type));
0267 status = AE_AML_INTERNAL;
0268 goto cleanup;
0269 }
0270
0271 *actual_return_desc = return_desc;
0272
0273 cleanup:
0274 if (local_operand0 != operand0) {
0275 acpi_ut_remove_reference(local_operand0);
0276 }
0277
0278 if (local_operand1 != operand1) {
0279 acpi_ut_remove_reference(local_operand1);
0280 }
0281
0282 return_ACPI_STATUS(status);
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 static acpi_status
0301 acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
0302 union acpi_operand_object **result_desc)
0303 {
0304 union acpi_operand_object *return_desc;
0305 const char *type_string;
0306
0307 type_string = acpi_ut_get_type_name(obj_desc->common.type);
0308
0309 return_desc = acpi_ut_create_string_object(((acpi_size)strlen(type_string) + 9));
0310 if (!return_desc) {
0311 return (AE_NO_MEMORY);
0312 }
0313
0314 strcpy(return_desc->string.pointer, "[");
0315 strcat(return_desc->string.pointer, type_string);
0316 strcat(return_desc->string.pointer, " Object]");
0317
0318 *result_desc = return_desc;
0319 return (AE_OK);
0320 }
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 acpi_status
0338 acpi_ex_concat_template(union acpi_operand_object *operand0,
0339 union acpi_operand_object *operand1,
0340 union acpi_operand_object **actual_return_desc,
0341 struct acpi_walk_state *walk_state)
0342 {
0343 acpi_status status;
0344 union acpi_operand_object *return_desc;
0345 u8 *new_buf;
0346 u8 *end_tag;
0347 acpi_size length0;
0348 acpi_size length1;
0349 acpi_size new_length;
0350
0351 ACPI_FUNCTION_TRACE(ex_concat_template);
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
0362 if (ACPI_FAILURE(status)) {
0363 return_ACPI_STATUS(status);
0364 }
0365
0366 length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
0367
0368
0369
0370 status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
0371 if (ACPI_FAILURE(status)) {
0372 return_ACPI_STATUS(status);
0373 }
0374
0375 length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
0376
0377
0378
0379 new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
0380
0381
0382
0383 return_desc = acpi_ut_create_buffer_object(new_length);
0384 if (!return_desc) {
0385 return_ACPI_STATUS(AE_NO_MEMORY);
0386 }
0387
0388
0389
0390
0391
0392 new_buf = return_desc->buffer.pointer;
0393 memcpy(new_buf, operand0->buffer.pointer, length0);
0394 memcpy(new_buf + length0, operand1->buffer.pointer, length1);
0395
0396
0397
0398 new_buf[new_length - 1] = 0;
0399 new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
0400
0401
0402
0403 *actual_return_desc = return_desc;
0404 return_ACPI_STATUS(AE_OK);
0405 }