1 /*******************************************************************************
   2  *
   3  * Module Name: dbinput - user front-end to the AML debugger
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 
  45 #include "acpi.h"
  46 #include "accommon.h"
  47 #include "acdebug.h"
  48 
  49 
  50 #ifdef ACPI_DEBUGGER
  51 
  52 #define _COMPONENT          ACPI_CA_DEBUGGER
  53         ACPI_MODULE_NAME    ("dbinput")
  54 
  55 /* Local prototypes */
  56 
  57 static UINT32
  58 AcpiDbGetLine (
  59     char                    *InputBuffer);
  60 
  61 static UINT32
  62 AcpiDbMatchCommand (
  63     char                    *UserCommand);
  64 
  65 static void
  66 AcpiDbSingleThread (
  67     void);
  68 
  69 static void
  70 AcpiDbDisplayHelp (
  71     void);
  72 
  73 
  74 /*
  75  * Top-level debugger commands.
  76  *
  77  * This list of commands must match the string table below it
  78  */
  79 enum AcpiExDebuggerCommands
  80 {
  81     CMD_NOT_FOUND = 0,
  82     CMD_NULL,
  83     CMD_ALLOCATIONS,
  84     CMD_ARGS,
  85     CMD_ARGUMENTS,
  86     CMD_BATCH,
  87     CMD_BREAKPOINT,
  88     CMD_BUSINFO,
  89     CMD_CALL,
  90     CMD_CLOSE,
  91     CMD_DEBUG,
  92     CMD_DISASSEMBLE,
  93     CMD_DUMP,
  94     CMD_ENABLEACPI,
  95     CMD_EVENT,
  96     CMD_EXECUTE,
  97     CMD_EXIT,
  98     CMD_FIND,
  99     CMD_GO,
 100     CMD_GPE,
 101     CMD_GPES,
 102     CMD_HANDLERS,
 103     CMD_HELP,
 104     CMD_HELP2,
 105     CMD_HISTORY,
 106     CMD_HISTORY_EXE,
 107     CMD_HISTORY_LAST,
 108     CMD_INFORMATION,
 109     CMD_INTEGRITY,
 110     CMD_INTO,
 111     CMD_LEVEL,
 112     CMD_LIST,
 113     CMD_LOAD,
 114     CMD_LOCALS,
 115     CMD_LOCKS,
 116     CMD_METHODS,
 117     CMD_NAMESPACE,
 118     CMD_NOTIFY,
 119     CMD_OBJECT,
 120     CMD_OPEN,
 121     CMD_OSI,
 122     CMD_OWNER,
 123     CMD_PREDEFINED,
 124     CMD_PREFIX,
 125     CMD_QUIT,
 126     CMD_REFERENCES,
 127     CMD_RESOURCES,
 128     CMD_RESULTS,
 129     CMD_SET,
 130     CMD_SLEEP,
 131     CMD_STATS,
 132     CMD_STOP,
 133     CMD_TABLES,
 134     CMD_TERMINATE,
 135     CMD_THREADS,
 136     CMD_TRACE,
 137     CMD_TREE,
 138     CMD_TYPE,
 139     CMD_UNLOAD
 140 };
 141 
 142 #define CMD_FIRST_VALID     2
 143 
 144 
 145 /* Second parameter is the required argument count */
 146 
 147 static const COMMAND_INFO       AcpiGbl_DbCommands[] =
 148 {
 149     {"<NOT FOUND>",  0},
 150     {"<NULL>",       0},
 151     {"ALLOCATIONS",  0},
 152     {"ARGS",         0},
 153     {"ARGUMENTS",    0},
 154     {"BATCH",        0},
 155     {"BREAKPOINT",   1},
 156     {"BUSINFO",      0},
 157     {"CALL",         0},
 158     {"CLOSE",        0},
 159     {"DEBUG",        1},
 160     {"DISASSEMBLE",  1},
 161     {"DUMP",         1},
 162     {"ENABLEACPI",   0},
 163     {"EVENT",        1},
 164     {"EXECUTE",      1},
 165     {"EXIT",         0},
 166     {"FIND",         1},
 167     {"GO",           0},
 168     {"GPE",          2},
 169     {"GPES",         0},
 170     {"HANDLERS",     0},
 171     {"HELP",         0},
 172     {"?",            0},
 173     {"HISTORY",      0},
 174     {"!",            1},
 175     {"!!",           0},
 176     {"INFORMATION",  0},
 177     {"INTEGRITY",    0},
 178     {"INTO",         0},
 179     {"LEVEL",        0},
 180     {"LIST",         0},
 181     {"LOAD",         1},
 182     {"LOCALS",       0},
 183     {"LOCKS",        0},
 184     {"METHODS",      0},
 185     {"NAMESPACE",    0},
 186     {"NOTIFY",       2},
 187     {"OBJECT",       1},
 188     {"OPEN",         1},
 189     {"OSI",          0},
 190     {"OWNER",        1},
 191     {"PREDEFINED",   0},
 192     {"PREFIX",       0},
 193     {"QUIT",         0},
 194     {"REFERENCES",   1},
 195     {"RESOURCES",    1},
 196     {"RESULTS",      0},
 197     {"SET",          3},
 198     {"SLEEP",        1},
 199     {"STATS",        0},
 200     {"STOP",         0},
 201     {"TABLES",       0},
 202     {"TERMINATE",    0},
 203     {"THREADS",      3},
 204     {"TRACE",        1},
 205     {"TREE",         0},
 206     {"TYPE",         1},
 207     {"UNLOAD",       1},
 208     {NULL,           0}
 209 };
 210 
 211 
 212 /*******************************************************************************
 213  *
 214  * FUNCTION:    AcpiDbDisplayHelp
 215  *
 216  * PARAMETERS:  None
 217  *
 218  * RETURN:      None
 219  *
 220  * DESCRIPTION: Print a usage message.
 221  *
 222  ******************************************************************************/
 223 
 224 static void
 225 AcpiDbDisplayHelp (
 226     void)
 227 {
 228 
 229     AcpiOsPrintf ("\nGeneral-Purpose Commands:\n");
 230     AcpiOsPrintf ("  Allocations                         Display list of current memory allocations\n");
 231     AcpiOsPrintf ("  Dump <Address>|<Namepath>\n");
 232     AcpiOsPrintf ("       [Byte|Word|Dword|Qword]        Display ACPI objects or memory\n");
 233     AcpiOsPrintf ("  EnableAcpi                          Enable ACPI (hardware) mode\n");
 234     AcpiOsPrintf ("  Handlers                            Info about global handlers\n");
 235     AcpiOsPrintf ("  Help                                This help screen\n");
 236     AcpiOsPrintf ("  History                             Display command history buffer\n");
 237     AcpiOsPrintf ("  Level [<DebugLevel>] [console]      Get/Set debug level for file or console\n");
 238     AcpiOsPrintf ("  Locks                               Current status of internal mutexes\n");
 239     AcpiOsPrintf ("  Osi [Install|Remove <name>]         Display or modify global _OSI list\n");
 240     AcpiOsPrintf ("  Quit or Exit                        Exit this command\n");
 241     AcpiOsPrintf ("  Stats [Allocations|Memory|Misc|\n");
 242     AcpiOsPrintf ("        Objects|Sizes|Stack|Tables]   Display namespace and memory statistics\n");
 243     AcpiOsPrintf ("     Allocations                      Display list of current memory allocations\n");
 244     AcpiOsPrintf ("     Memory                           Dump internal memory lists\n");
 245     AcpiOsPrintf ("     Misc                             Namespace search and mutex stats\n");
 246     AcpiOsPrintf ("     Objects                          Summary of namespace objects\n");
 247     AcpiOsPrintf ("     Sizes                            Sizes for each of the internal objects\n");
 248     AcpiOsPrintf ("     Stack                            Display CPU stack usage\n");
 249     AcpiOsPrintf ("     Tables                           Info about current ACPI table(s)\n");
 250     AcpiOsPrintf ("  Tables                              Display info about loaded ACPI tables\n");
 251     AcpiOsPrintf ("  Unload <TableSig> [Instance]        Unload an ACPI table\n");
 252     AcpiOsPrintf ("  ! <CommandNumber>                   Execute command from history buffer\n");
 253     AcpiOsPrintf ("  !!                                  Execute last command again\n");
 254 
 255     AcpiOsPrintf ("\nNamespace Access Commands:\n");
 256     AcpiOsPrintf ("  Businfo                             Display system bus info\n");
 257     AcpiOsPrintf ("  Disassemble <Method>                Disassemble a control method\n");
 258     AcpiOsPrintf ("  Event <F|G> <Value>                 Generate AcpiEvent (Fixed/GPE)\n");
 259     AcpiOsPrintf ("  Find <AcpiName>  (? is wildcard)    Find ACPI name(s) with wildcards\n");
 260     AcpiOsPrintf ("  Gpe <GpeNum> <GpeBlock>             Simulate a GPE\n");
 261     AcpiOsPrintf ("  Gpes                                Display info on all GPEs\n");
 262     AcpiOsPrintf ("  Integrity                           Validate namespace integrity\n");
 263     AcpiOsPrintf ("  Methods                             Display list of loaded control methods\n");
 264     AcpiOsPrintf ("  Namespace [Object] [Depth]          Display loaded namespace tree/subtree\n");
 265     AcpiOsPrintf ("  Notify <Object> <Value>             Send a notification on Object\n");
 266     AcpiOsPrintf ("  Objects <ObjectType>                Display all objects of the given type\n");
 267     AcpiOsPrintf ("  Owner <OwnerId> [Depth]             Display loaded namespace by object owner\n");
 268     AcpiOsPrintf ("  Predefined                          Check all predefined names\n");
 269     AcpiOsPrintf ("  Prefix [<NamePath>]                 Set or Get current execution prefix\n");
 270     AcpiOsPrintf ("  References <Addr>                   Find all references to object at addr\n");
 271     AcpiOsPrintf ("  Resources <Device>                  Get and display Device resources\n");
 272     AcpiOsPrintf ("  Set N <NamedObject> <Value>         Set value for named integer\n");
 273     AcpiOsPrintf ("  Sleep <SleepState>                  Simulate sleep/wake sequence\n");
 274     AcpiOsPrintf ("  Terminate                           Delete namespace and all internal objects\n");
 275     AcpiOsPrintf ("  Type <Object>                       Display object type\n");
 276 
 277     AcpiOsPrintf ("\nControl Method Execution Commands:\n");
 278     AcpiOsPrintf ("  Arguments (or Args)                 Display method arguments\n");
 279     AcpiOsPrintf ("  Breakpoint <AmlOffset>              Set an AML execution breakpoint\n");
 280     AcpiOsPrintf ("  Call                                Run to next control method invocation\n");
 281     AcpiOsPrintf ("  Debug <Namepath> [Arguments]        Single Step a control method\n");
 282     AcpiOsPrintf ("  Execute <Namepath> [Arguments]      Execute control method\n");
 283     AcpiOsPrintf ("     Hex Integer                      Integer method argument\n");
 284     AcpiOsPrintf ("     \"Ascii String\"                   String method argument\n");
 285     AcpiOsPrintf ("     (Byte List)                      Buffer method argument\n");
 286     AcpiOsPrintf ("     [Package Element List]           Package method argument\n");
 287     AcpiOsPrintf ("  Go                                  Allow method to run to completion\n");
 288     AcpiOsPrintf ("  Information                         Display info about the current method\n");
 289     AcpiOsPrintf ("  Into                                Step into (not over) a method call\n");
 290     AcpiOsPrintf ("  List [# of Aml Opcodes]             Display method ASL statements\n");
 291     AcpiOsPrintf ("  Locals                              Display method local variables\n");
 292     AcpiOsPrintf ("  Results                             Display method result stack\n");
 293     AcpiOsPrintf ("  Set <A|L> <#> <Value>               Set method data (Arguments/Locals)\n");
 294     AcpiOsPrintf ("  Stop                                Terminate control method\n");
 295     AcpiOsPrintf ("  Thread <Threads><Loops><NamePath>   Spawn threads to execute method(s)\n");
 296     AcpiOsPrintf ("  Trace <method name>                 Trace method execution\n");
 297     AcpiOsPrintf ("  Tree                                Display control method calling tree\n");
 298     AcpiOsPrintf ("  <Enter>                             Single step next AML opcode (over calls)\n");
 299 
 300     AcpiOsPrintf ("\nFile I/O Commands:\n");
 301     AcpiOsPrintf ("  Close                               Close debug output file\n");
 302     AcpiOsPrintf ("  Load <Input Filename>               Load ACPI table from a file\n");
 303     AcpiOsPrintf ("  Open <Output Filename>              Open a file for debug output\n");
 304 }
 305 
 306 
 307 /*******************************************************************************
 308  *
 309  * FUNCTION:    AcpiDbGetNextToken
 310  *
 311  * PARAMETERS:  String          - Command buffer
 312  *              Next            - Return value, end of next token
 313  *
 314  * RETURN:      Pointer to the start of the next token.
 315  *
 316  * DESCRIPTION: Command line parsing.  Get the next token on the command line
 317  *
 318  ******************************************************************************/
 319 
 320 char *
 321 AcpiDbGetNextToken (
 322     char                    *String,
 323     char                    **Next,
 324     ACPI_OBJECT_TYPE        *ReturnType)
 325 {
 326     char                    *Start;
 327     UINT32                  Depth;
 328     ACPI_OBJECT_TYPE        Type = ACPI_TYPE_INTEGER;
 329 
 330 
 331     /* At end of buffer? */
 332 
 333     if (!String || !(*String))
 334     {
 335         return (NULL);
 336     }
 337 
 338     /* Remove any spaces at the beginning */
 339 
 340     if (*String == ' ')
 341     {
 342         while (*String && (*String == ' '))
 343         {
 344             String++;
 345         }
 346 
 347         if (!(*String))
 348         {
 349             return (NULL);
 350         }
 351     }
 352 
 353     switch (*String)
 354     {
 355     case '"':
 356 
 357         /* This is a quoted string, scan until closing quote */
 358 
 359         String++;
 360         Start = String;
 361         Type = ACPI_TYPE_STRING;
 362 
 363         /* Find end of string */
 364 
 365         while (*String && (*String != '"'))
 366         {
 367             String++;
 368         }
 369         break;
 370 
 371     case '(':
 372 
 373         /* This is the start of a buffer, scan until closing paren */
 374 
 375         String++;
 376         Start = String;
 377         Type = ACPI_TYPE_BUFFER;
 378 
 379         /* Find end of buffer */
 380 
 381         while (*String && (*String != ')'))
 382         {
 383             String++;
 384         }
 385         break;
 386 
 387     case '[':
 388 
 389         /* This is the start of a package, scan until closing bracket */
 390 
 391         String++;
 392         Depth = 1;
 393         Start = String;
 394         Type = ACPI_TYPE_PACKAGE;
 395 
 396         /* Find end of package (closing bracket) */
 397 
 398         while (*String)
 399         {
 400             /* Handle String package elements */
 401 
 402             if (*String == '"')
 403             {
 404                 /* Find end of string */
 405 
 406                 String++;
 407                 while (*String && (*String != '"'))
 408                 {
 409                     String++;
 410                 }
 411                 if (!(*String))
 412                 {
 413                     break;
 414                 }
 415             }
 416             else if (*String == '[')
 417             {
 418                 Depth++;         /* A nested package declaration */
 419             }
 420             else if (*String == ']')
 421             {
 422                 Depth--;
 423                 if (Depth == 0) /* Found final package closing bracket */
 424                 {
 425                     break;
 426                 }
 427             }
 428 
 429             String++;
 430         }
 431         break;
 432 
 433     default:
 434 
 435         Start = String;
 436 
 437         /* Find end of token */
 438 
 439         while (*String && (*String != ' '))
 440         {
 441             String++;
 442         }
 443         break;
 444     }
 445 
 446     if (!(*String))
 447     {
 448         *Next = NULL;
 449     }
 450     else
 451     {
 452         *String = 0;
 453         *Next = String + 1;
 454     }
 455 
 456     *ReturnType = Type;
 457     return (Start);
 458 }
 459 
 460 
 461 /*******************************************************************************
 462  *
 463  * FUNCTION:    AcpiDbGetLine
 464  *
 465  * PARAMETERS:  InputBuffer         - Command line buffer
 466  *
 467  * RETURN:      Count of arguments to the command
 468  *
 469  * DESCRIPTION: Get the next command line from the user.  Gets entire line
 470  *              up to the next newline
 471  *
 472  ******************************************************************************/
 473 
 474 static UINT32
 475 AcpiDbGetLine (
 476     char                    *InputBuffer)
 477 {
 478     UINT32                  i;
 479     UINT32                  Count;
 480     char                    *Next;
 481     char                    *This;
 482 
 483 
 484     ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
 485 
 486     This = AcpiGbl_DbParsedBuf;
 487     for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
 488     {
 489         AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next,
 490             &AcpiGbl_DbArgTypes[i]);
 491         if (!AcpiGbl_DbArgs[i])
 492         {
 493             break;
 494         }
 495 
 496         This = Next;
 497     }
 498 
 499     /* Uppercase the actual command */
 500 
 501     if (AcpiGbl_DbArgs[0])
 502     {
 503         AcpiUtStrupr (AcpiGbl_DbArgs[0]);
 504     }
 505 
 506     Count = i;
 507     if (Count)
 508     {
 509         Count--;  /* Number of args only */
 510     }
 511 
 512     return (Count);
 513 }
 514 
 515 
 516 /*******************************************************************************
 517  *
 518  * FUNCTION:    AcpiDbMatchCommand
 519  *
 520  * PARAMETERS:  UserCommand             - User command line
 521  *
 522  * RETURN:      Index into command array, -1 if not found
 523  *
 524  * DESCRIPTION: Search command array for a command match
 525  *
 526  ******************************************************************************/
 527 
 528 static UINT32
 529 AcpiDbMatchCommand (
 530     char                    *UserCommand)
 531 {
 532     UINT32                  i;
 533 
 534 
 535     if (!UserCommand || UserCommand[0] == 0)
 536     {
 537         return (CMD_NULL);
 538     }
 539 
 540     for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
 541     {
 542         if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
 543                          AcpiGbl_DbCommands[i].Name)
 544         {
 545             return (i);
 546         }
 547     }
 548 
 549     /* Command not recognized */
 550 
 551     return (CMD_NOT_FOUND);
 552 }
 553 
 554 
 555 /*******************************************************************************
 556  *
 557  * FUNCTION:    AcpiDbCommandDispatch
 558  *
 559  * PARAMETERS:  InputBuffer         - Command line buffer
 560  *              WalkState           - Current walk
 561  *              Op                  - Current (executing) parse op
 562  *
 563  * RETURN:      Status
 564  *
 565  * DESCRIPTION: Command dispatcher.
 566  *
 567  ******************************************************************************/
 568 
 569 ACPI_STATUS
 570 AcpiDbCommandDispatch (
 571     char                    *InputBuffer,
 572     ACPI_WALK_STATE         *WalkState,
 573     ACPI_PARSE_OBJECT       *Op)
 574 {
 575     UINT32                  Temp;
 576     UINT32                  CommandIndex;
 577     UINT32                  ParamCount;
 578     char                    *CommandLine;
 579     ACPI_STATUS             Status = AE_CTRL_TRUE;
 580 
 581 
 582     /* If AcpiTerminate has been called, terminate this thread */
 583 
 584     if (AcpiGbl_DbTerminateThreads)
 585     {
 586         return (AE_CTRL_TERMINATE);
 587     }
 588 
 589     ParamCount = AcpiDbGetLine (InputBuffer);
 590     CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
 591     Temp = 0;
 592 
 593     /* Verify that we have the minimum number of params */
 594 
 595     if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
 596     {
 597         AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
 598             ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
 599             AcpiGbl_DbCommands[CommandIndex].MinArgs);
 600 
 601         return (AE_CTRL_TRUE);
 602     }
 603 
 604     /* Decode and dispatch the command */
 605 
 606     switch (CommandIndex)
 607     {
 608     case CMD_NULL:
 609         if (Op)
 610         {
 611             return (AE_OK);
 612         }
 613         break;
 614 
 615     case CMD_ALLOCATIONS:
 616 
 617 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
 618         AcpiUtDumpAllocations ((UINT32) -1, NULL);
 619 #endif
 620         break;
 621 
 622     case CMD_ARGS:
 623     case CMD_ARGUMENTS:
 624         AcpiDbDisplayArguments ();
 625         break;
 626 
 627     case CMD_BATCH:
 628         AcpiDbBatchExecute (AcpiGbl_DbArgs[1]);
 629         break;
 630 
 631     case CMD_BREAKPOINT:
 632         AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
 633         break;
 634 
 635     case CMD_BUSINFO:
 636         AcpiDbGetBusInfo ();
 637         break;
 638 
 639     case CMD_CALL:
 640         AcpiDbSetMethodCallBreakpoint (Op);
 641         Status = AE_OK;
 642         break;
 643 
 644     case CMD_CLOSE:
 645         AcpiDbCloseDebugFile ();
 646         break;
 647 
 648     case CMD_DEBUG:
 649         AcpiDbExecute (AcpiGbl_DbArgs[1],
 650             &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP);
 651         break;
 652 
 653     case CMD_DISASSEMBLE:
 654         (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
 655         break;
 656 
 657     case CMD_DUMP:
 658         AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
 659         break;
 660 
 661     case CMD_ENABLEACPI:
 662         Status = AcpiEnable();
 663         if (ACPI_FAILURE(Status))
 664         {
 665             AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
 666             return (Status);
 667         }
 668         break;
 669 
 670     case CMD_EVENT:
 671         AcpiOsPrintf ("Event command not implemented\n");
 672         break;
 673 
 674     case CMD_EXECUTE:
 675         AcpiDbExecute (AcpiGbl_DbArgs[1],
 676             &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP);
 677         break;
 678 
 679     case CMD_FIND:
 680         Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
 681         break;
 682 
 683     case CMD_GO:
 684         AcpiGbl_CmSingleStep = FALSE;
 685         return (AE_OK);
 686 
 687     case CMD_GPE:
 688         AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
 689         break;
 690 
 691     case CMD_GPES:
 692         AcpiDbDisplayGpes ();
 693         break;
 694 
 695     case CMD_HANDLERS:
 696         AcpiDbDisplayHandlers ();
 697         break;
 698 
 699     case CMD_HELP:
 700     case CMD_HELP2:
 701         AcpiDbDisplayHelp ();
 702         break;
 703 
 704     case CMD_HISTORY:
 705         AcpiDbDisplayHistory ();
 706         break;
 707 
 708     case CMD_HISTORY_EXE:
 709         CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
 710         if (!CommandLine)
 711         {
 712             return (AE_CTRL_TRUE);
 713         }
 714 
 715         Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
 716         return (Status);
 717 
 718     case CMD_HISTORY_LAST:
 719         CommandLine = AcpiDbGetFromHistory (NULL);
 720         if (!CommandLine)
 721         {
 722             return (AE_CTRL_TRUE);
 723         }
 724 
 725         Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
 726         return (Status);
 727 
 728     case CMD_INFORMATION:
 729         AcpiDbDisplayMethodInfo (Op);
 730         break;
 731 
 732     case CMD_INTEGRITY:
 733         AcpiDbCheckIntegrity ();
 734         break;
 735 
 736     case CMD_INTO:
 737         if (Op)
 738         {
 739             AcpiGbl_CmSingleStep = TRUE;
 740             return (AE_OK);
 741         }
 742         break;
 743 
 744     case CMD_LEVEL:
 745         if (ParamCount == 0)
 746         {
 747             AcpiOsPrintf ("Current debug level for file output is:    %8.8lX\n",
 748                 AcpiGbl_DbDebugLevel);
 749             AcpiOsPrintf ("Current debug level for console output is: %8.8lX\n",
 750                 AcpiGbl_DbConsoleDebugLevel);
 751         }
 752         else if (ParamCount == 2)
 753         {
 754             Temp = AcpiGbl_DbConsoleDebugLevel;
 755             AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
 756                                             NULL, 16);
 757             AcpiOsPrintf (
 758                 "Debug Level for console output was %8.8lX, now %8.8lX\n",
 759                 Temp, AcpiGbl_DbConsoleDebugLevel);
 760         }
 761         else
 762         {
 763             Temp = AcpiGbl_DbDebugLevel;
 764             AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
 765             AcpiOsPrintf (
 766                 "Debug Level for file output was %8.8lX, now %8.8lX\n",
 767                 Temp, AcpiGbl_DbDebugLevel);
 768         }
 769         break;
 770 
 771     case CMD_LIST:
 772         AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
 773         break;
 774 
 775     case CMD_LOAD:
 776         Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL);
 777         break;
 778 
 779     case CMD_LOCKS:
 780         AcpiDbDisplayLocks ();
 781         break;
 782 
 783     case CMD_LOCALS:
 784         AcpiDbDisplayLocals ();
 785         break;
 786 
 787     case CMD_METHODS:
 788         Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
 789         break;
 790 
 791     case CMD_NAMESPACE:
 792         AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
 793         break;
 794 
 795     case CMD_NOTIFY:
 796         Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
 797         AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
 798         break;
 799 
 800     case CMD_OBJECT:
 801         AcpiUtStrupr (AcpiGbl_DbArgs[1]);
 802         Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
 803         break;
 804 
 805     case CMD_OPEN:
 806         AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
 807         break;
 808 
 809     case CMD_OSI:
 810         AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
 811         break;
 812 
 813     case CMD_OWNER:
 814         AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
 815         break;
 816 
 817     case CMD_PREDEFINED:
 818         AcpiDbCheckPredefinedNames ();
 819         break;
 820 
 821     case CMD_PREFIX:
 822         AcpiDbSetScope (AcpiGbl_DbArgs[1]);
 823         break;
 824 
 825     case CMD_REFERENCES:
 826         AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
 827         break;
 828 
 829     case CMD_RESOURCES:
 830         AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
 831         break;
 832 
 833     case CMD_RESULTS:
 834         AcpiDbDisplayResults ();
 835         break;
 836 
 837     case CMD_SET:
 838         AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
 839             AcpiGbl_DbArgs[3]);
 840         break;
 841 
 842     case CMD_SLEEP:
 843         Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
 844         break;
 845 
 846     case CMD_STATS:
 847         Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
 848         break;
 849 
 850     case CMD_STOP:
 851         return (AE_NOT_IMPLEMENTED);
 852 
 853     case CMD_TABLES:
 854         AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
 855         break;
 856 
 857     case CMD_TERMINATE:
 858         AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
 859         AcpiUtSubsystemShutdown ();
 860 
 861         /*
 862          * TBD: [Restructure] Need some way to re-initialize without
 863          * re-creating the semaphores!
 864          */
 865 
 866         /*  AcpiInitialize (NULL);  */
 867         break;
 868 
 869     case CMD_THREADS:
 870         AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
 871             AcpiGbl_DbArgs[3]);
 872         break;
 873 
 874     case CMD_TRACE:
 875         (void) AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1);
 876         break;
 877 
 878     case CMD_TREE:
 879         AcpiDbDisplayCallingTree ();
 880         break;
 881 
 882     case CMD_TYPE:
 883         AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
 884         break;
 885 
 886     case CMD_UNLOAD:
 887         AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
 888         break;
 889 
 890     case CMD_EXIT:
 891     case CMD_QUIT:
 892         if (Op)
 893         {
 894             AcpiOsPrintf ("Method execution terminated\n");
 895             return (AE_CTRL_TERMINATE);
 896         }
 897 
 898         if (!AcpiGbl_DbOutputToFile)
 899         {
 900             AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
 901         }
 902 
 903         AcpiDbCloseDebugFile ();
 904         AcpiGbl_DbTerminateThreads = TRUE;
 905         return (AE_CTRL_TERMINATE);
 906 
 907     case CMD_NOT_FOUND:
 908     default:
 909         AcpiOsPrintf ("Unknown Command\n");
 910         return (AE_CTRL_TRUE);
 911     }
 912 
 913     if (ACPI_SUCCESS (Status))
 914     {
 915         Status = AE_CTRL_TRUE;
 916     }
 917 
 918     /* Add all commands that come here to the history buffer */
 919 
 920     AcpiDbAddToHistory (InputBuffer);
 921     return (Status);
 922 }
 923 
 924 
 925 /*******************************************************************************
 926  *
 927  * FUNCTION:    AcpiDbExecuteThread
 928  *
 929  * PARAMETERS:  Context         - Not used
 930  *
 931  * RETURN:      None
 932  *
 933  * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
 934  *              simply dispatches it.
 935  *
 936  ******************************************************************************/
 937 
 938 void ACPI_SYSTEM_XFACE
 939 AcpiDbExecuteThread (
 940     void                    *Context)
 941 {
 942     ACPI_STATUS             Status = AE_OK;
 943     ACPI_STATUS             MStatus;
 944 
 945 
 946     while (Status != AE_CTRL_TERMINATE)
 947     {
 948         AcpiGbl_MethodExecuting = FALSE;
 949         AcpiGbl_StepToNextCall = FALSE;
 950 
 951         MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
 952         if (ACPI_FAILURE (MStatus))
 953         {
 954             return;
 955         }
 956 
 957         Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
 958 
 959         MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
 960         if (ACPI_FAILURE (MStatus))
 961         {
 962             return;
 963         }
 964     }
 965 }
 966 
 967 
 968 /*******************************************************************************
 969  *
 970  * FUNCTION:    AcpiDbSingleThread
 971  *
 972  * PARAMETERS:  None
 973  *
 974  * RETURN:      None
 975  *
 976  * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
 977  *              simply dispatches it.
 978  *
 979  ******************************************************************************/
 980 
 981 static void
 982 AcpiDbSingleThread (
 983     void)
 984 {
 985 
 986     AcpiGbl_MethodExecuting = FALSE;
 987     AcpiGbl_StepToNextCall = FALSE;
 988 
 989     (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
 990 }
 991 
 992 
 993 /*******************************************************************************
 994  *
 995  * FUNCTION:    AcpiDbUserCommands
 996  *
 997  * PARAMETERS:  Prompt              - User prompt (depends on mode)
 998  *              Op                  - Current executing parse op
 999  *
1000  * RETURN:      None
1001  *
1002  * DESCRIPTION: Command line execution for the AML debugger.  Commands are
1003  *              matched and dispatched here.
1004  *
1005  ******************************************************************************/
1006 
1007 ACPI_STATUS
1008 AcpiDbUserCommands (
1009     char                    Prompt,
1010     ACPI_PARSE_OBJECT       *Op)
1011 {
1012     ACPI_STATUS             Status = AE_OK;
1013 
1014 
1015     /* TBD: [Restructure] Need a separate command line buffer for step mode */
1016 
1017     while (!AcpiGbl_DbTerminateThreads)
1018     {
1019         /* Force output to console until a command is entered */
1020 
1021         AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1022 
1023         /* Different prompt if method is executing */
1024 
1025         if (!AcpiGbl_MethodExecuting)
1026         {
1027             AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
1028         }
1029         else
1030         {
1031             AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
1032         }
1033 
1034         /* Get the user input line */
1035 
1036         Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
1037             ACPI_DB_LINE_BUFFER_SIZE, NULL);
1038         if (ACPI_FAILURE (Status))
1039         {
1040             ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line"));
1041             return (Status);
1042         }
1043 
1044         /* Check for single or multithreaded debug */
1045 
1046         if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
1047         {
1048             /*
1049              * Signal the debug thread that we have a command to execute,
1050              * and wait for the command to complete.
1051              */
1052             Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
1053             if (ACPI_FAILURE (Status))
1054             {
1055                 return (Status);
1056             }
1057 
1058             Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
1059             if (ACPI_FAILURE (Status))
1060             {
1061                 return (Status);
1062             }
1063         }
1064         else
1065         {
1066             /* Just call to the command line interpreter */
1067 
1068             AcpiDbSingleThread ();
1069         }
1070     }
1071 
1072     /*
1073      * Only this thread (the original thread) should actually terminate the
1074      * subsystem, because all the semaphores are deleted during termination
1075      */
1076     Status = AcpiTerminate ();
1077     return (Status);
1078 }
1079 
1080 #endif  /* ACPI_DEBUGGER */
1081