Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:02

0001 /******************************************************************************
0002  *
0003  * Module Name: exconvrt - Object conversion routines
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #include "acpi.h"
0153 #include "accommon.h"
0154 #include "acinterp.h"
0155 #include "amlcode.h"
0156 
0157 
0158 #define _COMPONENT          ACPI_EXECUTER
0159         ACPI_MODULE_NAME    ("exconvrt")
0160 
0161 /* Local prototypes */
0162 
0163 static UINT32
0164 AcpiExConvertToAscii (
0165     UINT64                  Integer,
0166     UINT16                  Base,
0167     UINT8                   *String,
0168     UINT8                   MaxLength,
0169     BOOLEAN                 LeadingZeros);
0170 
0171 
0172 /*******************************************************************************
0173  *
0174  * FUNCTION:    AcpiExConvertToInteger
0175  *
0176  * PARAMETERS:  ObjDesc             - Object to be converted. Must be an
0177  *                                    Integer, Buffer, or String
0178  *              ResultDesc          - Where the new Integer object is returned
0179  *              ImplicitConversion  - Used for string conversion
0180  *
0181  * RETURN:      Status
0182  *
0183  * DESCRIPTION: Convert an ACPI Object to an integer.
0184  *
0185  ******************************************************************************/
0186 
0187 ACPI_STATUS
0188 AcpiExConvertToInteger (
0189     ACPI_OPERAND_OBJECT     *ObjDesc,
0190     ACPI_OPERAND_OBJECT     **ResultDesc,
0191     UINT32                  ImplicitConversion)
0192 {
0193     ACPI_OPERAND_OBJECT     *ReturnDesc;
0194     UINT8                   *Pointer;
0195     UINT64                  Result;
0196     UINT32                  i;
0197     UINT32                  Count;
0198 
0199 
0200     ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc);
0201 
0202 
0203     switch (ObjDesc->Common.Type)
0204     {
0205     case ACPI_TYPE_INTEGER:
0206 
0207         /* No conversion necessary */
0208 
0209         *ResultDesc = ObjDesc;
0210         return_ACPI_STATUS (AE_OK);
0211 
0212     case ACPI_TYPE_BUFFER:
0213     case ACPI_TYPE_STRING:
0214 
0215         /* Note: Takes advantage of common buffer/string fields */
0216 
0217         Pointer = ObjDesc->Buffer.Pointer;
0218         Count   = ObjDesc->Buffer.Length;
0219         break;
0220 
0221     default:
0222 
0223         return_ACPI_STATUS (AE_TYPE);
0224     }
0225 
0226     /*
0227      * Convert the buffer/string to an integer. Note that both buffers and
0228      * strings are treated as raw data - we don't convert ascii to hex for
0229      * strings.
0230      *
0231      * There are two terminating conditions for the loop:
0232      * 1) The size of an integer has been reached, or
0233      * 2) The end of the buffer or string has been reached
0234      */
0235     Result = 0;
0236 
0237     /* String conversion is different than Buffer conversion */
0238 
0239     switch (ObjDesc->Common.Type)
0240     {
0241     case ACPI_TYPE_STRING:
0242         /*
0243          * Convert string to an integer - for most cases, the string must be
0244          * hexadecimal as per the ACPI specification. The only exception (as
0245          * of ACPI 3.0) is that the ToInteger() operator allows both decimal
0246          * and hexadecimal strings (hex prefixed with "0x").
0247          *
0248          * Explicit conversion is used only by ToInteger.
0249          * All other string-to-integer conversions are implicit conversions.
0250          */
0251         if (ImplicitConversion)
0252         {
0253             Result = AcpiUtImplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
0254         }
0255         else
0256         {
0257             Result = AcpiUtExplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
0258         }
0259         break;
0260 
0261     case ACPI_TYPE_BUFFER:
0262 
0263         /* Check for zero-length buffer */
0264 
0265         if (!Count)
0266         {
0267             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
0268         }
0269 
0270         /* Transfer no more than an integer's worth of data */
0271 
0272         if (Count > AcpiGbl_IntegerByteWidth)
0273         {
0274             Count = AcpiGbl_IntegerByteWidth;
0275         }
0276 
0277         /*
0278          * Convert buffer to an integer - we simply grab enough raw data
0279          * from the buffer to fill an integer
0280          */
0281         for (i = 0; i < Count; i++)
0282         {
0283             /*
0284              * Get next byte and shift it into the Result.
0285              * Little endian is used, meaning that the first byte of the buffer
0286              * is the LSB of the integer
0287              */
0288             Result |= (((UINT64) Pointer[i]) << (i * 8));
0289         }
0290         break;
0291 
0292     default:
0293 
0294         /* No other types can get here */
0295 
0296         break;
0297     }
0298 
0299     /* Create a new integer */
0300 
0301     ReturnDesc = AcpiUtCreateIntegerObject (Result);
0302     if (!ReturnDesc)
0303     {
0304         return_ACPI_STATUS (AE_NO_MEMORY);
0305     }
0306 
0307     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
0308         ACPI_FORMAT_UINT64 (Result)));
0309 
0310     /* Save the Result */
0311 
0312     (void) AcpiExTruncateFor32bitTable (ReturnDesc);
0313     *ResultDesc = ReturnDesc;
0314     return_ACPI_STATUS (AE_OK);
0315 }
0316 
0317 
0318 /*******************************************************************************
0319  *
0320  * FUNCTION:    AcpiExConvertToBuffer
0321  *
0322  * PARAMETERS:  ObjDesc         - Object to be converted. Must be an
0323  *                                Integer, Buffer, or String
0324  *              ResultDesc      - Where the new buffer object is returned
0325  *
0326  * RETURN:      Status
0327  *
0328  * DESCRIPTION: Convert an ACPI Object to a Buffer
0329  *
0330  ******************************************************************************/
0331 
0332 ACPI_STATUS
0333 AcpiExConvertToBuffer (
0334     ACPI_OPERAND_OBJECT     *ObjDesc,
0335     ACPI_OPERAND_OBJECT     **ResultDesc)
0336 {
0337     ACPI_OPERAND_OBJECT     *ReturnDesc;
0338     UINT8                   *NewBuf;
0339 
0340 
0341     ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc);
0342 
0343 
0344     switch (ObjDesc->Common.Type)
0345     {
0346     case ACPI_TYPE_BUFFER:
0347 
0348         /* No conversion necessary */
0349 
0350         *ResultDesc = ObjDesc;
0351         return_ACPI_STATUS (AE_OK);
0352 
0353 
0354     case ACPI_TYPE_INTEGER:
0355         /*
0356          * Create a new Buffer object.
0357          * Need enough space for one integer
0358          */
0359         ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth);
0360         if (!ReturnDesc)
0361         {
0362             return_ACPI_STATUS (AE_NO_MEMORY);
0363         }
0364 
0365         /* Copy the integer to the buffer, LSB first */
0366 
0367         NewBuf = ReturnDesc->Buffer.Pointer;
0368         memcpy (NewBuf, &ObjDesc->Integer.Value, AcpiGbl_IntegerByteWidth);
0369         break;
0370 
0371     case ACPI_TYPE_STRING:
0372         /*
0373          * Create a new Buffer object
0374          * Size will be the string length
0375          *
0376          * NOTE: Add one to the string length to include the null terminator.
0377          * The ACPI spec is unclear on this subject, but there is existing
0378          * ASL/AML code that depends on the null being transferred to the new
0379          * buffer.
0380          */
0381         ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
0382             ObjDesc->String.Length + 1);
0383         if (!ReturnDesc)
0384         {
0385             return_ACPI_STATUS (AE_NO_MEMORY);
0386         }
0387 
0388         /* Copy the string to the buffer */
0389 
0390         NewBuf = ReturnDesc->Buffer.Pointer;
0391         strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer,
0392             ObjDesc->String.Length);
0393         break;
0394 
0395     default:
0396 
0397         return_ACPI_STATUS (AE_TYPE);
0398     }
0399 
0400     /* Mark buffer initialized */
0401 
0402     ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID;
0403     *ResultDesc = ReturnDesc;
0404     return_ACPI_STATUS (AE_OK);
0405 }
0406 
0407 
0408 /*******************************************************************************
0409  *
0410  * FUNCTION:    AcpiExConvertToAscii
0411  *
0412  * PARAMETERS:  Integer         - Value to be converted
0413  *              Base            - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
0414  *              String          - Where the string is returned
0415  *              DataWidth       - Size of data item to be converted, in bytes
0416  *              LeadingZeros    - Allow leading zeros
0417  *
0418  * RETURN:      Actual string length
0419  *
0420  * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
0421  *
0422  ******************************************************************************/
0423 
0424 static UINT32
0425 AcpiExConvertToAscii (
0426     UINT64                  Integer,
0427     UINT16                  Base,
0428     UINT8                   *String,
0429     UINT8                   DataWidth,
0430     BOOLEAN                 LeadingZeros)
0431 {
0432     UINT64                  Digit;
0433     UINT32                  i;
0434     UINT32                  j;
0435     UINT32                  k = 0;
0436     UINT32                  HexLength;
0437     UINT32                  DecimalLength;
0438     UINT32                  Remainder;
0439     BOOLEAN                 SupressZeros = !LeadingZeros;
0440     UINT8                   HexChar;
0441 
0442 
0443     ACPI_FUNCTION_ENTRY ();
0444 
0445 
0446     switch (Base)
0447     {
0448     case 10:
0449 
0450         /* Setup max length for the decimal number */
0451 
0452         switch (DataWidth)
0453         {
0454         case 1:
0455 
0456             DecimalLength = ACPI_MAX8_DECIMAL_DIGITS;
0457             break;
0458 
0459         case 4:
0460 
0461             DecimalLength = ACPI_MAX32_DECIMAL_DIGITS;
0462             break;
0463 
0464         case 8:
0465         default:
0466 
0467             DecimalLength = ACPI_MAX64_DECIMAL_DIGITS;
0468             break;
0469         }
0470 
0471         Remainder = 0;
0472 
0473         for (i = DecimalLength; i > 0; i--)
0474         {
0475             /* Divide by nth factor of 10 */
0476 
0477             Digit = Integer;
0478             for (j = 0; j < i; j++)
0479             {
0480                 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder);
0481             }
0482 
0483             /* Handle leading zeros */
0484 
0485             if (Remainder != 0)
0486             {
0487                 SupressZeros = FALSE;
0488             }
0489 
0490             if (!SupressZeros)
0491             {
0492                 String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder);
0493                 k++;
0494             }
0495         }
0496         break;
0497 
0498     case 16:
0499 
0500         /* HexLength: 2 ascii hex chars per data byte */
0501 
0502         HexLength = (DataWidth * 2);
0503         for (i = 0, j = (HexLength-1); i < HexLength; i++, j--)
0504         {
0505             /* Get one hex digit, most significant digits first */
0506 
0507             HexChar = (UINT8)
0508                 AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j));
0509 
0510             /* Supress leading zeros until the first non-zero character */
0511 
0512             if (HexChar == ACPI_ASCII_ZERO && SupressZeros)
0513             {
0514                 continue;
0515             }
0516 
0517             SupressZeros = FALSE;
0518             String[k] = HexChar;
0519             k++;
0520         }
0521         break;
0522 
0523     default:
0524         return (0);
0525     }
0526 
0527     /*
0528      * Since leading zeros are suppressed, we must check for the case where
0529      * the integer equals 0
0530      *
0531      * Finally, null terminate the string and return the length
0532      */
0533     if (!k)
0534     {
0535         String [0] = ACPI_ASCII_ZERO;
0536         k = 1;
0537     }
0538 
0539     String [k] = 0;
0540     return ((UINT32) k);
0541 }
0542 
0543 
0544 /*******************************************************************************
0545  *
0546  * FUNCTION:    AcpiExConvertToString
0547  *
0548  * PARAMETERS:  ObjDesc         - Object to be converted. Must be an
0549  *                                Integer, Buffer, or String
0550  *              ResultDesc      - Where the string object is returned
0551  *              Type            - String flags (base and conversion type)
0552  *
0553  * RETURN:      Status
0554  *
0555  * DESCRIPTION: Convert an ACPI Object to a string. Supports both implicit
0556  *              and explicit conversions and related rules.
0557  *
0558  ******************************************************************************/
0559 
0560 ACPI_STATUS
0561 AcpiExConvertToString (
0562     ACPI_OPERAND_OBJECT     *ObjDesc,
0563     ACPI_OPERAND_OBJECT     **ResultDesc,
0564     UINT32                  Type)
0565 {
0566     ACPI_OPERAND_OBJECT     *ReturnDesc;
0567     UINT8                   *NewBuf;
0568     UINT32                  i;
0569     UINT32                  StringLength = 0;
0570     UINT16                  Base = 16;
0571     UINT8                   Separator = ',';
0572     BOOLEAN                 LeadingZeros;
0573 
0574 
0575     ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc);
0576 
0577 
0578     switch (ObjDesc->Common.Type)
0579     {
0580     case ACPI_TYPE_STRING:
0581 
0582         /* No conversion necessary */
0583 
0584         *ResultDesc = ObjDesc;
0585         return_ACPI_STATUS (AE_OK);
0586 
0587     case ACPI_TYPE_INTEGER:
0588 
0589         switch (Type)
0590         {
0591         case ACPI_EXPLICIT_CONVERT_DECIMAL:
0592             /*
0593              * From ToDecimalString, integer source.
0594              *
0595              * Make room for the maximum decimal number size
0596              */
0597             StringLength = ACPI_MAX_DECIMAL_DIGITS;
0598             LeadingZeros = FALSE;
0599             Base = 10;
0600             break;
0601 
0602         case ACPI_EXPLICIT_CONVERT_HEX:
0603             /*
0604              * From ToHexString.
0605              *
0606              * Supress leading zeros and append "0x"
0607              */
0608             StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth) + 2;
0609             LeadingZeros = FALSE;
0610             break;
0611         default:
0612 
0613             /* Two hex string characters for each integer byte */
0614 
0615             StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth);
0616             LeadingZeros = TRUE;
0617             break;
0618         }
0619 
0620         /*
0621          * Create a new String
0622          * Need enough space for one ASCII integer (plus null terminator)
0623          */
0624         ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
0625         if (!ReturnDesc)
0626         {
0627             return_ACPI_STATUS (AE_NO_MEMORY);
0628         }
0629 
0630         NewBuf = ReturnDesc->Buffer.Pointer;
0631         if (Type == ACPI_EXPLICIT_CONVERT_HEX)
0632         {
0633             /* Append "0x" prefix for explicit hex conversion */
0634 
0635             *NewBuf++ = '0';
0636             *NewBuf++ = 'x';
0637         }
0638 
0639         /* Convert integer to string */
0640 
0641         StringLength = AcpiExConvertToAscii (
0642             ObjDesc->Integer.Value, Base, NewBuf, AcpiGbl_IntegerByteWidth, LeadingZeros);
0643 
0644         /* Null terminate at the correct place */
0645 
0646         ReturnDesc->String.Length = StringLength;
0647         if (Type == ACPI_EXPLICIT_CONVERT_HEX)
0648         {
0649             /* Take "0x" prefix into account */
0650 
0651             ReturnDesc->String.Length += 2;
0652         }
0653 
0654         NewBuf [StringLength] = 0;
0655         break;
0656 
0657     case ACPI_TYPE_BUFFER:
0658 
0659         /* Setup string length, base, and separator */
0660 
0661         switch (Type)
0662         {
0663         case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */
0664             /*
0665              * Explicit conversion from the ToDecimalString ASL operator.
0666              *
0667              * From ACPI: "If the input is a buffer, it is converted to a
0668              * a string of decimal values separated by commas."
0669              */
0670             LeadingZeros = FALSE;
0671             Base = 10;
0672 
0673             /*
0674              * Calculate the final string length. Individual string values
0675              * are variable length (include separator for each)
0676              */
0677             for (i = 0; i < ObjDesc->Buffer.Length; i++)
0678             {
0679                 if (ObjDesc->Buffer.Pointer[i] >= 100)
0680                 {
0681                     StringLength += 4;
0682                 }
0683                 else if (ObjDesc->Buffer.Pointer[i] >= 10)
0684                 {
0685                     StringLength += 3;
0686                 }
0687                 else
0688                 {
0689                     StringLength += 2;
0690                 }
0691             }
0692             break;
0693 
0694         case ACPI_IMPLICIT_CONVERT_HEX:
0695             /*
0696              * Implicit buffer-to-string conversion
0697              *
0698              * From the ACPI spec:
0699              * "The entire contents of the buffer are converted to a string of
0700              * two-character hexadecimal numbers, each separated by a space."
0701              *
0702              * Each hex number is prefixed with 0x (11/2018)
0703              */
0704             LeadingZeros = TRUE;
0705             Separator = ' ';
0706             StringLength = (ObjDesc->Buffer.Length * 5);
0707             break;
0708 
0709         case ACPI_EXPLICIT_CONVERT_HEX:
0710             /*
0711              * Explicit conversion from the ToHexString ASL operator.
0712              *
0713              * From ACPI: "If Data is a buffer, it is converted to a string of
0714              * hexadecimal values separated by commas."
0715              *
0716              * Each hex number is prefixed with 0x (11/2018)
0717              */
0718             LeadingZeros = TRUE;
0719             Separator = ',';
0720             StringLength = (ObjDesc->Buffer.Length * 5);
0721             break;
0722 
0723         default:
0724             return_ACPI_STATUS (AE_BAD_PARAMETER);
0725         }
0726 
0727         /*
0728          * Create a new string object and string buffer
0729          * (-1 because of extra separator included in StringLength from above)
0730          * Allow creation of zero-length strings from zero-length buffers.
0731          */
0732         if (StringLength)
0733         {
0734             StringLength--;
0735         }
0736 
0737         ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
0738         if (!ReturnDesc)
0739         {
0740             return_ACPI_STATUS (AE_NO_MEMORY);
0741         }
0742 
0743         NewBuf = ReturnDesc->Buffer.Pointer;
0744 
0745         /*
0746          * Convert buffer bytes to hex or decimal values
0747          * (separated by commas or spaces)
0748          */
0749         for (i = 0; i < ObjDesc->Buffer.Length; i++)
0750         {
0751             if (Base == 16)
0752             {
0753                 /* Emit 0x prefix for explicit/implicit hex conversion */
0754 
0755                 *NewBuf++ = '0';
0756                 *NewBuf++ = 'x';
0757             }
0758 
0759             NewBuf += AcpiExConvertToAscii (
0760                 (UINT64) ObjDesc->Buffer.Pointer[i], Base, NewBuf, 1, LeadingZeros);
0761 
0762             /* Each digit is separated by either a comma or space */
0763 
0764             *NewBuf++ = Separator;
0765         }
0766 
0767         /*
0768          * Null terminate the string
0769          * (overwrites final comma/space from above)
0770          */
0771         if (ObjDesc->Buffer.Length)
0772         {
0773             NewBuf--;
0774         }
0775         *NewBuf = 0;
0776         break;
0777 
0778     default:
0779 
0780         return_ACPI_STATUS (AE_TYPE);
0781     }
0782 
0783     *ResultDesc = ReturnDesc;
0784     return_ACPI_STATUS (AE_OK);
0785 }
0786 
0787 
0788 /*******************************************************************************
0789  *
0790  * FUNCTION:    AcpiExConvertToTargetType
0791  *
0792  * PARAMETERS:  DestinationType     - Current type of the destination
0793  *              SourceDesc          - Source object to be converted.
0794  *              ResultDesc          - Where the converted object is returned
0795  *              WalkState           - Current method state
0796  *
0797  * RETURN:      Status
0798  *
0799  * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
0800  *
0801  ******************************************************************************/
0802 
0803 ACPI_STATUS
0804 AcpiExConvertToTargetType (
0805     ACPI_OBJECT_TYPE        DestinationType,
0806     ACPI_OPERAND_OBJECT     *SourceDesc,
0807     ACPI_OPERAND_OBJECT     **ResultDesc,
0808     ACPI_WALK_STATE         *WalkState)
0809 {
0810     ACPI_STATUS             Status = AE_OK;
0811 
0812 
0813     ACPI_FUNCTION_TRACE (ExConvertToTargetType);
0814 
0815 
0816     /* Default behavior */
0817 
0818     *ResultDesc = SourceDesc;
0819 
0820     /*
0821      * If required by the target,
0822      * perform implicit conversion on the source before we store it.
0823      */
0824     switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs))
0825     {
0826     case ARGI_SIMPLE_TARGET:
0827     case ARGI_FIXED_TARGET:
0828     case ARGI_INTEGER_REF:      /* Handles Increment, Decrement cases */
0829 
0830         switch (DestinationType)
0831         {
0832         case ACPI_TYPE_LOCAL_REGION_FIELD:
0833             /*
0834              * Named field can always handle conversions
0835              */
0836             break;
0837 
0838         default:
0839 
0840             /* No conversion allowed for these types */
0841 
0842             if (DestinationType != SourceDesc->Common.Type)
0843             {
0844                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0845                     "Explicit operator, will store (%s) over existing type (%s)\n",
0846                     AcpiUtGetObjectTypeName (SourceDesc),
0847                     AcpiUtGetTypeName (DestinationType)));
0848                 Status = AE_TYPE;
0849             }
0850         }
0851         break;
0852 
0853     case ARGI_TARGETREF:
0854     case ARGI_STORE_TARGET:
0855 
0856         switch (DestinationType)
0857         {
0858         case ACPI_TYPE_INTEGER:
0859         case ACPI_TYPE_BUFFER_FIELD:
0860         case ACPI_TYPE_LOCAL_BANK_FIELD:
0861         case ACPI_TYPE_LOCAL_INDEX_FIELD:
0862             /*
0863              * These types require an Integer operand. We can convert
0864              * a Buffer or a String to an Integer if necessary.
0865              */
0866             Status = AcpiExConvertToInteger (SourceDesc, ResultDesc,
0867                 ACPI_IMPLICIT_CONVERSION);
0868             break;
0869 
0870         case ACPI_TYPE_STRING:
0871             /*
0872              * The operand must be a String. We can convert an
0873              * Integer or Buffer if necessary
0874              */
0875             Status = AcpiExConvertToString (SourceDesc, ResultDesc,
0876                 ACPI_IMPLICIT_CONVERT_HEX);
0877             break;
0878 
0879         case ACPI_TYPE_BUFFER:
0880             /*
0881              * The operand must be a Buffer. We can convert an
0882              * Integer or String if necessary
0883              */
0884             Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc);
0885             break;
0886 
0887         default:
0888 
0889             ACPI_ERROR ((AE_INFO,
0890                 "Bad destination type during conversion: 0x%X",
0891                 DestinationType));
0892             Status = AE_AML_INTERNAL;
0893             break;
0894         }
0895         break;
0896 
0897     case ARGI_REFERENCE:
0898         /*
0899          * CreateXxxxField cases - we are storing the field object into the name
0900          */
0901         break;
0902 
0903     default:
0904 
0905         ACPI_ERROR ((AE_INFO,
0906             "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
0907             GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs),
0908             WalkState->Opcode, AcpiUtGetTypeName (DestinationType)));
0909         Status = AE_AML_INTERNAL;
0910     }
0911 
0912     /*
0913      * Source-to-Target conversion semantics:
0914      *
0915      * If conversion to the target type cannot be performed, then simply
0916      * overwrite the target with the new object and type.
0917      */
0918     if (Status == AE_TYPE)
0919     {
0920         Status = AE_OK;
0921     }
0922 
0923     return_ACPI_STATUS (Status);
0924 }