dbinput.c revision 209746
1132718Skan/*******************************************************************************
2117395Skan *
350397Sobrien * Module Name: dbinput - user front-end to the AML debugger
450397Sobrien *
550397Sobrien ******************************************************************************/
650397Sobrien
750397Sobrien/******************************************************************************
8132718Skan *
950397Sobrien * 1. Copyright Notice
10132718Skan *
1150397Sobrien * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
1250397Sobrien * All rights reserved.
1350397Sobrien *
1450397Sobrien * 2. License
15132718Skan *
1650397Sobrien * 2.1. This is your license from Intel Corp. under its intellectual property
1750397Sobrien * rights.  You may have additional license terms from the party that provided
1850397Sobrien * you this software, covering your right to use that party's intellectual
1950397Sobrien * property rights.
2050397Sobrien *
21132718Skan * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22169689Skan * copy of the source code appearing in this file ("Covered Code") an
23169689Skan * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2450397Sobrien * base code distributed originally by Intel ("Original Intel Code") to copy,
2550397Sobrien * make derivatives, distribute, use and display any portion of the Covered
2650397Sobrien * Code in any form, with the right to sublicense such rights; and
2750397Sobrien *
2850397Sobrien * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2950397Sobrien * license (with the right to sublicense), under only those claims of Intel
3050397Sobrien * patents that are infringed by the Original Intel Code, to make, use, sell,
3150397Sobrien * offer to sell, and import the Covered Code and derivative works thereof
3250397Sobrien * solely to the minimum extent necessary to exercise the above copyright
3390075Sobrien * license, and in no event shall the patent license extend to any additions
3490075Sobrien * to or modifications of the Original Intel Code.  No other license or right
3550397Sobrien * is granted directly or by implication, estoppel or otherwise;
36117395Skan *
37117395Skan * The above copyright and patent license is granted only if the following
38117395Skan * conditions are met:
39117395Skan *
40117395Skan * 3. Conditions
41117395Skan *
42117395Skan * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43117395Skan * Redistribution of source code of any substantial portion of the Covered
44117395Skan * Code or modification with rights to further distribute source must include
4550397Sobrien * the above Copyright Notice, the above License, this list of Conditions,
4650397Sobrien * and the following Disclaimer and Export Compliance provision.  In addition,
4790075Sobrien * Licensee must cause all Covered Code to which Licensee contributes to
4850397Sobrien * contain a file documenting the changes Licensee made to create that Covered
4950397Sobrien * Code and the date of any change.  Licensee must include in that file the
5050397Sobrien * documentation of any changes made by any predecessor Licensee.  Licensee
5150397Sobrien * must include a prominent statement that the modification is derived,
5250397Sobrien * directly or indirectly, from Original Intel Code.
5350397Sobrien *
5450397Sobrien * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5550397Sobrien * Redistribution of source code of any substantial portion of the Covered
5650397Sobrien * Code or modification without rights to further distribute source must
5750397Sobrien * include the following Disclaimer and Export Compliance provision in the
5850397Sobrien * documentation and/or other materials provided with distribution.  In
5950397Sobrien * addition, Licensee may not authorize further sublicense of source of any
60132718Skan * portion of the Covered Code, and must include terms to the effect that the
6190075Sobrien * license from Licensee to its licensee is limited to the intellectual
62132718Skan * property embodied in the software Licensee provides to its licensee, and
63132718Skan * not to intellectual property embodied in modifications its licensee may
6450397Sobrien * make.
6550397Sobrien *
66132718Skan * 3.3. Redistribution of Executable. Redistribution in executable form of any
6750397Sobrien * substantial portion of the Covered Code or modification must reproduce the
6850397Sobrien * above Copyright Notice, and the following Disclaimer and Export Compliance
6950397Sobrien * provision in the documentation and/or other materials provided with the
7050397Sobrien * distribution.
7150397Sobrien *
7250397Sobrien * 3.4. Intel retains all right, title, and interest in and to the Original
7350397Sobrien * Intel Code.
7490075Sobrien *
7550397Sobrien * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7650397Sobrien * Intel shall be used in advertising or otherwise to promote the sale, use or
7750397Sobrien * other dealings in products derived from or relating to the Covered Code
7850397Sobrien * without prior written authorization from Intel.
7950397Sobrien *
8050397Sobrien * 4. Disclaimer and Export Compliance
8150397Sobrien *
8250397Sobrien * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8350397Sobrien * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8450397Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8550397Sobrien * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8650397Sobrien * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8750397Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8850397Sobrien * PARTICULAR PURPOSE.
8950397Sobrien *
9050397Sobrien * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9150397Sobrien * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9250397Sobrien * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9350397Sobrien * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9450397Sobrien * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9550397Sobrien * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9650397Sobrien * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9750397Sobrien * 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
117#include <contrib/dev/acpica/include/acpi.h>
118#include <contrib/dev/acpica/include/accommon.h>
119#include <contrib/dev/acpica/include/acdebug.h>
120
121
122#ifdef ACPI_DEBUGGER
123
124#define _COMPONENT          ACPI_CA_DEBUGGER
125        ACPI_MODULE_NAME    ("dbinput")
126
127/* Local prototypes */
128
129static char *
130AcpiDbGetNextToken (
131    char                    *String,
132    char                    **Next);
133
134static UINT32
135AcpiDbGetLine (
136    char                    *InputBuffer);
137
138static UINT32
139AcpiDbMatchCommand (
140    char                    *UserCommand);
141
142static void
143AcpiDbSingleThread (
144    void);
145
146static void
147AcpiDbDisplayHelp (
148    char                    *HelpType);
149
150
151/*
152 * Top-level debugger commands.
153 *
154 * This list of commands must match the string table below it
155 */
156enum AcpiExDebuggerCommands
157{
158    CMD_NOT_FOUND = 0,
159    CMD_NULL,
160    CMD_ALLOCATIONS,
161    CMD_ARGS,
162    CMD_ARGUMENTS,
163    CMD_BATCH,
164    CMD_BREAKPOINT,
165    CMD_BUSINFO,
166    CMD_CALL,
167    CMD_CLOSE,
168    CMD_DEBUG,
169    CMD_DISASSEMBLE,
170    CMD_DUMP,
171    CMD_ENABLEACPI,
172    CMD_EVENT,
173    CMD_EXECUTE,
174    CMD_EXIT,
175    CMD_FIND,
176    CMD_GO,
177    CMD_GPE,
178    CMD_GPES,
179    CMD_HELP,
180    CMD_HELP2,
181    CMD_HISTORY,
182    CMD_HISTORY_EXE,
183    CMD_HISTORY_LAST,
184    CMD_INFORMATION,
185    CMD_INTEGRITY,
186    CMD_INTO,
187    CMD_LEVEL,
188    CMD_LIST,
189    CMD_LOAD,
190    CMD_LOCALS,
191    CMD_LOCKS,
192    CMD_METHODS,
193    CMD_NAMESPACE,
194    CMD_NOTIFY,
195    CMD_OBJECT,
196    CMD_OPEN,
197    CMD_OWNER,
198    CMD_PREDEFINED,
199    CMD_PREFIX,
200    CMD_QUIT,
201    CMD_REFERENCES,
202    CMD_RESOURCES,
203    CMD_RESULTS,
204    CMD_SET,
205    CMD_SLEEP,
206    CMD_STATS,
207    CMD_STOP,
208    CMD_TABLES,
209    CMD_TERMINATE,
210    CMD_THREADS,
211    CMD_TRACE,
212    CMD_TREE,
213    CMD_TYPE,
214    CMD_UNLOAD
215};
216
217#define CMD_FIRST_VALID     2
218
219
220/* Second parameter is the required argument count */
221
222static const COMMAND_INFO       AcpiGbl_DbCommands[] =
223{
224    {"<NOT FOUND>",  0},
225    {"<NULL>",       0},
226    {"ALLOCATIONS",  0},
227    {"ARGS",         0},
228    {"ARGUMENTS",    0},
229    {"BATCH",        0},
230    {"BREAKPOINT",   1},
231    {"BUSINFO",      0},
232    {"CALL",         0},
233    {"CLOSE",        0},
234    {"DEBUG",        1},
235    {"DISASSEMBLE",  1},
236    {"DUMP",         1},
237    {"ENABLEACPI",   0},
238    {"EVENT",        1},
239    {"EXECUTE",      1},
240    {"EXIT",         0},
241    {"FIND",         1},
242    {"GO",           0},
243    {"GPE",          2},
244    {"GPES",         0},
245    {"HELP",         0},
246    {"?",            0},
247    {"HISTORY",      0},
248    {"!",            1},
249    {"!!",           0},
250    {"INFORMATION",  0},
251    {"INTEGRITY",    0},
252    {"INTO",         0},
253    {"LEVEL",        0},
254    {"LIST",         0},
255    {"LOAD",         1},
256    {"LOCALS",       0},
257    {"LOCKS",        0},
258    {"METHODS",      0},
259    {"NAMESPACE",    0},
260    {"NOTIFY",       2},
261    {"OBJECT",       1},
262    {"OPEN",         1},
263    {"OWNER",        1},
264    {"PREDEFINED",   0},
265    {"PREFIX",       0},
266    {"QUIT",         0},
267    {"REFERENCES",   1},
268    {"RESOURCES",    1},
269    {"RESULTS",      0},
270    {"SET",          3},
271    {"SLEEP",        1},
272    {"STATS",        0},
273    {"STOP",         0},
274    {"TABLES",       0},
275    {"TERMINATE",    0},
276    {"THREADS",      3},
277    {"TRACE",        1},
278    {"TREE",         0},
279    {"TYPE",         1},
280    {"UNLOAD",       1},
281    {NULL,           0}
282};
283
284
285/*******************************************************************************
286 *
287 * FUNCTION:    AcpiDbDisplayHelp
288 *
289 * PARAMETERS:  HelpType        - Subcommand (optional)
290 *
291 * RETURN:      None
292 *
293 * DESCRIPTION: Print a usage message.
294 *
295 ******************************************************************************/
296
297static void
298AcpiDbDisplayHelp (
299    char                    *HelpType)
300{
301
302    AcpiUtStrupr (HelpType);
303
304    /* No parameter, just give the overview */
305
306    if (!HelpType)
307    {
308        AcpiOsPrintf ("ACPI CA Debugger Commands\n\n");
309        AcpiOsPrintf ("The following classes of commands are available.  Help is available for\n");
310        AcpiOsPrintf ("each class by entering \"Help <ClassName>\"\n\n");
311        AcpiOsPrintf ("    [GENERAL]       General-Purpose Commands\n");
312        AcpiOsPrintf ("    [NAMESPACE]     Namespace Access Commands\n");
313        AcpiOsPrintf ("    [METHOD]        Control Method Execution Commands\n");
314        AcpiOsPrintf ("    [STATISTICS]    Statistical Information\n");
315        AcpiOsPrintf ("    [FILE]          File I/O Commands\n");
316        return;
317    }
318
319    /*
320     * Parameter is the command class
321     *
322     * The idea here is to keep each class of commands smaller than a screenful
323     */
324    switch (HelpType[0])
325    {
326    case 'G':
327        AcpiOsPrintf ("\nGeneral-Purpose Commands\n\n");
328        AcpiOsPrintf ("Allocations                         Display list of current memory allocations\n");
329        AcpiOsPrintf ("Dump <Address>|<Namepath>\n");
330        AcpiOsPrintf ("     [Byte|Word|Dword|Qword]        Display ACPI objects or memory\n");
331        AcpiOsPrintf ("EnableAcpi                          Enable ACPI (hardware) mode\n");
332        AcpiOsPrintf ("Help                                This help screen\n");
333        AcpiOsPrintf ("History                             Display command history buffer\n");
334        AcpiOsPrintf ("Level [<DebugLevel>] [console]      Get/Set debug level for file or console\n");
335        AcpiOsPrintf ("Locks                               Current status of internal mutexes\n");
336        AcpiOsPrintf ("Quit or Exit                        Exit this command\n");
337        AcpiOsPrintf ("Stats [Allocations|Memory|Misc\n");
338        AcpiOsPrintf ("      |Objects|Sizes|Stack|Tables]  Display namespace and memory statistics\n");
339        AcpiOsPrintf ("Tables                              Display info about loaded ACPI tables\n");
340        AcpiOsPrintf ("Unload <TableSig> [Instance]        Unload an ACPI table\n");
341        AcpiOsPrintf ("! <CommandNumber>                   Execute command from history buffer\n");
342        AcpiOsPrintf ("!!                                  Execute last command again\n");
343        return;
344
345    case 'S':
346        AcpiOsPrintf ("\nStats Subcommands\n\n");
347        AcpiOsPrintf ("Allocations                         Display list of current memory allocations\n");
348        AcpiOsPrintf ("Memory                              Dump internal memory lists\n");
349        AcpiOsPrintf ("Misc                                Namespace search and mutex stats\n");
350        AcpiOsPrintf ("Objects                             Summary of namespace objects\n");
351        AcpiOsPrintf ("Sizes                               Sizes for each of the internal objects\n");
352        AcpiOsPrintf ("Stack                               Display CPU stack usage\n");
353        AcpiOsPrintf ("Tables                              Info about current ACPI table(s)\n");
354        return;
355
356    case 'N':
357        AcpiOsPrintf ("\nNamespace Access Commands\n\n");
358        AcpiOsPrintf ("Businfo                             Display system bus info\n");
359        AcpiOsPrintf ("Disassemble <Method>                Disassemble a control method\n");
360        AcpiOsPrintf ("Event <F|G> <Value>                 Generate AcpiEvent (Fixed/GPE)\n");
361        AcpiOsPrintf ("Find <AcpiName>  (? is wildcard)    Find ACPI name(s) with wildcards\n");
362        AcpiOsPrintf ("Gpe <GpeNum> <GpeBlock>             Simulate a GPE\n");
363        AcpiOsPrintf ("Gpes                                Display info on all GPEs\n");
364        AcpiOsPrintf ("Integrity                           Validate namespace integrity\n");
365        AcpiOsPrintf ("Methods                             Display list of loaded control methods\n");
366        AcpiOsPrintf ("Namespace [Object] [Depth]          Display loaded namespace tree/subtree\n");
367        AcpiOsPrintf ("Notify <Object> <Value>             Send a notification on Object\n");
368        AcpiOsPrintf ("Objects <ObjectType>                Display all objects of the given type\n");
369        AcpiOsPrintf ("Owner <OwnerId> [Depth]             Display loaded namespace by object owner\n");
370        AcpiOsPrintf ("Predefined                          Check all predefined names\n");
371        AcpiOsPrintf ("Prefix [<NamePath>]                 Set or Get current execution prefix\n");
372        AcpiOsPrintf ("References <Addr>                   Find all references to object at addr\n");
373        AcpiOsPrintf ("Resources <Device>                  Get and display Device resources\n");
374        AcpiOsPrintf ("Set N <NamedObject> <Value>         Set value for named integer\n");
375        AcpiOsPrintf ("Sleep <SleepState>                  Simulate sleep/wake sequence\n");
376        AcpiOsPrintf ("Terminate                           Delete namespace and all internal objects\n");
377        AcpiOsPrintf ("Type <Object>                       Display object type\n");
378        return;
379
380    case 'M':
381        AcpiOsPrintf ("\nControl Method Execution Commands\n\n");
382        AcpiOsPrintf ("Arguments (or Args)                 Display method arguments\n");
383        AcpiOsPrintf ("Breakpoint <AmlOffset>              Set an AML execution breakpoint\n");
384        AcpiOsPrintf ("Call                                Run to next control method invocation\n");
385        AcpiOsPrintf ("Debug <Namepath> [Arguments]        Single Step a control method\n");
386        AcpiOsPrintf ("Execute <Namepath> [Arguments]      Execute control method\n");
387        AcpiOsPrintf ("Go                                  Allow method to run to completion\n");
388        AcpiOsPrintf ("Information                         Display info about the current method\n");
389        AcpiOsPrintf ("Into                                Step into (not over) a method call\n");
390        AcpiOsPrintf ("List [# of Aml Opcodes]             Display method ASL statements\n");
391        AcpiOsPrintf ("Locals                              Display method local variables\n");
392        AcpiOsPrintf ("Results                             Display method result stack\n");
393        AcpiOsPrintf ("Set <A|L> <#> <Value>               Set method data (Arguments/Locals)\n");
394        AcpiOsPrintf ("Stop                                Terminate control method\n");
395        AcpiOsPrintf ("Thread <Threads><Loops><NamePath>   Spawn threads to execute method(s)\n");
396        AcpiOsPrintf ("Trace <method name>                 Trace method execution\n");
397        AcpiOsPrintf ("Tree                                Display control method calling tree\n");
398        AcpiOsPrintf ("<Enter>                             Single step next AML opcode (over calls)\n");
399        return;
400
401    case 'F':
402        AcpiOsPrintf ("\nFile I/O Commands\n\n");
403        AcpiOsPrintf ("Close                               Close debug output file\n");
404        AcpiOsPrintf ("Open <Output Filename>              Open a file for debug output\n");
405        AcpiOsPrintf ("Load <Input Filename>               Load ACPI table from a file\n");
406        return;
407
408    default:
409        AcpiOsPrintf ("Unrecognized Command Class: %s\n", HelpType);
410        return;
411    }
412}
413
414
415/*******************************************************************************
416 *
417 * FUNCTION:    AcpiDbGetNextToken
418 *
419 * PARAMETERS:  String          - Command buffer
420 *              Next            - Return value, end of next token
421 *
422 * RETURN:      Pointer to the start of the next token.
423 *
424 * DESCRIPTION: Command line parsing.  Get the next token on the command line
425 *
426 ******************************************************************************/
427
428static char *
429AcpiDbGetNextToken (
430    char                    *String,
431    char                    **Next)
432{
433    char                    *Start;
434
435
436    /* At end of buffer? */
437
438    if (!String || !(*String))
439    {
440        return (NULL);
441    }
442
443    /* Get rid of any spaces at the beginning */
444
445    if (*String == ' ')
446    {
447        while (*String && (*String == ' '))
448        {
449            String++;
450        }
451
452        if (!(*String))
453        {
454            return (NULL);
455        }
456    }
457
458    Start = String;
459
460    /* Find end of token */
461
462    while (*String && (*String != ' '))
463    {
464        String++;
465    }
466
467    if (!(*String))
468    {
469        *Next = NULL;
470    }
471    else
472    {
473        *String = 0;
474        *Next = String + 1;
475    }
476
477    return (Start);
478}
479
480
481/*******************************************************************************
482 *
483 * FUNCTION:    AcpiDbGetLine
484 *
485 * PARAMETERS:  InputBuffer         - Command line buffer
486 *
487 * RETURN:      Count of arguments to the command
488 *
489 * DESCRIPTION: Get the next command line from the user.  Gets entire line
490 *              up to the next newline
491 *
492 ******************************************************************************/
493
494static UINT32
495AcpiDbGetLine (
496    char                    *InputBuffer)
497{
498    UINT32                  i;
499    UINT32                  Count;
500    char                    *Next;
501    char                    *This;
502
503
504    ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
505
506    This = AcpiGbl_DbParsedBuf;
507    for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
508    {
509        AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next);
510        if (!AcpiGbl_DbArgs[i])
511        {
512            break;
513        }
514
515        This = Next;
516    }
517
518    /* Uppercase the actual command */
519
520    if (AcpiGbl_DbArgs[0])
521    {
522        AcpiUtStrupr (AcpiGbl_DbArgs[0]);
523    }
524
525    Count = i;
526    if (Count)
527    {
528        Count--;  /* Number of args only */
529    }
530
531    return (Count);
532}
533
534
535/*******************************************************************************
536 *
537 * FUNCTION:    AcpiDbMatchCommand
538 *
539 * PARAMETERS:  UserCommand             - User command line
540 *
541 * RETURN:      Index into command array, -1 if not found
542 *
543 * DESCRIPTION: Search command array for a command match
544 *
545 ******************************************************************************/
546
547static UINT32
548AcpiDbMatchCommand (
549    char                    *UserCommand)
550{
551    UINT32                  i;
552
553
554    if (!UserCommand || UserCommand[0] == 0)
555    {
556        return (CMD_NULL);
557    }
558
559    for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
560    {
561        if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
562                         AcpiGbl_DbCommands[i].Name)
563        {
564            return (i);
565        }
566    }
567
568    /* Command not recognized */
569
570    return (CMD_NOT_FOUND);
571}
572
573
574/*******************************************************************************
575 *
576 * FUNCTION:    AcpiDbCommandDispatch
577 *
578 * PARAMETERS:  InputBuffer         - Command line buffer
579 *              WalkState           - Current walk
580 *              Op                  - Current (executing) parse op
581 *
582 * RETURN:      Status
583 *
584 * DESCRIPTION: Command dispatcher.
585 *
586 ******************************************************************************/
587
588ACPI_STATUS
589AcpiDbCommandDispatch (
590    char                    *InputBuffer,
591    ACPI_WALK_STATE         *WalkState,
592    ACPI_PARSE_OBJECT       *Op)
593{
594    UINT32                  Temp;
595    UINT32                  CommandIndex;
596    UINT32                  ParamCount;
597    char                    *CommandLine;
598    ACPI_STATUS             Status = AE_CTRL_TRUE;
599
600
601    /* If AcpiTerminate has been called, terminate this thread */
602
603    if (AcpiGbl_DbTerminateThreads)
604    {
605        return (AE_CTRL_TERMINATE);
606    }
607
608    ParamCount = AcpiDbGetLine (InputBuffer);
609    CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
610    Temp = 0;
611
612    /* Verify that we have the minimum number of params */
613
614    if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
615    {
616        AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
617            ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
618            AcpiGbl_DbCommands[CommandIndex].MinArgs);
619
620        return (AE_CTRL_TRUE);
621    }
622
623    /* Decode and dispatch the command */
624
625    switch (CommandIndex)
626    {
627    case CMD_NULL:
628        if (Op)
629        {
630            return (AE_OK);
631        }
632        break;
633
634    case CMD_ALLOCATIONS:
635
636#ifdef ACPI_DBG_TRACK_ALLOCATIONS
637        AcpiUtDumpAllocations ((UINT32) -1, NULL);
638#endif
639        break;
640
641    case CMD_ARGS:
642    case CMD_ARGUMENTS:
643        AcpiDbDisplayArguments ();
644        break;
645
646    case CMD_BATCH:
647        AcpiDbBatchExecute (AcpiGbl_DbArgs[1]);
648        break;
649
650    case CMD_BREAKPOINT:
651        AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
652        break;
653
654    case CMD_BUSINFO:
655        AcpiDbGetBusInfo ();
656        break;
657
658    case CMD_CALL:
659        AcpiDbSetMethodCallBreakpoint (Op);
660        Status = AE_OK;
661        break;
662
663    case CMD_CLOSE:
664        AcpiDbCloseDebugFile ();
665        break;
666
667    case CMD_DEBUG:
668        AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], EX_SINGLE_STEP);
669        break;
670
671    case CMD_DISASSEMBLE:
672        (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
673        break;
674
675    case CMD_DUMP:
676        AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
677        break;
678
679    case CMD_ENABLEACPI:
680        Status = AcpiEnable();
681        if (ACPI_FAILURE(Status))
682        {
683            AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
684            return (Status);
685        }
686        break;
687
688    case CMD_EVENT:
689        AcpiOsPrintf ("Event command not implemented\n");
690        break;
691
692    case CMD_EXECUTE:
693        AcpiDbExecute (AcpiGbl_DbArgs[1],
694            &AcpiGbl_DbArgs[2], EX_NO_SINGLE_STEP);
695        break;
696
697    case CMD_FIND:
698        Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
699        break;
700
701    case CMD_GO:
702        AcpiGbl_CmSingleStep = FALSE;
703        return (AE_OK);
704
705    case CMD_GPE:
706        AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
707        break;
708
709    case CMD_GPES:
710        AcpiDbDisplayGpes ();
711        break;
712
713    case CMD_HELP:
714    case CMD_HELP2:
715        AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]);
716        break;
717
718    case CMD_HISTORY:
719        AcpiDbDisplayHistory ();
720        break;
721
722    case CMD_HISTORY_EXE:
723        CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
724        if (!CommandLine)
725        {
726            return (AE_CTRL_TRUE);
727        }
728
729        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
730        return (Status);
731
732    case CMD_HISTORY_LAST:
733        CommandLine = AcpiDbGetFromHistory (NULL);
734        if (!CommandLine)
735        {
736            return (AE_CTRL_TRUE);
737        }
738
739        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
740        return (Status);
741
742    case CMD_INFORMATION:
743        AcpiDbDisplayMethodInfo (Op);
744        break;
745
746    case CMD_INTEGRITY:
747        AcpiDbCheckIntegrity ();
748        break;
749
750    case CMD_INTO:
751        if (Op)
752        {
753            AcpiGbl_CmSingleStep = TRUE;
754            return (AE_OK);
755        }
756        break;
757
758    case CMD_LEVEL:
759        if (ParamCount == 0)
760        {
761            AcpiOsPrintf ("Current debug level for file output is:    %8.8lX\n",
762                AcpiGbl_DbDebugLevel);
763            AcpiOsPrintf ("Current debug level for console output is: %8.8lX\n",
764                AcpiGbl_DbConsoleDebugLevel);
765        }
766        else if (ParamCount == 2)
767        {
768            Temp = AcpiGbl_DbConsoleDebugLevel;
769            AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
770                                            NULL, 16);
771            AcpiOsPrintf (
772                "Debug Level for console output was %8.8lX, now %8.8lX\n",
773                Temp, AcpiGbl_DbConsoleDebugLevel);
774        }
775        else
776        {
777            Temp = AcpiGbl_DbDebugLevel;
778            AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
779            AcpiOsPrintf (
780                "Debug Level for file output was %8.8lX, now %8.8lX\n",
781                Temp, AcpiGbl_DbDebugLevel);
782        }
783        break;
784
785    case CMD_LIST:
786        AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
787        break;
788
789    case CMD_LOAD:
790        Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL);
791        break;
792
793    case CMD_LOCKS:
794        AcpiDbDisplayLocks ();
795        break;
796
797    case CMD_LOCALS:
798        AcpiDbDisplayLocals ();
799        break;
800
801    case CMD_METHODS:
802        Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
803        break;
804
805    case CMD_NAMESPACE:
806        AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
807        break;
808
809    case CMD_NOTIFY:
810        Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
811        AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
812        break;
813
814    case CMD_OBJECT:
815        AcpiUtStrupr (AcpiGbl_DbArgs[1]);
816        Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
817        break;
818
819    case CMD_OPEN:
820        AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
821        break;
822
823    case CMD_OWNER:
824        AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
825        break;
826
827    case CMD_PREDEFINED:
828        AcpiDbCheckPredefinedNames ();
829        break;
830
831    case CMD_PREFIX:
832        AcpiDbSetScope (AcpiGbl_DbArgs[1]);
833        break;
834
835    case CMD_REFERENCES:
836        AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
837        break;
838
839    case CMD_RESOURCES:
840        AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
841        break;
842
843    case CMD_RESULTS:
844        AcpiDbDisplayResults ();
845        break;
846
847    case CMD_SET:
848        AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
849            AcpiGbl_DbArgs[3]);
850        break;
851
852    case CMD_SLEEP:
853        Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
854        break;
855
856    case CMD_STATS:
857        Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
858        break;
859
860    case CMD_STOP:
861        return (AE_NOT_IMPLEMENTED);
862
863    case CMD_TABLES:
864        AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
865        break;
866
867    case CMD_TERMINATE:
868        AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
869        AcpiUtSubsystemShutdown ();
870
871        /*
872         * TBD: [Restructure] Need some way to re-initialize without
873         * re-creating the semaphores!
874         */
875
876        /*  AcpiInitialize (NULL);  */
877        break;
878
879    case CMD_THREADS:
880        AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
881            AcpiGbl_DbArgs[3]);
882        break;
883
884    case CMD_TRACE:
885        (void) AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1);
886        break;
887
888    case CMD_TREE:
889        AcpiDbDisplayCallingTree ();
890        break;
891
892    case CMD_TYPE:
893        AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
894        break;
895
896    case CMD_UNLOAD:
897        AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
898        break;
899
900    case CMD_EXIT:
901    case CMD_QUIT:
902        if (Op)
903        {
904            AcpiOsPrintf ("Method execution terminated\n");
905            return (AE_CTRL_TERMINATE);
906        }
907
908        if (!AcpiGbl_DbOutputToFile)
909        {
910            AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
911        }
912
913        AcpiDbCloseDebugFile ();
914        AcpiGbl_DbTerminateThreads = TRUE;
915        return (AE_CTRL_TERMINATE);
916
917    case CMD_NOT_FOUND:
918    default:
919        AcpiOsPrintf ("Unknown Command\n");
920        return (AE_CTRL_TRUE);
921    }
922
923    if (ACPI_SUCCESS (Status))
924    {
925        Status = AE_CTRL_TRUE;
926    }
927
928    /* Add all commands that come here to the history buffer */
929
930    AcpiDbAddToHistory (InputBuffer);
931    return (Status);
932}
933
934
935/*******************************************************************************
936 *
937 * FUNCTION:    AcpiDbExecuteThread
938 *
939 * PARAMETERS:  Context         - Not used
940 *
941 * RETURN:      None
942 *
943 * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
944 *              simply dispatches it.
945 *
946 ******************************************************************************/
947
948void ACPI_SYSTEM_XFACE
949AcpiDbExecuteThread (
950    void                    *Context)
951{
952    ACPI_STATUS             Status = AE_OK;
953    ACPI_STATUS             MStatus;
954
955
956    while (Status != AE_CTRL_TERMINATE)
957    {
958        AcpiGbl_MethodExecuting = FALSE;
959        AcpiGbl_StepToNextCall = FALSE;
960
961        MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
962        if (ACPI_FAILURE (MStatus))
963        {
964            return;
965        }
966
967        Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
968
969        MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
970        if (ACPI_FAILURE (MStatus))
971        {
972            return;
973        }
974    }
975}
976
977
978/*******************************************************************************
979 *
980 * FUNCTION:    AcpiDbSingleThread
981 *
982 * PARAMETERS:  None
983 *
984 * RETURN:      None
985 *
986 * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
987 *              simply dispatches it.
988 *
989 ******************************************************************************/
990
991static void
992AcpiDbSingleThread (
993    void)
994{
995
996    AcpiGbl_MethodExecuting = FALSE;
997    AcpiGbl_StepToNextCall = FALSE;
998
999    (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
1000}
1001
1002
1003/*******************************************************************************
1004 *
1005 * FUNCTION:    AcpiDbUserCommands
1006 *
1007 * PARAMETERS:  Prompt              - User prompt (depends on mode)
1008 *              Op                  - Current executing parse op
1009 *
1010 * RETURN:      None
1011 *
1012 * DESCRIPTION: Command line execution for the AML debugger.  Commands are
1013 *              matched and dispatched here.
1014 *
1015 ******************************************************************************/
1016
1017ACPI_STATUS
1018AcpiDbUserCommands (
1019    char                    Prompt,
1020    ACPI_PARSE_OBJECT       *Op)
1021{
1022    ACPI_STATUS             Status = AE_OK;
1023
1024
1025    /* TBD: [Restructure] Need a separate command line buffer for step mode */
1026
1027    while (!AcpiGbl_DbTerminateThreads)
1028    {
1029        /* Force output to console until a command is entered */
1030
1031        AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1032
1033        /* Different prompt if method is executing */
1034
1035        if (!AcpiGbl_MethodExecuting)
1036        {
1037            AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
1038        }
1039        else
1040        {
1041            AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
1042        }
1043
1044        /* Get the user input line */
1045
1046        (void) AcpiOsGetLine (AcpiGbl_DbLineBuf);
1047
1048        /* Check for single or multithreaded debug */
1049
1050        if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
1051        {
1052            /*
1053             * Signal the debug thread that we have a command to execute,
1054             * and wait for the command to complete.
1055             */
1056            Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
1057            if (ACPI_FAILURE (Status))
1058            {
1059                return (Status);
1060            }
1061
1062            Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
1063            if (ACPI_FAILURE (Status))
1064            {
1065                return (Status);
1066            }
1067        }
1068        else
1069        {
1070            /* Just call to the command line interpreter */
1071
1072            AcpiDbSingleThread ();
1073        }
1074    }
1075
1076    /*
1077     * Only this thread (the original thread) should actually terminate the
1078     * subsystem, because all the semaphores are deleted during termination
1079     */
1080    Status = AcpiTerminate ();
1081    return (Status);
1082}
1083
1084#endif  /* ACPI_DEBUGGER */
1085
1086