ACPICA: Add function trace macros to improve debugging
[linux-2.6-microblaze.git] / drivers / acpi / acpica / nspredef.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: nspredef - Validation of ACPI predefined methods and objects
5  *
6  * Copyright (C) 2000 - 2020, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #define ACPI_CREATE_PREDEFINED_TABLE
11
12 #include <acpi/acpi.h>
13 #include "accommon.h"
14 #include "acnamesp.h"
15 #include "acpredef.h"
16
17 #define _COMPONENT          ACPI_NAMESPACE
18 ACPI_MODULE_NAME("nspredef")
19
20 /*******************************************************************************
21  *
22  * This module validates predefined ACPI objects that appear in the namespace,
23  * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
24  * validation is to detect problems with BIOS-exposed predefined ACPI objects
25  * before the results are returned to the ACPI-related drivers.
26  *
27  * There are several areas that are validated:
28  *
29  *  1) The number of input arguments as defined by the method/object in the
30  *     ASL is validated against the ACPI specification.
31  *  2) The type of the return object (if any) is validated against the ACPI
32  *     specification.
33  *  3) For returned package objects, the count of package elements is
34  *     validated, as well as the type of each package element. Nested
35  *     packages are supported.
36  *
37  * For any problems found, a warning message is issued.
38  *
39  ******************************************************************************/
40 /* Local prototypes */
41 static acpi_status
42 acpi_ns_check_reference(struct acpi_evaluate_info *info,
43                         union acpi_operand_object *return_object);
44
45 static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
46
47 /*******************************************************************************
48  *
49  * FUNCTION:    acpi_ns_check_return_value
50  *
51  * PARAMETERS:  node            - Namespace node for the method/object
52  *              info            - Method execution information block
53  *              user_param_count - Number of parameters actually passed
54  *              return_status   - Status from the object evaluation
55  *              return_object_ptr - Pointer to the object returned from the
56  *                                evaluation of a method or object
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: Check the value returned from a predefined name.
61  *
62  ******************************************************************************/
63
64 acpi_status
65 acpi_ns_check_return_value(struct acpi_namespace_node *node,
66                            struct acpi_evaluate_info *info,
67                            u32 user_param_count,
68                            acpi_status return_status,
69                            union acpi_operand_object **return_object_ptr)
70 {
71         acpi_status status;
72         const union acpi_predefined_info *predefined;
73
74         ACPI_FUNCTION_TRACE(ns_check_return_value);
75
76         /* If not a predefined name, we cannot validate the return object */
77
78         predefined = info->predefined;
79         if (!predefined) {
80                 return_ACPI_STATUS(AE_OK);
81         }
82
83         /*
84          * If the method failed or did not actually return an object, we cannot
85          * validate the return object
86          */
87         if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
88                 return_ACPI_STATUS(AE_OK);
89         }
90
91         /*
92          * Return value validation and possible repair.
93          *
94          * 1) Don't perform return value validation/repair if this feature
95          * has been disabled via a global option.
96          *
97          * 2) We have a return value, but if one wasn't expected, just exit,
98          * this is not a problem. For example, if the "Implicit Return"
99          * feature is enabled, methods will always return a value.
100          *
101          * 3) If the return value can be of any type, then we cannot perform
102          * any validation, just exit.
103          */
104         if (acpi_gbl_disable_auto_repair ||
105             (!predefined->info.expected_btypes) ||
106             (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
107                 return_ACPI_STATUS(AE_OK);
108         }
109
110         /*
111          * Check that the type of the main return object is what is expected
112          * for this predefined name
113          */
114         status = acpi_ns_check_object_type(info, return_object_ptr,
115                                            predefined->info.expected_btypes,
116                                            ACPI_NOT_PACKAGE_ELEMENT);
117         if (ACPI_FAILURE(status)) {
118                 goto exit;
119         }
120
121         /*
122          *
123          * 4) If there is no return value and it is optional, just return
124          * AE_OK (_WAK).
125          */
126         if (!(*return_object_ptr)) {
127                 goto exit;
128         }
129
130         /*
131          * For returned Package objects, check the type of all sub-objects.
132          * Note: Package may have been newly created by call above.
133          */
134         if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
135                 info->parent_package = *return_object_ptr;
136                 status = acpi_ns_check_package(info, return_object_ptr);
137                 if (ACPI_FAILURE(status)) {
138
139                         /* We might be able to fix some errors */
140
141                         if ((status != AE_AML_OPERAND_TYPE) &&
142                             (status != AE_AML_OPERAND_VALUE)) {
143                                 goto exit;
144                         }
145                 }
146         }
147
148         /*
149          * The return object was OK, or it was successfully repaired above.
150          * Now make some additional checks such as verifying that package
151          * objects are sorted correctly (if required) or buffer objects have
152          * the correct data width (bytes vs. dwords). These repairs are
153          * performed on a per-name basis, i.e., the code is specific to
154          * particular predefined names.
155          */
156         status = acpi_ns_complex_repairs(info, node, status, return_object_ptr);
157
158 exit:
159         /*
160          * If the object validation failed or if we successfully repaired one
161          * or more objects, mark the parent node to suppress further warning
162          * messages during the next evaluation of the same method/object.
163          */
164         if (ACPI_FAILURE(status) || (info->return_flags & ACPI_OBJECT_REPAIRED)) {
165                 node->flags |= ANOBJ_EVALUATED;
166         }
167
168         return_ACPI_STATUS(status);
169 }
170
171 /*******************************************************************************
172  *
173  * FUNCTION:    acpi_ns_check_object_type
174  *
175  * PARAMETERS:  info            - Method execution information block
176  *              return_object_ptr - Pointer to the object returned from the
177  *                                evaluation of a method or object
178  *              expected_btypes - Bitmap of expected return type(s)
179  *              package_index   - Index of object within parent package (if
180  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
181  *                                otherwise)
182  *
183  * RETURN:      Status
184  *
185  * DESCRIPTION: Check the type of the return object against the expected object
186  *              type(s). Use of Btype allows multiple expected object types.
187  *
188  ******************************************************************************/
189
190 acpi_status
191 acpi_ns_check_object_type(struct acpi_evaluate_info *info,
192                           union acpi_operand_object **return_object_ptr,
193                           u32 expected_btypes, u32 package_index)
194 {
195         union acpi_operand_object *return_object = *return_object_ptr;
196         acpi_status status = AE_OK;
197         char type_buffer[96];   /* Room for 10 types */
198
199         /* A Namespace node should not get here, but make sure */
200
201         if (return_object &&
202             ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
203                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
204                                       info->node_flags,
205                                       "Invalid return type - Found a Namespace node [%4.4s] type %s",
206                                       return_object->node.name.ascii,
207                                       acpi_ut_get_type_name(return_object->node.
208                                                             type)));
209                 return (AE_AML_OPERAND_TYPE);
210         }
211
212         /*
213          * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
214          * The bitmapped type allows multiple possible return types.
215          *
216          * Note, the cases below must handle all of the possible types returned
217          * from all of the predefined names (including elements of returned
218          * packages)
219          */
220         info->return_btype = acpi_ns_get_bitmapped_type(return_object);
221         if (info->return_btype == ACPI_RTYPE_ANY) {
222
223                 /* Not one of the supported objects, must be incorrect */
224                 goto type_error_exit;
225         }
226
227         /* For reference objects, check that the reference type is correct */
228
229         if ((info->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
230                 status = acpi_ns_check_reference(info, return_object);
231                 return (status);
232         }
233
234         /* Attempt simple repair of the returned object if necessary */
235
236         status = acpi_ns_simple_repair(info, expected_btypes,
237                                        package_index, return_object_ptr);
238         if (ACPI_SUCCESS(status)) {
239                 return (AE_OK); /* Successful repair */
240         }
241
242 type_error_exit:
243
244         /* Create a string with all expected types for this predefined object */
245
246         acpi_ut_get_expected_return_types(type_buffer, expected_btypes);
247
248         if (!return_object) {
249                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
250                                       info->node_flags,
251                                       "Expected return object of type %s",
252                                       type_buffer));
253         } else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
254                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
255                                       info->node_flags,
256                                       "Return type mismatch - found %s, expected %s",
257                                       acpi_ut_get_object_type_name
258                                       (return_object), type_buffer));
259         } else {
260                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
261                                       info->node_flags,
262                                       "Return Package type mismatch at index %u - "
263                                       "found %s, expected %s", package_index,
264                                       acpi_ut_get_object_type_name
265                                       (return_object), type_buffer));
266         }
267
268         return (AE_AML_OPERAND_TYPE);
269 }
270
271 /*******************************************************************************
272  *
273  * FUNCTION:    acpi_ns_check_reference
274  *
275  * PARAMETERS:  info            - Method execution information block
276  *              return_object   - Object returned from the evaluation of a
277  *                                method or object
278  *
279  * RETURN:      Status
280  *
281  * DESCRIPTION: Check a returned reference object for the correct reference
282  *              type. The only reference type that can be returned from a
283  *              predefined method is a named reference. All others are invalid.
284  *
285  ******************************************************************************/
286
287 static acpi_status
288 acpi_ns_check_reference(struct acpi_evaluate_info *info,
289                         union acpi_operand_object *return_object)
290 {
291
292         /*
293          * Check the reference object for the correct reference type (opcode).
294          * The only type of reference that can be converted to a union acpi_object is
295          * a reference to a named object (reference class: NAME)
296          */
297         if (return_object->reference.class == ACPI_REFCLASS_NAME) {
298                 return (AE_OK);
299         }
300
301         ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
302                               "Return type mismatch - unexpected reference object type [%s] %2.2X",
303                               acpi_ut_get_reference_name(return_object),
304                               return_object->reference.class));
305
306         return (AE_AML_OPERAND_TYPE);
307 }
308
309 /*******************************************************************************
310  *
311  * FUNCTION:    acpi_ns_get_bitmapped_type
312  *
313  * PARAMETERS:  return_object   - Object returned from method/obj evaluation
314  *
315  * RETURN:      Object return type. ACPI_RTYPE_ANY indicates that the object
316  *              type is not supported. ACPI_RTYPE_NONE indicates that no
317  *              object was returned (return_object is NULL).
318  *
319  * DESCRIPTION: Convert object type into a bitmapped object return type.
320  *
321  ******************************************************************************/
322
323 static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object)
324 {
325         u32 return_btype;
326
327         if (!return_object) {
328                 return (ACPI_RTYPE_NONE);
329         }
330
331         /* Map acpi_object_type to internal bitmapped type */
332
333         switch (return_object->common.type) {
334         case ACPI_TYPE_INTEGER:
335
336                 return_btype = ACPI_RTYPE_INTEGER;
337                 break;
338
339         case ACPI_TYPE_BUFFER:
340
341                 return_btype = ACPI_RTYPE_BUFFER;
342                 break;
343
344         case ACPI_TYPE_STRING:
345
346                 return_btype = ACPI_RTYPE_STRING;
347                 break;
348
349         case ACPI_TYPE_PACKAGE:
350
351                 return_btype = ACPI_RTYPE_PACKAGE;
352                 break;
353
354         case ACPI_TYPE_LOCAL_REFERENCE:
355
356                 return_btype = ACPI_RTYPE_REFERENCE;
357                 break;
358
359         default:
360
361                 /* Not one of the supported objects, must be incorrect */
362
363                 return_btype = ACPI_RTYPE_ANY;
364                 break;
365         }
366
367         return (return_btype);
368 }