cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsargs.c (10408B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: dsargs - Support for execution of dynamic arguments for static
      5 *                       objects (regions, fields, buffer fields, etc.)
      6 *
      7 * Copyright (C) 2000 - 2022, 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_DISPATCHER
     19ACPI_MODULE_NAME("dsargs")
     20
     21/* Local prototypes */
     22static acpi_status
     23acpi_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_arguments
     30 *
     31 * PARAMETERS:  node                - Object NS node
     32 *              scope_node          - Parent NS node
     33 *              aml_length          - Length of executable AML
     34 *              aml_start           - Pointer to the AML
     35 *
     36 * RETURN:      Status.
     37 *
     38 * DESCRIPTION: Late (deferred) execution of region or field arguments
     39 *
     40 ******************************************************************************/
     41
     42static acpi_status
     43acpi_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_arguments
    135 *
    136 * PARAMETERS:  obj_desc        - A valid buffer_field object
    137 *
    138 * RETURN:      Status.
    139 *
    140 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
    141 *              evaluation of these field attributes.
    142 *
    143 ******************************************************************************/
    144
    145acpi_status
    146acpi_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_pathname
    164			(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_arguments
    180 *
    181 * PARAMETERS:  obj_desc        - A valid bank_field object
    182 *
    183 * RETURN:      Status.
    184 *
    185 * DESCRIPTION: Get bank_field bank_value. This implements the late
    186 *              evaluation of these field attributes.
    187 *
    188 ******************************************************************************/
    189
    190acpi_status
    191acpi_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_pathname
    209			(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_arguments
    232 *
    233 * PARAMETERS:  obj_desc        - A valid Buffer object
    234 *
    235 * RETURN:      Status.
    236 *
    237 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
    238 *              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_arguments
    276 *
    277 * PARAMETERS:  obj_desc        - A valid Package object
    278 *
    279 * RETURN:      Status.
    280 *
    281 * DESCRIPTION: Get Package length and initializer byte list. This implements
    282 *              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_arguments
    322 *
    323 * PARAMETERS:  obj_desc        - A valid region object
    324 *
    325 * RETURN:      Status.
    326 *
    327 * DESCRIPTION: Get region address and length. This implements the late
    328 *              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_pathname
    354			(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}