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