0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acinterp.h"
0013 #include "amlcode.h"
0014
0015 #define _COMPONENT ACPI_EXECUTER
0016 ACPI_MODULE_NAME("exconvrt")
0017
0018
0019 static u32
0020 acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length);
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 acpi_status
0038 acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
0039 union acpi_operand_object **result_desc,
0040 u32 implicit_conversion)
0041 {
0042 union acpi_operand_object *return_desc;
0043 u8 *pointer;
0044 u64 result;
0045 u32 i;
0046 u32 count;
0047
0048 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
0049
0050 switch (obj_desc->common.type) {
0051 case ACPI_TYPE_INTEGER:
0052
0053
0054
0055 *result_desc = obj_desc;
0056 return_ACPI_STATUS(AE_OK);
0057
0058 case ACPI_TYPE_BUFFER:
0059 case ACPI_TYPE_STRING:
0060
0061
0062
0063 pointer = obj_desc->buffer.pointer;
0064 count = obj_desc->buffer.length;
0065 break;
0066
0067 default:
0068
0069 return_ACPI_STATUS(AE_TYPE);
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 result = 0;
0082
0083
0084
0085 switch (obj_desc->common.type) {
0086 case ACPI_TYPE_STRING:
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 if (implicit_conversion) {
0097 result =
0098 acpi_ut_implicit_strtoul64(ACPI_CAST_PTR
0099 (char, pointer));
0100 } else {
0101 result =
0102 acpi_ut_explicit_strtoul64(ACPI_CAST_PTR
0103 (char, pointer));
0104 }
0105 break;
0106
0107 case ACPI_TYPE_BUFFER:
0108
0109
0110
0111 if (!count) {
0112 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
0113 }
0114
0115
0116
0117 if (count > acpi_gbl_integer_byte_width) {
0118 count = acpi_gbl_integer_byte_width;
0119 }
0120
0121
0122
0123
0124
0125 for (i = 0; i < count; i++) {
0126
0127
0128
0129
0130
0131 result |= (((u64) pointer[i]) << (i * 8));
0132 }
0133 break;
0134
0135 default:
0136
0137
0138
0139 break;
0140 }
0141
0142
0143
0144 return_desc = acpi_ut_create_integer_object(result);
0145 if (!return_desc) {
0146 return_ACPI_STATUS(AE_NO_MEMORY);
0147 }
0148
0149 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
0150 ACPI_FORMAT_UINT64(result)));
0151
0152
0153
0154 (void)acpi_ex_truncate_for32bit_table(return_desc);
0155 *result_desc = return_desc;
0156 return_ACPI_STATUS(AE_OK);
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 acpi_status
0174 acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
0175 union acpi_operand_object **result_desc)
0176 {
0177 union acpi_operand_object *return_desc;
0178 u8 *new_buf;
0179
0180 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
0181
0182 switch (obj_desc->common.type) {
0183 case ACPI_TYPE_BUFFER:
0184
0185
0186
0187 *result_desc = obj_desc;
0188 return_ACPI_STATUS(AE_OK);
0189
0190 case ACPI_TYPE_INTEGER:
0191
0192
0193
0194
0195 return_desc =
0196 acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
0197 if (!return_desc) {
0198 return_ACPI_STATUS(AE_NO_MEMORY);
0199 }
0200
0201
0202
0203 new_buf = return_desc->buffer.pointer;
0204 memcpy(new_buf, &obj_desc->integer.value,
0205 acpi_gbl_integer_byte_width);
0206 break;
0207
0208 case ACPI_TYPE_STRING:
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 return_desc = acpi_ut_create_buffer_object((acpi_size)
0219 obj_desc->string.
0220 length + 1);
0221 if (!return_desc) {
0222 return_ACPI_STATUS(AE_NO_MEMORY);
0223 }
0224
0225
0226
0227 new_buf = return_desc->buffer.pointer;
0228 strncpy((char *)new_buf, (char *)obj_desc->string.pointer,
0229 obj_desc->string.length);
0230 break;
0231
0232 default:
0233
0234 return_ACPI_STATUS(AE_TYPE);
0235 }
0236
0237
0238
0239 return_desc->common.flags |= AOPOBJ_DATA_VALID;
0240 *result_desc = return_desc;
0241 return_ACPI_STATUS(AE_OK);
0242 }
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 static u32
0260 acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
0261 {
0262 u64 digit;
0263 u32 i;
0264 u32 j;
0265 u32 k = 0;
0266 u32 hex_length;
0267 u32 decimal_length;
0268 u32 remainder;
0269 u8 supress_zeros;
0270
0271 ACPI_FUNCTION_ENTRY();
0272
0273 switch (base) {
0274 case 10:
0275
0276
0277
0278 switch (data_width) {
0279 case 1:
0280
0281 decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
0282 break;
0283
0284 case 4:
0285
0286 decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
0287 break;
0288
0289 case 8:
0290 default:
0291
0292 decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
0293 break;
0294 }
0295
0296 supress_zeros = TRUE;
0297 remainder = 0;
0298
0299 for (i = decimal_length; i > 0; i--) {
0300
0301
0302
0303 digit = integer;
0304 for (j = 0; j < i; j++) {
0305 (void)acpi_ut_short_divide(digit, 10, &digit,
0306 &remainder);
0307 }
0308
0309
0310
0311 if (remainder != 0) {
0312 supress_zeros = FALSE;
0313 }
0314
0315 if (!supress_zeros) {
0316 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
0317 k++;
0318 }
0319 }
0320 break;
0321
0322 case 16:
0323
0324
0325
0326 hex_length = (data_width * 2);
0327 for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
0328
0329
0330
0331 string[k] = (u8)
0332 acpi_ut_hex_to_ascii_char(integer, ACPI_MUL_4(j));
0333 k++;
0334 }
0335 break;
0336
0337 default:
0338 return (0);
0339 }
0340
0341
0342
0343
0344
0345
0346
0347 if (!k) {
0348 string[0] = ACPI_ASCII_ZERO;
0349 k = 1;
0350 }
0351
0352 string[k] = 0;
0353 return ((u32) k);
0354 }
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372 acpi_status
0373 acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
0374 union acpi_operand_object ** result_desc, u32 type)
0375 {
0376 union acpi_operand_object *return_desc;
0377 u8 *new_buf;
0378 u32 i;
0379 u32 string_length = 0;
0380 u16 base = 16;
0381 u8 separator = ',';
0382
0383 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
0384
0385 switch (obj_desc->common.type) {
0386 case ACPI_TYPE_STRING:
0387
0388
0389
0390 *result_desc = obj_desc;
0391 return_ACPI_STATUS(AE_OK);
0392
0393 case ACPI_TYPE_INTEGER:
0394
0395 switch (type) {
0396 case ACPI_EXPLICIT_CONVERT_DECIMAL:
0397
0398
0399
0400
0401
0402 string_length = ACPI_MAX_DECIMAL_DIGITS;
0403 base = 10;
0404 break;
0405
0406 default:
0407
0408
0409
0410 string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
0411 break;
0412 }
0413
0414
0415
0416
0417
0418 return_desc =
0419 acpi_ut_create_string_object((acpi_size)string_length);
0420 if (!return_desc) {
0421 return_ACPI_STATUS(AE_NO_MEMORY);
0422 }
0423
0424 new_buf = return_desc->buffer.pointer;
0425
0426
0427
0428 string_length =
0429 acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
0430 new_buf,
0431 acpi_gbl_integer_byte_width);
0432
0433
0434
0435 return_desc->string.length = string_length;
0436 new_buf[string_length] = 0;
0437 break;
0438
0439 case ACPI_TYPE_BUFFER:
0440
0441
0442
0443 switch (type) {
0444 case ACPI_EXPLICIT_CONVERT_DECIMAL:
0445
0446
0447
0448
0449
0450
0451 base = 10;
0452
0453
0454
0455
0456
0457 for (i = 0; i < obj_desc->buffer.length; i++) {
0458 if (obj_desc->buffer.pointer[i] >= 100) {
0459 string_length += 4;
0460 } else if (obj_desc->buffer.pointer[i] >= 10) {
0461 string_length += 3;
0462 } else {
0463 string_length += 2;
0464 }
0465 }
0466 break;
0467
0468 case ACPI_IMPLICIT_CONVERT_HEX:
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478 separator = ' ';
0479 string_length = (obj_desc->buffer.length * 5);
0480 break;
0481
0482 case ACPI_EXPLICIT_CONVERT_HEX:
0483
0484
0485
0486
0487
0488
0489
0490
0491 separator = ',';
0492 string_length = (obj_desc->buffer.length * 5);
0493 break;
0494
0495 default:
0496 return_ACPI_STATUS(AE_BAD_PARAMETER);
0497 }
0498
0499
0500
0501
0502
0503
0504 if (string_length) {
0505 string_length--;
0506 }
0507
0508 return_desc =
0509 acpi_ut_create_string_object((acpi_size)string_length);
0510 if (!return_desc) {
0511 return_ACPI_STATUS(AE_NO_MEMORY);
0512 }
0513
0514 new_buf = return_desc->buffer.pointer;
0515
0516
0517
0518
0519
0520 for (i = 0; i < obj_desc->buffer.length; i++) {
0521 if (base == 16) {
0522
0523
0524
0525 *new_buf++ = '0';
0526 *new_buf++ = 'x';
0527 }
0528
0529 new_buf += acpi_ex_convert_to_ascii((u64) obj_desc->
0530 buffer.pointer[i],
0531 base, new_buf, 1);
0532
0533
0534
0535 *new_buf++ = separator;
0536 }
0537
0538
0539
0540
0541
0542 if (obj_desc->buffer.length) {
0543 new_buf--;
0544 }
0545 *new_buf = 0;
0546 break;
0547
0548 default:
0549
0550 return_ACPI_STATUS(AE_TYPE);
0551 }
0552
0553 *result_desc = return_desc;
0554 return_ACPI_STATUS(AE_OK);
0555 }
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 acpi_status
0573 acpi_ex_convert_to_target_type(acpi_object_type destination_type,
0574 union acpi_operand_object *source_desc,
0575 union acpi_operand_object **result_desc,
0576 struct acpi_walk_state *walk_state)
0577 {
0578 acpi_status status = AE_OK;
0579
0580 ACPI_FUNCTION_TRACE(ex_convert_to_target_type);
0581
0582
0583
0584 *result_desc = source_desc;
0585
0586
0587
0588
0589
0590 switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
0591 case ARGI_SIMPLE_TARGET:
0592 case ARGI_FIXED_TARGET:
0593 case ARGI_INTEGER_REF:
0594
0595 switch (destination_type) {
0596 case ACPI_TYPE_LOCAL_REGION_FIELD:
0597
0598
0599
0600 break;
0601
0602 default:
0603
0604
0605
0606 if (destination_type != source_desc->common.type) {
0607 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0608 "Explicit operator, will store (%s) over existing type (%s)\n",
0609 acpi_ut_get_object_type_name
0610 (source_desc),
0611 acpi_ut_get_type_name
0612 (destination_type)));
0613 status = AE_TYPE;
0614 }
0615 }
0616 break;
0617
0618 case ARGI_TARGETREF:
0619 case ARGI_STORE_TARGET:
0620
0621 switch (destination_type) {
0622 case ACPI_TYPE_INTEGER:
0623 case ACPI_TYPE_BUFFER_FIELD:
0624 case ACPI_TYPE_LOCAL_BANK_FIELD:
0625 case ACPI_TYPE_LOCAL_INDEX_FIELD:
0626
0627
0628
0629
0630 status =
0631 acpi_ex_convert_to_integer(source_desc, result_desc,
0632 ACPI_IMPLICIT_CONVERSION);
0633 break;
0634
0635 case ACPI_TYPE_STRING:
0636
0637
0638
0639
0640 status =
0641 acpi_ex_convert_to_string(source_desc, result_desc,
0642 ACPI_IMPLICIT_CONVERT_HEX);
0643 break;
0644
0645 case ACPI_TYPE_BUFFER:
0646
0647
0648
0649
0650 status =
0651 acpi_ex_convert_to_buffer(source_desc, result_desc);
0652 break;
0653
0654 default:
0655
0656 ACPI_ERROR((AE_INFO,
0657 "Bad destination type during conversion: 0x%X",
0658 destination_type));
0659 status = AE_AML_INTERNAL;
0660 break;
0661 }
0662 break;
0663
0664 case ARGI_REFERENCE:
0665
0666
0667
0668 break;
0669
0670 default:
0671
0672 ACPI_ERROR((AE_INFO,
0673 "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
0674 GET_CURRENT_ARG_TYPE(walk_state->op_info->
0675 runtime_args),
0676 walk_state->opcode,
0677 acpi_ut_get_type_name(destination_type)));
0678 status = AE_AML_INTERNAL;
0679 }
0680
0681
0682
0683
0684
0685
0686
0687 if (status == AE_TYPE) {
0688 status = AE_OK;
0689 }
0690
0691 return_ACPI_STATUS(status);
0692 }