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

dswload.c (16315B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: dswload - Dispatcher first pass namespace load callbacks
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acparser.h"
     13#include "amlcode.h"
     14#include "acdispat.h"
     15#include "acinterp.h"
     16#include "acnamesp.h"
     17#ifdef ACPI_ASL_COMPILER
     18#include "acdisasm.h"
     19#endif
     20
     21#define _COMPONENT          ACPI_DISPATCHER
     22ACPI_MODULE_NAME("dswload")
     23
     24/*******************************************************************************
     25 *
     26 * FUNCTION:    acpi_ds_init_callbacks
     27 *
     28 * PARAMETERS:  walk_state      - Current state of the parse tree walk
     29 *              pass_number     - 1, 2, or 3
     30 *
     31 * RETURN:      Status
     32 *
     33 * DESCRIPTION: Init walk state callbacks
     34 *
     35 ******************************************************************************/
     36acpi_status
     37acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
     38{
     39
     40	switch (pass_number) {
     41	case 0:
     42
     43		/* Parse only - caller will setup callbacks */
     44
     45		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
     46		    ACPI_PARSE_DELETE_TREE | ACPI_PARSE_DISASSEMBLE;
     47		walk_state->descending_callback = NULL;
     48		walk_state->ascending_callback = NULL;
     49		break;
     50
     51	case 1:
     52
     53		/* Load pass 1 */
     54
     55		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
     56		    ACPI_PARSE_DELETE_TREE;
     57		walk_state->descending_callback = acpi_ds_load1_begin_op;
     58		walk_state->ascending_callback = acpi_ds_load1_end_op;
     59		break;
     60
     61	case 2:
     62
     63		/* Load pass 2 */
     64
     65		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
     66		    ACPI_PARSE_DELETE_TREE;
     67		walk_state->descending_callback = acpi_ds_load2_begin_op;
     68		walk_state->ascending_callback = acpi_ds_load2_end_op;
     69		break;
     70
     71	case 3:
     72
     73		/* Execution pass */
     74
     75		walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
     76		    ACPI_PARSE_DELETE_TREE;
     77		walk_state->descending_callback = acpi_ds_exec_begin_op;
     78		walk_state->ascending_callback = acpi_ds_exec_end_op;
     79		break;
     80
     81	default:
     82
     83		return (AE_BAD_PARAMETER);
     84	}
     85
     86	return (AE_OK);
     87}
     88
     89/*******************************************************************************
     90 *
     91 * FUNCTION:    acpi_ds_load1_begin_op
     92 *
     93 * PARAMETERS:  walk_state      - Current state of the parse tree walk
     94 *              out_op          - Where to return op if a new one is created
     95 *
     96 * RETURN:      Status
     97 *
     98 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
     99 *
    100 ******************************************************************************/
    101
    102acpi_status
    103acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
    104		       union acpi_parse_object **out_op)
    105{
    106	union acpi_parse_object *op;
    107	struct acpi_namespace_node *node;
    108	acpi_status status;
    109	acpi_object_type object_type;
    110	char *path;
    111	u32 flags;
    112
    113	ACPI_FUNCTION_TRACE_PTR(ds_load1_begin_op, walk_state->op);
    114
    115	op = walk_state->op;
    116	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
    117			  walk_state));
    118
    119	/* We are only interested in opcodes that have an associated name */
    120
    121	if (op) {
    122		if (!(walk_state->op_info->flags & AML_NAMED)) {
    123			*out_op = op;
    124			return_ACPI_STATUS(AE_OK);
    125		}
    126
    127		/* Check if this object has already been installed in the namespace */
    128
    129		if (op->common.node) {
    130			*out_op = op;
    131			return_ACPI_STATUS(AE_OK);
    132		}
    133	}
    134
    135	path = acpi_ps_get_next_namestring(&walk_state->parser_state);
    136
    137	/* Map the raw opcode into an internal object type */
    138
    139	object_type = walk_state->op_info->object_type;
    140
    141	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    142			  "State=%p Op=%p [%s]\n", walk_state, op,
    143			  acpi_ut_get_type_name(object_type)));
    144
    145	switch (walk_state->opcode) {
    146	case AML_SCOPE_OP:
    147		/*
    148		 * The target name of the Scope() operator must exist at this point so
    149		 * that we can actually open the scope to enter new names underneath it.
    150		 * Allow search-to-root for single namesegs.
    151		 */
    152		status =
    153		    acpi_ns_lookup(walk_state->scope_info, path, object_type,
    154				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
    155				   walk_state, &(node));
    156#ifdef ACPI_ASL_COMPILER
    157		if (status == AE_NOT_FOUND) {
    158			/*
    159			 * Table disassembly:
    160			 * Target of Scope() not found. Generate an External for it, and
    161			 * insert the name into the namespace.
    162			 */
    163			acpi_dm_add_op_to_external_list(op, path,
    164							ACPI_TYPE_DEVICE, 0, 0);
    165			status =
    166			    acpi_ns_lookup(walk_state->scope_info, path,
    167					   object_type, ACPI_IMODE_LOAD_PASS1,
    168					   ACPI_NS_SEARCH_PARENT, walk_state,
    169					   &node);
    170		}
    171#endif
    172		if (ACPI_FAILURE(status)) {
    173			ACPI_ERROR_NAMESPACE(walk_state->scope_info, path,
    174					     status);
    175			return_ACPI_STATUS(status);
    176		}
    177
    178		/*
    179		 * Check to make sure that the target is
    180		 * one of the opcodes that actually opens a scope
    181		 */
    182		switch (node->type) {
    183		case ACPI_TYPE_ANY:
    184		case ACPI_TYPE_LOCAL_SCOPE:	/* Scope  */
    185		case ACPI_TYPE_DEVICE:
    186		case ACPI_TYPE_POWER:
    187		case ACPI_TYPE_PROCESSOR:
    188		case ACPI_TYPE_THERMAL:
    189
    190			/* These are acceptable types */
    191			break;
    192
    193		case ACPI_TYPE_INTEGER:
    194		case ACPI_TYPE_STRING:
    195		case ACPI_TYPE_BUFFER:
    196			/*
    197			 * These types we will allow, but we will change the type.
    198			 * This enables some existing code of the form:
    199			 *
    200			 *  Name (DEB, 0)
    201			 *  Scope (DEB) { ... }
    202			 *
    203			 * Note: silently change the type here. On the second pass,
    204			 * we will report a warning
    205			 */
    206			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    207					  "Type override - [%4.4s] had invalid type (%s) "
    208					  "for Scope operator, changed to type ANY\n",
    209					  acpi_ut_get_node_name(node),
    210					  acpi_ut_get_type_name(node->type)));
    211
    212			node->type = ACPI_TYPE_ANY;
    213			walk_state->scope_info->common.value = ACPI_TYPE_ANY;
    214			break;
    215
    216		case ACPI_TYPE_METHOD:
    217			/*
    218			 * Allow scope change to root during execution of module-level
    219			 * code. Root is typed METHOD during this time.
    220			 */
    221			if ((node == acpi_gbl_root_node) &&
    222			    (walk_state->
    223			     parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
    224				break;
    225			}
    226
    227			ACPI_FALLTHROUGH;
    228
    229		default:
    230
    231			/* All other types are an error */
    232
    233			ACPI_ERROR((AE_INFO,
    234				    "Invalid type (%s) for target of "
    235				    "Scope operator [%4.4s] (Cannot override)",
    236				    acpi_ut_get_type_name(node->type),
    237				    acpi_ut_get_node_name(node)));
    238
    239			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
    240		}
    241		break;
    242
    243	default:
    244		/*
    245		 * For all other named opcodes, we will enter the name into
    246		 * the namespace.
    247		 *
    248		 * Setup the search flags.
    249		 * Since we are entering a name into the namespace, we do not want to
    250		 * enable the search-to-root upsearch.
    251		 *
    252		 * There are only two conditions where it is acceptable that the name
    253		 * already exists:
    254		 *    1) the Scope() operator can reopen a scoping object that was
    255		 *       previously defined (Scope, Method, Device, etc.)
    256		 *    2) Whenever we are parsing a deferred opcode (op_region, Buffer,
    257		 *       buffer_field, or Package), the name of the object is already
    258		 *       in the namespace.
    259		 */
    260		if (walk_state->deferred_node) {
    261
    262			/* This name is already in the namespace, get the node */
    263
    264			node = walk_state->deferred_node;
    265			status = AE_OK;
    266			break;
    267		}
    268
    269		/*
    270		 * If we are executing a method, do not create any namespace objects
    271		 * during the load phase, only during execution.
    272		 */
    273		if (walk_state->method_node) {
    274			node = NULL;
    275			status = AE_OK;
    276			break;
    277		}
    278
    279		flags = ACPI_NS_NO_UPSEARCH;
    280		if ((walk_state->opcode != AML_SCOPE_OP) &&
    281		    (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
    282			if (walk_state->namespace_override) {
    283				flags |= ACPI_NS_OVERRIDE_IF_FOUND;
    284				ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    285						  "[%s] Override allowed\n",
    286						  acpi_ut_get_type_name
    287						  (object_type)));
    288			} else {
    289				flags |= ACPI_NS_ERROR_IF_FOUND;
    290				ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    291						  "[%s] Cannot already exist\n",
    292						  acpi_ut_get_type_name
    293						  (object_type)));
    294			}
    295		} else {
    296			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    297					  "[%s] Both Find or Create allowed\n",
    298					  acpi_ut_get_type_name(object_type)));
    299		}
    300
    301		/*
    302		 * Enter the named type into the internal namespace. We enter the name
    303		 * as we go downward in the parse tree. Any necessary subobjects that
    304		 * involve arguments to the opcode must be created as we go back up the
    305		 * parse tree later.
    306		 */
    307		status =
    308		    acpi_ns_lookup(walk_state->scope_info, path, object_type,
    309				   ACPI_IMODE_LOAD_PASS1, flags, walk_state,
    310				   &node);
    311		if (ACPI_FAILURE(status)) {
    312			if (status == AE_ALREADY_EXISTS) {
    313
    314				/* The name already exists in this scope */
    315
    316				if (node->flags & ANOBJ_IS_EXTERNAL) {
    317					/*
    318					 * Allow one create on an object or segment that was
    319					 * previously declared External
    320					 */
    321					node->flags &= ~ANOBJ_IS_EXTERNAL;
    322					node->type = (u8) object_type;
    323
    324					/* Just retyped a node, probably will need to open a scope */
    325
    326					if (acpi_ns_opens_scope(object_type)) {
    327						status =
    328						    acpi_ds_scope_stack_push
    329						    (node, object_type,
    330						     walk_state);
    331						if (ACPI_FAILURE(status)) {
    332							return_ACPI_STATUS
    333							    (status);
    334						}
    335					}
    336
    337					status = AE_OK;
    338				}
    339			}
    340
    341			if (ACPI_FAILURE(status)) {
    342				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    343						     path, status);
    344				return_ACPI_STATUS(status);
    345			}
    346		}
    347		break;
    348	}
    349
    350	/* Common exit */
    351
    352	if (!op) {
    353
    354		/* Create a new op */
    355
    356		op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml);
    357		if (!op) {
    358			return_ACPI_STATUS(AE_NO_MEMORY);
    359		}
    360	}
    361
    362	/* Initialize the op */
    363
    364#ifdef ACPI_CONSTANT_EVAL_ONLY
    365	op->named.path = path;
    366#endif
    367
    368	if (node) {
    369		/*
    370		 * Put the Node in the "op" object that the parser uses, so we
    371		 * can get it again quickly when this scope is closed
    372		 */
    373		op->common.node = node;
    374		op->named.name = node->name.integer;
    375	}
    376
    377	acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
    378			   op);
    379	*out_op = op;
    380	return_ACPI_STATUS(status);
    381}
    382
    383/*******************************************************************************
    384 *
    385 * FUNCTION:    acpi_ds_load1_end_op
    386 *
    387 * PARAMETERS:  walk_state      - Current state of the parse tree walk
    388 *
    389 * RETURN:      Status
    390 *
    391 * DESCRIPTION: Ascending callback used during the loading of the namespace,
    392 *              both control methods and everything else.
    393 *
    394 ******************************************************************************/
    395
    396acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
    397{
    398	union acpi_parse_object *op;
    399	acpi_object_type object_type;
    400	acpi_status status = AE_OK;
    401#ifdef ACPI_ASL_COMPILER
    402	u8 param_count;
    403#endif
    404
    405	ACPI_FUNCTION_TRACE(ds_load1_end_op);
    406
    407	op = walk_state->op;
    408	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
    409			  walk_state));
    410
    411	/*
    412	 * Disassembler: handle create field operators here.
    413	 *
    414	 * create_buffer_field is a deferred op that is typically processed in load
    415	 * pass 2. However, disassembly of control method contents walk the parse
    416	 * tree with ACPI_PARSE_LOAD_PASS1 and AML_CREATE operators are processed
    417	 * in a later walk. This is a problem when there is a control method that
    418	 * has the same name as the AML_CREATE object. In this case, any use of the
    419	 * name segment will be detected as a method call rather than a reference
    420	 * to a buffer field.
    421	 *
    422	 * This earlier creation during disassembly solves this issue by inserting
    423	 * the named object in the ACPI namespace so that references to this name
    424	 * would be a name string rather than a method call.
    425	 */
    426	if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) &&
    427	    (walk_state->op_info->flags & AML_CREATE)) {
    428		status = acpi_ds_create_buffer_field(op, walk_state);
    429		return_ACPI_STATUS(status);
    430	}
    431
    432	/* We are only interested in opcodes that have an associated name */
    433
    434	if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
    435		return_ACPI_STATUS(AE_OK);
    436	}
    437
    438	/* Get the object type to determine if we should pop the scope */
    439
    440	object_type = walk_state->op_info->object_type;
    441
    442	if (walk_state->op_info->flags & AML_FIELD) {
    443		/*
    444		 * If we are executing a method, do not create any namespace objects
    445		 * during the load phase, only during execution.
    446		 */
    447		if (!walk_state->method_node) {
    448			if (walk_state->opcode == AML_FIELD_OP ||
    449			    walk_state->opcode == AML_BANK_FIELD_OP ||
    450			    walk_state->opcode == AML_INDEX_FIELD_OP) {
    451				status =
    452				    acpi_ds_init_field_objects(op, walk_state);
    453			}
    454		}
    455		return_ACPI_STATUS(status);
    456	}
    457
    458	/*
    459	 * If we are executing a method, do not create any namespace objects
    460	 * during the load phase, only during execution.
    461	 */
    462	if (!walk_state->method_node) {
    463		if (op->common.aml_opcode == AML_REGION_OP) {
    464			status =
    465			    acpi_ex_create_region(op->named.data,
    466						  op->named.length,
    467						  (acpi_adr_space_type)
    468						  ((op->common.value.arg)->
    469						   common.value.integer),
    470						  walk_state);
    471			if (ACPI_FAILURE(status)) {
    472				return_ACPI_STATUS(status);
    473			}
    474		} else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
    475			status =
    476			    acpi_ex_create_region(op->named.data,
    477						  op->named.length,
    478						  ACPI_ADR_SPACE_DATA_TABLE,
    479						  walk_state);
    480			if (ACPI_FAILURE(status)) {
    481				return_ACPI_STATUS(status);
    482			}
    483		}
    484	}
    485
    486	if (op->common.aml_opcode == AML_NAME_OP) {
    487
    488		/* For Name opcode, get the object type from the argument */
    489
    490		if (op->common.value.arg) {
    491			object_type = (acpi_ps_get_opcode_info((op->common.
    492								value.arg)->
    493							       common.
    494							       aml_opcode))->
    495			    object_type;
    496
    497			/* Set node type if we have a namespace node */
    498
    499			if (op->common.node) {
    500				op->common.node->type = (u8) object_type;
    501			}
    502		}
    503	}
    504#ifdef ACPI_ASL_COMPILER
    505	/*
    506	 * For external opcode, get the object type from the argument and
    507	 * get the parameter count from the argument's next.
    508	 */
    509	if (acpi_gbl_disasm_flag &&
    510	    op->common.node && op->common.aml_opcode == AML_EXTERNAL_OP) {
    511		/*
    512		 * Note, if this external is not a method
    513		 * Op->Common.Value.Arg->Common.Next->Common.Value.Integer == 0
    514		 * Therefore, param_count will be 0.
    515		 */
    516		param_count =
    517		    (u8)op->common.value.arg->common.next->common.value.integer;
    518		object_type = (u8)op->common.value.arg->common.value.integer;
    519		op->common.node->flags |= ANOBJ_IS_EXTERNAL;
    520		op->common.node->type = (u8)object_type;
    521
    522		acpi_dm_create_subobject_for_external((u8)object_type,
    523						      &op->common.node,
    524						      param_count);
    525
    526		/*
    527		 * Add the external to the external list because we may be
    528		 * emitting code based off of the items within the external list.
    529		 */
    530		acpi_dm_add_op_to_external_list(op, op->named.path,
    531						(u8)object_type, param_count,
    532						ACPI_EXT_ORIGIN_FROM_OPCODE |
    533						ACPI_EXT_RESOLVED_REFERENCE);
    534	}
    535#endif
    536
    537	/*
    538	 * If we are executing a method, do not create any namespace objects
    539	 * during the load phase, only during execution.
    540	 */
    541	if (!walk_state->method_node) {
    542		if (op->common.aml_opcode == AML_METHOD_OP) {
    543			/*
    544			 * method_op pkg_length name_string method_flags term_list
    545			 *
    546			 * Note: We must create the method node/object pair as soon as we
    547			 * see the method declaration. This allows later pass1 parsing
    548			 * of invocations of the method (need to know the number of
    549			 * arguments.)
    550			 */
    551			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    552					  "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
    553					  walk_state, op, op->named.node));
    554
    555			if (!acpi_ns_get_attached_object(op->named.node)) {
    556				walk_state->operands[0] =
    557				    ACPI_CAST_PTR(void, op->named.node);
    558				walk_state->num_operands = 1;
    559
    560				status =
    561				    acpi_ds_create_operands(walk_state,
    562							    op->common.value.
    563							    arg);
    564				if (ACPI_SUCCESS(status)) {
    565					status =
    566					    acpi_ex_create_method(op->named.
    567								  data,
    568								  op->named.
    569								  length,
    570								  walk_state);
    571				}
    572
    573				walk_state->operands[0] = NULL;
    574				walk_state->num_operands = 0;
    575
    576				if (ACPI_FAILURE(status)) {
    577					return_ACPI_STATUS(status);
    578				}
    579			}
    580		}
    581	}
    582
    583	/* Pop the scope stack (only if loading a table) */
    584
    585	if (!walk_state->method_node &&
    586	    op->common.aml_opcode != AML_EXTERNAL_OP &&
    587	    acpi_ns_opens_scope(object_type)) {
    588		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    589				  "(%s): Popping scope for Op %p\n",
    590				  acpi_ut_get_type_name(object_type), op));
    591
    592		status = acpi_ds_scope_stack_pop(walk_state);
    593	}
    594
    595	return_ACPI_STATUS(status);
    596}