Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/*******************************************************************************
   3 *
   4 * Module Name: dbtest - Various debug-related tests
   5 *
   6 ******************************************************************************/
   7
   8#include <acpi/acpi.h>
   9#include "accommon.h"
  10#include "acdebug.h"
  11#include "acnamesp.h"
  12#include "acpredef.h"
  13
  14#define _COMPONENT          ACPI_CA_DEBUGGER
  15ACPI_MODULE_NAME("dbtest")
  16
  17/* Local prototypes */
  18static void acpi_db_test_all_objects(void);
  19
  20static acpi_status
  21acpi_db_test_one_object(acpi_handle obj_handle,
  22			u32 nesting_level, void *context, void **return_value);
  23
  24static acpi_status
  25acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
  26
  27static acpi_status
  28acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
  29
  30static acpi_status
  31acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
  32
  33static acpi_status
  34acpi_db_read_from_object(struct acpi_namespace_node *node,
  35			 acpi_object_type expected_type,
  36			 union acpi_object **value);
  37
  38static acpi_status
  39acpi_db_write_to_object(struct acpi_namespace_node *node,
  40			union acpi_object *value);
  41
  42static void acpi_db_evaluate_all_predefined_names(char *count_arg);
  43
  44static acpi_status
  45acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
  46				     u32 nesting_level,
  47				     void *context, void **return_value);
  48
  49/*
  50 * Test subcommands
  51 */
  52static struct acpi_db_argument_info acpi_db_test_types[] = {
  53	{"OBJECTS"},
  54	{"PREDEFINED"},
  55	{NULL}			/* Must be null terminated */
  56};
  57
  58#define CMD_TEST_OBJECTS        0
  59#define CMD_TEST_PREDEFINED     1
  60
  61#define BUFFER_FILL_VALUE       0xFF
  62
  63/*
  64 * Support for the special debugger read/write control methods.
  65 * These methods are installed into the current namespace and are
  66 * used to read and write the various namespace objects. The point
  67 * is to force the AML interpreter do all of the work.
  68 */
  69#define ACPI_DB_READ_METHOD     "\\_T98"
  70#define ACPI_DB_WRITE_METHOD    "\\_T99"
  71
  72static acpi_handle read_handle = NULL;
  73static acpi_handle write_handle = NULL;
  74
  75/* ASL Definitions of the debugger read/write control methods */
  76
  77#if 0
  78definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
  79{
  80	method(_T98, 1, not_serialized) {	/* Read */
  81		return (de_ref_of(arg0))
  82	}
  83}
  84
  85definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
  86{
  87	method(_T99, 2, not_serialized) {	/* Write */
  88		store(arg1, arg0)
  89	}
  90}
  91#endif
  92
  93static unsigned char read_method_code[] = {
  94	0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00,	/* 00000000    "SSDT...." */
  95	0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00,	/* 00000008    "..Intel." */
  96	0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00,	/* 00000010    "DEBUG..." */
  97	0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C,	/* 00000018    "....INTL" */
  98	0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54,	/* 00000020    "... .._T" */
  99	0x39, 0x38, 0x01, 0xA4, 0x83, 0x68	/* 00000028    "98...h"   */
 100};
 101
 102static unsigned char write_method_code[] = {
 103	0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00,	/* 00000000    "SSDT...." */
 104	0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00,	/* 00000008    "..Intel." */
 105	0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00,	/* 00000010    "DEBUG..." */
 106	0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C,	/* 00000018    "....INTL" */
 107	0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54,	/* 00000020    "... .._T" */
 108	0x39, 0x39, 0x02, 0x70, 0x69, 0x68	/* 00000028    "99.pih"   */
 109};
 110
 111/*******************************************************************************
 112 *
 113 * FUNCTION:    acpi_db_execute_test
 114 *
 115 * PARAMETERS:  type_arg        - Subcommand
 116 *
 117 * RETURN:      None
 118 *
 119 * DESCRIPTION: Execute various debug tests.
 120 *
 121 * Note: Code is prepared for future expansion of the TEST command.
 122 *
 123 ******************************************************************************/
 124
 125void acpi_db_execute_test(char *type_arg)
 126{
 127	u32 temp;
 128
 129	acpi_ut_strupr(type_arg);
 130	temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
 131	if (temp == ACPI_TYPE_NOT_FOUND) {
 132		acpi_os_printf("Invalid or unsupported argument\n");
 133		return;
 134	}
 135
 136	switch (temp) {
 137	case CMD_TEST_OBJECTS:
 138
 139		acpi_db_test_all_objects();
 140		break;
 141
 142	case CMD_TEST_PREDEFINED:
 143
 144		acpi_db_evaluate_all_predefined_names(NULL);
 145		break;
 146
 147	default:
 148		break;
 149	}
 150}
 151
 152/*******************************************************************************
 153 *
 154 * FUNCTION:    acpi_db_test_all_objects
 155 *
 156 * PARAMETERS:  None
 157 *
 158 * RETURN:      None
 159 *
 160 * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
 161 *              namespace by reading/writing/comparing all data objects such
 162 *              as integers, strings, buffers, fields, buffer fields, etc.
 163 *
 164 ******************************************************************************/
 165
 166static void acpi_db_test_all_objects(void)
 167{
 168	acpi_status status;
 169
 170	/* Install the debugger read-object control method if necessary */
 171
 172	if (!read_handle) {
 173		status = acpi_install_method(read_method_code);
 174		if (ACPI_FAILURE(status)) {
 175			acpi_os_printf
 176			    ("%s, Could not install debugger read method\n",
 177			     acpi_format_exception(status));
 178			return;
 179		}
 180
 181		status =
 182		    acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
 183		if (ACPI_FAILURE(status)) {
 184			acpi_os_printf
 185			    ("Could not obtain handle for debug method %s\n",
 186			     ACPI_DB_READ_METHOD);
 187			return;
 188		}
 189	}
 190
 191	/* Install the debugger write-object control method if necessary */
 192
 193	if (!write_handle) {
 194		status = acpi_install_method(write_method_code);
 195		if (ACPI_FAILURE(status)) {
 196			acpi_os_printf
 197			    ("%s, Could not install debugger write method\n",
 198			     acpi_format_exception(status));
 199			return;
 200		}
 201
 202		status =
 203		    acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
 204		if (ACPI_FAILURE(status)) {
 205			acpi_os_printf
 206			    ("Could not obtain handle for debug method %s\n",
 207			     ACPI_DB_WRITE_METHOD);
 208			return;
 209		}
 210	}
 211
 212	/* Walk the entire namespace, testing each supported named data object */
 213
 214	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 215				  ACPI_UINT32_MAX, acpi_db_test_one_object,
 216				  NULL, NULL, NULL);
 217}
 218
 219/*******************************************************************************
 220 *
 221 * FUNCTION:    acpi_db_test_one_object
 222 *
 223 * PARAMETERS:  acpi_walk_callback
 224 *
 225 * RETURN:      Status
 226 *
 227 * DESCRIPTION: Test one namespace object. Supported types are Integer,
 228 *              String, Buffer, buffer_field, and field_unit. All other object
 229 *              types are simply ignored.
 230 *
 231 *              Note: Support for Packages is not implemented.
 232 *
 233 ******************************************************************************/
 234
 235static acpi_status
 236acpi_db_test_one_object(acpi_handle obj_handle,
 237			u32 nesting_level, void *context, void **return_value)
 238{
 239	struct acpi_namespace_node *node;
 240	union acpi_operand_object *obj_desc;
 241	union acpi_operand_object *region_obj;
 242	acpi_object_type local_type;
 243	u32 bit_length = 0;
 244	u32 byte_length = 0;
 245	acpi_status status = AE_OK;
 246
 247	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
 248	obj_desc = node->object;
 249
 250	/*
 251	 * For the supported types, get the actual bit length or
 252	 * byte length. Map the type to one of Integer/String/Buffer.
 253	 */
 254	switch (node->type) {
 255	case ACPI_TYPE_INTEGER:
 256
 257		/* Integer width is either 32 or 64 */
 258
 259		local_type = ACPI_TYPE_INTEGER;
 260		bit_length = acpi_gbl_integer_bit_width;
 261		break;
 262
 263	case ACPI_TYPE_STRING:
 264
 265		local_type = ACPI_TYPE_STRING;
 266		byte_length = obj_desc->string.length;
 267		break;
 268
 269	case ACPI_TYPE_BUFFER:
 270
 271		local_type = ACPI_TYPE_BUFFER;
 272		byte_length = obj_desc->buffer.length;
 273		bit_length = byte_length * 8;
 274		break;
 275
 276	case ACPI_TYPE_FIELD_UNIT:
 277	case ACPI_TYPE_BUFFER_FIELD:
 278	case ACPI_TYPE_LOCAL_REGION_FIELD:
 279	case ACPI_TYPE_LOCAL_INDEX_FIELD:
 280	case ACPI_TYPE_LOCAL_BANK_FIELD:
 281
 282		local_type = ACPI_TYPE_INTEGER;
 283		if (obj_desc) {
 284			/*
 285			 * Returned object will be a Buffer if the field length
 286			 * is larger than the size of an Integer (32 or 64 bits
 287			 * depending on the DSDT version).
 288			 */
 289			bit_length = obj_desc->common_field.bit_length;
 290			byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
 291			if (bit_length > acpi_gbl_integer_bit_width) {
 292				local_type = ACPI_TYPE_BUFFER;
 293			}
 294		}
 295		break;
 296
 297	default:
 298
 299		/* Ignore all other types */
 300
 301		return (AE_OK);
 302	}
 303
 304	/* Emit the common prefix: Type:Name */
 305
 306	acpi_os_printf("%14s: %4.4s",
 307		       acpi_ut_get_type_name(node->type), node->name.ascii);
 308	if (!obj_desc) {
 309		acpi_os_printf(" Ignoring, no attached object\n");
 310		return (AE_OK);
 311	}
 312
 313	/*
 314	 * Check for unsupported region types. Note: acpi_exec simulates
 315	 * access to system_memory, system_IO, PCI_Config, and EC.
 316	 */
 317	switch (node->type) {
 318	case ACPI_TYPE_LOCAL_REGION_FIELD:
 319
 320		region_obj = obj_desc->field.region_obj;
 321		switch (region_obj->region.space_id) {
 322		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 323		case ACPI_ADR_SPACE_SYSTEM_IO:
 324		case ACPI_ADR_SPACE_PCI_CONFIG:
 325		case ACPI_ADR_SPACE_EC:
 326
 327			break;
 328
 329		default:
 330
 331			acpi_os_printf
 332			    ("    %s space is not supported [%4.4s]\n",
 333			     acpi_ut_get_region_name(region_obj->region.
 334						     space_id),
 335			     region_obj->region.node->name.ascii);
 336			return (AE_OK);
 337		}
 338		break;
 339
 340	default:
 341		break;
 342	}
 343
 344	/* At this point, we have resolved the object to one of the major types */
 345
 346	switch (local_type) {
 347	case ACPI_TYPE_INTEGER:
 348
 349		status = acpi_db_test_integer_type(node, bit_length);
 350		break;
 351
 352	case ACPI_TYPE_STRING:
 353
 354		status = acpi_db_test_string_type(node, byte_length);
 355		break;
 356
 357	case ACPI_TYPE_BUFFER:
 358
 359		status = acpi_db_test_buffer_type(node, bit_length);
 360		break;
 361
 362	default:
 363
 364		acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
 365			       local_type);
 366		break;
 367	}
 368
 369	switch (node->type) {
 370	case ACPI_TYPE_LOCAL_REGION_FIELD:
 371
 372		region_obj = obj_desc->field.region_obj;
 373		acpi_os_printf(" (%s)",
 374			       acpi_ut_get_region_name(region_obj->region.
 375						       space_id));
 376		break;
 377
 378	default:
 379		break;
 380	}
 381
 382	acpi_os_printf("\n");
 383	return (status);
 384}
 385
 386/*******************************************************************************
 387 *
 388 * FUNCTION:    acpi_db_test_integer_type
 389 *
 390 * PARAMETERS:  node                - Parent NS node for the object
 391 *              bit_length          - Actual length of the object. Used for
 392 *                                    support of arbitrary length field_unit
 393 *                                    and buffer_field objects.
 394 *
 395 * RETURN:      Status
 396 *
 397 * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
 398 *              write/read/compare of an arbitrary new value, then performs
 399 *              a write/read/compare of the original value.
 400 *
 401 ******************************************************************************/
 402
 403static acpi_status
 404acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
 405{
 406	union acpi_object *temp1 = NULL;
 407	union acpi_object *temp2 = NULL;
 408	union acpi_object *temp3 = NULL;
 409	union acpi_object write_value;
 410	u64 value_to_write;
 411	acpi_status status;
 412
 413	if (bit_length > 64) {
 414		acpi_os_printf(" Invalid length for an Integer: %u",
 415			       bit_length);
 416		return (AE_OK);
 417	}
 418
 419	/* Read the original value */
 420
 421	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
 422	if (ACPI_FAILURE(status)) {
 423		return (status);
 424	}
 425
 426	acpi_os_printf(" (%4.4X/%3.3X) %8.8X%8.8X",
 427		       bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
 428		       ACPI_FORMAT_UINT64(temp1->integer.value));
 429
 430	value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
 431	if (temp1->integer.value == value_to_write) {
 432		value_to_write = 0;
 433	}
 434
 435	/* Write a new value */
 436
 437	write_value.type = ACPI_TYPE_INTEGER;
 438	write_value.integer.value = value_to_write;
 439	status = acpi_db_write_to_object(node, &write_value);
 440	if (ACPI_FAILURE(status)) {
 441		goto exit;
 442	}
 443
 444	/* Ensure that we can read back the new value */
 445
 446	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
 447	if (ACPI_FAILURE(status)) {
 448		goto exit;
 449	}
 450
 451	if (temp2->integer.value != value_to_write) {
 452		acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
 453			       ACPI_FORMAT_UINT64(temp2->integer.value),
 454			       ACPI_FORMAT_UINT64(value_to_write));
 455	}
 456
 457	/* Write back the original value */
 458
 459	write_value.integer.value = temp1->integer.value;
 460	status = acpi_db_write_to_object(node, &write_value);
 461	if (ACPI_FAILURE(status)) {
 462		goto exit;
 463	}
 464
 465	/* Ensure that we can read back the original value */
 466
 467	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
 468	if (ACPI_FAILURE(status)) {
 469		goto exit;
 470	}
 471
 472	if (temp3->integer.value != temp1->integer.value) {
 473		acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
 474			       ACPI_FORMAT_UINT64(temp3->integer.value),
 475			       ACPI_FORMAT_UINT64(temp1->integer.value));
 476	}
 477
 478exit:
 479	if (temp1) {
 480		acpi_os_free(temp1);
 481	}
 482	if (temp2) {
 483		acpi_os_free(temp2);
 484	}
 485	if (temp3) {
 486		acpi_os_free(temp3);
 487	}
 488	return (AE_OK);
 489}
 490
 491/*******************************************************************************
 492 *
 493 * FUNCTION:    acpi_db_test_buffer_type
 494 *
 495 * PARAMETERS:  node                - Parent NS node for the object
 496 *              bit_length          - Actual length of the object.
 497 *
 498 * RETURN:      Status
 499 *
 500 * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
 501 *              write/read/compare of an arbitrary new value, then performs
 502 *              a write/read/compare of the original value.
 503 *
 504 ******************************************************************************/
 505
 506static acpi_status
 507acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
 508{
 509	union acpi_object *temp1 = NULL;
 510	union acpi_object *temp2 = NULL;
 511	union acpi_object *temp3 = NULL;
 512	u8 *buffer;
 513	union acpi_object write_value;
 514	acpi_status status;
 515	u32 byte_length;
 516	u32 i;
 517	u8 extra_bits;
 518
 519	byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
 520	if (byte_length == 0) {
 521		acpi_os_printf(" Ignoring zero length buffer");
 522		return (AE_OK);
 523	}
 524
 525	/* Allocate a local buffer */
 526
 527	buffer = ACPI_ALLOCATE_ZEROED(byte_length);
 528	if (!buffer) {
 529		return (AE_NO_MEMORY);
 530	}
 531
 532	/* Read the original value */
 533
 534	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
 535	if (ACPI_FAILURE(status)) {
 536		goto exit;
 537	}
 538
 539	/* Emit a few bytes of the buffer */
 540
 541	acpi_os_printf(" (%4.4X/%3.3X)", bit_length, temp1->buffer.length);
 542	for (i = 0; ((i < 4) && (i < byte_length)); i++) {
 543		acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
 544	}
 545	acpi_os_printf("... ");
 546
 547	/*
 548	 * Write a new value.
 549	 *
 550	 * Handle possible extra bits at the end of the buffer. Can
 551	 * happen for field_units larger than an integer, but the bit
 552	 * count is not an integral number of bytes. Zero out the
 553	 * unused bits.
 554	 */
 555	memset(buffer, BUFFER_FILL_VALUE, byte_length);
 556	extra_bits = bit_length % 8;
 557	if (extra_bits) {
 558		buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
 559	}
 560
 561	write_value.type = ACPI_TYPE_BUFFER;
 562	write_value.buffer.length = byte_length;
 563	write_value.buffer.pointer = buffer;
 564
 565	status = acpi_db_write_to_object(node, &write_value);
 566	if (ACPI_FAILURE(status)) {
 567		goto exit;
 568	}
 569
 570	/* Ensure that we can read back the new value */
 571
 572	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
 573	if (ACPI_FAILURE(status)) {
 574		goto exit;
 575	}
 576
 577	if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
 578		acpi_os_printf(" MISMATCH 2: New buffer value");
 579	}
 580
 581	/* Write back the original value */
 582
 583	write_value.buffer.length = byte_length;
 584	write_value.buffer.pointer = temp1->buffer.pointer;
 585
 586	status = acpi_db_write_to_object(node, &write_value);
 587	if (ACPI_FAILURE(status)) {
 588		goto exit;
 589	}
 590
 591	/* Ensure that we can read back the original value */
 592
 593	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
 594	if (ACPI_FAILURE(status)) {
 595		goto exit;
 596	}
 597
 598	if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
 599		acpi_os_printf(" MISMATCH 3: While restoring original buffer");
 600	}
 601
 602exit:
 603	ACPI_FREE(buffer);
 604	if (temp1) {
 605		acpi_os_free(temp1);
 606	}
 607	if (temp2) {
 608		acpi_os_free(temp2);
 609	}
 610	if (temp3) {
 611		acpi_os_free(temp3);
 612	}
 613	return (status);
 614}
 615
 616/*******************************************************************************
 617 *
 618 * FUNCTION:    acpi_db_test_string_type
 619 *
 620 * PARAMETERS:  node                - Parent NS node for the object
 621 *              byte_length         - Actual length of the object.
 622 *
 623 * RETURN:      Status
 624 *
 625 * DESCRIPTION: Test read/write for an String-valued object. Performs a
 626 *              write/read/compare of an arbitrary new value, then performs
 627 *              a write/read/compare of the original value.
 628 *
 629 ******************************************************************************/
 630
 631static acpi_status
 632acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
 633{
 634	union acpi_object *temp1 = NULL;
 635	union acpi_object *temp2 = NULL;
 636	union acpi_object *temp3 = NULL;
 637	char *value_to_write = "Test String from AML Debugger";
 638	union acpi_object write_value;
 639	acpi_status status;
 640
 641	/* Read the original value */
 642
 643	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
 644	if (ACPI_FAILURE(status)) {
 645		return (status);
 646	}
 647
 648	acpi_os_printf(" (%4.4X/%3.3X) \"%s\"", (temp1->string.length * 8),
 649		       temp1->string.length, temp1->string.pointer);
 650
 651	/* Write a new value */
 652
 653	write_value.type = ACPI_TYPE_STRING;
 654	write_value.string.length = strlen(value_to_write);
 655	write_value.string.pointer = value_to_write;
 656
 657	status = acpi_db_write_to_object(node, &write_value);
 658	if (ACPI_FAILURE(status)) {
 659		goto exit;
 660	}
 661
 662	/* Ensure that we can read back the new value */
 663
 664	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
 665	if (ACPI_FAILURE(status)) {
 666		goto exit;
 667	}
 668
 669	if (strcmp(temp2->string.pointer, value_to_write)) {
 670		acpi_os_printf(" MISMATCH 2: %s, expecting %s",
 671			       temp2->string.pointer, value_to_write);
 672	}
 673
 674	/* Write back the original value */
 675
 676	write_value.string.length = strlen(temp1->string.pointer);
 677	write_value.string.pointer = temp1->string.pointer;
 678
 679	status = acpi_db_write_to_object(node, &write_value);
 680	if (ACPI_FAILURE(status)) {
 681		goto exit;
 682	}
 683
 684	/* Ensure that we can read back the original value */
 685
 686	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
 687	if (ACPI_FAILURE(status)) {
 688		goto exit;
 689	}
 690
 691	if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
 692		acpi_os_printf(" MISMATCH 3: %s, expecting %s",
 693			       temp3->string.pointer, temp1->string.pointer);
 694	}
 695
 696exit:
 697	if (temp1) {
 698		acpi_os_free(temp1);
 699	}
 700	if (temp2) {
 701		acpi_os_free(temp2);
 702	}
 703	if (temp3) {
 704		acpi_os_free(temp3);
 705	}
 706	return (status);
 707}
 708
 709/*******************************************************************************
 710 *
 711 * FUNCTION:    acpi_db_read_from_object
 712 *
 713 * PARAMETERS:  node                - Parent NS node for the object
 714 *              expected_type       - Object type expected from the read
 715 *              value               - Where the value read is returned
 716 *
 717 * RETURN:      Status
 718 *
 719 * DESCRIPTION: Performs a read from the specified object by invoking the
 720 *              special debugger control method that reads the object. Thus,
 721 *              the AML interpreter is doing all of the work, increasing the
 722 *              validity of the test.
 723 *
 724 ******************************************************************************/
 725
 726static acpi_status
 727acpi_db_read_from_object(struct acpi_namespace_node *node,
 728			 acpi_object_type expected_type,
 729			 union acpi_object **value)
 730{
 731	union acpi_object *ret_value;
 732	struct acpi_object_list param_objects;
 733	union acpi_object params[2];
 734	struct acpi_buffer return_obj;
 735	acpi_status status;
 736
 737	params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
 738	params[0].reference.actual_type = node->type;
 739	params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
 740
 741	param_objects.count = 1;
 742	param_objects.pointer = params;
 743
 744	return_obj.length = ACPI_ALLOCATE_BUFFER;
 745
 746	acpi_gbl_method_executing = TRUE;
 747	status = acpi_evaluate_object(read_handle, NULL,
 748				      &param_objects, &return_obj);
 749	acpi_gbl_method_executing = FALSE;
 750
 751	if (ACPI_FAILURE(status)) {
 752		acpi_os_printf("Could not read from object, %s",
 753			       acpi_format_exception(status));
 754		return (status);
 755	}
 756
 757	ret_value = (union acpi_object *)return_obj.pointer;
 758
 759	switch (ret_value->type) {
 760	case ACPI_TYPE_INTEGER:
 761	case ACPI_TYPE_BUFFER:
 762	case ACPI_TYPE_STRING:
 763		/*
 764		 * Did we receive the type we wanted? Most important for the
 765		 * Integer/Buffer case (when a field is larger than an Integer,
 766		 * it should return a Buffer).
 767		 */
 768		if (ret_value->type != expected_type) {
 769			acpi_os_printf
 770			    (" Type mismatch: Expected %s, Received %s",
 771			     acpi_ut_get_type_name(expected_type),
 772			     acpi_ut_get_type_name(ret_value->type));
 773
 774			return (AE_TYPE);
 775		}
 776
 777		*value = ret_value;
 778		break;
 779
 780	default:
 781
 782		acpi_os_printf(" Unsupported return object type, %s",
 783			       acpi_ut_get_type_name(ret_value->type));
 784
 785		acpi_os_free(return_obj.pointer);
 786		return (AE_TYPE);
 787	}
 788
 789	return (status);
 790}
 791
 792/*******************************************************************************
 793 *
 794 * FUNCTION:    acpi_db_write_to_object
 795 *
 796 * PARAMETERS:  node                - Parent NS node for the object
 797 *              value               - Value to be written
 798 *
 799 * RETURN:      Status
 800 *
 801 * DESCRIPTION: Performs a write to the specified object by invoking the
 802 *              special debugger control method that writes the object. Thus,
 803 *              the AML interpreter is doing all of the work, increasing the
 804 *              validity of the test.
 805 *
 806 ******************************************************************************/
 807
 808static acpi_status
 809acpi_db_write_to_object(struct acpi_namespace_node *node,
 810			union acpi_object *value)
 811{
 812	struct acpi_object_list param_objects;
 813	union acpi_object params[2];
 814	acpi_status status;
 815
 816	params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
 817	params[0].reference.actual_type = node->type;
 818	params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
 819
 820	/* Copy the incoming user parameter */
 821
 822	memcpy(&params[1], value, sizeof(union acpi_object));
 823
 824	param_objects.count = 2;
 825	param_objects.pointer = params;
 826
 827	acpi_gbl_method_executing = TRUE;
 828	status = acpi_evaluate_object(write_handle, NULL, &param_objects, NULL);
 829	acpi_gbl_method_executing = FALSE;
 830
 831	if (ACPI_FAILURE(status)) {
 832		acpi_os_printf("Could not write to object, %s",
 833			       acpi_format_exception(status));
 834	}
 835
 836	return (status);
 837}
 838
 839/*******************************************************************************
 840 *
 841 * FUNCTION:    acpi_db_evaluate_all_predefined_names
 842 *
 843 * PARAMETERS:  count_arg           - Max number of methods to execute
 844 *
 845 * RETURN:      None
 846 *
 847 * DESCRIPTION: Namespace batch execution. Execute predefined names in the
 848 *              namespace, up to the max count, if specified.
 849 *
 850 ******************************************************************************/
 851
 852static void acpi_db_evaluate_all_predefined_names(char *count_arg)
 853{
 854	struct acpi_db_execute_walk info;
 855
 856	info.count = 0;
 857	info.max_count = ACPI_UINT32_MAX;
 858
 859	if (count_arg) {
 860		info.max_count = strtoul(count_arg, NULL, 0);
 861	}
 862
 863	/* Search all nodes in namespace */
 864
 865	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 866				  ACPI_UINT32_MAX,
 867				  acpi_db_evaluate_one_predefined_name, NULL,
 868				  (void *)&info, NULL);
 869
 870	acpi_os_printf("Evaluated %u predefined names in the namespace\n",
 871		       info.count);
 872}
 873
 874/*******************************************************************************
 875 *
 876 * FUNCTION:    acpi_db_evaluate_one_predefined_name
 877 *
 878 * PARAMETERS:  Callback from walk_namespace
 879 *
 880 * RETURN:      Status
 881 *
 882 * DESCRIPTION: Batch execution module. Currently only executes predefined
 883 *              ACPI names.
 884 *
 885 ******************************************************************************/
 886
 887static acpi_status
 888acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
 889				     u32 nesting_level,
 890				     void *context, void **return_value)
 891{
 892	struct acpi_namespace_node *node =
 893	    (struct acpi_namespace_node *)obj_handle;
 894	struct acpi_db_execute_walk *info =
 895	    (struct acpi_db_execute_walk *)context;
 896	char *pathname;
 897	const union acpi_predefined_info *predefined;
 898	struct acpi_device_info *obj_info;
 899	struct acpi_object_list param_objects;
 900	union acpi_object params[ACPI_METHOD_NUM_ARGS];
 901	union acpi_object *this_param;
 902	struct acpi_buffer return_obj;
 903	acpi_status status;
 904	u16 arg_type_list;
 905	u8 arg_count;
 906	u8 arg_type;
 907	u32 i;
 908
 909	/* The name must be a predefined ACPI name */
 910
 911	predefined = acpi_ut_match_predefined_method(node->name.ascii);
 912	if (!predefined) {
 913		return (AE_OK);
 914	}
 915
 916	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
 917		return (AE_OK);
 918	}
 919
 920	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
 921	if (!pathname) {
 922		return (AE_OK);
 923	}
 924
 925	/* Get the object info for number of method parameters */
 926
 927	status = acpi_get_object_info(obj_handle, &obj_info);
 928	if (ACPI_FAILURE(status)) {
 929		ACPI_FREE(pathname);
 930		return (status);
 931	}
 932
 933	param_objects.count = 0;
 934	param_objects.pointer = NULL;
 935
 936	if (obj_info->type == ACPI_TYPE_METHOD) {
 937
 938		/* Setup default parameters (with proper types) */
 939
 940		arg_type_list = predefined->info.argument_list;
 941		arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
 942
 943		/*
 944		 * Setup the ACPI-required number of arguments, regardless of what
 945		 * the actual method defines. If there is a difference, then the
 946		 * method is wrong and a warning will be issued during execution.
 947		 */
 948		this_param = params;
 949		for (i = 0; i < arg_count; i++) {
 950			arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
 951			this_param->type = arg_type;
 952
 953			switch (arg_type) {
 954			case ACPI_TYPE_INTEGER:
 955
 956				this_param->integer.value = 1;
 957				break;
 958
 959			case ACPI_TYPE_STRING:
 960
 961				this_param->string.pointer =
 962				    "This is the default argument string";
 963				this_param->string.length =
 964				    strlen(this_param->string.pointer);
 965				break;
 966
 967			case ACPI_TYPE_BUFFER:
 968
 969				this_param->buffer.pointer = (u8 *)params;	/* just a garbage buffer */
 970				this_param->buffer.length = 48;
 971				break;
 972
 973			case ACPI_TYPE_PACKAGE:
 974
 975				this_param->package.elements = NULL;
 976				this_param->package.count = 0;
 977				break;
 978
 979			default:
 980
 981				acpi_os_printf
 982				    ("%s: Unsupported argument type: %u\n",
 983				     pathname, arg_type);
 984				break;
 985			}
 986
 987			this_param++;
 988		}
 989
 990		param_objects.count = arg_count;
 991		param_objects.pointer = params;
 992	}
 993
 994	ACPI_FREE(obj_info);
 995	return_obj.pointer = NULL;
 996	return_obj.length = ACPI_ALLOCATE_BUFFER;
 997
 998	/* Do the actual method execution */
 999
1000	acpi_gbl_method_executing = TRUE;
1001
1002	status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
1003
1004	acpi_os_printf("%-32s returned %s\n",
1005		       pathname, acpi_format_exception(status));
1006	acpi_gbl_method_executing = FALSE;
1007	ACPI_FREE(pathname);
1008
1009	/* Ignore status from method execution */
1010
1011	status = AE_OK;
1012
1013	/* Update count, check if we have executed enough methods */
1014
1015	info->count++;
1016	if (info->count >= info->max_count) {
1017		status = AE_CTRL_TERMINATE;
1018	}
1019
1020	return (status);
1021}