Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/******************************************************************************
2
 *
3
 * Module Name: exconvrt - Object conversion routines
4
 *
5
 *****************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, Intel Corp.
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions, and the following disclaimer,
16
 *    without modification.
17
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18
 *    substantially similar to the "NO WARRANTY" disclaimer below
19
 *    ("Disclaimer") and any redistribution must be conditioned upon
20
 *    including a substantially similar Disclaimer requirement for further
21
 *    binary redistribution.
22
 * 3. Neither the names of the above-listed copyright holders nor the names
23
 *    of any contributors may be used to endorse or promote products derived
24
 *    from this software without specific prior written permission.
25
 *
26
 * Alternatively, this software may be distributed under the terms of the
27
 * GNU General Public License ("GPL") version 2 as published by the Free
28
 * Software Foundation.
29
 *
30
 * NO WARRANTY
31
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
 * POSSIBILITY OF SUCH DAMAGES.
42
 */
43
 
44
#include 
45
#include "accommon.h"
46
#include "acinterp.h"
47
#include "amlcode.h"
48
 
49
#define _COMPONENT          ACPI_EXECUTER
50
ACPI_MODULE_NAME("exconvrt")
51
 
52
/* Local prototypes */
53
static u32
54
acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length);
55
 
56
/*******************************************************************************
57
 *
58
 * FUNCTION:    acpi_ex_convert_to_integer
59
 *
60
 * PARAMETERS:  obj_desc        - Object to be converted. Must be an
61
 *                                Integer, Buffer, or String
62
 *              result_desc     - Where the new Integer object is returned
63
 *              flags           - Used for string conversion
64
 *
65
 * RETURN:      Status
66
 *
67
 * DESCRIPTION: Convert an ACPI Object to an integer.
68
 *
69
 ******************************************************************************/
70
 
71
acpi_status
72
acpi_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
		/* No conversion necessary */
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
		/* Note: Takes advantage of common buffer/string fields */
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
	 * Convert the buffer/string to an integer. Note that both buffers and
108
	 * strings are treated as raw data - we don't convert ascii to hex for
109
	 * strings.
110
	 *
111
	 * There are two terminating conditions for the loop:
112
	 * 1) The size of an integer has been reached, or
113
	 * 2) The end of the buffer or string has been reached
114
	 */
115
	result = 0;
116
 
117
	/* String conversion is different than Buffer conversion */
118
 
119
	switch (obj_desc->common.type) {
120
	case ACPI_TYPE_STRING:
121
		/*
122
		 * Convert string to an integer - for most cases, the string must be
123
		 * hexadecimal as per the ACPI specification. The only exception (as
124
		 * of ACPI 3.0) is that the to_integer() operator allows both decimal
125
		 * and hexadecimal strings (hex prefixed with "0x").
126
		 */
127
		status = acpi_ut_strtoul64((char *)pointer, flags, &result);
128
		if (ACPI_FAILURE(status)) {
129
			return_ACPI_STATUS(status);
130
		}
131
		break;
132
 
133
	case ACPI_TYPE_BUFFER:
134
 
135
		/* Check for zero-length buffer */
136
 
137
		if (!count) {
138
			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
139
		}
140
 
141
		/* Transfer no more than an integer's worth of data */
142
 
143
		if (count > acpi_gbl_integer_byte_width) {
144
			count = acpi_gbl_integer_byte_width;
145
		}
146
 
147
		/*
148
		 * Convert buffer to an integer - we simply grab enough raw data
149
		 * from the buffer to fill an integer
150
		 */
151
		for (i = 0; i < count; i++) {
152
			/*
153
			 * Get next byte and shift it into the Result.
154
			 * Little endian is used, meaning that the first byte of the buffer
155
			 * is the LSB of the integer
156
			 */
157
			result |= (((u64) pointer[i]) << (i * 8));
158
		}
159
		break;
160
 
161
	default:
162
 
163
		/* No other types can get here */
164
 
165
		break;
166
	}
167
 
168
	/* Create a new integer */
169
 
170
	return_desc = acpi_ut_create_integer_object(result);
171
	if (!return_desc) {
172
		return_ACPI_STATUS(AE_NO_MEMORY);
173
	}
174
 
175
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
176
			  ACPI_FORMAT_UINT64(result)));
177
 
178
	/* Save the Result */
179
 
180
	(void)acpi_ex_truncate_for32bit_table(return_desc);
181
	*result_desc = return_desc;
182
	return_ACPI_STATUS(AE_OK);
183
}
184
 
185
/*******************************************************************************
186
 *
187
 * FUNCTION:    acpi_ex_convert_to_buffer
188
 *
189
 * PARAMETERS:  obj_desc        - Object to be converted. Must be an
190
 *                                Integer, Buffer, or String
191
 *              result_desc     - Where the new buffer object is returned
192
 *
193
 * RETURN:      Status
194
 *
195
 * DESCRIPTION: Convert an ACPI Object to a Buffer
196
 *
197
 ******************************************************************************/
198
 
199
acpi_status
200
acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
201
			  union acpi_operand_object **result_desc)
202
{
203
	union acpi_operand_object *return_desc;
204
	u8 *new_buf;
205
 
206
	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
207
 
208
	switch (obj_desc->common.type) {
209
	case ACPI_TYPE_BUFFER:
210
 
211
		/* No conversion necessary */
212
 
213
		*result_desc = obj_desc;
214
		return_ACPI_STATUS(AE_OK);
215
 
216
	case ACPI_TYPE_INTEGER:
217
		/*
218
		 * Create a new Buffer object.
219
		 * Need enough space for one integer
220
		 */
221
		return_desc =
222
		    acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
223
		if (!return_desc) {
224
			return_ACPI_STATUS(AE_NO_MEMORY);
225
		}
226
 
227
		/* Copy the integer to the buffer, LSB first */
228
 
229
		new_buf = return_desc->buffer.pointer;
230
		memcpy(new_buf,
231
		       &obj_desc->integer.value, acpi_gbl_integer_byte_width);
232
		break;
233
 
234
	case ACPI_TYPE_STRING:
235
		/*
236
		 * Create a new Buffer object
237
		 * Size will be the string length
238
		 *
239
		 * NOTE: Add one to the string length to include the null terminator.
240
		 * The ACPI spec is unclear on this subject, but there is existing
241
		 * ASL/AML code that depends on the null being transferred to the new
242
		 * buffer.
243
		 */
244
		return_desc = acpi_ut_create_buffer_object((acpi_size)
245
							   obj_desc->string.
246
							   length + 1);
247
		if (!return_desc) {
248
			return_ACPI_STATUS(AE_NO_MEMORY);
249
		}
250
 
251
		/* Copy the string to the buffer */
252
 
253
		new_buf = return_desc->buffer.pointer;
254
		strncpy((char *)new_buf, (char *)obj_desc->string.pointer,
255
			obj_desc->string.length);
256
		break;
257
 
258
	default:
259
 
260
		return_ACPI_STATUS(AE_TYPE);
261
	}
262
 
263
	/* Mark buffer initialized */
264
 
265
	return_desc->common.flags |= AOPOBJ_DATA_VALID;
266
	*result_desc = return_desc;
267
	return_ACPI_STATUS(AE_OK);
268
}
269
 
270
/*******************************************************************************
271
 *
272
 * FUNCTION:    acpi_ex_convert_to_ascii
273
 *
274
 * PARAMETERS:  integer         - Value to be converted
275
 *              base            - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
276
 *              string          - Where the string is returned
277
 *              data_width      - Size of data item to be converted, in bytes
278
 *
279
 * RETURN:      Actual string length
280
 *
281
 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
282
 *
283
 ******************************************************************************/
284
 
285
static u32
286
acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
287
{
288
	u64 digit;
289
	u32 i;
290
	u32 j;
291
	u32 k = 0;
292
	u32 hex_length;
293
	u32 decimal_length;
294
	u32 remainder;
295
	u8 supress_zeros;
296
 
297
	ACPI_FUNCTION_ENTRY();
298
 
299
	switch (base) {
300
	case 10:
301
 
302
		/* Setup max length for the decimal number */
303
 
304
		switch (data_width) {
305
		case 1:
306
 
307
			decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
308
			break;
309
 
310
		case 4:
311
 
312
			decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
313
			break;
314
 
315
		case 8:
316
		default:
317
 
318
			decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
319
			break;
320
		}
321
 
322
		supress_zeros = TRUE;	/* No leading zeros */
323
		remainder = 0;
324
 
325
		for (i = decimal_length; i > 0; i--) {
326
 
327
			/* Divide by nth factor of 10 */
328
 
329
			digit = integer;
330
			for (j = 0; j < i; j++) {
331
				(void)acpi_ut_short_divide(digit, 10, &digit,
332
							   &remainder);
333
			}
334
 
335
			/* Handle leading zeros */
336
 
337
			if (remainder != 0) {
338
				supress_zeros = FALSE;
339
			}
340
 
341
			if (!supress_zeros) {
342
				string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
343
				k++;
344
			}
345
		}
346
		break;
347
 
348
	case 16:
349
 
350
		/* hex_length: 2 ascii hex chars per data byte */
351
 
352
		hex_length = ACPI_MUL_2(data_width);
353
		for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
354
 
355
			/* Get one hex digit, most significant digits first */
356
 
357
			string[k] =
358
			    (u8) acpi_ut_hex_to_ascii_char(integer,
359
							   ACPI_MUL_4(j));
360
			k++;
361
		}
362
		break;
363
 
364
	default:
365
		return (0);
366
	}
367
 
368
	/*
369
	 * Since leading zeros are suppressed, we must check for the case where
370
	 * the integer equals 0
371
	 *
372
	 * Finally, null terminate the string and return the length
373
	 */
374
	if (!k) {
375
		string[0] = ACPI_ASCII_ZERO;
376
		k = 1;
377
	}
378
 
379
	string[k] = 0;
380
	return ((u32) k);
381
}
382
 
383
/*******************************************************************************
384
 *
385
 * FUNCTION:    acpi_ex_convert_to_string
386
 *
387
 * PARAMETERS:  obj_desc        - Object to be converted. Must be an
388
 *                                Integer, Buffer, or String
389
 *              result_desc     - Where the string object is returned
390
 *              type            - String flags (base and conversion type)
391
 *
392
 * RETURN:      Status
393
 *
394
 * DESCRIPTION: Convert an ACPI Object to a string
395
 *
396
 ******************************************************************************/
397
 
398
acpi_status
399
acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
400
			  union acpi_operand_object ** result_desc, u32 type)
401
{
402
	union acpi_operand_object *return_desc;
403
	u8 *new_buf;
404
	u32 i;
405
	u32 string_length = 0;
406
	u16 base = 16;
407
	u8 separator = ',';
408
 
409
	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
410
 
411
	switch (obj_desc->common.type) {
412
	case ACPI_TYPE_STRING:
413
 
414
		/* No conversion necessary */
415
 
416
		*result_desc = obj_desc;
417
		return_ACPI_STATUS(AE_OK);
418
 
419
	case ACPI_TYPE_INTEGER:
420
 
421
		switch (type) {
422
		case ACPI_EXPLICIT_CONVERT_DECIMAL:
423
 
424
			/* Make room for maximum decimal number */
425
 
426
			string_length = ACPI_MAX_DECIMAL_DIGITS;
427
			base = 10;
428
			break;
429
 
430
		default:
431
 
432
			/* Two hex string characters for each integer byte */
433
 
434
			string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
435
			break;
436
		}
437
 
438
		/*
439
		 * Create a new String
440
		 * Need enough space for one ASCII integer (plus null terminator)
441
		 */
442
		return_desc =
443
		    acpi_ut_create_string_object((acpi_size) string_length);
444
		if (!return_desc) {
445
			return_ACPI_STATUS(AE_NO_MEMORY);
446
		}
447
 
448
		new_buf = return_desc->buffer.pointer;
449
 
450
		/* Convert integer to string */
451
 
452
		string_length =
453
		    acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
454
					     new_buf,
455
					     acpi_gbl_integer_byte_width);
456
 
457
		/* Null terminate at the correct place */
458
 
459
		return_desc->string.length = string_length;
460
		new_buf[string_length] = 0;
461
		break;
462
 
463
	case ACPI_TYPE_BUFFER:
464
 
465
		/* Setup string length, base, and separator */
466
 
467
		switch (type) {
468
		case ACPI_EXPLICIT_CONVERT_DECIMAL:	/* Used by to_decimal_string */
469
			/*
470
			 * From ACPI: "If Data is a buffer, it is converted to a string of
471
			 * decimal values separated by commas."
472
			 */
473
			base = 10;
474
 
475
			/*
476
			 * Calculate the final string length. Individual string values
477
			 * are variable length (include separator for each)
478
			 */
479
			for (i = 0; i < obj_desc->buffer.length; i++) {
480
				if (obj_desc->buffer.pointer[i] >= 100) {
481
					string_length += 4;
482
				} else if (obj_desc->buffer.pointer[i] >= 10) {
483
					string_length += 3;
484
				} else {
485
					string_length += 2;
486
				}
487
			}
488
			break;
489
 
490
		case ACPI_IMPLICIT_CONVERT_HEX:
491
			/*
492
			 * From the ACPI spec:
493
			 *"The entire contents of the buffer are converted to a string of
494
			 * two-character hexadecimal numbers, each separated by a space."
495
			 */
496
			separator = ' ';
497
			string_length = (obj_desc->buffer.length * 3);
498
			break;
499
 
500
		case ACPI_EXPLICIT_CONVERT_HEX:	/* Used by to_hex_string */
501
			/*
502
			 * From ACPI: "If Data is a buffer, it is converted to a string of
503
			 * hexadecimal values separated by commas."
504
			 */
505
			string_length = (obj_desc->buffer.length * 3);
506
			break;
507
 
508
		default:
509
			return_ACPI_STATUS(AE_BAD_PARAMETER);
510
		}
511
 
512
		/*
513
		 * Create a new string object and string buffer
514
		 * (-1 because of extra separator included in string_length from above)
515
		 * Allow creation of zero-length strings from zero-length buffers.
516
		 */
517
		if (string_length) {
518
			string_length--;
519
		}
520
 
521
		return_desc =
522
		    acpi_ut_create_string_object((acpi_size) string_length);
523
		if (!return_desc) {
524
			return_ACPI_STATUS(AE_NO_MEMORY);
525
		}
526
 
527
		new_buf = return_desc->buffer.pointer;
528
 
529
		/*
530
		 * Convert buffer bytes to hex or decimal values
531
		 * (separated by commas or spaces)
532
		 */
533
		for (i = 0; i < obj_desc->buffer.length; i++) {
534
			new_buf += acpi_ex_convert_to_ascii((u64) obj_desc->
535
							    buffer.pointer[i],
536
							    base, new_buf, 1);
537
			*new_buf++ = separator;	/* each separated by a comma or space */
538
		}
539
 
540
		/*
541
		 * Null terminate the string
542
		 * (overwrites final comma/space from above)
543
		 */
544
		if (obj_desc->buffer.length) {
545
			new_buf--;
546
		}
547
		*new_buf = 0;
548
		break;
549
 
550
	default:
551
 
552
		return_ACPI_STATUS(AE_TYPE);
553
	}
554
 
555
	*result_desc = return_desc;
556
	return_ACPI_STATUS(AE_OK);
557
}
558
 
559
/*******************************************************************************
560
 *
561
 * FUNCTION:    acpi_ex_convert_to_target_type
562
 *
563
 * PARAMETERS:  destination_type    - Current type of the destination
564
 *              source_desc         - Source object to be converted.
565
 *              result_desc         - Where the converted object is returned
566
 *              walk_state          - Current method state
567
 *
568
 * RETURN:      Status
569
 *
570
 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
571
 *
572
 ******************************************************************************/
573
 
574
acpi_status
575
acpi_ex_convert_to_target_type(acpi_object_type destination_type,
576
			       union acpi_operand_object *source_desc,
577
			       union acpi_operand_object **result_desc,
578
			       struct acpi_walk_state *walk_state)
579
{
580
	acpi_status status = AE_OK;
581
 
582
	ACPI_FUNCTION_TRACE(ex_convert_to_target_type);
583
 
584
	/* Default behavior */
585
 
586
	*result_desc = source_desc;
587
 
588
	/*
589
	 * If required by the target,
590
	 * perform implicit conversion on the source before we store it.
591
	 */
592
	switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
593
	case ARGI_SIMPLE_TARGET:
594
	case ARGI_FIXED_TARGET:
595
	case ARGI_INTEGER_REF:	/* Handles Increment, Decrement cases */
596
 
597
		switch (destination_type) {
598
		case ACPI_TYPE_LOCAL_REGION_FIELD:
599
			/*
600
			 * Named field can always handle conversions
601
			 */
602
			break;
603
 
604
		default:
605
 
606
			/* No conversion allowed for these types */
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
			 * These types require an Integer operand. We can convert
630
			 * a Buffer or a String to an Integer if necessary.
631
			 */
632
			status =
633
			    acpi_ex_convert_to_integer(source_desc, result_desc,
634
						       16);
635
			break;
636
 
637
		case ACPI_TYPE_STRING:
638
			/*
639
			 * The operand must be a String. We can convert an
640
			 * Integer or Buffer if necessary
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
			 * The operand must be a Buffer. We can convert an
650
			 * Integer or String if necessary
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
		 * create_xxxx_field cases - we are storing the field object into the name
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
	 * Source-to-Target conversion semantics:
685
	 *
686
	 * If conversion to the target type cannot be performed, then simply
687
	 * overwrite the target with the new object and type.
688
	 */
689
	if (status == AE_TYPE) {
690
		status = AE_OK;
691
	}
692
 
693
	return_ACPI_STATUS(status);
694
}