195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
29ad19ac4SBob Moore /******************************************************************************
39ad19ac4SBob Moore *
49ad19ac4SBob Moore * Module Name: dsargs - Support for execution of dynamic arguments for static
59ad19ac4SBob Moore * objects (regions, fields, buffer fields, etc.)
69ad19ac4SBob Moore *
7*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
89ad19ac4SBob Moore *
995857638SErik Schmauss *****************************************************************************/
109ad19ac4SBob Moore
119ad19ac4SBob Moore #include <acpi/acpi.h>
129ad19ac4SBob Moore #include "accommon.h"
139ad19ac4SBob Moore #include "acparser.h"
149ad19ac4SBob Moore #include "amlcode.h"
159ad19ac4SBob Moore #include "acdispat.h"
169ad19ac4SBob Moore #include "acnamesp.h"
179ad19ac4SBob Moore
189ad19ac4SBob Moore #define _COMPONENT ACPI_DISPATCHER
199ad19ac4SBob Moore ACPI_MODULE_NAME("dsargs")
209ad19ac4SBob Moore
219ad19ac4SBob Moore /* Local prototypes */
229ad19ac4SBob Moore static acpi_status
239ad19ac4SBob Moore acpi_ds_execute_arguments(struct acpi_namespace_node *node,
249ad19ac4SBob Moore struct acpi_namespace_node *scope_node,
259ad19ac4SBob Moore u32 aml_length, u8 *aml_start);
269ad19ac4SBob Moore
279ad19ac4SBob Moore /*******************************************************************************
289ad19ac4SBob Moore *
299ad19ac4SBob Moore * FUNCTION: acpi_ds_execute_arguments
309ad19ac4SBob Moore *
31ba494beeSBob Moore * PARAMETERS: node - Object NS node
329ad19ac4SBob Moore * scope_node - Parent NS node
339ad19ac4SBob Moore * aml_length - Length of executable AML
349ad19ac4SBob Moore * aml_start - Pointer to the AML
359ad19ac4SBob Moore *
369ad19ac4SBob Moore * RETURN: Status.
379ad19ac4SBob Moore *
389ad19ac4SBob Moore * DESCRIPTION: Late (deferred) execution of region or field arguments
399ad19ac4SBob Moore *
409ad19ac4SBob Moore ******************************************************************************/
419ad19ac4SBob Moore
429ad19ac4SBob Moore static acpi_status
acpi_ds_execute_arguments(struct acpi_namespace_node * node,struct acpi_namespace_node * scope_node,u32 aml_length,u8 * aml_start)439ad19ac4SBob Moore acpi_ds_execute_arguments(struct acpi_namespace_node *node,
449ad19ac4SBob Moore struct acpi_namespace_node *scope_node,
459ad19ac4SBob Moore u32 aml_length, u8 *aml_start)
469ad19ac4SBob Moore {
479ad19ac4SBob Moore acpi_status status;
489ad19ac4SBob Moore union acpi_parse_object *op;
499ad19ac4SBob Moore struct acpi_walk_state *walk_state;
509ad19ac4SBob Moore
51b9ef2ab0SBob Moore ACPI_FUNCTION_TRACE_PTR(ds_execute_arguments, aml_start);
529ad19ac4SBob Moore
539ad19ac4SBob Moore /* Allocate a new parser op to be the root of the parsed tree */
549ad19ac4SBob Moore
5562eb935bSLv Zheng op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
569ad19ac4SBob Moore if (!op) {
579ad19ac4SBob Moore return_ACPI_STATUS(AE_NO_MEMORY);
589ad19ac4SBob Moore }
599ad19ac4SBob Moore
609ad19ac4SBob Moore /* Save the Node for use in acpi_ps_parse_aml */
619ad19ac4SBob Moore
629ad19ac4SBob Moore op->common.node = scope_node;
639ad19ac4SBob Moore
649ad19ac4SBob Moore /* Create and initialize a new parser state */
659ad19ac4SBob Moore
669ad19ac4SBob Moore walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
679ad19ac4SBob Moore if (!walk_state) {
689ad19ac4SBob Moore status = AE_NO_MEMORY;
699ad19ac4SBob Moore goto cleanup;
709ad19ac4SBob Moore }
719ad19ac4SBob Moore
729ad19ac4SBob Moore status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
739ad19ac4SBob Moore aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
749ad19ac4SBob Moore if (ACPI_FAILURE(status)) {
759ad19ac4SBob Moore acpi_ds_delete_walk_state(walk_state);
769ad19ac4SBob Moore goto cleanup;
779ad19ac4SBob Moore }
789ad19ac4SBob Moore
799ad19ac4SBob Moore /* Mark this parse as a deferred opcode */
809ad19ac4SBob Moore
819ad19ac4SBob Moore walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
829ad19ac4SBob Moore walk_state->deferred_node = node;
839ad19ac4SBob Moore
849ad19ac4SBob Moore /* Pass1: Parse the entire declaration */
859ad19ac4SBob Moore
869ad19ac4SBob Moore status = acpi_ps_parse_aml(walk_state);
879ad19ac4SBob Moore if (ACPI_FAILURE(status)) {
889ad19ac4SBob Moore goto cleanup;
899ad19ac4SBob Moore }
909ad19ac4SBob Moore
919ad19ac4SBob Moore /* Get and init the Op created above */
929ad19ac4SBob Moore
939ad19ac4SBob Moore op->common.node = node;
949ad19ac4SBob Moore acpi_ps_delete_parse_tree(op);
959ad19ac4SBob Moore
969ad19ac4SBob Moore /* Evaluate the deferred arguments */
979ad19ac4SBob Moore
9862eb935bSLv Zheng op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
999ad19ac4SBob Moore if (!op) {
1009ad19ac4SBob Moore return_ACPI_STATUS(AE_NO_MEMORY);
1019ad19ac4SBob Moore }
1029ad19ac4SBob Moore
1039ad19ac4SBob Moore op->common.node = scope_node;
1049ad19ac4SBob Moore
1059ad19ac4SBob Moore /* Create and initialize a new parser state */
1069ad19ac4SBob Moore
1079ad19ac4SBob Moore walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
1089ad19ac4SBob Moore if (!walk_state) {
1099ad19ac4SBob Moore status = AE_NO_MEMORY;
1109ad19ac4SBob Moore goto cleanup;
1119ad19ac4SBob Moore }
1129ad19ac4SBob Moore
1139ad19ac4SBob Moore /* Execute the opcode and arguments */
1149ad19ac4SBob Moore
1159ad19ac4SBob Moore status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
1169ad19ac4SBob Moore aml_length, NULL, ACPI_IMODE_EXECUTE);
1179ad19ac4SBob Moore if (ACPI_FAILURE(status)) {
1189ad19ac4SBob Moore acpi_ds_delete_walk_state(walk_state);
1199ad19ac4SBob Moore goto cleanup;
1209ad19ac4SBob Moore }
1219ad19ac4SBob Moore
1229ad19ac4SBob Moore /* Mark this execution as a deferred opcode */
1239ad19ac4SBob Moore
1249ad19ac4SBob Moore walk_state->deferred_node = node;
1259ad19ac4SBob Moore status = acpi_ps_parse_aml(walk_state);
1269ad19ac4SBob Moore
1279ad19ac4SBob Moore cleanup:
1289ad19ac4SBob Moore acpi_ps_delete_parse_tree(op);
1299ad19ac4SBob Moore return_ACPI_STATUS(status);
1309ad19ac4SBob Moore }
1319ad19ac4SBob Moore
1329ad19ac4SBob Moore /*******************************************************************************
1339ad19ac4SBob Moore *
1349ad19ac4SBob Moore * FUNCTION: acpi_ds_get_buffer_field_arguments
1359ad19ac4SBob Moore *
1369ad19ac4SBob Moore * PARAMETERS: obj_desc - A valid buffer_field object
1379ad19ac4SBob Moore *
1389ad19ac4SBob Moore * RETURN: Status.
1399ad19ac4SBob Moore *
1409ad19ac4SBob Moore * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
1419ad19ac4SBob Moore * evaluation of these field attributes.
1429ad19ac4SBob Moore *
1439ad19ac4SBob Moore ******************************************************************************/
1449ad19ac4SBob Moore
1459ad19ac4SBob Moore acpi_status
acpi_ds_get_buffer_field_arguments(union acpi_operand_object * obj_desc)1469ad19ac4SBob Moore acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
1479ad19ac4SBob Moore {
1489ad19ac4SBob Moore union acpi_operand_object *extra_desc;
1499ad19ac4SBob Moore struct acpi_namespace_node *node;
1509ad19ac4SBob Moore acpi_status status;
1519ad19ac4SBob Moore
1529ad19ac4SBob Moore ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
1539ad19ac4SBob Moore
1549ad19ac4SBob Moore if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
1559ad19ac4SBob Moore return_ACPI_STATUS(AE_OK);
1569ad19ac4SBob Moore }
1579ad19ac4SBob Moore
1589ad19ac4SBob Moore /* Get the AML pointer (method object) and buffer_field node */
1599ad19ac4SBob Moore
1609ad19ac4SBob Moore extra_desc = acpi_ns_get_secondary_object(obj_desc);
1619ad19ac4SBob Moore node = obj_desc->buffer_field.node;
1629ad19ac4SBob Moore
1631fad8738SBob Moore ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
1641fad8738SBob Moore (ACPI_TYPE_BUFFER_FIELD, node, NULL));
1659ad19ac4SBob Moore
1669ad19ac4SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
1679ad19ac4SBob Moore acpi_ut_get_node_name(node)));
1689ad19ac4SBob Moore
1699ad19ac4SBob Moore /* Execute the AML code for the term_arg arguments */
1709ad19ac4SBob Moore
1719ad19ac4SBob Moore status = acpi_ds_execute_arguments(node, node->parent,
1729ad19ac4SBob Moore extra_desc->extra.aml_length,
1739ad19ac4SBob Moore extra_desc->extra.aml_start);
1749ad19ac4SBob Moore return_ACPI_STATUS(status);
1759ad19ac4SBob Moore }
1769ad19ac4SBob Moore
1779ad19ac4SBob Moore /*******************************************************************************
1789ad19ac4SBob Moore *
1799ad19ac4SBob Moore * FUNCTION: acpi_ds_get_bank_field_arguments
1809ad19ac4SBob Moore *
1819ad19ac4SBob Moore * PARAMETERS: obj_desc - A valid bank_field object
1829ad19ac4SBob Moore *
1839ad19ac4SBob Moore * RETURN: Status.
1849ad19ac4SBob Moore *
1859ad19ac4SBob Moore * DESCRIPTION: Get bank_field bank_value. This implements the late
1869ad19ac4SBob Moore * evaluation of these field attributes.
1879ad19ac4SBob Moore *
1889ad19ac4SBob Moore ******************************************************************************/
1899ad19ac4SBob Moore
1909ad19ac4SBob Moore acpi_status
acpi_ds_get_bank_field_arguments(union acpi_operand_object * obj_desc)1919ad19ac4SBob Moore acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
1929ad19ac4SBob Moore {
1939ad19ac4SBob Moore union acpi_operand_object *extra_desc;
1949ad19ac4SBob Moore struct acpi_namespace_node *node;
1959ad19ac4SBob Moore acpi_status status;
1969ad19ac4SBob Moore
1979ad19ac4SBob Moore ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
1989ad19ac4SBob Moore
1999ad19ac4SBob Moore if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
2009ad19ac4SBob Moore return_ACPI_STATUS(AE_OK);
2019ad19ac4SBob Moore }
2029ad19ac4SBob Moore
2039ad19ac4SBob Moore /* Get the AML pointer (method object) and bank_field node */
2049ad19ac4SBob Moore
2059ad19ac4SBob Moore extra_desc = acpi_ns_get_secondary_object(obj_desc);
2069ad19ac4SBob Moore node = obj_desc->bank_field.node;
2079ad19ac4SBob Moore
2089ad19ac4SBob Moore ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
2099ad19ac4SBob Moore (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
2109ad19ac4SBob Moore
2119ad19ac4SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
2129ad19ac4SBob Moore acpi_ut_get_node_name(node)));
2139ad19ac4SBob Moore
2149ad19ac4SBob Moore /* Execute the AML code for the term_arg arguments */
2159ad19ac4SBob Moore
2169ad19ac4SBob Moore status = acpi_ds_execute_arguments(node, node->parent,
2179ad19ac4SBob Moore extra_desc->extra.aml_length,
2189ad19ac4SBob Moore extra_desc->extra.aml_start);
219f654c0feSLin Ming if (ACPI_FAILURE(status)) {
220f654c0feSLin Ming return_ACPI_STATUS(status);
221f654c0feSLin Ming }
222f654c0feSLin Ming
223f654c0feSLin Ming status = acpi_ut_add_address_range(obj_desc->region.space_id,
224f654c0feSLin Ming obj_desc->region.address,
225f654c0feSLin Ming obj_desc->region.length, node);
2269ad19ac4SBob Moore return_ACPI_STATUS(status);
2279ad19ac4SBob Moore }
2289ad19ac4SBob Moore
2299ad19ac4SBob Moore /*******************************************************************************
2309ad19ac4SBob Moore *
2319ad19ac4SBob Moore * FUNCTION: acpi_ds_get_buffer_arguments
2329ad19ac4SBob Moore *
2339ad19ac4SBob Moore * PARAMETERS: obj_desc - A valid Buffer object
2349ad19ac4SBob Moore *
2359ad19ac4SBob Moore * RETURN: Status.
2369ad19ac4SBob Moore *
2379ad19ac4SBob Moore * DESCRIPTION: Get Buffer length and initializer byte list. This implements
2389ad19ac4SBob Moore * the late evaluation of these attributes.
2399ad19ac4SBob Moore *
2409ad19ac4SBob Moore ******************************************************************************/
2419ad19ac4SBob Moore
acpi_ds_get_buffer_arguments(union acpi_operand_object * obj_desc)2429ad19ac4SBob Moore acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
2439ad19ac4SBob Moore {
2449ad19ac4SBob Moore struct acpi_namespace_node *node;
2459ad19ac4SBob Moore acpi_status status;
2469ad19ac4SBob Moore
2479ad19ac4SBob Moore ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
2489ad19ac4SBob Moore
2499ad19ac4SBob Moore if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
2509ad19ac4SBob Moore return_ACPI_STATUS(AE_OK);
2519ad19ac4SBob Moore }
2529ad19ac4SBob Moore
2539ad19ac4SBob Moore /* Get the Buffer node */
2549ad19ac4SBob Moore
2559ad19ac4SBob Moore node = obj_desc->buffer.node;
2569ad19ac4SBob Moore if (!node) {
2579ad19ac4SBob Moore ACPI_ERROR((AE_INFO,
2589ad19ac4SBob Moore "No pointer back to namespace node in buffer object %p",
2599ad19ac4SBob Moore obj_desc));
2609ad19ac4SBob Moore return_ACPI_STATUS(AE_AML_INTERNAL);
2619ad19ac4SBob Moore }
2629ad19ac4SBob Moore
2639ad19ac4SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
2649ad19ac4SBob Moore
2659ad19ac4SBob Moore /* Execute the AML code for the term_arg arguments */
2669ad19ac4SBob Moore
2679ad19ac4SBob Moore status = acpi_ds_execute_arguments(node, node,
2689ad19ac4SBob Moore obj_desc->buffer.aml_length,
2699ad19ac4SBob Moore obj_desc->buffer.aml_start);
2709ad19ac4SBob Moore return_ACPI_STATUS(status);
2719ad19ac4SBob Moore }
2729ad19ac4SBob Moore
2739ad19ac4SBob Moore /*******************************************************************************
2749ad19ac4SBob Moore *
2759ad19ac4SBob Moore * FUNCTION: acpi_ds_get_package_arguments
2769ad19ac4SBob Moore *
2779ad19ac4SBob Moore * PARAMETERS: obj_desc - A valid Package object
2789ad19ac4SBob Moore *
2799ad19ac4SBob Moore * RETURN: Status.
2809ad19ac4SBob Moore *
2819ad19ac4SBob Moore * DESCRIPTION: Get Package length and initializer byte list. This implements
2829ad19ac4SBob Moore * the late evaluation of these attributes.
2839ad19ac4SBob Moore *
2849ad19ac4SBob Moore ******************************************************************************/
2859ad19ac4SBob Moore
acpi_ds_get_package_arguments(union acpi_operand_object * obj_desc)2869ad19ac4SBob Moore acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
2879ad19ac4SBob Moore {
2889ad19ac4SBob Moore struct acpi_namespace_node *node;
2899ad19ac4SBob Moore acpi_status status;
2909ad19ac4SBob Moore
2919ad19ac4SBob Moore ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
2929ad19ac4SBob Moore
2939ad19ac4SBob Moore if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
2949ad19ac4SBob Moore return_ACPI_STATUS(AE_OK);
2959ad19ac4SBob Moore }
2969ad19ac4SBob Moore
2979ad19ac4SBob Moore /* Get the Package node */
2989ad19ac4SBob Moore
2999ad19ac4SBob Moore node = obj_desc->package.node;
3009ad19ac4SBob Moore if (!node) {
3019ad19ac4SBob Moore ACPI_ERROR((AE_INFO,
3029ad19ac4SBob Moore "No pointer back to namespace node in package %p",
3039ad19ac4SBob Moore obj_desc));
3049ad19ac4SBob Moore return_ACPI_STATUS(AE_AML_INTERNAL);
3059ad19ac4SBob Moore }
3069ad19ac4SBob Moore
307b9ef2ab0SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Argument Init, AML Ptr: %p\n",
308b9ef2ab0SBob Moore obj_desc->package.aml_start));
3099ad19ac4SBob Moore
3109ad19ac4SBob Moore /* Execute the AML code for the term_arg arguments */
3119ad19ac4SBob Moore
3129ad19ac4SBob Moore status = acpi_ds_execute_arguments(node, node,
3139ad19ac4SBob Moore obj_desc->package.aml_length,
3149ad19ac4SBob Moore obj_desc->package.aml_start);
3151ef63231SBob Moore
3169ad19ac4SBob Moore return_ACPI_STATUS(status);
3179ad19ac4SBob Moore }
3189ad19ac4SBob Moore
3199ad19ac4SBob Moore /*******************************************************************************
3209ad19ac4SBob Moore *
3219ad19ac4SBob Moore * FUNCTION: acpi_ds_get_region_arguments
3229ad19ac4SBob Moore *
3239ad19ac4SBob Moore * PARAMETERS: obj_desc - A valid region object
3249ad19ac4SBob Moore *
3259ad19ac4SBob Moore * RETURN: Status.
3269ad19ac4SBob Moore *
3279ad19ac4SBob Moore * DESCRIPTION: Get region address and length. This implements the late
3289ad19ac4SBob Moore * evaluation of these region attributes.
3299ad19ac4SBob Moore *
3309ad19ac4SBob Moore ******************************************************************************/
3319ad19ac4SBob Moore
acpi_ds_get_region_arguments(union acpi_operand_object * obj_desc)3329ad19ac4SBob Moore acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
3339ad19ac4SBob Moore {
3349ad19ac4SBob Moore struct acpi_namespace_node *node;
3359ad19ac4SBob Moore acpi_status status;
3369ad19ac4SBob Moore union acpi_operand_object *extra_desc;
3379ad19ac4SBob Moore
3389ad19ac4SBob Moore ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
3399ad19ac4SBob Moore
3409ad19ac4SBob Moore if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
3419ad19ac4SBob Moore return_ACPI_STATUS(AE_OK);
3429ad19ac4SBob Moore }
3439ad19ac4SBob Moore
3449ad19ac4SBob Moore extra_desc = acpi_ns_get_secondary_object(obj_desc);
3459ad19ac4SBob Moore if (!extra_desc) {
3469ad19ac4SBob Moore return_ACPI_STATUS(AE_NOT_EXIST);
3479ad19ac4SBob Moore }
3489ad19ac4SBob Moore
3499ad19ac4SBob Moore /* Get the Region node */
3509ad19ac4SBob Moore
3519ad19ac4SBob Moore node = obj_desc->region.node;
3529ad19ac4SBob Moore
3539ad19ac4SBob Moore ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
3549ad19ac4SBob Moore (ACPI_TYPE_REGION, node, NULL));
3559ad19ac4SBob Moore
3561fad8738SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
3571fad8738SBob Moore "[%4.4s] OpRegion Arg Init at AML %p\n",
3589ad19ac4SBob Moore acpi_ut_get_node_name(node),
3599ad19ac4SBob Moore extra_desc->extra.aml_start));
3609ad19ac4SBob Moore
3619ad19ac4SBob Moore /* Execute the argument AML */
3629ad19ac4SBob Moore
3638931d9eaSLin Ming status = acpi_ds_execute_arguments(node, extra_desc->extra.scope_node,
3649ad19ac4SBob Moore extra_desc->extra.aml_length,
3659ad19ac4SBob Moore extra_desc->extra.aml_start);
366da4d8b28SLin Ming if (ACPI_FAILURE(status)) {
367da4d8b28SLin Ming return_ACPI_STATUS(status);
368da4d8b28SLin Ming }
369da4d8b28SLin Ming
370f654c0feSLin Ming status = acpi_ut_add_address_range(obj_desc->region.space_id,
371da4d8b28SLin Ming obj_desc->region.address,
372f654c0feSLin Ming obj_desc->region.length, node);
3739ad19ac4SBob Moore return_ACPI_STATUS(status);
3749ad19ac4SBob Moore }
375