[ACPICA] Update to version 20190108. CORE-15593
[reactos.git] / drivers / bus / acpi / acpica / executer / exconvrt.c
1 /******************************************************************************
2 *
3 * Module Name: exconvrt - Object conversion routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2019, 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 "acpi.h"
45 #include "accommon.h"
46 #include "acinterp.h"
47 #include "amlcode.h"
48
49
50 #define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exconvrt")
52
53 /* Local prototypes */
54
55 static UINT32
56 AcpiExConvertToAscii (
57 UINT64 Integer,
58 UINT16 Base,
59 UINT8 *String,
60 UINT8 MaxLength);
61
62
63 /*******************************************************************************
64 *
65 * FUNCTION: AcpiExConvertToInteger
66 *
67 * PARAMETERS: ObjDesc - Object to be converted. Must be an
68 * Integer, Buffer, or String
69 * ResultDesc - Where the new Integer object is returned
70 * ImplicitConversion - Used for string conversion
71 *
72 * RETURN: Status
73 *
74 * DESCRIPTION: Convert an ACPI Object to an integer.
75 *
76 ******************************************************************************/
77
78 ACPI_STATUS
79 AcpiExConvertToInteger (
80 ACPI_OPERAND_OBJECT *ObjDesc,
81 ACPI_OPERAND_OBJECT **ResultDesc,
82 UINT32 ImplicitConversion)
83 {
84 ACPI_OPERAND_OBJECT *ReturnDesc;
85 UINT8 *Pointer;
86 UINT64 Result;
87 UINT32 i;
88 UINT32 Count;
89
90
91 ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc);
92
93
94 switch (ObjDesc->Common.Type)
95 {
96 case ACPI_TYPE_INTEGER:
97
98 /* No conversion necessary */
99
100 *ResultDesc = ObjDesc;
101 return_ACPI_STATUS (AE_OK);
102
103 case ACPI_TYPE_BUFFER:
104 case ACPI_TYPE_STRING:
105
106 /* Note: Takes advantage of common buffer/string fields */
107
108 Pointer = ObjDesc->Buffer.Pointer;
109 Count = ObjDesc->Buffer.Length;
110 break;
111
112 default:
113
114 return_ACPI_STATUS (AE_TYPE);
115 }
116
117 /*
118 * Convert the buffer/string to an integer. Note that both buffers and
119 * strings are treated as raw data - we don't convert ascii to hex for
120 * strings.
121 *
122 * There are two terminating conditions for the loop:
123 * 1) The size of an integer has been reached, or
124 * 2) The end of the buffer or string has been reached
125 */
126 Result = 0;
127
128 /* String conversion is different than Buffer conversion */
129
130 switch (ObjDesc->Common.Type)
131 {
132 case ACPI_TYPE_STRING:
133 /*
134 * Convert string to an integer - for most cases, the string must be
135 * hexadecimal as per the ACPI specification. The only exception (as
136 * of ACPI 3.0) is that the ToInteger() operator allows both decimal
137 * and hexadecimal strings (hex prefixed with "0x").
138 *
139 * Explicit conversion is used only by ToInteger.
140 * All other string-to-integer conversions are implicit conversions.
141 */
142 if (ImplicitConversion)
143 {
144 Result = AcpiUtImplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
145 }
146 else
147 {
148 Result = AcpiUtExplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
149 }
150 break;
151
152 case ACPI_TYPE_BUFFER:
153
154 /* Check for zero-length buffer */
155
156 if (!Count)
157 {
158 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
159 }
160
161 /* Transfer no more than an integer's worth of data */
162
163 if (Count > AcpiGbl_IntegerByteWidth)
164 {
165 Count = AcpiGbl_IntegerByteWidth;
166 }
167
168 /*
169 * Convert buffer to an integer - we simply grab enough raw data
170 * from the buffer to fill an integer
171 */
172 for (i = 0; i < Count; i++)
173 {
174 /*
175 * Get next byte and shift it into the Result.
176 * Little endian is used, meaning that the first byte of the buffer
177 * is the LSB of the integer
178 */
179 Result |= (((UINT64) Pointer[i]) << (i * 8));
180 }
181 break;
182
183 default:
184
185 /* No other types can get here */
186
187 break;
188 }
189
190 /* Create a new integer */
191
192 ReturnDesc = AcpiUtCreateIntegerObject (Result);
193 if (!ReturnDesc)
194 {
195 return_ACPI_STATUS (AE_NO_MEMORY);
196 }
197
198 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
199 ACPI_FORMAT_UINT64 (Result)));
200
201 /* Save the Result */
202
203 (void) AcpiExTruncateFor32bitTable (ReturnDesc);
204 *ResultDesc = ReturnDesc;
205 return_ACPI_STATUS (AE_OK);
206 }
207
208
209 /*******************************************************************************
210 *
211 * FUNCTION: AcpiExConvertToBuffer
212 *
213 * PARAMETERS: ObjDesc - Object to be converted. Must be an
214 * Integer, Buffer, or String
215 * ResultDesc - Where the new buffer object is returned
216 *
217 * RETURN: Status
218 *
219 * DESCRIPTION: Convert an ACPI Object to a Buffer
220 *
221 ******************************************************************************/
222
223 ACPI_STATUS
224 AcpiExConvertToBuffer (
225 ACPI_OPERAND_OBJECT *ObjDesc,
226 ACPI_OPERAND_OBJECT **ResultDesc)
227 {
228 ACPI_OPERAND_OBJECT *ReturnDesc;
229 UINT8 *NewBuf;
230
231
232 ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc);
233
234
235 switch (ObjDesc->Common.Type)
236 {
237 case ACPI_TYPE_BUFFER:
238
239 /* No conversion necessary */
240
241 *ResultDesc = ObjDesc;
242 return_ACPI_STATUS (AE_OK);
243
244
245 case ACPI_TYPE_INTEGER:
246 /*
247 * Create a new Buffer object.
248 * Need enough space for one integer
249 */
250 ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth);
251 if (!ReturnDesc)
252 {
253 return_ACPI_STATUS (AE_NO_MEMORY);
254 }
255
256 /* Copy the integer to the buffer, LSB first */
257
258 NewBuf = ReturnDesc->Buffer.Pointer;
259 memcpy (NewBuf, &ObjDesc->Integer.Value, AcpiGbl_IntegerByteWidth);
260 break;
261
262 case ACPI_TYPE_STRING:
263 /*
264 * Create a new Buffer object
265 * Size will be the string length
266 *
267 * NOTE: Add one to the string length to include the null terminator.
268 * The ACPI spec is unclear on this subject, but there is existing
269 * ASL/AML code that depends on the null being transferred to the new
270 * buffer.
271 */
272 ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
273 ObjDesc->String.Length + 1);
274 if (!ReturnDesc)
275 {
276 return_ACPI_STATUS (AE_NO_MEMORY);
277 }
278
279 /* Copy the string to the buffer */
280
281 NewBuf = ReturnDesc->Buffer.Pointer;
282 strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer,
283 ObjDesc->String.Length);
284 break;
285
286 default:
287
288 return_ACPI_STATUS (AE_TYPE);
289 }
290
291 /* Mark buffer initialized */
292
293 ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID;
294 *ResultDesc = ReturnDesc;
295 return_ACPI_STATUS (AE_OK);
296 }
297
298
299 /*******************************************************************************
300 *
301 * FUNCTION: AcpiExConvertToAscii
302 *
303 * PARAMETERS: Integer - Value to be converted
304 * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
305 * String - Where the string is returned
306 * DataWidth - Size of data item to be converted, in bytes
307 *
308 * RETURN: Actual string length
309 *
310 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
311 *
312 ******************************************************************************/
313
314 static UINT32
315 AcpiExConvertToAscii (
316 UINT64 Integer,
317 UINT16 Base,
318 UINT8 *String,
319 UINT8 DataWidth)
320 {
321 UINT64 Digit;
322 UINT32 i;
323 UINT32 j;
324 UINT32 k = 0;
325 UINT32 HexLength;
326 UINT32 DecimalLength;
327 UINT32 Remainder;
328 BOOLEAN SupressZeros;
329
330
331 ACPI_FUNCTION_ENTRY ();
332
333
334 switch (Base)
335 {
336 case 10:
337
338 /* Setup max length for the decimal number */
339
340 switch (DataWidth)
341 {
342 case 1:
343
344 DecimalLength = ACPI_MAX8_DECIMAL_DIGITS;
345 break;
346
347 case 4:
348
349 DecimalLength = ACPI_MAX32_DECIMAL_DIGITS;
350 break;
351
352 case 8:
353 default:
354
355 DecimalLength = ACPI_MAX64_DECIMAL_DIGITS;
356 break;
357 }
358
359 SupressZeros = TRUE; /* No leading zeros */
360 Remainder = 0;
361
362 for (i = DecimalLength; i > 0; i--)
363 {
364 /* Divide by nth factor of 10 */
365
366 Digit = Integer;
367 for (j = 0; j < i; j++)
368 {
369 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder);
370 }
371
372 /* Handle leading zeros */
373
374 if (Remainder != 0)
375 {
376 SupressZeros = FALSE;
377 }
378
379 if (!SupressZeros)
380 {
381 String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder);
382 k++;
383 }
384 }
385 break;
386
387 case 16:
388
389 /* HexLength: 2 ascii hex chars per data byte */
390
391 HexLength = (DataWidth * 2);
392 for (i = 0, j = (HexLength-1); i < HexLength; i++, j--)
393 {
394 /* Get one hex digit, most significant digits first */
395
396 String[k] = (UINT8)
397 AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j));
398 k++;
399 }
400 break;
401
402 default:
403 return (0);
404 }
405
406 /*
407 * Since leading zeros are suppressed, we must check for the case where
408 * the integer equals 0
409 *
410 * Finally, null terminate the string and return the length
411 */
412 if (!k)
413 {
414 String [0] = ACPI_ASCII_ZERO;
415 k = 1;
416 }
417
418 String [k] = 0;
419 return ((UINT32) k);
420 }
421
422
423 /*******************************************************************************
424 *
425 * FUNCTION: AcpiExConvertToString
426 *
427 * PARAMETERS: ObjDesc - Object to be converted. Must be an
428 * Integer, Buffer, or String
429 * ResultDesc - Where the string object is returned
430 * Type - String flags (base and conversion type)
431 *
432 * RETURN: Status
433 *
434 * DESCRIPTION: Convert an ACPI Object to a string. Supports both implicit
435 * and explicit conversions and related rules.
436 *
437 ******************************************************************************/
438
439 ACPI_STATUS
440 AcpiExConvertToString (
441 ACPI_OPERAND_OBJECT *ObjDesc,
442 ACPI_OPERAND_OBJECT **ResultDesc,
443 UINT32 Type)
444 {
445 ACPI_OPERAND_OBJECT *ReturnDesc;
446 UINT8 *NewBuf;
447 UINT32 i;
448 UINT32 StringLength = 0;
449 UINT16 Base = 16;
450 UINT8 Separator = ',';
451
452
453 ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc);
454
455
456 switch (ObjDesc->Common.Type)
457 {
458 case ACPI_TYPE_STRING:
459
460 /* No conversion necessary */
461
462 *ResultDesc = ObjDesc;
463 return_ACPI_STATUS (AE_OK);
464
465 case ACPI_TYPE_INTEGER:
466
467 switch (Type)
468 {
469 case ACPI_EXPLICIT_CONVERT_DECIMAL:
470 /*
471 * From ToDecimalString, integer source.
472 *
473 * Make room for the maximum decimal number size
474 */
475 StringLength = ACPI_MAX_DECIMAL_DIGITS;
476 Base = 10;
477 break;
478
479 default:
480
481 /* Two hex string characters for each integer byte */
482
483 StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth);
484 break;
485 }
486
487 /*
488 * Create a new String
489 * Need enough space for one ASCII integer (plus null terminator)
490 */
491 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
492 if (!ReturnDesc)
493 {
494 return_ACPI_STATUS (AE_NO_MEMORY);
495 }
496
497 NewBuf = ReturnDesc->Buffer.Pointer;
498
499 /* Convert integer to string */
500
501 StringLength = AcpiExConvertToAscii (
502 ObjDesc->Integer.Value, Base, NewBuf, AcpiGbl_IntegerByteWidth);
503
504 /* Null terminate at the correct place */
505
506 ReturnDesc->String.Length = StringLength;
507 NewBuf [StringLength] = 0;
508 break;
509
510 case ACPI_TYPE_BUFFER:
511
512 /* Setup string length, base, and separator */
513
514 switch (Type)
515 {
516 case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */
517 /*
518 * Explicit conversion from the ToDecimalString ASL operator.
519 *
520 * From ACPI: "If the input is a buffer, it is converted to a
521 * a string of decimal values separated by commas."
522 */
523 Base = 10;
524
525 /*
526 * Calculate the final string length. Individual string values
527 * are variable length (include separator for each)
528 */
529 for (i = 0; i < ObjDesc->Buffer.Length; i++)
530 {
531 if (ObjDesc->Buffer.Pointer[i] >= 100)
532 {
533 StringLength += 4;
534 }
535 else if (ObjDesc->Buffer.Pointer[i] >= 10)
536 {
537 StringLength += 3;
538 }
539 else
540 {
541 StringLength += 2;
542 }
543 }
544 break;
545
546 case ACPI_IMPLICIT_CONVERT_HEX:
547 /*
548 * Implicit buffer-to-string conversion
549 *
550 * From the ACPI spec:
551 * "The entire contents of the buffer are converted to a string of
552 * two-character hexadecimal numbers, each separated by a space."
553 *
554 * Each hex number is prefixed with 0x (11/2018)
555 */
556 Separator = ' ';
557 StringLength = (ObjDesc->Buffer.Length * 5);
558 break;
559
560 case ACPI_EXPLICIT_CONVERT_HEX:
561 /*
562 * Explicit conversion from the ToHexString ASL operator.
563 *
564 * From ACPI: "If Data is a buffer, it is converted to a string of
565 * hexadecimal values separated by commas."
566 *
567 * Each hex number is prefixed with 0x (11/2018)
568 */
569 Separator = ',';
570 StringLength = (ObjDesc->Buffer.Length * 5);
571 break;
572
573 default:
574 return_ACPI_STATUS (AE_BAD_PARAMETER);
575 }
576
577 /*
578 * Create a new string object and string buffer
579 * (-1 because of extra separator included in StringLength from above)
580 * Allow creation of zero-length strings from zero-length buffers.
581 */
582 if (StringLength)
583 {
584 StringLength--;
585 }
586
587 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
588 if (!ReturnDesc)
589 {
590 return_ACPI_STATUS (AE_NO_MEMORY);
591 }
592
593 NewBuf = ReturnDesc->Buffer.Pointer;
594
595 /*
596 * Convert buffer bytes to hex or decimal values
597 * (separated by commas or spaces)
598 */
599 for (i = 0; i < ObjDesc->Buffer.Length; i++)
600 {
601 if (Base == 16)
602 {
603 /* Emit 0x prefix for explict/implicit hex conversion */
604
605 *NewBuf++ = '0';
606 *NewBuf++ = 'x';
607 }
608
609 NewBuf += AcpiExConvertToAscii (
610 (UINT64) ObjDesc->Buffer.Pointer[i], Base, NewBuf, 1);
611
612 /* Each digit is separated by either a comma or space */
613
614 *NewBuf++ = Separator;
615 }
616
617 /*
618 * Null terminate the string
619 * (overwrites final comma/space from above)
620 */
621 if (ObjDesc->Buffer.Length)
622 {
623 NewBuf--;
624 }
625 *NewBuf = 0;
626 break;
627
628 default:
629
630 return_ACPI_STATUS (AE_TYPE);
631 }
632
633 *ResultDesc = ReturnDesc;
634 return_ACPI_STATUS (AE_OK);
635 }
636
637
638 /*******************************************************************************
639 *
640 * FUNCTION: AcpiExConvertToTargetType
641 *
642 * PARAMETERS: DestinationType - Current type of the destination
643 * SourceDesc - Source object to be converted.
644 * ResultDesc - Where the converted object is returned
645 * WalkState - Current method state
646 *
647 * RETURN: Status
648 *
649 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
650 *
651 ******************************************************************************/
652
653 ACPI_STATUS
654 AcpiExConvertToTargetType (
655 ACPI_OBJECT_TYPE DestinationType,
656 ACPI_OPERAND_OBJECT *SourceDesc,
657 ACPI_OPERAND_OBJECT **ResultDesc,
658 ACPI_WALK_STATE *WalkState)
659 {
660 ACPI_STATUS Status = AE_OK;
661
662
663 ACPI_FUNCTION_TRACE (ExConvertToTargetType);
664
665
666 /* Default behavior */
667
668 *ResultDesc = SourceDesc;
669
670 /*
671 * If required by the target,
672 * perform implicit conversion on the source before we store it.
673 */
674 switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs))
675 {
676 case ARGI_SIMPLE_TARGET:
677 case ARGI_FIXED_TARGET:
678 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
679
680 switch (DestinationType)
681 {
682 case ACPI_TYPE_LOCAL_REGION_FIELD:
683 /*
684 * Named field can always handle conversions
685 */
686 break;
687
688 default:
689
690 /* No conversion allowed for these types */
691
692 if (DestinationType != SourceDesc->Common.Type)
693 {
694 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
695 "Explicit operator, will store (%s) over existing type (%s)\n",
696 AcpiUtGetObjectTypeName (SourceDesc),
697 AcpiUtGetTypeName (DestinationType)));
698 Status = AE_TYPE;
699 }
700 }
701 break;
702
703 case ARGI_TARGETREF:
704 case ARGI_STORE_TARGET:
705
706 switch (DestinationType)
707 {
708 case ACPI_TYPE_INTEGER:
709 case ACPI_TYPE_BUFFER_FIELD:
710 case ACPI_TYPE_LOCAL_BANK_FIELD:
711 case ACPI_TYPE_LOCAL_INDEX_FIELD:
712 /*
713 * These types require an Integer operand. We can convert
714 * a Buffer or a String to an Integer if necessary.
715 */
716 Status = AcpiExConvertToInteger (SourceDesc, ResultDesc,
717 ACPI_IMPLICIT_CONVERSION);
718 break;
719
720 case ACPI_TYPE_STRING:
721 /*
722 * The operand must be a String. We can convert an
723 * Integer or Buffer if necessary
724 */
725 Status = AcpiExConvertToString (SourceDesc, ResultDesc,
726 ACPI_IMPLICIT_CONVERT_HEX);
727 break;
728
729 case ACPI_TYPE_BUFFER:
730 /*
731 * The operand must be a Buffer. We can convert an
732 * Integer or String if necessary
733 */
734 Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc);
735 break;
736
737 default:
738
739 ACPI_ERROR ((AE_INFO,
740 "Bad destination type during conversion: 0x%X",
741 DestinationType));
742 Status = AE_AML_INTERNAL;
743 break;
744 }
745 break;
746
747 case ARGI_REFERENCE:
748 /*
749 * CreateXxxxField cases - we are storing the field object into the name
750 */
751 break;
752
753 default:
754
755 ACPI_ERROR ((AE_INFO,
756 "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
757 GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs),
758 WalkState->Opcode, AcpiUtGetTypeName (DestinationType)));
759 Status = AE_AML_INTERNAL;
760 }
761
762 /*
763 * Source-to-Target conversion semantics:
764 *
765 * If conversion to the target type cannot be performed, then simply
766 * overwrite the target with the new object and type.
767 */
768 if (Status == AE_TYPE)
769 {
770 Status = AE_OK;
771 }
772
773 return_ACPI_STATUS (Status);
774 }