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