xref: /openbmc/linux/drivers/acpi/acpica/dswload2.c (revision 612c2932)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
29ad19ac4SBob Moore /******************************************************************************
39ad19ac4SBob Moore  *
49ad19ac4SBob Moore  * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
59ad19ac4SBob Moore  *
6*612c2932SBob Moore  * Copyright (C) 2000 - 2023, Intel Corp.
79ad19ac4SBob Moore  *
895857638SErik Schmauss  *****************************************************************************/
99ad19ac4SBob Moore 
109ad19ac4SBob Moore #include <acpi/acpi.h>
119ad19ac4SBob Moore #include "accommon.h"
129ad19ac4SBob Moore #include "acparser.h"
139ad19ac4SBob Moore #include "amlcode.h"
149ad19ac4SBob Moore #include "acdispat.h"
159ad19ac4SBob Moore #include "acinterp.h"
169ad19ac4SBob Moore #include "acnamesp.h"
179ad19ac4SBob Moore #include "acevents.h"
189a1ae804SBob Moore #ifdef ACPI_EXEC_APP
199a1ae804SBob Moore #include "aecommon.h"
209a1ae804SBob Moore #endif
219ad19ac4SBob Moore 
229ad19ac4SBob Moore #define _COMPONENT          ACPI_DISPATCHER
239ad19ac4SBob Moore ACPI_MODULE_NAME("dswload2")
249ad19ac4SBob Moore 
259ad19ac4SBob Moore /*******************************************************************************
269ad19ac4SBob Moore  *
279ad19ac4SBob Moore  * FUNCTION:    acpi_ds_load2_begin_op
289ad19ac4SBob Moore  *
299ad19ac4SBob Moore  * PARAMETERS:  walk_state      - Current state of the parse tree walk
30c163f90cSErik Schmauss  *              out_op          - Where to return op if a new one is created
319ad19ac4SBob Moore  *
329ad19ac4SBob Moore  * RETURN:      Status
339ad19ac4SBob Moore  *
349ad19ac4SBob Moore  * DESCRIPTION: Descending callback used during the loading of ACPI tables.
359ad19ac4SBob Moore  *
369ad19ac4SBob Moore  ******************************************************************************/
379ad19ac4SBob Moore acpi_status
acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,union acpi_parse_object ** out_op)389ad19ac4SBob Moore acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
399ad19ac4SBob Moore 		       union acpi_parse_object **out_op)
409ad19ac4SBob Moore {
419ad19ac4SBob Moore 	union acpi_parse_object *op;
429ad19ac4SBob Moore 	struct acpi_namespace_node *node;
439ad19ac4SBob Moore 	acpi_status status;
449ad19ac4SBob Moore 	acpi_object_type object_type;
459ad19ac4SBob Moore 	char *buffer_ptr;
469ad19ac4SBob Moore 	u32 flags;
479ad19ac4SBob Moore 
489ad19ac4SBob Moore 	ACPI_FUNCTION_TRACE(ds_load2_begin_op);
499ad19ac4SBob Moore 
509ad19ac4SBob Moore 	op = walk_state->op;
519ad19ac4SBob Moore 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
529ad19ac4SBob Moore 			  walk_state));
539ad19ac4SBob Moore 
549ad19ac4SBob Moore 	if (op) {
559ad19ac4SBob Moore 		if ((walk_state->control_state) &&
569ad19ac4SBob Moore 		    (walk_state->control_state->common.state ==
579ad19ac4SBob Moore 		     ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
589ad19ac4SBob Moore 
599ad19ac4SBob Moore 			/* We are executing a while loop outside of a method */
609ad19ac4SBob Moore 
619ad19ac4SBob Moore 			status = acpi_ds_exec_begin_op(walk_state, out_op);
629ad19ac4SBob Moore 			return_ACPI_STATUS(status);
639ad19ac4SBob Moore 		}
649ad19ac4SBob Moore 
659ad19ac4SBob Moore 		/* We only care about Namespace opcodes here */
669ad19ac4SBob Moore 
679ad19ac4SBob Moore 		if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
689ad19ac4SBob Moore 		     (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
699ad19ac4SBob Moore 		    (!(walk_state->op_info->flags & AML_NAMED))) {
709ad19ac4SBob Moore 			return_ACPI_STATUS(AE_OK);
719ad19ac4SBob Moore 		}
729ad19ac4SBob Moore 
739ad19ac4SBob Moore 		/* Get the name we are going to enter or lookup in the namespace */
749ad19ac4SBob Moore 
759ad19ac4SBob Moore 		if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
769ad19ac4SBob Moore 
779ad19ac4SBob Moore 			/* For Namepath op, get the path string */
789ad19ac4SBob Moore 
799ad19ac4SBob Moore 			buffer_ptr = op->common.value.string;
809ad19ac4SBob Moore 			if (!buffer_ptr) {
819ad19ac4SBob Moore 
829ad19ac4SBob Moore 				/* No name, just exit */
839ad19ac4SBob Moore 
849ad19ac4SBob Moore 				return_ACPI_STATUS(AE_OK);
859ad19ac4SBob Moore 			}
869ad19ac4SBob Moore 		} else {
879ad19ac4SBob Moore 			/* Get name from the op */
889ad19ac4SBob Moore 
899ad19ac4SBob Moore 			buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
909ad19ac4SBob Moore 		}
919ad19ac4SBob Moore 	} else {
929ad19ac4SBob Moore 		/* Get the namestring from the raw AML */
939ad19ac4SBob Moore 
949ad19ac4SBob Moore 		buffer_ptr =
959ad19ac4SBob Moore 		    acpi_ps_get_next_namestring(&walk_state->parser_state);
969ad19ac4SBob Moore 	}
979ad19ac4SBob Moore 
989ad19ac4SBob Moore 	/* Map the opcode into an internal object type */
999ad19ac4SBob Moore 
1009ad19ac4SBob Moore 	object_type = walk_state->op_info->object_type;
1019ad19ac4SBob Moore 
1029ad19ac4SBob Moore 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1039ad19ac4SBob Moore 			  "State=%p Op=%p Type=%X\n", walk_state, op,
1049ad19ac4SBob Moore 			  object_type));
1059ad19ac4SBob Moore 
1069ad19ac4SBob Moore 	switch (walk_state->opcode) {
1079ad19ac4SBob Moore 	case AML_FIELD_OP:
1089ad19ac4SBob Moore 	case AML_BANK_FIELD_OP:
1099ad19ac4SBob Moore 	case AML_INDEX_FIELD_OP:
1109ad19ac4SBob Moore 
1119ad19ac4SBob Moore 		node = NULL;
1129ad19ac4SBob Moore 		status = AE_OK;
1139ad19ac4SBob Moore 		break;
1149ad19ac4SBob Moore 
1159ad19ac4SBob Moore 	case AML_INT_NAMEPATH_OP:
1169ad19ac4SBob Moore 		/*
1179ad19ac4SBob Moore 		 * The name_path is an object reference to an existing object.
1189ad19ac4SBob Moore 		 * Don't enter the name into the namespace, but look it up
1199ad19ac4SBob Moore 		 * for use later.
1209ad19ac4SBob Moore 		 */
1219ad19ac4SBob Moore 		status =
1229ad19ac4SBob Moore 		    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
1239ad19ac4SBob Moore 				   object_type, ACPI_IMODE_EXECUTE,
1249ad19ac4SBob Moore 				   ACPI_NS_SEARCH_PARENT, walk_state, &(node));
1259ad19ac4SBob Moore 		break;
1269ad19ac4SBob Moore 
1279ad19ac4SBob Moore 	case AML_SCOPE_OP:
1289ad19ac4SBob Moore 
1299ad19ac4SBob Moore 		/* Special case for Scope(\) -> refers to the Root node */
1309ad19ac4SBob Moore 
1319ad19ac4SBob Moore 		if (op && (op->named.node == acpi_gbl_root_node)) {
1329ad19ac4SBob Moore 			node = op->named.node;
1339ad19ac4SBob Moore 
1349ad19ac4SBob Moore 			status =
1359ad19ac4SBob Moore 			    acpi_ds_scope_stack_push(node, object_type,
1369ad19ac4SBob Moore 						     walk_state);
1379ad19ac4SBob Moore 			if (ACPI_FAILURE(status)) {
1389ad19ac4SBob Moore 				return_ACPI_STATUS(status);
1399ad19ac4SBob Moore 			}
1409ad19ac4SBob Moore 		} else {
1419ad19ac4SBob Moore 			/*
1429ad19ac4SBob Moore 			 * The Path is an object reference to an existing object.
1439ad19ac4SBob Moore 			 * Don't enter the name into the namespace, but look it up
1449ad19ac4SBob Moore 			 * for use later.
1459ad19ac4SBob Moore 			 */
1469ad19ac4SBob Moore 			status =
1479ad19ac4SBob Moore 			    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
1489ad19ac4SBob Moore 					   object_type, ACPI_IMODE_EXECUTE,
1499ad19ac4SBob Moore 					   ACPI_NS_SEARCH_PARENT, walk_state,
1509ad19ac4SBob Moore 					   &(node));
1519ad19ac4SBob Moore 			if (ACPI_FAILURE(status)) {
1529ad19ac4SBob Moore #ifdef ACPI_ASL_COMPILER
1539ad19ac4SBob Moore 				if (status == AE_NOT_FOUND) {
1549ad19ac4SBob Moore 					status = AE_OK;
1559ad19ac4SBob Moore 				} else {
15616ccf829SBob Moore 					ACPI_ERROR_NAMESPACE(walk_state->
15716ccf829SBob Moore 							     scope_info,
15816ccf829SBob Moore 							     buffer_ptr,
1599ad19ac4SBob Moore 							     status);
1609ad19ac4SBob Moore 				}
1619ad19ac4SBob Moore #else
16216ccf829SBob Moore 				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
16316ccf829SBob Moore 						     buffer_ptr, status);
1649ad19ac4SBob Moore #endif
1659ad19ac4SBob Moore 				return_ACPI_STATUS(status);
1669ad19ac4SBob Moore 			}
1679ad19ac4SBob Moore 		}
1689ad19ac4SBob Moore 
1699ad19ac4SBob Moore 		/*
1709ad19ac4SBob Moore 		 * We must check to make sure that the target is
1719ad19ac4SBob Moore 		 * one of the opcodes that actually opens a scope
1729ad19ac4SBob Moore 		 */
1739ad19ac4SBob Moore 		switch (node->type) {
1749ad19ac4SBob Moore 		case ACPI_TYPE_ANY:
1759ad19ac4SBob Moore 		case ACPI_TYPE_LOCAL_SCOPE:	/* Scope */
1769ad19ac4SBob Moore 		case ACPI_TYPE_DEVICE:
1779ad19ac4SBob Moore 		case ACPI_TYPE_POWER:
1789ad19ac4SBob Moore 		case ACPI_TYPE_PROCESSOR:
1799ad19ac4SBob Moore 		case ACPI_TYPE_THERMAL:
1809ad19ac4SBob Moore 
1819ad19ac4SBob Moore 			/* These are acceptable types */
1829ad19ac4SBob Moore 			break;
1839ad19ac4SBob Moore 
1849ad19ac4SBob Moore 		case ACPI_TYPE_INTEGER:
1859ad19ac4SBob Moore 		case ACPI_TYPE_STRING:
1869ad19ac4SBob Moore 		case ACPI_TYPE_BUFFER:
1879ad19ac4SBob Moore 
1889ad19ac4SBob Moore 			/*
1899ad19ac4SBob Moore 			 * These types we will allow, but we will change the type.
1909ad19ac4SBob Moore 			 * This enables some existing code of the form:
1919ad19ac4SBob Moore 			 *
1929ad19ac4SBob Moore 			 *  Name (DEB, 0)
1939ad19ac4SBob Moore 			 *  Scope (DEB) { ... }
1949ad19ac4SBob Moore 			 */
1959ad19ac4SBob Moore 			ACPI_WARNING((AE_INFO,
1969ad19ac4SBob Moore 				      "Type override - [%4.4s] had invalid type (%s) "
1975e30a96eSBob Moore 				      "for Scope operator, changed to type ANY",
1989ad19ac4SBob Moore 				      acpi_ut_get_node_name(node),
1999ad19ac4SBob Moore 				      acpi_ut_get_type_name(node->type)));
2009ad19ac4SBob Moore 
2019ad19ac4SBob Moore 			node->type = ACPI_TYPE_ANY;
2029ad19ac4SBob Moore 			walk_state->scope_info->common.value = ACPI_TYPE_ANY;
2039ad19ac4SBob Moore 			break;
2049ad19ac4SBob Moore 
20528f538b5SBob Moore 		case ACPI_TYPE_METHOD:
20628f538b5SBob Moore 
20728f538b5SBob Moore 			/*
20828f538b5SBob Moore 			 * Allow scope change to root during execution of module-level
20928f538b5SBob Moore 			 * code. Root is typed METHOD during this time.
21028f538b5SBob Moore 			 */
21128f538b5SBob Moore 			if ((node == acpi_gbl_root_node) &&
21228f538b5SBob Moore 			    (walk_state->
21328f538b5SBob Moore 			     parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
21428f538b5SBob Moore 				break;
21528f538b5SBob Moore 			}
21628f538b5SBob Moore 
217c1a7c2ceSNick Desaulniers 			ACPI_FALLTHROUGH;
21828f538b5SBob Moore 
2199ad19ac4SBob Moore 		default:
2209ad19ac4SBob Moore 
2219ad19ac4SBob Moore 			/* All other types are an error */
2229ad19ac4SBob Moore 
2239ad19ac4SBob Moore 			ACPI_ERROR((AE_INFO,
2249ad19ac4SBob Moore 				    "Invalid type (%s) for target of "
2259ad19ac4SBob Moore 				    "Scope operator [%4.4s] (Cannot override)",
2269ad19ac4SBob Moore 				    acpi_ut_get_type_name(node->type),
2279ad19ac4SBob Moore 				    acpi_ut_get_node_name(node)));
2289ad19ac4SBob Moore 
22968aafc35SBob Moore 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
2309ad19ac4SBob Moore 		}
2319ad19ac4SBob Moore 		break;
2329ad19ac4SBob Moore 
2339ad19ac4SBob Moore 	default:
2349ad19ac4SBob Moore 
2359ad19ac4SBob Moore 		/* All other opcodes */
2369ad19ac4SBob Moore 
2379ad19ac4SBob Moore 		if (op && op->common.node) {
2389ad19ac4SBob Moore 
2399ad19ac4SBob Moore 			/* This op/node was previously entered into the namespace */
2409ad19ac4SBob Moore 
2419ad19ac4SBob Moore 			node = op->common.node;
2429ad19ac4SBob Moore 
2439ad19ac4SBob Moore 			if (acpi_ns_opens_scope(object_type)) {
2449ad19ac4SBob Moore 				status =
2459ad19ac4SBob Moore 				    acpi_ds_scope_stack_push(node, object_type,
2469ad19ac4SBob Moore 							     walk_state);
2479ad19ac4SBob Moore 				if (ACPI_FAILURE(status)) {
2489ad19ac4SBob Moore 					return_ACPI_STATUS(status);
2499ad19ac4SBob Moore 				}
2509ad19ac4SBob Moore 			}
2519ad19ac4SBob Moore 
2529ad19ac4SBob Moore 			return_ACPI_STATUS(AE_OK);
2539ad19ac4SBob Moore 		}
2549ad19ac4SBob Moore 
2559ad19ac4SBob Moore 		/*
2569ad19ac4SBob Moore 		 * Enter the named type into the internal namespace. We enter the name
2579ad19ac4SBob Moore 		 * as we go downward in the parse tree. Any necessary subobjects that
2589ad19ac4SBob Moore 		 * involve arguments to the opcode must be created as we go back up the
2599ad19ac4SBob Moore 		 * parse tree later.
2609ad19ac4SBob Moore 		 *
2619ad19ac4SBob Moore 		 * Note: Name may already exist if we are executing a deferred opcode.
2629ad19ac4SBob Moore 		 */
2639ad19ac4SBob Moore 		if (walk_state->deferred_node) {
2649ad19ac4SBob Moore 
2659ad19ac4SBob Moore 			/* This name is already in the namespace, get the node */
2669ad19ac4SBob Moore 
2679ad19ac4SBob Moore 			node = walk_state->deferred_node;
2689ad19ac4SBob Moore 			status = AE_OK;
2699ad19ac4SBob Moore 			break;
2709ad19ac4SBob Moore 		}
2719ad19ac4SBob Moore 
2729ad19ac4SBob Moore 		flags = ACPI_NS_NO_UPSEARCH;
2739ad19ac4SBob Moore 		if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
2749ad19ac4SBob Moore 
2759ad19ac4SBob Moore 			/* Execution mode, node cannot already exist, node is temporary */
2769ad19ac4SBob Moore 
2779ad19ac4SBob Moore 			flags |= ACPI_NS_ERROR_IF_FOUND;
2789ad19ac4SBob Moore 
2799ad19ac4SBob Moore 			if (!
2809ad19ac4SBob Moore 			    (walk_state->
2819ad19ac4SBob Moore 			     parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
2829ad19ac4SBob Moore 				flags |= ACPI_NS_TEMPORARY;
2839ad19ac4SBob Moore 			}
2849ad19ac4SBob Moore 		}
2852f8c1141SErik Schmauss #ifdef ACPI_ASL_COMPILER
2862f8c1141SErik Schmauss 
2872f8c1141SErik Schmauss 		/*
288bdcf4cdbSErik Schmauss 		 * Do not open a scope for AML_EXTERNAL_OP
289bdcf4cdbSErik Schmauss 		 * acpi_ns_lookup can open a new scope based on the object type
290bdcf4cdbSErik Schmauss 		 * of this op. AML_EXTERNAL_OP is a declaration rather than a
291bdcf4cdbSErik Schmauss 		 * definition. In the case that this external is a method object,
292bdcf4cdbSErik Schmauss 		 * acpi_ns_lookup will open a new scope. However, an AML_EXTERNAL_OP
293bdcf4cdbSErik Schmauss 		 * associated with the ACPI_TYPE_METHOD is a declaration, rather than
294bdcf4cdbSErik Schmauss 		 * a definition. Flags is set to avoid opening a scope for any
295bdcf4cdbSErik Schmauss 		 * AML_EXTERNAL_OP.
2962f8c1141SErik Schmauss 		 */
2972f8c1141SErik Schmauss 		if (walk_state->opcode == AML_EXTERNAL_OP) {
2982f8c1141SErik Schmauss 			flags |= ACPI_NS_DONT_OPEN_SCOPE;
2992f8c1141SErik Schmauss 		}
3002f8c1141SErik Schmauss #endif
3019ad19ac4SBob Moore 
302927a6abfSBob Moore 		/*
303927a6abfSBob Moore 		 * For name creation opcodes, the full namepath prefix must
304927a6abfSBob Moore 		 * exist, except for the final (new) nameseg.
305927a6abfSBob Moore 		 */
306927a6abfSBob Moore 		if (walk_state->op_info->flags & AML_NAMED) {
307927a6abfSBob Moore 			flags |= ACPI_NS_PREFIX_MUST_EXIST;
308927a6abfSBob Moore 		}
309927a6abfSBob Moore 
3109ad19ac4SBob Moore 		/* Add new entry or lookup existing entry */
3119ad19ac4SBob Moore 
3129ad19ac4SBob Moore 		status =
3139ad19ac4SBob Moore 		    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
3149ad19ac4SBob Moore 				   object_type, ACPI_IMODE_LOAD_PASS2, flags,
3159ad19ac4SBob Moore 				   walk_state, &node);
3169ad19ac4SBob Moore 
3179ad19ac4SBob Moore 		if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
3189ad19ac4SBob Moore 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
3199ad19ac4SBob Moore 					  "***New Node [%4.4s] %p is temporary\n",
3209ad19ac4SBob Moore 					  acpi_ut_get_node_name(node), node));
3219ad19ac4SBob Moore 		}
3229ad19ac4SBob Moore 		break;
3239ad19ac4SBob Moore 	}
3249ad19ac4SBob Moore 
3259ad19ac4SBob Moore 	if (ACPI_FAILURE(status)) {
32616ccf829SBob Moore 		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
32716ccf829SBob Moore 				     buffer_ptr, status);
3289ad19ac4SBob Moore 		return_ACPI_STATUS(status);
3299ad19ac4SBob Moore 	}
3309ad19ac4SBob Moore 
3319ad19ac4SBob Moore 	if (!op) {
3329ad19ac4SBob Moore 
3339ad19ac4SBob Moore 		/* Create a new op */
3349ad19ac4SBob Moore 
33562eb935bSLv Zheng 		op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml);
3369ad19ac4SBob Moore 		if (!op) {
3379ad19ac4SBob Moore 			return_ACPI_STATUS(AE_NO_MEMORY);
3389ad19ac4SBob Moore 		}
3399ad19ac4SBob Moore 
3409ad19ac4SBob Moore 		/* Initialize the new op */
3419ad19ac4SBob Moore 
3429ad19ac4SBob Moore 		if (node) {
3439ad19ac4SBob Moore 			op->named.name = node->name.integer;
3449ad19ac4SBob Moore 		}
3459ad19ac4SBob Moore 		*out_op = op;
3469ad19ac4SBob Moore 	}
3479ad19ac4SBob Moore 
3489ad19ac4SBob Moore 	/*
3499ad19ac4SBob Moore 	 * Put the Node in the "op" object that the parser uses, so we
3509ad19ac4SBob Moore 	 * can get it again quickly when this scope is closed
3519ad19ac4SBob Moore 	 */
3529ad19ac4SBob Moore 	op->common.node = node;
3539ad19ac4SBob Moore 	return_ACPI_STATUS(status);
3549ad19ac4SBob Moore }
3559ad19ac4SBob Moore 
3569ad19ac4SBob Moore /*******************************************************************************
3579ad19ac4SBob Moore  *
3589ad19ac4SBob Moore  * FUNCTION:    acpi_ds_load2_end_op
3599ad19ac4SBob Moore  *
3609ad19ac4SBob Moore  * PARAMETERS:  walk_state      - Current state of the parse tree walk
3619ad19ac4SBob Moore  *
3629ad19ac4SBob Moore  * RETURN:      Status
3639ad19ac4SBob Moore  *
3649ad19ac4SBob Moore  * DESCRIPTION: Ascending callback used during the loading of the namespace,
3659ad19ac4SBob Moore  *              both control methods and everything else.
3669ad19ac4SBob Moore  *
3679ad19ac4SBob Moore  ******************************************************************************/
3689ad19ac4SBob Moore 
acpi_ds_load2_end_op(struct acpi_walk_state * walk_state)3699ad19ac4SBob Moore acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
3709ad19ac4SBob Moore {
3719ad19ac4SBob Moore 	union acpi_parse_object *op;
3729ad19ac4SBob Moore 	acpi_status status = AE_OK;
3739ad19ac4SBob Moore 	acpi_object_type object_type;
3749ad19ac4SBob Moore 	struct acpi_namespace_node *node;
3759ad19ac4SBob Moore 	union acpi_parse_object *arg;
3769ad19ac4SBob Moore 	struct acpi_namespace_node *new_node;
3779ad19ac4SBob Moore 	u32 i;
3789ad19ac4SBob Moore 	u8 region_space;
3799a1ae804SBob Moore #ifdef ACPI_EXEC_APP
3809a1ae804SBob Moore 	union acpi_operand_object *obj_desc;
3819a1ae804SBob Moore 	char *namepath;
3829a1ae804SBob Moore #endif
3839ad19ac4SBob Moore 
3849ad19ac4SBob Moore 	ACPI_FUNCTION_TRACE(ds_load2_end_op);
3859ad19ac4SBob Moore 
3869ad19ac4SBob Moore 	op = walk_state->op;
3879ad19ac4SBob Moore 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
3889ad19ac4SBob Moore 			  walk_state->op_info->name, op, walk_state));
3899ad19ac4SBob Moore 
3909ad19ac4SBob Moore 	/* Check if opcode had an associated namespace object */
3919ad19ac4SBob Moore 
3929ad19ac4SBob Moore 	if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
3939ad19ac4SBob Moore 		return_ACPI_STATUS(AE_OK);
3949ad19ac4SBob Moore 	}
3959ad19ac4SBob Moore 
3969ad19ac4SBob Moore 	if (op->common.aml_opcode == AML_SCOPE_OP) {
3979ad19ac4SBob Moore 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
3989ad19ac4SBob Moore 				  "Ending scope Op=%p State=%p\n", op,
3999ad19ac4SBob Moore 				  walk_state));
4009ad19ac4SBob Moore 	}
4019ad19ac4SBob Moore 
4029ad19ac4SBob Moore 	object_type = walk_state->op_info->object_type;
4039ad19ac4SBob Moore 
4049ad19ac4SBob Moore 	/*
4059ad19ac4SBob Moore 	 * Get the Node/name from the earlier lookup
4069ad19ac4SBob Moore 	 * (It was saved in the *op structure)
4079ad19ac4SBob Moore 	 */
4089ad19ac4SBob Moore 	node = op->common.node;
4099ad19ac4SBob Moore 
4109ad19ac4SBob Moore 	/*
4119ad19ac4SBob Moore 	 * Put the Node on the object stack (Contains the ACPI Name of
4129ad19ac4SBob Moore 	 * this object)
4139ad19ac4SBob Moore 	 */
4149ad19ac4SBob Moore 	walk_state->operands[0] = (void *)node;
4159ad19ac4SBob Moore 	walk_state->num_operands = 1;
4169ad19ac4SBob Moore 
4179ad19ac4SBob Moore 	/* Pop the scope stack */
4189ad19ac4SBob Moore 
4199ad19ac4SBob Moore 	if (acpi_ns_opens_scope(object_type) &&
4209ad19ac4SBob Moore 	    (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
4219ad19ac4SBob Moore 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
4229ad19ac4SBob Moore 				  "(%s) Popping scope for Op %p\n",
4239ad19ac4SBob Moore 				  acpi_ut_get_type_name(object_type), op));
4249ad19ac4SBob Moore 
4259ad19ac4SBob Moore 		status = acpi_ds_scope_stack_pop(walk_state);
4269ad19ac4SBob Moore 		if (ACPI_FAILURE(status)) {
4279ad19ac4SBob Moore 			goto cleanup;
4289ad19ac4SBob Moore 		}
4299ad19ac4SBob Moore 	}
4309ad19ac4SBob Moore 
4319ad19ac4SBob Moore 	/*
4329ad19ac4SBob Moore 	 * Named operations are as follows:
4339ad19ac4SBob Moore 	 *
4349ad19ac4SBob Moore 	 * AML_ALIAS
4359ad19ac4SBob Moore 	 * AML_BANKFIELD
4369ad19ac4SBob Moore 	 * AML_CREATEBITFIELD
4379ad19ac4SBob Moore 	 * AML_CREATEBYTEFIELD
4389ad19ac4SBob Moore 	 * AML_CREATEDWORDFIELD
4399ad19ac4SBob Moore 	 * AML_CREATEFIELD
4409ad19ac4SBob Moore 	 * AML_CREATEQWORDFIELD
4419ad19ac4SBob Moore 	 * AML_CREATEWORDFIELD
4429ad19ac4SBob Moore 	 * AML_DATA_REGION
4439ad19ac4SBob Moore 	 * AML_DEVICE
4449ad19ac4SBob Moore 	 * AML_EVENT
4459ad19ac4SBob Moore 	 * AML_FIELD
4469ad19ac4SBob Moore 	 * AML_INDEXFIELD
4479ad19ac4SBob Moore 	 * AML_METHOD
4489ad19ac4SBob Moore 	 * AML_METHODCALL
4499ad19ac4SBob Moore 	 * AML_MUTEX
4509ad19ac4SBob Moore 	 * AML_NAME
4519ad19ac4SBob Moore 	 * AML_NAMEDFIELD
4529ad19ac4SBob Moore 	 * AML_OPREGION
4539ad19ac4SBob Moore 	 * AML_POWERRES
4549ad19ac4SBob Moore 	 * AML_PROCESSOR
4559ad19ac4SBob Moore 	 * AML_SCOPE
4569ad19ac4SBob Moore 	 * AML_THERMALZONE
4579ad19ac4SBob Moore 	 */
4589ad19ac4SBob Moore 
4599ad19ac4SBob Moore 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
4609ad19ac4SBob Moore 			  "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
4619ad19ac4SBob Moore 			  acpi_ps_get_opcode_name(op->common.aml_opcode),
4629ad19ac4SBob Moore 			  walk_state, op, node));
4639ad19ac4SBob Moore 
4649ad19ac4SBob Moore 	/* Decode the opcode */
4659ad19ac4SBob Moore 
4669ad19ac4SBob Moore 	arg = op->common.value.arg;
4679ad19ac4SBob Moore 
4689ad19ac4SBob Moore 	switch (walk_state->op_info->type) {
4699ad19ac4SBob Moore 
4709ad19ac4SBob Moore 	case AML_TYPE_CREATE_FIELD:
4719ad19ac4SBob Moore 		/*
4729ad19ac4SBob Moore 		 * Create the field object, but the field buffer and index must
4739ad19ac4SBob Moore 		 * be evaluated later during the execution phase
4749ad19ac4SBob Moore 		 */
4759ad19ac4SBob Moore 		status = acpi_ds_create_buffer_field(op, walk_state);
4769a1ae804SBob Moore 		if (ACPI_FAILURE(status)) {
4779a1ae804SBob Moore 			ACPI_EXCEPTION((AE_INFO, status,
4789a1ae804SBob Moore 					"CreateBufferField failure"));
4799a1ae804SBob Moore 			goto cleanup;
4809a1ae804SBob Moore 			}
4819ad19ac4SBob Moore 		break;
4829ad19ac4SBob Moore 
4839ad19ac4SBob Moore 	case AML_TYPE_NAMED_FIELD:
4849ad19ac4SBob Moore 		/*
4859ad19ac4SBob Moore 		 * If we are executing a method, initialize the field
4869ad19ac4SBob Moore 		 */
4879ad19ac4SBob Moore 		if (walk_state->method_node) {
4889ad19ac4SBob Moore 			status = acpi_ds_init_field_objects(op, walk_state);
4899ad19ac4SBob Moore 		}
4909ad19ac4SBob Moore 
4919ad19ac4SBob Moore 		switch (op->common.aml_opcode) {
4929ad19ac4SBob Moore 		case AML_INDEX_FIELD_OP:
4939ad19ac4SBob Moore 
4949ad19ac4SBob Moore 			status =
4959ad19ac4SBob Moore 			    acpi_ds_create_index_field(op,
496f5c1e1c5SLv Zheng 						       (acpi_handle)arg->common.
497f5c1e1c5SLv Zheng 						       node, walk_state);
4989ad19ac4SBob Moore 			break;
4999ad19ac4SBob Moore 
5009ad19ac4SBob Moore 		case AML_BANK_FIELD_OP:
5019ad19ac4SBob Moore 
5029ad19ac4SBob Moore 			status =
5039ad19ac4SBob Moore 			    acpi_ds_create_bank_field(op, arg->common.node,
5049ad19ac4SBob Moore 						      walk_state);
5059ad19ac4SBob Moore 			break;
5069ad19ac4SBob Moore 
5079ad19ac4SBob Moore 		case AML_FIELD_OP:
5089ad19ac4SBob Moore 
5099ad19ac4SBob Moore 			status =
5109ad19ac4SBob Moore 			    acpi_ds_create_field(op, arg->common.node,
5119ad19ac4SBob Moore 						 walk_state);
5129ad19ac4SBob Moore 			break;
5139ad19ac4SBob Moore 
5149ad19ac4SBob Moore 		default:
5151d1ea1b7SChao Guan 
5169ad19ac4SBob Moore 			/* All NAMED_FIELD opcodes must be handled above */
5179ad19ac4SBob Moore 			break;
5189ad19ac4SBob Moore 		}
5199ad19ac4SBob Moore 		break;
5209ad19ac4SBob Moore 
5219ad19ac4SBob Moore 	case AML_TYPE_NAMED_SIMPLE:
5229ad19ac4SBob Moore 
5239ad19ac4SBob Moore 		status = acpi_ds_create_operands(walk_state, arg);
5249ad19ac4SBob Moore 		if (ACPI_FAILURE(status)) {
5259ad19ac4SBob Moore 			goto cleanup;
5269ad19ac4SBob Moore 		}
5279ad19ac4SBob Moore 
5289ad19ac4SBob Moore 		switch (op->common.aml_opcode) {
5299ad19ac4SBob Moore 		case AML_PROCESSOR_OP:
5309ad19ac4SBob Moore 
5319ad19ac4SBob Moore 			status = acpi_ex_create_processor(walk_state);
5329ad19ac4SBob Moore 			break;
5339ad19ac4SBob Moore 
5349ff5a21aSBob Moore 		case AML_POWER_RESOURCE_OP:
5359ad19ac4SBob Moore 
5369ad19ac4SBob Moore 			status = acpi_ex_create_power_resource(walk_state);
5379ad19ac4SBob Moore 			break;
5389ad19ac4SBob Moore 
5399ad19ac4SBob Moore 		case AML_MUTEX_OP:
5409ad19ac4SBob Moore 
5419ad19ac4SBob Moore 			status = acpi_ex_create_mutex(walk_state);
5429ad19ac4SBob Moore 			break;
5439ad19ac4SBob Moore 
5449ad19ac4SBob Moore 		case AML_EVENT_OP:
5459ad19ac4SBob Moore 
5469ad19ac4SBob Moore 			status = acpi_ex_create_event(walk_state);
5479ad19ac4SBob Moore 			break;
5489ad19ac4SBob Moore 
5499ad19ac4SBob Moore 		case AML_ALIAS_OP:
5509ad19ac4SBob Moore 
5519ad19ac4SBob Moore 			status = acpi_ex_create_alias(walk_state);
5529ad19ac4SBob Moore 			break;
5539ad19ac4SBob Moore 
5549ad19ac4SBob Moore 		default:
5551d1ea1b7SChao Guan 
5569ad19ac4SBob Moore 			/* Unknown opcode */
5579ad19ac4SBob Moore 
5589ad19ac4SBob Moore 			status = AE_OK;
5599ad19ac4SBob Moore 			goto cleanup;
5609ad19ac4SBob Moore 		}
5619ad19ac4SBob Moore 
5629ad19ac4SBob Moore 		/* Delete operands */
5639ad19ac4SBob Moore 
5649ad19ac4SBob Moore 		for (i = 1; i < walk_state->num_operands; i++) {
5659ad19ac4SBob Moore 			acpi_ut_remove_reference(walk_state->operands[i]);
5669ad19ac4SBob Moore 			walk_state->operands[i] = NULL;
5679ad19ac4SBob Moore 		}
5689ad19ac4SBob Moore 
5699ad19ac4SBob Moore 		break;
5709ad19ac4SBob Moore 
5719ad19ac4SBob Moore 	case AML_TYPE_NAMED_COMPLEX:
5729ad19ac4SBob Moore 
5739ad19ac4SBob Moore 		switch (op->common.aml_opcode) {
5749ad19ac4SBob Moore 		case AML_REGION_OP:
5759ad19ac4SBob Moore 		case AML_DATA_REGION_OP:
5769ad19ac4SBob Moore 
5779ad19ac4SBob Moore 			if (op->common.aml_opcode == AML_REGION_OP) {
5789ad19ac4SBob Moore 				region_space = (acpi_adr_space_type)
5799ad19ac4SBob Moore 				    ((op->common.value.arg)->common.value.
5809ad19ac4SBob Moore 				     integer);
5819ad19ac4SBob Moore 			} else {
58282a1b7cbSBob Moore 				region_space = ACPI_ADR_SPACE_DATA_TABLE;
5839ad19ac4SBob Moore 			}
5849ad19ac4SBob Moore 
5859ad19ac4SBob Moore 			/*
5869ad19ac4SBob Moore 			 * The op_region is not fully parsed at this time. The only valid
5879ad19ac4SBob Moore 			 * argument is the space_id. (We must save the address of the
5889ad19ac4SBob Moore 			 * AML of the address and length operands)
5899ad19ac4SBob Moore 			 *
5909ad19ac4SBob Moore 			 * If we have a valid region, initialize it. The namespace is
5919ad19ac4SBob Moore 			 * unlocked at this point.
5929ad19ac4SBob Moore 			 *
5939ad19ac4SBob Moore 			 * Need to unlock interpreter if it is locked (if we are running
5949ad19ac4SBob Moore 			 * a control method), in order to allow _REG methods to be run
5959ad19ac4SBob Moore 			 * during acpi_ev_initialize_region.
5969ad19ac4SBob Moore 			 */
5979ad19ac4SBob Moore 			if (walk_state->method_node) {
5989ad19ac4SBob Moore 				/*
5999ad19ac4SBob Moore 				 * Executing a method: initialize the region and unlock
6009ad19ac4SBob Moore 				 * the interpreter
6019ad19ac4SBob Moore 				 */
6021fad8738SBob Moore 				status = acpi_ex_create_region(op->named.data,
6039ad19ac4SBob Moore 							       op->named.length,
6049ad19ac4SBob Moore 							       region_space,
6059ad19ac4SBob Moore 							       walk_state);
6069ad19ac4SBob Moore 				if (ACPI_FAILURE(status)) {
60768aafc35SBob Moore 					return_ACPI_STATUS(status);
6089ad19ac4SBob Moore 				}
6099ad19ac4SBob Moore 			}
6109ad19ac4SBob Moore 
6119ad19ac4SBob Moore 			status =
6129ad19ac4SBob Moore 			    acpi_ev_initialize_region
613760235cdSLv Zheng 			    (acpi_ns_get_attached_object(node));
6149ad19ac4SBob Moore 			break;
6159ad19ac4SBob Moore 
6169ad19ac4SBob Moore 		case AML_NAME_OP:
6179ad19ac4SBob Moore 
6189ad19ac4SBob Moore 			status = acpi_ds_create_node(walk_state, node, op);
6199a1ae804SBob Moore 			if (ACPI_FAILURE(status)) {
6209a1ae804SBob Moore 				goto cleanup;
6219a1ae804SBob Moore 			}
6229a1ae804SBob Moore #ifdef ACPI_EXEC_APP
6239a1ae804SBob Moore 			/*
6249a1ae804SBob Moore 			 * acpi_exec support for namespace initialization file (initialize
6259a1ae804SBob Moore 			 * Name opcodes in this code.)
6269a1ae804SBob Moore 			 */
6279a1ae804SBob Moore 			namepath = acpi_ns_get_external_pathname(node);
6289a1ae804SBob Moore 			status = ae_lookup_init_file_entry(namepath, &obj_desc);
6299a1ae804SBob Moore 			if (ACPI_SUCCESS(status)) {
6309a1ae804SBob Moore 
6319a1ae804SBob Moore 				/* Detach any existing object, attach new object */
6329a1ae804SBob Moore 
6339a1ae804SBob Moore 				if (node->object) {
6349a1ae804SBob Moore 					acpi_ns_detach_object(node);
6359a1ae804SBob Moore 				}
6369a1ae804SBob Moore 				acpi_ns_attach_object(node, obj_desc,
6379a1ae804SBob Moore 						      obj_desc->common.type);
6389a1ae804SBob Moore 			}
6399a1ae804SBob Moore 			ACPI_FREE(namepath);
6409a1ae804SBob Moore 			status = AE_OK;
6419a1ae804SBob Moore #endif
6429ad19ac4SBob Moore 			break;
6439ad19ac4SBob Moore 
6449ad19ac4SBob Moore 		case AML_METHOD_OP:
6459ad19ac4SBob Moore 			/*
6469ad19ac4SBob Moore 			 * method_op pkg_length name_string method_flags term_list
6479ad19ac4SBob Moore 			 *
6489ad19ac4SBob Moore 			 * Note: We must create the method node/object pair as soon as we
6499ad19ac4SBob Moore 			 * see the method declaration. This allows later pass1 parsing
6509ad19ac4SBob Moore 			 * of invocations of the method (need to know the number of
6519ad19ac4SBob Moore 			 * arguments.)
6529ad19ac4SBob Moore 			 */
6539ad19ac4SBob Moore 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
6549ad19ac4SBob Moore 					  "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
6559ad19ac4SBob Moore 					  walk_state, op, op->named.node));
6569ad19ac4SBob Moore 
6579ad19ac4SBob Moore 			if (!acpi_ns_get_attached_object(op->named.node)) {
6589ad19ac4SBob Moore 				walk_state->operands[0] =
6599ad19ac4SBob Moore 				    ACPI_CAST_PTR(void, op->named.node);
6609ad19ac4SBob Moore 				walk_state->num_operands = 1;
6619ad19ac4SBob Moore 
6629ad19ac4SBob Moore 				status =
6639ad19ac4SBob Moore 				    acpi_ds_create_operands(walk_state,
6649ad19ac4SBob Moore 							    op->common.value.
6659ad19ac4SBob Moore 							    arg);
6669ad19ac4SBob Moore 				if (ACPI_SUCCESS(status)) {
6679ad19ac4SBob Moore 					status =
6689ad19ac4SBob Moore 					    acpi_ex_create_method(op->named.
6699ad19ac4SBob Moore 								  data,
6709ad19ac4SBob Moore 								  op->named.
6719ad19ac4SBob Moore 								  length,
6729ad19ac4SBob Moore 								  walk_state);
6739ad19ac4SBob Moore 				}
6741fad8738SBob Moore 
6759ad19ac4SBob Moore 				walk_state->operands[0] = NULL;
6769ad19ac4SBob Moore 				walk_state->num_operands = 0;
6779ad19ac4SBob Moore 
6789ad19ac4SBob Moore 				if (ACPI_FAILURE(status)) {
6799ad19ac4SBob Moore 					return_ACPI_STATUS(status);
6809ad19ac4SBob Moore 				}
6819ad19ac4SBob Moore 			}
6829ad19ac4SBob Moore 			break;
6839ad19ac4SBob Moore 
6849ad19ac4SBob Moore 		default:
6851d1ea1b7SChao Guan 
6869ad19ac4SBob Moore 			/* All NAMED_COMPLEX opcodes must be handled above */
6879ad19ac4SBob Moore 			break;
6889ad19ac4SBob Moore 		}
6899ad19ac4SBob Moore 		break;
6909ad19ac4SBob Moore 
6919ad19ac4SBob Moore 	case AML_CLASS_INTERNAL:
6929ad19ac4SBob Moore 
6939ad19ac4SBob Moore 		/* case AML_INT_NAMEPATH_OP: */
6949ad19ac4SBob Moore 		break;
6959ad19ac4SBob Moore 
6969ad19ac4SBob Moore 	case AML_CLASS_METHOD_CALL:
6979ad19ac4SBob Moore 
6989ad19ac4SBob Moore 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
6999ad19ac4SBob Moore 				  "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
7009ad19ac4SBob Moore 				  walk_state, op, node));
7019ad19ac4SBob Moore 
7029ad19ac4SBob Moore 		/*
7039ad19ac4SBob Moore 		 * Lookup the method name and save the Node
7049ad19ac4SBob Moore 		 */
7059ad19ac4SBob Moore 		status =
7069ad19ac4SBob Moore 		    acpi_ns_lookup(walk_state->scope_info,
7079ad19ac4SBob Moore 				   arg->common.value.string, ACPI_TYPE_ANY,
7089ad19ac4SBob Moore 				   ACPI_IMODE_LOAD_PASS2,
7099ad19ac4SBob Moore 				   ACPI_NS_SEARCH_PARENT |
7109ad19ac4SBob Moore 				   ACPI_NS_DONT_OPEN_SCOPE, walk_state,
7119ad19ac4SBob Moore 				   &(new_node));
7129ad19ac4SBob Moore 		if (ACPI_SUCCESS(status)) {
7139ad19ac4SBob Moore 			/*
7149ad19ac4SBob Moore 			 * Make sure that what we found is indeed a method
7159ad19ac4SBob Moore 			 * We didn't search for a method on purpose, to see if the name
7169ad19ac4SBob Moore 			 * would resolve
7179ad19ac4SBob Moore 			 */
7189ad19ac4SBob Moore 			if (new_node->type != ACPI_TYPE_METHOD) {
7199ad19ac4SBob Moore 				status = AE_AML_OPERAND_TYPE;
7209ad19ac4SBob Moore 			}
7219ad19ac4SBob Moore 
7229ad19ac4SBob Moore 			/* We could put the returned object (Node) on the object stack for
7239ad19ac4SBob Moore 			 * later, but for now, we will put it in the "op" object that the
7249ad19ac4SBob Moore 			 * parser uses, so we can get it again at the end of this scope
7259ad19ac4SBob Moore 			 */
7269ad19ac4SBob Moore 			op->common.node = new_node;
7279ad19ac4SBob Moore 		} else {
72816ccf829SBob Moore 			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
72916ccf829SBob Moore 					     arg->common.value.string, status);
7309ad19ac4SBob Moore 		}
7319ad19ac4SBob Moore 		break;
7329ad19ac4SBob Moore 
7339ad19ac4SBob Moore 	default:
7341d1ea1b7SChao Guan 
7359ad19ac4SBob Moore 		break;
7369ad19ac4SBob Moore 	}
7379ad19ac4SBob Moore 
7389ad19ac4SBob Moore cleanup:
7399ad19ac4SBob Moore 
7409ad19ac4SBob Moore 	/* Remove the Node pushed at the very beginning */
7419ad19ac4SBob Moore 
7429ad19ac4SBob Moore 	walk_state->operands[0] = NULL;
7439ad19ac4SBob Moore 	walk_state->num_operands = 0;
7449ad19ac4SBob Moore 	return_ACPI_STATUS(status);
7459ad19ac4SBob Moore }
746