⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ammonad.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 2 页
字号:
	}


	status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);


cleanup:
	/* Always delete the operand object */

	acpi_cm_remove_reference (obj_desc);

	/* Delete return object(s) on error */

	if (ACPI_FAILURE (status)) {
		acpi_cm_remove_reference (res_desc); /* Result descriptor */
		if (ret_desc) {
			acpi_cm_remove_reference (ret_desc);
			ret_desc = NULL;
		}
	}

	/* Set the return object and exit */

	*return_desc = ret_desc;
	return (status);
}


/*******************************************************************************
 *
 * FUNCTION:    Acpi_aml_exec_monadic2
 *
 * PARAMETERS:  Opcode              - The opcode to be executed
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute Type 2 monadic operator with numeric operand:
 *              Deref_of_op, Ref_of_op, Size_of_op, Type_op, Increment_op,
 *              Decrement_op, LNot_op,
 *
 ******************************************************************************/

ACPI_STATUS
acpi_aml_exec_monadic2 (
	u16                     opcode,
	ACPI_WALK_STATE         *walk_state,
	ACPI_OPERAND_OBJECT     **return_desc)
{
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_OPERAND_OBJECT     *tmp_desc;
	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
	ACPI_STATUS             resolve_status;
	ACPI_STATUS             status;
	u32                     type;
	ACPI_INTEGER            value;


	/* Attempt to resolve the operands */

	resolve_status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
	/* Always get all operands */

	status = acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);


	/* Now we can check the status codes */

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

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


	/* Get the operand and decode the opcode */


	switch (opcode) {

	/*  Def_lNot := LNot_op Operand */

	case AML_LNOT_OP:

		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
		if (!ret_desc) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		ret_desc->integer.value = !obj_desc->integer.value;
		break;


	/*  Def_decrement   :=  Decrement_op Target */
	/*  Def_increment   :=  Increment_op Target */

	case AML_DECREMENT_OP:
	case AML_INCREMENT_OP:

		/*
		 * Since we are expecting an Reference on the top of the stack, it
		 * can be either an Node or an internal object.
		 *
		 * TBD: [Future] This may be the prototype code for all cases where
		 * an Reference is expected!! 10/99
		 */

		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
			ret_desc = obj_desc;
		}

		else {
			/*
			 * Duplicate the Reference in a new object so that we can resolve it
			 * without destroying the original Reference object
			 */

			ret_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
			if (!ret_desc) {
				status = AE_NO_MEMORY;
				goto cleanup;
			}

			ret_desc->reference.opcode = obj_desc->reference.opcode;
			ret_desc->reference.offset = obj_desc->reference.offset;
			ret_desc->reference.object = obj_desc->reference.object;
		}


		/*
		 * Convert the Ret_desc Reference to a Number
		 * (This deletes the original Ret_desc)
		 */

		status = acpi_aml_resolve_operands (AML_LNOT_OP, &ret_desc, walk_state);
		if (ACPI_FAILURE (status)) {
			goto cleanup;
		}

		/* Do the actual increment or decrement */

		if (AML_INCREMENT_OP == opcode) {
			ret_desc->integer.value++;
		}
		else {
			ret_desc->integer.value--;
		}

		/* Store the result back in the original descriptor */

		status = acpi_aml_exec_store (ret_desc, obj_desc, walk_state);

		/* Objdesc was just deleted (because it is an Reference) */

		obj_desc = NULL;

		break;


	/*  Def_object_type :=  Object_type_op  Source_object   */

	case AML_TYPE_OP:

		if (INTERNAL_TYPE_REFERENCE == obj_desc->common.type) {
			/*
			 * Not a Name -- an indirect name pointer would have
			 * been converted to a direct name pointer in Resolve_operands
			 */
			switch (obj_desc->reference.opcode) {
			case AML_ZERO_OP:
			case AML_ONE_OP:
			case AML_ONES_OP:

				/* Constants are of type Number */

				type = ACPI_TYPE_INTEGER;
				break;


			case AML_DEBUG_OP:

				/* Per 1.0b spec, Debug object is of type Debug_object */

				type = ACPI_TYPE_DEBUG_OBJECT;
				break;


			case AML_INDEX_OP:

				/* Get the type of this reference (index into another object) */

				type = obj_desc->reference.target_type;
				if (type == ACPI_TYPE_PACKAGE) {
					/*
					 * The main object is a package, we want to get the type
					 * of the individual package element that is referenced by
					 * the index.
					 */
					type = (*(obj_desc->reference.where))->common.type;
				}

				break;


			case AML_LOCAL_OP:
			case AML_ARG_OP:

				type = acpi_ds_method_data_get_type (obj_desc->reference.opcode,
						  obj_desc->reference.offset, walk_state);
				break;


			default:

				REPORT_ERROR (("Acpi_aml_exec_monadic2/Type_op: Internal error - Unknown Reference subtype %X\n",
					obj_desc->reference.opcode));
				status = AE_AML_INTERNAL;
				goto cleanup;
			}
		}

		else {
			/*
			 * It's not a Reference, so it must be a direct name pointer.
			 */
			type = acpi_ns_get_type ((ACPI_HANDLE) obj_desc);
		}

		/* Allocate a descriptor to hold the type. */

		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
		if (!ret_desc) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		ret_desc->integer.value = type;
		break;


	/*  Def_size_of :=  Size_of_op  Source_object   */

	case AML_SIZE_OF_OP:

		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
			obj_desc = acpi_ns_get_attached_object (obj_desc);
		}

		if (!obj_desc) {
			value = 0;
		}

		else {
			switch (obj_desc->common.type) {

			case ACPI_TYPE_BUFFER:

				value = obj_desc->buffer.length;
				break;


			case ACPI_TYPE_STRING:

				value = obj_desc->string.length;
				break;


			case ACPI_TYPE_PACKAGE:

				value = obj_desc->package.count;
				break;

			case INTERNAL_TYPE_REFERENCE:

				value = 4;
				break;

			default:

				status = AE_AML_OPERAND_TYPE;
				goto cleanup;
			}
		}

		/*
		 * Now that we have the size of the object, create a result
		 * object to hold the value
		 */

		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
		if (!ret_desc) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		ret_desc->integer.value = value;
		break;


	/*  Def_ref_of  :=  Ref_of_op   Source_object   */

	case AML_REF_OF_OP:

		status = acpi_aml_get_object_reference (obj_desc, &ret_desc, walk_state);
		if (ACPI_FAILURE (status)) {
			goto cleanup;
		}
		break;


	/*  Def_deref_of := Deref_of_op Obj_reference   */

	case AML_DEREF_OF_OP:


		/* Check for a method local or argument */

		if (!VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
			/*
			 * Must resolve/dereference the local/arg reference first
			 */
			switch (obj_desc->reference.opcode) {
			/* Set Obj_desc to the value of the local/arg */

			case AML_LOCAL_OP:
			case AML_ARG_OP:

				acpi_ds_method_data_get_value (obj_desc->reference.opcode,
						obj_desc->reference.offset, walk_state, &tmp_desc);

				/*
				 * Delete our reference to the input object and
				 * point to the object just retrieved
				 */
				acpi_cm_remove_reference (obj_desc);
				obj_desc = tmp_desc;
				break;

			default:

				/* Index op - handled below */
				break;
			}
		}


		/* Obj_desc may have changed from the code above */

		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
			/* Get the actual object from the Node (This is the dereference) */

			ret_desc = ((ACPI_NAMESPACE_NODE *) obj_desc)->object;

			/* Returning a pointer to the object, add another reference! */

			acpi_cm_add_reference (ret_desc);
		}

		else {
			/*
			 * This must be a reference object produced by the Index
			 * ASL operation -- check internal opcode
			 */

			if ((obj_desc->reference.opcode != AML_INDEX_OP) &&
				(obj_desc->reference.opcode != AML_REF_OF_OP)) {
				status = AE_TYPE;
				goto cleanup;
			}


			switch (obj_desc->reference.opcode) {
			case AML_INDEX_OP:

				/*
				 * Supported target types for the Index operator are
				 * 1) A Buffer
				 * 2) A Package
				 */

				if (obj_desc->reference.target_type == ACPI_TYPE_BUFFER_FIELD) {
					/*
					 * The target is a buffer, we must create a new object that
					 * contains one element of the buffer, the element pointed
					 * to by the index.
					 *
					 * NOTE: index into a buffer is NOT a pointer to a
					 * sub-buffer of the main buffer, it is only a pointer to a
					 * single element (byte) of the buffer!
					 */
					ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
					if (!ret_desc) {
						status = AE_NO_MEMORY;
						goto cleanup;
					}

					tmp_desc = obj_desc->reference.object;
					ret_desc->integer.value =
						tmp_desc->buffer.pointer[obj_desc->reference.offset];

					/* TBD: [Investigate] (see below) Don't add an additional
					 * ref!
					 */
				}

				else if (obj_desc->reference.target_type == ACPI_TYPE_PACKAGE) {
					/*
					 * The target is a package, we want to return the referenced
					 * element of the package.  We must add another reference to
					 * this object, however.
					 */

					ret_desc = *(obj_desc->reference.where);
					if (!ret_desc) {
						/*
						 * We can't return a NULL dereferenced value.  This is
						 * an uninitialized package element and is thus a
						 * severe error.
						 */

						status = AE_AML_UNINITIALIZED_ELEMENT;
						goto cleanup;
					}

					acpi_cm_add_reference (ret_desc);
				}

				else {
					status = AE_AML_OPERAND_TYPE;
					goto cleanup;
				}

				break;


			case AML_REF_OF_OP:

				ret_desc = obj_desc->reference.object;

				/* Add another reference to the object! */

				acpi_cm_add_reference (ret_desc);
				break;
			}
		}

		break;


	default:

		REPORT_ERROR (("Acpi_aml_exec_monadic2: Unknown monadic opcode %X\n",
			opcode));
		status = AE_AML_BAD_OPCODE;
		goto cleanup;
	}


cleanup:

	if (obj_desc) {
		acpi_cm_remove_reference (obj_desc);
	}

	/* Delete return object on error */

	if (ACPI_FAILURE (status) &&
		(ret_desc)) {
		acpi_cm_remove_reference (ret_desc);
		ret_desc = NULL;
	}

	*return_desc = ret_desc;
	return (status);
}

⌨️ 快捷键说明

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