Subversion Repositories Kolibri OS

Rev

Rev 1498 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 - 2011, 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.  
  117. #define __EXCONVRT_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acinterp.h"
  122. #include "amlcode.h"
  123.  
  124.  
  125. #define _COMPONENT          ACPI_EXECUTER
  126.         ACPI_MODULE_NAME    ("exconvrt")
  127.  
  128. /* Local prototypes */
  129.  
  130. static UINT32
  131. AcpiExConvertToAscii (
  132.     UINT64                  Integer,
  133.     UINT16                  Base,
  134.     UINT8                   *String,
  135.     UINT8                   MaxLength);
  136.  
  137.  
  138. /*******************************************************************************
  139.  *
  140.  * FUNCTION:    AcpiExConvertToInteger
  141.  *
  142.  * PARAMETERS:  ObjDesc         - Object to be converted. Must be an
  143.  *                                Integer, Buffer, or String
  144.  *              ResultDesc      - Where the new Integer object is returned
  145.  *              Flags           - Used for string conversion
  146.  *
  147.  * RETURN:      Status
  148.  *
  149.  * DESCRIPTION: Convert an ACPI Object to an integer.
  150.  *
  151.  ******************************************************************************/
  152.  
  153. ACPI_STATUS
  154. AcpiExConvertToInteger (
  155.     ACPI_OPERAND_OBJECT     *ObjDesc,
  156.     ACPI_OPERAND_OBJECT     **ResultDesc,
  157.     UINT32                  Flags)
  158. {
  159.     ACPI_OPERAND_OBJECT     *ReturnDesc;
  160.     UINT8                   *Pointer;
  161.     UINT64                  Result;
  162.     UINT32                  i;
  163.     UINT32                  Count;
  164.     ACPI_STATUS             Status;
  165.  
  166.  
  167.     ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc);
  168.  
  169.  
  170.     switch (ObjDesc->Common.Type)
  171.     {
  172.     case ACPI_TYPE_INTEGER:
  173.  
  174.         /* No conversion necessary */
  175.  
  176.         *ResultDesc = ObjDesc;
  177.         return_ACPI_STATUS (AE_OK);
  178.  
  179.     case ACPI_TYPE_BUFFER:
  180.     case ACPI_TYPE_STRING:
  181.  
  182.         /* Note: Takes advantage of common buffer/string fields */
  183.  
  184.         Pointer = ObjDesc->Buffer.Pointer;
  185.         Count   = ObjDesc->Buffer.Length;
  186.         break;
  187.  
  188.     default:
  189.         return_ACPI_STATUS (AE_TYPE);
  190.     }
  191.  
  192.     /*
  193.      * Convert the buffer/string to an integer. Note that both buffers and
  194.      * strings are treated as raw data - we don't convert ascii to hex for
  195.      * strings.
  196.      *
  197.      * There are two terminating conditions for the loop:
  198.      * 1) The size of an integer has been reached, or
  199.      * 2) The end of the buffer or string has been reached
  200.      */
  201.     Result = 0;
  202.  
  203.     /* String conversion is different than Buffer conversion */
  204.  
  205.     switch (ObjDesc->Common.Type)
  206.     {
  207.     case ACPI_TYPE_STRING:
  208.  
  209.         /*
  210.          * Convert string to an integer - for most cases, the string must be
  211.          * hexadecimal as per the ACPI specification. The only exception (as
  212.          * of ACPI 3.0) is that the ToInteger() operator allows both decimal
  213.          * and hexadecimal strings (hex prefixed with "0x").
  214.          */
  215.         Status = AcpiUtStrtoul64 ((char *) Pointer, Flags, &Result);
  216.         if (ACPI_FAILURE (Status))
  217.         {
  218.             return_ACPI_STATUS (Status);
  219.         }
  220.         break;
  221.  
  222.  
  223.     case ACPI_TYPE_BUFFER:
  224.  
  225.         /* Check for zero-length buffer */
  226.  
  227.         if (!Count)
  228.         {
  229.             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
  230.         }
  231.  
  232.         /* Transfer no more than an integer's worth of data */
  233.  
  234.         if (Count > AcpiGbl_IntegerByteWidth)
  235.         {
  236.             Count = AcpiGbl_IntegerByteWidth;
  237.         }
  238.  
  239.         /*
  240.          * Convert buffer to an integer - we simply grab enough raw data
  241.          * from the buffer to fill an integer
  242.          */
  243.         for (i = 0; i < Count; i++)
  244.         {
  245.             /*
  246.              * Get next byte and shift it into the Result.
  247.              * Little endian is used, meaning that the first byte of the buffer
  248.              * is the LSB of the integer
  249.              */
  250.             Result |= (((UINT64) Pointer[i]) << (i * 8));
  251.         }
  252.         break;
  253.  
  254.  
  255.     default:
  256.  
  257.         /* No other types can get here */
  258.         break;
  259.     }
  260.  
  261.     /* Create a new integer */
  262.  
  263.     ReturnDesc = AcpiUtCreateIntegerObject (Result);
  264.     if (!ReturnDesc)
  265.     {
  266.         return_ACPI_STATUS (AE_NO_MEMORY);
  267.     }
  268.  
  269.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
  270.         ACPI_FORMAT_UINT64 (Result)));
  271.  
  272.     /* Save the Result */
  273.  
  274.     AcpiExTruncateFor32bitTable (ReturnDesc);
  275.     *ResultDesc = ReturnDesc;
  276.     return_ACPI_STATUS (AE_OK);
  277. }
  278.  
  279.  
  280. /*******************************************************************************
  281.  *
  282.  * FUNCTION:    AcpiExConvertToBuffer
  283.  *
  284.  * PARAMETERS:  ObjDesc         - Object to be converted. Must be an
  285.  *                                Integer, Buffer, or String
  286.  *              ResultDesc      - Where the new buffer object is returned
  287.  *
  288.  * RETURN:      Status
  289.  *
  290.  * DESCRIPTION: Convert an ACPI Object to a Buffer
  291.  *
  292.  ******************************************************************************/
  293.  
  294. ACPI_STATUS
  295. AcpiExConvertToBuffer (
  296.     ACPI_OPERAND_OBJECT     *ObjDesc,
  297.     ACPI_OPERAND_OBJECT     **ResultDesc)
  298. {
  299.     ACPI_OPERAND_OBJECT     *ReturnDesc;
  300.     UINT8                   *NewBuf;
  301.  
  302.  
  303.     ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc);
  304.  
  305.  
  306.     switch (ObjDesc->Common.Type)
  307.     {
  308.     case ACPI_TYPE_BUFFER:
  309.  
  310.         /* No conversion necessary */
  311.  
  312.         *ResultDesc = ObjDesc;
  313.         return_ACPI_STATUS (AE_OK);
  314.  
  315.  
  316.     case ACPI_TYPE_INTEGER:
  317.  
  318.         /*
  319.          * Create a new Buffer object.
  320.          * Need enough space for one integer
  321.          */
  322.         ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth);
  323.         if (!ReturnDesc)
  324.         {
  325.             return_ACPI_STATUS (AE_NO_MEMORY);
  326.         }
  327.  
  328.         /* Copy the integer to the buffer, LSB first */
  329.  
  330.         NewBuf = ReturnDesc->Buffer.Pointer;
  331.         ACPI_MEMCPY (NewBuf,
  332.                         &ObjDesc->Integer.Value,
  333.                         AcpiGbl_IntegerByteWidth);
  334.         break;
  335.  
  336.  
  337.     case ACPI_TYPE_STRING:
  338.  
  339.         /*
  340.          * Create a new Buffer object
  341.          * Size will be the string length
  342.          *
  343.          * NOTE: Add one to the string length to include the null terminator.
  344.          * The ACPI spec is unclear on this subject, but there is existing
  345.          * ASL/AML code that depends on the null being transferred to the new
  346.          * buffer.
  347.          */
  348.         ReturnDesc = AcpiUtCreateBufferObject (
  349.                         (ACPI_SIZE) ObjDesc->String.Length + 1);
  350.         if (!ReturnDesc)
  351.         {
  352.             return_ACPI_STATUS (AE_NO_MEMORY);
  353.         }
  354.  
  355.         /* Copy the string to the buffer */
  356.  
  357.         NewBuf = ReturnDesc->Buffer.Pointer;
  358.         ACPI_STRNCPY ((char *) NewBuf, (char *) ObjDesc->String.Pointer,
  359.             ObjDesc->String.Length);
  360.         break;
  361.  
  362.  
  363.     default:
  364.         return_ACPI_STATUS (AE_TYPE);
  365.     }
  366.  
  367.     /* Mark buffer initialized */
  368.  
  369.     ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID;
  370.     *ResultDesc = ReturnDesc;
  371.     return_ACPI_STATUS (AE_OK);
  372. }
  373.  
  374.  
  375. /*******************************************************************************
  376.  *
  377.  * FUNCTION:    AcpiExConvertToAscii
  378.  *
  379.  * PARAMETERS:  Integer         - Value to be converted
  380.  *              Base            - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
  381.  *              String          - Where the string is returned
  382.  *              DataWidth       - Size of data item to be converted, in bytes
  383.  *
  384.  * RETURN:      Actual string length
  385.  *
  386.  * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
  387.  *
  388.  ******************************************************************************/
  389.  
  390. static UINT32
  391. AcpiExConvertToAscii (
  392.     UINT64                  Integer,
  393.     UINT16                  Base,
  394.     UINT8                   *String,
  395.     UINT8                   DataWidth)
  396. {
  397.     UINT64                  Digit;
  398.     UINT32                  i;
  399.     UINT32                  j;
  400.     UINT32                  k = 0;
  401.     UINT32                  HexLength;
  402.     UINT32                  DecimalLength;
  403.     UINT32                  Remainder;
  404.     BOOLEAN                 SupressZeros;
  405.  
  406.  
  407.     ACPI_FUNCTION_ENTRY ();
  408.  
  409.  
  410.     switch (Base)
  411.     {
  412.     case 10:
  413.  
  414.         /* Setup max length for the decimal number */
  415.  
  416.         switch (DataWidth)
  417.         {
  418.         case 1:
  419.             DecimalLength = ACPI_MAX8_DECIMAL_DIGITS;
  420.             break;
  421.  
  422.         case 4:
  423.             DecimalLength = ACPI_MAX32_DECIMAL_DIGITS;
  424.             break;
  425.  
  426.         case 8:
  427.         default:
  428.             DecimalLength = ACPI_MAX64_DECIMAL_DIGITS;
  429.             break;
  430.         }
  431.  
  432.         SupressZeros = TRUE;     /* No leading zeros */
  433.         Remainder = 0;
  434.  
  435.         for (i = DecimalLength; i > 0; i--)
  436.         {
  437.             /* Divide by nth factor of 10 */
  438.  
  439.             Digit = Integer;
  440.             for (j = 0; j < i; j++)
  441.             {
  442.                 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder);
  443.             }
  444.  
  445.             /* Handle leading zeros */
  446.  
  447.             if (Remainder != 0)
  448.             {
  449.                 SupressZeros = FALSE;
  450.             }
  451.  
  452.             if (!SupressZeros)
  453.             {
  454.                 String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder);
  455.                 k++;
  456.             }
  457.         }
  458.         break;
  459.  
  460.     case 16:
  461.  
  462.         /* HexLength: 2 ascii hex chars per data byte */
  463.  
  464.         HexLength = ACPI_MUL_2 (DataWidth);
  465.         for (i = 0, j = (HexLength-1); i < HexLength; i++, j--)
  466.         {
  467.             /* Get one hex digit, most significant digits first */
  468.  
  469.             String[k] = (UINT8) AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j));
  470.             k++;
  471.         }
  472.         break;
  473.  
  474.     default:
  475.         return (0);
  476.     }
  477.  
  478.     /*
  479.      * Since leading zeros are suppressed, we must check for the case where
  480.      * the integer equals 0
  481.      *
  482.      * Finally, null terminate the string and return the length
  483.      */
  484.     if (!k)
  485.     {
  486.         String [0] = ACPI_ASCII_ZERO;
  487.         k = 1;
  488.     }
  489.  
  490.     String [k] = 0;
  491.     return ((UINT32) k);
  492. }
  493.  
  494.  
  495. /*******************************************************************************
  496.  *
  497.  * FUNCTION:    AcpiExConvertToString
  498.  *
  499.  * PARAMETERS:  ObjDesc         - Object to be converted. Must be an
  500.  *                                Integer, Buffer, or String
  501.  *              ResultDesc      - Where the string object is returned
  502.  *              Type            - String flags (base and conversion type)
  503.  *
  504.  * RETURN:      Status
  505.  *
  506.  * DESCRIPTION: Convert an ACPI Object to a string
  507.  *
  508.  ******************************************************************************/
  509.  
  510. ACPI_STATUS
  511. AcpiExConvertToString (
  512.     ACPI_OPERAND_OBJECT     *ObjDesc,
  513.     ACPI_OPERAND_OBJECT     **ResultDesc,
  514.     UINT32                  Type)
  515. {
  516.     ACPI_OPERAND_OBJECT     *ReturnDesc;
  517.     UINT8                   *NewBuf;
  518.     UINT32                  i;
  519.     UINT32                  StringLength = 0;
  520.     UINT16                  Base = 16;
  521.     UINT8                   Separator = ',';
  522.  
  523.  
  524.     ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc);
  525.  
  526.  
  527.     switch (ObjDesc->Common.Type)
  528.     {
  529.     case ACPI_TYPE_STRING:
  530.  
  531.         /* No conversion necessary */
  532.  
  533.         *ResultDesc = ObjDesc;
  534.         return_ACPI_STATUS (AE_OK);
  535.  
  536.  
  537.     case ACPI_TYPE_INTEGER:
  538.  
  539.         switch (Type)
  540.         {
  541.         case ACPI_EXPLICIT_CONVERT_DECIMAL:
  542.  
  543.             /* Make room for maximum decimal number */
  544.  
  545.             StringLength = ACPI_MAX_DECIMAL_DIGITS;
  546.             Base = 10;
  547.             break;
  548.  
  549.         default:
  550.  
  551.             /* Two hex string characters for each integer byte */
  552.  
  553.             StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth);
  554.             break;
  555.         }
  556.  
  557.         /*
  558.          * Create a new String
  559.          * Need enough space for one ASCII integer (plus null terminator)
  560.          */
  561.         ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
  562.         if (!ReturnDesc)
  563.         {
  564.             return_ACPI_STATUS (AE_NO_MEMORY);
  565.         }
  566.  
  567.         NewBuf = ReturnDesc->Buffer.Pointer;
  568.  
  569.         /* Convert integer to string */
  570.  
  571.         StringLength = AcpiExConvertToAscii (ObjDesc->Integer.Value, Base,
  572.                             NewBuf, AcpiGbl_IntegerByteWidth);
  573.  
  574.         /* Null terminate at the correct place */
  575.  
  576.         ReturnDesc->String.Length = StringLength;
  577.         NewBuf [StringLength] = 0;
  578.         break;
  579.  
  580.  
  581.     case ACPI_TYPE_BUFFER:
  582.  
  583.         /* Setup string length, base, and separator */
  584.  
  585.         switch (Type)
  586.         {
  587.         case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */
  588.             /*
  589.              * From ACPI: "If Data is a buffer, it is converted to a string of
  590.              * decimal values separated by commas."
  591.              */
  592.             Base = 10;
  593.  
  594.             /*
  595.              * Calculate the final string length. Individual string values
  596.              * are variable length (include separator for each)
  597.              */
  598.             for (i = 0; i < ObjDesc->Buffer.Length; i++)
  599.             {
  600.                 if (ObjDesc->Buffer.Pointer[i] >= 100)
  601.                 {
  602.                     StringLength += 4;
  603.                 }
  604.                 else if (ObjDesc->Buffer.Pointer[i] >= 10)
  605.                 {
  606.                     StringLength += 3;
  607.                 }
  608.                 else
  609.                 {
  610.                     StringLength += 2;
  611.                 }
  612.             }
  613.             break;
  614.  
  615.         case ACPI_IMPLICIT_CONVERT_HEX:
  616.             /*
  617.              * From the ACPI spec:
  618.              *"The entire contents of the buffer are converted to a string of
  619.              * two-character hexadecimal numbers, each separated by a space."
  620.              */
  621.             Separator = ' ';
  622.             StringLength = (ObjDesc->Buffer.Length * 3);
  623.             break;
  624.  
  625.         case ACPI_EXPLICIT_CONVERT_HEX:     /* Used by ToHexString */
  626.             /*
  627.              * From ACPI: "If Data is a buffer, it is converted to a string of
  628.              * hexadecimal values separated by commas."
  629.              */
  630.             StringLength = (ObjDesc->Buffer.Length * 3);
  631.             break;
  632.  
  633.         default:
  634.             return_ACPI_STATUS (AE_BAD_PARAMETER);
  635.         }
  636.  
  637.         /*
  638.          * Create a new string object and string buffer
  639.          * (-1 because of extra separator included in StringLength from above)
  640.          * Allow creation of zero-length strings from zero-length buffers.
  641.          */
  642.         if (StringLength)
  643.         {
  644.             StringLength--;
  645.         }
  646.  
  647.         ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
  648.         if (!ReturnDesc)
  649.         {
  650.             return_ACPI_STATUS (AE_NO_MEMORY);
  651.         }
  652.  
  653.         NewBuf = ReturnDesc->Buffer.Pointer;
  654.  
  655.         /*
  656.          * Convert buffer bytes to hex or decimal values
  657.          * (separated by commas or spaces)
  658.          */
  659.         for (i = 0; i < ObjDesc->Buffer.Length; i++)
  660.         {
  661.             NewBuf += AcpiExConvertToAscii (
  662.                         (UINT64) ObjDesc->Buffer.Pointer[i], Base,
  663.                         NewBuf, 1);
  664.             *NewBuf++ = Separator; /* each separated by a comma or space */
  665.         }
  666.  
  667.         /*
  668.          * Null terminate the string
  669.          * (overwrites final comma/space from above)
  670.          */
  671.         if (ObjDesc->Buffer.Length)
  672.         {
  673.             NewBuf--;
  674.         }
  675.         *NewBuf = 0;
  676.         break;
  677.  
  678.     default:
  679.         return_ACPI_STATUS (AE_TYPE);
  680.     }
  681.  
  682.     *ResultDesc = ReturnDesc;
  683.     return_ACPI_STATUS (AE_OK);
  684. }
  685.  
  686.  
  687. /*******************************************************************************
  688.  *
  689.  * FUNCTION:    AcpiExConvertToTargetType
  690.  *
  691.  * PARAMETERS:  DestinationType     - Current type of the destination
  692.  *              SourceDesc          - Source object to be converted.
  693.  *              ResultDesc          - Where the converted object is returned
  694.  *              WalkState           - Current method state
  695.  *
  696.  * RETURN:      Status
  697.  *
  698.  * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
  699.  *
  700.  ******************************************************************************/
  701.  
  702. ACPI_STATUS
  703. AcpiExConvertToTargetType (
  704.     ACPI_OBJECT_TYPE        DestinationType,
  705.     ACPI_OPERAND_OBJECT     *SourceDesc,
  706.     ACPI_OPERAND_OBJECT     **ResultDesc,
  707.     ACPI_WALK_STATE         *WalkState)
  708. {
  709.     ACPI_STATUS             Status = AE_OK;
  710.  
  711.  
  712.     ACPI_FUNCTION_TRACE (ExConvertToTargetType);
  713.  
  714.  
  715.     /* Default behavior */
  716.  
  717.     *ResultDesc = SourceDesc;
  718.  
  719.     /*
  720.      * If required by the target,
  721.      * perform implicit conversion on the source before we store it.
  722.      */
  723.     switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs))
  724.     {
  725.     case ARGI_SIMPLE_TARGET:
  726.     case ARGI_FIXED_TARGET:
  727.     case ARGI_INTEGER_REF:      /* Handles Increment, Decrement cases */
  728.  
  729.         switch (DestinationType)
  730.         {
  731.         case ACPI_TYPE_LOCAL_REGION_FIELD:
  732.             /*
  733.              * Named field can always handle conversions
  734.              */
  735.             break;
  736.  
  737.         default:
  738.             /* No conversion allowed for these types */
  739.  
  740.             if (DestinationType != SourceDesc->Common.Type)
  741.             {
  742.                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  743.                     "Explicit operator, will store (%s) over existing type (%s)\n",
  744.                     AcpiUtGetObjectTypeName (SourceDesc),
  745.                     AcpiUtGetTypeName (DestinationType)));
  746.                 Status = AE_TYPE;
  747.             }
  748.         }
  749.         break;
  750.  
  751.  
  752.     case ARGI_TARGETREF:
  753.  
  754.         switch (DestinationType)
  755.         {
  756.         case ACPI_TYPE_INTEGER:
  757.         case ACPI_TYPE_BUFFER_FIELD:
  758.         case ACPI_TYPE_LOCAL_BANK_FIELD:
  759.         case ACPI_TYPE_LOCAL_INDEX_FIELD:
  760.             /*
  761.              * These types require an Integer operand. We can convert
  762.              * a Buffer or a String to an Integer if necessary.
  763.              */
  764.             Status = AcpiExConvertToInteger (SourceDesc, ResultDesc,
  765.                         16);
  766.             break;
  767.  
  768.  
  769.         case ACPI_TYPE_STRING:
  770.             /*
  771.              * The operand must be a String. We can convert an
  772.              * Integer or Buffer if necessary
  773.              */
  774.             Status = AcpiExConvertToString (SourceDesc, ResultDesc,
  775.                         ACPI_IMPLICIT_CONVERT_HEX);
  776.             break;
  777.  
  778.  
  779.         case ACPI_TYPE_BUFFER:
  780.             /*
  781.              * The operand must be a Buffer. We can convert an
  782.              * Integer or String if necessary
  783.              */
  784.             Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc);
  785.             break;
  786.  
  787.  
  788.         default:
  789.             ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: 0x%X",
  790.                 DestinationType));
  791.             Status = AE_AML_INTERNAL;
  792.             break;
  793.         }
  794.         break;
  795.  
  796.  
  797.     case ARGI_REFERENCE:
  798.         /*
  799.          * CreateXxxxField cases - we are storing the field object into the name
  800.          */
  801.         break;
  802.  
  803.  
  804.     default:
  805.         ACPI_ERROR ((AE_INFO,
  806.             "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
  807.             GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs),
  808.             WalkState->Opcode, AcpiUtGetTypeName (DestinationType)));
  809.         Status = AE_AML_INTERNAL;
  810.     }
  811.  
  812.     /*
  813.      * Source-to-Target conversion semantics:
  814.      *
  815.      * If conversion to the target type cannot be performed, then simply
  816.      * overwrite the target with the new object and type.
  817.      */
  818.     if (Status == AE_TYPE)
  819.     {
  820.         Status = AE_OK;
  821.     }
  822.  
  823.     return_ACPI_STATUS (Status);
  824. }
  825.  
  826.  
  827.