brintos

brintos / linux-shallow public Read only

0
0
Text · 9.3 KiB · 6f4eace Raw
342 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: psxface - Parser external interfaces5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acparser.h"13#include "acdispat.h"14#include "acinterp.h"15#include "actables.h"16#include "acnamesp.h"17 18#define _COMPONENT          ACPI_PARSER19ACPI_MODULE_NAME("psxface")20 21/* Local Prototypes */22static void23acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);24 25/*******************************************************************************26 *27 * FUNCTION:    acpi_debug_trace28 *29 * PARAMETERS:  method_name     - Valid ACPI name string30 *              debug_level     - Optional level mask. 0 to use default31 *              debug_layer     - Optional layer mask. 0 to use default32 *              flags           - bit 1: one shot(1) or persistent(0)33 *34 * RETURN:      Status35 *36 * DESCRIPTION: External interface to enable debug tracing during control37 *              method execution38 *39 ******************************************************************************/40 41acpi_status42acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags)43{44	acpi_status status;45 46	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);47	if (ACPI_FAILURE(status)) {48		return (status);49	}50 51	acpi_gbl_trace_method_name = name;52	acpi_gbl_trace_flags = flags;53	acpi_gbl_trace_dbg_level = debug_level;54	acpi_gbl_trace_dbg_layer = debug_layer;55	status = AE_OK;56 57	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);58	return (status);59}60 61/*******************************************************************************62 *63 * FUNCTION:    acpi_ps_execute_method64 *65 * PARAMETERS:  info            - Method info block, contains:66 *                  node            - Method Node to execute67 *                  obj_desc        - Method object68 *                  parameters      - List of parameters to pass to the method,69 *                                    terminated by NULL. Params itself may be70 *                                    NULL if no parameters are being passed.71 *                  return_object   - Where to put method's return value (if72 *                                    any). If NULL, no value is returned.73 *                  parameter_type  - Type of Parameter list74 *                  return_object   - Where to put method's return value (if75 *                                    any). If NULL, no value is returned.76 *                  pass_number     - Parse or execute pass77 *78 * RETURN:      Status79 *80 * DESCRIPTION: Execute a control method81 *82 ******************************************************************************/83 84acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)85{86	acpi_status status;87	union acpi_parse_object *op;88	struct acpi_walk_state *walk_state;89 90	ACPI_FUNCTION_TRACE(ps_execute_method);91 92	/* Quick validation of DSDT header */93 94	acpi_tb_check_dsdt_header();95 96	/* Validate the Info and method Node */97 98	if (!info || !info->node) {99		return_ACPI_STATUS(AE_NULL_ENTRY);100	}101 102	/* Init for new method, wait on concurrency semaphore */103 104	status =105	    acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);106	if (ACPI_FAILURE(status)) {107		return_ACPI_STATUS(status);108	}109 110	/*111	 * The caller "owns" the parameters, so give each one an extra reference112	 */113	acpi_ps_update_parameter_list(info, REF_INCREMENT);114 115	/*116	 * Execute the method. Performs parse simultaneously117	 */118	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,119			  "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",120			  info->node->name.ascii, info->node, info->obj_desc));121 122	/* Create and init a Root Node */123 124	op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);125	if (!op) {126		status = AE_NO_MEMORY;127		goto cleanup;128	}129 130	/* Create and initialize a new walk state */131 132	info->pass_number = ACPI_IMODE_EXECUTE;133	walk_state =134	    acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,135				      NULL, NULL);136	if (!walk_state) {137		status = AE_NO_MEMORY;138		goto cleanup;139	}140 141	status = acpi_ds_init_aml_walk(walk_state, op, info->node,142				       info->obj_desc->method.aml_start,143				       info->obj_desc->method.aml_length, info,144				       info->pass_number);145	if (ACPI_FAILURE(status)) {146		acpi_ds_delete_walk_state(walk_state);147		goto cleanup;148	}149 150	walk_state->method_pathname = info->full_pathname;151	walk_state->method_is_nested = FALSE;152 153	if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {154		walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;155	}156 157	/* Invoke an internal method if necessary */158 159	if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {160		status =161		    info->obj_desc->method.dispatch.implementation(walk_state);162		info->return_object = walk_state->return_desc;163 164		/* Cleanup states */165 166		acpi_ds_scope_stack_clear(walk_state);167		acpi_ps_cleanup_scope(&walk_state->parser_state);168		acpi_ds_terminate_control_method(walk_state->method_desc,169						 walk_state);170		acpi_ds_delete_walk_state(walk_state);171		goto cleanup;172	}173 174	/*175	 * Start method evaluation with an implicit return of zero.176	 * This is done for Windows compatibility.177	 */178	if (acpi_gbl_enable_interpreter_slack) {179		walk_state->implicit_return_obj =180		    acpi_ut_create_integer_object((u64) 0);181		if (!walk_state->implicit_return_obj) {182			status = AE_NO_MEMORY;183			acpi_ds_delete_walk_state(walk_state);184			goto cleanup;185		}186	}187 188	/* Parse the AML */189 190	status = acpi_ps_parse_aml(walk_state);191 192	/* walk_state was deleted by parse_aml */193 194cleanup:195	acpi_ps_delete_parse_tree(op);196 197	/* Take away the extra reference that we gave the parameters above */198 199	acpi_ps_update_parameter_list(info, REF_DECREMENT);200 201	/* Exit now if error above */202 203	if (ACPI_FAILURE(status)) {204		return_ACPI_STATUS(status);205	}206 207	/*208	 * If the method has returned an object, signal this to the caller with209	 * a control exception code210	 */211	if (info->return_object) {212		ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",213				  info->return_object));214		ACPI_DUMP_STACK_ENTRY(info->return_object);215 216		status = AE_CTRL_RETURN_VALUE;217	}218 219	return_ACPI_STATUS(status);220}221 222/*******************************************************************************223 *224 * FUNCTION:    acpi_ps_execute_table225 *226 * PARAMETERS:  info            - Method info block, contains:227 *              node            - Node to where the is entered into the228 *                                namespace229 *              obj_desc        - Pseudo method object describing the AML230 *                                code of the entire table231 *              pass_number     - Parse or execute pass232 *233 * RETURN:      Status234 *235 * DESCRIPTION: Execute a table236 *237 ******************************************************************************/238 239acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info)240{241	acpi_status status;242	union acpi_parse_object *op = NULL;243	struct acpi_walk_state *walk_state = NULL;244 245	ACPI_FUNCTION_TRACE(ps_execute_table);246 247	/* Create and init a Root Node */248 249	op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);250	if (!op) {251		status = AE_NO_MEMORY;252		goto cleanup;253	}254 255	/* Create and initialize a new walk state */256 257	walk_state =258	    acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,259				      NULL, NULL);260	if (!walk_state) {261		status = AE_NO_MEMORY;262		goto cleanup;263	}264 265	status = acpi_ds_init_aml_walk(walk_state, op, info->node,266				       info->obj_desc->method.aml_start,267				       info->obj_desc->method.aml_length, info,268				       info->pass_number);269	if (ACPI_FAILURE(status)) {270		goto cleanup;271	}272 273	walk_state->method_pathname = info->full_pathname;274	walk_state->method_is_nested = FALSE;275 276	if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {277		walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;278	}279 280	/* Info->Node is the default location to load the table  */281 282	if (info->node && info->node != acpi_gbl_root_node) {283		status =284		    acpi_ds_scope_stack_push(info->node, ACPI_TYPE_METHOD,285					     walk_state);286		if (ACPI_FAILURE(status)) {287			goto cleanup;288		}289	}290 291	/*292	 * Parse the AML, walk_state will be deleted by parse_aml293	 */294	acpi_ex_enter_interpreter();295	status = acpi_ps_parse_aml(walk_state);296	acpi_ex_exit_interpreter();297	walk_state = NULL;298 299cleanup:300	if (walk_state) {301		acpi_ds_delete_walk_state(walk_state);302	}303	if (op) {304		acpi_ps_delete_parse_tree(op);305	}306	return_ACPI_STATUS(status);307}308 309/*******************************************************************************310 *311 * FUNCTION:    acpi_ps_update_parameter_list312 *313 * PARAMETERS:  info            - See struct acpi_evaluate_info314 *                                (Used: parameter_type and Parameters)315 *              action          - Add or Remove reference316 *317 * RETURN:      Status318 *319 * DESCRIPTION: Update reference count on all method parameter objects320 *321 ******************************************************************************/322 323static void324acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)325{326	u32 i;327 328	if (info->parameters) {329 330		/* Update reference count for each parameter */331 332		for (i = 0; info->parameters[i]; i++) {333 334			/* Ignore errors, just do them all */335 336			(void)acpi_ut_update_object_reference(info->337							      parameters[i],338							      action);339		}340	}341}342