1 /*******************************************************************************
3 * Module Name: dbinput - user front-end to the AML debugger
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2011, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
45 #include <contrib/dev/acpica/include/acpi.h>
46 #include <contrib/dev/acpica/include/accommon.h>
47 #include <contrib/dev/acpica/include/acdebug.h>
52 #define _COMPONENT ACPI_CA_DEBUGGER
53 ACPI_MODULE_NAME ("dbinput")
55 /* Local prototypes */
80 * Top-level debugger commands.
82 * This list of commands must match the string table below it
84 enum AcpiExDebuggerCommands
146 #define CMD_FIRST_VALID 2
149 /* Second parameter is the required argument count */
151 static const COMMAND_INFO AcpiGbl_DbCommands[] =
215 /*******************************************************************************
217 * FUNCTION: AcpiDbDisplayHelp
219 * PARAMETERS: HelpType - Subcommand (optional)
223 * DESCRIPTION: Print a usage message.
225 ******************************************************************************/
232 AcpiUtStrupr (HelpType);
234 /* No parameter, just give the overview */
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");
250 * Parameter is the command class
252 * The idea here is to keep each class of commands smaller than a screenful
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");
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");
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");
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");
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");
340 AcpiOsPrintf ("Unrecognized Command Class: %s\n", HelpType);
346 /*******************************************************************************
348 * FUNCTION: AcpiDbGetNextToken
350 * PARAMETERS: String - Command buffer
351 * Next - Return value, end of next token
353 * RETURN: Pointer to the start of the next token.
355 * DESCRIPTION: Command line parsing. Get the next token on the command line
357 ******************************************************************************/
367 /* At end of buffer? */
369 if (!String || !(*String))
374 /* Get rid of any spaces at the beginning */
378 while (*String && (*String == ' '))
391 /* This is a quoted string, scan until closing quote */
396 /* Find end of token */
398 while (*String && (*String != '"'))
407 /* Find end of token */
409 while (*String && (*String != ' '))
429 /*******************************************************************************
431 * FUNCTION: AcpiDbGetLine
433 * PARAMETERS: InputBuffer - Command line buffer
435 * RETURN: Count of arguments to the command
437 * DESCRIPTION: Get the next command line from the user. Gets entire line
438 * up to the next newline
440 ******************************************************************************/
452 ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
454 This = AcpiGbl_DbParsedBuf;
455 for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
457 AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next);
458 if (!AcpiGbl_DbArgs[i])
466 /* Uppercase the actual command */
468 if (AcpiGbl_DbArgs[0])
470 AcpiUtStrupr (AcpiGbl_DbArgs[0]);
476 Count--; /* Number of args only */
483 /*******************************************************************************
485 * FUNCTION: AcpiDbMatchCommand
487 * PARAMETERS: UserCommand - User command line
489 * RETURN: Index into command array, -1 if not found
491 * DESCRIPTION: Search command array for a command match
493 ******************************************************************************/
502 if (!UserCommand || UserCommand[0] == 0)
507 for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
509 if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
510 AcpiGbl_DbCommands[i].Name)
516 /* Command not recognized */
518 return (CMD_NOT_FOUND);
522 /*******************************************************************************
524 * FUNCTION: AcpiDbCommandDispatch
526 * PARAMETERS: InputBuffer - Command line buffer
527 * WalkState - Current walk
528 * Op - Current (executing) parse op
532 * DESCRIPTION: Command dispatcher.
534 ******************************************************************************/
537 AcpiDbCommandDispatch (
539 ACPI_WALK_STATE *WalkState,
540 ACPI_PARSE_OBJECT *Op)
546 ACPI_STATUS Status = AE_CTRL_TRUE;
549 /* If AcpiTerminate has been called, terminate this thread */
551 if (AcpiGbl_DbTerminateThreads)
553 return (AE_CTRL_TERMINATE);
556 ParamCount = AcpiDbGetLine (InputBuffer);
557 CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
560 /* Verify that we have the minimum number of params */
562 if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
564 AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
565 ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
566 AcpiGbl_DbCommands[CommandIndex].MinArgs);
568 return (AE_CTRL_TRUE);
571 /* Decode and dispatch the command */
573 switch (CommandIndex)
582 case CMD_ALLOCATIONS:
584 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
585 AcpiUtDumpAllocations ((UINT32) -1, NULL);
591 AcpiDbDisplayArguments ();
595 AcpiDbBatchExecute (AcpiGbl_DbArgs[1]);
599 AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
607 AcpiDbSetMethodCallBreakpoint (Op);
612 AcpiDbCloseDebugFile ();
616 AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], EX_SINGLE_STEP);
619 case CMD_DISASSEMBLE:
620 (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
624 AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
628 Status = AcpiEnable();
629 if (ACPI_FAILURE(Status))
631 AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
637 AcpiOsPrintf ("Event command not implemented\n");
641 AcpiDbExecute (AcpiGbl_DbArgs[1],
642 &AcpiGbl_DbArgs[2], EX_NO_SINGLE_STEP);
646 Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
650 AcpiGbl_CmSingleStep = FALSE;
654 AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
658 AcpiDbDisplayGpes ();
663 AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]);
667 AcpiDbDisplayHistory ();
670 case CMD_HISTORY_EXE:
671 CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
674 return (AE_CTRL_TRUE);
677 Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
680 case CMD_HISTORY_LAST:
681 CommandLine = AcpiDbGetFromHistory (NULL);
684 return (AE_CTRL_TRUE);
687 Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
690 case CMD_INFORMATION:
691 AcpiDbDisplayMethodInfo (Op);
695 AcpiDbCheckIntegrity ();
701 AcpiGbl_CmSingleStep = TRUE;
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);
714 else if (ParamCount == 2)
716 Temp = AcpiGbl_DbConsoleDebugLevel;
717 AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
720 "Debug Level for console output was %8.8lX, now %8.8lX\n",
721 Temp, AcpiGbl_DbConsoleDebugLevel);
725 Temp = AcpiGbl_DbDebugLevel;
726 AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
728 "Debug Level for file output was %8.8lX, now %8.8lX\n",
729 Temp, AcpiGbl_DbDebugLevel);
734 AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
738 Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL);
742 AcpiDbDisplayLocks ();
746 AcpiDbDisplayLocals ();
750 Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
754 AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
758 Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
759 AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
763 AcpiUtStrupr (AcpiGbl_DbArgs[1]);
764 Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
768 AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
772 AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
776 AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
780 AcpiDbCheckPredefinedNames ();
784 AcpiDbSetScope (AcpiGbl_DbArgs[1]);
788 AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
792 AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
796 AcpiDbDisplayResults ();
800 AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
805 Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
809 Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
813 return (AE_NOT_IMPLEMENTED);
816 AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
820 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
821 AcpiUtSubsystemShutdown ();
824 * TBD: [Restructure] Need some way to re-initialize without
825 * re-creating the semaphores!
828 /* AcpiInitialize (NULL); */
832 AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
837 (void) AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1);
841 AcpiDbDisplayCallingTree ();
845 AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
849 AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
856 AcpiOsPrintf ("Method execution terminated\n");
857 return (AE_CTRL_TERMINATE);
860 if (!AcpiGbl_DbOutputToFile)
862 AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
865 AcpiDbCloseDebugFile ();
866 AcpiGbl_DbTerminateThreads = TRUE;
867 return (AE_CTRL_TERMINATE);
871 AcpiOsPrintf ("Unknown Command\n");
872 return (AE_CTRL_TRUE);
875 if (ACPI_SUCCESS (Status))
877 Status = AE_CTRL_TRUE;
880 /* Add all commands that come here to the history buffer */
882 AcpiDbAddToHistory (InputBuffer);
887 /*******************************************************************************
889 * FUNCTION: AcpiDbExecuteThread
891 * PARAMETERS: Context - Not used
895 * DESCRIPTION: Debugger execute thread. Waits for a command line, then
896 * simply dispatches it.
898 ******************************************************************************/
900 void ACPI_SYSTEM_XFACE
901 AcpiDbExecuteThread (
904 ACPI_STATUS Status = AE_OK;
908 while (Status != AE_CTRL_TERMINATE)
910 AcpiGbl_MethodExecuting = FALSE;
911 AcpiGbl_StepToNextCall = FALSE;
913 MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
914 if (ACPI_FAILURE (MStatus))
919 Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
921 MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
922 if (ACPI_FAILURE (MStatus))
930 /*******************************************************************************
932 * FUNCTION: AcpiDbSingleThread
938 * DESCRIPTION: Debugger execute thread. Waits for a command line, then
939 * simply dispatches it.
941 ******************************************************************************/
948 AcpiGbl_MethodExecuting = FALSE;
949 AcpiGbl_StepToNextCall = FALSE;
951 (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
955 /*******************************************************************************
957 * FUNCTION: AcpiDbUserCommands
959 * PARAMETERS: Prompt - User prompt (depends on mode)
960 * Op - Current executing parse op
964 * DESCRIPTION: Command line execution for the AML debugger. Commands are
965 * matched and dispatched here.
967 ******************************************************************************/
972 ACPI_PARSE_OBJECT *Op)
974 ACPI_STATUS Status = AE_OK;
977 /* TBD: [Restructure] Need a separate command line buffer for step mode */
979 while (!AcpiGbl_DbTerminateThreads)
981 /* Force output to console until a command is entered */
983 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
985 /* Different prompt if method is executing */
987 if (!AcpiGbl_MethodExecuting)
989 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
993 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
996 /* Get the user input line */
998 (void) AcpiOsGetLine (AcpiGbl_DbLineBuf);
1000 /* Check for single or multithreaded debug */
1002 if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
1005 * Signal the debug thread that we have a command to execute,
1006 * and wait for the command to complete.
1008 Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
1009 if (ACPI_FAILURE (Status))
1014 Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
1015 if (ACPI_FAILURE (Status))
1022 /* Just call to the command line interpreter */
1024 AcpiDbSingleThread ();
1029 * Only this thread (the original thread) should actually terminate the
1030 * subsystem, because all the semaphores are deleted during termination
1032 Status = AcpiTerminate ();
1036 #endif /* ACPI_DEBUGGER */