dbinput.c revision 167802
1214571Sdim/*******************************************************************************
2214571Sdim *
3214571Sdim * Module Name: dbinput - user front-end to the AML debugger
4214571Sdim *              $Revision: 1.114 $
5214571Sdim *
6214571Sdim ******************************************************************************/
7214571Sdim
8214571Sdim/******************************************************************************
9214571Sdim *
10214571Sdim * 1. Copyright Notice
11214571Sdim *
12214571Sdim * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13214571Sdim * All rights reserved.
14214571Sdim *
15214571Sdim * 2. License
16214571Sdim *
17214571Sdim * 2.1. This is your license from Intel Corp. under its intellectual property
18214571Sdim * rights.  You may have additional license terms from the party that provided
19214571Sdim * you this software, covering your right to use that party's intellectual
20214571Sdim * property rights.
21214571Sdim *
22214571Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23214571Sdim * copy of the source code appearing in this file ("Covered Code") an
24214571Sdim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25214571Sdim * base code distributed originally by Intel ("Original Intel Code") to copy,
26214571Sdim * make derivatives, distribute, use and display any portion of the Covered
27214571Sdim * Code in any form, with the right to sublicense such rights; and
28214571Sdim *
29214571Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30214571Sdim * license (with the right to sublicense), under only those claims of Intel
31214571Sdim * patents that are infringed by the Original Intel Code, to make, use, sell,
32214571Sdim * offer to sell, and import the Covered Code and derivative works thereof
33214571Sdim * solely to the minimum extent necessary to exercise the above copyright
34214571Sdim * license, and in no event shall the patent license extend to any additions
35214571Sdim * to or modifications of the Original Intel Code.  No other license or right
36214571Sdim * is granted directly or by implication, estoppel or otherwise;
37214571Sdim *
38214571Sdim * The above copyright and patent license is granted only if the following
39214571Sdim * conditions are met:
40214571Sdim *
41214571Sdim * 3. Conditions
42214571Sdim *
43214571Sdim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44214571Sdim * Redistribution of source code of any substantial portion of the Covered
45214571Sdim * Code or modification with rights to further distribute source must include
46214571Sdim * the above Copyright Notice, the above License, this list of Conditions,
47214571Sdim * and the following Disclaimer and Export Compliance provision.  In addition,
48214571Sdim * Licensee must cause all Covered Code to which Licensee contributes to
49214571Sdim * contain a file documenting the changes Licensee made to create that Covered
50214571Sdim * Code and the date of any change.  Licensee must include in that file the
51214571Sdim * documentation of any changes made by any predecessor Licensee.  Licensee
52214571Sdim * must include a prominent statement that the modification is derived,
53214571Sdim * directly or indirectly, from Original Intel Code.
54214571Sdim *
55214571Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56214571Sdim * Redistribution of source code of any substantial portion of the Covered
57214571Sdim * Code or modification without rights to further distribute source must
58214571Sdim * include the following Disclaimer and Export Compliance provision in the
59214571Sdim * documentation and/or other materials provided with distribution.  In
60214571Sdim * addition, Licensee may not authorize further sublicense of source of any
61214571Sdim * portion of the Covered Code, and must include terms to the effect that the
62214571Sdim * license from Licensee to its licensee is limited to the intellectual
63214571Sdim * property embodied in the software Licensee provides to its licensee, and
64214571Sdim * not to intellectual property embodied in modifications its licensee may
65214571Sdim * make.
66214571Sdim *
67214571Sdim * 3.3. Redistribution of Executable. Redistribution in executable form of any
68214571Sdim * substantial portion of the Covered Code or modification must reproduce the
69214571Sdim * above Copyright Notice, and the following Disclaimer and Export Compliance
70214571Sdim * provision in the documentation and/or other materials provided with the
71214571Sdim * distribution.
72214571Sdim *
73214571Sdim * 3.4. Intel retains all right, title, and interest in and to the Original
74214571Sdim * Intel Code.
75214571Sdim *
76214571Sdim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77214571Sdim * Intel shall be used in advertising or otherwise to promote the sale, use or
78214571Sdim * other dealings in products derived from or relating to the Covered Code
79214571Sdim * without prior written authorization from Intel.
80214571Sdim *
81214571Sdim * 4. Disclaimer and Export Compliance
82214571Sdim *
83214571Sdim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84214571Sdim * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85214571Sdim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86214571Sdim * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87214571Sdim * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88214571Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89214571Sdim * PARTICULAR PURPOSE.
90214571Sdim *
91214571Sdim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92214571Sdim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93214571Sdim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94214571Sdim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95214571Sdim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96214571Sdim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97214571Sdim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98214571Sdim * LIMITED REMEDY.
99214571Sdim *
100214571Sdim * 4.3. Licensee shall not export, either directly or indirectly, any of this
101214571Sdim * software or system incorporating such software without first obtaining any
102214571Sdim * required license or other approval from the U. S. Department of Commerce or
103214571Sdim * any other agency or department of the United States Government.  In the
104214571Sdim * event Licensee exports any such software from the United States or
105214571Sdim * re-exports any such software from a foreign destination, Licensee shall
106214571Sdim * ensure that the distribution and export/re-export of the software is in
107214571Sdim * compliance with all laws, regulations, orders, or other restrictions of the
108214571Sdim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109214571Sdim * any of its subsidiaries will export/re-export any technical data, process,
110214571Sdim * software, or service, directly or indirectly, to any country for which the
111214571Sdim * United States government or any agency thereof requires an export license,
112214571Sdim * other governmental approval, or letter of assurance, without first obtaining
113214571Sdim * such license, approval or letter.
114214571Sdim *
115214571Sdim *****************************************************************************/
116214571Sdim
117214571Sdim
118214571Sdim#include <contrib/dev/acpica/acpi.h>
119214571Sdim#include <contrib/dev/acpica/acdebug.h>
120214571Sdim
121214571Sdim
122214571Sdim#ifdef ACPI_DEBUGGER
123214571Sdim
124214571Sdim#define _COMPONENT          ACPI_CA_DEBUGGER
125214571Sdim        ACPI_MODULE_NAME    ("dbinput")
126214571Sdim
127214571Sdim/* Local prototypes */
128214571Sdim
129214571Sdimstatic char *
130214571SdimAcpiDbGetNextToken (
131214571Sdim    char                    *String,
132214571Sdim    char                    **Next);
133214571Sdim
134214571Sdimstatic UINT32
135214571SdimAcpiDbGetLine (
136214571Sdim    char                    *InputBuffer);
137214571Sdim
138214571Sdimstatic UINT32
139214571SdimAcpiDbMatchCommand (
140214571Sdim    char                    *UserCommand);
141214571Sdim
142214571Sdimstatic void
143214571SdimAcpiDbSingleThread (
144214571Sdim    void);
145214571Sdim
146214571Sdimstatic void
147214571SdimAcpiDbDisplayHelp (
148214571Sdim    char                    *HelpType);
149214571Sdim
150214571Sdim
151214571Sdim/*
152214571Sdim * Top-level debugger commands.
153214571Sdim *
154214571Sdim * This list of commands must match the string table below it
155214571Sdim */
156214571Sdimenum AcpiExDebuggerCommands
157214571Sdim{
158214571Sdim    CMD_NOT_FOUND = 0,
159214571Sdim    CMD_NULL,
160214571Sdim    CMD_ALLOCATIONS,
161214571Sdim    CMD_ARGS,
162214571Sdim    CMD_ARGUMENTS,
163214571Sdim    CMD_BREAKPOINT,
164214571Sdim    CMD_BUSINFO,
165214571Sdim    CMD_CALL,
166214571Sdim    CMD_CLOSE,
167214571Sdim    CMD_DEBUG,
168214571Sdim    CMD_DISASSEMBLE,
169214571Sdim    CMD_DUMP,
170214571Sdim    CMD_ENABLEACPI,
171214571Sdim    CMD_EVENT,
172214571Sdim    CMD_EXECUTE,
173214571Sdim    CMD_EXIT,
174214571Sdim    CMD_FIND,
175214571Sdim    CMD_GO,
176214571Sdim    CMD_GPE,
177214571Sdim    CMD_GPES,
178214571Sdim    CMD_HELP,
179214571Sdim    CMD_HELP2,
180214571Sdim    CMD_HISTORY,
181214571Sdim    CMD_HISTORY_EXE,
182214571Sdim    CMD_HISTORY_LAST,
183214571Sdim    CMD_INFORMATION,
184214571Sdim    CMD_INTEGRITY,
185214571Sdim    CMD_INTO,
186214571Sdim    CMD_LEVEL,
187214571Sdim    CMD_LIST,
188214571Sdim    CMD_LOAD,
189214571Sdim    CMD_LOCALS,
190214571Sdim    CMD_LOCKS,
191214571Sdim    CMD_METHODS,
192214571Sdim    CMD_NAMESPACE,
193214571Sdim    CMD_NOTIFY,
194214571Sdim    CMD_OBJECT,
195214571Sdim    CMD_OPEN,
196214571Sdim    CMD_OWNER,
197214571Sdim    CMD_PREFIX,
198214571Sdim    CMD_QUIT,
199214571Sdim    CMD_REFERENCES,
200214571Sdim    CMD_RESOURCES,
201214571Sdim    CMD_RESULTS,
202214571Sdim    CMD_SET,
203214571Sdim    CMD_SLEEP,
204214571Sdim    CMD_STATS,
205214571Sdim    CMD_STOP,
206214571Sdim    CMD_TABLES,
207214571Sdim    CMD_TERMINATE,
208214571Sdim    CMD_THREADS,
209214571Sdim    CMD_TRACE,
210214571Sdim    CMD_TREE,
211214571Sdim    CMD_TYPE,
212214571Sdim    CMD_UNLOAD
213214571Sdim};
214214571Sdim
215214571Sdim#define CMD_FIRST_VALID     2
216214571Sdim
217214571Sdimstatic const COMMAND_INFO       AcpiGbl_DbCommands[] =
218214571Sdim{
219214571Sdim    {"<NOT FOUND>",  0},
220214571Sdim    {"<NULL>",       0},
221214571Sdim    {"ALLOCATIONS",  0},
222214571Sdim    {"ARGS",         0},
223214571Sdim    {"ARGUMENTS",    0},
224214571Sdim    {"BREAKPOINT",   1},
225214571Sdim    {"BUSINFO",      0},
226214571Sdim    {"CALL",         0},
227214571Sdim    {"CLOSE",        0},
228214571Sdim    {"DEBUG",        1},
229214571Sdim    {"DISASSEMBLE",  1},
230214571Sdim    {"DUMP",         1},
231214571Sdim    {"ENABLEACPI",   0},
232214571Sdim    {"EVENT",        1},
233214571Sdim    {"EXECUTE",      1},
234214571Sdim    {"EXIT",         0},
235214571Sdim    {"FIND",         1},
236214571Sdim    {"GO",           0},
237214571Sdim    {"GPE",          2},
238214571Sdim    {"GPES",         0},
239214571Sdim    {"HELP",         0},
240214571Sdim    {"?",            0},
241214571Sdim    {"HISTORY",      0},
242214571Sdim    {"!",            1},
243214571Sdim    {"!!",           0},
244214571Sdim    {"INFORMATION",  0},
245214571Sdim    {"INTEGRITY",    0},
246214571Sdim    {"INTO",         0},
247214571Sdim    {"LEVEL",        0},
248214571Sdim    {"LIST",         0},
249214571Sdim    {"LOAD",         1},
250214571Sdim    {"LOCALS",       0},
251214571Sdim    {"LOCKS",        0},
252214571Sdim    {"METHODS",      0},
253214571Sdim    {"NAMESPACE",    0},
254214571Sdim    {"NOTIFY",       2},
255214571Sdim    {"OBJECT",       1},
256214571Sdim    {"OPEN",         1},
257214571Sdim    {"OWNER",        1},
258214571Sdim    {"PREFIX",       0},
259214571Sdim    {"QUIT",         0},
260214571Sdim    {"REFERENCES",   1},
261214571Sdim    {"RESOURCES",    1},
262214571Sdim    {"RESULTS",      0},
263214571Sdim    {"SET",          3},
264214571Sdim    {"SLEEP",        1},
265214571Sdim    {"STATS",        0},
266214571Sdim    {"STOP",         0},
267214571Sdim    {"TABLES",       0},
268214571Sdim    {"TERMINATE",    0},
269214571Sdim    {"THREADS",      3},
270214571Sdim    {"TRACE",        1},
271214571Sdim    {"TREE",         0},
272214571Sdim    {"TYPE",         1},
273214571Sdim    {"UNLOAD",       1},
274214571Sdim    {NULL,           0}
275214571Sdim};
276214571Sdim
277214571Sdim
278214571Sdim/*******************************************************************************
279214571Sdim *
280214571Sdim * FUNCTION:    AcpiDbDisplayHelp
281214571Sdim *
282214571Sdim * PARAMETERS:  HelpType        - Subcommand (optional)
283214571Sdim *
284214571Sdim * RETURN:      None
285214571Sdim *
286214571Sdim * DESCRIPTION: Print a usage message.
287214571Sdim *
288214571Sdim ******************************************************************************/
289214571Sdim
290214571Sdimstatic void
291214571SdimAcpiDbDisplayHelp (
292214571Sdim    char                    *HelpType)
293214571Sdim{
294214571Sdim
295214571Sdim    AcpiUtStrupr (HelpType);
296214571Sdim
297214571Sdim    /* No parameter, just give the overview */
298214571Sdim
299214571Sdim    if (!HelpType)
300214571Sdim    {
301214571Sdim        AcpiOsPrintf ("ACPI CA Debugger Commands\n\n");
302214571Sdim        AcpiOsPrintf ("The following classes of commands are available.  Help is available for\n");
303214571Sdim        AcpiOsPrintf ("each class by entering \"Help <ClassName>\"\n\n");
304214571Sdim        AcpiOsPrintf ("    [GENERAL]       General-Purpose Commands\n");
305214571Sdim        AcpiOsPrintf ("    [NAMESPACE]     Namespace Access Commands\n");
306214571Sdim        AcpiOsPrintf ("    [METHOD]        Control Method Execution Commands\n");
307214571Sdim        AcpiOsPrintf ("    [STATISTICS]    Statistical Information\n");
308214571Sdim        AcpiOsPrintf ("    [FILE]          File I/O Commands\n");
309214571Sdim        return;
310214571Sdim    }
311214571Sdim
312214571Sdim    /*
313214571Sdim     * Parameter is the command class
314214571Sdim     *
315214571Sdim     * The idea here is to keep each class of commands smaller than a screenful
316214571Sdim     */
317214571Sdim    switch (HelpType[0])
318214571Sdim    {
319214571Sdim    case 'G':
320214571Sdim        AcpiOsPrintf ("\nGeneral-Purpose Commands\n\n");
321214571Sdim        AcpiOsPrintf ("Allocations                         Display list of current memory allocations\n");
322214571Sdim        AcpiOsPrintf ("Dump <Address>|<Namepath>\n");
323214571Sdim        AcpiOsPrintf ("     [Byte|Word|Dword|Qword]        Display ACPI objects or memory\n");
324214571Sdim        AcpiOsPrintf ("EnableAcpi                          Enable ACPI (hardware) mode\n");
325214571Sdim        AcpiOsPrintf ("Help                                This help screen\n");
326214571Sdim        AcpiOsPrintf ("History                             Display command history buffer\n");
327214571Sdim        AcpiOsPrintf ("Level [<DebugLevel>] [console]      Get/Set debug level for file or console\n");
328214571Sdim        AcpiOsPrintf ("Locks                               Current status of internal mutexes\n");
329214571Sdim        AcpiOsPrintf ("Quit or Exit                        Exit this command\n");
330214571Sdim        AcpiOsPrintf ("Stats [Allocations|Memory|Misc\n");
331214571Sdim        AcpiOsPrintf ("      |Objects|Sizes|Stack|Tables]  Display namespace and memory statistics\n");
332214571Sdim        AcpiOsPrintf ("Tables                              Display info about loaded ACPI tables\n");
333214571Sdim        AcpiOsPrintf ("Unload <TableSig> [Instance]        Unload an ACPI table\n");
334214571Sdim        AcpiOsPrintf ("! <CommandNumber>                   Execute command from history buffer\n");
335214571Sdim        AcpiOsPrintf ("!!                                  Execute last command again\n");
336214571Sdim        return;
337214571Sdim
338214571Sdim    case 'S':
339214571Sdim        AcpiOsPrintf ("\nStats Subcommands\n\n");
340214571Sdim        AcpiOsPrintf ("Allocations                         Display list of current memory allocations\n");
341214571Sdim        AcpiOsPrintf ("Memory                              Dump internal memory lists\n");
342214571Sdim        AcpiOsPrintf ("Misc                                Namespace search and mutex stats\n");
343214571Sdim        AcpiOsPrintf ("Objects                             Summary of namespace objects\n");
344214571Sdim        AcpiOsPrintf ("Sizes                               Sizes for each of the internal objects\n");
345214571Sdim        AcpiOsPrintf ("Stack                               Display CPU stack usage\n");
346214571Sdim        AcpiOsPrintf ("Tables                              Info about current ACPI table(s)\n");
347214571Sdim        return;
348214571Sdim
349214571Sdim    case 'N':
350214571Sdim        AcpiOsPrintf ("\nNamespace Access Commands\n\n");
351214571Sdim        AcpiOsPrintf ("Businfo                             Display system bus info\n");
352214571Sdim        AcpiOsPrintf ("Disassemble <Method>                Disassemble a control method\n");
353214571Sdim        AcpiOsPrintf ("Event <F|G> <Value>                 Generate AcpiEvent (Fixed/GPE)\n");
354214571Sdim        AcpiOsPrintf ("Find <AcpiName>  (? is wildcard)    Find ACPI name(s) with wildcards\n");
355214571Sdim        AcpiOsPrintf ("Gpe <GpeNum> <GpeBlock>             Simulate a GPE\n");
356214571Sdim        AcpiOsPrintf ("Gpes                                Display info on all GPEs\n");
357214571Sdim        AcpiOsPrintf ("Integrity                           Validate namespace integrity\n");
358214571Sdim        AcpiOsPrintf ("Methods                             Display list of loaded control methods\n");
359214571Sdim        AcpiOsPrintf ("Namespace [Object] [Depth]          Display loaded namespace tree/subtree\n");
360214571Sdim        AcpiOsPrintf ("Notify <Object> <Value>             Send a notification on Object\n");
361214571Sdim        AcpiOsPrintf ("Objects <ObjectType>                Display all objects of the given type\n");
362214571Sdim        AcpiOsPrintf ("Owner <OwnerId> [Depth]             Display loaded namespace by object owner\n");
363214571Sdim        AcpiOsPrintf ("Prefix [<NamePath>]                 Set or Get current execution prefix\n");
364214571Sdim        AcpiOsPrintf ("References <Addr>                   Find all references to object at addr\n");
365214571Sdim        AcpiOsPrintf ("Resources <Device>                  Get and display Device resources\n");
366214571Sdim        AcpiOsPrintf ("Set N <NamedObject> <Value>         Set value for named integer\n");
367214571Sdim        AcpiOsPrintf ("Sleep <SleepState>                  Simulate sleep/wake sequence\n");
368214571Sdim        AcpiOsPrintf ("Terminate                           Delete namespace and all internal objects\n");
369214571Sdim        AcpiOsPrintf ("Type <Object>                       Display object type\n");
370214571Sdim        return;
371214571Sdim
372214571Sdim    case 'M':
373214571Sdim        AcpiOsPrintf ("\nControl Method Execution Commands\n\n");
374214571Sdim        AcpiOsPrintf ("Arguments (or Args)                 Display method arguments\n");
375214571Sdim        AcpiOsPrintf ("Breakpoint <AmlOffset>              Set an AML execution breakpoint\n");
376214571Sdim        AcpiOsPrintf ("Call                                Run to next control method invocation\n");
377214571Sdim        AcpiOsPrintf ("Debug <Namepath> [Arguments]        Single Step a control method\n");
378214571Sdim        AcpiOsPrintf ("Execute <Namepath> [Arguments]      Execute control method\n");
379214571Sdim        AcpiOsPrintf ("Go                                  Allow method to run to completion\n");
380214571Sdim        AcpiOsPrintf ("Information                         Display info about the current method\n");
381214571Sdim        AcpiOsPrintf ("Into                                Step into (not over) a method call\n");
382214571Sdim        AcpiOsPrintf ("List [# of Aml Opcodes]             Display method ASL statements\n");
383214571Sdim        AcpiOsPrintf ("Locals                              Display method local variables\n");
384214571Sdim        AcpiOsPrintf ("Results                             Display method result stack\n");
385214571Sdim        AcpiOsPrintf ("Set <A|L> <#> <Value>               Set method data (Arguments/Locals)\n");
386214571Sdim        AcpiOsPrintf ("Stop                                Terminate control method\n");
387214571Sdim        AcpiOsPrintf ("Thread <Threads><Loops><NamePath>   Spawn threads to execute method(s)\n");
388214571Sdim        AcpiOsPrintf ("Trace <method name>                 Trace method execution\n");
389214571Sdim        AcpiOsPrintf ("Tree                                Display control method calling tree\n");
390214571Sdim        AcpiOsPrintf ("<Enter>                             Single step next AML opcode (over calls)\n");
391214571Sdim        return;
392214571Sdim
393214571Sdim    case 'F':
394214571Sdim        AcpiOsPrintf ("\nFile I/O Commands\n\n");
395214571Sdim        AcpiOsPrintf ("Close                               Close debug output file\n");
396214571Sdim        AcpiOsPrintf ("Open <Output Filename>              Open a file for debug output\n");
397214571Sdim        AcpiOsPrintf ("Load <Input Filename>               Load ACPI table from a file\n");
398214571Sdim        return;
399214571Sdim
400214571Sdim    default:
401214571Sdim        AcpiOsPrintf ("Unrecognized Command Class: %s\n", HelpType);
402214571Sdim        return;
403214571Sdim    }
404214571Sdim}
405214571Sdim
406214571Sdim
407214571Sdim/*******************************************************************************
408214571Sdim *
409214571Sdim * FUNCTION:    AcpiDbGetNextToken
410214571Sdim *
411214571Sdim * PARAMETERS:  String          - Command buffer
412214571Sdim *              Next            - Return value, end of next token
413214571Sdim *
414214571Sdim * RETURN:      Pointer to the start of the next token.
415214571Sdim *
416214571Sdim * DESCRIPTION: Command line parsing.  Get the next token on the command line
417214571Sdim *
418214571Sdim ******************************************************************************/
419214571Sdim
420214571Sdimstatic char *
421214571SdimAcpiDbGetNextToken (
422214571Sdim    char                    *String,
423214571Sdim    char                    **Next)
424214571Sdim{
425214571Sdim    char                    *Start;
426214571Sdim
427214571Sdim
428214571Sdim    /* At end of buffer? */
429214571Sdim
430214571Sdim    if (!String || !(*String))
431214571Sdim    {
432214571Sdim        return (NULL);
433214571Sdim    }
434214571Sdim
435214571Sdim    /* Get rid of any spaces at the beginning */
436214571Sdim
437214571Sdim    if (*String == ' ')
438214571Sdim    {
439214571Sdim        while (*String && (*String == ' '))
440214571Sdim        {
441214571Sdim            String++;
442214571Sdim        }
443214571Sdim
444214571Sdim        if (!(*String))
445214571Sdim        {
446214571Sdim            return (NULL);
447214571Sdim        }
448214571Sdim    }
449214571Sdim
450214571Sdim    Start = String;
451214571Sdim
452214571Sdim    /* Find end of token */
453214571Sdim
454214571Sdim    while (*String && (*String != ' '))
455214571Sdim    {
456214571Sdim        String++;
457214571Sdim    }
458214571Sdim
459214571Sdim    if (!(*String))
460214571Sdim    {
461214571Sdim        *Next = NULL;
462214571Sdim    }
463214571Sdim    else
464214571Sdim    {
465214571Sdim        *String = 0;
466214571Sdim        *Next = String + 1;
467214571Sdim    }
468214571Sdim
469214571Sdim    return (Start);
470214571Sdim}
471214571Sdim
472214571Sdim
473214571Sdim/*******************************************************************************
474214571Sdim *
475214571Sdim * FUNCTION:    AcpiDbGetLine
476214571Sdim *
477214571Sdim * PARAMETERS:  InputBuffer         - Command line buffer
478214571Sdim *
479214571Sdim * RETURN:      Count of arguments to the command
480214571Sdim *
481214571Sdim * DESCRIPTION: Get the next command line from the user.  Gets entire line
482214571Sdim *              up to the next newline
483214571Sdim *
484214571Sdim ******************************************************************************/
485214571Sdim
486214571Sdimstatic UINT32
487214571SdimAcpiDbGetLine (
488    char                    *InputBuffer)
489{
490    UINT32                  i;
491    UINT32                  Count;
492    char                    *Next;
493    char                    *This;
494
495
496    ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
497
498    This = AcpiGbl_DbParsedBuf;
499    for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
500    {
501        AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next);
502        if (!AcpiGbl_DbArgs[i])
503        {
504            break;
505        }
506
507        This = Next;
508    }
509
510    /* Uppercase the actual command */
511
512    if (AcpiGbl_DbArgs[0])
513    {
514        AcpiUtStrupr (AcpiGbl_DbArgs[0]);
515    }
516
517    Count = i;
518    if (Count)
519    {
520        Count--;  /* Number of args only */
521    }
522
523    return (Count);
524}
525
526
527/*******************************************************************************
528 *
529 * FUNCTION:    AcpiDbMatchCommand
530 *
531 * PARAMETERS:  UserCommand             - User command line
532 *
533 * RETURN:      Index into command array, -1 if not found
534 *
535 * DESCRIPTION: Search command array for a command match
536 *
537 ******************************************************************************/
538
539static UINT32
540AcpiDbMatchCommand (
541    char                    *UserCommand)
542{
543    UINT32                  i;
544
545
546    if (!UserCommand || UserCommand[0] == 0)
547    {
548        return (CMD_NULL);
549    }
550
551    for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
552    {
553        if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
554                         AcpiGbl_DbCommands[i].Name)
555        {
556            return (i);
557        }
558    }
559
560    /* Command not recognized */
561
562    return (CMD_NOT_FOUND);
563}
564
565
566/*******************************************************************************
567 *
568 * FUNCTION:    AcpiDbCommandDispatch
569 *
570 * PARAMETERS:  InputBuffer         - Command line buffer
571 *              WalkState           - Current walk
572 *              Op                  - Current (executing) parse op
573 *
574 * RETURN:      Status
575 *
576 * DESCRIPTION: Command dispatcher.
577 *
578 ******************************************************************************/
579
580ACPI_STATUS
581AcpiDbCommandDispatch (
582    char                    *InputBuffer,
583    ACPI_WALK_STATE         *WalkState,
584    ACPI_PARSE_OBJECT       *Op)
585{
586    UINT32                  Temp;
587    UINT32                  CommandIndex;
588    UINT32                  ParamCount;
589    char                    *CommandLine;
590    ACPI_STATUS             Status = AE_CTRL_TRUE;
591
592
593    /* If AcpiTerminate has been called, terminate this thread */
594
595    if (AcpiGbl_DbTerminateThreads)
596    {
597        return (AE_CTRL_TERMINATE);
598    }
599
600    ParamCount = AcpiDbGetLine (InputBuffer);
601    CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
602    Temp = 0;
603
604    /* Verify that we have the minimum number of params */
605
606    if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
607    {
608        AcpiOsPrintf ("%d parameters entered, [%s] requires %d parameters\n",
609            ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
610            AcpiGbl_DbCommands[CommandIndex].MinArgs);
611
612        return (AE_CTRL_TRUE);
613    }
614
615    /* Decode and dispatch the command */
616
617    switch (CommandIndex)
618    {
619    case CMD_NULL:
620        if (Op)
621        {
622            return (AE_OK);
623        }
624        break;
625
626    case CMD_ALLOCATIONS:
627
628#ifdef ACPI_DBG_TRACK_ALLOCATIONS
629        AcpiUtDumpAllocations ((UINT32) -1, NULL);
630#endif
631        break;
632
633    case CMD_ARGS:
634    case CMD_ARGUMENTS:
635        AcpiDbDisplayArguments ();
636        break;
637
638    case CMD_BREAKPOINT:
639        AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
640        break;
641
642    case CMD_BUSINFO:
643        AcpiDbGetBusInfo ();
644        break;
645
646    case CMD_CALL:
647        AcpiDbSetMethodCallBreakpoint (Op);
648        Status = AE_OK;
649        break;
650
651    case CMD_CLOSE:
652        AcpiDbCloseDebugFile ();
653        break;
654
655    case CMD_DEBUG:
656        AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], EX_SINGLE_STEP);
657        break;
658
659    case CMD_DISASSEMBLE:
660        (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
661        break;
662
663    case CMD_DUMP:
664        AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
665        break;
666
667    case CMD_ENABLEACPI:
668        Status = AcpiEnable();
669        if (ACPI_FAILURE(Status))
670        {
671            AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
672            return (Status);
673        }
674        break;
675
676    case CMD_EVENT:
677        AcpiOsPrintf ("Event command not implemented\n");
678        break;
679
680    case CMD_EXECUTE:
681        AcpiDbExecute (AcpiGbl_DbArgs[1],
682            &AcpiGbl_DbArgs[2], EX_NO_SINGLE_STEP);
683        break;
684
685    case CMD_FIND:
686        Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
687        break;
688
689    case CMD_GO:
690        AcpiGbl_CmSingleStep = FALSE;
691        return (AE_OK);
692
693    case CMD_GPE:
694        AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
695        break;
696
697    case CMD_GPES:
698        AcpiDbDisplayGpes ();
699        break;
700
701    case CMD_HELP:
702    case CMD_HELP2:
703        AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]);
704        break;
705
706    case CMD_HISTORY:
707        AcpiDbDisplayHistory ();
708        break;
709
710    case CMD_HISTORY_EXE:
711        CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
712        if (!CommandLine)
713        {
714            return (AE_CTRL_TRUE);
715        }
716
717        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
718        return (Status);
719
720    case CMD_HISTORY_LAST:
721        CommandLine = AcpiDbGetFromHistory (NULL);
722        if (!CommandLine)
723        {
724            return (AE_CTRL_TRUE);
725        }
726
727        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
728        return (Status);
729
730    case CMD_INFORMATION:
731        AcpiDbDisplayMethodInfo (Op);
732        break;
733
734    case CMD_INTEGRITY:
735        AcpiDbCheckIntegrity ();
736        break;
737
738    case CMD_INTO:
739        if (Op)
740        {
741            AcpiGbl_CmSingleStep = TRUE;
742            return (AE_OK);
743        }
744        break;
745
746    case CMD_LEVEL:
747        if (ParamCount == 0)
748        {
749            AcpiOsPrintf ("Current debug level for file output is:    %8.8lX\n",
750                AcpiGbl_DbDebugLevel);
751            AcpiOsPrintf ("Current debug level for console output is: %8.8lX\n",
752                AcpiGbl_DbConsoleDebugLevel);
753        }
754        else if (ParamCount == 2)
755        {
756            Temp = AcpiGbl_DbConsoleDebugLevel;
757            AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
758                                            NULL, 16);
759            AcpiOsPrintf (
760                "Debug Level for console output was %8.8lX, now %8.8lX\n",
761                Temp, AcpiGbl_DbConsoleDebugLevel);
762        }
763        else
764        {
765            Temp = AcpiGbl_DbDebugLevel;
766            AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
767            AcpiOsPrintf (
768                "Debug Level for file output was %8.8lX, now %8.8lX\n",
769                Temp, AcpiGbl_DbDebugLevel);
770        }
771        break;
772
773    case CMD_LIST:
774        AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
775        break;
776
777    case CMD_LOAD:
778        Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL);
779        break;
780
781    case CMD_LOCKS:
782        AcpiDbDisplayLocks ();
783        break;
784
785    case CMD_LOCALS:
786        AcpiDbDisplayLocals ();
787        break;
788
789    case CMD_METHODS:
790        Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
791        break;
792
793    case CMD_NAMESPACE:
794        AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
795        break;
796
797    case CMD_NOTIFY:
798        Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
799        AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
800        break;
801
802    case CMD_OBJECT:
803        AcpiUtStrupr (AcpiGbl_DbArgs[1]);
804        Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
805        break;
806
807    case CMD_OPEN:
808        AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
809        break;
810
811    case CMD_OWNER:
812        AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
813        break;
814
815    case CMD_PREFIX:
816        AcpiDbSetScope (AcpiGbl_DbArgs[1]);
817        break;
818
819    case CMD_REFERENCES:
820        AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
821        break;
822
823    case CMD_RESOURCES:
824        AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
825        break;
826
827    case CMD_RESULTS:
828        AcpiDbDisplayResults ();
829        break;
830
831    case CMD_SET:
832        AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
833            AcpiGbl_DbArgs[3]);
834        break;
835
836    case CMD_SLEEP:
837        Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
838        break;
839
840    case CMD_STATS:
841        Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
842        break;
843
844    case CMD_STOP:
845        return (AE_NOT_IMPLEMENTED);
846
847    case CMD_TABLES:
848        AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
849        break;
850
851    case CMD_TERMINATE:
852        AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
853        AcpiUtSubsystemShutdown ();
854
855        /*
856         * TBD: [Restructure] Need some way to re-initialize without
857         * re-creating the semaphores!
858         */
859
860        /*  AcpiInitialize (NULL);  */
861        break;
862
863    case CMD_THREADS:
864        AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
865            AcpiGbl_DbArgs[3]);
866        break;
867
868    case CMD_TRACE:
869        AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1);
870        break;
871
872    case CMD_TREE:
873        AcpiDbDisplayCallingTree ();
874        break;
875
876    case CMD_TYPE:
877        AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
878        break;
879
880    case CMD_UNLOAD:
881        AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
882        break;
883
884    case CMD_EXIT:
885    case CMD_QUIT:
886        if (Op)
887        {
888            AcpiOsPrintf ("Method execution terminated\n");
889            return (AE_CTRL_TERMINATE);
890        }
891
892        if (!AcpiGbl_DbOutputToFile)
893        {
894            AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
895        }
896
897        AcpiDbCloseDebugFile ();
898        AcpiGbl_DbTerminateThreads = TRUE;
899        return (AE_CTRL_TERMINATE);
900
901    case CMD_NOT_FOUND:
902    default:
903        AcpiOsPrintf ("Unknown Command\n");
904        return (AE_CTRL_TRUE);
905    }
906
907    if (ACPI_SUCCESS (Status))
908    {
909        Status = AE_CTRL_TRUE;
910    }
911
912    /* Add all commands that come here to the history buffer */
913
914    AcpiDbAddToHistory (InputBuffer);
915    return (Status);
916}
917
918
919/*******************************************************************************
920 *
921 * FUNCTION:    AcpiDbExecuteThread
922 *
923 * PARAMETERS:  Context         - Not used
924 *
925 * RETURN:      None
926 *
927 * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
928 *              simply dispatches it.
929 *
930 ******************************************************************************/
931
932void ACPI_SYSTEM_XFACE
933AcpiDbExecuteThread (
934    void                    *Context)
935{
936    ACPI_STATUS             Status = AE_OK;
937    ACPI_STATUS             MStatus;
938
939
940    while (Status != AE_CTRL_TERMINATE)
941    {
942        AcpiGbl_MethodExecuting = FALSE;
943        AcpiGbl_StepToNextCall = FALSE;
944
945        MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
946        if (ACPI_FAILURE (MStatus))
947        {
948            return;
949        }
950
951        Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
952
953        MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
954        if (ACPI_FAILURE (MStatus))
955        {
956            return;
957        }
958    }
959}
960
961
962/*******************************************************************************
963 *
964 * FUNCTION:    AcpiDbSingleThread
965 *
966 * PARAMETERS:  None
967 *
968 * RETURN:      None
969 *
970 * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
971 *              simply dispatches it.
972 *
973 ******************************************************************************/
974
975static void
976AcpiDbSingleThread (
977    void)
978{
979
980    AcpiGbl_MethodExecuting = FALSE;
981    AcpiGbl_StepToNextCall = FALSE;
982
983    (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
984}
985
986
987/*******************************************************************************
988 *
989 * FUNCTION:    AcpiDbUserCommands
990 *
991 * PARAMETERS:  Prompt              - User prompt (depends on mode)
992 *              Op                  - Current executing parse op
993 *
994 * RETURN:      None
995 *
996 * DESCRIPTION: Command line execution for the AML debugger.  Commands are
997 *              matched and dispatched here.
998 *
999 ******************************************************************************/
1000
1001ACPI_STATUS
1002AcpiDbUserCommands (
1003    char                    Prompt,
1004    ACPI_PARSE_OBJECT       *Op)
1005{
1006    ACPI_STATUS             Status = AE_OK;
1007
1008
1009    /* TBD: [Restructure] Need a separate command line buffer for step mode */
1010
1011    while (!AcpiGbl_DbTerminateThreads)
1012    {
1013        /* Force output to console until a command is entered */
1014
1015        AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1016
1017        /* Different prompt if method is executing */
1018
1019        if (!AcpiGbl_MethodExecuting)
1020        {
1021            AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
1022        }
1023        else
1024        {
1025            AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
1026        }
1027
1028        /* Get the user input line */
1029
1030        (void) AcpiOsGetLine (AcpiGbl_DbLineBuf);
1031
1032        /* Check for single or multithreaded debug */
1033
1034        if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
1035        {
1036            /*
1037             * Signal the debug thread that we have a command to execute,
1038             * and wait for the command to complete.
1039             */
1040            Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
1041            if (ACPI_FAILURE (Status))
1042            {
1043                return (Status);
1044            }
1045
1046            Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
1047            if (ACPI_FAILURE (Status))
1048            {
1049                return (Status);
1050            }
1051        }
1052        else
1053        {
1054            /* Just call to the command line interpreter */
1055
1056            AcpiDbSingleThread ();
1057        }
1058    }
1059
1060    /*
1061     * Only this thread (the original thread) should actually terminate the
1062     * subsystem, because all the semaphores are deleted during termination
1063     */
1064    Status = AcpiTerminate ();
1065    return (Status);
1066}
1067
1068#endif  /* ACPI_DEBUGGER */
1069
1070