1/******************************************************************************
2 *
3 * Module Name: exconvrt - Object conversion routines
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 *    notice, this list of conditions, and the following disclaimer,
124 *    without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 *    substantially similar to the "NO WARRANTY" disclaimer below
127 *    ("Disclaimer") and any redistribution must be conditioned upon
128 *    including a substantially similar Disclaimer requirement for further
129 *    binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 *    of any contributors may be used to endorse or promote products derived
132 *    from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152#include "acpi.h"
153#include "accommon.h"
154#include "acinterp.h"
155#include "amlcode.h"
156
157
158#define _COMPONENT          ACPI_EXECUTER
159        ACPI_MODULE_NAME    ("exconvrt")
160
161/* Local prototypes */
162
163static UINT32
164AcpiExConvertToAscii (
165    UINT64                  Integer,
166    UINT16                  Base,
167    UINT8                   *String,
168    UINT8                   MaxLength);
169
170
171/*******************************************************************************
172 *
173 * FUNCTION:    AcpiExConvertToInteger
174 *
175 * PARAMETERS:  ObjDesc             - Object to be converted. Must be an
176 *                                    Integer, Buffer, or String
177 *              ResultDesc          - Where the new Integer object is returned
178 *              ImplicitConversion  - Used for string conversion
179 *
180 * RETURN:      Status
181 *
182 * DESCRIPTION: Convert an ACPI Object to an integer.
183 *
184 ******************************************************************************/
185
186ACPI_STATUS
187AcpiExConvertToInteger (
188    ACPI_OPERAND_OBJECT     *ObjDesc,
189    ACPI_OPERAND_OBJECT     **ResultDesc,
190    UINT32                  ImplicitConversion)
191{
192    ACPI_OPERAND_OBJECT     *ReturnDesc;
193    UINT8                   *Pointer;
194    UINT64                  Result;
195    UINT32                  i;
196    UINT32                  Count;
197
198
199    ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc);
200
201
202    switch (ObjDesc->Common.Type)
203    {
204    case ACPI_TYPE_INTEGER:
205
206        /* No conversion necessary */
207
208        *ResultDesc = ObjDesc;
209        return_ACPI_STATUS (AE_OK);
210
211    case ACPI_TYPE_BUFFER:
212    case ACPI_TYPE_STRING:
213
214        /* Note: Takes advantage of common buffer/string fields */
215
216        Pointer = ObjDesc->Buffer.Pointer;
217        Count   = ObjDesc->Buffer.Length;
218        break;
219
220    default:
221
222        return_ACPI_STATUS (AE_TYPE);
223    }
224
225    /*
226     * Convert the buffer/string to an integer. Note that both buffers and
227     * strings are treated as raw data - we don't convert ascii to hex for
228     * strings.
229     *
230     * There are two terminating conditions for the loop:
231     * 1) The size of an integer has been reached, or
232     * 2) The end of the buffer or string has been reached
233     */
234    Result = 0;
235
236    /* String conversion is different than Buffer conversion */
237
238    switch (ObjDesc->Common.Type)
239    {
240    case ACPI_TYPE_STRING:
241        /*
242         * Convert string to an integer - for most cases, the string must be
243         * hexadecimal as per the ACPI specification. The only exception (as
244         * of ACPI 3.0) is that the ToInteger() operator allows both decimal
245         * and hexadecimal strings (hex prefixed with "0x").
246         *
247         * Explicit conversion is used only by ToInteger.
248         * All other string-to-integer conversions are implicit conversions.
249         */
250        if (ImplicitConversion)
251        {
252            Result = AcpiUtImplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
253        }
254        else
255        {
256            Result = AcpiUtExplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
257        }
258        break;
259
260    case ACPI_TYPE_BUFFER:
261
262        /* Check for zero-length buffer */
263
264        if (!Count)
265        {
266            return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
267        }
268
269        /* Transfer no more than an integer's worth of data */
270
271        if (Count > AcpiGbl_IntegerByteWidth)
272        {
273            Count = AcpiGbl_IntegerByteWidth;
274        }
275
276        /*
277         * Convert buffer to an integer - we simply grab enough raw data
278         * from the buffer to fill an integer
279         */
280        for (i = 0; i < Count; i++)
281        {
282            /*
283             * Get next byte and shift it into the Result.
284             * Little endian is used, meaning that the first byte of the buffer
285             * is the LSB of the integer
286             */
287            Result |= (((UINT64) Pointer[i]) << (i * 8));
288        }
289        break;
290
291    default:
292
293        /* No other types can get here */
294
295        break;
296    }
297
298    /* Create a new integer */
299
300    ReturnDesc = AcpiUtCreateIntegerObject (Result);
301    if (!ReturnDesc)
302    {
303        return_ACPI_STATUS (AE_NO_MEMORY);
304    }
305
306    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
307        ACPI_FORMAT_UINT64 (Result)));
308
309    /* Save the Result */
310
311    (void) AcpiExTruncateFor32bitTable (ReturnDesc);
312    *ResultDesc = ReturnDesc;
313    return_ACPI_STATUS (AE_OK);
314}
315
316
317/*******************************************************************************
318 *
319 * FUNCTION:    AcpiExConvertToBuffer
320 *
321 * PARAMETERS:  ObjDesc         - Object to be converted. Must be an
322 *                                Integer, Buffer, or String
323 *              ResultDesc      - Where the new buffer object is returned
324 *
325 * RETURN:      Status
326 *
327 * DESCRIPTION: Convert an ACPI Object to a Buffer
328 *
329 ******************************************************************************/
330
331ACPI_STATUS
332AcpiExConvertToBuffer (
333    ACPI_OPERAND_OBJECT     *ObjDesc,
334    ACPI_OPERAND_OBJECT     **ResultDesc)
335{
336    ACPI_OPERAND_OBJECT     *ReturnDesc;
337    UINT8                   *NewBuf;
338
339
340    ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc);
341
342
343    switch (ObjDesc->Common.Type)
344    {
345    case ACPI_TYPE_BUFFER:
346
347        /* No conversion necessary */
348
349        *ResultDesc = ObjDesc;
350        return_ACPI_STATUS (AE_OK);
351
352
353    case ACPI_TYPE_INTEGER:
354        /*
355         * Create a new Buffer object.
356         * Need enough space for one integer
357         */
358        ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth);
359        if (!ReturnDesc)
360        {
361            return_ACPI_STATUS (AE_NO_MEMORY);
362        }
363
364        /* Copy the integer to the buffer, LSB first */
365
366        NewBuf = ReturnDesc->Buffer.Pointer;
367        memcpy (NewBuf, &ObjDesc->Integer.Value, AcpiGbl_IntegerByteWidth);
368        break;
369
370    case ACPI_TYPE_STRING:
371        /*
372         * Create a new Buffer object
373         * Size will be the string length
374         *
375         * NOTE: Add one to the string length to include the null terminator.
376         * The ACPI spec is unclear on this subject, but there is existing
377         * ASL/AML code that depends on the null being transferred to the new
378         * buffer.
379         */
380        ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
381            ObjDesc->String.Length + 1);
382        if (!ReturnDesc)
383        {
384            return_ACPI_STATUS (AE_NO_MEMORY);
385        }
386
387        /* Copy the string to the buffer */
388
389        NewBuf = ReturnDesc->Buffer.Pointer;
390        strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer,
391            ObjDesc->String.Length);
392        break;
393
394    default:
395
396        return_ACPI_STATUS (AE_TYPE);
397    }
398
399    /* Mark buffer initialized */
400
401    ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID;
402    *ResultDesc = ReturnDesc;
403    return_ACPI_STATUS (AE_OK);
404}
405
406
407/*******************************************************************************
408 *
409 * FUNCTION:    AcpiExConvertToAscii
410 *
411 * PARAMETERS:  Integer         - Value to be converted
412 *              Base            - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
413 *              String          - Where the string is returned
414 *              DataWidth       - Size of data item to be converted, in bytes
415 *
416 * RETURN:      Actual string length
417 *
418 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
419 *
420 ******************************************************************************/
421
422static UINT32
423AcpiExConvertToAscii (
424    UINT64                  Integer,
425    UINT16                  Base,
426    UINT8                   *String,
427    UINT8                   DataWidth)
428{
429    UINT64                  Digit;
430    UINT32                  i;
431    UINT32                  j;
432    UINT32                  k = 0;
433    UINT32                  HexLength;
434    UINT32                  DecimalLength;
435    UINT32                  Remainder;
436    BOOLEAN                 SupressZeros;
437
438
439    ACPI_FUNCTION_ENTRY ();
440
441
442    switch (Base)
443    {
444    case 10:
445
446        /* Setup max length for the decimal number */
447
448        switch (DataWidth)
449        {
450        case 1:
451
452            DecimalLength = ACPI_MAX8_DECIMAL_DIGITS;
453            break;
454
455        case 4:
456
457            DecimalLength = ACPI_MAX32_DECIMAL_DIGITS;
458            break;
459
460        case 8:
461        default:
462
463            DecimalLength = ACPI_MAX64_DECIMAL_DIGITS;
464            break;
465        }
466
467        SupressZeros = TRUE;     /* No leading zeros */
468        Remainder = 0;
469
470        for (i = DecimalLength; i > 0; i--)
471        {
472            /* Divide by nth factor of 10 */
473
474            Digit = Integer;
475            for (j = 0; j < i; j++)
476            {
477                (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder);
478            }
479
480            /* Handle leading zeros */
481
482            if (Remainder != 0)
483            {
484                SupressZeros = FALSE;
485            }
486
487            if (!SupressZeros)
488            {
489                String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder);
490                k++;
491            }
492        }
493        break;
494
495    case 16:
496
497        /* HexLength: 2 ascii hex chars per data byte */
498
499        HexLength = (DataWidth * 2);
500        for (i = 0, j = (HexLength-1); i < HexLength; i++, j--)
501        {
502            /* Get one hex digit, most significant digits first */
503
504            String[k] = (UINT8)
505                AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j));
506            k++;
507        }
508        break;
509
510    default:
511        return (0);
512    }
513
514    /*
515     * Since leading zeros are suppressed, we must check for the case where
516     * the integer equals 0
517     *
518     * Finally, null terminate the string and return the length
519     */
520    if (!k)
521    {
522        String [0] = ACPI_ASCII_ZERO;
523        k = 1;
524    }
525
526    String [k] = 0;
527    return ((UINT32) k);
528}
529
530
531/*******************************************************************************
532 *
533 * FUNCTION:    AcpiExConvertToString
534 *
535 * PARAMETERS:  ObjDesc         - Object to be converted. Must be an
536 *                                Integer, Buffer, or String
537 *              ResultDesc      - Where the string object is returned
538 *              Type            - String flags (base and conversion type)
539 *
540 * RETURN:      Status
541 *
542 * DESCRIPTION: Convert an ACPI Object to a string. Supports both implicit
543 *              and explicit conversions and related rules.
544 *
545 ******************************************************************************/
546
547ACPI_STATUS
548AcpiExConvertToString (
549    ACPI_OPERAND_OBJECT     *ObjDesc,
550    ACPI_OPERAND_OBJECT     **ResultDesc,
551    UINT32                  Type)
552{
553    ACPI_OPERAND_OBJECT     *ReturnDesc;
554    UINT8                   *NewBuf;
555    UINT32                  i;
556    UINT32                  StringLength = 0;
557    UINT16                  Base = 16;
558    UINT8                   Separator = ',';
559
560
561    ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc);
562
563
564    switch (ObjDesc->Common.Type)
565    {
566    case ACPI_TYPE_STRING:
567
568        /* No conversion necessary */
569
570        *ResultDesc = ObjDesc;
571        return_ACPI_STATUS (AE_OK);
572
573    case ACPI_TYPE_INTEGER:
574
575        switch (Type)
576        {
577        case ACPI_EXPLICIT_CONVERT_DECIMAL:
578            /*
579             * From ToDecimalString, integer source.
580             *
581             * Make room for the maximum decimal number size
582             */
583            StringLength = ACPI_MAX_DECIMAL_DIGITS;
584            Base = 10;
585            break;
586
587        default:
588
589            /* Two hex string characters for each integer byte */
590
591            StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth);
592            break;
593        }
594
595        /*
596         * Create a new String
597         * Need enough space for one ASCII integer (plus null terminator)
598         */
599        ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
600        if (!ReturnDesc)
601        {
602            return_ACPI_STATUS (AE_NO_MEMORY);
603        }
604
605        NewBuf = ReturnDesc->Buffer.Pointer;
606
607        /* Convert integer to string */
608
609        StringLength = AcpiExConvertToAscii (
610            ObjDesc->Integer.Value, Base, NewBuf, AcpiGbl_IntegerByteWidth);
611
612        /* Null terminate at the correct place */
613
614        ReturnDesc->String.Length = StringLength;
615        NewBuf [StringLength] = 0;
616        break;
617
618    case ACPI_TYPE_BUFFER:
619
620        /* Setup string length, base, and separator */
621
622        switch (Type)
623        {
624        case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */
625            /*
626             * Explicit conversion from the ToDecimalString ASL operator.
627             *
628             * From ACPI: "If the input is a buffer, it is converted to a
629             * a string of decimal values separated by commas."
630             */
631            Base = 10;
632
633            /*
634             * Calculate the final string length. Individual string values
635             * are variable length (include separator for each)
636             */
637            for (i = 0; i < ObjDesc->Buffer.Length; i++)
638            {
639                if (ObjDesc->Buffer.Pointer[i] >= 100)
640                {
641                    StringLength += 4;
642                }
643                else if (ObjDesc->Buffer.Pointer[i] >= 10)
644                {
645                    StringLength += 3;
646                }
647                else
648                {
649                    StringLength += 2;
650                }
651            }
652            break;
653
654        case ACPI_IMPLICIT_CONVERT_HEX:
655            /*
656             * Implicit buffer-to-string conversion
657             *
658             * From the ACPI spec:
659             * "The entire contents of the buffer are converted to a string of
660             * two-character hexadecimal numbers, each separated by a space."
661             *
662             * Each hex number is prefixed with 0x (11/2018)
663             */
664            Separator = ' ';
665            StringLength = (ObjDesc->Buffer.Length * 5);
666            break;
667
668        case ACPI_EXPLICIT_CONVERT_HEX:
669            /*
670             * Explicit conversion from the ToHexString ASL operator.
671             *
672             * From ACPI: "If Data is a buffer, it is converted to a string of
673             * hexadecimal values separated by commas."
674             *
675             * Each hex number is prefixed with 0x (11/2018)
676             */
677            Separator = ',';
678            StringLength = (ObjDesc->Buffer.Length * 5);
679            break;
680
681        default:
682            return_ACPI_STATUS (AE_BAD_PARAMETER);
683        }
684
685        /*
686         * Create a new string object and string buffer
687         * (-1 because of extra separator included in StringLength from above)
688         * Allow creation of zero-length strings from zero-length buffers.
689         */
690        if (StringLength)
691        {
692            StringLength--;
693        }
694
695        ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
696        if (!ReturnDesc)
697        {
698            return_ACPI_STATUS (AE_NO_MEMORY);
699        }
700
701        NewBuf = ReturnDesc->Buffer.Pointer;
702
703        /*
704         * Convert buffer bytes to hex or decimal values
705         * (separated by commas or spaces)
706         */
707        for (i = 0; i < ObjDesc->Buffer.Length; i++)
708        {
709            if (Base == 16)
710            {
711                /* Emit 0x prefix for explicit/implicit hex conversion */
712
713                *NewBuf++ = '0';
714                *NewBuf++ = 'x';
715            }
716
717            NewBuf += AcpiExConvertToAscii (
718                (UINT64) ObjDesc->Buffer.Pointer[i], Base, NewBuf, 1);
719
720            /* Each digit is separated by either a comma or space */
721
722            *NewBuf++ = Separator;
723        }
724
725        /*
726         * Null terminate the string
727         * (overwrites final comma/space from above)
728         */
729        if (ObjDesc->Buffer.Length)
730        {
731            NewBuf--;
732        }
733        *NewBuf = 0;
734        break;
735
736    default:
737
738        return_ACPI_STATUS (AE_TYPE);
739    }
740
741    *ResultDesc = ReturnDesc;
742    return_ACPI_STATUS (AE_OK);
743}
744
745
746/*******************************************************************************
747 *
748 * FUNCTION:    AcpiExConvertToTargetType
749 *
750 * PARAMETERS:  DestinationType     - Current type of the destination
751 *              SourceDesc          - Source object to be converted.
752 *              ResultDesc          - Where the converted object is returned
753 *              WalkState           - Current method state
754 *
755 * RETURN:      Status
756 *
757 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
758 *
759 ******************************************************************************/
760
761ACPI_STATUS
762AcpiExConvertToTargetType (
763    ACPI_OBJECT_TYPE        DestinationType,
764    ACPI_OPERAND_OBJECT     *SourceDesc,
765    ACPI_OPERAND_OBJECT     **ResultDesc,
766    ACPI_WALK_STATE         *WalkState)
767{
768    ACPI_STATUS             Status = AE_OK;
769
770
771    ACPI_FUNCTION_TRACE (ExConvertToTargetType);
772
773
774    /* Default behavior */
775
776    *ResultDesc = SourceDesc;
777
778    /*
779     * If required by the target,
780     * perform implicit conversion on the source before we store it.
781     */
782    switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs))
783    {
784    case ARGI_SIMPLE_TARGET:
785    case ARGI_FIXED_TARGET:
786    case ARGI_INTEGER_REF:      /* Handles Increment, Decrement cases */
787
788        switch (DestinationType)
789        {
790        case ACPI_TYPE_LOCAL_REGION_FIELD:
791            /*
792             * Named field can always handle conversions
793             */
794            break;
795
796        default:
797
798            /* No conversion allowed for these types */
799
800            if (DestinationType != SourceDesc->Common.Type)
801            {
802                ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
803                    "Explicit operator, will store (%s) over existing type (%s)\n",
804                    AcpiUtGetObjectTypeName (SourceDesc),
805                    AcpiUtGetTypeName (DestinationType)));
806                Status = AE_TYPE;
807            }
808        }
809        break;
810
811    case ARGI_TARGETREF:
812    case ARGI_STORE_TARGET:
813
814        switch (DestinationType)
815        {
816        case ACPI_TYPE_INTEGER:
817        case ACPI_TYPE_BUFFER_FIELD:
818        case ACPI_TYPE_LOCAL_BANK_FIELD:
819        case ACPI_TYPE_LOCAL_INDEX_FIELD:
820            /*
821             * These types require an Integer operand. We can convert
822             * a Buffer or a String to an Integer if necessary.
823             */
824            Status = AcpiExConvertToInteger (SourceDesc, ResultDesc,
825                ACPI_IMPLICIT_CONVERSION);
826            break;
827
828        case ACPI_TYPE_STRING:
829            /*
830             * The operand must be a String. We can convert an
831             * Integer or Buffer if necessary
832             */
833            Status = AcpiExConvertToString (SourceDesc, ResultDesc,
834                ACPI_IMPLICIT_CONVERT_HEX);
835            break;
836
837        case ACPI_TYPE_BUFFER:
838            /*
839             * The operand must be a Buffer. We can convert an
840             * Integer or String if necessary
841             */
842            Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc);
843            break;
844
845        default:
846
847            ACPI_ERROR ((AE_INFO,
848                "Bad destination type during conversion: 0x%X",
849                DestinationType));
850            Status = AE_AML_INTERNAL;
851            break;
852        }
853        break;
854
855    case ARGI_REFERENCE:
856        /*
857         * CreateXxxxField cases - we are storing the field object into the name
858         */
859        break;
860
861    default:
862
863        ACPI_ERROR ((AE_INFO,
864            "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
865            GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs),
866            WalkState->Opcode, AcpiUtGetTypeName (DestinationType)));
867        Status = AE_AML_INTERNAL;
868    }
869
870    /*
871     * Source-to-Target conversion semantics:
872     *
873     * If conversion to the target type cannot be performed, then simply
874     * overwrite the target with the new object and type.
875     */
876    if (Status == AE_TYPE)
877    {
878        Status = AE_OK;
879    }
880
881    return_ACPI_STATUS (Status);
882}
883