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 */
75 * Top-level debugger commands.
77 * This list of commands must match the string table below it
79 enum AcpiExDebuggerCommands
142 #define CMD_FIRST_VALID 2
145 /* Second parameter is the required argument count */
147 static const COMMAND_INFO AcpiGbl_DbCommands[] =
212 /*******************************************************************************
214 * FUNCTION: AcpiDbDisplayHelp
220 * DESCRIPTION: Print a usage message.
222 ******************************************************************************/
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");
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");
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");
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");
307 /*******************************************************************************
309 * FUNCTION: AcpiDbGetNextToken
311 * PARAMETERS: String - Command buffer
312 * Next - Return value, end of next token
314 * RETURN: Pointer to the start of the next token.
316 * DESCRIPTION: Command line parsing. Get the next token on the command line
318 ******************************************************************************/
324 ACPI_OBJECT_TYPE *ReturnType)
328 ACPI_OBJECT_TYPE Type = ACPI_TYPE_INTEGER;
331 /* At end of buffer? */
333 if (!String || !(*String))
338 /* Remove any spaces at the beginning */
342 while (*String && (*String == ' '))
357 /* This is a quoted string, scan until closing quote */
361 Type = ACPI_TYPE_STRING;
363 /* Find end of string */
365 while (*String && (*String != '"'))
373 /* This is the start of a buffer, scan until closing paren */
377 Type = ACPI_TYPE_BUFFER;
379 /* Find end of buffer */
381 while (*String && (*String != ')'))
389 /* This is the start of a package, scan until closing bracket */
394 Type = ACPI_TYPE_PACKAGE;
396 /* Find end of package (closing bracket) */
400 /* Handle String package elements */
404 /* Find end of string */
407 while (*String && (*String != '"'))
416 else if (*String == '[')
418 Depth++; /* A nested package declaration */
420 else if (*String == ']')
423 if (Depth == 0) /* Found final package closing bracket */
437 /* Find end of token */
439 while (*String && (*String != ' '))
461 /*******************************************************************************
463 * FUNCTION: AcpiDbGetLine
465 * PARAMETERS: InputBuffer - Command line buffer
467 * RETURN: Count of arguments to the command
469 * DESCRIPTION: Get the next command line from the user. Gets entire line
470 * up to the next newline
472 ******************************************************************************/
484 ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
486 This = AcpiGbl_DbParsedBuf;
487 for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
489 AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next,
490 &AcpiGbl_DbArgTypes[i]);
491 if (!AcpiGbl_DbArgs[i])
499 /* Uppercase the actual command */
501 if (AcpiGbl_DbArgs[0])
503 AcpiUtStrupr (AcpiGbl_DbArgs[0]);
509 Count--; /* Number of args only */
516 /*******************************************************************************
518 * FUNCTION: AcpiDbMatchCommand
520 * PARAMETERS: UserCommand - User command line
522 * RETURN: Index into command array, -1 if not found
524 * DESCRIPTION: Search command array for a command match
526 ******************************************************************************/
535 if (!UserCommand || UserCommand[0] == 0)
540 for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
542 if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
543 AcpiGbl_DbCommands[i].Name)
549 /* Command not recognized */
551 return (CMD_NOT_FOUND);
555 /*******************************************************************************
557 * FUNCTION: AcpiDbCommandDispatch
559 * PARAMETERS: InputBuffer - Command line buffer
560 * WalkState - Current walk
561 * Op - Current (executing) parse op
565 * DESCRIPTION: Command dispatcher.
567 ******************************************************************************/
570 AcpiDbCommandDispatch (
572 ACPI_WALK_STATE *WalkState,
573 ACPI_PARSE_OBJECT *Op)
579 ACPI_STATUS Status = AE_CTRL_TRUE;
582 /* If AcpiTerminate has been called, terminate this thread */
584 if (AcpiGbl_DbTerminateThreads)
586 return (AE_CTRL_TERMINATE);
589 ParamCount = AcpiDbGetLine (InputBuffer);
590 CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
593 /* Verify that we have the minimum number of params */
595 if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
597 AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
598 ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
599 AcpiGbl_DbCommands[CommandIndex].MinArgs);
601 return (AE_CTRL_TRUE);
604 /* Decode and dispatch the command */
606 switch (CommandIndex)
615 case CMD_ALLOCATIONS:
617 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
618 AcpiUtDumpAllocations ((UINT32) -1, NULL);
624 AcpiDbDisplayArguments ();
628 AcpiDbBatchExecute (AcpiGbl_DbArgs[1]);
632 AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
640 AcpiDbSetMethodCallBreakpoint (Op);
645 AcpiDbCloseDebugFile ();
649 AcpiDbExecute (AcpiGbl_DbArgs[1],
650 &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP);
653 case CMD_DISASSEMBLE:
654 (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
658 AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
662 Status = AcpiEnable();
663 if (ACPI_FAILURE(Status))
665 AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
671 AcpiOsPrintf ("Event command not implemented\n");
675 AcpiDbExecute (AcpiGbl_DbArgs[1],
676 &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP);
680 Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
684 AcpiGbl_CmSingleStep = FALSE;
688 AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
692 AcpiDbDisplayGpes ();
696 AcpiDbDisplayHandlers ();
701 AcpiDbDisplayHelp ();
705 AcpiDbDisplayHistory ();
708 case CMD_HISTORY_EXE:
709 CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
712 return (AE_CTRL_TRUE);
715 Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
718 case CMD_HISTORY_LAST:
719 CommandLine = AcpiDbGetFromHistory (NULL);
722 return (AE_CTRL_TRUE);
725 Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
728 case CMD_INFORMATION:
729 AcpiDbDisplayMethodInfo (Op);
733 AcpiDbCheckIntegrity ();
739 AcpiGbl_CmSingleStep = TRUE;
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);
752 else if (ParamCount == 2)
754 Temp = AcpiGbl_DbConsoleDebugLevel;
755 AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
758 "Debug Level for console output was %8.8lX, now %8.8lX\n",
759 Temp, AcpiGbl_DbConsoleDebugLevel);
763 Temp = AcpiGbl_DbDebugLevel;
764 AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
766 "Debug Level for file output was %8.8lX, now %8.8lX\n",
767 Temp, AcpiGbl_DbDebugLevel);
772 AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
776 Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL);
780 AcpiDbDisplayLocks ();
784 AcpiDbDisplayLocals ();
788 Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
792 AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
796 Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
797 AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
801 AcpiUtStrupr (AcpiGbl_DbArgs[1]);
802 Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
806 AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
810 AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
814 AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
818 AcpiDbCheckPredefinedNames ();
822 AcpiDbSetScope (AcpiGbl_DbArgs[1]);
826 AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
830 AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
834 AcpiDbDisplayResults ();
838 AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
843 Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
847 Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
851 return (AE_NOT_IMPLEMENTED);
854 AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
858 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
859 AcpiUtSubsystemShutdown ();
862 * TBD: [Restructure] Need some way to re-initialize without
863 * re-creating the semaphores!
866 /* AcpiInitialize (NULL); */
870 AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
875 (void) AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1);
879 AcpiDbDisplayCallingTree ();
883 AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
887 AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
894 AcpiOsPrintf ("Method execution terminated\n");
895 return (AE_CTRL_TERMINATE);
898 if (!AcpiGbl_DbOutputToFile)
900 AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
903 AcpiDbCloseDebugFile ();
904 AcpiGbl_DbTerminateThreads = TRUE;
905 return (AE_CTRL_TERMINATE);
909 AcpiOsPrintf ("Unknown Command\n");
910 return (AE_CTRL_TRUE);
913 if (ACPI_SUCCESS (Status))
915 Status = AE_CTRL_TRUE;
918 /* Add all commands that come here to the history buffer */
920 AcpiDbAddToHistory (InputBuffer);
925 /*******************************************************************************
927 * FUNCTION: AcpiDbExecuteThread
929 * PARAMETERS: Context - Not used
933 * DESCRIPTION: Debugger execute thread. Waits for a command line, then
934 * simply dispatches it.
936 ******************************************************************************/
938 void ACPI_SYSTEM_XFACE
939 AcpiDbExecuteThread (
942 ACPI_STATUS Status = AE_OK;
946 while (Status != AE_CTRL_TERMINATE)
948 AcpiGbl_MethodExecuting = FALSE;
949 AcpiGbl_StepToNextCall = FALSE;
951 MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
952 if (ACPI_FAILURE (MStatus))
957 Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
959 MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
960 if (ACPI_FAILURE (MStatus))
968 /*******************************************************************************
970 * FUNCTION: AcpiDbSingleThread
976 * DESCRIPTION: Debugger execute thread. Waits for a command line, then
977 * simply dispatches it.
979 ******************************************************************************/
986 AcpiGbl_MethodExecuting = FALSE;
987 AcpiGbl_StepToNextCall = FALSE;
989 (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
993 /*******************************************************************************
995 * FUNCTION: AcpiDbUserCommands
997 * PARAMETERS: Prompt - User prompt (depends on mode)
998 * Op - Current executing parse op
1002 * DESCRIPTION: Command line execution for the AML debugger. Commands are
1003 * matched and dispatched here.
1005 ******************************************************************************/
1008 AcpiDbUserCommands (
1010 ACPI_PARSE_OBJECT *Op)
1012 ACPI_STATUS Status = AE_OK;
1015 /* TBD: [Restructure] Need a separate command line buffer for step mode */
1017 while (!AcpiGbl_DbTerminateThreads)
1019 /* Force output to console until a command is entered */
1021 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1023 /* Different prompt if method is executing */
1025 if (!AcpiGbl_MethodExecuting)
1027 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
1031 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
1034 /* Get the user input line */
1036 Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
1037 ACPI_DB_LINE_BUFFER_SIZE, NULL);
1038 if (ACPI_FAILURE (Status))
1040 ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line"));
1044 /* Check for single or multithreaded debug */
1046 if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
1049 * Signal the debug thread that we have a command to execute,
1050 * and wait for the command to complete.
1052 Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
1053 if (ACPI_FAILURE (Status))
1058 Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
1059 if (ACPI_FAILURE (Status))
1066 /* Just call to the command line interpreter */
1068 AcpiDbSingleThread ();
1073 * Only this thread (the original thread) should actually terminate the
1074 * subsystem, because all the semaphores are deleted during termination
1076 Status = AcpiTerminate ();
1080 #endif /* ACPI_DEBUGGER */