The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/executer/exconvrt.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 - 2022, 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 <contrib/dev/acpica/include/acpi.h>
  153 #include <contrib/dev/acpica/include/accommon.h>
  154 #include <contrib/dev/acpica/include/acinterp.h>
  155 #include <contrib/dev/acpica/include/amlcode.h>
  156 
  157 
  158 #define _COMPONENT          ACPI_EXECUTER
  159         ACPI_MODULE_NAME    ("exconvrt")
  160 
  161 /* Local prototypes */
  162 
  163 static UINT32
  164 AcpiExConvertToAscii (
  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 
  186 ACPI_STATUS
  187 AcpiExConvertToInteger (
  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 
  331 ACPI_STATUS
  332 AcpiExConvertToBuffer (
  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 
  422 static UINT32
  423 AcpiExConvertToAscii (
  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 
  547 ACPI_STATUS
  548 AcpiExConvertToString (
  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++ = '';
  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 
  761 ACPI_STATUS
  762 AcpiExConvertToTargetType (
  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 }

Cache object: e5b6dc02910e45d9730332fa33bd3ebc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.