162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: utpredef - support functions for predefined names 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci *****************************************************************************/ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <acpi/acpi.h> 1162306a36Sopenharmony_ci#include "accommon.h" 1262306a36Sopenharmony_ci#include "acpredef.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define _COMPONENT ACPI_UTILITIES 1562306a36Sopenharmony_ciACPI_MODULE_NAME("utpredef") 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * Names for the types that can be returned by the predefined objects. 1962306a36Sopenharmony_ci * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_cistatic const char *ut_rtype_names[] = { 2262306a36Sopenharmony_ci "/Integer", 2362306a36Sopenharmony_ci "/String", 2462306a36Sopenharmony_ci "/Buffer", 2562306a36Sopenharmony_ci "/Package", 2662306a36Sopenharmony_ci "/Reference", 2762306a36Sopenharmony_ci}; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/******************************************************************************* 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * FUNCTION: acpi_ut_get_next_predefined_method 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * PARAMETERS: this_name - Entry in the predefined method/name table 3462306a36Sopenharmony_ci * 3562306a36Sopenharmony_ci * RETURN: Pointer to next entry in predefined table. 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci * DESCRIPTION: Get the next entry in the predefine method table. Handles the 3862306a36Sopenharmony_ci * cases where a package info entry follows a method name that 3962306a36Sopenharmony_ci * returns a package. 4062306a36Sopenharmony_ci * 4162306a36Sopenharmony_ci ******************************************************************************/ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciconst union acpi_predefined_info *acpi_ut_get_next_predefined_method(const union 4462306a36Sopenharmony_ci acpi_predefined_info 4562306a36Sopenharmony_ci *this_name) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci /* 4962306a36Sopenharmony_ci * Skip next entry in the table if this name returns a Package 5062306a36Sopenharmony_ci * (next entry contains the package info) 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_ci if ((this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) && 5362306a36Sopenharmony_ci (this_name->info.expected_btypes != ACPI_RTYPE_ALL)) { 5462306a36Sopenharmony_ci this_name++; 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci this_name++; 5862306a36Sopenharmony_ci return (this_name); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/******************************************************************************* 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * FUNCTION: acpi_ut_match_predefined_method 6462306a36Sopenharmony_ci * 6562306a36Sopenharmony_ci * PARAMETERS: name - Name to find 6662306a36Sopenharmony_ci * 6762306a36Sopenharmony_ci * RETURN: Pointer to entry in predefined table. NULL indicates not found. 6862306a36Sopenharmony_ci * 6962306a36Sopenharmony_ci * DESCRIPTION: Check an object name against the predefined object list. 7062306a36Sopenharmony_ci * 7162306a36Sopenharmony_ci ******************************************************************************/ 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciconst union acpi_predefined_info *acpi_ut_match_predefined_method(char *name) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci const union acpi_predefined_info *this_name; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci /* Quick check for a predefined name, first character must be underscore */ 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci if (name[0] != '_') { 8062306a36Sopenharmony_ci return (NULL); 8162306a36Sopenharmony_ci } 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci /* Search info table for a predefined method/object name */ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci this_name = acpi_gbl_predefined_methods; 8662306a36Sopenharmony_ci while (this_name->info.name[0]) { 8762306a36Sopenharmony_ci if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) { 8862306a36Sopenharmony_ci return (this_name); 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci this_name = acpi_ut_get_next_predefined_method(this_name); 9262306a36Sopenharmony_ci } 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci return (NULL); /* Not found */ 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/******************************************************************************* 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * FUNCTION: acpi_ut_get_expected_return_types 10062306a36Sopenharmony_ci * 10162306a36Sopenharmony_ci * PARAMETERS: buffer - Where the formatted string is returned 10262306a36Sopenharmony_ci * expected_Btypes - Bitfield of expected data types 10362306a36Sopenharmony_ci * 10462306a36Sopenharmony_ci * RETURN: Formatted string in Buffer. 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * DESCRIPTION: Format the expected object types into a printable string. 10762306a36Sopenharmony_ci * 10862306a36Sopenharmony_ci ******************************************************************************/ 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_civoid acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci u32 this_rtype; 11362306a36Sopenharmony_ci u32 i; 11462306a36Sopenharmony_ci u32 j; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci if (!expected_btypes) { 11762306a36Sopenharmony_ci strcpy(buffer, "NONE"); 11862306a36Sopenharmony_ci return; 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci j = 1; 12262306a36Sopenharmony_ci buffer[0] = 0; 12362306a36Sopenharmony_ci this_rtype = ACPI_RTYPE_INTEGER; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci for (i = 0; i < ACPI_NUM_RTYPES; i++) { 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci /* If one of the expected types, concatenate the name of this type */ 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci if (expected_btypes & this_rtype) { 13062306a36Sopenharmony_ci strcat(buffer, &ut_rtype_names[i][j]); 13162306a36Sopenharmony_ci j = 0; /* Use name separator from now on */ 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci this_rtype <<= 1; /* Next Rtype */ 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/******************************************************************************* 13962306a36Sopenharmony_ci * 14062306a36Sopenharmony_ci * The remaining functions are used by iASL and acpi_help only 14162306a36Sopenharmony_ci * 14262306a36Sopenharmony_ci ******************************************************************************/ 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci#if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP) 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/* Local prototypes */ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci/* Types that can be returned externally by a predefined name */ 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cistatic const char *ut_external_type_names[] = /* Indexed by ACPI_TYPE_* */ 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci ", Type_ANY", 15562306a36Sopenharmony_ci ", Integer", 15662306a36Sopenharmony_ci ", String", 15762306a36Sopenharmony_ci ", Buffer", 15862306a36Sopenharmony_ci ", Package" 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* Bit widths for resource descriptor predefined names */ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic const char *ut_resource_type_names[] = { 16462306a36Sopenharmony_ci "/1", 16562306a36Sopenharmony_ci "/2", 16662306a36Sopenharmony_ci "/3", 16762306a36Sopenharmony_ci "/8", 16862306a36Sopenharmony_ci "/16", 16962306a36Sopenharmony_ci "/32", 17062306a36Sopenharmony_ci "/64", 17162306a36Sopenharmony_ci "/variable", 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci/******************************************************************************* 17562306a36Sopenharmony_ci * 17662306a36Sopenharmony_ci * FUNCTION: acpi_ut_match_resource_name 17762306a36Sopenharmony_ci * 17862306a36Sopenharmony_ci * PARAMETERS: name - Name to find 17962306a36Sopenharmony_ci * 18062306a36Sopenharmony_ci * RETURN: Pointer to entry in the resource table. NULL indicates not 18162306a36Sopenharmony_ci * found. 18262306a36Sopenharmony_ci * 18362306a36Sopenharmony_ci * DESCRIPTION: Check an object name against the predefined resource 18462306a36Sopenharmony_ci * descriptor object list. 18562306a36Sopenharmony_ci * 18662306a36Sopenharmony_ci ******************************************************************************/ 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciconst union acpi_predefined_info *acpi_ut_match_resource_name(char *name) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci const union acpi_predefined_info *this_name; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci /* 19362306a36Sopenharmony_ci * Quick check for a predefined name, first character must 19462306a36Sopenharmony_ci * be underscore 19562306a36Sopenharmony_ci */ 19662306a36Sopenharmony_ci if (name[0] != '_') { 19762306a36Sopenharmony_ci return (NULL); 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci /* Search info table for a predefined method/object name */ 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci this_name = acpi_gbl_resource_names; 20362306a36Sopenharmony_ci while (this_name->info.name[0]) { 20462306a36Sopenharmony_ci if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) { 20562306a36Sopenharmony_ci return (this_name); 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci this_name++; 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci return (NULL); /* Not found */ 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/******************************************************************************* 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * FUNCTION: acpi_ut_display_predefined_method 21762306a36Sopenharmony_ci * 21862306a36Sopenharmony_ci * PARAMETERS: buffer - Scratch buffer for this function 21962306a36Sopenharmony_ci * this_name - Entry in the predefined method/name table 22062306a36Sopenharmony_ci * multi_line - TRUE if output should be on >1 line 22162306a36Sopenharmony_ci * 22262306a36Sopenharmony_ci * RETURN: None 22362306a36Sopenharmony_ci * 22462306a36Sopenharmony_ci * DESCRIPTION: Display information about a predefined method. Number and 22562306a36Sopenharmony_ci * type of the input arguments, and expected type(s) for the 22662306a36Sopenharmony_ci * return value, if any. 22762306a36Sopenharmony_ci * 22862306a36Sopenharmony_ci ******************************************************************************/ 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_civoid 23162306a36Sopenharmony_ciacpi_ut_display_predefined_method(char *buffer, 23262306a36Sopenharmony_ci const union acpi_predefined_info *this_name, 23362306a36Sopenharmony_ci u8 multi_line) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci u32 arg_count; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci /* 23862306a36Sopenharmony_ci * Get the argument count and the string buffer 23962306a36Sopenharmony_ci * containing all argument types 24062306a36Sopenharmony_ci */ 24162306a36Sopenharmony_ci arg_count = acpi_ut_get_argument_types(buffer, 24262306a36Sopenharmony_ci this_name->info.argument_list); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci if (multi_line) { 24562306a36Sopenharmony_ci printf(" "); 24662306a36Sopenharmony_ci } 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci printf("%4.4s Requires %s%u argument%s", 24962306a36Sopenharmony_ci this_name->info.name, 25062306a36Sopenharmony_ci (this_name->info.argument_list & ARG_COUNT_IS_MINIMUM) ? 25162306a36Sopenharmony_ci "(at least) " : "", arg_count, arg_count != 1 ? "s" : ""); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci /* Display the types for any arguments */ 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci if (arg_count > 0) { 25662306a36Sopenharmony_ci printf(" (%s)", buffer); 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci if (multi_line) { 26062306a36Sopenharmony_ci printf("\n "); 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* Get the return value type(s) allowed */ 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci if (this_name->info.expected_btypes) { 26662306a36Sopenharmony_ci acpi_ut_get_expected_return_types(buffer, 26762306a36Sopenharmony_ci this_name->info. 26862306a36Sopenharmony_ci expected_btypes); 26962306a36Sopenharmony_ci printf(" Return value types: %s\n", buffer); 27062306a36Sopenharmony_ci } else { 27162306a36Sopenharmony_ci printf(" No return value\n"); 27262306a36Sopenharmony_ci } 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci/******************************************************************************* 27662306a36Sopenharmony_ci * 27762306a36Sopenharmony_ci * FUNCTION: acpi_ut_get_argument_types 27862306a36Sopenharmony_ci * 27962306a36Sopenharmony_ci * PARAMETERS: buffer - Where to return the formatted types 28062306a36Sopenharmony_ci * argument_types - Types field for this method 28162306a36Sopenharmony_ci * 28262306a36Sopenharmony_ci * RETURN: count - the number of arguments required for this method 28362306a36Sopenharmony_ci * 28462306a36Sopenharmony_ci * DESCRIPTION: Format the required data types for this method (Integer, 28562306a36Sopenharmony_ci * String, Buffer, or Package) and return the required argument 28662306a36Sopenharmony_ci * count. 28762306a36Sopenharmony_ci * 28862306a36Sopenharmony_ci ******************************************************************************/ 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci u16 this_argument_type; 29362306a36Sopenharmony_ci u16 sub_index; 29462306a36Sopenharmony_ci u16 arg_count; 29562306a36Sopenharmony_ci u32 i; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci *buffer = 0; 29862306a36Sopenharmony_ci sub_index = 2; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci /* First field in the types list is the count of args to follow */ 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci arg_count = METHOD_GET_ARG_COUNT(argument_types); 30362306a36Sopenharmony_ci if (arg_count > METHOD_PREDEF_ARGS_MAX) { 30462306a36Sopenharmony_ci printf("**** Invalid argument count (%u) " 30562306a36Sopenharmony_ci "in predefined info structure\n", arg_count); 30662306a36Sopenharmony_ci return (arg_count); 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci /* Get each argument from the list, convert to ascii, store to buffer */ 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci for (i = 0; i < arg_count; i++) { 31262306a36Sopenharmony_ci this_argument_type = METHOD_GET_NEXT_TYPE(argument_types); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (this_argument_type > METHOD_MAX_ARG_TYPE) { 31562306a36Sopenharmony_ci printf("**** Invalid argument type (%u) " 31662306a36Sopenharmony_ci "in predefined info structure\n", 31762306a36Sopenharmony_ci this_argument_type); 31862306a36Sopenharmony_ci return (arg_count); 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci strcat(buffer, 32262306a36Sopenharmony_ci ut_external_type_names[this_argument_type] + sub_index); 32362306a36Sopenharmony_ci sub_index = 0; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci return (arg_count); 32762306a36Sopenharmony_ci} 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci/******************************************************************************* 33062306a36Sopenharmony_ci * 33162306a36Sopenharmony_ci * FUNCTION: acpi_ut_get_resource_bit_width 33262306a36Sopenharmony_ci * 33362306a36Sopenharmony_ci * PARAMETERS: buffer - Where the formatted string is returned 33462306a36Sopenharmony_ci * types - Bitfield of expected data types 33562306a36Sopenharmony_ci * 33662306a36Sopenharmony_ci * RETURN: Count of return types. Formatted string in Buffer. 33762306a36Sopenharmony_ci * 33862306a36Sopenharmony_ci * DESCRIPTION: Format the resource bit widths into a printable string. 33962306a36Sopenharmony_ci * 34062306a36Sopenharmony_ci ******************************************************************************/ 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ciu32 acpi_ut_get_resource_bit_width(char *buffer, u16 types) 34362306a36Sopenharmony_ci{ 34462306a36Sopenharmony_ci u32 i; 34562306a36Sopenharmony_ci u16 sub_index; 34662306a36Sopenharmony_ci u32 found; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci *buffer = 0; 34962306a36Sopenharmony_ci sub_index = 1; 35062306a36Sopenharmony_ci found = 0; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci for (i = 0; i < NUM_RESOURCE_WIDTHS; i++) { 35362306a36Sopenharmony_ci if (types & 1) { 35462306a36Sopenharmony_ci strcat(buffer, &(ut_resource_type_names[i][sub_index])); 35562306a36Sopenharmony_ci sub_index = 0; 35662306a36Sopenharmony_ci found++; 35762306a36Sopenharmony_ci } 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci types >>= 1; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci return (found); 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci#endif 365