162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/******************************************************************************* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: utstrtoul64 - String-to-integer conversion support for both 562306a36Sopenharmony_ci * 64-bit and 32-bit integers 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci ******************************************************************************/ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <acpi/acpi.h> 1062306a36Sopenharmony_ci#include "accommon.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define _COMPONENT ACPI_UTILITIES 1362306a36Sopenharmony_ciACPI_MODULE_NAME("utstrtoul64") 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/******************************************************************************* 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * This module contains the top-level string to 64/32-bit unsigned integer 1862306a36Sopenharmony_ci * conversion functions: 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * 1) A standard strtoul() function that supports 64-bit integers, base 2162306a36Sopenharmony_ci * 8/10/16, with integer overflow support. This is used mainly by the 2262306a36Sopenharmony_ci * iASL compiler, which implements tighter constraints on integer 2362306a36Sopenharmony_ci * constants than the runtime (interpreter) integer-to-string conversions. 2462306a36Sopenharmony_ci * 2) Runtime "Explicit conversion" as defined in the ACPI specification. 2562306a36Sopenharmony_ci * 3) Runtime "Implicit conversion" as defined in the ACPI specification. 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * Current users of this module: 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * iASL - Preprocessor (constants and math expressions) 3062306a36Sopenharmony_ci * iASL - Main parser, conversion of constants to integers 3162306a36Sopenharmony_ci * iASL - Data Table Compiler parser (constants and math expressions) 3262306a36Sopenharmony_ci * interpreter - Implicit and explicit conversions, GPE method names 3362306a36Sopenharmony_ci * interpreter - Repair code for return values from predefined names 3462306a36Sopenharmony_ci * debugger - Command line input string conversion 3562306a36Sopenharmony_ci * acpi_dump - ACPI table physical addresses 3662306a36Sopenharmony_ci * acpi_exec - Support for namespace overrides 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * Notes concerning users of these interfaces: 3962306a36Sopenharmony_ci * 4062306a36Sopenharmony_ci * acpi_gbl_integer_byte_width is used to set the 32/64 bit limit for explicit 4162306a36Sopenharmony_ci * and implicit conversions. This global must be set to the proper width. 4262306a36Sopenharmony_ci * For the core ACPICA code, the width depends on the DSDT version. For the 4362306a36Sopenharmony_ci * acpi_ut_strtoul64 interface, all conversions are 64 bits. This interface is 4462306a36Sopenharmony_ci * used primarily for iASL, where the default width is 64 bits for all parsers, 4562306a36Sopenharmony_ci * but error checking is performed later to flag cases where a 64-bit constant 4662306a36Sopenharmony_ci * is wrongly defined in a 32-bit DSDT/SSDT. 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * In ACPI, the only place where octal numbers are supported is within 4962306a36Sopenharmony_ci * the ASL language itself. This is implemented via the main acpi_ut_strtoul64 5062306a36Sopenharmony_ci * interface. According the ACPI specification, there is no ACPI runtime 5162306a36Sopenharmony_ci * support (explicit/implicit) for octal string conversions. 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci ******************************************************************************/ 5462306a36Sopenharmony_ci/******************************************************************************* 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * FUNCTION: acpi_ut_strtoul64 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * PARAMETERS: string - Null terminated input string, 5962306a36Sopenharmony_ci * must be a valid pointer 6062306a36Sopenharmony_ci * return_value - Where the converted integer is 6162306a36Sopenharmony_ci * returned. Must be a valid pointer 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * RETURN: Status and converted integer. Returns an exception on a 6462306a36Sopenharmony_ci * 64-bit numeric overflow 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * DESCRIPTION: Convert a string into an unsigned integer. Always performs a 6762306a36Sopenharmony_ci * full 64-bit conversion, regardless of the current global 6862306a36Sopenharmony_ci * integer width. Supports Decimal, Hex, and Octal strings. 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * Current users of this function: 7162306a36Sopenharmony_ci * 7262306a36Sopenharmony_ci * iASL - Preprocessor (constants and math expressions) 7362306a36Sopenharmony_ci * iASL - Main ASL parser, conversion of ASL constants to integers 7462306a36Sopenharmony_ci * iASL - Data Table Compiler parser (constants and math expressions) 7562306a36Sopenharmony_ci * interpreter - Repair code for return values from predefined names 7662306a36Sopenharmony_ci * acpi_dump - ACPI table physical addresses 7762306a36Sopenharmony_ci * acpi_exec - Support for namespace overrides 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci ******************************************************************************/ 8062306a36Sopenharmony_ciacpi_status acpi_ut_strtoul64(char *string, u64 *return_value) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci acpi_status status = AE_OK; 8362306a36Sopenharmony_ci u8 original_bit_width; 8462306a36Sopenharmony_ci u32 base = 10; /* Default is decimal */ 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci *return_value = 0; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* A NULL return string returns a value of zero */ 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci if (*string == 0) { 9362306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 9462306a36Sopenharmony_ci } 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci if (!acpi_ut_remove_whitespace(&string)) { 9762306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* 10162306a36Sopenharmony_ci * 1) Check for a hex constant. A "0x" prefix indicates base 16. 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_ci if (acpi_ut_detect_hex_prefix(&string)) { 10462306a36Sopenharmony_ci base = 16; 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* 10862306a36Sopenharmony_ci * 2) Check for an octal constant, defined to be a leading zero 10962306a36Sopenharmony_ci * followed by sequence of octal digits (0-7) 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci else if (acpi_ut_detect_octal_prefix(&string)) { 11262306a36Sopenharmony_ci base = 8; 11362306a36Sopenharmony_ci } 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (!acpi_ut_remove_leading_zeros(&string)) { 11662306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); /* Return value 0 */ 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci /* 12062306a36Sopenharmony_ci * Force a full 64-bit conversion. The caller (usually iASL) must 12162306a36Sopenharmony_ci * check for a 32-bit overflow later as necessary (If current mode 12262306a36Sopenharmony_ci * is 32-bit, meaning a 32-bit DSDT). 12362306a36Sopenharmony_ci */ 12462306a36Sopenharmony_ci original_bit_width = acpi_gbl_integer_bit_width; 12562306a36Sopenharmony_ci acpi_gbl_integer_bit_width = 64; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci /* 12862306a36Sopenharmony_ci * Perform the base 8, 10, or 16 conversion. A 64-bit numeric overflow 12962306a36Sopenharmony_ci * will return an exception (to allow iASL to flag the statement). 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_ci switch (base) { 13262306a36Sopenharmony_ci case 8: 13362306a36Sopenharmony_ci status = acpi_ut_convert_octal_string(string, return_value); 13462306a36Sopenharmony_ci break; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci case 10: 13762306a36Sopenharmony_ci status = acpi_ut_convert_decimal_string(string, return_value); 13862306a36Sopenharmony_ci break; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci case 16: 14162306a36Sopenharmony_ci default: 14262306a36Sopenharmony_ci status = acpi_ut_convert_hex_string(string, return_value); 14362306a36Sopenharmony_ci break; 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci /* Only possible exception from above is a 64-bit overflow */ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci acpi_gbl_integer_bit_width = original_bit_width; 14962306a36Sopenharmony_ci return_ACPI_STATUS(status); 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci/******************************************************************************* 15362306a36Sopenharmony_ci * 15462306a36Sopenharmony_ci * FUNCTION: acpi_ut_implicit_strtoul64 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * PARAMETERS: string - Null terminated input string, 15762306a36Sopenharmony_ci * must be a valid pointer 15862306a36Sopenharmony_ci * 15962306a36Sopenharmony_ci * RETURN: Converted integer 16062306a36Sopenharmony_ci * 16162306a36Sopenharmony_ci * DESCRIPTION: Perform a 64-bit conversion with restrictions placed upon 16262306a36Sopenharmony_ci * an "implicit conversion" by the ACPI specification. Used by 16362306a36Sopenharmony_ci * many ASL operators that require an integer operand, and support 16462306a36Sopenharmony_ci * an automatic (implicit) conversion from a string operand 16562306a36Sopenharmony_ci * to the final integer operand. The major restriction is that 16662306a36Sopenharmony_ci * only hex strings are supported. 16762306a36Sopenharmony_ci * 16862306a36Sopenharmony_ci * ----------------------------------------------------------------------------- 16962306a36Sopenharmony_ci * 17062306a36Sopenharmony_ci * Base is always 16, either with or without the 0x prefix. Decimal and 17162306a36Sopenharmony_ci * Octal strings are not supported, as per the ACPI specification. 17262306a36Sopenharmony_ci * 17362306a36Sopenharmony_ci * Examples (both are hex values): 17462306a36Sopenharmony_ci * Add ("BA98", Arg0, Local0) 17562306a36Sopenharmony_ci * Subtract ("0x12345678", Arg1, Local1) 17662306a36Sopenharmony_ci * 17762306a36Sopenharmony_ci * Conversion rules as extracted from the ACPI specification: 17862306a36Sopenharmony_ci * 17962306a36Sopenharmony_ci * The converted integer is initialized to the value zero. 18062306a36Sopenharmony_ci * The ASCII string is always interpreted as a hexadecimal constant. 18162306a36Sopenharmony_ci * 18262306a36Sopenharmony_ci * 1) According to the ACPI specification, a "0x" prefix is not allowed. 18362306a36Sopenharmony_ci * However, ACPICA allows this as an ACPI extension on general 18462306a36Sopenharmony_ci * principle. (NO ERROR) 18562306a36Sopenharmony_ci * 18662306a36Sopenharmony_ci * 2) The conversion terminates when the size of an integer is reached 18762306a36Sopenharmony_ci * (32 or 64 bits). There are no numeric overflow conditions. (NO ERROR) 18862306a36Sopenharmony_ci * 18962306a36Sopenharmony_ci * 3) The first non-hex character terminates the conversion and returns 19062306a36Sopenharmony_ci * the current accumulated value of the converted integer (NO ERROR). 19162306a36Sopenharmony_ci * 19262306a36Sopenharmony_ci * 4) Conversion of a null (zero-length) string to an integer is 19362306a36Sopenharmony_ci * technically not allowed. However, ACPICA allows this as an ACPI 19462306a36Sopenharmony_ci * extension. The conversion returns the value 0. (NO ERROR) 19562306a36Sopenharmony_ci * 19662306a36Sopenharmony_ci * NOTE: There are no error conditions returned by this function. At 19762306a36Sopenharmony_ci * the minimum, a value of zero is returned. 19862306a36Sopenharmony_ci * 19962306a36Sopenharmony_ci * Current users of this function: 20062306a36Sopenharmony_ci * 20162306a36Sopenharmony_ci * interpreter - All runtime implicit conversions, as per ACPI specification 20262306a36Sopenharmony_ci * iASL - Data Table Compiler parser (constants and math expressions) 20362306a36Sopenharmony_ci * 20462306a36Sopenharmony_ci ******************************************************************************/ 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ciu64 acpi_ut_implicit_strtoul64(char *string) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci u64 converted_integer = 0; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci ACPI_FUNCTION_TRACE_STR(ut_implicit_strtoul64, string); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci if (!acpi_ut_remove_whitespace(&string)) { 21362306a36Sopenharmony_ci return_VALUE(0); 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* 21762306a36Sopenharmony_ci * Per the ACPI specification, only hexadecimal is supported for 21862306a36Sopenharmony_ci * implicit conversions, and the "0x" prefix is "not allowed". 21962306a36Sopenharmony_ci * However, allow a "0x" prefix as an ACPI extension. 22062306a36Sopenharmony_ci */ 22162306a36Sopenharmony_ci acpi_ut_remove_hex_prefix(&string); 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci if (!acpi_ut_remove_leading_zeros(&string)) { 22462306a36Sopenharmony_ci return_VALUE(0); 22562306a36Sopenharmony_ci } 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci /* 22862306a36Sopenharmony_ci * Ignore overflow as per the ACPI specification. This is implemented by 22962306a36Sopenharmony_ci * ignoring the return status from the conversion function called below. 23062306a36Sopenharmony_ci * On overflow, the input string is simply truncated. 23162306a36Sopenharmony_ci */ 23262306a36Sopenharmony_ci acpi_ut_convert_hex_string(string, &converted_integer); 23362306a36Sopenharmony_ci return_VALUE(converted_integer); 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci/******************************************************************************* 23762306a36Sopenharmony_ci * 23862306a36Sopenharmony_ci * FUNCTION: acpi_ut_explicit_strtoul64 23962306a36Sopenharmony_ci * 24062306a36Sopenharmony_ci * PARAMETERS: string - Null terminated input string, 24162306a36Sopenharmony_ci * must be a valid pointer 24262306a36Sopenharmony_ci * 24362306a36Sopenharmony_ci * RETURN: Converted integer 24462306a36Sopenharmony_ci * 24562306a36Sopenharmony_ci * DESCRIPTION: Perform a 64-bit conversion with the restrictions placed upon 24662306a36Sopenharmony_ci * an "explicit conversion" by the ACPI specification. The 24762306a36Sopenharmony_ci * main restriction is that only hex and decimal are supported. 24862306a36Sopenharmony_ci * 24962306a36Sopenharmony_ci * ----------------------------------------------------------------------------- 25062306a36Sopenharmony_ci * 25162306a36Sopenharmony_ci * Base is either 10 (default) or 16 (with 0x prefix). Octal (base 8) strings 25262306a36Sopenharmony_ci * are not supported, as per the ACPI specification. 25362306a36Sopenharmony_ci * 25462306a36Sopenharmony_ci * Examples: 25562306a36Sopenharmony_ci * to_integer ("1000") Decimal 25662306a36Sopenharmony_ci * to_integer ("0xABCD") Hex 25762306a36Sopenharmony_ci * 25862306a36Sopenharmony_ci * Conversion rules as extracted from the ACPI specification: 25962306a36Sopenharmony_ci * 26062306a36Sopenharmony_ci * 1) The input string is either a decimal or hexadecimal numeric string. 26162306a36Sopenharmony_ci * A hex value must be prefixed by "0x" or it is interpreted as decimal. 26262306a36Sopenharmony_ci * 26362306a36Sopenharmony_ci * 2) The value must not exceed the maximum of an integer value 26462306a36Sopenharmony_ci * (32 or 64 bits). The ACPI specification states the behavior is 26562306a36Sopenharmony_ci * "unpredictable", so ACPICA matches the behavior of the implicit 26662306a36Sopenharmony_ci * conversion case. There are no numeric overflow conditions. (NO ERROR) 26762306a36Sopenharmony_ci * 26862306a36Sopenharmony_ci * 3) Behavior on the first non-hex character is not defined by the ACPI 26962306a36Sopenharmony_ci * specification (for the to_integer operator), so ACPICA matches the 27062306a36Sopenharmony_ci * behavior of the implicit conversion case. It terminates the 27162306a36Sopenharmony_ci * conversion and returns the current accumulated value of the converted 27262306a36Sopenharmony_ci * integer. (NO ERROR) 27362306a36Sopenharmony_ci * 27462306a36Sopenharmony_ci * 4) Conversion of a null (zero-length) string to an integer is 27562306a36Sopenharmony_ci * technically not allowed. However, ACPICA allows this as an ACPI 27662306a36Sopenharmony_ci * extension. The conversion returns the value 0. (NO ERROR) 27762306a36Sopenharmony_ci * 27862306a36Sopenharmony_ci * NOTE: There are no error conditions returned by this function. At the 27962306a36Sopenharmony_ci * minimum, a value of zero is returned. 28062306a36Sopenharmony_ci * 28162306a36Sopenharmony_ci * Current users of this function: 28262306a36Sopenharmony_ci * 28362306a36Sopenharmony_ci * interpreter - Runtime ASL to_integer operator, as per the ACPI specification 28462306a36Sopenharmony_ci * 28562306a36Sopenharmony_ci ******************************************************************************/ 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ciu64 acpi_ut_explicit_strtoul64(char *string) 28862306a36Sopenharmony_ci{ 28962306a36Sopenharmony_ci u64 converted_integer = 0; 29062306a36Sopenharmony_ci u32 base = 10; /* Default is decimal */ 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci ACPI_FUNCTION_TRACE_STR(ut_explicit_strtoul64, string); 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci if (!acpi_ut_remove_whitespace(&string)) { 29562306a36Sopenharmony_ci return_VALUE(0); 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci /* 29962306a36Sopenharmony_ci * Only Hex and Decimal are supported, as per the ACPI specification. 30062306a36Sopenharmony_ci * A "0x" prefix indicates hex; otherwise decimal is assumed. 30162306a36Sopenharmony_ci */ 30262306a36Sopenharmony_ci if (acpi_ut_detect_hex_prefix(&string)) { 30362306a36Sopenharmony_ci base = 16; 30462306a36Sopenharmony_ci } 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci if (!acpi_ut_remove_leading_zeros(&string)) { 30762306a36Sopenharmony_ci return_VALUE(0); 30862306a36Sopenharmony_ci } 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci /* 31162306a36Sopenharmony_ci * Ignore overflow as per the ACPI specification. This is implemented by 31262306a36Sopenharmony_ci * ignoring the return status from the conversion functions called below. 31362306a36Sopenharmony_ci * On overflow, the input string is simply truncated. 31462306a36Sopenharmony_ci */ 31562306a36Sopenharmony_ci switch (base) { 31662306a36Sopenharmony_ci case 10: 31762306a36Sopenharmony_ci default: 31862306a36Sopenharmony_ci acpi_ut_convert_decimal_string(string, &converted_integer); 31962306a36Sopenharmony_ci break; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci case 16: 32262306a36Sopenharmony_ci acpi_ut_convert_hex_string(string, &converted_integer); 32362306a36Sopenharmony_ci break; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci return_VALUE(converted_integer); 32762306a36Sopenharmony_ci} 328