dbinput.c revision 222544
1/*******************************************************************************
2 *
3 * Module Name: dbinput - user front-end to the AML debugger
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <contrib/dev/acpica/include/acpi.h>
46#include <contrib/dev/acpica/include/accommon.h>
47#include <contrib/dev/acpica/include/acdebug.h>
48
49
50#ifdef ACPI_DEBUGGER
51
52#define _COMPONENT          ACPI_CA_DEBUGGER
53        ACPI_MODULE_NAME    ("dbinput")
54
55/* Local prototypes */
56
57static UINT32
58AcpiDbGetLine (
59    char                    *InputBuffer);
60
61static UINT32
62AcpiDbMatchCommand (
63    char                    *UserCommand);
64
65static void
66AcpiDbSingleThread (
67    void);
68
69static void
70AcpiDbDisplayHelp (
71    void);
72
73
74/*
75 * Top-level debugger commands.
76 *
77 * This list of commands must match the string table below it
78 */
79enum AcpiExDebuggerCommands
80{
81    CMD_NOT_FOUND = 0,
82    CMD_NULL,
83    CMD_ALLOCATIONS,
84    CMD_ARGS,
85    CMD_ARGUMENTS,
86    CMD_BATCH,
87    CMD_BREAKPOINT,
88    CMD_BUSINFO,
89    CMD_CALL,
90    CMD_CLOSE,
91    CMD_DEBUG,
92    CMD_DISASSEMBLE,
93    CMD_DUMP,
94    CMD_ENABLEACPI,
95    CMD_EVENT,
96    CMD_EXECUTE,
97    CMD_EXIT,
98    CMD_FIND,
99    CMD_GO,
100    CMD_GPE,
101    CMD_GPES,
102    CMD_HANDLERS,
103    CMD_HELP,
104    CMD_HELP2,
105    CMD_HISTORY,
106    CMD_HISTORY_EXE,
107    CMD_HISTORY_LAST,
108    CMD_INFORMATION,
109    CMD_INTEGRITY,
110    CMD_INTO,
111    CMD_LEVEL,
112    CMD_LIST,
113    CMD_LOAD,
114    CMD_LOCALS,
115    CMD_LOCKS,
116    CMD_METHODS,
117    CMD_NAMESPACE,
118    CMD_NOTIFY,
119    CMD_OBJECT,
120    CMD_OPEN,
121    CMD_OSI,
122    CMD_OWNER,
123    CMD_PREDEFINED,
124    CMD_PREFIX,
125    CMD_QUIT,
126    CMD_REFERENCES,
127    CMD_RESOURCES,
128    CMD_RESULTS,
129    CMD_SET,
130    CMD_SLEEP,
131    CMD_STATS,
132    CMD_STOP,
133    CMD_TABLES,
134    CMD_TERMINATE,
135    CMD_THREADS,
136    CMD_TRACE,
137    CMD_TREE,
138    CMD_TYPE,
139    CMD_UNLOAD
140};
141
142#define CMD_FIRST_VALID     2
143
144
145/* Second parameter is the required argument count */
146
147static const COMMAND_INFO       AcpiGbl_DbCommands[] =
148{
149    {"<NOT FOUND>",  0},
150    {"<NULL>",       0},
151    {"ALLOCATIONS",  0},
152    {"ARGS",         0},
153    {"ARGUMENTS",    0},
154    {"BATCH",        0},
155    {"BREAKPOINT",   1},
156    {"BUSINFO",      0},
157    {"CALL",         0},
158    {"CLOSE",        0},
159    {"DEBUG",        1},
160    {"DISASSEMBLE",  1},
161    {"DUMP",         1},
162    {"ENABLEACPI",   0},
163    {"EVENT",        1},
164    {"EXECUTE",      1},
165    {"EXIT",         0},
166    {"FIND",         1},
167    {"GO",           0},
168    {"GPE",          2},
169    {"GPES",         0},
170    {"HANDLERS",     0},
171    {"HELP",         0},
172    {"?",            0},
173    {"HISTORY",      0},
174    {"!",            1},
175    {"!!",           0},
176    {"INFORMATION",  0},
177    {"INTEGRITY",    0},
178    {"INTO",         0},
179    {"LEVEL",        0},
180    {"LIST",         0},
181    {"LOAD",         1},
182    {"LOCALS",       0},
183    {"LOCKS",        0},
184    {"METHODS",      0},
185    {"NAMESPACE",    0},
186    {"NOTIFY",       2},
187    {"OBJECT",       1},
188    {"OPEN",         1},
189    {"OSI",          0},
190    {"OWNER",        1},
191    {"PREDEFINED",   0},
192    {"PREFIX",       0},
193    {"QUIT",         0},
194    {"REFERENCES",   1},
195    {"RESOURCES",    1},
196    {"RESULTS",      0},
197    {"SET",          3},
198    {"SLEEP",        1},
199    {"STATS",        0},
200    {"STOP",         0},
201    {"TABLES",       0},
202    {"TERMINATE",    0},
203    {"THREADS",      3},
204    {"TRACE",        1},
205    {"TREE",         0},
206    {"TYPE",         1},
207    {"UNLOAD",       1},
208    {NULL,           0}
209};
210
211
212/*******************************************************************************
213 *
214 * FUNCTION:    AcpiDbDisplayHelp
215 *
216 * PARAMETERS:  None
217 *
218 * RETURN:      None
219 *
220 * DESCRIPTION: Print a usage message.
221 *
222 ******************************************************************************/
223
224static void
225AcpiDbDisplayHelp (
226    void)
227{
228
229    AcpiOsPrintf ("\nGeneral-Purpose Commands:\n");
230    AcpiOsPrintf ("  Allocations                         Display list of current memory allocations\n");
231    AcpiOsPrintf ("  Dump <Address>|<Namepath>\n");
232    AcpiOsPrintf ("       [Byte|Word|Dword|Qword]        Display ACPI objects or memory\n");
233    AcpiOsPrintf ("  EnableAcpi                          Enable ACPI (hardware) mode\n");
234    AcpiOsPrintf ("  Handlers                            Info about global handlers\n");
235    AcpiOsPrintf ("  Help                                This help screen\n");
236    AcpiOsPrintf ("  History                             Display command history buffer\n");
237    AcpiOsPrintf ("  Level [<DebugLevel>] [console]      Get/Set debug level for file or console\n");
238    AcpiOsPrintf ("  Locks                               Current status of internal mutexes\n");
239    AcpiOsPrintf ("  Osi [Install|Remove <name>]         Display or modify global _OSI list\n");
240    AcpiOsPrintf ("  Quit or Exit                        Exit this command\n");
241    AcpiOsPrintf ("  Stats [Allocations|Memory|Misc|\n");
242    AcpiOsPrintf ("        Objects|Sizes|Stack|Tables]   Display namespace and memory statistics\n");
243    AcpiOsPrintf ("     Allocations                      Display list of current memory allocations\n");
244    AcpiOsPrintf ("     Memory                           Dump internal memory lists\n");
245    AcpiOsPrintf ("     Misc                             Namespace search and mutex stats\n");
246    AcpiOsPrintf ("     Objects                          Summary of namespace objects\n");
247    AcpiOsPrintf ("     Sizes                            Sizes for each of the internal objects\n");
248    AcpiOsPrintf ("     Stack                            Display CPU stack usage\n");
249    AcpiOsPrintf ("     Tables                           Info about current ACPI table(s)\n");
250    AcpiOsPrintf ("  Tables                              Display info about loaded ACPI tables\n");
251    AcpiOsPrintf ("  Unload <TableSig> [Instance]        Unload an ACPI table\n");
252    AcpiOsPrintf ("  ! <CommandNumber>                   Execute command from history buffer\n");
253    AcpiOsPrintf ("  !!                                  Execute last command again\n");
254
255    AcpiOsPrintf ("\nNamespace Access Commands:\n");
256    AcpiOsPrintf ("  Businfo                             Display system bus info\n");
257    AcpiOsPrintf ("  Disassemble <Method>                Disassemble a control method\n");
258    AcpiOsPrintf ("  Event <F|G> <Value>                 Generate AcpiEvent (Fixed/GPE)\n");
259    AcpiOsPrintf ("  Find <AcpiName>  (? is wildcard)    Find ACPI name(s) with wildcards\n");
260    AcpiOsPrintf ("  Gpe <GpeNum> <GpeBlock>             Simulate a GPE\n");
261    AcpiOsPrintf ("  Gpes                                Display info on all GPEs\n");
262    AcpiOsPrintf ("  Integrity                           Validate namespace integrity\n");
263    AcpiOsPrintf ("  Methods                             Display list of loaded control methods\n");
264    AcpiOsPrintf ("  Namespace [Object] [Depth]          Display loaded namespace tree/subtree\n");
265    AcpiOsPrintf ("  Notify <Object> <Value>             Send a notification on Object\n");
266    AcpiOsPrintf ("  Objects <ObjectType>                Display all objects of the given type\n");
267    AcpiOsPrintf ("  Owner <OwnerId> [Depth]             Display loaded namespace by object owner\n");
268    AcpiOsPrintf ("  Predefined                          Check all predefined names\n");
269    AcpiOsPrintf ("  Prefix [<NamePath>]                 Set or Get current execution prefix\n");
270    AcpiOsPrintf ("  References <Addr>                   Find all references to object at addr\n");
271    AcpiOsPrintf ("  Resources <Device>                  Get and display Device resources\n");
272    AcpiOsPrintf ("  Set N <NamedObject> <Value>         Set value for named integer\n");
273    AcpiOsPrintf ("  Sleep <SleepState>                  Simulate sleep/wake sequence\n");
274    AcpiOsPrintf ("  Terminate                           Delete namespace and all internal objects\n");
275    AcpiOsPrintf ("  Type <Object>                       Display object type\n");
276
277    AcpiOsPrintf ("\nControl Method Execution Commands:\n");
278    AcpiOsPrintf ("  Arguments (or Args)                 Display method arguments\n");
279    AcpiOsPrintf ("  Breakpoint <AmlOffset>              Set an AML execution breakpoint\n");
280    AcpiOsPrintf ("  Call                                Run to next control method invocation\n");
281    AcpiOsPrintf ("  Debug <Namepath> [Arguments]        Single Step a control method\n");
282    AcpiOsPrintf ("  Execute <Namepath> [Arguments]      Execute control method\n");
283    AcpiOsPrintf ("     Hex Integer                      Integer method argument\n");
284    AcpiOsPrintf ("     \"Ascii String\"                   String method argument\n");
285    AcpiOsPrintf ("     (Byte List)                      Buffer method argument\n");
286    AcpiOsPrintf ("     [Package Element List]           Package method argument\n");
287    AcpiOsPrintf ("  Go                                  Allow method to run to completion\n");
288    AcpiOsPrintf ("  Information                         Display info about the current method\n");
289    AcpiOsPrintf ("  Into                                Step into (not over) a method call\n");
290    AcpiOsPrintf ("  List [# of Aml Opcodes]             Display method ASL statements\n");
291    AcpiOsPrintf ("  Locals                              Display method local variables\n");
292    AcpiOsPrintf ("  Results                             Display method result stack\n");
293    AcpiOsPrintf ("  Set <A|L> <#> <Value>               Set method data (Arguments/Locals)\n");
294    AcpiOsPrintf ("  Stop                                Terminate control method\n");
295    AcpiOsPrintf ("  Thread <Threads><Loops><NamePath>   Spawn threads to execute method(s)\n");
296    AcpiOsPrintf ("  Trace <method name>                 Trace method execution\n");
297    AcpiOsPrintf ("  Tree                                Display control method calling tree\n");
298    AcpiOsPrintf ("  <Enter>                             Single step next AML opcode (over calls)\n");
299
300    AcpiOsPrintf ("\nFile I/O Commands:\n");
301    AcpiOsPrintf ("  Close                               Close debug output file\n");
302    AcpiOsPrintf ("  Load <Input Filename>               Load ACPI table from a file\n");
303    AcpiOsPrintf ("  Open <Output Filename>              Open a file for debug output\n");
304}
305
306
307/*******************************************************************************
308 *
309 * FUNCTION:    AcpiDbGetNextToken
310 *
311 * PARAMETERS:  String          - Command buffer
312 *              Next            - Return value, end of next token
313 *
314 * RETURN:      Pointer to the start of the next token.
315 *
316 * DESCRIPTION: Command line parsing.  Get the next token on the command line
317 *
318 ******************************************************************************/
319
320char *
321AcpiDbGetNextToken (
322    char                    *String,
323    char                    **Next,
324    ACPI_OBJECT_TYPE        *ReturnType)
325{
326    char                    *Start;
327    UINT32                  Depth;
328    ACPI_OBJECT_TYPE        Type = ACPI_TYPE_INTEGER;
329
330
331    /* At end of buffer? */
332
333    if (!String || !(*String))
334    {
335        return (NULL);
336    }
337
338    /* Remove any spaces at the beginning */
339
340    if (*String == ' ')
341    {
342        while (*String && (*String == ' '))
343        {
344            String++;
345        }
346
347        if (!(*String))
348        {
349            return (NULL);
350        }
351    }
352
353    switch (*String)
354    {
355    case '"':
356
357        /* This is a quoted string, scan until closing quote */
358
359        String++;
360        Start = String;
361        Type = ACPI_TYPE_STRING;
362
363        /* Find end of string */
364
365        while (*String && (*String != '"'))
366        {
367            String++;
368        }
369        break;
370
371    case '(':
372
373        /* This is the start of a buffer, scan until closing paren */
374
375        String++;
376        Start = String;
377        Type = ACPI_TYPE_BUFFER;
378
379        /* Find end of buffer */
380
381        while (*String && (*String != ')'))
382        {
383            String++;
384        }
385        break;
386
387    case '[':
388
389        /* This is the start of a package, scan until closing bracket */
390
391        String++;
392        Depth = 1;
393        Start = String;
394        Type = ACPI_TYPE_PACKAGE;
395
396        /* Find end of package (closing bracket) */
397
398        while (*String)
399        {
400            /* Handle String package elements */
401
402            if (*String == '"')
403            {
404                /* Find end of string */
405
406                String++;
407                while (*String && (*String != '"'))
408                {
409                    String++;
410                }
411                if (!(*String))
412                {
413                    break;
414                }
415            }
416            else if (*String == '[')
417            {
418                Depth++;         /* A nested package declaration */
419            }
420            else if (*String == ']')
421            {
422                Depth--;
423                if (Depth == 0) /* Found final package closing bracket */
424                {
425                    break;
426                }
427            }
428
429            String++;
430        }
431        break;
432
433    default:
434
435        Start = String;
436
437        /* Find end of token */
438
439        while (*String && (*String != ' '))
440        {
441            String++;
442        }
443        break;
444    }
445
446    if (!(*String))
447    {
448        *Next = NULL;
449    }
450    else
451    {
452        *String = 0;
453        *Next = String + 1;
454    }
455
456    *ReturnType = Type;
457    return (Start);
458}
459
460
461/*******************************************************************************
462 *
463 * FUNCTION:    AcpiDbGetLine
464 *
465 * PARAMETERS:  InputBuffer         - Command line buffer
466 *
467 * RETURN:      Count of arguments to the command
468 *
469 * DESCRIPTION: Get the next command line from the user.  Gets entire line
470 *              up to the next newline
471 *
472 ******************************************************************************/
473
474static UINT32
475AcpiDbGetLine (
476    char                    *InputBuffer)
477{
478    UINT32                  i;
479    UINT32                  Count;
480    char                    *Next;
481    char                    *This;
482
483
484    ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
485
486    This = AcpiGbl_DbParsedBuf;
487    for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
488    {
489        AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next,
490            &AcpiGbl_DbArgTypes[i]);
491        if (!AcpiGbl_DbArgs[i])
492        {
493            break;
494        }
495
496        This = Next;
497    }
498
499    /* Uppercase the actual command */
500
501    if (AcpiGbl_DbArgs[0])
502    {
503        AcpiUtStrupr (AcpiGbl_DbArgs[0]);
504    }
505
506    Count = i;
507    if (Count)
508    {
509        Count--;  /* Number of args only */
510    }
511
512    return (Count);
513}
514
515
516/*******************************************************************************
517 *
518 * FUNCTION:    AcpiDbMatchCommand
519 *
520 * PARAMETERS:  UserCommand             - User command line
521 *
522 * RETURN:      Index into command array, -1 if not found
523 *
524 * DESCRIPTION: Search command array for a command match
525 *
526 ******************************************************************************/
527
528static UINT32
529AcpiDbMatchCommand (
530    char                    *UserCommand)
531{
532    UINT32                  i;
533
534
535    if (!UserCommand || UserCommand[0] == 0)
536    {
537        return (CMD_NULL);
538    }
539
540    for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
541    {
542        if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
543                         AcpiGbl_DbCommands[i].Name)
544        {
545            return (i);
546        }
547    }
548
549    /* Command not recognized */
550
551    return (CMD_NOT_FOUND);
552}
553
554
555/*******************************************************************************
556 *
557 * FUNCTION:    AcpiDbCommandDispatch
558 *
559 * PARAMETERS:  InputBuffer         - Command line buffer
560 *              WalkState           - Current walk
561 *              Op                  - Current (executing) parse op
562 *
563 * RETURN:      Status
564 *
565 * DESCRIPTION: Command dispatcher.
566 *
567 ******************************************************************************/
568
569ACPI_STATUS
570AcpiDbCommandDispatch (
571    char                    *InputBuffer,
572    ACPI_WALK_STATE         *WalkState,
573    ACPI_PARSE_OBJECT       *Op)
574{
575    UINT32                  Temp;
576    UINT32                  CommandIndex;
577    UINT32                  ParamCount;
578    char                    *CommandLine;
579    ACPI_STATUS             Status = AE_CTRL_TRUE;
580
581
582    /* If AcpiTerminate has been called, terminate this thread */
583
584    if (AcpiGbl_DbTerminateThreads)
585    {
586        return (AE_CTRL_TERMINATE);
587    }
588
589    ParamCount = AcpiDbGetLine (InputBuffer);
590    CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
591    Temp = 0;
592
593    /* Verify that we have the minimum number of params */
594
595    if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
596    {
597        AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
598            ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
599            AcpiGbl_DbCommands[CommandIndex].MinArgs);
600
601        return (AE_CTRL_TRUE);
602    }
603
604    /* Decode and dispatch the command */
605
606    switch (CommandIndex)
607    {
608    case CMD_NULL:
609        if (Op)
610        {
611            return (AE_OK);
612        }
613        break;
614
615    case CMD_ALLOCATIONS:
616
617#ifdef ACPI_DBG_TRACK_ALLOCATIONS
618        AcpiUtDumpAllocations ((UINT32) -1, NULL);
619#endif
620        break;
621
622    case CMD_ARGS:
623    case CMD_ARGUMENTS:
624        AcpiDbDisplayArguments ();
625        break;
626
627    case CMD_BATCH:
628        AcpiDbBatchExecute (AcpiGbl_DbArgs[1]);
629        break;
630
631    case CMD_BREAKPOINT:
632        AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
633        break;
634
635    case CMD_BUSINFO:
636        AcpiDbGetBusInfo ();
637        break;
638
639    case CMD_CALL:
640        AcpiDbSetMethodCallBreakpoint (Op);
641        Status = AE_OK;
642        break;
643
644    case CMD_CLOSE:
645        AcpiDbCloseDebugFile ();
646        break;
647
648    case CMD_DEBUG:
649        AcpiDbExecute (AcpiGbl_DbArgs[1],
650            &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP);
651        break;
652
653    case CMD_DISASSEMBLE:
654        (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
655        break;
656
657    case CMD_DUMP:
658        AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
659        break;
660
661    case CMD_ENABLEACPI:
662        Status = AcpiEnable();
663        if (ACPI_FAILURE(Status))
664        {
665            AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
666            return (Status);
667        }
668        break;
669
670    case CMD_EVENT:
671        AcpiOsPrintf ("Event command not implemented\n");
672        break;
673
674    case CMD_EXECUTE:
675        AcpiDbExecute (AcpiGbl_DbArgs[1],
676            &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP);
677        break;
678
679    case CMD_FIND:
680        Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
681        break;
682
683    case CMD_GO:
684        AcpiGbl_CmSingleStep = FALSE;
685        return (AE_OK);
686
687    case CMD_GPE:
688        AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
689        break;
690
691    case CMD_GPES:
692        AcpiDbDisplayGpes ();
693        break;
694
695    case CMD_HANDLERS:
696        AcpiDbDisplayHandlers ();
697        break;
698
699    case CMD_HELP:
700    case CMD_HELP2:
701        AcpiDbDisplayHelp ();
702        break;
703
704    case CMD_HISTORY:
705        AcpiDbDisplayHistory ();
706        break;
707
708    case CMD_HISTORY_EXE:
709        CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
710        if (!CommandLine)
711        {
712            return (AE_CTRL_TRUE);
713        }
714
715        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
716        return (Status);
717
718    case CMD_HISTORY_LAST:
719        CommandLine = AcpiDbGetFromHistory (NULL);
720        if (!CommandLine)
721        {
722            return (AE_CTRL_TRUE);
723        }
724
725        Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
726        return (Status);
727
728    case CMD_INFORMATION:
729        AcpiDbDisplayMethodInfo (Op);
730        break;
731
732    case CMD_INTEGRITY:
733        AcpiDbCheckIntegrity ();
734        break;
735
736    case CMD_INTO:
737        if (Op)
738        {
739            AcpiGbl_CmSingleStep = TRUE;
740            return (AE_OK);
741        }
742        break;
743
744    case CMD_LEVEL:
745        if (ParamCount == 0)
746        {
747            AcpiOsPrintf ("Current debug level for file output is:    %8.8lX\n",
748                AcpiGbl_DbDebugLevel);
749            AcpiOsPrintf ("Current debug level for console output is: %8.8lX\n",
750                AcpiGbl_DbConsoleDebugLevel);
751        }
752        else if (ParamCount == 2)
753        {
754            Temp = AcpiGbl_DbConsoleDebugLevel;
755            AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
756                                            NULL, 16);
757            AcpiOsPrintf (
758                "Debug Level for console output was %8.8lX, now %8.8lX\n",
759                Temp, AcpiGbl_DbConsoleDebugLevel);
760        }
761        else
762        {
763            Temp = AcpiGbl_DbDebugLevel;
764            AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
765            AcpiOsPrintf (
766                "Debug Level for file output was %8.8lX, now %8.8lX\n",
767                Temp, AcpiGbl_DbDebugLevel);
768        }
769        break;
770
771    case CMD_LIST:
772        AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
773        break;
774
775    case CMD_LOAD:
776        Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL);
777        break;
778
779    case CMD_LOCKS:
780        AcpiDbDisplayLocks ();
781        break;
782
783    case CMD_LOCALS:
784        AcpiDbDisplayLocals ();
785        break;
786
787    case CMD_METHODS:
788        Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
789        break;
790
791    case CMD_NAMESPACE:
792        AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
793        break;
794
795    case CMD_NOTIFY:
796        Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
797        AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
798        break;
799
800    case CMD_OBJECT:
801        AcpiUtStrupr (AcpiGbl_DbArgs[1]);
802        Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
803        break;
804
805    case CMD_OPEN:
806        AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
807        break;
808
809    case CMD_OSI:
810        AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
811        break;
812
813    case CMD_OWNER:
814        AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
815        break;
816
817    case CMD_PREDEFINED:
818        AcpiDbCheckPredefinedNames ();
819        break;
820
821    case CMD_PREFIX:
822        AcpiDbSetScope (AcpiGbl_DbArgs[1]);
823        break;
824
825    case CMD_REFERENCES:
826        AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
827        break;
828
829    case CMD_RESOURCES:
830        AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
831        break;
832
833    case CMD_RESULTS:
834        AcpiDbDisplayResults ();
835        break;
836
837    case CMD_SET:
838        AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
839            AcpiGbl_DbArgs[3]);
840        break;
841
842    case CMD_SLEEP:
843        Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
844        break;
845
846    case CMD_STATS:
847        Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
848        break;
849
850    case CMD_STOP:
851        return (AE_NOT_IMPLEMENTED);
852
853    case CMD_TABLES:
854        AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
855        break;
856
857    case CMD_TERMINATE:
858        AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
859        AcpiUtSubsystemShutdown ();
860
861        /*
862         * TBD: [Restructure] Need some way to re-initialize without
863         * re-creating the semaphores!
864         */
865
866        /*  AcpiInitialize (NULL);  */
867        break;
868
869    case CMD_THREADS:
870        AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
871            AcpiGbl_DbArgs[3]);
872        break;
873
874    case CMD_TRACE:
875        (void) AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1);
876        break;
877
878    case CMD_TREE:
879        AcpiDbDisplayCallingTree ();
880        break;
881
882    case CMD_TYPE:
883        AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
884        break;
885
886    case CMD_UNLOAD:
887        AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
888        break;
889
890    case CMD_EXIT:
891    case CMD_QUIT:
892        if (Op)
893        {
894            AcpiOsPrintf ("Method execution terminated\n");
895            return (AE_CTRL_TERMINATE);
896        }
897
898        if (!AcpiGbl_DbOutputToFile)
899        {
900            AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
901        }
902
903        AcpiDbCloseDebugFile ();
904        AcpiGbl_DbTerminateThreads = TRUE;
905        return (AE_CTRL_TERMINATE);
906
907    case CMD_NOT_FOUND:
908    default:
909        AcpiOsPrintf ("Unknown Command\n");
910        return (AE_CTRL_TRUE);
911    }
912
913    if (ACPI_SUCCESS (Status))
914    {
915        Status = AE_CTRL_TRUE;
916    }
917
918    /* Add all commands that come here to the history buffer */
919
920    AcpiDbAddToHistory (InputBuffer);
921    return (Status);
922}
923
924
925/*******************************************************************************
926 *
927 * FUNCTION:    AcpiDbExecuteThread
928 *
929 * PARAMETERS:  Context         - Not used
930 *
931 * RETURN:      None
932 *
933 * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
934 *              simply dispatches it.
935 *
936 ******************************************************************************/
937
938void ACPI_SYSTEM_XFACE
939AcpiDbExecuteThread (
940    void                    *Context)
941{
942    ACPI_STATUS             Status = AE_OK;
943    ACPI_STATUS             MStatus;
944
945
946    while (Status != AE_CTRL_TERMINATE)
947    {
948        AcpiGbl_MethodExecuting = FALSE;
949        AcpiGbl_StepToNextCall = FALSE;
950
951        MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
952        if (ACPI_FAILURE (MStatus))
953        {
954            return;
955        }
956
957        Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
958
959        MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
960        if (ACPI_FAILURE (MStatus))
961        {
962            return;
963        }
964    }
965}
966
967
968/*******************************************************************************
969 *
970 * FUNCTION:    AcpiDbSingleThread
971 *
972 * PARAMETERS:  None
973 *
974 * RETURN:      None
975 *
976 * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
977 *              simply dispatches it.
978 *
979 ******************************************************************************/
980
981static void
982AcpiDbSingleThread (
983    void)
984{
985
986    AcpiGbl_MethodExecuting = FALSE;
987    AcpiGbl_StepToNextCall = FALSE;
988
989    (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
990}
991
992
993/*******************************************************************************
994 *
995 * FUNCTION:    AcpiDbUserCommands
996 *
997 * PARAMETERS:  Prompt              - User prompt (depends on mode)
998 *              Op                  - Current executing parse op
999 *
1000 * RETURN:      None
1001 *
1002 * DESCRIPTION: Command line execution for the AML debugger.  Commands are
1003 *              matched and dispatched here.
1004 *
1005 ******************************************************************************/
1006
1007ACPI_STATUS
1008AcpiDbUserCommands (
1009    char                    Prompt,
1010    ACPI_PARSE_OBJECT       *Op)
1011{
1012    ACPI_STATUS             Status = AE_OK;
1013
1014
1015    /* TBD: [Restructure] Need a separate command line buffer for step mode */
1016
1017    while (!AcpiGbl_DbTerminateThreads)
1018    {
1019        /* Force output to console until a command is entered */
1020
1021        AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1022
1023        /* Different prompt if method is executing */
1024
1025        if (!AcpiGbl_MethodExecuting)
1026        {
1027            AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
1028        }
1029        else
1030        {
1031            AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
1032        }
1033
1034        /* Get the user input line */
1035
1036        Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
1037            ACPI_DB_LINE_BUFFER_SIZE, NULL);
1038        if (ACPI_FAILURE (Status))
1039        {
1040            ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line"));
1041            return (Status);
1042        }
1043
1044        /* Check for single or multithreaded debug */
1045
1046        if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
1047        {
1048            /*
1049             * Signal the debug thread that we have a command to execute,
1050             * and wait for the command to complete.
1051             */
1052            Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
1053            if (ACPI_FAILURE (Status))
1054            {
1055                return (Status);
1056            }
1057
1058            Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
1059            if (ACPI_FAILURE (Status))
1060            {
1061                return (Status);
1062            }
1063        }
1064        else
1065        {
1066            /* Just call to the command line interpreter */
1067
1068            AcpiDbSingleThread ();
1069        }
1070    }
1071
1072    /*
1073     * Only this thread (the original thread) should actually terminate the
1074     * subsystem, because all the semaphores are deleted during termination
1075     */
1076    Status = AcpiTerminate ();
1077    return (Status);
1078}
1079
1080#endif  /* ACPI_DEBUGGER */
1081
1082