示例#1
0
文件: dswload.c 项目: 274914765/C
acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
{
    union acpi_parse_object *op;
    acpi_object_type object_type;
    acpi_status status = AE_OK;

    ACPI_FUNCTION_TRACE(ds_load1_end_op);

    op = walk_state->op;
    ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
              walk_state));

    /* We are only interested in opcodes that have an associated name */

    if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
        return_ACPI_STATUS(AE_OK);
    }

    /* Get the object type to determine if we should pop the scope */

    object_type = walk_state->op_info->object_type;

#ifndef ACPI_NO_METHOD_EXECUTION
    if (walk_state->op_info->flags & AML_FIELD) {
        /*
         * If we are executing a method, do not create any namespace objects
         * during the load phase, only during execution.
         */
        if (!walk_state->method_node) {
            if (walk_state->opcode == AML_FIELD_OP ||
                walk_state->opcode == AML_BANK_FIELD_OP ||
                walk_state->opcode == AML_INDEX_FIELD_OP) {
                status =
                    acpi_ds_init_field_objects(op, walk_state);
            }
        }
        return_ACPI_STATUS(status);
    }

    /*
     * If we are executing a method, do not create any namespace objects
     * during the load phase, only during execution.
     */
    if (!walk_state->method_node) {
        if (op->common.aml_opcode == AML_REGION_OP) {
            status =
                acpi_ex_create_region(op->named.data,
                          op->named.length,
                          (acpi_adr_space_type) ((op->
                                      common.
                                      value.
                                      arg)->
                                     common.
                                     value.
                                     integer),
                          walk_state);
            if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
            }
        } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
            status =
                acpi_ex_create_region(op->named.data,
                          op->named.length,
                          REGION_DATA_TABLE,
                          walk_state);
            if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
            }
        }
    }
#endif

    if (op->common.aml_opcode == AML_NAME_OP) {

        /* For Name opcode, get the object type from the argument */

        if (op->common.value.arg) {
            object_type = (acpi_ps_get_opcode_info((op->common.
                                value.arg)->
                                   common.
                                   aml_opcode))->
                object_type;

            /* Set node type if we have a namespace node */

            if (op->common.node) {
                op->common.node->type = (u8) object_type;
            }
        }
    }

    /*
     * If we are executing a method, do not create any namespace objects
     * during the load phase, only during execution.
     */
    if (!walk_state->method_node) {
        if (op->common.aml_opcode == AML_METHOD_OP) {
            /*
             * method_op pkg_length name_string method_flags term_list
             *
             * Note: We must create the method node/object pair as soon as we
             * see the method declaration. This allows later pass1 parsing
             * of invocations of the method (need to know the number of
             * arguments.)
             */
            ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
                      "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
                      walk_state, op, op->named.node));

            if (!acpi_ns_get_attached_object(op->named.node)) {
                walk_state->operands[0] =
                    ACPI_CAST_PTR(void, op->named.node);
                walk_state->num_operands = 1;

                status =
                    acpi_ds_create_operands(walk_state,
                                op->common.value.
                                arg);
                if (ACPI_SUCCESS(status)) {
                    status =
                        acpi_ex_create_method(op->named.
                                  data,
                                  op->named.
                                  length,
                                  walk_state);
                }

                walk_state->operands[0] = NULL;
                walk_state->num_operands = 0;

                if (ACPI_FAILURE(status)) {
                    return_ACPI_STATUS(status);
                }
            }
        }
示例#2
0
acpi_status
acpi_ds_load2_end_op (
	acpi_walk_state         *walk_state)
{
	acpi_parse_object       *op;
	acpi_status             status = AE_OK;
	acpi_object_type8       data_type;
	acpi_namespace_node     *node;
	acpi_parse_object       *arg;
	acpi_namespace_node     *new_node;
	u32                     i;


	PROC_NAME ("Ds_load2_end_op");

	op = walk_state->op;
	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));


	/* Only interested in opcodes that have namespace objects */

	if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
		return (AE_OK);
	}

	if (op->opcode == AML_SCOPE_OP) {
		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
			"Ending scope Op=%p State=%p\n", op, walk_state));

		if (((acpi_parse2_object *)op)->name == -1) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n",
				op, walk_state));
			return (AE_OK);
		}
	}


	data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);

	/*
	 * Get the Node/name from the earlier lookup
	 * (It was saved in the *op structure)
	 */
	node = op->node;

	/*
	 * Put the Node on the object stack (Contains the ACPI Name of
	 * this object)
	 */
	walk_state->operands[0] = (void *) node;
	walk_state->num_operands = 1;

	/* Pop the scope stack */

	if (acpi_ns_opens_scope (data_type)) {

		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
			acpi_ut_get_type_name (data_type), op));
		acpi_ds_scope_stack_pop (walk_state);
	}

	/*
	 * Named operations are as follows:
	 *
	 * AML_ALIAS
	 * AML_BANKFIELD
	 * AML_CREATEBITFIELD
	 * AML_CREATEBYTEFIELD
	 * AML_CREATEDWORDFIELD
	 * AML_CREATEFIELD
	 * AML_CREATEQWORDFIELD
	 * AML_CREATEWORDFIELD
	 * AML_DATA_REGION
	 * AML_DEVICE
	 * AML_EVENT
	 * AML_FIELD
	 * AML_INDEXFIELD
	 * AML_METHOD
	 * AML_METHODCALL
	 * AML_MUTEX
	 * AML_NAME
	 * AML_NAMEDFIELD
	 * AML_OPREGION
	 * AML_POWERRES
	 * AML_PROCESSOR
	 * AML_SCOPE
	 * AML_THERMALZONE
	 */

	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
		"Create-Load [%s] State=%p Op=%p Named_obj=%p\n",
		acpi_ps_get_opcode_name (op->opcode), walk_state, op, node));

	/* Decode the opcode */

	arg = op->value.arg;

	switch (walk_state->op_info->type) {
	case AML_TYPE_CREATE_FIELD:

		/*
		 * Create the field object, but the field buffer and index must
		 * be evaluated later during the execution phase
		 */
		status = acpi_ds_create_buffer_field (op, walk_state);
		break;


	 case AML_TYPE_NAMED_FIELD:

		arg = op->value.arg;
		switch (op->opcode) {
		case AML_INDEX_FIELD_OP:

			status = acpi_ds_create_index_field (op, (acpi_handle) arg->node,
					   walk_state);
			break;


		case AML_BANK_FIELD_OP:

			status = acpi_ds_create_bank_field (op, arg->node, walk_state);
			break;


		case AML_FIELD_OP:

			status = acpi_ds_create_field (op, arg->node, walk_state);
			break;
		}
		break;


	 case AML_TYPE_NAMED_SIMPLE:

		status = acpi_ds_create_operands (walk_state, arg);
		if (ACPI_FAILURE (status)) {
			goto cleanup;
		}

		switch (op->opcode) {
		case AML_PROCESSOR_OP:

			status = acpi_ex_create_processor (walk_state);
			break;


		case AML_POWER_RES_OP:

			status = acpi_ex_create_power_resource (walk_state);
			break;


		case AML_MUTEX_OP:

			status = acpi_ex_create_mutex (walk_state);
			break;


		case AML_EVENT_OP:

			status = acpi_ex_create_event (walk_state);
			break;


		case AML_DATA_REGION_OP:

			status = acpi_ex_create_table_region (walk_state);
			break;

		case AML_ALIAS_OP:

			status = acpi_ex_create_alias (walk_state);
			break;

		default:
			/* Unknown opcode */

			status = AE_OK;
			goto cleanup;
			break;
		}

		/* Delete operands */

		for (i = 1; i < walk_state->num_operands; i++) {
			acpi_ut_remove_reference (walk_state->operands[i]);
			walk_state->operands[i] = NULL;
		}

		break;


	case AML_TYPE_NAMED_COMPLEX:

		switch (op->opcode) {
		case AML_METHOD_OP:
			/*
			 * Method_op Pkg_length Names_string Method_flags Term_list
			 */
			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
				"LOADING-Method: State=%p Op=%p Named_obj=%p\n",
				walk_state, op, node));

			if (!node->object) {
				status = acpi_ds_create_operands (walk_state, arg);
				if (ACPI_FAILURE (status)) {
					goto cleanup;
				}

				status = acpi_ex_create_method (((acpi_parse2_object *) op)->data,
						   ((acpi_parse2_object *) op)->length,
						   walk_state);
			}
			break;


		case AML_REGION_OP:
			/*
			 * The Op_region is not fully parsed at this time. Only valid argument is the Space_id.
			 * (We must save the address of the AML of the address and length operands)
			 */
			status = acpi_ex_create_region (((acpi_parse2_object *) op)->data,
					  ((acpi_parse2_object *) op)->length,
							 (ACPI_ADR_SPACE_TYPE) arg->value.integer, walk_state);
			break;


		case AML_NAME_OP:

			status = acpi_ds_create_node (walk_state, node, op);
			break;
		}
		break;


	case AML_CLASS_INTERNAL:

		/* case AML_INT_NAMEPATH_OP: */
		break;


	case AML_CLASS_METHOD_CALL:

		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
			"RESOLVING-Method_call: State=%p Op=%p Named_obj=%p\n",
			walk_state, op, node));

		/*
		 * Lookup the method name and save the Node
		 */
		status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
				  ACPI_TYPE_ANY, IMODE_LOAD_PASS2,
				  NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
				  walk_state, &(new_node));
		if (ACPI_SUCCESS (status)) {
			/* TBD: has name already been resolved by here ??*/

			/* TBD: [Restructure] Make sure that what we found is indeed a method! */
			/* We didn't search for a method on purpose, to see if the name would resolve! */

			/* We could put the returned object (Node) on the object stack for later, but
			 * for now, we will put it in the "op" object that the parser uses, so we
			 * can get it again at the end of this scope
			 */
			op->node = new_node;
		}

		break;


	default:
		break;
	}


cleanup:

	/* Remove the Node pushed at the very beginning */

	walk_state->operands[0] = NULL;
	walk_state->num_operands = 0;
	return (status);
}