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
55static UINT32
56AcpiExConvertToAscii (
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
78ACPI_STATUS
79AcpiExConvertToInteger (
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
218ACPI_STATUS
219AcpiExConvertToBuffer (
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
309static UINT32
310AcpiExConvertToAscii (
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
433ACPI_STATUS
434AcpiExConvertToString (
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
623ACPI_STATUS
624AcpiExConvertToTargetType (
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}
744