brintos

brintos / linux-shallow public Read only

0
0
Text · 8.8 KiB · 3efb46f Raw
276 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: nsarguments - Validation of args for ACPI predefined methods5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acnamesp.h"13#include "acpredef.h"14 15#define _COMPONENT          ACPI_NAMESPACE16ACPI_MODULE_NAME("nsarguments")17 18/*******************************************************************************19 *20 * FUNCTION:    acpi_ns_check_argument_types21 *22 * PARAMETERS:  info            - Method execution information block23 *24 * RETURN:      None25 *26 * DESCRIPTION: Check the incoming argument count and all argument types27 *              against the argument type list for a predefined name.28 *29 ******************************************************************************/30void acpi_ns_check_argument_types(struct acpi_evaluate_info *info)31{32	u16 arg_type_list;33	u8 arg_count;34	u8 arg_type;35	u8 user_arg_type;36	u32 i;37 38	/*39	 * If not a predefined name, cannot typecheck args, because40	 * we have no idea what argument types are expected.41	 * Also, ignore typecheck if warnings/errors if this method42	 * has already been evaluated at least once -- in order43	 * to suppress repetitive messages.44	 */45	if (!info->predefined || (info->node->flags & ANOBJ_EVALUATED)) {46		return;47	}48 49	arg_type_list = info->predefined->info.argument_list;50	arg_count = METHOD_GET_ARG_COUNT(arg_type_list);51 52	/* Typecheck all arguments */53 54	for (i = 0; ((i < arg_count) && (i < info->param_count)); i++) {55		arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);56		user_arg_type = info->parameters[i]->common.type;57 58		/* No typechecking for ACPI_TYPE_ANY */59 60		if ((user_arg_type != arg_type) && (arg_type != ACPI_TYPE_ANY)) {61			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,62					      ACPI_WARN_ALWAYS,63					      "Argument #%u type mismatch - "64					      "Found [%s], ACPI requires [%s]",65					      (i + 1),66					      acpi_ut_get_type_name67					      (user_arg_type),68					      acpi_ut_get_type_name(arg_type)));69 70			/* Prevent any additional typechecking for this method */71 72			info->node->flags |= ANOBJ_EVALUATED;73		}74	}75}76 77/*******************************************************************************78 *79 * FUNCTION:    acpi_ns_check_acpi_compliance80 *81 * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)82 *              node            - Namespace node for the method/object83 *              predefined      - Pointer to entry in predefined name table84 *85 * RETURN:      None86 *87 * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a88 *              predefined name is what is expected (matches what is defined in89 *              the ACPI specification for this predefined name.)90 *91 ******************************************************************************/92 93void94acpi_ns_check_acpi_compliance(char *pathname,95			      struct acpi_namespace_node *node,96			      const union acpi_predefined_info *predefined)97{98	u32 aml_param_count;99	u32 required_param_count;100 101	if (!predefined || (node->flags & ANOBJ_EVALUATED)) {102		return;103	}104 105	/* Get the ACPI-required arg count from the predefined info table */106 107	required_param_count =108	    METHOD_GET_ARG_COUNT(predefined->info.argument_list);109 110	/*111	 * If this object is not a control method, we can check if the ACPI112	 * spec requires that it be a method.113	 */114	if (node->type != ACPI_TYPE_METHOD) {115		if (required_param_count > 0) {116 117			/* Object requires args, must be implemented as a method */118 119			ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,120						    ACPI_WARN_ALWAYS,121						    "Object (%s) must be a control method with %u arguments",122						    acpi_ut_get_type_name(node->123									  type),124						    required_param_count));125		} else if (!required_param_count126			   && !predefined->info.expected_btypes) {127 128			/* Object requires no args and no return value, must be a method */129 130			ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,131						    ACPI_WARN_ALWAYS,132						    "Object (%s) must be a control method "133						    "with no arguments and no return value",134						    acpi_ut_get_type_name(node->135									  type)));136		}137 138		return;139	}140 141	/*142	 * This is a control method.143	 * Check that the ASL/AML-defined parameter count for this method144	 * matches the ACPI-required parameter count145	 *146	 * Some methods are allowed to have a "minimum" number of args (_SCP)147	 * because their definition in ACPI has changed over time.148	 *149	 * Note: These are BIOS errors in the declaration of the object150	 */151	aml_param_count = node->object->method.param_count;152 153	if (aml_param_count < required_param_count) {154		ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,155					    "Insufficient arguments - "156					    "ASL declared %u, ACPI requires %u",157					    aml_param_count,158					    required_param_count));159	} else if ((aml_param_count > required_param_count)160		   && !(predefined->info.161			argument_list & ARG_COUNT_IS_MINIMUM)) {162		ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,163					    "Excess arguments - "164					    "ASL declared %u, ACPI requires %u",165					    aml_param_count,166					    required_param_count));167	}168}169 170/*******************************************************************************171 *172 * FUNCTION:    acpi_ns_check_argument_count173 *174 * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)175 *              node            - Namespace node for the method/object176 *              user_param_count - Number of args passed in by the caller177 *              predefined      - Pointer to entry in predefined name table178 *179 * RETURN:      None180 *181 * DESCRIPTION: Check that incoming argument count matches the declared182 *              parameter count (in the ASL/AML) for an object.183 *184 ******************************************************************************/185 186void187acpi_ns_check_argument_count(char *pathname,188			     struct acpi_namespace_node *node,189			     u32 user_param_count,190			     const union acpi_predefined_info *predefined)191{192	u32 aml_param_count;193	u32 required_param_count;194 195	if (node->flags & ANOBJ_EVALUATED) {196		return;197	}198 199	if (!predefined) {200		/*201		 * Not a predefined name. Check the incoming user argument count202		 * against the count that is specified in the method/object.203		 */204		if (node->type != ACPI_TYPE_METHOD) {205			if (user_param_count) {206				ACPI_INFO_PREDEFINED((AE_INFO, pathname,207						      ACPI_WARN_ALWAYS,208						      "%u arguments were passed to a non-method ACPI object (%s)",209						      user_param_count,210						      acpi_ut_get_type_name211						      (node->type)));212			}213 214			return;215		}216 217		/*218		 * This is a control method. Check the parameter count.219		 * We can only check the incoming argument count against the220		 * argument count declared for the method in the ASL/AML.221		 *222		 * Emit a message if too few or too many arguments have been passed223		 * by the caller.224		 *225		 * Note: Too many arguments will not cause the method to226		 * fail. However, the method will fail if there are too few227		 * arguments and the method attempts to use one of the missing ones.228		 */229		aml_param_count = node->object->method.param_count;230 231		if (user_param_count < aml_param_count) {232			ACPI_WARN_PREDEFINED((AE_INFO, pathname,233					      ACPI_WARN_ALWAYS,234					      "Insufficient arguments - "235					      "Caller passed %u, method requires %u",236					      user_param_count,237					      aml_param_count));238		} else if (user_param_count > aml_param_count) {239			ACPI_INFO_PREDEFINED((AE_INFO, pathname,240					      ACPI_WARN_ALWAYS,241					      "Excess arguments - "242					      "Caller passed %u, method requires %u",243					      user_param_count,244					      aml_param_count));245		}246 247		return;248	}249 250	/*251	 * This is a predefined name. Validate the user-supplied parameter252	 * count against the ACPI specification. We don't validate against253	 * the method itself because what is important here is that the254	 * caller is in conformance with the spec. (The arg count for the255	 * method was checked against the ACPI spec earlier.)256	 *257	 * Some methods are allowed to have a "minimum" number of args (_SCP)258	 * because their definition in ACPI has changed over time.259	 */260	required_param_count =261	    METHOD_GET_ARG_COUNT(predefined->info.argument_list);262 263	if (user_param_count < required_param_count) {264		ACPI_WARN_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,265				      "Insufficient arguments - "266				      "Caller passed %u, ACPI requires %u",267				      user_param_count, required_param_count));268	} else if ((user_param_count > required_param_count) &&269		   !(predefined->info.argument_list & ARG_COUNT_IS_MINIMUM)) {270		ACPI_INFO_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,271				      "Excess arguments - "272				      "Caller passed %u, ACPI requires %u",273				      user_param_count, required_param_count));274	}275}276