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); }
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); }