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