Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: dsargs - Support for execution of dynamic arguments for static
0005  *                       objects (regions, fields, buffer fields, etc.)
0006  *
0007  * Copyright (C) 2000 - 2022, Intel Corp.
0008  *
0009  *****************************************************************************/
0010 
0011 #include <acpi/acpi.h>
0012 #include "accommon.h"
0013 #include "acparser.h"
0014 #include "amlcode.h"
0015 #include "acdispat.h"
0016 #include "acnamesp.h"
0017 
0018 #define _COMPONENT          ACPI_DISPATCHER
0019 ACPI_MODULE_NAME("dsargs")
0020 
0021 /* Local prototypes */
0022 static acpi_status
0023 acpi_ds_execute_arguments(struct acpi_namespace_node *node,
0024               struct acpi_namespace_node *scope_node,
0025               u32 aml_length, u8 *aml_start);
0026 
0027 /*******************************************************************************
0028  *
0029  * FUNCTION:    acpi_ds_execute_arguments
0030  *
0031  * PARAMETERS:  node                - Object NS node
0032  *              scope_node          - Parent NS node
0033  *              aml_length          - Length of executable AML
0034  *              aml_start           - Pointer to the AML
0035  *
0036  * RETURN:      Status.
0037  *
0038  * DESCRIPTION: Late (deferred) execution of region or field arguments
0039  *
0040  ******************************************************************************/
0041 
0042 static acpi_status
0043 acpi_ds_execute_arguments(struct acpi_namespace_node *node,
0044               struct acpi_namespace_node *scope_node,
0045               u32 aml_length, u8 *aml_start)
0046 {
0047     acpi_status status;
0048     union acpi_parse_object *op;
0049     struct acpi_walk_state *walk_state;
0050 
0051     ACPI_FUNCTION_TRACE_PTR(ds_execute_arguments, aml_start);
0052 
0053     /* Allocate a new parser op to be the root of the parsed tree */
0054 
0055     op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
0056     if (!op) {
0057         return_ACPI_STATUS(AE_NO_MEMORY);
0058     }
0059 
0060     /* Save the Node for use in acpi_ps_parse_aml */
0061 
0062     op->common.node = scope_node;
0063 
0064     /* Create and initialize a new parser state */
0065 
0066     walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
0067     if (!walk_state) {
0068         status = AE_NO_MEMORY;
0069         goto cleanup;
0070     }
0071 
0072     status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
0073                        aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
0074     if (ACPI_FAILURE(status)) {
0075         acpi_ds_delete_walk_state(walk_state);
0076         goto cleanup;
0077     }
0078 
0079     /* Mark this parse as a deferred opcode */
0080 
0081     walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
0082     walk_state->deferred_node = node;
0083 
0084     /* Pass1: Parse the entire declaration */
0085 
0086     status = acpi_ps_parse_aml(walk_state);
0087     if (ACPI_FAILURE(status)) {
0088         goto cleanup;
0089     }
0090 
0091     /* Get and init the Op created above */
0092 
0093     op->common.node = node;
0094     acpi_ps_delete_parse_tree(op);
0095 
0096     /* Evaluate the deferred arguments */
0097 
0098     op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
0099     if (!op) {
0100         return_ACPI_STATUS(AE_NO_MEMORY);
0101     }
0102 
0103     op->common.node = scope_node;
0104 
0105     /* Create and initialize a new parser state */
0106 
0107     walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
0108     if (!walk_state) {
0109         status = AE_NO_MEMORY;
0110         goto cleanup;
0111     }
0112 
0113     /* Execute the opcode and arguments */
0114 
0115     status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
0116                        aml_length, NULL, ACPI_IMODE_EXECUTE);
0117     if (ACPI_FAILURE(status)) {
0118         acpi_ds_delete_walk_state(walk_state);
0119         goto cleanup;
0120     }
0121 
0122     /* Mark this execution as a deferred opcode */
0123 
0124     walk_state->deferred_node = node;
0125     status = acpi_ps_parse_aml(walk_state);
0126 
0127 cleanup:
0128     acpi_ps_delete_parse_tree(op);
0129     return_ACPI_STATUS(status);
0130 }
0131 
0132 /*******************************************************************************
0133  *
0134  * FUNCTION:    acpi_ds_get_buffer_field_arguments
0135  *
0136  * PARAMETERS:  obj_desc        - A valid buffer_field object
0137  *
0138  * RETURN:      Status.
0139  *
0140  * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
0141  *              evaluation of these field attributes.
0142  *
0143  ******************************************************************************/
0144 
0145 acpi_status
0146 acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
0147 {
0148     union acpi_operand_object *extra_desc;
0149     struct acpi_namespace_node *node;
0150     acpi_status status;
0151 
0152     ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
0153 
0154     if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
0155         return_ACPI_STATUS(AE_OK);
0156     }
0157 
0158     /* Get the AML pointer (method object) and buffer_field node */
0159 
0160     extra_desc = acpi_ns_get_secondary_object(obj_desc);
0161     node = obj_desc->buffer_field.node;
0162 
0163     ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
0164             (ACPI_TYPE_BUFFER_FIELD, node, NULL));
0165 
0166     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
0167               acpi_ut_get_node_name(node)));
0168 
0169     /* Execute the AML code for the term_arg arguments */
0170 
0171     status = acpi_ds_execute_arguments(node, node->parent,
0172                        extra_desc->extra.aml_length,
0173                        extra_desc->extra.aml_start);
0174     return_ACPI_STATUS(status);
0175 }
0176 
0177 /*******************************************************************************
0178  *
0179  * FUNCTION:    acpi_ds_get_bank_field_arguments
0180  *
0181  * PARAMETERS:  obj_desc        - A valid bank_field object
0182  *
0183  * RETURN:      Status.
0184  *
0185  * DESCRIPTION: Get bank_field bank_value. This implements the late
0186  *              evaluation of these field attributes.
0187  *
0188  ******************************************************************************/
0189 
0190 acpi_status
0191 acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
0192 {
0193     union acpi_operand_object *extra_desc;
0194     struct acpi_namespace_node *node;
0195     acpi_status status;
0196 
0197     ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
0198 
0199     if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
0200         return_ACPI_STATUS(AE_OK);
0201     }
0202 
0203     /* Get the AML pointer (method object) and bank_field node */
0204 
0205     extra_desc = acpi_ns_get_secondary_object(obj_desc);
0206     node = obj_desc->bank_field.node;
0207 
0208     ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
0209             (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
0210 
0211     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
0212               acpi_ut_get_node_name(node)));
0213 
0214     /* Execute the AML code for the term_arg arguments */
0215 
0216     status = acpi_ds_execute_arguments(node, node->parent,
0217                        extra_desc->extra.aml_length,
0218                        extra_desc->extra.aml_start);
0219     if (ACPI_FAILURE(status)) {
0220         return_ACPI_STATUS(status);
0221     }
0222 
0223     status = acpi_ut_add_address_range(obj_desc->region.space_id,
0224                        obj_desc->region.address,
0225                        obj_desc->region.length, node);
0226     return_ACPI_STATUS(status);
0227 }
0228 
0229 /*******************************************************************************
0230  *
0231  * FUNCTION:    acpi_ds_get_buffer_arguments
0232  *
0233  * PARAMETERS:  obj_desc        - A valid Buffer object
0234  *
0235  * RETURN:      Status.
0236  *
0237  * DESCRIPTION: Get Buffer length and initializer byte list. This implements
0238  *              the late evaluation of these attributes.
0239  *
0240  ******************************************************************************/
0241 
0242 acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
0243 {
0244     struct acpi_namespace_node *node;
0245     acpi_status status;
0246 
0247     ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
0248 
0249     if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
0250         return_ACPI_STATUS(AE_OK);
0251     }
0252 
0253     /* Get the Buffer node */
0254 
0255     node = obj_desc->buffer.node;
0256     if (!node) {
0257         ACPI_ERROR((AE_INFO,
0258                 "No pointer back to namespace node in buffer object %p",
0259                 obj_desc));
0260         return_ACPI_STATUS(AE_AML_INTERNAL);
0261     }
0262 
0263     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
0264 
0265     /* Execute the AML code for the term_arg arguments */
0266 
0267     status = acpi_ds_execute_arguments(node, node,
0268                        obj_desc->buffer.aml_length,
0269                        obj_desc->buffer.aml_start);
0270     return_ACPI_STATUS(status);
0271 }
0272 
0273 /*******************************************************************************
0274  *
0275  * FUNCTION:    acpi_ds_get_package_arguments
0276  *
0277  * PARAMETERS:  obj_desc        - A valid Package object
0278  *
0279  * RETURN:      Status.
0280  *
0281  * DESCRIPTION: Get Package length and initializer byte list. This implements
0282  *              the late evaluation of these attributes.
0283  *
0284  ******************************************************************************/
0285 
0286 acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
0287 {
0288     struct acpi_namespace_node *node;
0289     acpi_status status;
0290 
0291     ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
0292 
0293     if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
0294         return_ACPI_STATUS(AE_OK);
0295     }
0296 
0297     /* Get the Package node */
0298 
0299     node = obj_desc->package.node;
0300     if (!node) {
0301         ACPI_ERROR((AE_INFO,
0302                 "No pointer back to namespace node in package %p",
0303                 obj_desc));
0304         return_ACPI_STATUS(AE_AML_INTERNAL);
0305     }
0306 
0307     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Argument Init, AML Ptr: %p\n",
0308               obj_desc->package.aml_start));
0309 
0310     /* Execute the AML code for the term_arg arguments */
0311 
0312     status = acpi_ds_execute_arguments(node, node,
0313                        obj_desc->package.aml_length,
0314                        obj_desc->package.aml_start);
0315 
0316     return_ACPI_STATUS(status);
0317 }
0318 
0319 /*******************************************************************************
0320  *
0321  * FUNCTION:    acpi_ds_get_region_arguments
0322  *
0323  * PARAMETERS:  obj_desc        - A valid region object
0324  *
0325  * RETURN:      Status.
0326  *
0327  * DESCRIPTION: Get region address and length. This implements the late
0328  *              evaluation of these region attributes.
0329  *
0330  ******************************************************************************/
0331 
0332 acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
0333 {
0334     struct acpi_namespace_node *node;
0335     acpi_status status;
0336     union acpi_operand_object *extra_desc;
0337 
0338     ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
0339 
0340     if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
0341         return_ACPI_STATUS(AE_OK);
0342     }
0343 
0344     extra_desc = acpi_ns_get_secondary_object(obj_desc);
0345     if (!extra_desc) {
0346         return_ACPI_STATUS(AE_NOT_EXIST);
0347     }
0348 
0349     /* Get the Region node */
0350 
0351     node = obj_desc->region.node;
0352 
0353     ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
0354             (ACPI_TYPE_REGION, node, NULL));
0355 
0356     ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0357               "[%4.4s] OpRegion Arg Init at AML %p\n",
0358               acpi_ut_get_node_name(node),
0359               extra_desc->extra.aml_start));
0360 
0361     /* Execute the argument AML */
0362 
0363     status = acpi_ds_execute_arguments(node, extra_desc->extra.scope_node,
0364                        extra_desc->extra.aml_length,
0365                        extra_desc->extra.aml_start);
0366     if (ACPI_FAILURE(status)) {
0367         return_ACPI_STATUS(status);
0368     }
0369 
0370     status = acpi_ut_add_address_range(obj_desc->region.space_id,
0371                        obj_desc->region.address,
0372                        obj_desc->region.length, node);
0373     return_ACPI_STATUS(status);
0374 }