amcreate.c

来自「一个类似windows」· C语言 代码 · 共 715 行 · 第 1/2 页

C
715
字号
	}


cleanup:

	/* Always delete the operand */

	acpi_cm_remove_reference (sync_desc);

	return (status);
}


/*****************************************************************************
 *
 * FUNCTION:    Acpi_aml_exec_create_region
 *
 * PARAMETERS:  Aml_ptr             - Pointer to the region declaration AML
 *              Aml_length          - Max length of the declaration AML
 *              Operands            - List of operands for the opcode
 *              Interpreter_mode    - Load1/Load2/Execute
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Create a new operation region object
 *
 ****************************************************************************/

ACPI_STATUS
acpi_aml_exec_create_region (
	u8                      *aml_ptr,
	u32                     aml_length,
	u8                      region_space,
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_STATUS             status;
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_NAMESPACE_NODE     *node;


	/*
	 * Space ID must be one of the predefined IDs, or in the user-defined
	 * range
	 */
	if ((region_space >= NUM_REGION_TYPES) &&
		(region_space < USER_REGION_BEGIN)) {
		REPORT_ERROR (("Invalid Address_space type %X\n", region_space));
		return (AE_AML_INVALID_SPACE_ID);
	}


	/* Get the Node from the object stack  */

	node = (ACPI_NAMESPACE_NODE *) acpi_ds_obj_stack_get_value (0, walk_state);

	/* Create the region descriptor */

	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_REGION);
	if (!obj_desc) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/*
	 * Allocate a method object for this region.
	 */

	obj_desc->region.extra = acpi_cm_create_internal_object (
			 INTERNAL_TYPE_EXTRA);
	if (!obj_desc->region.extra) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/*
	 * Remember location in AML stream of address & length
	 * operands since they need to be evaluated at run time.
	 */

	obj_desc->region.extra->extra.pcode      = aml_ptr;
	obj_desc->region.extra->extra.pcode_length = aml_length;

	/* Init the region from the operands */

	obj_desc->region.space_id     = region_space;
	obj_desc->region.address      = 0;
	obj_desc->region.length       = 0;


	/* Install the new region object in the parent Node */

	obj_desc->region.node = node;

	status = acpi_ns_attach_object (node, obj_desc,
			  (u8) ACPI_TYPE_REGION);

	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	/*
	 * If we have a valid region, initialize it
	 * Namespace is NOT locked at this point.
	 */

	status = acpi_ev_initialize_region (obj_desc, FALSE);

	if (ACPI_FAILURE (status)) {
		/*
		 *  If AE_NOT_EXIST is returned, it is not fatal
		 *  because many regions get created before a handler
		 *  is installed for said region.
		 */
		if (AE_NOT_EXIST == status) {
			status = AE_OK;
		}
	}

cleanup:

	if (ACPI_FAILURE (status)) {
		/* Delete region object and method subobject */

		if (obj_desc) {
			/* Remove deletes both objects! */

			acpi_cm_remove_reference (obj_desc);
			obj_desc = NULL;
		}
	}

	return (status);
}


/*****************************************************************************
 *
 * FUNCTION:    Acpi_aml_exec_create_processor
 *
 * PARAMETERS:  Op              - Op containing the Processor definition and
 *                                args
 *              Processor_nTE   - Node for the containing Node
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Create a new processor object and populate the fields
 *
 ****************************************************************************/

ACPI_STATUS
acpi_aml_exec_create_processor (
	ACPI_PARSE_OBJECT       *op,
	ACPI_HANDLE             processor_nTE)
{
	ACPI_STATUS             status;
	ACPI_PARSE_OBJECT       *arg;
	ACPI_OPERAND_OBJECT     *obj_desc;


	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_PROCESSOR);
	if (!obj_desc) {
		status = AE_NO_MEMORY;
		return (status);
	}

	/* Install the new processor object in the parent Node */

	status = acpi_ns_attach_object (processor_nTE, obj_desc,
			   (u8) ACPI_TYPE_PROCESSOR);
	if (ACPI_FAILURE (status)) {
		return(status);
	}

	arg = op->value.arg;

	/* check existence */

	if (!arg) {
		status = AE_AML_NO_OPERAND;
		return (status);
	}

	/* First arg is the Processor ID */

	obj_desc->processor.proc_id = (u8) arg->value.integer;

	/* Move to next arg and check existence */

	arg = arg->next;
	if (!arg) {
		status = AE_AML_NO_OPERAND;
		return (status);
	}

	/* Second arg is the PBlock Address */

	obj_desc->processor.address = (ACPI_IO_ADDRESS) arg->value.integer;

	/* Move to next arg and check existence */

	arg = arg->next;
	if (!arg) {
		status = AE_AML_NO_OPERAND;
		return (status);
	}

	/* Third arg is the PBlock Length */

	obj_desc->processor.length = (u8) arg->value.integer;

	return (AE_OK);
}


/*****************************************************************************
 *
 * FUNCTION:    Acpi_aml_exec_create_power_resource
 *
 * PARAMETERS:  Op              - Op containing the Power_resource definition
 *                                and args
 *              Power_res_nTE   - Node for the containing Node
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Create a new Power_resource object and populate the fields
 *
 ****************************************************************************/

ACPI_STATUS
acpi_aml_exec_create_power_resource (
	ACPI_PARSE_OBJECT       *op,
	ACPI_HANDLE             power_res_nTE)
{
	ACPI_STATUS             status;
	ACPI_PARSE_OBJECT       *arg;
	ACPI_OPERAND_OBJECT     *obj_desc;


	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_POWER);
	if (!obj_desc) {
		status = AE_NO_MEMORY;
		return (status);
	}

	/* Install the new power resource object in the parent Node */

	status = acpi_ns_attach_object (power_res_nTE, obj_desc,
			  (u8) ACPI_TYPE_POWER);
	if (ACPI_FAILURE (status)) {
		return(status);
	}

	arg = op->value.arg;

	/* check existence */

	if (!arg) {
		status = AE_AML_NO_OPERAND;
		return (status);
	}

	/* First arg is the System_level */

	obj_desc->power_resource.system_level = (u8) arg->value.integer;

	/* Move to next arg and check existence */

	arg = arg->next;
	if (!arg) {
		status = AE_AML_NO_OPERAND;
		return (status);
	}

	/* Second arg is the PBlock Address */

	obj_desc->power_resource.resource_order = (u16) arg->value.integer;

	return (AE_OK);
}


/*****************************************************************************
 *
 * FUNCTION:    Acpi_aml_exec_create_method
 *
 * PARAMETERS:  Aml_ptr         - First byte of the method's AML
 *              Aml_length      - AML byte count for this method
 *              Method_flags    - AML method flag byte
 *              Method          - Method Node
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Create a new method object
 *
 ****************************************************************************/

ACPI_STATUS
acpi_aml_exec_create_method (
	u8                      *aml_ptr,
	u32                     aml_length,
	u32                     method_flags,
	ACPI_HANDLE             method)
{
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_STATUS             status;


	/* Create a new method object */

	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_METHOD);
	if (!obj_desc) {
	   return (AE_NO_MEMORY);
	}

	/* Get the method's AML pointer/length from the Op */

	obj_desc->method.pcode      = aml_ptr;
	obj_desc->method.pcode_length = aml_length;

	/*
	 * First argument is the Method Flags (contains parameter count for the
	 * method)
	 */

	obj_desc->method.method_flags = (u8) method_flags;
	obj_desc->method.param_count = (u8) (method_flags &
			  METHOD_FLAGS_ARG_COUNT);

	/*
	 * Get the concurrency count.  If required, a semaphore will be
	 * created for this method when it is parsed.
	 */
	if (method_flags & METHOD_FLAGS_SERIALIZED) {
		/*
		 * ACPI 1.0: Concurrency = 1
		 * ACPI 2.0: Concurrency = (Sync_level (in method declaration) + 1)
		 */
		obj_desc->method.concurrency = (u8)
				  (((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1);
	}

	else {
		obj_desc->method.concurrency = INFINITE_CONCURRENCY;
	}

	/* Attach the new object to the method Node */

	status = acpi_ns_attach_object (method, obj_desc, (u8) ACPI_TYPE_METHOD);
	if (ACPI_FAILURE (status)) {
		acpi_cm_delete_object_desc (obj_desc);
	}

	return (status);
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?