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