xref: /freebsd-src/sys/contrib/dev/acpica/components/utilities/utstrsuppt.c (revision 804fe2660352e090f4481f2c1d646b508859e79a)
12f6a1a81SJung-uk Kim /*******************************************************************************
22f6a1a81SJung-uk Kim  *
32f6a1a81SJung-uk Kim  * Module Name: utstrsuppt - Support functions for string-to-integer conversion
42f6a1a81SJung-uk Kim  *
52f6a1a81SJung-uk Kim  ******************************************************************************/
62f6a1a81SJung-uk Kim 
72f6a1a81SJung-uk Kim /******************************************************************************
82f6a1a81SJung-uk Kim  *
92f6a1a81SJung-uk Kim  * 1. Copyright Notice
102f6a1a81SJung-uk Kim  *
11*804fe266SJung-uk Kim  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
122f6a1a81SJung-uk Kim  * All rights reserved.
132f6a1a81SJung-uk Kim  *
142f6a1a81SJung-uk Kim  * 2. License
152f6a1a81SJung-uk Kim  *
162f6a1a81SJung-uk Kim  * 2.1. This is your license from Intel Corp. under its intellectual property
172f6a1a81SJung-uk Kim  * rights. You may have additional license terms from the party that provided
182f6a1a81SJung-uk Kim  * you this software, covering your right to use that party's intellectual
192f6a1a81SJung-uk Kim  * property rights.
202f6a1a81SJung-uk Kim  *
212f6a1a81SJung-uk Kim  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
222f6a1a81SJung-uk Kim  * copy of the source code appearing in this file ("Covered Code") an
232f6a1a81SJung-uk Kim  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
242f6a1a81SJung-uk Kim  * base code distributed originally by Intel ("Original Intel Code") to copy,
252f6a1a81SJung-uk Kim  * make derivatives, distribute, use and display any portion of the Covered
262f6a1a81SJung-uk Kim  * Code in any form, with the right to sublicense such rights; and
272f6a1a81SJung-uk Kim  *
282f6a1a81SJung-uk Kim  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
292f6a1a81SJung-uk Kim  * license (with the right to sublicense), under only those claims of Intel
302f6a1a81SJung-uk Kim  * patents that are infringed by the Original Intel Code, to make, use, sell,
312f6a1a81SJung-uk Kim  * offer to sell, and import the Covered Code and derivative works thereof
322f6a1a81SJung-uk Kim  * solely to the minimum extent necessary to exercise the above copyright
332f6a1a81SJung-uk Kim  * license, and in no event shall the patent license extend to any additions
342f6a1a81SJung-uk Kim  * to or modifications of the Original Intel Code. No other license or right
352f6a1a81SJung-uk Kim  * is granted directly or by implication, estoppel or otherwise;
362f6a1a81SJung-uk Kim  *
372f6a1a81SJung-uk Kim  * The above copyright and patent license is granted only if the following
382f6a1a81SJung-uk Kim  * conditions are met:
392f6a1a81SJung-uk Kim  *
402f6a1a81SJung-uk Kim  * 3. Conditions
412f6a1a81SJung-uk Kim  *
422f6a1a81SJung-uk Kim  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
432f6a1a81SJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
442f6a1a81SJung-uk Kim  * Code or modification with rights to further distribute source must include
452f6a1a81SJung-uk Kim  * the above Copyright Notice, the above License, this list of Conditions,
462f6a1a81SJung-uk Kim  * and the following Disclaimer and Export Compliance provision. In addition,
472f6a1a81SJung-uk Kim  * Licensee must cause all Covered Code to which Licensee contributes to
482f6a1a81SJung-uk Kim  * contain a file documenting the changes Licensee made to create that Covered
492f6a1a81SJung-uk Kim  * Code and the date of any change. Licensee must include in that file the
502f6a1a81SJung-uk Kim  * documentation of any changes made by any predecessor Licensee. Licensee
512f6a1a81SJung-uk Kim  * must include a prominent statement that the modification is derived,
522f6a1a81SJung-uk Kim  * directly or indirectly, from Original Intel Code.
532f6a1a81SJung-uk Kim  *
542f6a1a81SJung-uk Kim  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
552f6a1a81SJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
562f6a1a81SJung-uk Kim  * Code or modification without rights to further distribute source must
572f6a1a81SJung-uk Kim  * include the following Disclaimer and Export Compliance provision in the
582f6a1a81SJung-uk Kim  * documentation and/or other materials provided with distribution. In
592f6a1a81SJung-uk Kim  * addition, Licensee may not authorize further sublicense of source of any
602f6a1a81SJung-uk Kim  * portion of the Covered Code, and must include terms to the effect that the
612f6a1a81SJung-uk Kim  * license from Licensee to its licensee is limited to the intellectual
622f6a1a81SJung-uk Kim  * property embodied in the software Licensee provides to its licensee, and
632f6a1a81SJung-uk Kim  * not to intellectual property embodied in modifications its licensee may
642f6a1a81SJung-uk Kim  * make.
652f6a1a81SJung-uk Kim  *
662f6a1a81SJung-uk Kim  * 3.3. Redistribution of Executable. Redistribution in executable form of any
672f6a1a81SJung-uk Kim  * substantial portion of the Covered Code or modification must reproduce the
682f6a1a81SJung-uk Kim  * above Copyright Notice, and the following Disclaimer and Export Compliance
692f6a1a81SJung-uk Kim  * provision in the documentation and/or other materials provided with the
702f6a1a81SJung-uk Kim  * distribution.
712f6a1a81SJung-uk Kim  *
722f6a1a81SJung-uk Kim  * 3.4. Intel retains all right, title, and interest in and to the Original
732f6a1a81SJung-uk Kim  * Intel Code.
742f6a1a81SJung-uk Kim  *
752f6a1a81SJung-uk Kim  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
762f6a1a81SJung-uk Kim  * Intel shall be used in advertising or otherwise to promote the sale, use or
772f6a1a81SJung-uk Kim  * other dealings in products derived from or relating to the Covered Code
782f6a1a81SJung-uk Kim  * without prior written authorization from Intel.
792f6a1a81SJung-uk Kim  *
802f6a1a81SJung-uk Kim  * 4. Disclaimer and Export Compliance
812f6a1a81SJung-uk Kim  *
822f6a1a81SJung-uk Kim  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
832f6a1a81SJung-uk Kim  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
842f6a1a81SJung-uk Kim  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
852f6a1a81SJung-uk Kim  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
862f6a1a81SJung-uk Kim  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
872f6a1a81SJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
882f6a1a81SJung-uk Kim  * PARTICULAR PURPOSE.
892f6a1a81SJung-uk Kim  *
902f6a1a81SJung-uk Kim  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
912f6a1a81SJung-uk Kim  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
922f6a1a81SJung-uk Kim  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
932f6a1a81SJung-uk Kim  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
942f6a1a81SJung-uk Kim  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
952f6a1a81SJung-uk Kim  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
962f6a1a81SJung-uk Kim  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
972f6a1a81SJung-uk Kim  * LIMITED REMEDY.
982f6a1a81SJung-uk Kim  *
992f6a1a81SJung-uk Kim  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1002f6a1a81SJung-uk Kim  * software or system incorporating such software without first obtaining any
1012f6a1a81SJung-uk Kim  * required license or other approval from the U. S. Department of Commerce or
1022f6a1a81SJung-uk Kim  * any other agency or department of the United States Government. In the
1032f6a1a81SJung-uk Kim  * event Licensee exports any such software from the United States or
1042f6a1a81SJung-uk Kim  * re-exports any such software from a foreign destination, Licensee shall
1052f6a1a81SJung-uk Kim  * ensure that the distribution and export/re-export of the software is in
1062f6a1a81SJung-uk Kim  * compliance with all laws, regulations, orders, or other restrictions of the
1072f6a1a81SJung-uk Kim  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1082f6a1a81SJung-uk Kim  * any of its subsidiaries will export/re-export any technical data, process,
1092f6a1a81SJung-uk Kim  * software, or service, directly or indirectly, to any country for which the
1102f6a1a81SJung-uk Kim  * United States government or any agency thereof requires an export license,
1112f6a1a81SJung-uk Kim  * other governmental approval, or letter of assurance, without first obtaining
1122f6a1a81SJung-uk Kim  * such license, approval or letter.
1132f6a1a81SJung-uk Kim  *
1142f6a1a81SJung-uk Kim  *****************************************************************************
1152f6a1a81SJung-uk Kim  *
1162f6a1a81SJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
1172f6a1a81SJung-uk Kim  * following license:
1182f6a1a81SJung-uk Kim  *
1192f6a1a81SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
1202f6a1a81SJung-uk Kim  * modification, are permitted provided that the following conditions
1212f6a1a81SJung-uk Kim  * are met:
1222f6a1a81SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
1232f6a1a81SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
1242f6a1a81SJung-uk Kim  *    without modification.
1252f6a1a81SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1262f6a1a81SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
1272f6a1a81SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
1282f6a1a81SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
1292f6a1a81SJung-uk Kim  *    binary redistribution.
1302f6a1a81SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
1312f6a1a81SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
1322f6a1a81SJung-uk Kim  *    from this software without specific prior written permission.
1332f6a1a81SJung-uk Kim  *
1342f6a1a81SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1352f6a1a81SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1362f6a1a81SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1372f6a1a81SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1382f6a1a81SJung-uk Kim  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1392f6a1a81SJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1402f6a1a81SJung-uk Kim  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1412f6a1a81SJung-uk Kim  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1422f6a1a81SJung-uk Kim  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1432f6a1a81SJung-uk Kim  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1442f6a1a81SJung-uk Kim  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1452f6a1a81SJung-uk Kim  *
1462f6a1a81SJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
1472f6a1a81SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
1482f6a1a81SJung-uk Kim  * Software Foundation.
1492f6a1a81SJung-uk Kim  *
1502f6a1a81SJung-uk Kim  *****************************************************************************/
1512f6a1a81SJung-uk Kim 
1522f6a1a81SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
1532f6a1a81SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
1542f6a1a81SJung-uk Kim 
1552f6a1a81SJung-uk Kim #define _COMPONENT          ACPI_UTILITIES
1562f6a1a81SJung-uk Kim         ACPI_MODULE_NAME    ("utstrsuppt")
1572f6a1a81SJung-uk Kim 
1582f6a1a81SJung-uk Kim 
1592f6a1a81SJung-uk Kim /* Local prototypes */
1602f6a1a81SJung-uk Kim 
1612f6a1a81SJung-uk Kim static ACPI_STATUS
1622f6a1a81SJung-uk Kim AcpiUtInsertDigit (
1632f6a1a81SJung-uk Kim     UINT64                  *AccumulatedValue,
1642f6a1a81SJung-uk Kim     UINT32                  Base,
1652f6a1a81SJung-uk Kim     int                     AsciiDigit);
1662f6a1a81SJung-uk Kim 
1672f6a1a81SJung-uk Kim static ACPI_STATUS
1682f6a1a81SJung-uk Kim AcpiUtStrtoulMultiply64 (
1692f6a1a81SJung-uk Kim     UINT64                  Multiplicand,
170b7b7e711SJung-uk Kim     UINT32                  Base,
1712f6a1a81SJung-uk Kim     UINT64                  *OutProduct);
1722f6a1a81SJung-uk Kim 
1732f6a1a81SJung-uk Kim static ACPI_STATUS
1742f6a1a81SJung-uk Kim AcpiUtStrtoulAdd64 (
1752f6a1a81SJung-uk Kim     UINT64                  Addend1,
176b7b7e711SJung-uk Kim     UINT32                  Digit,
1772f6a1a81SJung-uk Kim     UINT64                  *OutSum);
1782f6a1a81SJung-uk Kim 
1792f6a1a81SJung-uk Kim 
1802f6a1a81SJung-uk Kim /*******************************************************************************
1812f6a1a81SJung-uk Kim  *
1822f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtConvertOctalString
1832f6a1a81SJung-uk Kim  *
1842f6a1a81SJung-uk Kim  * PARAMETERS:  String                  - Null terminated input string
1852f6a1a81SJung-uk Kim  *              ReturnValuePtr          - Where the converted value is returned
1862f6a1a81SJung-uk Kim  *
1872f6a1a81SJung-uk Kim  * RETURN:      Status and 64-bit converted integer
1882f6a1a81SJung-uk Kim  *
1892f6a1a81SJung-uk Kim  * DESCRIPTION: Performs a base 8 conversion of the input string to an
1902f6a1a81SJung-uk Kim  *              integer value, either 32 or 64 bits.
1912f6a1a81SJung-uk Kim  *
1922f6a1a81SJung-uk Kim  * NOTE:        Maximum 64-bit unsigned octal value is 01777777777777777777777
1932f6a1a81SJung-uk Kim  *              Maximum 32-bit unsigned octal value is 037777777777
1942f6a1a81SJung-uk Kim  *
1952f6a1a81SJung-uk Kim  ******************************************************************************/
1962f6a1a81SJung-uk Kim 
1972f6a1a81SJung-uk Kim ACPI_STATUS
1982f6a1a81SJung-uk Kim AcpiUtConvertOctalString (
1992f6a1a81SJung-uk Kim     char                    *String,
2002f6a1a81SJung-uk Kim     UINT64                  *ReturnValuePtr)
2012f6a1a81SJung-uk Kim {
2022f6a1a81SJung-uk Kim     UINT64                  AccumulatedValue = 0;
2032f6a1a81SJung-uk Kim     ACPI_STATUS             Status = AE_OK;
2042f6a1a81SJung-uk Kim 
2052f6a1a81SJung-uk Kim 
2062f6a1a81SJung-uk Kim     /* Convert each ASCII byte in the input string */
2072f6a1a81SJung-uk Kim 
2082f6a1a81SJung-uk Kim     while (*String)
2092f6a1a81SJung-uk Kim     {
210f15e9afbSJung-uk Kim         /*
211f15e9afbSJung-uk Kim          * Character must be ASCII 0-7, otherwise:
212f15e9afbSJung-uk Kim          * 1) Runtime: terminate with no error, per the ACPI spec
213f15e9afbSJung-uk Kim          * 2) Compiler: return an error
214f15e9afbSJung-uk Kim          */
2152f6a1a81SJung-uk Kim         if (!(ACPI_IS_OCTAL_DIGIT (*String)))
2162f6a1a81SJung-uk Kim         {
217f15e9afbSJung-uk Kim #ifdef ACPI_ASL_COMPILER
218f15e9afbSJung-uk Kim             Status = AE_BAD_OCTAL_CONSTANT;
219f15e9afbSJung-uk Kim #endif
2202f6a1a81SJung-uk Kim             break;
2212f6a1a81SJung-uk Kim         }
2222f6a1a81SJung-uk Kim 
2232f6a1a81SJung-uk Kim         /* Convert and insert this octal digit into the accumulator */
2242f6a1a81SJung-uk Kim 
2252f6a1a81SJung-uk Kim         Status = AcpiUtInsertDigit (&AccumulatedValue, 8, *String);
2262f6a1a81SJung-uk Kim         if (ACPI_FAILURE (Status))
2272f6a1a81SJung-uk Kim         {
2282f6a1a81SJung-uk Kim             Status = AE_OCTAL_OVERFLOW;
2292f6a1a81SJung-uk Kim             break;
2302f6a1a81SJung-uk Kim         }
2312f6a1a81SJung-uk Kim 
2322f6a1a81SJung-uk Kim         String++;
2332f6a1a81SJung-uk Kim     }
2342f6a1a81SJung-uk Kim 
2352f6a1a81SJung-uk Kim     /* Always return the value that has been accumulated */
2362f6a1a81SJung-uk Kim 
2372f6a1a81SJung-uk Kim     *ReturnValuePtr = AccumulatedValue;
2382f6a1a81SJung-uk Kim     return (Status);
2392f6a1a81SJung-uk Kim }
2402f6a1a81SJung-uk Kim 
2412f6a1a81SJung-uk Kim 
2422f6a1a81SJung-uk Kim /*******************************************************************************
2432f6a1a81SJung-uk Kim  *
2442f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtConvertDecimalString
2452f6a1a81SJung-uk Kim  *
2462f6a1a81SJung-uk Kim  * PARAMETERS:  String                  - Null terminated input string
2472f6a1a81SJung-uk Kim  *              ReturnValuePtr          - Where the converted value is returned
2482f6a1a81SJung-uk Kim  *
2492f6a1a81SJung-uk Kim  * RETURN:      Status and 64-bit converted integer
2502f6a1a81SJung-uk Kim  *
2512f6a1a81SJung-uk Kim  * DESCRIPTION: Performs a base 10 conversion of the input string to an
2522f6a1a81SJung-uk Kim  *              integer value, either 32 or 64 bits.
2532f6a1a81SJung-uk Kim  *
2542f6a1a81SJung-uk Kim  * NOTE:        Maximum 64-bit unsigned decimal value is 18446744073709551615
2552f6a1a81SJung-uk Kim  *              Maximum 32-bit unsigned decimal value is 4294967295
2562f6a1a81SJung-uk Kim  *
2572f6a1a81SJung-uk Kim  ******************************************************************************/
2582f6a1a81SJung-uk Kim 
2592f6a1a81SJung-uk Kim ACPI_STATUS
2602f6a1a81SJung-uk Kim AcpiUtConvertDecimalString (
2612f6a1a81SJung-uk Kim     char                    *String,
2622f6a1a81SJung-uk Kim     UINT64                  *ReturnValuePtr)
2632f6a1a81SJung-uk Kim {
2642f6a1a81SJung-uk Kim     UINT64                  AccumulatedValue = 0;
2652f6a1a81SJung-uk Kim     ACPI_STATUS             Status = AE_OK;
2662f6a1a81SJung-uk Kim 
2672f6a1a81SJung-uk Kim 
2682f6a1a81SJung-uk Kim     /* Convert each ASCII byte in the input string */
2692f6a1a81SJung-uk Kim 
2702f6a1a81SJung-uk Kim     while (*String)
2712f6a1a81SJung-uk Kim     {
272f15e9afbSJung-uk Kim         /*
273f15e9afbSJung-uk Kim          * Character must be ASCII 0-9, otherwise:
274f15e9afbSJung-uk Kim          * 1) Runtime: terminate with no error, per the ACPI spec
275f15e9afbSJung-uk Kim          * 2) Compiler: return an error
276f15e9afbSJung-uk Kim          */
277385fb5d9SJung-uk Kim         if (!isdigit ((int) *String))
2782f6a1a81SJung-uk Kim         {
279f15e9afbSJung-uk Kim #ifdef ACPI_ASL_COMPILER
280f15e9afbSJung-uk Kim             Status = AE_BAD_DECIMAL_CONSTANT;
281f15e9afbSJung-uk Kim #endif
2822f6a1a81SJung-uk Kim            break;
2832f6a1a81SJung-uk Kim         }
2842f6a1a81SJung-uk Kim 
2852f6a1a81SJung-uk Kim         /* Convert and insert this decimal digit into the accumulator */
2862f6a1a81SJung-uk Kim 
2872f6a1a81SJung-uk Kim         Status = AcpiUtInsertDigit (&AccumulatedValue, 10, *String);
2882f6a1a81SJung-uk Kim         if (ACPI_FAILURE (Status))
2892f6a1a81SJung-uk Kim         {
2902f6a1a81SJung-uk Kim             Status = AE_DECIMAL_OVERFLOW;
2912f6a1a81SJung-uk Kim             break;
2922f6a1a81SJung-uk Kim         }
2932f6a1a81SJung-uk Kim 
2942f6a1a81SJung-uk Kim         String++;
2952f6a1a81SJung-uk Kim     }
2962f6a1a81SJung-uk Kim 
2972f6a1a81SJung-uk Kim     /* Always return the value that has been accumulated */
2982f6a1a81SJung-uk Kim 
2992f6a1a81SJung-uk Kim     *ReturnValuePtr = AccumulatedValue;
3002f6a1a81SJung-uk Kim     return (Status);
3012f6a1a81SJung-uk Kim }
3022f6a1a81SJung-uk Kim 
3032f6a1a81SJung-uk Kim 
3042f6a1a81SJung-uk Kim /*******************************************************************************
3052f6a1a81SJung-uk Kim  *
3062f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtConvertHexString
3072f6a1a81SJung-uk Kim  *
3082f6a1a81SJung-uk Kim  * PARAMETERS:  String                  - Null terminated input string
3092f6a1a81SJung-uk Kim  *              ReturnValuePtr          - Where the converted value is returned
3102f6a1a81SJung-uk Kim  *
3112f6a1a81SJung-uk Kim  * RETURN:      Status and 64-bit converted integer
3122f6a1a81SJung-uk Kim  *
3132f6a1a81SJung-uk Kim  * DESCRIPTION: Performs a base 16 conversion of the input string to an
3142f6a1a81SJung-uk Kim  *              integer value, either 32 or 64 bits.
3152f6a1a81SJung-uk Kim  *
3162f6a1a81SJung-uk Kim  * NOTE:        Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF
3172f6a1a81SJung-uk Kim  *              Maximum 32-bit unsigned hex value is 0xFFFFFFFF
3182f6a1a81SJung-uk Kim  *
3192f6a1a81SJung-uk Kim  ******************************************************************************/
3202f6a1a81SJung-uk Kim 
3212f6a1a81SJung-uk Kim ACPI_STATUS
3222f6a1a81SJung-uk Kim AcpiUtConvertHexString (
3232f6a1a81SJung-uk Kim     char                    *String,
3242f6a1a81SJung-uk Kim     UINT64                  *ReturnValuePtr)
3252f6a1a81SJung-uk Kim {
3262f6a1a81SJung-uk Kim     UINT64                  AccumulatedValue = 0;
3272f6a1a81SJung-uk Kim     ACPI_STATUS             Status = AE_OK;
3282f6a1a81SJung-uk Kim 
3292f6a1a81SJung-uk Kim 
3302f6a1a81SJung-uk Kim     /* Convert each ASCII byte in the input string */
3312f6a1a81SJung-uk Kim 
3322f6a1a81SJung-uk Kim     while (*String)
3332f6a1a81SJung-uk Kim     {
334f15e9afbSJung-uk Kim         /*
335f15e9afbSJung-uk Kim          * Character must be ASCII A-F, a-f, or 0-9, otherwise:
336f15e9afbSJung-uk Kim          * 1) Runtime: terminate with no error, per the ACPI spec
337f15e9afbSJung-uk Kim          * 2) Compiler: return an error
338f15e9afbSJung-uk Kim          */
339385fb5d9SJung-uk Kim         if (!isxdigit ((int) *String))
3402f6a1a81SJung-uk Kim         {
341f15e9afbSJung-uk Kim #ifdef ACPI_ASL_COMPILER
342f15e9afbSJung-uk Kim             Status = AE_BAD_HEX_CONSTANT;
343f15e9afbSJung-uk Kim #endif
3442f6a1a81SJung-uk Kim             break;
3452f6a1a81SJung-uk Kim         }
3462f6a1a81SJung-uk Kim 
3472f6a1a81SJung-uk Kim         /* Convert and insert this hex digit into the accumulator */
3482f6a1a81SJung-uk Kim 
3492f6a1a81SJung-uk Kim         Status = AcpiUtInsertDigit (&AccumulatedValue, 16, *String);
3502f6a1a81SJung-uk Kim         if (ACPI_FAILURE (Status))
3512f6a1a81SJung-uk Kim         {
3522f6a1a81SJung-uk Kim             Status = AE_HEX_OVERFLOW;
3532f6a1a81SJung-uk Kim             break;
3542f6a1a81SJung-uk Kim         }
3552f6a1a81SJung-uk Kim 
3562f6a1a81SJung-uk Kim         String++;
3572f6a1a81SJung-uk Kim     }
3582f6a1a81SJung-uk Kim 
3592f6a1a81SJung-uk Kim     /* Always return the value that has been accumulated */
3602f6a1a81SJung-uk Kim 
3612f6a1a81SJung-uk Kim     *ReturnValuePtr = AccumulatedValue;
3622f6a1a81SJung-uk Kim     return (Status);
3632f6a1a81SJung-uk Kim }
3642f6a1a81SJung-uk Kim 
3652f6a1a81SJung-uk Kim 
3662f6a1a81SJung-uk Kim /*******************************************************************************
3672f6a1a81SJung-uk Kim  *
3682f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtRemoveLeadingZeros
3692f6a1a81SJung-uk Kim  *
3702f6a1a81SJung-uk Kim  * PARAMETERS:  String                  - Pointer to input ASCII string
3712f6a1a81SJung-uk Kim  *
3722f6a1a81SJung-uk Kim  * RETURN:      Next character after any leading zeros. This character may be
3732f6a1a81SJung-uk Kim  *              used by the caller to detect end-of-string.
3742f6a1a81SJung-uk Kim  *
3752f6a1a81SJung-uk Kim  * DESCRIPTION: Remove any leading zeros in the input string. Return the
3762f6a1a81SJung-uk Kim  *              next character after the final ASCII zero to enable the caller
3772f6a1a81SJung-uk Kim  *              to check for the end of the string (NULL terminator).
3782f6a1a81SJung-uk Kim  *
3792f6a1a81SJung-uk Kim  ******************************************************************************/
3802f6a1a81SJung-uk Kim 
3812f6a1a81SJung-uk Kim char
3822f6a1a81SJung-uk Kim AcpiUtRemoveLeadingZeros (
3832f6a1a81SJung-uk Kim     char                    **String)
3842f6a1a81SJung-uk Kim {
3852f6a1a81SJung-uk Kim 
3862f6a1a81SJung-uk Kim     while (**String == ACPI_ASCII_ZERO)
3872f6a1a81SJung-uk Kim     {
3882f6a1a81SJung-uk Kim         *String += 1;
3892f6a1a81SJung-uk Kim     }
3902f6a1a81SJung-uk Kim 
3912f6a1a81SJung-uk Kim     return (**String);
3922f6a1a81SJung-uk Kim }
3932f6a1a81SJung-uk Kim 
3942f6a1a81SJung-uk Kim 
3952f6a1a81SJung-uk Kim /*******************************************************************************
3962f6a1a81SJung-uk Kim  *
3972f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtRemoveWhitespace
3982f6a1a81SJung-uk Kim  *
3992f6a1a81SJung-uk Kim  * PARAMETERS:  String                  - Pointer to input ASCII string
4002f6a1a81SJung-uk Kim  *
4012f6a1a81SJung-uk Kim  * RETURN:      Next character after any whitespace. This character may be
4022f6a1a81SJung-uk Kim  *              used by the caller to detect end-of-string.
4032f6a1a81SJung-uk Kim  *
4042f6a1a81SJung-uk Kim  * DESCRIPTION: Remove any leading whitespace in the input string. Return the
4052f6a1a81SJung-uk Kim  *              next character after the final ASCII zero to enable the caller
4062f6a1a81SJung-uk Kim  *              to check for the end of the string (NULL terminator).
4072f6a1a81SJung-uk Kim  *
4082f6a1a81SJung-uk Kim  ******************************************************************************/
4092f6a1a81SJung-uk Kim 
4102f6a1a81SJung-uk Kim char
4112f6a1a81SJung-uk Kim AcpiUtRemoveWhitespace (
4122f6a1a81SJung-uk Kim     char                    **String)
4132f6a1a81SJung-uk Kim {
4142f6a1a81SJung-uk Kim 
4152f6a1a81SJung-uk Kim     while (isspace ((UINT8) **String))
4162f6a1a81SJung-uk Kim     {
4172f6a1a81SJung-uk Kim         *String += 1;
4182f6a1a81SJung-uk Kim     }
4192f6a1a81SJung-uk Kim 
4202f6a1a81SJung-uk Kim     return (**String);
4212f6a1a81SJung-uk Kim }
4222f6a1a81SJung-uk Kim 
4232f6a1a81SJung-uk Kim 
4242f6a1a81SJung-uk Kim /*******************************************************************************
4252f6a1a81SJung-uk Kim  *
4262f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtDetectHexPrefix
4272f6a1a81SJung-uk Kim  *
4282f6a1a81SJung-uk Kim  * PARAMETERS:  String                  - Pointer to input ASCII string
4292f6a1a81SJung-uk Kim  *
4302f6a1a81SJung-uk Kim  * RETURN:      TRUE if a "0x" prefix was found at the start of the string
4312f6a1a81SJung-uk Kim  *
4322f6a1a81SJung-uk Kim  * DESCRIPTION: Detect and remove a hex "0x" prefix
4332f6a1a81SJung-uk Kim  *
4342f6a1a81SJung-uk Kim  ******************************************************************************/
4352f6a1a81SJung-uk Kim 
4362f6a1a81SJung-uk Kim BOOLEAN
4372f6a1a81SJung-uk Kim AcpiUtDetectHexPrefix (
4382f6a1a81SJung-uk Kim     char                    **String)
4392f6a1a81SJung-uk Kim {
44051f42badSJung-uk Kim     char                    *InitialPosition = *String;
4412f6a1a81SJung-uk Kim 
44251f42badSJung-uk Kim     AcpiUtRemoveHexPrefix (String);
44351f42badSJung-uk Kim     if (*String != InitialPosition)
44451f42badSJung-uk Kim     {
44551f42badSJung-uk Kim         return (TRUE); /* String is past leading 0x */
44651f42badSJung-uk Kim     }
44751f42badSJung-uk Kim 
44851f42badSJung-uk Kim     return (FALSE);     /* Not a hex string */
44951f42badSJung-uk Kim }
45051f42badSJung-uk Kim 
45151f42badSJung-uk Kim 
45251f42badSJung-uk Kim /*******************************************************************************
45351f42badSJung-uk Kim  *
45451f42badSJung-uk Kim  * FUNCTION:    AcpiUtRemoveHexPrefix
45551f42badSJung-uk Kim  *
45651f42badSJung-uk Kim  * PARAMETERS:  String                  - Pointer to input ASCII string
45751f42badSJung-uk Kim  *
45851f42badSJung-uk Kim  * RETURN:      none
45951f42badSJung-uk Kim  *
46051f42badSJung-uk Kim  * DESCRIPTION: Remove a hex "0x" prefix
46151f42badSJung-uk Kim  *
46251f42badSJung-uk Kim  ******************************************************************************/
46351f42badSJung-uk Kim 
46451f42badSJung-uk Kim void
46551f42badSJung-uk Kim AcpiUtRemoveHexPrefix (
46651f42badSJung-uk Kim     char                    **String)
46751f42badSJung-uk Kim {
4682f6a1a81SJung-uk Kim     if ((**String == ACPI_ASCII_ZERO) &&
4692f6a1a81SJung-uk Kim         (tolower ((int) *(*String + 1)) == 'x'))
4702f6a1a81SJung-uk Kim     {
4712f6a1a81SJung-uk Kim         *String += 2;        /* Go past the leading 0x */
4722f6a1a81SJung-uk Kim     }
4732f6a1a81SJung-uk Kim }
4742f6a1a81SJung-uk Kim 
4752f6a1a81SJung-uk Kim 
4762f6a1a81SJung-uk Kim /*******************************************************************************
4772f6a1a81SJung-uk Kim  *
4782f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtDetectOctalPrefix
4792f6a1a81SJung-uk Kim  *
4802f6a1a81SJung-uk Kim  * PARAMETERS:  String                  - Pointer to input ASCII string
4812f6a1a81SJung-uk Kim  *
4822f6a1a81SJung-uk Kim  * RETURN:      True if an octal "0" prefix was found at the start of the
4832f6a1a81SJung-uk Kim  *              string
4842f6a1a81SJung-uk Kim  *
4852f6a1a81SJung-uk Kim  * DESCRIPTION: Detect and remove an octal prefix (zero)
4862f6a1a81SJung-uk Kim  *
4872f6a1a81SJung-uk Kim  ******************************************************************************/
4882f6a1a81SJung-uk Kim 
4892f6a1a81SJung-uk Kim BOOLEAN
4902f6a1a81SJung-uk Kim AcpiUtDetectOctalPrefix (
4912f6a1a81SJung-uk Kim     char                    **String)
4922f6a1a81SJung-uk Kim {
4932f6a1a81SJung-uk Kim 
4942f6a1a81SJung-uk Kim     if (**String == ACPI_ASCII_ZERO)
4952f6a1a81SJung-uk Kim     {
4962f6a1a81SJung-uk Kim         *String += 1;       /* Go past the leading 0 */
4972f6a1a81SJung-uk Kim         return (TRUE);
4982f6a1a81SJung-uk Kim     }
4992f6a1a81SJung-uk Kim 
5002f6a1a81SJung-uk Kim     return (FALSE);     /* Not an octal string */
5012f6a1a81SJung-uk Kim }
5022f6a1a81SJung-uk Kim 
5032f6a1a81SJung-uk Kim 
5042f6a1a81SJung-uk Kim /*******************************************************************************
5052f6a1a81SJung-uk Kim  *
5062f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtInsertDigit
5072f6a1a81SJung-uk Kim  *
5082f6a1a81SJung-uk Kim  * PARAMETERS:  AccumulatedValue        - Current value of the integer value
5092f6a1a81SJung-uk Kim  *                                        accumulator. The new value is
5102f6a1a81SJung-uk Kim  *                                        returned here.
5112f6a1a81SJung-uk Kim  *              Base                    - Radix, either 8/10/16
5122f6a1a81SJung-uk Kim  *              AsciiDigit              - ASCII single digit to be inserted
5132f6a1a81SJung-uk Kim  *
5142f6a1a81SJung-uk Kim  * RETURN:      Status and result of the convert/insert operation. The only
5152f6a1a81SJung-uk Kim  *              possible returned exception code is numeric overflow of
5162f6a1a81SJung-uk Kim  *              either the multiply or add conversion operations.
5172f6a1a81SJung-uk Kim  *
5182f6a1a81SJung-uk Kim  * DESCRIPTION: Generic conversion and insertion function for all bases:
5192f6a1a81SJung-uk Kim  *
5202f6a1a81SJung-uk Kim  *              1) Multiply the current accumulated/converted value by the
5212f6a1a81SJung-uk Kim  *              base in order to make room for the new character.
5222f6a1a81SJung-uk Kim  *
5232f6a1a81SJung-uk Kim  *              2) Convert the new character to binary and add it to the
5242f6a1a81SJung-uk Kim  *              current accumulated value.
5252f6a1a81SJung-uk Kim  *
5262f6a1a81SJung-uk Kim  *              Note: The only possible exception indicates an integer
5272f6a1a81SJung-uk Kim  *              overflow (AE_NUMERIC_OVERFLOW)
5282f6a1a81SJung-uk Kim  *
5292f6a1a81SJung-uk Kim  ******************************************************************************/
5302f6a1a81SJung-uk Kim 
5312f6a1a81SJung-uk Kim static ACPI_STATUS
5322f6a1a81SJung-uk Kim AcpiUtInsertDigit (
5332f6a1a81SJung-uk Kim     UINT64                  *AccumulatedValue,
5342f6a1a81SJung-uk Kim     UINT32                  Base,
5352f6a1a81SJung-uk Kim     int                     AsciiDigit)
5362f6a1a81SJung-uk Kim {
5372f6a1a81SJung-uk Kim     ACPI_STATUS             Status;
5382f6a1a81SJung-uk Kim     UINT64                  Product;
5392f6a1a81SJung-uk Kim 
5402f6a1a81SJung-uk Kim 
5412f6a1a81SJung-uk Kim      /* Make room in the accumulated value for the incoming digit */
5422f6a1a81SJung-uk Kim 
5432f6a1a81SJung-uk Kim     Status = AcpiUtStrtoulMultiply64 (*AccumulatedValue, Base, &Product);
5442f6a1a81SJung-uk Kim     if (ACPI_FAILURE (Status))
5452f6a1a81SJung-uk Kim     {
5462f6a1a81SJung-uk Kim         return (Status);
5472f6a1a81SJung-uk Kim     }
5482f6a1a81SJung-uk Kim 
5492f6a1a81SJung-uk Kim     /* Add in the new digit, and store the sum to the accumulated value */
5502f6a1a81SJung-uk Kim 
5512f6a1a81SJung-uk Kim     Status = AcpiUtStrtoulAdd64 (Product, AcpiUtAsciiCharToHex (AsciiDigit),
5522f6a1a81SJung-uk Kim         AccumulatedValue);
5532f6a1a81SJung-uk Kim 
5542f6a1a81SJung-uk Kim     return (Status);
5552f6a1a81SJung-uk Kim }
5562f6a1a81SJung-uk Kim 
5572f6a1a81SJung-uk Kim 
5582f6a1a81SJung-uk Kim /*******************************************************************************
5592f6a1a81SJung-uk Kim  *
5602f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtStrtoulMultiply64
5612f6a1a81SJung-uk Kim  *
5622f6a1a81SJung-uk Kim  * PARAMETERS:  Multiplicand            - Current accumulated converted integer
563b7b7e711SJung-uk Kim  *              Base                    - Base/Radix
5642f6a1a81SJung-uk Kim  *              OutProduct              - Where the product is returned
5652f6a1a81SJung-uk Kim  *
5662f6a1a81SJung-uk Kim  * RETURN:      Status and 64-bit product
5672f6a1a81SJung-uk Kim  *
5682f6a1a81SJung-uk Kim  * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as
5692f6a1a81SJung-uk Kim  *              well as 32-bit overflow if necessary (if the current global
5702f6a1a81SJung-uk Kim  *              integer width is 32).
5712f6a1a81SJung-uk Kim  *
5722f6a1a81SJung-uk Kim  ******************************************************************************/
5732f6a1a81SJung-uk Kim 
5742f6a1a81SJung-uk Kim static ACPI_STATUS
5752f6a1a81SJung-uk Kim AcpiUtStrtoulMultiply64 (
5762f6a1a81SJung-uk Kim     UINT64                  Multiplicand,
577b7b7e711SJung-uk Kim     UINT32                  Base,
5782f6a1a81SJung-uk Kim     UINT64                  *OutProduct)
5792f6a1a81SJung-uk Kim {
5802f6a1a81SJung-uk Kim     UINT64                  Product;
581b7b7e711SJung-uk Kim     UINT64                  Quotient;
5822f6a1a81SJung-uk Kim 
5832f6a1a81SJung-uk Kim 
5842f6a1a81SJung-uk Kim     /* Exit if either operand is zero */
5852f6a1a81SJung-uk Kim 
5862f6a1a81SJung-uk Kim     *OutProduct = 0;
587b7b7e711SJung-uk Kim     if (!Multiplicand || !Base)
5882f6a1a81SJung-uk Kim     {
5892f6a1a81SJung-uk Kim         return (AE_OK);
5902f6a1a81SJung-uk Kim     }
5912f6a1a81SJung-uk Kim 
592b7b7e711SJung-uk Kim     /*
593b7b7e711SJung-uk Kim      * Check for 64-bit overflow before the actual multiplication.
594b7b7e711SJung-uk Kim      *
595b7b7e711SJung-uk Kim      * Notes: 64-bit division is often not supported on 32-bit platforms
596b7b7e711SJung-uk Kim      * (it requires a library function), Therefore ACPICA has a local
597b7b7e711SJung-uk Kim      * 64-bit divide function. Also, Multiplier is currently only used
598b7b7e711SJung-uk Kim      * as the radix (8/10/16), to the 64/32 divide will always work.
599b7b7e711SJung-uk Kim      */
600b7b7e711SJung-uk Kim     AcpiUtShortDivide (ACPI_UINT64_MAX, Base, &Quotient, NULL);
601b7b7e711SJung-uk Kim     if (Multiplicand > Quotient)
6022f6a1a81SJung-uk Kim     {
6032f6a1a81SJung-uk Kim         return (AE_NUMERIC_OVERFLOW);
6042f6a1a81SJung-uk Kim     }
6052f6a1a81SJung-uk Kim 
606b7b7e711SJung-uk Kim     Product = Multiplicand * Base;
6072f6a1a81SJung-uk Kim 
6082f6a1a81SJung-uk Kim     /* Check for 32-bit overflow if necessary */
6092f6a1a81SJung-uk Kim 
6102f6a1a81SJung-uk Kim     if ((AcpiGbl_IntegerBitWidth == 32) && (Product > ACPI_UINT32_MAX))
6112f6a1a81SJung-uk Kim     {
6122f6a1a81SJung-uk Kim         return (AE_NUMERIC_OVERFLOW);
6132f6a1a81SJung-uk Kim     }
6142f6a1a81SJung-uk Kim 
6152f6a1a81SJung-uk Kim     *OutProduct = Product;
6162f6a1a81SJung-uk Kim     return (AE_OK);
6172f6a1a81SJung-uk Kim }
6182f6a1a81SJung-uk Kim 
6192f6a1a81SJung-uk Kim 
6202f6a1a81SJung-uk Kim /*******************************************************************************
6212f6a1a81SJung-uk Kim  *
6222f6a1a81SJung-uk Kim  * FUNCTION:    AcpiUtStrtoulAdd64
6232f6a1a81SJung-uk Kim  *
6242f6a1a81SJung-uk Kim  * PARAMETERS:  Addend1                 - Current accumulated converted integer
625b7b7e711SJung-uk Kim  *              Digit                   - New hex value/char
6262f6a1a81SJung-uk Kim  *              OutSum                  - Where sum is returned (Accumulator)
6272f6a1a81SJung-uk Kim  *
6282f6a1a81SJung-uk Kim  * RETURN:      Status and 64-bit sum
6292f6a1a81SJung-uk Kim  *
6302f6a1a81SJung-uk Kim  * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as
6312f6a1a81SJung-uk Kim  *              well as 32-bit overflow if necessary (if the current global
6322f6a1a81SJung-uk Kim  *              integer width is 32).
6332f6a1a81SJung-uk Kim  *
6342f6a1a81SJung-uk Kim  ******************************************************************************/
6352f6a1a81SJung-uk Kim 
6362f6a1a81SJung-uk Kim static ACPI_STATUS
6372f6a1a81SJung-uk Kim AcpiUtStrtoulAdd64 (
6382f6a1a81SJung-uk Kim     UINT64                  Addend1,
639b7b7e711SJung-uk Kim     UINT32                  Digit,
6402f6a1a81SJung-uk Kim     UINT64                  *OutSum)
6412f6a1a81SJung-uk Kim {
6422f6a1a81SJung-uk Kim     UINT64                  Sum;
6432f6a1a81SJung-uk Kim 
6442f6a1a81SJung-uk Kim 
6452f6a1a81SJung-uk Kim     /* Check for 64-bit overflow before the actual addition */
6462f6a1a81SJung-uk Kim 
647b7b7e711SJung-uk Kim     if ((Addend1 > 0) && (Digit > (ACPI_UINT64_MAX - Addend1)))
6482f6a1a81SJung-uk Kim     {
6492f6a1a81SJung-uk Kim         return (AE_NUMERIC_OVERFLOW);
6502f6a1a81SJung-uk Kim     }
6512f6a1a81SJung-uk Kim 
652b7b7e711SJung-uk Kim     Sum = Addend1 + Digit;
6532f6a1a81SJung-uk Kim 
6542f6a1a81SJung-uk Kim     /* Check for 32-bit overflow if necessary */
6552f6a1a81SJung-uk Kim 
6562f6a1a81SJung-uk Kim     if ((AcpiGbl_IntegerBitWidth == 32) && (Sum > ACPI_UINT32_MAX))
6572f6a1a81SJung-uk Kim     {
6582f6a1a81SJung-uk Kim         return (AE_NUMERIC_OVERFLOW);
6592f6a1a81SJung-uk Kim     }
6602f6a1a81SJung-uk Kim 
6612f6a1a81SJung-uk Kim     *OutSum = Sum;
6622f6a1a81SJung-uk Kim     return (AE_OK);
6632f6a1a81SJung-uk Kim }
664