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