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