1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/******************************************************************************
3 *
4 * Module Name: utpredef - support functions for predefined names
5 *
6 * Copyright (C) 2000 - 2023, Intel Corp.
7 *
8 *****************************************************************************/
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acpredef.h"
13
14#define _COMPONENT          ACPI_UTILITIES
15ACPI_MODULE_NAME("utpredef")
16
17/*
18 * Names for the types that can be returned by the predefined objects.
19 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
20 */
21static const char *ut_rtype_names[] = {
22	"/Integer",
23	"/String",
24	"/Buffer",
25	"/Package",
26	"/Reference",
27};
28
29/*******************************************************************************
30 *
31 * FUNCTION:    acpi_ut_get_next_predefined_method
32 *
33 * PARAMETERS:  this_name           - Entry in the predefined method/name table
34 *
35 * RETURN:      Pointer to next entry in predefined table.
36 *
37 * DESCRIPTION: Get the next entry in the predefine method table. Handles the
38 *              cases where a package info entry follows a method name that
39 *              returns a package.
40 *
41 ******************************************************************************/
42
43const union acpi_predefined_info *acpi_ut_get_next_predefined_method(const union
44								     acpi_predefined_info
45								     *this_name)
46{
47
48	/*
49	 * Skip next entry in the table if this name returns a Package
50	 * (next entry contains the package info)
51	 */
52	if ((this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) &&
53	    (this_name->info.expected_btypes != ACPI_RTYPE_ALL)) {
54		this_name++;
55	}
56
57	this_name++;
58	return (this_name);
59}
60
61/*******************************************************************************
62 *
63 * FUNCTION:    acpi_ut_match_predefined_method
64 *
65 * PARAMETERS:  name                - Name to find
66 *
67 * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
68 *
69 * DESCRIPTION: Check an object name against the predefined object list.
70 *
71 ******************************************************************************/
72
73const union acpi_predefined_info *acpi_ut_match_predefined_method(char *name)
74{
75	const union acpi_predefined_info *this_name;
76
77	/* Quick check for a predefined name, first character must be underscore */
78
79	if (name[0] != '_') {
80		return (NULL);
81	}
82
83	/* Search info table for a predefined method/object name */
84
85	this_name = acpi_gbl_predefined_methods;
86	while (this_name->info.name[0]) {
87		if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) {
88			return (this_name);
89		}
90
91		this_name = acpi_ut_get_next_predefined_method(this_name);
92	}
93
94	return (NULL);		/* Not found */
95}
96
97/*******************************************************************************
98 *
99 * FUNCTION:    acpi_ut_get_expected_return_types
100 *
101 * PARAMETERS:  buffer              - Where the formatted string is returned
102 *              expected_Btypes     - Bitfield of expected data types
103 *
104 * RETURN:      Formatted string in Buffer.
105 *
106 * DESCRIPTION: Format the expected object types into a printable string.
107 *
108 ******************************************************************************/
109
110void acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes)
111{
112	u32 this_rtype;
113	u32 i;
114	u32 j;
115
116	if (!expected_btypes) {
117		strcpy(buffer, "NONE");
118		return;
119	}
120
121	j = 1;
122	buffer[0] = 0;
123	this_rtype = ACPI_RTYPE_INTEGER;
124
125	for (i = 0; i < ACPI_NUM_RTYPES; i++) {
126
127		/* If one of the expected types, concatenate the name of this type */
128
129		if (expected_btypes & this_rtype) {
130			strcat(buffer, &ut_rtype_names[i][j]);
131			j = 0;	/* Use name separator from now on */
132		}
133
134		this_rtype <<= 1;	/* Next Rtype */
135	}
136}
137
138/*******************************************************************************
139 *
140 * The remaining functions are used by iASL and acpi_help only
141 *
142 ******************************************************************************/
143
144#if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP)
145
146/* Local prototypes */
147
148static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types);
149
150/* Types that can be returned externally by a predefined name */
151
152static const char *ut_external_type_names[] =	/* Indexed by ACPI_TYPE_* */
153{
154	", Type_ANY",
155	", Integer",
156	", String",
157	", Buffer",
158	", Package"
159};
160
161/* Bit widths for resource descriptor predefined names */
162
163static const char *ut_resource_type_names[] = {
164	"/1",
165	"/2",
166	"/3",
167	"/8",
168	"/16",
169	"/32",
170	"/64",
171	"/variable",
172};
173
174/*******************************************************************************
175 *
176 * FUNCTION:    acpi_ut_match_resource_name
177 *
178 * PARAMETERS:  name                - Name to find
179 *
180 * RETURN:      Pointer to entry in the resource table. NULL indicates not
181 *              found.
182 *
183 * DESCRIPTION: Check an object name against the predefined resource
184 *              descriptor object list.
185 *
186 ******************************************************************************/
187
188const union acpi_predefined_info *acpi_ut_match_resource_name(char *name)
189{
190	const union acpi_predefined_info *this_name;
191
192	/*
193	 * Quick check for a predefined name, first character must
194	 * be underscore
195	 */
196	if (name[0] != '_') {
197		return (NULL);
198	}
199
200	/* Search info table for a predefined method/object name */
201
202	this_name = acpi_gbl_resource_names;
203	while (this_name->info.name[0]) {
204		if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) {
205			return (this_name);
206		}
207
208		this_name++;
209	}
210
211	return (NULL);		/* Not found */
212}
213
214/*******************************************************************************
215 *
216 * FUNCTION:    acpi_ut_display_predefined_method
217 *
218 * PARAMETERS:  buffer              - Scratch buffer for this function
219 *              this_name           - Entry in the predefined method/name table
220 *              multi_line          - TRUE if output should be on >1 line
221 *
222 * RETURN:      None
223 *
224 * DESCRIPTION: Display information about a predefined method. Number and
225 *              type of the input arguments, and expected type(s) for the
226 *              return value, if any.
227 *
228 ******************************************************************************/
229
230void
231acpi_ut_display_predefined_method(char *buffer,
232				  const union acpi_predefined_info *this_name,
233				  u8 multi_line)
234{
235	u32 arg_count;
236
237	/*
238	 * Get the argument count and the string buffer
239	 * containing all argument types
240	 */
241	arg_count = acpi_ut_get_argument_types(buffer,
242					       this_name->info.argument_list);
243
244	if (multi_line) {
245		printf("      ");
246	}
247
248	printf("%4.4s    Requires %s%u argument%s",
249	       this_name->info.name,
250	       (this_name->info.argument_list & ARG_COUNT_IS_MINIMUM) ?
251	       "(at least) " : "", arg_count, arg_count != 1 ? "s" : "");
252
253	/* Display the types for any arguments */
254
255	if (arg_count > 0) {
256		printf(" (%s)", buffer);
257	}
258
259	if (multi_line) {
260		printf("\n    ");
261	}
262
263	/* Get the return value type(s) allowed */
264
265	if (this_name->info.expected_btypes) {
266		acpi_ut_get_expected_return_types(buffer,
267						  this_name->info.
268						  expected_btypes);
269		printf("  Return value types: %s\n", buffer);
270	} else {
271		printf("  No return value\n");
272	}
273}
274
275/*******************************************************************************
276 *
277 * FUNCTION:    acpi_ut_get_argument_types
278 *
279 * PARAMETERS:  buffer              - Where to return the formatted types
280 *              argument_types      - Types field for this method
281 *
282 * RETURN:      count - the number of arguments required for this method
283 *
284 * DESCRIPTION: Format the required data types for this method (Integer,
285 *              String, Buffer, or Package) and return the required argument
286 *              count.
287 *
288 ******************************************************************************/
289
290static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types)
291{
292	u16 this_argument_type;
293	u16 sub_index;
294	u16 arg_count;
295	u32 i;
296
297	*buffer = 0;
298	sub_index = 2;
299
300	/* First field in the types list is the count of args to follow */
301
302	arg_count = METHOD_GET_ARG_COUNT(argument_types);
303	if (arg_count > METHOD_PREDEF_ARGS_MAX) {
304		printf("**** Invalid argument count (%u) "
305		       "in predefined info structure\n", arg_count);
306		return (arg_count);
307	}
308
309	/* Get each argument from the list, convert to ascii, store to buffer */
310
311	for (i = 0; i < arg_count; i++) {
312		this_argument_type = METHOD_GET_NEXT_TYPE(argument_types);
313
314		if (this_argument_type > METHOD_MAX_ARG_TYPE) {
315			printf("**** Invalid argument type (%u) "
316			       "in predefined info structure\n",
317			       this_argument_type);
318			return (arg_count);
319		}
320
321		strcat(buffer,
322		       ut_external_type_names[this_argument_type] + sub_index);
323		sub_index = 0;
324	}
325
326	return (arg_count);
327}
328
329/*******************************************************************************
330 *
331 * FUNCTION:    acpi_ut_get_resource_bit_width
332 *
333 * PARAMETERS:  buffer              - Where the formatted string is returned
334 *              types               - Bitfield of expected data types
335 *
336 * RETURN:      Count of return types. Formatted string in Buffer.
337 *
338 * DESCRIPTION: Format the resource bit widths into a printable string.
339 *
340 ******************************************************************************/
341
342u32 acpi_ut_get_resource_bit_width(char *buffer, u16 types)
343{
344	u32 i;
345	u16 sub_index;
346	u32 found;
347
348	*buffer = 0;
349	sub_index = 1;
350	found = 0;
351
352	for (i = 0; i < NUM_RESOURCE_WIDTHS; i++) {
353		if (types & 1) {
354			strcat(buffer, &(ut_resource_type_names[i][sub_index]));
355			sub_index = 0;
356			found++;
357		}
358
359		types >>= 1;
360	}
361
362	return (found);
363}
364#endif
365