Exemplo n.º 1
0
acpi_status
acpi_ex_resolve_node_to_value (
	acpi_namespace_node     **object_ptr,
	acpi_walk_state         *walk_state)

{
	acpi_status             status = AE_OK;
	acpi_operand_object     *source_desc;
	acpi_operand_object     *obj_desc = NULL;
	acpi_namespace_node     *node;
	acpi_object_type8       entry_type;
	acpi_integer            temp_val;


	FUNCTION_TRACE ("Ex_resolve_node_to_value");


	/*
	 * The stack pointer points to a acpi_namespace_node (Node).  Get the
	 * object that is attached to the Node.
	 */
	node      = *object_ptr;
	source_desc  = acpi_ns_get_attached_object (node);
	entry_type = acpi_ns_get_type ((acpi_handle) node);

	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p Source_desc=%p Type=%X\n",
		 node, source_desc, entry_type));


	/*
	 * Several object types require no further processing:
	 * 1) Devices rarely have an attached object, return the Node
	 * 2) Method locals and arguments have a pseudo-Node
	 */
	if (entry_type == ACPI_TYPE_DEVICE ||
		(node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
		return_ACPI_STATUS (AE_OK);
	}

	if (!source_desc) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object attached to node %p\n",
			node));
		return_ACPI_STATUS (AE_AML_NO_OPERAND);
	}

	/*
	 * Action is based on the type of the Node, which indicates the type
	 * of the attached object or pointer
	 */
	switch (entry_type) {

	case ACPI_TYPE_PACKAGE:

		if (ACPI_TYPE_PACKAGE != source_desc->common.type) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Package, type %s\n",
				acpi_ut_get_type_name (source_desc->common.type)));
			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
		}

		/* Return an additional reference to the object */

		obj_desc = source_desc;
		acpi_ut_add_reference (obj_desc);
		break;


	case ACPI_TYPE_BUFFER:

		if (ACPI_TYPE_BUFFER != source_desc->common.type) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Buffer, type %s\n",
				acpi_ut_get_type_name (source_desc->common.type)));
			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
		}

		/* Return an additional reference to the object */

		obj_desc = source_desc;
		acpi_ut_add_reference (obj_desc);
		break;


	case ACPI_TYPE_STRING:

		if (ACPI_TYPE_STRING != source_desc->common.type) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a String, type %s\n",
				acpi_ut_get_type_name (source_desc->common.type)));
			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
		}

		/* Return an additional reference to the object */

		obj_desc = source_desc;
		acpi_ut_add_reference (obj_desc);
		break;


	case ACPI_TYPE_INTEGER:

		if (ACPI_TYPE_INTEGER != source_desc->common.type) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Integer, type %s\n",
				acpi_ut_get_type_name (source_desc->common.type)));
			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
		}

		/* Return an additional reference to the object */

		obj_desc = source_desc;
		acpi_ut_add_reference (obj_desc);
		break;


	case ACPI_TYPE_BUFFER_FIELD:
	case INTERNAL_TYPE_REGION_FIELD:
	case INTERNAL_TYPE_BANK_FIELD:
	case INTERNAL_TYPE_INDEX_FIELD:

		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Field_read Node=%p Source_desc=%p Type=%X\n",
			node, source_desc, entry_type));

		status = acpi_ex_read_data_from_field (source_desc, &obj_desc);
		break;


	/*
	 * For these objects, just return the object attached to the Node
	 */
	case ACPI_TYPE_MUTEX:
	case ACPI_TYPE_METHOD:
	case ACPI_TYPE_POWER:
	case ACPI_TYPE_PROCESSOR:
	case ACPI_TYPE_THERMAL:
	case ACPI_TYPE_EVENT:
	case ACPI_TYPE_REGION:

		/* Return an additional reference to the object */

		obj_desc = source_desc;
		acpi_ut_add_reference (obj_desc);
		break;


	/* TYPE_Any is untyped, and thus there is no object associated with it */

	case ACPI_TYPE_ANY:

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Untyped entry %p, no attached object!\n",
			node));

		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);  /* Cannot be AE_TYPE */
		break;


	/*
	 * The only named references allowed are named constants
	 *   e.g. -- Name (\OSFL, Ones)
	 */
	case INTERNAL_TYPE_REFERENCE:

		switch (source_desc->reference.opcode) {

		case AML_ZERO_OP:

			temp_val = 0;
			break;

		case AML_ONE_OP:

			temp_val = 1;
			break;

		case AML_ONES_OP:

			temp_val = ACPI_INTEGER_MAX;
			break;

		case AML_REVISION_OP:

			temp_val = ACPI_CA_SUPPORT_LEVEL;
			break;

		default:

			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n",
				source_desc->reference.opcode));

			return_ACPI_STATUS (AE_AML_BAD_OPCODE);
		}

		/* Create object for result */

		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
		if (!obj_desc) {
			return_ACPI_STATUS (AE_NO_MEMORY);
		}

		obj_desc->integer.value = temp_val;

		/*
		 * Truncate value if we are executing from a 32-bit ACPI table
		 * AND actually executing AML code.  If we are resolving
		 * an object in the namespace via an external call to the
		 * subsystem, we will have a null Walk_state
		 */
		if (walk_state) {
			acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
		}
		break;


	/* Default case is for unknown types */

	default:

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Node %p - Unknown object type %X\n",
			node, entry_type));

		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);

	} /* switch (Entry_type) */


	/* Put the object descriptor on the stack */

	*object_ptr = (void *) obj_desc;
	return_ACPI_STATUS (status);
}
acpi_status
acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
			   union acpi_operand_object **result_desc, u32 flags)
{
	union acpi_operand_object *return_desc;
	u8 *pointer;
	acpi_integer result;
	u32 i;
	u32 count;
	acpi_status status;

	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);

	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
	case ACPI_TYPE_INTEGER:

		/* No conversion necessary */

		*result_desc = obj_desc;
		return_ACPI_STATUS(AE_OK);

	case ACPI_TYPE_BUFFER:
	case ACPI_TYPE_STRING:

		/* Note: Takes advantage of common buffer/string fields */

		pointer = obj_desc->buffer.pointer;
		count = obj_desc->buffer.length;
		break;

	default:
		return_ACPI_STATUS(AE_TYPE);
	}

	/*
	 * Convert the buffer/string to an integer.  Note that both buffers and
	 * strings are treated as raw data - we don't convert ascii to hex for
	 * strings.
	 *
	 * There are two terminating conditions for the loop:
	 * 1) The size of an integer has been reached, or
	 * 2) The end of the buffer or string has been reached
	 */
	result = 0;

	/* String conversion is different than Buffer conversion */

	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
	case ACPI_TYPE_STRING:

		/*
		 * Convert string to an integer - for most cases, the string must be
		 * hexadecimal as per the ACPI specification.  The only exception (as
		 * of ACPI 3.0) is that the to_integer() operator allows both decimal
		 * and hexadecimal strings (hex prefixed with "0x").
		 */
		status = acpi_ut_strtoul64((char *)pointer, flags, &result);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}
		break;

	case ACPI_TYPE_BUFFER:

		/* Check for zero-length buffer */

		if (!count) {
			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
		}

		/* Transfer no more than an integer's worth of data */

		if (count > acpi_gbl_integer_byte_width) {
			count = acpi_gbl_integer_byte_width;
		}

		/*
		 * Convert buffer to an integer - we simply grab enough raw data
		 * from the buffer to fill an integer
		 */
		for (i = 0; i < count; i++) {
			/*
			 * Get next byte and shift it into the Result.
			 * Little endian is used, meaning that the first byte of the buffer
			 * is the LSB of the integer
			 */
			result |= (((acpi_integer) pointer[i]) << (i * 8));
		}
		break;

	default:
		/* No other types can get here */
		break;
	}

	/* Create a new integer */

	return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
	if (!return_desc) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
			  ACPI_FORMAT_UINT64(result)));

	/* Save the Result */

	return_desc->integer.value = result;
	acpi_ex_truncate_for32bit_table(return_desc);
	*result_desc = return_desc;
	return_ACPI_STATUS(AE_OK);
}
Exemplo n.º 3
0
acpi_status
acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
			       union acpi_operand_object *dest_desc,
			       union acpi_operand_object **new_desc,
			       struct acpi_walk_state *walk_state)
{
	union acpi_operand_object *actual_src_desc;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc);

	actual_src_desc = source_desc;
	if (!dest_desc) {
		/*
		 * There is no destination object (An uninitialized node or
		 * package element), so we can simply copy the source object
		 * creating a new destination object
		 */
		status =
		    acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,
						    walk_state);
		return_ACPI_STATUS(status);
	}

	if (ACPI_GET_OBJECT_TYPE(source_desc) !=
	    ACPI_GET_OBJECT_TYPE(dest_desc)) {
		/*
		 * The source type does not match the type of the destination.
		 * Perform the "implicit conversion" of the source to the current type
		 * of the target as per the ACPI specification.
		 *
		 * If no conversion performed, actual_src_desc = source_desc.
		 * Otherwise, actual_src_desc is a temporary object to hold the
		 * converted object.
		 */
		status =
		    acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
						   (dest_desc), source_desc,
						   &actual_src_desc,
						   walk_state);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		if (source_desc == actual_src_desc) {
			/*
			 * No conversion was performed. Return the source_desc as the
			 * new object.
			 */
			*new_desc = source_desc;
			return_ACPI_STATUS(AE_OK);
		}
	}

	/*
	 * We now have two objects of identical types, and we can perform a
	 * copy of the *value* of the source object.
	 */
	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
	case ACPI_TYPE_INTEGER:

		dest_desc->integer.value = actual_src_desc->integer.value;

		/* Truncate value if we are executing from a 32-bit ACPI table */

		acpi_ex_truncate_for32bit_table(dest_desc);
		break;

	case ACPI_TYPE_STRING:

		status =
		    acpi_ex_store_string_to_string(actual_src_desc, dest_desc);
		break;

	case ACPI_TYPE_BUFFER:

		status =
		    acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);
		break;

	case ACPI_TYPE_PACKAGE:

		status =
		    acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,
						    walk_state);
		break;

	default:
		/*
		 * All other types come here.
		 */
		ACPI_WARNING((AE_INFO, "Store into type %s not implemented",
			      acpi_ut_get_object_type_name(dest_desc)));

		status = AE_NOT_IMPLEMENTED;
		break;
	}

	if (actual_src_desc != source_desc) {

		/* Delete the intermediate (temporary) source object */

		acpi_ut_remove_reference(actual_src_desc);
	}

	*new_desc = dest_desc;
	return_ACPI_STATUS(status);
}