/* * Support for the special debugger read/write control methods. * These methods are installed into the current namespace and are * used to read and write the various namespace objects. The point * is to force the AML interpreter do all of the work.
*/ #define ACPI_DB_READ_METHOD "\\_T98" #define ACPI_DB_WRITE_METHOD "\\_T99"
/******************************************************************************* * * FUNCTION: acpi_db_test_all_objects * * PARAMETERS: None * * RETURN: None * * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the * namespace by reading/writing/comparing all data objects such * as integers, strings, buffers, fields, buffer fields, etc. *
******************************************************************************/
/* Install the debugger read-object control method if necessary */
if (!read_handle) {
status = acpi_install_method(read_method_code); if (ACPI_FAILURE(status)) {
acpi_os_printf
("%s, Could not install debugger read method\n",
acpi_format_exception(status)); return;
}
status =
acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle); if (ACPI_FAILURE(status)) {
acpi_os_printf
("Could not obtain handle for debug method %s\n",
ACPI_DB_READ_METHOD); return;
}
}
/* Install the debugger write-object control method if necessary */
if (!write_handle) {
status = acpi_install_method(write_method_code); if (ACPI_FAILURE(status)) {
acpi_os_printf
("%s, Could not install debugger write method\n",
acpi_format_exception(status)); return;
}
status =
acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle); if (ACPI_FAILURE(status)) {
acpi_os_printf
("Could not obtain handle for debug method %s\n",
ACPI_DB_WRITE_METHOD); return;
}
}
/* Walk the entire namespace, testing each supported named data object */
/* * For the supported types, get the actual bit length or * byte length. Map the type to one of Integer/String/Buffer.
*/ switch (node->type) { case ACPI_TYPE_INTEGER:
case ACPI_TYPE_FIELD_UNIT: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD:
local_type = ACPI_TYPE_FIELD_UNIT; break;
case ACPI_TYPE_BUFFER_FIELD: /* * The returned object will be a Buffer if the field length * is larger than the size of an Integer (32 or 64 bits * depending on the DSDT version).
*/
local_type = ACPI_TYPE_INTEGER; if (obj_desc) {
bit_length = obj_desc->common_field.bit_length;
byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length); if (bit_length > acpi_gbl_integer_bit_width) {
local_type = ACPI_TYPE_BUFFER;
}
} break;
default:
/* Ignore all non-data types - Methods, Devices, Scopes, etc. */
if (!obj_desc) {
acpi_os_printf(" No attached sub-object, ignoring\n"); return (AE_OK);
}
/* At this point, we have resolved the object to one of the major types */
switch (local_type) { case ACPI_TYPE_INTEGER:
status = acpi_db_test_integer_type(node, bit_length); break;
case ACPI_TYPE_STRING:
status = acpi_db_test_string_type(node, byte_length); break;
case ACPI_TYPE_BUFFER:
status = acpi_db_test_buffer_type(node, bit_length); break;
case ACPI_TYPE_PACKAGE:
status = acpi_db_test_package_type(node); break;
case ACPI_TYPE_FIELD_UNIT:
status = acpi_db_test_field_unit_type(obj_desc); break;
default:
acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
local_type); break;
}
/* Exit on error, but don't abort the namespace walk */
if (ACPI_FAILURE(status)) {
status = AE_OK;
}
acpi_os_printf("\n"); return (status);
}
/******************************************************************************* * * FUNCTION: acpi_db_test_integer_type * * PARAMETERS: node - Parent NS node for the object * bit_length - Actual length of the object. Used for * support of arbitrary length field_unit * and buffer_field objects. * * RETURN: Status * * DESCRIPTION: Test read/write for an Integer-valued object. Performs a * write/read/compare of an arbitrary new value, then performs * a write/read/compare of the original value. *
******************************************************************************/
static acpi_status
acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
{ union acpi_object *temp1 = NULL; union acpi_object *temp2 = NULL; union acpi_object *temp3 = NULL; union acpi_object write_value;
u64 value_to_write;
acpi_status status;
if (bit_length > 64) {
acpi_os_printf(" Invalid length for an Integer: %u",
bit_length); return (AE_OK);
}
/* Read the original value */
status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1); if (ACPI_FAILURE(status)) { return (status);
}
exit: if (temp1) {
acpi_os_free(temp1);
} if (temp2) {
acpi_os_free(temp2);
} if (temp3) {
acpi_os_free(temp3);
} return (AE_OK);
}
/******************************************************************************* * * FUNCTION: acpi_db_test_buffer_type * * PARAMETERS: node - Parent NS node for the object * bit_length - Actual length of the object. * * RETURN: Status * * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a * write/read/compare of an arbitrary new value, then performs * a write/read/compare of the original value. *
******************************************************************************/
static acpi_status
acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
{ union acpi_object *temp1 = NULL; union acpi_object *temp2 = NULL; union acpi_object *temp3 = NULL;
u8 *buffer; union acpi_object write_value;
acpi_status status;
u32 byte_length;
u32 i;
u8 extra_bits;
byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length); if (byte_length == 0) {
acpi_os_printf(" Ignoring zero length buffer"); return (AE_OK);
}
/* Allocate a local buffer */
buffer = ACPI_ALLOCATE_ZEROED(byte_length); if (!buffer) { return (AE_NO_MEMORY);
}
/* Read the original value */
status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1); if (ACPI_FAILURE(status)) { gotoexit;
}
/* Emit a few bytes of the buffer */
acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT, bit_length,
temp1->buffer.length); for (i = 0; ((i < 8) && (i < byte_length)); i++) {
acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
}
acpi_os_printf("... ");
/* * Write a new value. * * Handle possible extra bits at the end of the buffer. Can * happen for field_units larger than an integer, but the bit * count is not an integral number of bytes. Zero out the * unused bits.
*/
memset(buffer, BUFFER_FILL_VALUE, byte_length);
extra_bits = bit_length % 8; if (extra_bits) {
buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
}
status = acpi_db_write_to_object(node, &write_value); if (ACPI_FAILURE(status)) { gotoexit;
}
/* Ensure that we can read back the original value */
status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3); if (ACPI_FAILURE(status)) { gotoexit;
}
if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
acpi_os_printf(" MISMATCH 3: While restoring original buffer");
}
exit:
ACPI_FREE(buffer); if (temp1) {
acpi_os_free(temp1);
} if (temp2) {
acpi_os_free(temp2);
} if (temp3) {
acpi_os_free(temp3);
} return (status);
}
/******************************************************************************* * * FUNCTION: acpi_db_test_string_type * * PARAMETERS: node - Parent NS node for the object * byte_length - Actual length of the object. * * RETURN: Status * * DESCRIPTION: Test read/write for an String-valued object. Performs a * write/read/compare of an arbitrary new value, then performs * a write/read/compare of the original value. *
******************************************************************************/
static acpi_status
acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
{ union acpi_object *temp1 = NULL; union acpi_object *temp2 = NULL; union acpi_object *temp3 = NULL; char *value_to_write = "Test String from AML Debugger"; union acpi_object write_value;
acpi_status status;
/* Read the original value */
status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1); if (ACPI_FAILURE(status)) { return (status);
}
/******************************************************************************* * * FUNCTION: acpi_db_test_field_unit_type * * PARAMETERS: obj_desc - A field unit object * * RETURN: Status * * DESCRIPTION: Test read/write on a named field unit. *
******************************************************************************/
static acpi_status
acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc)
{ union acpi_operand_object *region_obj;
u32 bit_length = 0;
u32 byte_length = 0;
acpi_status status = AE_OK; union acpi_operand_object *ret_buffer_desc;
/* Supported spaces are memory/io/pci_config */
region_obj = obj_desc->field.region_obj; switch (region_obj->region.space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_IO: case ACPI_ADR_SPACE_PCI_CONFIG:
acpi_os_printf
(" %s address space is not supported in this command [%4.4s]",
acpi_ut_get_region_name(region_obj->region.space_id),
region_obj->region.node->name.ascii); return (AE_OK);
}
}
/******************************************************************************* * * FUNCTION: acpi_db_read_from_object * * PARAMETERS: node - Parent NS node for the object * expected_type - Object type expected from the read * value - Where the value read is returned * * RETURN: Status * * DESCRIPTION: Performs a read from the specified object by invoking the * special debugger control method that reads the object. Thus, * the AML interpreter is doing all of the work, increasing the * validity of the test. *
******************************************************************************/
static acpi_status
acpi_db_read_from_object(struct acpi_namespace_node *node,
acpi_object_type expected_type, union acpi_object **value)
{ union acpi_object *ret_value; struct acpi_object_list param_objects; union acpi_object params[2]; struct acpi_buffer return_obj;
acpi_status status;
switch (ret_value->type) { case ACPI_TYPE_INTEGER: case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: case ACPI_TYPE_PACKAGE: /* * Did we receive the type we wanted? Most important for the * Integer/Buffer case (when a field is larger than an Integer, * it should return a Buffer).
*/ if (ret_value->type != expected_type) {
acpi_os_printf
(" Type mismatch: Expected %s, Received %s",
acpi_ut_get_type_name(expected_type),
acpi_ut_get_type_name(ret_value->type));
/******************************************************************************* * * FUNCTION: acpi_db_write_to_object * * PARAMETERS: node - Parent NS node for the object * value - Value to be written * * RETURN: Status * * DESCRIPTION: Performs a write to the specified object by invoking the * special debugger control method that writes the object. Thus, * the AML interpreter is doing all of the work, increasing the * validity of the test. *
******************************************************************************/
static acpi_status
acpi_db_write_to_object(struct acpi_namespace_node *node, union acpi_object *value)
{ struct acpi_object_list param_objects; union acpi_object params[2];
acpi_status status;
if (ACPI_FAILURE(status)) {
acpi_os_printf("Could not write to object, %s",
acpi_format_exception(status));
}
return (status);
}
/******************************************************************************* * * FUNCTION: acpi_db_evaluate_all_predefined_names * * PARAMETERS: count_arg - Max number of methods to execute * * RETURN: None * * DESCRIPTION: Namespace batch execution. Execute predefined names in the * namespace, up to the max count, if specified. *
******************************************************************************/
/* * Setup the ACPI-required number of arguments, regardless of what * the actual method defines. If there is a difference, then the * method is wrong and a warning will be issued during execution.
*/
this_param = params; for (i = 0; i < arg_count; i++) {
arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
this_param->type = arg_type;
switch (arg_type) { case ACPI_TYPE_INTEGER:
this_param->integer.value = 1; break;
case ACPI_TYPE_STRING:
this_param->string.pointer = "This is the default argument string";
this_param->string.length =
strlen(this_param->string.pointer); break;
case ACPI_TYPE_BUFFER:
this_param->buffer.pointer = (u8 *)params; /* just a garbage buffer */
this_param->buffer.length = 48; break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.