brintos

brintos / linux-shallow public Read only

0
0
Text · 10.2 KiB · 4354c17 Raw
375 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: dsargs - Support for execution of dynamic arguments for static5 *                       objects (regions, fields, buffer fields, etc.)6 *7 * Copyright (C) 2000 - 2023, Intel Corp.8 *9 *****************************************************************************/10 11#include <acpi/acpi.h>12#include "accommon.h"13#include "acparser.h"14#include "amlcode.h"15#include "acdispat.h"16#include "acnamesp.h"17 18#define _COMPONENT          ACPI_DISPATCHER19ACPI_MODULE_NAME("dsargs")20 21/* Local prototypes */22static acpi_status23acpi_ds_execute_arguments(struct acpi_namespace_node *node,24			  struct acpi_namespace_node *scope_node,25			  u32 aml_length, u8 *aml_start);26 27/*******************************************************************************28 *29 * FUNCTION:    acpi_ds_execute_arguments30 *31 * PARAMETERS:  node                - Object NS node32 *              scope_node          - Parent NS node33 *              aml_length          - Length of executable AML34 *              aml_start           - Pointer to the AML35 *36 * RETURN:      Status.37 *38 * DESCRIPTION: Late (deferred) execution of region or field arguments39 *40 ******************************************************************************/41 42static acpi_status43acpi_ds_execute_arguments(struct acpi_namespace_node *node,44			  struct acpi_namespace_node *scope_node,45			  u32 aml_length, u8 *aml_start)46{47	acpi_status status;48	union acpi_parse_object *op;49	struct acpi_walk_state *walk_state;50 51	ACPI_FUNCTION_TRACE_PTR(ds_execute_arguments, aml_start);52 53	/* Allocate a new parser op to be the root of the parsed tree */54 55	op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);56	if (!op) {57		return_ACPI_STATUS(AE_NO_MEMORY);58	}59 60	/* Save the Node for use in acpi_ps_parse_aml */61 62	op->common.node = scope_node;63 64	/* Create and initialize a new parser state */65 66	walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);67	if (!walk_state) {68		status = AE_NO_MEMORY;69		goto cleanup;70	}71 72	status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,73				       aml_length, NULL, ACPI_IMODE_LOAD_PASS1);74	if (ACPI_FAILURE(status)) {75		acpi_ds_delete_walk_state(walk_state);76		goto cleanup;77	}78 79	/* Mark this parse as a deferred opcode */80 81	walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;82	walk_state->deferred_node = node;83 84	/* Pass1: Parse the entire declaration */85 86	status = acpi_ps_parse_aml(walk_state);87	if (ACPI_FAILURE(status)) {88		goto cleanup;89	}90 91	/* Get and init the Op created above */92 93	op->common.node = node;94	acpi_ps_delete_parse_tree(op);95 96	/* Evaluate the deferred arguments */97 98	op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);99	if (!op) {100		return_ACPI_STATUS(AE_NO_MEMORY);101	}102 103	op->common.node = scope_node;104 105	/* Create and initialize a new parser state */106 107	walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);108	if (!walk_state) {109		status = AE_NO_MEMORY;110		goto cleanup;111	}112 113	/* Execute the opcode and arguments */114 115	status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,116				       aml_length, NULL, ACPI_IMODE_EXECUTE);117	if (ACPI_FAILURE(status)) {118		acpi_ds_delete_walk_state(walk_state);119		goto cleanup;120	}121 122	/* Mark this execution as a deferred opcode */123 124	walk_state->deferred_node = node;125	status = acpi_ps_parse_aml(walk_state);126 127cleanup:128	acpi_ps_delete_parse_tree(op);129	return_ACPI_STATUS(status);130}131 132/*******************************************************************************133 *134 * FUNCTION:    acpi_ds_get_buffer_field_arguments135 *136 * PARAMETERS:  obj_desc        - A valid buffer_field object137 *138 * RETURN:      Status.139 *140 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late141 *              evaluation of these field attributes.142 *143 ******************************************************************************/144 145acpi_status146acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)147{148	union acpi_operand_object *extra_desc;149	struct acpi_namespace_node *node;150	acpi_status status;151 152	ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);153 154	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {155		return_ACPI_STATUS(AE_OK);156	}157 158	/* Get the AML pointer (method object) and buffer_field node */159 160	extra_desc = acpi_ns_get_secondary_object(obj_desc);161	node = obj_desc->buffer_field.node;162 163	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname164			(ACPI_TYPE_BUFFER_FIELD, node, NULL));165 166	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",167			  acpi_ut_get_node_name(node)));168 169	/* Execute the AML code for the term_arg arguments */170 171	status = acpi_ds_execute_arguments(node, node->parent,172					   extra_desc->extra.aml_length,173					   extra_desc->extra.aml_start);174	return_ACPI_STATUS(status);175}176 177/*******************************************************************************178 *179 * FUNCTION:    acpi_ds_get_bank_field_arguments180 *181 * PARAMETERS:  obj_desc        - A valid bank_field object182 *183 * RETURN:      Status.184 *185 * DESCRIPTION: Get bank_field bank_value. This implements the late186 *              evaluation of these field attributes.187 *188 ******************************************************************************/189 190acpi_status191acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)192{193	union acpi_operand_object *extra_desc;194	struct acpi_namespace_node *node;195	acpi_status status;196 197	ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);198 199	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {200		return_ACPI_STATUS(AE_OK);201	}202 203	/* Get the AML pointer (method object) and bank_field node */204 205	extra_desc = acpi_ns_get_secondary_object(obj_desc);206	node = obj_desc->bank_field.node;207 208	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname209			(ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));210 211	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",212			  acpi_ut_get_node_name(node)));213 214	/* Execute the AML code for the term_arg arguments */215 216	status = acpi_ds_execute_arguments(node, node->parent,217					   extra_desc->extra.aml_length,218					   extra_desc->extra.aml_start);219	if (ACPI_FAILURE(status)) {220		return_ACPI_STATUS(status);221	}222 223	status = acpi_ut_add_address_range(obj_desc->region.space_id,224					   obj_desc->region.address,225					   obj_desc->region.length, node);226	return_ACPI_STATUS(status);227}228 229/*******************************************************************************230 *231 * FUNCTION:    acpi_ds_get_buffer_arguments232 *233 * PARAMETERS:  obj_desc        - A valid Buffer object234 *235 * RETURN:      Status.236 *237 * DESCRIPTION: Get Buffer length and initializer byte list. This implements238 *              the late evaluation of these attributes.239 *240 ******************************************************************************/241 242acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)243{244	struct acpi_namespace_node *node;245	acpi_status status;246 247	ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);248 249	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {250		return_ACPI_STATUS(AE_OK);251	}252 253	/* Get the Buffer node */254 255	node = obj_desc->buffer.node;256	if (!node) {257		ACPI_ERROR((AE_INFO,258			    "No pointer back to namespace node in buffer object %p",259			    obj_desc));260		return_ACPI_STATUS(AE_AML_INTERNAL);261	}262 263	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));264 265	/* Execute the AML code for the term_arg arguments */266 267	status = acpi_ds_execute_arguments(node, node,268					   obj_desc->buffer.aml_length,269					   obj_desc->buffer.aml_start);270	return_ACPI_STATUS(status);271}272 273/*******************************************************************************274 *275 * FUNCTION:    acpi_ds_get_package_arguments276 *277 * PARAMETERS:  obj_desc        - A valid Package object278 *279 * RETURN:      Status.280 *281 * DESCRIPTION: Get Package length and initializer byte list. This implements282 *              the late evaluation of these attributes.283 *284 ******************************************************************************/285 286acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)287{288	struct acpi_namespace_node *node;289	acpi_status status;290 291	ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);292 293	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {294		return_ACPI_STATUS(AE_OK);295	}296 297	/* Get the Package node */298 299	node = obj_desc->package.node;300	if (!node) {301		ACPI_ERROR((AE_INFO,302			    "No pointer back to namespace node in package %p",303			    obj_desc));304		return_ACPI_STATUS(AE_AML_INTERNAL);305	}306 307	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Argument Init, AML Ptr: %p\n",308			  obj_desc->package.aml_start));309 310	/* Execute the AML code for the term_arg arguments */311 312	status = acpi_ds_execute_arguments(node, node,313					   obj_desc->package.aml_length,314					   obj_desc->package.aml_start);315 316	return_ACPI_STATUS(status);317}318 319/*******************************************************************************320 *321 * FUNCTION:    acpi_ds_get_region_arguments322 *323 * PARAMETERS:  obj_desc        - A valid region object324 *325 * RETURN:      Status.326 *327 * DESCRIPTION: Get region address and length. This implements the late328 *              evaluation of these region attributes.329 *330 ******************************************************************************/331 332acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)333{334	struct acpi_namespace_node *node;335	acpi_status status;336	union acpi_operand_object *extra_desc;337 338	ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);339 340	if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {341		return_ACPI_STATUS(AE_OK);342	}343 344	extra_desc = acpi_ns_get_secondary_object(obj_desc);345	if (!extra_desc) {346		return_ACPI_STATUS(AE_NOT_EXIST);347	}348 349	/* Get the Region node */350 351	node = obj_desc->region.node;352 353	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname354			(ACPI_TYPE_REGION, node, NULL));355 356	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,357			  "[%4.4s] OpRegion Arg Init at AML %p\n",358			  acpi_ut_get_node_name(node),359			  extra_desc->extra.aml_start));360 361	/* Execute the argument AML */362 363	status = acpi_ds_execute_arguments(node, extra_desc->extra.scope_node,364					   extra_desc->extra.aml_length,365					   extra_desc->extra.aml_start);366	if (ACPI_FAILURE(status)) {367		return_ACPI_STATUS(status);368	}369 370	status = acpi_ut_add_address_range(obj_desc->region.space_id,371					   obj_desc->region.address,372					   obj_desc->region.length, node);373	return_ACPI_STATUS(status);374}375