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