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