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