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