1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acinterp.h"
47#include "amlcode.h"
48
49#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exconvrt")
51
52
53static u32
54acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length);
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71acpi_status
72acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
73 union acpi_operand_object **result_desc, u32 flags)
74{
75 union acpi_operand_object *return_desc;
76 u8 *pointer;
77 u64 result;
78 u32 i;
79 u32 count;
80 acpi_status status;
81
82 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
83
84 switch (obj_desc->common.type) {
85 case ACPI_TYPE_INTEGER:
86
87
88
89 *result_desc = obj_desc;
90 return_ACPI_STATUS(AE_OK);
91
92 case ACPI_TYPE_BUFFER:
93 case ACPI_TYPE_STRING:
94
95
96
97 pointer = obj_desc->buffer.pointer;
98 count = obj_desc->buffer.length;
99 break;
100
101 default:
102
103 return_ACPI_STATUS(AE_TYPE);
104 }
105
106
107
108
109
110
111
112
113
114
115 result = 0;
116
117
118
119 switch (obj_desc->common.type) {
120 case ACPI_TYPE_STRING:
121
122
123
124
125
126
127 status = acpi_ut_strtoul64(ACPI_CAST_PTR(char, pointer),
128 (acpi_gbl_integer_byte_width |
129 flags), &result);
130 if (ACPI_FAILURE(status)) {
131 return_ACPI_STATUS(status);
132 }
133 break;
134
135 case ACPI_TYPE_BUFFER:
136
137
138
139 if (!count) {
140 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
141 }
142
143
144
145 if (count > acpi_gbl_integer_byte_width) {
146 count = acpi_gbl_integer_byte_width;
147 }
148
149
150
151
152
153 for (i = 0; i < count; i++) {
154
155
156
157
158
159 result |= (((u64) pointer[i]) << (i * 8));
160 }
161 break;
162
163 default:
164
165
166
167 break;
168 }
169
170
171
172 return_desc = acpi_ut_create_integer_object(result);
173 if (!return_desc) {
174 return_ACPI_STATUS(AE_NO_MEMORY);
175 }
176
177 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
178 ACPI_FORMAT_UINT64(result)));
179
180
181
182 (void)acpi_ex_truncate_for32bit_table(return_desc);
183 *result_desc = return_desc;
184 return_ACPI_STATUS(AE_OK);
185}
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201acpi_status
202acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
203 union acpi_operand_object **result_desc)
204{
205 union acpi_operand_object *return_desc;
206 u8 *new_buf;
207
208 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
209
210 switch (obj_desc->common.type) {
211 case ACPI_TYPE_BUFFER:
212
213
214
215 *result_desc = obj_desc;
216 return_ACPI_STATUS(AE_OK);
217
218 case ACPI_TYPE_INTEGER:
219
220
221
222
223 return_desc =
224 acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
225 if (!return_desc) {
226 return_ACPI_STATUS(AE_NO_MEMORY);
227 }
228
229
230
231 new_buf = return_desc->buffer.pointer;
232 memcpy(new_buf, &obj_desc->integer.value,
233 acpi_gbl_integer_byte_width);
234 break;
235
236 case ACPI_TYPE_STRING:
237
238
239
240
241
242
243
244
245
246 return_desc = acpi_ut_create_buffer_object((acpi_size)
247 obj_desc->string.
248 length + 1);
249 if (!return_desc) {
250 return_ACPI_STATUS(AE_NO_MEMORY);
251 }
252
253
254
255 new_buf = return_desc->buffer.pointer;
256 strncpy((char *)new_buf, (char *)obj_desc->string.pointer,
257 obj_desc->string.length);
258 break;
259
260 default:
261
262 return_ACPI_STATUS(AE_TYPE);
263 }
264
265
266
267 return_desc->common.flags |= AOPOBJ_DATA_VALID;
268 *result_desc = return_desc;
269 return_ACPI_STATUS(AE_OK);
270}
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287static u32
288acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
289{
290 u64 digit;
291 u32 i;
292 u32 j;
293 u32 k = 0;
294 u32 hex_length;
295 u32 decimal_length;
296 u32 remainder;
297 u8 supress_zeros;
298
299 ACPI_FUNCTION_ENTRY();
300
301 switch (base) {
302 case 10:
303
304
305
306 switch (data_width) {
307 case 1:
308
309 decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
310 break;
311
312 case 4:
313
314 decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
315 break;
316
317 case 8:
318 default:
319
320 decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
321 break;
322 }
323
324 supress_zeros = TRUE;
325 remainder = 0;
326
327 for (i = decimal_length; i > 0; i--) {
328
329
330
331 digit = integer;
332 for (j = 0; j < i; j++) {
333 (void)acpi_ut_short_divide(digit, 10, &digit,
334 &remainder);
335 }
336
337
338
339 if (remainder != 0) {
340 supress_zeros = FALSE;
341 }
342
343 if (!supress_zeros) {
344 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
345 k++;
346 }
347 }
348 break;
349
350 case 16:
351
352
353
354 hex_length = ACPI_MUL_2(data_width);
355 for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
356
357
358
359 string[k] = (u8)
360 acpi_ut_hex_to_ascii_char(integer, ACPI_MUL_4(j));
361 k++;
362 }
363 break;
364
365 default:
366 return (0);
367 }
368
369
370
371
372
373
374
375 if (!k) {
376 string[0] = ACPI_ASCII_ZERO;
377 k = 1;
378 }
379
380 string[k] = 0;
381 return ((u32) k);
382}
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399acpi_status
400acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
401 union acpi_operand_object ** result_desc, u32 type)
402{
403 union acpi_operand_object *return_desc;
404 u8 *new_buf;
405 u32 i;
406 u32 string_length = 0;
407 u16 base = 16;
408 u8 separator = ',';
409
410 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
411
412 switch (obj_desc->common.type) {
413 case ACPI_TYPE_STRING:
414
415
416
417 *result_desc = obj_desc;
418 return_ACPI_STATUS(AE_OK);
419
420 case ACPI_TYPE_INTEGER:
421
422 switch (type) {
423 case ACPI_EXPLICIT_CONVERT_DECIMAL:
424
425
426
427 string_length = ACPI_MAX_DECIMAL_DIGITS;
428 base = 10;
429 break;
430
431 default:
432
433
434
435 string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
436 break;
437 }
438
439
440
441
442
443 return_desc =
444 acpi_ut_create_string_object((acpi_size)string_length);
445 if (!return_desc) {
446 return_ACPI_STATUS(AE_NO_MEMORY);
447 }
448
449 new_buf = return_desc->buffer.pointer;
450
451
452
453 string_length =
454 acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
455 new_buf,
456 acpi_gbl_integer_byte_width);
457
458
459
460 return_desc->string.length = string_length;
461 new_buf[string_length] = 0;
462 break;
463
464 case ACPI_TYPE_BUFFER:
465
466
467
468 switch (type) {
469 case ACPI_EXPLICIT_CONVERT_DECIMAL:
470
471
472
473
474 base = 10;
475
476
477
478
479
480 for (i = 0; i < obj_desc->buffer.length; i++) {
481 if (obj_desc->buffer.pointer[i] >= 100) {
482 string_length += 4;
483 } else if (obj_desc->buffer.pointer[i] >= 10) {
484 string_length += 3;
485 } else {
486 string_length += 2;
487 }
488 }
489 break;
490
491 case ACPI_IMPLICIT_CONVERT_HEX:
492
493
494
495
496
497 separator = ' ';
498 string_length = (obj_desc->buffer.length * 3);
499 break;
500
501 case ACPI_EXPLICIT_CONVERT_HEX:
502
503
504
505
506 string_length = (obj_desc->buffer.length * 3);
507 break;
508
509 default:
510 return_ACPI_STATUS(AE_BAD_PARAMETER);
511 }
512
513
514
515
516
517
518 if (string_length) {
519 string_length--;
520 }
521
522 return_desc =
523 acpi_ut_create_string_object((acpi_size)string_length);
524 if (!return_desc) {
525 return_ACPI_STATUS(AE_NO_MEMORY);
526 }
527
528 new_buf = return_desc->buffer.pointer;
529
530
531
532
533
534 for (i = 0; i < obj_desc->buffer.length; i++) {
535 new_buf += acpi_ex_convert_to_ascii((u64) obj_desc->
536 buffer.pointer[i],
537 base, new_buf, 1);
538 *new_buf++ = separator;
539 }
540
541
542
543
544
545 if (obj_desc->buffer.length) {
546 new_buf--;
547 }
548 *new_buf = 0;
549 break;
550
551 default:
552
553 return_ACPI_STATUS(AE_TYPE);
554 }
555
556 *result_desc = return_desc;
557 return_ACPI_STATUS(AE_OK);
558}
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575acpi_status
576acpi_ex_convert_to_target_type(acpi_object_type destination_type,
577 union acpi_operand_object *source_desc,
578 union acpi_operand_object **result_desc,
579 struct acpi_walk_state *walk_state)
580{
581 acpi_status status = AE_OK;
582
583 ACPI_FUNCTION_TRACE(ex_convert_to_target_type);
584
585
586
587 *result_desc = source_desc;
588
589
590
591
592
593 switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
594 case ARGI_SIMPLE_TARGET:
595 case ARGI_INTEGER_REF:
596
597 switch (destination_type) {
598 case ACPI_TYPE_LOCAL_REGION_FIELD:
599
600
601
602 break;
603
604 default:
605
606
607
608 if (destination_type != source_desc->common.type) {
609 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
610 "Explicit operator, will store (%s) over existing type (%s)\n",
611 acpi_ut_get_object_type_name
612 (source_desc),
613 acpi_ut_get_type_name
614 (destination_type)));
615 status = AE_TYPE;
616 }
617 }
618 break;
619
620 case ARGI_TARGETREF:
621 case ARGI_STORE_TARGET:
622
623 switch (destination_type) {
624 case ACPI_TYPE_INTEGER:
625 case ACPI_TYPE_BUFFER_FIELD:
626 case ACPI_TYPE_LOCAL_BANK_FIELD:
627 case ACPI_TYPE_LOCAL_INDEX_FIELD:
628
629
630
631
632 status =
633 acpi_ex_convert_to_integer(source_desc, result_desc,
634 ACPI_STRTOUL_BASE16);
635 break;
636
637 case ACPI_TYPE_STRING:
638
639
640
641
642 status =
643 acpi_ex_convert_to_string(source_desc, result_desc,
644 ACPI_IMPLICIT_CONVERT_HEX);
645 break;
646
647 case ACPI_TYPE_BUFFER:
648
649
650
651
652 status =
653 acpi_ex_convert_to_buffer(source_desc, result_desc);
654 break;
655
656 default:
657
658 ACPI_ERROR((AE_INFO,
659 "Bad destination type during conversion: 0x%X",
660 destination_type));
661 status = AE_AML_INTERNAL;
662 break;
663 }
664 break;
665
666 case ARGI_REFERENCE:
667
668
669
670 break;
671
672 default:
673
674 ACPI_ERROR((AE_INFO,
675 "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
676 GET_CURRENT_ARG_TYPE(walk_state->op_info->
677 runtime_args),
678 walk_state->opcode,
679 acpi_ut_get_type_name(destination_type)));
680 status = AE_AML_INTERNAL;
681 }
682
683
684
685
686
687
688
689 if (status == AE_TYPE) {
690 status = AE_OK;
691 }
692
693 return_ACPI_STATUS(status);
694}
695