195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: nspredef - Validation of ACPI predefined methods and objects
595b482a8SLen Brown *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
10999e08f9SBob Moore #define ACPI_CREATE_PREDEFINED_TABLE
11999e08f9SBob Moore
1295b482a8SLen Brown #include <acpi/acpi.h>
13e2f7a777SLen Brown #include "accommon.h"
14e2f7a777SLen Brown #include "acnamesp.h"
15e2f7a777SLen Brown #include "acpredef.h"
1695b482a8SLen Brown
1795b482a8SLen Brown #define _COMPONENT ACPI_NAMESPACE
1895b482a8SLen Brown ACPI_MODULE_NAME("nspredef")
1995b482a8SLen Brown
2095b482a8SLen Brown /*******************************************************************************
2195b482a8SLen Brown *
2295b482a8SLen Brown * This module validates predefined ACPI objects that appear in the namespace,
2395b482a8SLen Brown * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
2495b482a8SLen Brown * validation is to detect problems with BIOS-exposed predefined ACPI objects
2595b482a8SLen Brown * before the results are returned to the ACPI-related drivers.
2695b482a8SLen Brown *
2795b482a8SLen Brown * There are several areas that are validated:
2895b482a8SLen Brown *
2995b482a8SLen Brown * 1) The number of input arguments as defined by the method/object in the
3095b482a8SLen Brown * ASL is validated against the ACPI specification.
3195b482a8SLen Brown * 2) The type of the return object (if any) is validated against the ACPI
3295b482a8SLen Brown * specification.
3395b482a8SLen Brown * 3) For returned package objects, the count of package elements is
3495b482a8SLen Brown * validated, as well as the type of each package element. Nested
3595b482a8SLen Brown * packages are supported.
3695b482a8SLen Brown *
3795b482a8SLen Brown * For any problems found, a warning message is issued.
3895b482a8SLen Brown *
3995b482a8SLen Brown ******************************************************************************/
4095b482a8SLen Brown /* Local prototypes */
4195b482a8SLen Brown static acpi_status
4229a241ccSBob Moore acpi_ns_check_reference(struct acpi_evaluate_info *info,
4395b482a8SLen Brown union acpi_operand_object *return_object);
4495b482a8SLen Brown
45d5a36100SBob Moore static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
46d5a36100SBob Moore
4795b482a8SLen Brown /*******************************************************************************
4895b482a8SLen Brown *
4929a241ccSBob Moore * FUNCTION: acpi_ns_check_return_value
5095b482a8SLen Brown *
51ba494beeSBob Moore * PARAMETERS: node - Namespace node for the method/object
5229a241ccSBob Moore * info - Method execution information block
530444e8f6SBob Moore * user_param_count - Number of parameters actually passed
540444e8f6SBob Moore * return_status - Status from the object evaluation
5595b482a8SLen Brown * return_object_ptr - Pointer to the object returned from the
5695b482a8SLen Brown * evaluation of a method or object
5795b482a8SLen Brown *
5895b482a8SLen Brown * RETURN: Status
5995b482a8SLen Brown *
6029a241ccSBob Moore * DESCRIPTION: Check the value returned from a predefined name.
6195b482a8SLen Brown *
6295b482a8SLen Brown ******************************************************************************/
6395b482a8SLen Brown
6495b482a8SLen Brown acpi_status
acpi_ns_check_return_value(struct acpi_namespace_node * node,struct acpi_evaluate_info * info,u32 user_param_count,acpi_status return_status,union acpi_operand_object ** return_object_ptr)6529a241ccSBob Moore acpi_ns_check_return_value(struct acpi_namespace_node *node,
6629a241ccSBob Moore struct acpi_evaluate_info *info,
6795b482a8SLen Brown u32 user_param_count,
6895b482a8SLen Brown acpi_status return_status,
6995b482a8SLen Brown union acpi_operand_object **return_object_ptr)
7095b482a8SLen Brown {
7129a241ccSBob Moore acpi_status status;
7295b482a8SLen Brown const union acpi_predefined_info *predefined;
7395b482a8SLen Brown
740766efdfSErik Kaneda ACPI_FUNCTION_TRACE(ns_check_return_value);
750766efdfSErik Kaneda
7695b482a8SLen Brown /* If not a predefined name, we cannot validate the return object */
7795b482a8SLen Brown
7843e5318fSBob Moore predefined = info->predefined;
7995b482a8SLen Brown if (!predefined) {
800766efdfSErik Kaneda return_ACPI_STATUS(AE_OK);
8195b482a8SLen Brown }
8295b482a8SLen Brown
8395b482a8SLen Brown /*
840444e8f6SBob Moore * If the method failed or did not actually return an object, we cannot
850444e8f6SBob Moore * validate the return object
8695b482a8SLen Brown */
870444e8f6SBob Moore if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
880766efdfSErik Kaneda return_ACPI_STATUS(AE_OK);
8995b482a8SLen Brown }
9095b482a8SLen Brown
9195b482a8SLen Brown /*
92d57b23adSBob Moore * Return value validation and possible repair.
93307a0424SBob Moore *
94d57b23adSBob Moore * 1) Don't perform return value validation/repair if this feature
95d57b23adSBob Moore * has been disabled via a global option.
96d57b23adSBob Moore *
97d57b23adSBob Moore * 2) We have a return value, but if one wasn't expected, just exit,
98d57b23adSBob Moore * this is not a problem. For example, if the "Implicit Return"
99d57b23adSBob Moore * feature is enabled, methods will always return a value.
100d57b23adSBob Moore *
101d57b23adSBob Moore * 3) If the return value can be of any type, then we cannot perform
102d57b23adSBob Moore * any validation, just exit.
10395b482a8SLen Brown */
104d57b23adSBob Moore if (acpi_gbl_disable_auto_repair ||
105d57b23adSBob Moore (!predefined->info.expected_btypes) ||
106307a0424SBob Moore (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
1070766efdfSErik Kaneda return_ACPI_STATUS(AE_OK);
10895b482a8SLen Brown }
10995b482a8SLen Brown
11095b482a8SLen Brown /*
111465da9ebSBob Moore * Check that the type of the main return object is what is expected
112465da9ebSBob Moore * for this predefined name
11395b482a8SLen Brown */
11429a241ccSBob Moore status = acpi_ns_check_object_type(info, return_object_ptr,
11595b482a8SLen Brown predefined->info.expected_btypes,
1160444e8f6SBob Moore ACPI_NOT_PACKAGE_ELEMENT);
117465da9ebSBob Moore if (ACPI_FAILURE(status)) {
118465da9ebSBob Moore goto exit;
119465da9ebSBob Moore }
120465da9ebSBob Moore
121ea7c5ec1SBob Moore /*
122bf0dd264SBob Moore *
123bf0dd264SBob Moore * 4) If there is no return value and it is optional, just return
124bf0dd264SBob Moore * AE_OK (_WAK).
125bf0dd264SBob Moore */
126bf0dd264SBob Moore if (!(*return_object_ptr)) {
127bf0dd264SBob Moore goto exit;
128bf0dd264SBob Moore }
129bf0dd264SBob Moore
130bf0dd264SBob Moore /*
131ea7c5ec1SBob Moore * For returned Package objects, check the type of all sub-objects.
132465da9ebSBob Moore * Note: Package may have been newly created by call above.
133ea7c5ec1SBob Moore */
134ea7c5ec1SBob Moore if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
13529a241ccSBob Moore info->parent_package = *return_object_ptr;
13629a241ccSBob Moore status = acpi_ns_check_package(info, return_object_ptr);
137465da9ebSBob Moore if (ACPI_FAILURE(status)) {
138aa6329c4SLv Zheng
1395a9792f3SLv Zheng /* We might be able to fix some errors */
140aa6329c4SLv Zheng
1415a9792f3SLv Zheng if ((status != AE_AML_OPERAND_TYPE) &&
1425a9792f3SLv Zheng (status != AE_AML_OPERAND_VALUE)) {
143465da9ebSBob Moore goto exit;
14495b482a8SLen Brown }
14534c39c75SBob Moore }
146aa6329c4SLv Zheng }
14795b482a8SLen Brown
148ad5babeeSBob Moore /*
149465da9ebSBob Moore * The return object was OK, or it was successfully repaired above.
150465da9ebSBob Moore * Now make some additional checks such as verifying that package
151465da9ebSBob Moore * objects are sorted correctly (if required) or buffer objects have
152465da9ebSBob Moore * the correct data width (bytes vs. dwords). These repairs are
153465da9ebSBob Moore * performed on a per-name basis, i.e., the code is specific to
154465da9ebSBob Moore * particular predefined names.
155ad5babeeSBob Moore */
15629a241ccSBob Moore status = acpi_ns_complex_repairs(info, node, status, return_object_ptr);
157ad5babeeSBob Moore
158465da9ebSBob Moore exit:
1590444e8f6SBob Moore /*
1600444e8f6SBob Moore * If the object validation failed or if we successfully repaired one
1610444e8f6SBob Moore * or more objects, mark the parent node to suppress further warning
1620444e8f6SBob Moore * messages during the next evaluation of the same method/object.
1630444e8f6SBob Moore */
16429a241ccSBob Moore if (ACPI_FAILURE(status) || (info->return_flags & ACPI_OBJECT_REPAIRED)) {
1650444e8f6SBob Moore node->flags |= ANOBJ_EVALUATED;
1660444e8f6SBob Moore }
1670444e8f6SBob Moore
1680766efdfSErik Kaneda return_ACPI_STATUS(status);
16995b482a8SLen Brown }
17095b482a8SLen Brown
17195b482a8SLen Brown /*******************************************************************************
17295b482a8SLen Brown *
17395b482a8SLen Brown * FUNCTION: acpi_ns_check_object_type
17495b482a8SLen Brown *
17529a241ccSBob Moore * PARAMETERS: info - Method execution information block
17695b482a8SLen Brown * return_object_ptr - Pointer to the object returned from the
17795b482a8SLen Brown * evaluation of a method or object
17895b482a8SLen Brown * expected_btypes - Bitmap of expected return type(s)
17995b482a8SLen Brown * package_index - Index of object within parent package (if
1800444e8f6SBob Moore * applicable - ACPI_NOT_PACKAGE_ELEMENT
1810444e8f6SBob Moore * otherwise)
18295b482a8SLen Brown *
18395b482a8SLen Brown * RETURN: Status
18495b482a8SLen Brown *
18595b482a8SLen Brown * DESCRIPTION: Check the type of the return object against the expected object
18695b482a8SLen Brown * type(s). Use of Btype allows multiple expected object types.
18795b482a8SLen Brown *
18895b482a8SLen Brown ******************************************************************************/
18995b482a8SLen Brown
19042f8fb75SBob Moore acpi_status
acpi_ns_check_object_type(struct acpi_evaluate_info * info,union acpi_operand_object ** return_object_ptr,u32 expected_btypes,u32 package_index)19129a241ccSBob Moore acpi_ns_check_object_type(struct acpi_evaluate_info *info,
19295b482a8SLen Brown union acpi_operand_object **return_object_ptr,
19395b482a8SLen Brown u32 expected_btypes, u32 package_index)
19495b482a8SLen Brown {
19595b482a8SLen Brown union acpi_operand_object *return_object = *return_object_ptr;
19695b482a8SLen Brown acpi_status status = AE_OK;
197a5922a1fSBob Moore char type_buffer[96]; /* Room for 10 types */
19895b482a8SLen Brown
19995b482a8SLen Brown /* A Namespace node should not get here, but make sure */
20095b482a8SLen Brown
201d5a36100SBob Moore if (return_object &&
202d5a36100SBob Moore ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
20329a241ccSBob Moore ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
20429a241ccSBob Moore info->node_flags,
2050444e8f6SBob Moore "Invalid return type - Found a Namespace node [%4.4s] type %s",
2060444e8f6SBob Moore return_object->node.name.ascii,
2070444e8f6SBob Moore acpi_ut_get_type_name(return_object->node.
2080444e8f6SBob Moore type)));
20995b482a8SLen Brown return (AE_AML_OPERAND_TYPE);
21095b482a8SLen Brown }
21195b482a8SLen Brown
21295b482a8SLen Brown /*
21395b482a8SLen Brown * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
21495b482a8SLen Brown * The bitmapped type allows multiple possible return types.
21595b482a8SLen Brown *
21695b482a8SLen Brown * Note, the cases below must handle all of the possible types returned
21795b482a8SLen Brown * from all of the predefined names (including elements of returned
21895b482a8SLen Brown * packages)
21995b482a8SLen Brown */
22029a241ccSBob Moore info->return_btype = acpi_ns_get_bitmapped_type(return_object);
22129a241ccSBob Moore if (info->return_btype == ACPI_RTYPE_ANY) {
22295b482a8SLen Brown
22395b482a8SLen Brown /* Not one of the supported objects, must be incorrect */
22495b482a8SLen Brown goto type_error_exit;
22595b482a8SLen Brown }
22695b482a8SLen Brown
22795b482a8SLen Brown /* For reference objects, check that the reference type is correct */
22895b482a8SLen Brown
22929a241ccSBob Moore if ((info->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
23029a241ccSBob Moore status = acpi_ns_check_reference(info, return_object);
23195b482a8SLen Brown return (status);
2322147d3f0SBob Moore }
2332147d3f0SBob Moore
234d5a36100SBob Moore /* Attempt simple repair of the returned object if necessary */
2352147d3f0SBob Moore
23629a241ccSBob Moore status = acpi_ns_simple_repair(info, expected_btypes,
2372147d3f0SBob Moore package_index, return_object_ptr);
23829a241ccSBob Moore if (ACPI_SUCCESS(status)) {
23929a241ccSBob Moore return (AE_OK); /* Successful repair */
24029a241ccSBob Moore }
24195b482a8SLen Brown
24295b482a8SLen Brown type_error_exit:
24395b482a8SLen Brown
24495b482a8SLen Brown /* Create a string with all expected types for this predefined object */
24595b482a8SLen Brown
246c34c82bcSBob Moore acpi_ut_get_expected_return_types(type_buffer, expected_btypes);
24795b482a8SLen Brown
248bf0dd264SBob Moore if (!return_object) {
249bf0dd264SBob Moore ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
250bf0dd264SBob Moore info->node_flags,
251bf0dd264SBob Moore "Expected return object of type %s",
252bf0dd264SBob Moore type_buffer));
253bf0dd264SBob Moore } else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
25429a241ccSBob Moore ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
25529a241ccSBob Moore info->node_flags,
2560444e8f6SBob Moore "Return type mismatch - found %s, expected %s",
2570444e8f6SBob Moore acpi_ut_get_object_type_name
2580444e8f6SBob Moore (return_object), type_buffer));
25995b482a8SLen Brown } else {
26029a241ccSBob Moore ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
26129a241ccSBob Moore info->node_flags,
2620444e8f6SBob Moore "Return Package type mismatch at index %u - "
2630444e8f6SBob Moore "found %s, expected %s", package_index,
2640444e8f6SBob Moore acpi_ut_get_object_type_name
2650444e8f6SBob Moore (return_object), type_buffer));
26695b482a8SLen Brown }
26795b482a8SLen Brown
26895b482a8SLen Brown return (AE_AML_OPERAND_TYPE);
26995b482a8SLen Brown }
27095b482a8SLen Brown
27195b482a8SLen Brown /*******************************************************************************
27295b482a8SLen Brown *
27395b482a8SLen Brown * FUNCTION: acpi_ns_check_reference
27495b482a8SLen Brown *
27529a241ccSBob Moore * PARAMETERS: info - Method execution information block
27695b482a8SLen Brown * return_object - Object returned from the evaluation of a
27795b482a8SLen Brown * method or object
27895b482a8SLen Brown *
27995b482a8SLen Brown * RETURN: Status
28095b482a8SLen Brown *
28195b482a8SLen Brown * DESCRIPTION: Check a returned reference object for the correct reference
28295b482a8SLen Brown * type. The only reference type that can be returned from a
28395b482a8SLen Brown * predefined method is a named reference. All others are invalid.
28495b482a8SLen Brown *
28595b482a8SLen Brown ******************************************************************************/
28695b482a8SLen Brown
28795b482a8SLen Brown static acpi_status
acpi_ns_check_reference(struct acpi_evaluate_info * info,union acpi_operand_object * return_object)28829a241ccSBob Moore acpi_ns_check_reference(struct acpi_evaluate_info *info,
28995b482a8SLen Brown union acpi_operand_object *return_object)
29095b482a8SLen Brown {
29195b482a8SLen Brown
29295b482a8SLen Brown /*
29395b482a8SLen Brown * Check the reference object for the correct reference type (opcode).
29403440c4eSMasahiro Yamada * The only type of reference that can be converted to a union acpi_object is
29595b482a8SLen Brown * a reference to a named object (reference class: NAME)
29695b482a8SLen Brown */
29795b482a8SLen Brown if (return_object->reference.class == ACPI_REFCLASS_NAME) {
29895b482a8SLen Brown return (AE_OK);
29995b482a8SLen Brown }
30095b482a8SLen Brown
30129a241ccSBob Moore ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
3020444e8f6SBob Moore "Return type mismatch - unexpected reference object type [%s] %2.2X",
3030444e8f6SBob Moore acpi_ut_get_reference_name(return_object),
30495b482a8SLen Brown return_object->reference.class));
30595b482a8SLen Brown
30695b482a8SLen Brown return (AE_AML_OPERAND_TYPE);
30795b482a8SLen Brown }
30895b482a8SLen Brown
30995b482a8SLen Brown /*******************************************************************************
31095b482a8SLen Brown *
311d5a36100SBob Moore * FUNCTION: acpi_ns_get_bitmapped_type
312d5a36100SBob Moore *
313d5a36100SBob Moore * PARAMETERS: return_object - Object returned from method/obj evaluation
314d5a36100SBob Moore *
315d5a36100SBob Moore * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object
316d5a36100SBob Moore * type is not supported. ACPI_RTYPE_NONE indicates that no
317d5a36100SBob Moore * object was returned (return_object is NULL).
318d5a36100SBob Moore *
319d5a36100SBob Moore * DESCRIPTION: Convert object type into a bitmapped object return type.
320d5a36100SBob Moore *
321d5a36100SBob Moore ******************************************************************************/
322d5a36100SBob Moore
acpi_ns_get_bitmapped_type(union acpi_operand_object * return_object)323d5a36100SBob Moore static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object)
324d5a36100SBob Moore {
325d5a36100SBob Moore u32 return_btype;
326d5a36100SBob Moore
327d5a36100SBob Moore if (!return_object) {
328d5a36100SBob Moore return (ACPI_RTYPE_NONE);
329d5a36100SBob Moore }
330d5a36100SBob Moore
331d5a36100SBob Moore /* Map acpi_object_type to internal bitmapped type */
332d5a36100SBob Moore
333d5a36100SBob Moore switch (return_object->common.type) {
334d5a36100SBob Moore case ACPI_TYPE_INTEGER:
3351d1ea1b7SChao Guan
336d5a36100SBob Moore return_btype = ACPI_RTYPE_INTEGER;
337d5a36100SBob Moore break;
338d5a36100SBob Moore
339d5a36100SBob Moore case ACPI_TYPE_BUFFER:
3401d1ea1b7SChao Guan
341d5a36100SBob Moore return_btype = ACPI_RTYPE_BUFFER;
342d5a36100SBob Moore break;
343d5a36100SBob Moore
344d5a36100SBob Moore case ACPI_TYPE_STRING:
3451d1ea1b7SChao Guan
346d5a36100SBob Moore return_btype = ACPI_RTYPE_STRING;
347d5a36100SBob Moore break;
348d5a36100SBob Moore
349d5a36100SBob Moore case ACPI_TYPE_PACKAGE:
3501d1ea1b7SChao Guan
351d5a36100SBob Moore return_btype = ACPI_RTYPE_PACKAGE;
352d5a36100SBob Moore break;
353d5a36100SBob Moore
354d5a36100SBob Moore case ACPI_TYPE_LOCAL_REFERENCE:
3551d1ea1b7SChao Guan
356d5a36100SBob Moore return_btype = ACPI_RTYPE_REFERENCE;
357d5a36100SBob Moore break;
358d5a36100SBob Moore
359d5a36100SBob Moore default:
3601d1ea1b7SChao Guan
361d5a36100SBob Moore /* Not one of the supported objects, must be incorrect */
362d5a36100SBob Moore
363d5a36100SBob Moore return_btype = ACPI_RTYPE_ANY;
364d5a36100SBob Moore break;
365d5a36100SBob Moore }
366d5a36100SBob Moore
367d5a36100SBob Moore return (return_btype);
368d5a36100SBob Moore }
369