1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /******************************************************************************* 3 * 4 * Module Name: dbinput - user front-end to the AML debugger 5 * 6 ******************************************************************************/ 7 8 #include <acpi/acpi.h> 9 #include "accommon.h" 10 #include "acdebug.h" 11 12 #ifdef ACPI_APPLICATION 13 #include "acapps.h" 14 #endif 15 16 #define _COMPONENT ACPI_CA_DEBUGGER 17 ACPI_MODULE_NAME("dbinput") 18 19 /* Local prototypes */ 20 static u32 acpi_db_get_line(char *input_buffer); 21 22 static u32 acpi_db_match_command(char *user_command); 23 24 static void acpi_db_display_command_info(const char *command, u8 display_all); 25 26 static void acpi_db_display_help(char *command); 27 28 static u8 29 acpi_db_match_command_help(const char *command, 30 const struct acpi_db_command_help *help); 31 32 /* 33 * Top-level debugger commands. 34 * 35 * This list of commands must match the string table below it 36 */ 37 enum acpi_ex_debugger_commands { 38 CMD_NOT_FOUND = 0, 39 CMD_NULL, 40 CMD_ALLOCATIONS, 41 CMD_ARGS, 42 CMD_ARGUMENTS, 43 CMD_BREAKPOINT, 44 CMD_BUSINFO, 45 CMD_CALL, 46 CMD_DEBUG, 47 CMD_DISASSEMBLE, 48 CMD_DISASM, 49 CMD_DUMP, 50 CMD_EVALUATE, 51 CMD_EXECUTE, 52 CMD_EXIT, 53 CMD_FIELDS, 54 CMD_FIND, 55 CMD_GO, 56 CMD_HANDLERS, 57 CMD_HELP, 58 CMD_HELP2, 59 CMD_HISTORY, 60 CMD_HISTORY_EXE, 61 CMD_HISTORY_LAST, 62 CMD_INFORMATION, 63 CMD_INTEGRITY, 64 CMD_INTO, 65 CMD_LEVEL, 66 CMD_LIST, 67 CMD_LOCALS, 68 CMD_LOCKS, 69 CMD_METHODS, 70 CMD_NAMESPACE, 71 CMD_NOTIFY, 72 CMD_OBJECTS, 73 CMD_OSI, 74 CMD_OWNER, 75 CMD_PATHS, 76 CMD_PREDEFINED, 77 CMD_PREFIX, 78 CMD_QUIT, 79 CMD_REFERENCES, 80 CMD_RESOURCES, 81 CMD_RESULTS, 82 CMD_SET, 83 CMD_STATS, 84 CMD_STOP, 85 CMD_TABLES, 86 CMD_TEMPLATE, 87 CMD_TRACE, 88 CMD_TREE, 89 CMD_TYPE, 90 #ifdef ACPI_APPLICATION 91 CMD_ENABLEACPI, 92 CMD_EVENT, 93 CMD_GPE, 94 CMD_GPES, 95 CMD_SCI, 96 CMD_SLEEP, 97 98 CMD_CLOSE, 99 CMD_LOAD, 100 CMD_OPEN, 101 CMD_UNLOAD, 102 103 CMD_TERMINATE, 104 CMD_BACKGROUND, 105 CMD_THREADS, 106 107 CMD_TEST, 108 #endif 109 }; 110 111 #define CMD_FIRST_VALID 2 112 113 /* Second parameter is the required argument count */ 114 115 static const struct acpi_db_command_info acpi_gbl_db_commands[] = { 116 {"<NOT FOUND>", 0}, 117 {"<NULL>", 0}, 118 {"ALLOCATIONS", 0}, 119 {"ARGS", 0}, 120 {"ARGUMENTS", 0}, 121 {"BREAKPOINT", 1}, 122 {"BUSINFO", 0}, 123 {"CALL", 0}, 124 {"DEBUG", 1}, 125 {"DISASSEMBLE", 1}, 126 {"DISASM", 1}, 127 {"DUMP", 1}, 128 {"EVALUATE", 1}, 129 {"EXECUTE", 1}, 130 {"EXIT", 0}, 131 {"FIELDS", 1}, 132 {"FIND", 1}, 133 {"GO", 0}, 134 {"HANDLERS", 0}, 135 {"HELP", 0}, 136 {"?", 0}, 137 {"HISTORY", 0}, 138 {"!", 1}, 139 {"!!", 0}, 140 {"INFORMATION", 0}, 141 {"INTEGRITY", 0}, 142 {"INTO", 0}, 143 {"LEVEL", 0}, 144 {"LIST", 0}, 145 {"LOCALS", 0}, 146 {"LOCKS", 0}, 147 {"METHODS", 0}, 148 {"NAMESPACE", 0}, 149 {"NOTIFY", 2}, 150 {"OBJECTS", 0}, 151 {"OSI", 0}, 152 {"OWNER", 1}, 153 {"PATHS", 0}, 154 {"PREDEFINED", 0}, 155 {"PREFIX", 0}, 156 {"QUIT", 0}, 157 {"REFERENCES", 1}, 158 {"RESOURCES", 0}, 159 {"RESULTS", 0}, 160 {"SET", 3}, 161 {"STATS", 1}, 162 {"STOP", 0}, 163 {"TABLES", 0}, 164 {"TEMPLATE", 1}, 165 {"TRACE", 1}, 166 {"TREE", 0}, 167 {"TYPE", 1}, 168 #ifdef ACPI_APPLICATION 169 {"ENABLEACPI", 0}, 170 {"EVENT", 1}, 171 {"GPE", 1}, 172 {"GPES", 0}, 173 {"SCI", 0}, 174 {"SLEEP", 0}, 175 176 {"CLOSE", 0}, 177 {"LOAD", 1}, 178 {"OPEN", 1}, 179 {"UNLOAD", 1}, 180 181 {"TERMINATE", 0}, 182 {"BACKGROUND", 1}, 183 {"THREADS", 3}, 184 185 {"TEST", 1}, 186 #endif 187 {NULL, 0} 188 }; 189 190 /* 191 * Help for all debugger commands. First argument is the number of lines 192 * of help to output for the command. 193 * 194 * Note: Some commands are not supported by the kernel-level version of 195 * the debugger. 196 */ 197 static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { 198 {0, "\nNamespace Access:", "\n"}, 199 {1, " Businfo", "Display system bus info\n"}, 200 {1, " Disassemble <Method>", "Disassemble a control method\n"}, 201 {1, " Find <AcpiName> (? is wildcard)", 202 "Find ACPI name(s) with wildcards\n"}, 203 {1, " Integrity", "Validate namespace integrity\n"}, 204 {1, " Methods", "Display list of loaded control methods\n"}, 205 {1, " Fields <AddressSpaceId>", 206 "Display list of loaded field units by space ID\n"}, 207 {1, " Namespace [Object] [Depth]", 208 "Display loaded namespace tree/subtree\n"}, 209 {1, " Notify <Object> <Value>", "Send a notification on Object\n"}, 210 {1, " Objects [ObjectType]", 211 "Display summary of all objects or just given type\n"}, 212 {1, " Owner <OwnerId> [Depth]", 213 "Display loaded namespace by object owner\n"}, 214 {1, " Paths", "Display full pathnames of namespace objects\n"}, 215 {1, " Predefined", "Check all predefined names\n"}, 216 {1, " Prefix [<Namepath>]", "Set or Get current execution prefix\n"}, 217 {1, " References <Addr>", "Find all references to object at addr\n"}, 218 {1, " Resources [DeviceName]", 219 "Display Device resources (no arg = all devices)\n"}, 220 {1, " Set N <NamedObject> <Value>", "Set value for named integer\n"}, 221 {1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"}, 222 {1, " Type <Object>", "Display object type\n"}, 223 224 {0, "\nControl Method Execution:", "\n"}, 225 {1, " Evaluate <Namepath> [Arguments]", 226 "Evaluate object or control method\n"}, 227 {1, " Execute <Namepath> [Arguments]", "Synonym for Evaluate\n"}, 228 #ifdef ACPI_APPLICATION 229 {1, " Background <Namepath> [Arguments]", 230 "Evaluate object/method in a separate thread\n"}, 231 {1, " Thread <Threads><Loops><NamePath>", 232 "Spawn threads to execute method(s)\n"}, 233 #endif 234 {1, " Debug <Namepath> [Arguments]", "Single-Step a control method\n"}, 235 {7, " [Arguments] formats:", "Control method argument formats\n"}, 236 {1, " Hex Integer", "Integer\n"}, 237 {1, " \"Ascii String\"", "String\n"}, 238 {1, " (Hex Byte List)", "Buffer\n"}, 239 {1, " (01 42 7A BF)", "Buffer example (4 bytes)\n"}, 240 {1, " [Package Element List]", "Package\n"}, 241 {1, " [0x01 0x1234 \"string\"]", 242 "Package example (3 elements)\n"}, 243 244 {0, "\nMiscellaneous:", "\n"}, 245 {1, " Allocations", "Display list of current memory allocations\n"}, 246 {2, " Dump <Address>|<Namepath>", "\n"}, 247 {0, " [Byte|Word|Dword|Qword]", 248 "Display ACPI objects or memory\n"}, 249 {1, " Handlers", "Info about global handlers\n"}, 250 {1, " Help [Command]", "This help screen or individual command\n"}, 251 {1, " History", "Display command history buffer\n"}, 252 {1, " Level <DebugLevel>] [console]", 253 "Get/Set debug level for file or console\n"}, 254 {1, " Locks", "Current status of internal mutexes\n"}, 255 {1, " Osi [Install|Remove <name>]", 256 "Display or modify global _OSI list\n"}, 257 {1, " Quit or Exit", "Exit this command\n"}, 258 {8, " Stats <SubCommand>", 259 "Display namespace and memory statistics\n"}, 260 {1, " Allocations", "Display list of current memory allocations\n"}, 261 {1, " Memory", "Dump internal memory lists\n"}, 262 {1, " Misc", "Namespace search and mutex stats\n"}, 263 {1, " Objects", "Summary of namespace objects\n"}, 264 {1, " Sizes", "Sizes for each of the internal objects\n"}, 265 {1, " Stack", "Display CPU stack usage\n"}, 266 {1, " Tables", "Info about current ACPI table(s)\n"}, 267 {1, " Tables", "Display info about loaded ACPI tables\n"}, 268 #ifdef ACPI_APPLICATION 269 {1, " Terminate", "Delete namespace and all internal objects\n"}, 270 #endif 271 {1, " ! <CommandNumber>", "Execute command from history buffer\n"}, 272 {1, " !!", "Execute last command again\n"}, 273 274 {0, "\nMethod and Namespace Debugging:", "\n"}, 275 {5, " Trace <State> [<Namepath>] [Once]", 276 "Trace control method execution\n"}, 277 {1, " Enable", "Enable all messages\n"}, 278 {1, " Disable", "Disable tracing\n"}, 279 {1, " Method", "Enable method execution messages\n"}, 280 {1, " Opcode", "Enable opcode execution messages\n"}, 281 {3, " Test <TestName>", "Invoke a debug test\n"}, 282 {1, " Objects", "Read/write/compare all namespace data objects\n"}, 283 {1, " Predefined", 284 "Validate all ACPI predefined names (_STA, etc.)\n"}, 285 {1, " Execute predefined", 286 "Execute all predefined (public) methods\n"}, 287 288 {0, "\nControl Method Single-Step Execution:", "\n"}, 289 {1, " Arguments (or Args)", "Display method arguments\n"}, 290 {1, " Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"}, 291 {1, " Call", "Run to next control method invocation\n"}, 292 {1, " Go", "Allow method to run to completion\n"}, 293 {1, " Information", "Display info about the current method\n"}, 294 {1, " Into", "Step into (not over) a method call\n"}, 295 {1, " List [# of Aml Opcodes]", "Display method ASL statements\n"}, 296 {1, " Locals", "Display method local variables\n"}, 297 {1, " Results", "Display method result stack\n"}, 298 {1, " Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"}, 299 {1, " Stop", "Terminate control method\n"}, 300 {1, " Tree", "Display control method calling tree\n"}, 301 {1, " <Enter>", "Single step next AML opcode (over calls)\n"}, 302 303 #ifdef ACPI_APPLICATION 304 {0, "\nFile Operations:", "\n"}, 305 {1, " Close", "Close debug output file\n"}, 306 {1, " Load <Input Filename>", "Load ACPI table from a file\n"}, 307 {1, " Open <Output Filename>", "Open a file for debug output\n"}, 308 {1, " Unload <Namepath>", 309 "Unload an ACPI table via namespace object\n"}, 310 311 {0, "\nHardware Simulation:", "\n"}, 312 {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"}, 313 {1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"}, 314 {1, " Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"}, 315 {1, " Gpes", "Display info on all GPE devices\n"}, 316 {1, " Sci", "Generate an SCI\n"}, 317 {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"}, 318 #endif 319 {0, NULL, NULL} 320 }; 321 322 /******************************************************************************* 323 * 324 * FUNCTION: acpi_db_match_command_help 325 * 326 * PARAMETERS: command - Command string to match 327 * help - Help table entry to attempt match 328 * 329 * RETURN: TRUE if command matched, FALSE otherwise 330 * 331 * DESCRIPTION: Attempt to match a command in the help table in order to 332 * print help information for a single command. 333 * 334 ******************************************************************************/ 335 336 static u8 337 acpi_db_match_command_help(const char *command, 338 const struct acpi_db_command_help *help) 339 { 340 char *invocation = help->invocation; 341 u32 line_count; 342 343 /* Valid commands in the help table begin with a couple of spaces */ 344 345 if (*invocation != ' ') { 346 return (FALSE); 347 } 348 349 while (*invocation == ' ') { 350 invocation++; 351 } 352 353 /* Match command name (full command or substring) */ 354 355 while ((*command) && (*invocation) && (*invocation != ' ')) { 356 if (tolower((int)*command) != tolower((int)*invocation)) { 357 return (FALSE); 358 } 359 360 invocation++; 361 command++; 362 } 363 364 /* Print the appropriate number of help lines */ 365 366 line_count = help->line_count; 367 while (line_count) { 368 acpi_os_printf("%-38s : %s", help->invocation, 369 help->description); 370 help++; 371 line_count--; 372 } 373 374 return (TRUE); 375 } 376 377 /******************************************************************************* 378 * 379 * FUNCTION: acpi_db_display_command_info 380 * 381 * PARAMETERS: command - Command string to match 382 * display_all - Display all matching commands, or just 383 * the first one (substring match) 384 * 385 * RETURN: None 386 * 387 * DESCRIPTION: Display help information for a Debugger command. 388 * 389 ******************************************************************************/ 390 391 static void acpi_db_display_command_info(const char *command, u8 display_all) 392 { 393 const struct acpi_db_command_help *next; 394 u8 matched; 395 396 next = acpi_gbl_db_command_help; 397 while (next->invocation) { 398 matched = acpi_db_match_command_help(command, next); 399 if (!display_all && matched) { 400 return; 401 } 402 403 next++; 404 } 405 } 406 407 /******************************************************************************* 408 * 409 * FUNCTION: acpi_db_display_help 410 * 411 * PARAMETERS: command - Optional command string to display help. 412 * if not specified, all debugger command 413 * help strings are displayed 414 * 415 * RETURN: None 416 * 417 * DESCRIPTION: Display help for a single debugger command, or all of them. 418 * 419 ******************************************************************************/ 420 421 static void acpi_db_display_help(char *command) 422 { 423 const struct acpi_db_command_help *next = acpi_gbl_db_command_help; 424 425 if (!command) { 426 427 /* No argument to help, display help for all commands */ 428 429 acpi_os_printf("\nSummary of AML Debugger Commands\n\n"); 430 431 while (next->invocation) { 432 acpi_os_printf("%-38s%s", next->invocation, 433 next->description); 434 next++; 435 } 436 acpi_os_printf("\n"); 437 438 } else { 439 /* Display help for all commands that match the subtring */ 440 441 acpi_db_display_command_info(command, TRUE); 442 } 443 } 444 445 /******************************************************************************* 446 * 447 * FUNCTION: acpi_db_get_next_token 448 * 449 * PARAMETERS: string - Command buffer 450 * next - Return value, end of next token 451 * 452 * RETURN: Pointer to the start of the next token. 453 * 454 * DESCRIPTION: Command line parsing. Get the next token on the command line 455 * 456 ******************************************************************************/ 457 458 char *acpi_db_get_next_token(char *string, 459 char **next, acpi_object_type *return_type) 460 { 461 char *start; 462 u32 depth; 463 acpi_object_type type = ACPI_TYPE_INTEGER; 464 465 /* At end of buffer? */ 466 467 if (!string || !(*string)) { 468 return (NULL); 469 } 470 471 /* Remove any spaces at the beginning, ignore blank lines */ 472 473 while (*string && isspace(*string)) { 474 string++; 475 } 476 477 if (!(*string)) { 478 return (NULL); 479 } 480 481 switch (*string) { 482 case '"': 483 484 /* This is a quoted string, scan until closing quote */ 485 486 string++; 487 start = string; 488 type = ACPI_TYPE_STRING; 489 490 /* Find end of string */ 491 492 while (*string && (*string != '"')) { 493 string++; 494 } 495 break; 496 497 case '(': 498 499 /* This is the start of a buffer, scan until closing paren */ 500 501 string++; 502 start = string; 503 type = ACPI_TYPE_BUFFER; 504 505 /* Find end of buffer */ 506 507 while (*string && (*string != ')')) { 508 string++; 509 } 510 break; 511 512 case '{': 513 514 /* This is the start of a field unit, scan until closing brace */ 515 516 string++; 517 start = string; 518 type = ACPI_TYPE_FIELD_UNIT; 519 520 /* Find end of buffer */ 521 522 while (*string && (*string != '}')) { 523 string++; 524 } 525 break; 526 527 case '[': 528 529 /* This is the start of a package, scan until closing bracket */ 530 531 string++; 532 depth = 1; 533 start = string; 534 type = ACPI_TYPE_PACKAGE; 535 536 /* Find end of package (closing bracket) */ 537 538 while (*string) { 539 540 /* Handle String package elements */ 541 542 if (*string == '"') { 543 /* Find end of string */ 544 545 string++; 546 while (*string && (*string != '"')) { 547 string++; 548 } 549 if (!(*string)) { 550 break; 551 } 552 } else if (*string == '[') { 553 depth++; /* A nested package declaration */ 554 } else if (*string == ']') { 555 depth--; 556 if (depth == 0) { /* Found final package closing bracket */ 557 break; 558 } 559 } 560 561 string++; 562 } 563 break; 564 565 default: 566 567 start = string; 568 569 /* Find end of token */ 570 571 while (*string && !isspace(*string)) { 572 string++; 573 } 574 break; 575 } 576 577 if (!(*string)) { 578 *next = NULL; 579 } else { 580 *string = 0; 581 *next = string + 1; 582 } 583 584 *return_type = type; 585 return (start); 586 } 587 588 /******************************************************************************* 589 * 590 * FUNCTION: acpi_db_get_line 591 * 592 * PARAMETERS: input_buffer - Command line buffer 593 * 594 * RETURN: Count of arguments to the command 595 * 596 * DESCRIPTION: Get the next command line from the user. Gets entire line 597 * up to the next newline 598 * 599 ******************************************************************************/ 600 601 static u32 acpi_db_get_line(char *input_buffer) 602 { 603 u32 i; 604 u32 count; 605 char *next; 606 char *this; 607 608 if (acpi_ut_safe_strcpy 609 (acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf), 610 input_buffer)) { 611 acpi_os_printf 612 ("Buffer overflow while parsing input line (max %u characters)\n", 613 (u32)sizeof(acpi_gbl_db_parsed_buf)); 614 return (0); 615 } 616 617 this = acpi_gbl_db_parsed_buf; 618 for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++) { 619 acpi_gbl_db_args[i] = acpi_db_get_next_token(this, &next, 620 &acpi_gbl_db_arg_types 621 [i]); 622 if (!acpi_gbl_db_args[i]) { 623 break; 624 } 625 626 this = next; 627 } 628 629 /* Uppercase the actual command */ 630 631 acpi_ut_strupr(acpi_gbl_db_args[0]); 632 633 count = i; 634 if (count) { 635 count--; /* Number of args only */ 636 } 637 638 return (count); 639 } 640 641 /******************************************************************************* 642 * 643 * FUNCTION: acpi_db_match_command 644 * 645 * PARAMETERS: user_command - User command line 646 * 647 * RETURN: Index into command array, -1 if not found 648 * 649 * DESCRIPTION: Search command array for a command match 650 * 651 ******************************************************************************/ 652 653 static u32 acpi_db_match_command(char *user_command) 654 { 655 u32 i; 656 657 if (!user_command || user_command[0] == 0) { 658 return (CMD_NULL); 659 } 660 661 for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) { 662 if (strstr 663 (ACPI_CAST_PTR(char, acpi_gbl_db_commands[i].name), 664 user_command) == acpi_gbl_db_commands[i].name) { 665 return (i); 666 } 667 } 668 669 /* Command not recognized */ 670 671 return (CMD_NOT_FOUND); 672 } 673 674 /******************************************************************************* 675 * 676 * FUNCTION: acpi_db_command_dispatch 677 * 678 * PARAMETERS: input_buffer - Command line buffer 679 * walk_state - Current walk 680 * op - Current (executing) parse op 681 * 682 * RETURN: Status 683 * 684 * DESCRIPTION: Command dispatcher. 685 * 686 ******************************************************************************/ 687 688 acpi_status 689 acpi_db_command_dispatch(char *input_buffer, 690 struct acpi_walk_state *walk_state, 691 union acpi_parse_object *op) 692 { 693 u32 temp; 694 u64 temp64; 695 u32 command_index; 696 u32 param_count; 697 char *command_line; 698 acpi_status status = AE_CTRL_TRUE; 699 700 /* If acpi_terminate has been called, terminate this thread */ 701 702 if (acpi_gbl_db_terminate_loop) { 703 return (AE_CTRL_TERMINATE); 704 } 705 706 /* Find command and add to the history buffer */ 707 708 param_count = acpi_db_get_line(input_buffer); 709 command_index = acpi_db_match_command(acpi_gbl_db_args[0]); 710 711 /* 712 * We don't want to add the !! command to the history buffer. It 713 * would cause an infinite loop because it would always be the 714 * previous command. 715 */ 716 if (command_index != CMD_HISTORY_LAST) { 717 acpi_db_add_to_history(input_buffer); 718 } 719 720 /* Verify that we have the minimum number of params */ 721 722 if (param_count < acpi_gbl_db_commands[command_index].min_args) { 723 acpi_os_printf 724 ("%u parameters entered, [%s] requires %u parameters\n", 725 param_count, acpi_gbl_db_commands[command_index].name, 726 acpi_gbl_db_commands[command_index].min_args); 727 728 acpi_db_display_command_info(acpi_gbl_db_commands 729 [command_index].name, FALSE); 730 return (AE_CTRL_TRUE); 731 } 732 733 /* Decode and dispatch the command */ 734 735 switch (command_index) { 736 case CMD_NULL: 737 738 if (op) { 739 return (AE_OK); 740 } 741 break; 742 743 case CMD_ALLOCATIONS: 744 745 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 746 acpi_ut_dump_allocations((u32)-1, NULL); 747 #endif 748 break; 749 750 case CMD_ARGS: 751 case CMD_ARGUMENTS: 752 753 acpi_db_display_arguments(); 754 break; 755 756 case CMD_BREAKPOINT: 757 758 acpi_db_set_method_breakpoint(acpi_gbl_db_args[1], walk_state, 759 op); 760 break; 761 762 case CMD_BUSINFO: 763 764 acpi_db_get_bus_info(); 765 break; 766 767 case CMD_CALL: 768 769 acpi_db_set_method_call_breakpoint(op); 770 status = AE_OK; 771 break; 772 773 case CMD_DEBUG: 774 775 acpi_db_execute(acpi_gbl_db_args[1], 776 &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2], 777 EX_SINGLE_STEP); 778 break; 779 780 case CMD_DISASSEMBLE: 781 case CMD_DISASM: 782 783 #ifdef ACPI_DISASSEMBLER 784 (void)acpi_db_disassemble_method(acpi_gbl_db_args[1]); 785 #else 786 acpi_os_printf 787 ("The AML Disassembler is not configured/present\n"); 788 #endif 789 break; 790 791 case CMD_DUMP: 792 793 acpi_db_decode_and_display_object(acpi_gbl_db_args[1], 794 acpi_gbl_db_args[2]); 795 break; 796 797 case CMD_EVALUATE: 798 case CMD_EXECUTE: 799 800 acpi_db_execute(acpi_gbl_db_args[1], 801 &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2], 802 EX_NO_SINGLE_STEP); 803 break; 804 805 case CMD_FIND: 806 807 status = acpi_db_find_name_in_namespace(acpi_gbl_db_args[1]); 808 break; 809 810 case CMD_FIELDS: 811 812 status = acpi_ut_strtoul64(acpi_gbl_db_args[1], &temp64); 813 814 if (ACPI_FAILURE(status) 815 || temp64 >= ACPI_NUM_PREDEFINED_REGIONS) { 816 acpi_os_printf 817 ("Invalid address space ID: must be between 0 and %u inclusive\n", 818 ACPI_NUM_PREDEFINED_REGIONS - 1); 819 return (AE_OK); 820 } 821 822 status = acpi_db_display_fields((u32)temp64); 823 break; 824 825 case CMD_GO: 826 827 acpi_gbl_cm_single_step = FALSE; 828 return (AE_OK); 829 830 case CMD_HANDLERS: 831 832 acpi_db_display_handlers(); 833 break; 834 835 case CMD_HELP: 836 case CMD_HELP2: 837 838 acpi_db_display_help(acpi_gbl_db_args[1]); 839 break; 840 841 case CMD_HISTORY: 842 843 acpi_db_display_history(); 844 break; 845 846 case CMD_HISTORY_EXE: /* ! command */ 847 848 command_line = acpi_db_get_from_history(acpi_gbl_db_args[1]); 849 if (!command_line) { 850 return (AE_CTRL_TRUE); 851 } 852 853 status = acpi_db_command_dispatch(command_line, walk_state, op); 854 return (status); 855 856 case CMD_HISTORY_LAST: /* !! command */ 857 858 command_line = acpi_db_get_from_history(NULL); 859 if (!command_line) { 860 return (AE_CTRL_TRUE); 861 } 862 863 status = acpi_db_command_dispatch(command_line, walk_state, op); 864 return (status); 865 866 case CMD_INFORMATION: 867 868 acpi_db_display_method_info(op); 869 break; 870 871 case CMD_INTEGRITY: 872 873 acpi_db_check_integrity(); 874 break; 875 876 case CMD_INTO: 877 878 if (op) { 879 acpi_gbl_cm_single_step = TRUE; 880 return (AE_OK); 881 } 882 break; 883 884 case CMD_LEVEL: 885 886 if (param_count == 0) { 887 acpi_os_printf 888 ("Current debug level for file output is: %8.8X\n", 889 acpi_gbl_db_debug_level); 890 acpi_os_printf 891 ("Current debug level for console output is: %8.8X\n", 892 acpi_gbl_db_console_debug_level); 893 } else if (param_count == 2) { 894 temp = acpi_gbl_db_console_debug_level; 895 acpi_gbl_db_console_debug_level = 896 strtoul(acpi_gbl_db_args[1], NULL, 16); 897 acpi_os_printf 898 ("Debug Level for console output was %8.8X, now %8.8X\n", 899 temp, acpi_gbl_db_console_debug_level); 900 } else { 901 temp = acpi_gbl_db_debug_level; 902 acpi_gbl_db_debug_level = 903 strtoul(acpi_gbl_db_args[1], NULL, 16); 904 acpi_os_printf 905 ("Debug Level for file output was %8.8X, now %8.8X\n", 906 temp, acpi_gbl_db_debug_level); 907 } 908 break; 909 910 case CMD_LIST: 911 912 #ifdef ACPI_DISASSEMBLER 913 acpi_db_disassemble_aml(acpi_gbl_db_args[1], op); 914 #else 915 acpi_os_printf 916 ("The AML Disassembler is not configured/present\n"); 917 #endif 918 break; 919 920 case CMD_LOCKS: 921 922 acpi_db_display_locks(); 923 break; 924 925 case CMD_LOCALS: 926 927 acpi_db_display_locals(); 928 break; 929 930 case CMD_METHODS: 931 932 status = acpi_db_display_objects("METHOD", acpi_gbl_db_args[1]); 933 break; 934 935 case CMD_NAMESPACE: 936 937 acpi_db_dump_namespace(acpi_gbl_db_args[1], 938 acpi_gbl_db_args[2]); 939 break; 940 941 case CMD_NOTIFY: 942 943 temp = strtoul(acpi_gbl_db_args[2], NULL, 0); 944 acpi_db_send_notify(acpi_gbl_db_args[1], temp); 945 break; 946 947 case CMD_OBJECTS: 948 949 acpi_ut_strupr(acpi_gbl_db_args[1]); 950 status = 951 acpi_db_display_objects(acpi_gbl_db_args[1], 952 acpi_gbl_db_args[2]); 953 break; 954 955 case CMD_OSI: 956 957 acpi_db_display_interfaces(acpi_gbl_db_args[1], 958 acpi_gbl_db_args[2]); 959 break; 960 961 case CMD_OWNER: 962 963 acpi_db_dump_namespace_by_owner(acpi_gbl_db_args[1], 964 acpi_gbl_db_args[2]); 965 break; 966 967 case CMD_PATHS: 968 969 acpi_db_dump_namespace_paths(); 970 break; 971 972 case CMD_PREFIX: 973 974 acpi_db_set_scope(acpi_gbl_db_args[1]); 975 break; 976 977 case CMD_REFERENCES: 978 979 acpi_db_find_references(acpi_gbl_db_args[1]); 980 break; 981 982 case CMD_RESOURCES: 983 984 acpi_db_display_resources(acpi_gbl_db_args[1]); 985 break; 986 987 case CMD_RESULTS: 988 989 acpi_db_display_results(); 990 break; 991 992 case CMD_SET: 993 994 acpi_db_set_method_data(acpi_gbl_db_args[1], 995 acpi_gbl_db_args[2], 996 acpi_gbl_db_args[3]); 997 break; 998 999 case CMD_STATS: 1000 1001 status = acpi_db_display_statistics(acpi_gbl_db_args[1]); 1002 break; 1003 1004 case CMD_STOP: 1005 1006 return (AE_NOT_IMPLEMENTED); 1007 1008 case CMD_TABLES: 1009 1010 acpi_db_display_table_info(acpi_gbl_db_args[1]); 1011 break; 1012 1013 case CMD_TEMPLATE: 1014 1015 acpi_db_display_template(acpi_gbl_db_args[1]); 1016 break; 1017 1018 case CMD_TRACE: 1019 1020 acpi_db_trace(acpi_gbl_db_args[1], acpi_gbl_db_args[2], 1021 acpi_gbl_db_args[3]); 1022 break; 1023 1024 case CMD_TREE: 1025 1026 acpi_db_display_calling_tree(); 1027 break; 1028 1029 case CMD_TYPE: 1030 1031 acpi_db_display_object_type(acpi_gbl_db_args[1]); 1032 break; 1033 1034 #ifdef ACPI_APPLICATION 1035 1036 /* Hardware simulation commands. */ 1037 1038 case CMD_ENABLEACPI: 1039 #if (!ACPI_REDUCED_HARDWARE) 1040 1041 status = acpi_enable(); 1042 if (ACPI_FAILURE(status)) { 1043 acpi_os_printf("AcpiEnable failed (Status=%X)\n", 1044 status); 1045 return (status); 1046 } 1047 #endif /* !ACPI_REDUCED_HARDWARE */ 1048 break; 1049 1050 case CMD_EVENT: 1051 1052 acpi_os_printf("Event command not implemented\n"); 1053 break; 1054 1055 case CMD_GPE: 1056 1057 acpi_db_generate_gpe(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); 1058 break; 1059 1060 case CMD_GPES: 1061 1062 acpi_db_display_gpes(); 1063 break; 1064 1065 case CMD_SCI: 1066 1067 acpi_db_generate_sci(); 1068 break; 1069 1070 case CMD_SLEEP: 1071 1072 status = acpi_db_sleep(acpi_gbl_db_args[1]); 1073 break; 1074 1075 /* File I/O commands. */ 1076 1077 case CMD_CLOSE: 1078 1079 acpi_db_close_debug_file(); 1080 break; 1081 1082 case CMD_LOAD:{ 1083 struct acpi_new_table_desc *list_head = NULL; 1084 1085 status = 1086 ac_get_all_tables_from_file(acpi_gbl_db_args[1], 1087 ACPI_GET_ALL_TABLES, 1088 &list_head); 1089 if (ACPI_SUCCESS(status)) { 1090 acpi_db_load_tables(list_head); 1091 } 1092 } 1093 break; 1094 1095 case CMD_OPEN: 1096 1097 acpi_db_open_debug_file(acpi_gbl_db_args[1]); 1098 break; 1099 1100 /* User space commands. */ 1101 1102 case CMD_TERMINATE: 1103 1104 acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); 1105 acpi_ut_subsystem_shutdown(); 1106 1107 /* 1108 * TBD: [Restructure] Need some way to re-initialize without 1109 * re-creating the semaphores! 1110 */ 1111 1112 acpi_gbl_db_terminate_loop = TRUE; 1113 /* acpi_initialize (NULL); */ 1114 break; 1115 1116 case CMD_BACKGROUND: 1117 1118 acpi_db_create_execution_thread(acpi_gbl_db_args[1], 1119 &acpi_gbl_db_args[2], 1120 &acpi_gbl_db_arg_types[2]); 1121 break; 1122 1123 case CMD_THREADS: 1124 1125 acpi_db_create_execution_threads(acpi_gbl_db_args[1], 1126 acpi_gbl_db_args[2], 1127 acpi_gbl_db_args[3]); 1128 break; 1129 1130 /* Debug test commands. */ 1131 1132 case CMD_PREDEFINED: 1133 1134 acpi_db_check_predefined_names(); 1135 break; 1136 1137 case CMD_TEST: 1138 1139 acpi_db_execute_test(acpi_gbl_db_args[1]); 1140 break; 1141 1142 case CMD_UNLOAD: 1143 1144 acpi_db_unload_acpi_table(acpi_gbl_db_args[1]); 1145 break; 1146 #endif 1147 1148 case CMD_EXIT: 1149 case CMD_QUIT: 1150 1151 if (op) { 1152 acpi_os_printf("Method execution terminated\n"); 1153 return (AE_CTRL_TERMINATE); 1154 } 1155 1156 if (!acpi_gbl_db_output_to_file) { 1157 acpi_dbg_level = ACPI_DEBUG_DEFAULT; 1158 } 1159 #ifdef ACPI_APPLICATION 1160 acpi_db_close_debug_file(); 1161 #endif 1162 acpi_gbl_db_terminate_loop = TRUE; 1163 return (AE_CTRL_TERMINATE); 1164 1165 case CMD_NOT_FOUND: 1166 default: 1167 1168 acpi_os_printf("%s: unknown command\n", acpi_gbl_db_args[0]); 1169 return (AE_CTRL_TRUE); 1170 } 1171 1172 if (ACPI_SUCCESS(status)) { 1173 status = AE_CTRL_TRUE; 1174 } 1175 1176 return (status); 1177 } 1178 1179 /******************************************************************************* 1180 * 1181 * FUNCTION: acpi_db_execute_thread 1182 * 1183 * PARAMETERS: context - Not used 1184 * 1185 * RETURN: None 1186 * 1187 * DESCRIPTION: Debugger execute thread. Waits for a command line, then 1188 * simply dispatches it. 1189 * 1190 ******************************************************************************/ 1191 1192 void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context) 1193 { 1194 1195 (void)acpi_db_user_commands(); 1196 acpi_gbl_db_threads_terminated = TRUE; 1197 } 1198 1199 /******************************************************************************* 1200 * 1201 * FUNCTION: acpi_db_user_commands 1202 * 1203 * PARAMETERS: None 1204 * 1205 * RETURN: None 1206 * 1207 * DESCRIPTION: Command line execution for the AML debugger. Commands are 1208 * matched and dispatched here. 1209 * 1210 ******************************************************************************/ 1211 1212 acpi_status acpi_db_user_commands(void) 1213 { 1214 acpi_status status = AE_OK; 1215 1216 acpi_os_printf("\n"); 1217 1218 /* TBD: [Restructure] Need a separate command line buffer for step mode */ 1219 1220 while (!acpi_gbl_db_terminate_loop) { 1221 1222 /* Wait the readiness of the command */ 1223 1224 status = acpi_os_wait_command_ready(); 1225 if (ACPI_FAILURE(status)) { 1226 break; 1227 } 1228 1229 /* Just call to the command line interpreter */ 1230 1231 acpi_gbl_method_executing = FALSE; 1232 acpi_gbl_step_to_next_call = FALSE; 1233 1234 (void)acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, 1235 NULL); 1236 1237 /* Notify the completion of the command */ 1238 1239 status = acpi_os_notify_command_complete(); 1240 if (ACPI_FAILURE(status)) { 1241 break; 1242 } 1243 } 1244 1245 if (ACPI_FAILURE(status) && status != AE_CTRL_TERMINATE) { 1246 ACPI_EXCEPTION((AE_INFO, status, "While parsing command line")); 1247 } 1248 return (status); 1249 } 1250