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