1/*******************************************************************************
2 *
3 * Module Name: dbinput - user front-end to the AML debugger
4 *
5 ******************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 *    notice, this list of conditions, and the following disclaimer,
124 *    without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 *    substantially similar to the "NO WARRANTY" disclaimer below
127 *    ("Disclaimer") and any redistribution must be conditioned upon
128 *    including a substantially similar Disclaimer requirement for further
129 *    binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 *    of any contributors may be used to endorse or promote products derived
132 *    from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152#include <contrib/dev/acpica/include/acpi.h>
153#include <contrib/dev/acpica/include/accommon.h>
154#include <contrib/dev/acpica/include/acdebug.h>
155
156#ifdef ACPI_APPLICATION
157#include <contrib/dev/acpica/include/acapps.h>
158#endif
159
160#define _COMPONENT          ACPI_CA_DEBUGGER
161        ACPI_MODULE_NAME    ("dbinput")
162
163
164/* Local prototypes */
165
166static UINT32
167AcpiDbGetLine (
168    char                    *InputBuffer);
169
170static UINT32
171AcpiDbMatchCommand (
172    char                    *UserCommand);
173
174static void
175AcpiDbDisplayCommandInfo (
176    const char              *Command,
177    BOOLEAN                 DisplayAll);
178
179static void
180AcpiDbDisplayHelp (
181    char                    *Command);
182
183static BOOLEAN
184AcpiDbMatchCommandHelp (
185    const char                  *Command,
186    const ACPI_DB_COMMAND_HELP  *Help);
187
188
189/*
190 * Top-level debugger commands.
191 *
192 * This list of commands must match the string table below it
193 */
194enum AcpiExDebuggerCommands
195{
196    CMD_NOT_FOUND = 0,
197    CMD_NULL,
198    CMD_ALLOCATIONS,
199    CMD_ARGS,
200    CMD_ARGUMENTS,
201    CMD_BREAKPOINT,
202    CMD_BUSINFO,
203    CMD_CALL,
204    CMD_DEBUG,
205    CMD_DISASSEMBLE,
206    CMD_DISASM,
207    CMD_DUMP,
208    CMD_EVALUATE,
209    CMD_EXECUTE,
210    CMD_EXIT,
211    CMD_FIND,
212    CMD_GO,
213    CMD_HANDLERS,
214    CMD_HELP,
215    CMD_HELP2,
216    CMD_HISTORY,
217    CMD_HISTORY_EXE,
218    CMD_HISTORY_LAST,
219    CMD_INFORMATION,
220    CMD_INTEGRITY,
221    CMD_INTO,
222    CMD_LEVEL,
223    CMD_LIST,
224    CMD_LOCALS,
225    CMD_LOCKS,
226    CMD_METHODS,
227    CMD_NAMESPACE,
228    CMD_NOTIFY,
229    CMD_OBJECTS,
230    CMD_OSI,
231    CMD_OWNER,
232    CMD_PATHS,
233    CMD_PREDEFINED,
234    CMD_PREFIX,
235    CMD_QUIT,
236    CMD_REFERENCES,
237    CMD_RESOURCES,
238    CMD_RESULTS,
239    CMD_SET,
240    CMD_STATS,
241    CMD_STOP,
242    CMD_TABLES,
243    CMD_TEMPLATE,
244    CMD_TRACE,
245    CMD_TREE,
246    CMD_TYPE,
247#ifdef ACPI_APPLICATION
248    CMD_ENABLEACPI,
249    CMD_EVENT,
250    CMD_GPE,
251    CMD_GPES,
252    CMD_SCI,
253    CMD_SLEEP,
254
255    CMD_CLOSE,
256    CMD_LOAD,
257    CMD_OPEN,
258    CMD_UNLOAD,
259
260    CMD_TERMINATE,
261    CMD_BACKGROUND,
262    CMD_THREADS,
263
264    CMD_TEST,
265#endif
266};
267
268#define CMD_FIRST_VALID     2
269
270
271/* Second parameter is the required argument count */
272
273static const ACPI_DB_COMMAND_INFO   AcpiGbl_DbCommands[] =
274{
275    {"<NOT FOUND>",  0},
276    {"<NULL>",       0},
277    {"ALLOCATIONS",  0},
278    {"ARGS",         0},
279    {"ARGUMENTS",    0},
280    {"BREAKPOINT",   1},
281    {"BUSINFO",      0},
282    {"CALL",         0},
283    {"DEBUG",        1},
284    {"DISASSEMBLE",  1},
285    {"DISASM",       1},
286    {"DUMP",         1},
287    {"EVALUATE",     1},
288    {"EXECUTE",      1},
289    {"EXIT",         0},
290    {"FIND",         1},
291    {"GO",           0},
292    {"HANDLERS",     0},
293    {"HELP",         0},
294    {"?",            0},
295    {"HISTORY",      0},
296    {"!",            1},
297    {"!!",           0},
298    {"INFORMATION",  0},
299    {"INTEGRITY",    0},
300    {"INTO",         0},
301    {"LEVEL",        0},
302    {"LIST",         0},
303    {"LOCALS",       0},
304    {"LOCKS",        0},
305    {"METHODS",      0},
306    {"NAMESPACE",    0},
307    {"NOTIFY",       2},
308    {"OBJECTS",      0},
309    {"OSI",          0},
310    {"OWNER",        1},
311    {"PATHS",        0},
312    {"PREDEFINED",   0},
313    {"PREFIX",       0},
314    {"QUIT",         0},
315    {"REFERENCES",   1},
316    {"RESOURCES",    0},
317    {"RESULTS",      0},
318    {"SET",          3},
319    {"STATS",        1},
320    {"STOP",         0},
321    {"TABLES",       0},
322    {"TEMPLATE",     1},
323    {"TRACE",        1},
324    {"TREE",         0},
325    {"TYPE",         1},
326#ifdef ACPI_APPLICATION
327    {"ENABLEACPI",   0},
328    {"EVENT",        1},
329    {"GPE",          1},
330    {"GPES",         0},
331    {"SCI",          0},
332    {"SLEEP",        0},
333
334    {"CLOSE",        0},
335    {"LOAD",         1},
336    {"OPEN",         1},
337    {"UNLOAD",       1},
338
339    {"TERMINATE",    0},
340    {"BACKGROUND",   1},
341    {"THREADS",      3},
342
343    {"TEST",         1},
344#endif
345    {NULL,           0}
346};
347
348/*
349 * Help for all debugger commands. First argument is the number of lines
350 * of help to output for the command.
351 *
352 * Note: Some commands are not supported by the kernel-level version of
353 * the debugger.
354 */
355static const ACPI_DB_COMMAND_HELP   AcpiGbl_DbCommandHelp[] =
356{
357    {0, "\nNamespace Access:",                  "\n"},
358    {1, "  Businfo",                            "Display system bus info\n"},
359    {1, "  Disassemble <Method>",               "Disassemble a control method\n"},
360    {1, "  Find <AcpiName> (? is wildcard)",    "Find ACPI name(s) with wildcards\n"},
361    {1, "  Integrity",                          "Validate namespace integrity\n"},
362    {1, "  Methods",                            "Display list of loaded control methods\n"},
363    {1, "  Namespace [Object] [Depth]",         "Display loaded namespace tree/subtree\n"},
364    {1, "  Notify <Object> <Value>",            "Send a notification on Object\n"},
365    {1, "  Objects [ObjectType]",               "Display summary of all objects or just given type\n"},
366    {1, "  Owner <OwnerId> [Depth]",            "Display loaded namespace by object owner\n"},
367    {1, "  Paths",                              "Display full pathnames of namespace objects\n"},
368    {1, "  Predefined",                         "Check all predefined names\n"},
369    {1, "  Prefix [<Namepath>]",                "Set or Get current execution prefix\n"},
370    {1, "  References <Addr>",                  "Find all references to object at addr\n"},
371    {1, "  Resources [DeviceName]",             "Display Device resources (no arg = all devices)\n"},
372    {1, "  Set N <NamedObject> <Value>",        "Set value for named integer\n"},
373    {1, "  Template <Object>",                  "Format/dump a Buffer/ResourceTemplate\n"},
374    {1, "  Type <Object>",                      "Display object type\n"},
375
376    {0, "\nControl Method Execution:",          "\n"},
377    {1, "  Evaluate <Namepath> [Arguments]",    "Evaluate object or control method\n"},
378    {1, "  Execute <Namepath> [Arguments]",     "Synonym for Evaluate\n"},
379#ifdef ACPI_APPLICATION
380    {1, "  Background <Namepath> [Arguments]",  "Evaluate object/method in a separate thread\n"},
381    {1, "  Thread <Threads><Loops><NamePath>",  "Spawn threads to execute method(s)\n"},
382#endif
383    {1, "  Debug <Namepath> [Arguments]",       "Single-Step a control method\n"},
384    {7, "  [Arguments] formats:",               "Control method argument formats\n"},
385    {1, "     Hex Integer",                     "Integer\n"},
386    {1, "     \"Ascii String\"",                "String\n"},
387    {1, "     (Hex Byte List)",                 "Buffer\n"},
388    {1, "         (01 42 7A BF)",               "Buffer example (4 bytes)\n"},
389    {1, "     [Package Element List]",          "Package\n"},
390    {1, "         [0x01 0x1234 \"string\"]",    "Package example (3 elements)\n"},
391
392    {0, "\nMiscellaneous:",                     "\n"},
393    {1, "  Allocations",                        "Display list of current memory allocations\n"},
394    {2, "  Dump <Address>|<Namepath>",          "\n"},
395    {0, "       [Byte|Word|Dword|Qword]",       "Display ACPI objects or memory\n"},
396    {1, "  Handlers",                           "Info about global handlers\n"},
397    {1, "  Help [Command]",                     "This help screen or individual command\n"},
398    {1, "  History",                            "Display command history buffer\n"},
399    {1, "  Level <DebugLevel>] [console]",      "Get/Set debug level for file or console\n"},
400    {1, "  Locks",                              "Current status of internal mutexes\n"},
401    {1, "  Osi [Install|Remove <name>]",        "Display or modify global _OSI list\n"},
402    {1, "  Quit or Exit",                       "Exit this command\n"},
403    {8, "  Stats <SubCommand>",                 "Display namespace and memory statistics\n"},
404    {1, "     Allocations",                     "Display list of current memory allocations\n"},
405    {1, "     Memory",                          "Dump internal memory lists\n"},
406    {1, "     Misc",                            "Namespace search and mutex stats\n"},
407    {1, "     Objects",                         "Summary of namespace objects\n"},
408    {1, "     Sizes",                           "Sizes for each of the internal objects\n"},
409    {1, "     Stack",                           "Display CPU stack usage\n"},
410    {1, "     Tables",                          "Info about current ACPI table(s)\n"},
411    {1, "  Tables",                             "Display info about loaded ACPI tables\n"},
412#ifdef ACPI_APPLICATION
413    {1, "  Terminate",                          "Delete namespace and all internal objects\n"},
414#endif
415    {1, "  ! <CommandNumber>",                  "Execute command from history buffer\n"},
416    {1, "  !!",                                 "Execute last command again\n"},
417
418    {0, "\nMethod and Namespace Debugging:",    "\n"},
419    {5, "  Trace <State> [<Namepath>] [Once]",  "Trace control method execution\n"},
420    {1, "     Enable",                          "Enable all messages\n"},
421    {1, "     Disable",                         "Disable tracing\n"},
422    {1, "     Method",                          "Enable method execution messages\n"},
423    {1, "     Opcode",                          "Enable opcode execution messages\n"},
424    {3, "  Test <TestName>",                    "Invoke a debug test\n"},
425    {1, "     Objects",                         "Read/write/compare all namespace data objects\n"},
426    {1, "     Predefined",                      "Validate all ACPI predefined names (_STA, etc.)\n"},
427    {1, "  Execute predefined",                 "Execute all predefined (public) methods\n"},
428
429    {0, "\nControl Method Single-Step Execution:","\n"},
430    {1, "  Arguments (or Args)",                "Display method arguments\n"},
431    {1, "  Breakpoint <AmlOffset>",             "Set an AML execution breakpoint\n"},
432    {1, "  Call",                               "Run to next control method invocation\n"},
433    {1, "  Go",                                 "Allow method to run to completion\n"},
434    {1, "  Information",                        "Display info about the current method\n"},
435    {1, "  Into",                               "Step into (not over) a method call\n"},
436    {1, "  List [# of Aml Opcodes]",            "Display method ASL statements\n"},
437    {1, "  Locals",                             "Display method local variables\n"},
438    {1, "  Results",                            "Display method result stack\n"},
439    {1, "  Set <A|L> <#> <Value>",              "Set method data (Arguments/Locals)\n"},
440    {1, "  Stop",                               "Terminate control method\n"},
441    {1, "  Tree",                               "Display control method calling tree\n"},
442    {1, "  <Enter>",                            "Single step next AML opcode (over calls)\n"},
443
444#ifdef ACPI_APPLICATION
445    {0, "\nFile Operations:",                   "\n"},
446    {1, "  Close",                              "Close debug output file\n"},
447    {1, "  Load <Input Filename>",              "Load ACPI table from a file\n"},
448    {1, "  Open <Output Filename>",             "Open a file for debug output\n"},
449    {1, "  Unload <Namepath>",                  "Unload an ACPI table via namespace object\n"},
450
451    {0, "\nHardware Simulation:",               "\n"},
452    {1, "  EnableAcpi",                         "Enable ACPI (hardware) mode\n"},
453    {1, "  Event <F|G> <Value>",                "Generate AcpiEvent (Fixed/GPE)\n"},
454    {1, "  Gpe <GpeNum> [GpeBlockDevice]",      "Simulate a GPE\n"},
455    {1, "  Gpes",                               "Display info on all GPE devices\n"},
456    {1, "  Sci",                                "Generate an SCI\n"},
457    {1, "  Sleep [SleepState]",                 "Simulate sleep/wake sequence(s) (0-5)\n"},
458#endif
459    {0, NULL, NULL}
460};
461
462
463/*******************************************************************************
464 *
465 * FUNCTION:    AcpiDbMatchCommandHelp
466 *
467 * PARAMETERS:  Command             - Command string to match
468 *              Help                - Help table entry to attempt match
469 *
470 * RETURN:      TRUE if command matched, FALSE otherwise
471 *
472 * DESCRIPTION: Attempt to match a command in the help table in order to
473 *              print help information for a single command.
474 *
475 ******************************************************************************/
476
477static BOOLEAN
478AcpiDbMatchCommandHelp (
479    const char                  *Command,
480    const ACPI_DB_COMMAND_HELP  *Help)
481{
482    char                    *Invocation = Help->Invocation;
483    UINT32                  LineCount;
484
485
486    /* Valid commands in the help table begin with a couple of spaces */
487
488    if (*Invocation != ' ')
489    {
490        return (FALSE);
491    }
492
493    while (*Invocation == ' ')
494    {
495        Invocation++;
496    }
497
498    /* Match command name (full command or substring) */
499
500    while ((*Command) && (*Invocation) && (*Invocation != ' '))
501    {
502        if (tolower ((int) *Command) != tolower ((int) *Invocation))
503        {
504            return (FALSE);
505        }
506
507        Invocation++;
508        Command++;
509    }
510
511    /* Print the appropriate number of help lines */
512
513    LineCount = Help->LineCount;
514    while (LineCount)
515    {
516        AcpiOsPrintf ("%-38s : %s", Help->Invocation, Help->Description);
517        Help++;
518        LineCount--;
519    }
520
521    return (TRUE);
522}
523
524
525/*******************************************************************************
526 *
527 * FUNCTION:    AcpiDbDisplayCommandInfo
528 *
529 * PARAMETERS:  Command             - Command string to match
530 *              DisplayAll          - Display all matching commands, or just
531 *                                    the first one (substring match)
532 *
533 * RETURN:      None
534 *
535 * DESCRIPTION: Display help information for a Debugger command.
536 *
537 ******************************************************************************/
538
539static void
540AcpiDbDisplayCommandInfo (
541    const char              *Command,
542    BOOLEAN                 DisplayAll)
543{
544    const ACPI_DB_COMMAND_HELP  *Next;
545    BOOLEAN                     Matched;
546
547
548    Next = AcpiGbl_DbCommandHelp;
549    while (Next->Invocation)
550    {
551        Matched = AcpiDbMatchCommandHelp (Command, Next);
552        if (!DisplayAll && Matched)
553        {
554            return;
555        }
556
557        Next++;
558    }
559}
560
561
562/*******************************************************************************
563 *
564 * FUNCTION:    AcpiDbDisplayHelp
565 *
566 * PARAMETERS:  Command             - Optional command string to display help.
567 *                                    if not specified, all debugger command
568 *                                    help strings are displayed
569 *
570 * RETURN:      None
571 *
572 * DESCRIPTION: Display help for a single debugger command, or all of them.
573 *
574 ******************************************************************************/
575
576static void
577AcpiDbDisplayHelp (
578    char                    *Command)
579{
580    const ACPI_DB_COMMAND_HELP  *Next = AcpiGbl_DbCommandHelp;
581
582
583    if (!Command)
584    {
585        /* No argument to help, display help for all commands */
586
587        AcpiOsPrintf ("\nSummary of AML Debugger Commands\n\n");
588
589        while (Next->Invocation)
590        {
591            AcpiOsPrintf ("%-38s%s", Next->Invocation, Next->Description);
592            Next++;
593        }
594        AcpiOsPrintf ("\n");
595
596    }
597    else
598    {
599        /* Display help for all commands that match the subtring */
600
601        AcpiDbDisplayCommandInfo (Command, TRUE);
602    }
603}
604
605
606/*******************************************************************************
607 *
608 * FUNCTION:    AcpiDbGetNextToken
609 *
610 * PARAMETERS:  String          - Command buffer
611 *              Next            - Return value, end of next token
612 *
613 * RETURN:      Pointer to the start of the next token.
614 *
615 * DESCRIPTION: Command line parsing. Get the next token on the command line
616 *
617 ******************************************************************************/
618
619char *
620AcpiDbGetNextToken (
621    char                    *String,
622    char                    **Next,
623    ACPI_OBJECT_TYPE        *ReturnType)
624{
625    char                    *Start;
626    UINT32                  Depth;
627    ACPI_OBJECT_TYPE        Type = ACPI_TYPE_INTEGER;
628
629
630    /* At end of buffer? */
631
632    if (!String || !(*String))
633    {
634        return (NULL);
635    }
636
637    /* Remove any spaces at the beginning */
638
639    if (*String == ' ')
640    {
641        while (*String && (*String == ' '))
642        {
643            String++;
644        }
645
646        if (!(*String))
647        {
648            return (NULL);
649        }
650    }
651
652    switch (*String)
653    {
654    case '"':
655
656        /* This is a quoted string, scan until closing quote */
657
658        String++;
659        Start = String;
660        Type = ACPI_TYPE_STRING;
661
662        /* Find end of string */
663
664        while (*String && (*String != '"'))
665        {
666            String++;
667        }
668        break;
669
670    case '(':
671
672        /* This is the start of a buffer, scan until closing paren */
673
674        String++;
675        Start = String;
676        Type = ACPI_TYPE_BUFFER;
677
678        /* Find end of buffer */
679
680        while (*String && (*String != ')'))
681        {
682            String++;
683        }
684        break;
685
686    case '[':
687
688        /* This is the start of a package, scan until closing bracket */
689
690        String++;
691        Depth = 1;
692        Start = String;
693        Type = ACPI_TYPE_PACKAGE;
694
695        /* Find end of package (closing bracket) */
696
697        while (*String)
698        {
699            /* Handle String package elements */
700
701            if (*String == '"')
702            {
703                /* Find end of string */
704
705                String++;
706                while (*String && (*String != '"'))
707                {
708                    String++;
709                }
710                if (!(*String))
711                {
712                    break;
713                }
714            }
715            else if (*String == '[')
716            {
717                Depth++;         /* A nested package declaration */
718            }
719            else if (*String == ']')
720            {
721                Depth--;
722                if (Depth == 0) /* Found final package closing bracket */
723                {
724                    break;
725                }
726            }
727
728            String++;
729        }
730        break;
731
732    default:
733
734        Start = String;
735
736        /* Find end of token */
737
738        while (*String && (*String != ' '))
739        {
740            String++;
741        }
742        break;
743    }
744
745    if (!(*String))
746    {
747        *Next = NULL;
748    }
749    else
750    {
751        *String = 0;
752        *Next = String + 1;
753    }
754
755    *ReturnType = Type;
756    return (Start);
757}
758
759
760/*******************************************************************************
761 *
762 * FUNCTION:    AcpiDbGetLine
763 *
764 * PARAMETERS:  InputBuffer         - Command line buffer
765 *
766 * RETURN:      Count of arguments to the command
767 *
768 * DESCRIPTION: Get the next command line from the user. Gets entire line
769 *              up to the next newline
770 *
771 ******************************************************************************/
772
773static UINT32
774AcpiDbGetLine (
775    char                    *InputBuffer)
776{
777    UINT32                  i;
778    UINT32                  Count;
779    char                    *Next;
780    char                    *This;
781
782
783    if (AcpiUtSafeStrcpy (AcpiGbl_DbParsedBuf, sizeof (AcpiGbl_DbParsedBuf),
784        InputBuffer))
785    {
786        AcpiOsPrintf (
787            "Buffer overflow while parsing input line (max %u characters)\n",
788            sizeof (AcpiGbl_DbParsedBuf));
789        return (0);
790    }
791
792    This = AcpiGbl_DbParsedBuf;
793    for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
794    {
795        AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next,
796            &AcpiGbl_DbArgTypes[i]);
797        if (!AcpiGbl_DbArgs[i])
798        {
799            break;
800        }
801
802        This = Next;
803    }
804
805    /* Uppercase the actual command */
806
807    AcpiUtStrupr (AcpiGbl_DbArgs[0]);
808
809    Count = i;
810    if (Count)
811    {
812        Count--;  /* Number of args only */
813    }
814
815    return (Count);
816}
817
818
819/*******************************************************************************
820 *
821 * FUNCTION:    AcpiDbMatchCommand
822 *
823 * PARAMETERS:  UserCommand             - User command line
824 *
825 * RETURN:      Index into command array, -1 if not found
826 *
827 * DESCRIPTION: Search command array for a command match
828 *
829 ******************************************************************************/
830
831static UINT32
832AcpiDbMatchCommand (
833    char                    *UserCommand)
834{
835    UINT32                  i;
836
837
838    if (!UserCommand || UserCommand[0] == 0)
839    {
840        return (CMD_NULL);
841    }
842
843    for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
844    {
845        if (strstr (
846            ACPI_CAST_PTR (char, AcpiGbl_DbCommands[i].Name), UserCommand) ==
847            AcpiGbl_DbCommands[i].Name)
848        {
849            return (i);
850        }
851    }
852
853    /* Command not recognized */
854
855    return (CMD_NOT_FOUND);
856}
857
858
859/*******************************************************************************
860 *
861 * FUNCTION:    AcpiDbCommandDispatch
862 *
863 * PARAMETERS:  InputBuffer         - Command line buffer
864 *              WalkState           - Current walk
865 *              Op                  - Current (executing) parse op
866 *
867 * RETURN:      Status
868 *
869 * DESCRIPTION: Command dispatcher.
870 *
871 ******************************************************************************/
872
873ACPI_STATUS
874AcpiDbCommandDispatch (
875    char                    *InputBuffer,
876    ACPI_WALK_STATE         *WalkState,
877    ACPI_PARSE_OBJECT       *Op)
878{
879    UINT32                  Temp;
880    UINT32                  CommandIndex;
881    UINT32                  ParamCount;
882    char                    *CommandLine;
883    ACPI_STATUS             Status = AE_CTRL_TRUE;
884
885
886    /* If AcpiTerminate has been called, terminate this thread */
887
888    if (AcpiGbl_DbTerminateLoop)
889    {
890        return (AE_CTRL_TERMINATE);
891    }
892
893    /* Find command and add to the history buffer */
894
895    ParamCount = AcpiDbGetLine (InputBuffer);
896    CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
897    Temp = 0;
898
899    /*
900     * We don't want to add the !! command to the history buffer. It
901     * would cause an infinite loop because it would always be the
902     * previous command.
903     */
904    if (CommandIndex != CMD_HISTORY_LAST)
905    {
906        AcpiDbAddToHistory (InputBuffer);
907    }
908
909    /* Verify that we have the minimum number of params */
910
911    if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
912    {
913        AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
914            ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
915            AcpiGbl_DbCommands[CommandIndex].MinArgs);
916
917        AcpiDbDisplayCommandInfo (
918            AcpiGbl_DbCommands[CommandIndex].Name, FALSE);
919        return (AE_CTRL_TRUE);
920    }
921
922    /* Decode and dispatch the command */
923
924    switch (CommandIndex)
925    {
926    case CMD_NULL:
927
928        if (Op)
929        {
930            return (AE_OK);
931        }
932        break;
933
934    case CMD_ALLOCATIONS:
935
936#ifdef ACPI_DBG_TRACK_ALLOCATIONS
937        AcpiUtDumpAllocations ((UINT32) -1, NULL);
938#endif
939        break;
940
941    case CMD_ARGS:
942    case CMD_ARGUMENTS:
943
944        AcpiDbDisplayArguments ();
945        break;
946
947    case CMD_BREAKPOINT:
948
949        AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
950        break;
951
952    case CMD_BUSINFO:
953
954        AcpiDbGetBusInfo ();
955        break;
956
957    case CMD_CALL:
958
959        AcpiDbSetMethodCallBreakpoint (Op);
960        Status = AE_OK;
961        break;
962
963    case CMD_DEBUG:
964
965        AcpiDbExecute (AcpiGbl_DbArgs[1],
966            &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP);
967        break;
968
969    case CMD_DISASSEMBLE:
970    case CMD_DISASM:
971
972        (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
973        break;
974
975    case CMD_DUMP:
976
977        AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
978        break;
979
980    case CMD_EVALUATE:
981    case CMD_EXECUTE:
982
983        AcpiDbExecute (AcpiGbl_DbArgs[1],
984            &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP);
985        break;
986
987    case CMD_FIND:
988
989        Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
990        break;
991
992    case CMD_GO:
993
994        AcpiGbl_CmSingleStep = FALSE;
995        return (AE_OK);
996
997    case CMD_HANDLERS:
998
999        AcpiDbDisplayHandlers ();
1000        break;
1001
1002    case CMD_HELP:
1003    case CMD_HELP2:
1004
1005        AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]);
1006        break;
1007
1008    case CMD_HISTORY:
1009
1010        AcpiDbDisplayHistory ();
1011        break;
1012
1013    case CMD_HISTORY_EXE: /* ! command */
1014
1015        CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
1016        if (!CommandLine)
1017        {
1018            return (AE_CTRL_TRUE);
1019        }
1020
1021        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
1022        return (Status);
1023
1024    case CMD_HISTORY_LAST: /* !! command */
1025
1026        CommandLine = AcpiDbGetFromHistory (NULL);
1027        if (!CommandLine)
1028        {
1029            return (AE_CTRL_TRUE);
1030        }
1031
1032        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
1033        return (Status);
1034
1035    case CMD_INFORMATION:
1036
1037        AcpiDbDisplayMethodInfo (Op);
1038        break;
1039
1040    case CMD_INTEGRITY:
1041
1042        AcpiDbCheckIntegrity ();
1043        break;
1044
1045    case CMD_INTO:
1046
1047        if (Op)
1048        {
1049            AcpiGbl_CmSingleStep = TRUE;
1050            return (AE_OK);
1051        }
1052        break;
1053
1054    case CMD_LEVEL:
1055
1056        if (ParamCount == 0)
1057        {
1058            AcpiOsPrintf (
1059                "Current debug level for file output is:    %8.8lX\n",
1060                AcpiGbl_DbDebugLevel);
1061            AcpiOsPrintf (
1062                "Current debug level for console output is: %8.8lX\n",
1063                AcpiGbl_DbConsoleDebugLevel);
1064        }
1065        else if (ParamCount == 2)
1066        {
1067            Temp = AcpiGbl_DbConsoleDebugLevel;
1068            AcpiGbl_DbConsoleDebugLevel =
1069                strtoul (AcpiGbl_DbArgs[1], NULL, 16);
1070            AcpiOsPrintf (
1071                "Debug Level for console output was %8.8lX, now %8.8lX\n",
1072                Temp, AcpiGbl_DbConsoleDebugLevel);
1073        }
1074        else
1075        {
1076            Temp = AcpiGbl_DbDebugLevel;
1077            AcpiGbl_DbDebugLevel = strtoul (AcpiGbl_DbArgs[1], NULL, 16);
1078            AcpiOsPrintf (
1079                "Debug Level for file output was %8.8lX, now %8.8lX\n",
1080                Temp, AcpiGbl_DbDebugLevel);
1081        }
1082        break;
1083
1084    case CMD_LIST:
1085
1086        AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
1087        break;
1088
1089    case CMD_LOCKS:
1090
1091        AcpiDbDisplayLocks ();
1092        break;
1093
1094    case CMD_LOCALS:
1095
1096        AcpiDbDisplayLocals ();
1097        break;
1098
1099    case CMD_METHODS:
1100
1101        Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
1102        break;
1103
1104    case CMD_NAMESPACE:
1105
1106        AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
1107        break;
1108
1109    case CMD_NOTIFY:
1110
1111        Temp = strtoul (AcpiGbl_DbArgs[2], NULL, 0);
1112        AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
1113        break;
1114
1115    case CMD_OBJECTS:
1116
1117        AcpiUtStrupr (AcpiGbl_DbArgs[1]);
1118        Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
1119        break;
1120
1121    case CMD_OSI:
1122
1123        AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
1124        break;
1125
1126    case CMD_OWNER:
1127
1128        AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
1129        break;
1130
1131    case CMD_PATHS:
1132
1133        AcpiDbDumpNamespacePaths ();
1134        break;
1135
1136    case CMD_PREFIX:
1137
1138        AcpiDbSetScope (AcpiGbl_DbArgs[1]);
1139        break;
1140
1141    case CMD_REFERENCES:
1142
1143        AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
1144        break;
1145
1146    case CMD_RESOURCES:
1147
1148        AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
1149        break;
1150
1151    case CMD_RESULTS:
1152
1153        AcpiDbDisplayResults ();
1154        break;
1155
1156    case CMD_SET:
1157
1158        AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
1159            AcpiGbl_DbArgs[3]);
1160        break;
1161
1162    case CMD_STATS:
1163
1164        Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
1165        break;
1166
1167    case CMD_STOP:
1168
1169        return (AE_NOT_IMPLEMENTED);
1170
1171    case CMD_TABLES:
1172
1173        AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
1174        break;
1175
1176    case CMD_TEMPLATE:
1177
1178        AcpiDbDisplayTemplate (AcpiGbl_DbArgs[1]);
1179        break;
1180
1181    case CMD_TRACE:
1182
1183        AcpiDbTrace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]);
1184        break;
1185
1186    case CMD_TREE:
1187
1188        AcpiDbDisplayCallingTree ();
1189        break;
1190
1191    case CMD_TYPE:
1192
1193        AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
1194        break;
1195
1196#ifdef ACPI_APPLICATION
1197
1198    /* Hardware simulation commands. */
1199
1200    case CMD_ENABLEACPI:
1201#if (!ACPI_REDUCED_HARDWARE)
1202
1203        Status = AcpiEnable();
1204        if (ACPI_FAILURE(Status))
1205        {
1206            AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
1207            return (Status);
1208        }
1209#endif /* !ACPI_REDUCED_HARDWARE */
1210        break;
1211
1212    case CMD_EVENT:
1213
1214        AcpiOsPrintf ("Event command not implemented\n");
1215        break;
1216
1217    case CMD_GPE:
1218
1219        AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
1220        break;
1221
1222    case CMD_GPES:
1223
1224        AcpiDbDisplayGpes ();
1225        break;
1226
1227    case CMD_SCI:
1228
1229        AcpiDbGenerateSci ();
1230        break;
1231
1232    case CMD_SLEEP:
1233
1234        Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
1235        break;
1236
1237    /* File I/O commands. */
1238
1239    case CMD_CLOSE:
1240
1241        AcpiDbCloseDebugFile ();
1242        break;
1243
1244    case CMD_LOAD:
1245        {
1246            ACPI_NEW_TABLE_DESC     *ListHead = NULL;
1247
1248            Status = AcGetAllTablesFromFile (AcpiGbl_DbArgs[1],
1249                ACPI_GET_ALL_TABLES, &ListHead);
1250            if (ACPI_SUCCESS (Status))
1251            {
1252                AcpiDbLoadTables (ListHead);
1253            }
1254        }
1255        break;
1256
1257    case CMD_OPEN:
1258
1259        AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
1260        break;
1261
1262    /* User space commands. */
1263
1264    case CMD_TERMINATE:
1265
1266        AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1267        AcpiUtSubsystemShutdown ();
1268
1269        /*
1270         * TBD: [Restructure] Need some way to re-initialize without
1271         * re-creating the semaphores!
1272         */
1273
1274        AcpiGbl_DbTerminateLoop = TRUE;
1275        /*  AcpiInitialize (NULL);  */
1276        break;
1277
1278    case CMD_BACKGROUND:
1279
1280        AcpiDbCreateExecutionThread (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2],
1281            &AcpiGbl_DbArgTypes[2]);
1282        break;
1283
1284    case CMD_THREADS:
1285
1286        AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
1287            AcpiGbl_DbArgs[3]);
1288        break;
1289
1290    /* Debug test commands. */
1291
1292    case CMD_PREDEFINED:
1293
1294        AcpiDbCheckPredefinedNames ();
1295        break;
1296
1297    case CMD_TEST:
1298
1299        AcpiDbExecuteTest (AcpiGbl_DbArgs[1]);
1300        break;
1301
1302    case CMD_UNLOAD:
1303
1304        AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1]);
1305        break;
1306#endif
1307
1308    case CMD_EXIT:
1309    case CMD_QUIT:
1310
1311        if (Op)
1312        {
1313            AcpiOsPrintf ("Method execution terminated\n");
1314            return (AE_CTRL_TERMINATE);
1315        }
1316
1317        if (!AcpiGbl_DbOutputToFile)
1318        {
1319            AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
1320        }
1321
1322#ifdef ACPI_APPLICATION
1323        AcpiDbCloseDebugFile ();
1324#endif
1325        AcpiGbl_DbTerminateLoop = TRUE;
1326        return (AE_CTRL_TERMINATE);
1327
1328    case CMD_NOT_FOUND:
1329    default:
1330
1331        AcpiOsPrintf ("%s: unknown command\n", AcpiGbl_DbArgs[0]);
1332        return (AE_CTRL_TRUE);
1333    }
1334
1335    if (ACPI_SUCCESS (Status))
1336    {
1337        Status = AE_CTRL_TRUE;
1338    }
1339
1340    return (Status);
1341}
1342
1343
1344/*******************************************************************************
1345 *
1346 * FUNCTION:    AcpiDbExecuteThread
1347 *
1348 * PARAMETERS:  Context         - Not used
1349 *
1350 * RETURN:      None
1351 *
1352 * DESCRIPTION: Debugger execute thread. Waits for a command line, then
1353 *              simply dispatches it.
1354 *
1355 ******************************************************************************/
1356
1357void ACPI_SYSTEM_XFACE
1358AcpiDbExecuteThread (
1359    void                    *Context)
1360{
1361
1362    (void) AcpiDbUserCommands ();
1363    AcpiGbl_DbThreadsTerminated = TRUE;
1364}
1365
1366
1367/*******************************************************************************
1368 *
1369 * FUNCTION:    AcpiDbUserCommands
1370 *
1371 * PARAMETERS:  None
1372 *
1373 * RETURN:      None
1374 *
1375 * DESCRIPTION: Command line execution for the AML debugger. Commands are
1376 *              matched and dispatched here.
1377 *
1378 ******************************************************************************/
1379
1380ACPI_STATUS
1381AcpiDbUserCommands (
1382    void)
1383{
1384    ACPI_STATUS             Status = AE_OK;
1385
1386
1387    AcpiOsPrintf ("\n");
1388
1389    /* TBD: [Restructure] Need a separate command line buffer for step mode */
1390
1391    while (!AcpiGbl_DbTerminateLoop)
1392    {
1393        /* Wait the readiness of the command */
1394
1395        Status = AcpiOsWaitCommandReady ();
1396        if (ACPI_FAILURE (Status))
1397        {
1398            break;
1399        }
1400
1401        /* Just call to the command line interpreter */
1402
1403        AcpiGbl_MethodExecuting = FALSE;
1404        AcpiGbl_StepToNextCall = FALSE;
1405
1406        (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
1407
1408        /* Notify the completion of the command */
1409
1410        Status = AcpiOsNotifyCommandComplete ();
1411        if (ACPI_FAILURE (Status))
1412        {
1413            break;
1414        }
1415    }
1416
1417    if (ACPI_FAILURE (Status) && Status != AE_CTRL_TERMINATE)
1418    {
1419        ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line"));
1420    }
1421    return (Status);
1422}
1423