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