ACPI_STATUS AcpiDbDisplayObjects ( char *ObjTypeArg, char *DisplayCountArg) { ACPI_WALK_INFO Info; ACPI_OBJECT_TYPE Type; /* Get the object type */ Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes); if (Type == ACPI_TYPE_NOT_FOUND) { AcpiOsPrintf ("Invalid or unsupported argument\n"); return (AE_OK); } AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); AcpiOsPrintf ( "Objects of type [%s] defined in the current ACPI Namespace:\n", AcpiUtGetTypeName (Type)); AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); Info.Count = 0; Info.OwnerId = ACPI_OWNER_ID_MAX; Info.DebugLevel = ACPI_UINT32_MAX; Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; /* Walk the namespace from the root */ (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL); AcpiOsPrintf ( "\nFound %u objects of type [%s] in the current ACPI Namespace\n", Info.Count, AcpiUtGetTypeName (Type)); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); return (AE_OK); }
ACPI_STATUS AcpiOsWaitCommandReady ( void) { ACPI_STATUS Status = AE_OK; if (AcpiGbl_DebuggerConfiguration == DEBUGGER_MULTI_THREADED) { Status = AE_TIME; while (Status == AE_TIME) { if (AcpiGbl_DbTerminateLoop) { Status = AE_CTRL_TERMINATE; } else { Status = AcpiOsAcquireMutex (AcpiGbl_DbCommandReady, 1000); } } } else { /* Force output to console until a command is entered */ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!AcpiGbl_MethodExecuting) { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); } else { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); } /* Get the user input line */ Status = AcpiOsGetLine (AcpiGbl_DbLineBuf, ACPI_DB_LINE_BUFFER_SIZE, NULL); } if (ACPI_FAILURE (Status) && Status != AE_CTRL_TERMINATE) { ACPI_EXCEPTION ((AE_INFO, Status, "While parsing/handling command line")); } return (Status); }
void AcpiDbDisplayResources ( char *ObjectArg) { ACPI_NAMESPACE_NODE *Node; AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); AcpiDbgLevel |= ACPI_LV_RESOURCES; /* Asterisk means "display resources for all devices" */ if (!ObjectArg || (!strcmp (ObjectArg, "*"))) { (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL); } else { /* Convert string to object pointer */ Node = AcpiDbConvertToNode (ObjectArg); if (Node) { if (Node->Type != ACPI_TYPE_DEVICE) { AcpiOsPrintf ( "%4.4s: Name is not a device object (%s)\n", Node->Name.Ascii, AcpiUtGetTypeName (Node->Type)); } else { (void) AcpiDbDeviceResources (Node, 0, NULL, NULL); } } } AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); }
void AcpiDbDumpNamespace ( char *StartArg, char *DepthArg) { ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; UINT32 MaxDepth = ACPI_UINT32_MAX; /* No argument given, just start at the root and dump entire namespace */ if (StartArg) { SubtreeEntry = AcpiDbConvertToNode (StartArg); if (!SubtreeEntry) { return; } /* Now we can check for the depth argument */ if (DepthArg) { MaxDepth = strtoul (DepthArg, NULL, 0); } } AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n", ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry); /* Display the subtree */ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, ACPI_OWNER_ID_MAX, SubtreeEntry); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); }
static void MsgClaimPci(uintptr_t rcpt, uintptr_t addr, uintptr_t pins) { addr &= 0xffff; ACPI_PCI_ID id = { 0, (addr >> 8) & 0xff, (addr >> 3) & 31, addr & 7 }; log(claim_pci, "claim pci %02x:%02x.%x\n", id.Bus, id.Device, id.Function); // Set up whatever stuff to track PCI device drivers in general int irqs[4] = {0}; for (int pin = 0; pin < 4; pin++) { if (!(pins & (1 << pin))) continue; ACPI_STATUS status = RouteIRQ(&id, 0, &irqs[pin]); CHECK_STATUS("RouteIRQ"); log(claim_pci, "%02x:%02x.%x pin %d routed to IRQ %#x\n", id.Bus, id.Device, id.Function, pin, irqs[pin]); } if (pins & ACPI_PCI_CLAIM_MASTER) { u64 value; AcpiOsReadPciConfiguration(&id, PCI_COMMAND, &value, 16); if (!(value & PCI_COMMAND_MASTER)) { value |= PCI_COMMAND_MASTER; AcpiOsWritePciConfiguration(&id, PCI_COMMAND, value, 16); } } pins = (u64)irqs[3] << 48 | (u64)irqs[2] << 32 | irqs[1] << 16 | irqs[0]; send2(MSG_ACPI_CLAIM_PCI, rcpt, addr, pins); hmod(rcpt, (uintptr_t)pci_device_handles + addr, 0); return; failed: send2(MSG_ACPI_CLAIM_PCI, rcpt, 0, 0); } static size_t debugger_buffer_pos = 0; static void debugger_pre_cmd(void) { debugger_buffer_pos = 0; AcpiGbl_MethodExecuting = FALSE; AcpiGbl_StepToNextCall = FALSE; AcpiDbSetOutputDestination(ACPI_DB_CONSOLE_OUTPUT); }
static ACPI_STATUS AcpiDbStartCommand ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) { ACPI_STATUS Status; /* TBD: [Investigate] are there namespace locking issues here? */ /* AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); */ /* Go into the command loop and await next user command */ AcpiGbl_MethodExecuting = TRUE; Status = AE_CTRL_TRUE; while (Status == AE_CTRL_TRUE) { if (AcpiGbl_DebuggerConfiguration == DEBUGGER_MULTI_THREADED) { /* Handshake with the front-end that gets user command lines */ Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE); if (ACPI_FAILURE (Status)) { return (Status); } Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY); if (ACPI_FAILURE (Status)) { return (Status); } } else { /* Single threaded, we must get a command line ourselves */ /* Force output to console until a command is entered */ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!AcpiGbl_MethodExecuting) { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); } else { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); } /* Get the user input line */ (void) AcpiOsGetLine (AcpiGbl_DbLineBuf); } Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, WalkState, Op); } /* AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); */ return (Status); }
ACPI_STATUS AcpiDbCommandDispatch ( char *InputBuffer, ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) { UINT32 Temp; UINT32 CommandIndex; UINT32 ParamCount; char *CommandLine; ACPI_STATUS Status = AE_CTRL_TRUE; /* If AcpiTerminate has been called, terminate this thread */ if (AcpiGbl_DbTerminateLoop) { return (AE_CTRL_TERMINATE); } /* Find command and add to the history buffer */ ParamCount = AcpiDbGetLine (InputBuffer); CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]); Temp = 0; /* * We don't want to add the !! command to the history buffer. It * would cause an infinite loop because it would always be the * previous command. */ if (CommandIndex != CMD_HISTORY_LAST) { AcpiDbAddToHistory (InputBuffer); } /* Verify that we have the minimum number of params */ if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs) { AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n", ParamCount, AcpiGbl_DbCommands[CommandIndex].Name, AcpiGbl_DbCommands[CommandIndex].MinArgs); AcpiDbDisplayCommandInfo ( AcpiGbl_DbCommands[CommandIndex].Name, FALSE); return (AE_CTRL_TRUE); } /* Decode and dispatch the command */ switch (CommandIndex) { case CMD_NULL: if (Op) { return (AE_OK); } break; case CMD_ALLOCATIONS: #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiUtDumpAllocations ((UINT32) -1, NULL); #endif break; case CMD_ARGS: case CMD_ARGUMENTS: AcpiDbDisplayArguments (); break; case CMD_BREAKPOINT: AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op); break; case CMD_BUSINFO: AcpiDbGetBusInfo (); break; case CMD_CALL: AcpiDbSetMethodCallBreakpoint (Op); Status = AE_OK; break; case CMD_DEBUG: AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP); break; case CMD_DISASSEMBLE: case CMD_DISASM: (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]); break; case CMD_DUMP: AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_EVALUATE: case CMD_EXECUTE: AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP); break; case CMD_FIND: Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]); break; case CMD_GO: AcpiGbl_CmSingleStep = FALSE; return (AE_OK); case CMD_HANDLERS: AcpiDbDisplayHandlers (); break; case CMD_HELP: case CMD_HELP2: AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]); break; case CMD_HISTORY: AcpiDbDisplayHistory (); break; case CMD_HISTORY_EXE: /* ! command */ CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]); if (!CommandLine) { return (AE_CTRL_TRUE); } Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op); return (Status); case CMD_HISTORY_LAST: /* !! command */ CommandLine = AcpiDbGetFromHistory (NULL); if (!CommandLine) { return (AE_CTRL_TRUE); } Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op); return (Status); case CMD_INFORMATION: AcpiDbDisplayMethodInfo (Op); break; case CMD_INTEGRITY: AcpiDbCheckIntegrity (); break; case CMD_INTO: if (Op) { AcpiGbl_CmSingleStep = TRUE; return (AE_OK); } break; case CMD_LEVEL: if (ParamCount == 0) { AcpiOsPrintf ( "Current debug level for file output is: %8.8lX\n", AcpiGbl_DbDebugLevel); AcpiOsPrintf ( "Current debug level for console output is: %8.8lX\n", AcpiGbl_DbConsoleDebugLevel); } else if (ParamCount == 2) { Temp = AcpiGbl_DbConsoleDebugLevel; AcpiGbl_DbConsoleDebugLevel = strtoul (AcpiGbl_DbArgs[1], NULL, 16); AcpiOsPrintf ( "Debug Level for console output was %8.8lX, now %8.8lX\n", Temp, AcpiGbl_DbConsoleDebugLevel); } else { Temp = AcpiGbl_DbDebugLevel; AcpiGbl_DbDebugLevel = strtoul (AcpiGbl_DbArgs[1], NULL, 16); AcpiOsPrintf ( "Debug Level for file output was %8.8lX, now %8.8lX\n", Temp, AcpiGbl_DbDebugLevel); } break; case CMD_LIST: AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op); break; case CMD_LOCKS: AcpiDbDisplayLocks (); break; case CMD_LOCALS: AcpiDbDisplayLocals (); break; case CMD_METHODS: Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]); break; case CMD_NAMESPACE: AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_NOTIFY: Temp = strtoul (AcpiGbl_DbArgs[2], NULL, 0); AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp); break; case CMD_OBJECTS: AcpiUtStrupr (AcpiGbl_DbArgs[1]); Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_OSI: AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_OWNER: AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_PATHS: AcpiDbDumpNamespacePaths (); break; case CMD_PREFIX: AcpiDbSetScope (AcpiGbl_DbArgs[1]); break; case CMD_REFERENCES: AcpiDbFindReferences (AcpiGbl_DbArgs[1]); break; case CMD_RESOURCES: AcpiDbDisplayResources (AcpiGbl_DbArgs[1]); break; case CMD_RESULTS: AcpiDbDisplayResults (); break; case CMD_SET: AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]); break; case CMD_STATS: Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]); break; case CMD_STOP: return (AE_NOT_IMPLEMENTED); case CMD_TABLES: AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]); break; case CMD_TEMPLATE: AcpiDbDisplayTemplate (AcpiGbl_DbArgs[1]); break; case CMD_TRACE: AcpiDbTrace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]); break; case CMD_TREE: AcpiDbDisplayCallingTree (); break; case CMD_TYPE: AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]); break; #ifdef ACPI_APPLICATION /* Hardware simulation commands. */ case CMD_ENABLEACPI: #if (!ACPI_REDUCED_HARDWARE) Status = AcpiEnable(); if (ACPI_FAILURE(Status)) { AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status); return (Status); } #endif /* !ACPI_REDUCED_HARDWARE */ break; case CMD_EVENT: AcpiOsPrintf ("Event command not implemented\n"); break; case CMD_GPE: AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_GPES: AcpiDbDisplayGpes (); break; case CMD_SCI: AcpiDbGenerateSci (); break; case CMD_SLEEP: Status = AcpiDbSleep (AcpiGbl_DbArgs[1]); break; /* File I/O commands. */ case CMD_CLOSE: AcpiDbCloseDebugFile (); break; case CMD_LOAD: { ACPI_NEW_TABLE_DESC *ListHead = NULL; Status = AcGetAllTablesFromFile (AcpiGbl_DbArgs[1], ACPI_GET_ALL_TABLES, &ListHead); if (ACPI_SUCCESS (Status)) { AcpiDbLoadTables (ListHead); } } break; case CMD_OPEN: AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]); break; /* User space commands. */ case CMD_TERMINATE: AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); AcpiUtSubsystemShutdown (); /* * TBD: [Restructure] Need some way to re-initialize without * re-creating the semaphores! */ AcpiGbl_DbTerminateLoop = TRUE; /* AcpiInitialize (NULL); */ break; case CMD_BACKGROUND: AcpiDbCreateExecutionThread (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2]); break; case CMD_THREADS: AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]); break; /* Debug test commands. */ case CMD_PREDEFINED: AcpiDbCheckPredefinedNames (); break; case CMD_TEST: AcpiDbExecuteTest (AcpiGbl_DbArgs[1]); break; case CMD_UNLOAD: AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1]); break; #endif case CMD_EXIT: case CMD_QUIT: if (Op) { AcpiOsPrintf ("Method execution terminated\n"); return (AE_CTRL_TERMINATE); } if (!AcpiGbl_DbOutputToFile) { AcpiDbgLevel = ACPI_DEBUG_DEFAULT; } #ifdef ACPI_APPLICATION AcpiDbCloseDebugFile (); #endif AcpiGbl_DbTerminateLoop = TRUE; return (AE_CTRL_TERMINATE); case CMD_NOT_FOUND: default: AcpiOsPrintf ("%s: unknown command\n", AcpiGbl_DbArgs[0]); return (AE_CTRL_TRUE); } if (ACPI_SUCCESS (Status)) { Status = AE_CTRL_TRUE; } return (Status); }
void AcpiDbCreateExecutionThreads ( NATIVE_CHAR *NumThreadsArg, NATIVE_CHAR *NumLoopsArg, NATIVE_CHAR *MethodNameArg) { ACPI_STATUS Status; UINT32 NumThreads; UINT32 NumLoops; UINT32 i; ACPI_HANDLE ThreadGate; /* Get the arguments */ NumThreads = STRTOUL (NumThreadsArg, NULL, 0); NumLoops = STRTOUL (NumLoopsArg, NULL, 0); if (!NumThreads || !NumLoops) { AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", NumThreads, NumLoops); return; } /* Create the synchronization semaphore */ Status = AcpiOsCreateSemaphore (1, 0, &ThreadGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore, %s\n", AcpiFormatException (Status)); return; } /* Setup the context to be passed to each thread */ AcpiGbl_DbMethodInfo.Name = MethodNameArg; AcpiGbl_DbMethodInfo.Args = NULL; AcpiGbl_DbMethodInfo.Flags = 0; AcpiGbl_DbMethodInfo.NumLoops = NumLoops; AcpiGbl_DbMethodInfo.ThreadGate = ThreadGate; AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); /* Create the threads */ AcpiOsPrintf ("Creating %X threads to execute %X times each\n", NumThreads, NumLoops); for (i = 0; i < (NumThreads); i++) { AcpiOsQueueForExecution (OSD_PRIORITY_MED, AcpiDbMethodThread, &AcpiGbl_DbMethodInfo); } /* Wait for all threads to complete */ i = NumThreads; while (i) /* Brain damage for OSD implementations that only support wait of 1 unit */ { Status = AcpiOsWaitSemaphore (ThreadGate, 1, WAIT_FOREVER); i--; } /* Cleanup and exit */ AcpiOsDeleteSemaphore (ThreadGate); AcpiDbSetOutputDestination (DB_DUPLICATE_OUTPUT); AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); AcpiDbSetOutputDestination (DB_CONSOLE_OUTPUT); }
void AcpiDbExecute ( NATIVE_CHAR *Name, NATIVE_CHAR **Args, UINT32 Flags) { ACPI_STATUS Status; ACPI_BUFFER ReturnObj; #ifdef ACPI_DEBUG UINT32 PreviousAllocations; UINT32 Allocations; /* Memory allocation tracking */ PreviousAllocations = AcpiDbGetOutstandingAllocations (); #endif AcpiGbl_DbMethodInfo.Name = Name; AcpiGbl_DbMethodInfo.Args = Args; AcpiGbl_DbMethodInfo.Flags = Flags; AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); /* * Allow any handlers in separate threads to complete. * (Such as Notify handlers invoked from AML executed above). */ AcpiOsSleep (0, 10); #ifdef ACPI_DEBUG /* Memory allocation tracking */ Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; AcpiDbSetOutputDestination (DB_DUPLICATE_OUTPUT); if (Allocations > 0) { AcpiOsPrintf ("Outstanding: %ld allocations after execution\n", Allocations); } #endif if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Execution of %s failed with status %s\n", AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); } else { /* Display a return object, if any */ if (ReturnObj.Length) { AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, ReturnObj.Length); AcpiDbDumpObject (ReturnObj.Pointer, 1); } } AcpiDbSetOutputDestination (DB_CONSOLE_OUTPUT); }
void AcpiDbExecute ( char *Name, char **Args, UINT32 Flags) { ACPI_STATUS Status; ACPI_BUFFER ReturnObj; #ifdef ACPI_DEBUG_OUTPUT UINT32 PreviousAllocations; UINT32 Allocations; /* Memory allocation tracking */ PreviousAllocations = AcpiDbGetOutstandingAllocations (); #endif if (*Name == '*') { (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL); return; } else { AcpiGbl_DbMethodInfo.Name = Name; AcpiGbl_DbMethodInfo.Args = Args; AcpiGbl_DbMethodInfo.Flags = Flags; ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); } /* * Allow any handlers in separate threads to complete. * (Such as Notify handlers invoked from AML executed above). */ AcpiOsSleep (0, 10); #ifdef ACPI_DEBUG_OUTPUT /* Memory allocation tracking */ Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); if (Allocations > 0) { AcpiOsPrintf ("Outstanding: %ld allocations after execution\n", Allocations); } #endif if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Execution of %s failed with status %s\n", AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); } else { /* Display a return object, if any */ if (ReturnObj.Length) { AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); AcpiDbDumpObject (ReturnObj.Pointer, 1); } else { AcpiOsPrintf ("No return object from execution of %s\n", AcpiGbl_DbMethodInfo.Pathname); } } AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); }
static void AcpiDbRunRemoteDebugger ( char *BatchBuffer) { ACPI_STATUS Status; char *Ptr = BatchBuffer; char *Cmd = Ptr; while (!AcpiGbl_DbTerminateLoop) { if (BatchBuffer) { if (*Ptr) { while (*Ptr) { if (*Ptr == ',') { /* Convert commas to spaces */ *Ptr = ' '; } else if (*Ptr == ';') { *Ptr = '\0'; continue; } Ptr++; } strncpy (AcpiGbl_DbLineBuf, Cmd, ACPI_DB_LINE_BUFFER_SIZE); Ptr++; Cmd = Ptr; } else { return; } } else { /* Force output to console until a command is entered */ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!AcpiGbl_MethodExecuting) { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); } else { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); } /* Get the user input line */ Status = AcpiOsGetLine (AcpiGbl_DbLineBuf, ACPI_DB_LINE_BUFFER_SIZE, NULL); if (ACPI_FAILURE (Status)) { return; } } /* * Signal the debug thread that we have a command to execute, * and wait for the command to complete. */ AcpiOsReleaseMutex (AcpiGbl_DbCommandReady); Status = AcpiOsAcquireMutex (AcpiGbl_DbCommandComplete, ACPI_WAIT_FOREVER); if (ACPI_FAILURE (Status)) { return; } } }
ACPI_STATUS AcpiDbCommandDispatch ( char *InputBuffer, ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) { UINT32 Temp; UINT32 CommandIndex; UINT32 ParamCount; char *CommandLine; ACPI_STATUS Status = AE_CTRL_TRUE; /* If AcpiTerminate has been called, terminate this thread */ if (AcpiGbl_DbTerminateThreads) { return (AE_CTRL_TERMINATE); } ParamCount = AcpiDbGetLine (InputBuffer); CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]); Temp = 0; /* Verify that we have the minimum number of params */ if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs) { AcpiOsPrintf ("%d parameters entered, [%s] requires %d parameters\n", ParamCount, AcpiGbl_DbCommands[CommandIndex].Name, AcpiGbl_DbCommands[CommandIndex].MinArgs); return (AE_CTRL_TRUE); } /* Decode and dispatch the command */ switch (CommandIndex) { case CMD_NULL: if (Op) { return (AE_OK); } break; case CMD_ALLOCATIONS: #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiUtDumpAllocations ((UINT32) -1, NULL); #endif break; case CMD_ARGS: case CMD_ARGUMENTS: AcpiDbDisplayArguments (); break; case CMD_BREAKPOINT: AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op); break; case CMD_CALL: AcpiDbSetMethodCallBreakpoint (Op); Status = AE_OK; break; case CMD_CLOSE: AcpiDbCloseDebugFile (); break; case CMD_DEBUG: AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], EX_SINGLE_STEP); break; case CMD_DUMP: AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_ENABLEACPI: Status = AcpiEnable(); if (ACPI_FAILURE(Status)) { AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status); return (Status); } break; case CMD_EVENT: AcpiOsPrintf ("Event command not implemented\n"); break; case CMD_EXECUTE: AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], EX_NO_SINGLE_STEP); break; case CMD_FIND: AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]); break; case CMD_GO: AcpiGbl_CmSingleStep = FALSE; return (AE_OK); case CMD_GPE: AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_GPES: AcpiDbDisplayGpes (); break; case CMD_HELP: case CMD_HELP2: AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]); break; case CMD_HISTORY: AcpiDbDisplayHistory (); break; case CMD_HISTORY_EXE: CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]); if (!CommandLine) { return (AE_CTRL_TRUE); } Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op); if (ACPI_SUCCESS (Status)) { Status = AE_CTRL_TRUE; } return (Status); case CMD_HISTORY_LAST: CommandLine = AcpiDbGetFromHistory (NULL); if (!CommandLine) { return (AE_CTRL_TRUE); } Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op); if (ACPI_SUCCESS (Status)) { Status = AE_CTRL_TRUE; } return (Status); case CMD_INFORMATION: AcpiDbDisplayMethodInfo (Op); break; case CMD_INTEGRITY: AcpiDbCheckIntegrity (); break; case CMD_INTO: if (Op) { AcpiGbl_CmSingleStep = TRUE; return (AE_OK); } break; case CMD_LEVEL: if (ParamCount == 0) { AcpiOsPrintf ("Current debug level for file output is: %8.8lX\n", AcpiGbl_DbDebugLevel); AcpiOsPrintf ("Current debug level for console output is: %8.8lX\n", AcpiGbl_DbConsoleDebugLevel); } else if (ParamCount == 2) { Temp = AcpiGbl_DbConsoleDebugLevel; AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16); AcpiOsPrintf ("Debug Level for console output was %8.8lX, now %8.8lX\n", Temp, AcpiGbl_DbConsoleDebugLevel); } else { Temp = AcpiGbl_DbDebugLevel; AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16); AcpiOsPrintf ("Debug Level for file output was %8.8lX, now %8.8lX\n", Temp, AcpiGbl_DbDebugLevel); } break; case CMD_LIST: AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op); break; case CMD_LOAD: Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL); if (ACPI_FAILURE (Status)) { return (Status); } break; case CMD_LOCKS: AcpiDbDisplayLocks (); break; case CMD_LOCALS: AcpiDbDisplayLocals (); break; case CMD_METHODS: AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]); break; case CMD_NAMESPACE: AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_NOTIFY: Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0); AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp); break; case CMD_OBJECT: ACPI_STRUPR (AcpiGbl_DbArgs[1]); AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_OPEN: AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]); break; case CMD_OWNER: AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_PREFIX: AcpiDbSetScope (AcpiGbl_DbArgs[1]); break; case CMD_REFERENCES: AcpiDbFindReferences (AcpiGbl_DbArgs[1]); break; case CMD_RESOURCES: AcpiDbDisplayResources (AcpiGbl_DbArgs[1]); break; case CMD_RESULTS: AcpiDbDisplayResults (); break; case CMD_SET: AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]); break; case CMD_STATS: AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]); break; case CMD_STOP: return (AE_NOT_IMPLEMENTED); case CMD_TABLES: AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]); break; case CMD_TERMINATE: AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); AcpiUtSubsystemShutdown (); /* TBD: [Restructure] Need some way to re-initialize without re-creating the semaphores! */ /* AcpiInitialize (NULL); */ break; case CMD_THREADS: AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]); break; case CMD_TREE: AcpiDbDisplayCallingTree (); break; case CMD_UNLOAD: AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_EXIT: case CMD_QUIT: if (Op) { AcpiOsPrintf ("Method execution terminated\n"); return (AE_CTRL_TERMINATE); } if (!AcpiGbl_DbOutputToFile) { AcpiDbgLevel = ACPI_DEBUG_DEFAULT; } /* Shutdown */ /* AcpiUtSubsystemShutdown (); */ AcpiDbCloseDebugFile (); AcpiGbl_DbTerminateThreads = TRUE; return (AE_CTRL_TERMINATE); case CMD_NOT_FOUND: default: AcpiOsPrintf ("Unknown Command\n"); return (AE_CTRL_TRUE); } /* Add all commands that come here to the history buffer */ AcpiDbAddToHistory (InputBuffer); return (Status); }
ACPI_STATUS AcpiDbUserCommands ( NATIVE_CHAR Prompt, ACPI_PARSE_OBJECT *Op) { ACPI_STATUS Status = AE_OK; /* TBD: [Restructure] Need a separate command line buffer for step mode */ while (!AcpiGbl_DbTerminateThreads) { /* Force output to console until a command is entered */ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!AcpiGbl_MethodExecuting) { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); } else { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); } /* Get the user input line */ (void) AcpiOsGetLine (AcpiGbl_DbLineBuf); /* Check for single or multithreaded debug */ if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED) { /* * Signal the debug thread that we have a command to execute, * and wait for the command to complete. */ Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY); if (ACPI_FAILURE (Status)) { return (Status); } Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE); if (ACPI_FAILURE (Status)) { return (Status); } } else { /* Just call to the command line interpreter */ AcpiDbSingleThread (); } } /* * Only this thread (the original thread) should actually terminate the subsystem, * because all the semaphores are deleted during termination */ Status = AcpiTerminate (); return (Status); }
ACPI_STATUS AcpiDbDisplayObjects ( char *ObjTypeArg, char *DisplayCountArg) { ACPI_WALK_INFO Info; ACPI_OBJECT_TYPE Type; ACPI_OBJECT_INFO *ObjectInfo; UINT32 i; UINT32 TotalObjects = 0; /* No argument means display summary/count of all object types */ if (!ObjTypeArg) { ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO)); /* Walk the namespace from the root */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL, (void *) ObjectInfo, NULL); AcpiOsPrintf ("\nSummary of namespace objects:\n\n"); for (i = 0; i < ACPI_TOTAL_TYPES; i++) { AcpiOsPrintf ("%8u %s\n", ObjectInfo->Types[i], AcpiUtGetTypeName (i)); TotalObjects += ObjectInfo->Types[i]; } AcpiOsPrintf ("\n%8u Total namespace objects\n\n", TotalObjects); ACPI_FREE (ObjectInfo); return (AE_OK); } /* Get the object type */ Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes); if (Type == ACPI_TYPE_NOT_FOUND) { AcpiOsPrintf ("Invalid or unsupported argument\n"); return (AE_OK); } AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); AcpiOsPrintf ( "Objects of type [%s] defined in the current ACPI Namespace:\n", AcpiUtGetTypeName (Type)); AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); Info.Count = 0; Info.OwnerId = ACPI_OWNER_ID_MAX; Info.DebugLevel = ACPI_UINT32_MAX; Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; /* Walk the namespace from the root */ (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL); AcpiOsPrintf ( "\nFound %u objects of type [%s] in the current ACPI Namespace\n", Info.Count, AcpiUtGetTypeName (Type)); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); return (AE_OK); }
void AcpiDbExecute ( char *Name, char **Args, ACPI_OBJECT_TYPE *Types, UINT32 Flags) { ACPI_STATUS Status; ACPI_BUFFER ReturnObj; char *NameString; #ifdef ACPI_DEBUG_OUTPUT UINT32 PreviousAllocations; UINT32 Allocations; /* Memory allocation tracking */ PreviousAllocations = AcpiDbGetOutstandingAllocations (); #endif if (*Name == '*') { (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL); return; } else { NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1); if (!NameString) { return; } ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); ACPI_STRCPY (NameString, Name); AcpiUtStrupr (NameString); AcpiGbl_DbMethodInfo.Name = NameString; AcpiGbl_DbMethodInfo.Args = Args; AcpiGbl_DbMethodInfo.Types = Types; AcpiGbl_DbMethodInfo.Flags = Flags; ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { ACPI_FREE (NameString); return; } /* Get the NS node, determines existence also */ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname, &AcpiGbl_DbMethodInfo.Method); if (ACPI_SUCCESS (Status)) { Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); } ACPI_FREE (NameString); } /* * Allow any handlers in separate threads to complete. * (Such as Notify handlers invoked from AML executed above). */ AcpiOsSleep ((UINT64) 10); #ifdef ACPI_DEBUG_OUTPUT /* Memory allocation tracking */ Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); if (Allocations > 0) { AcpiOsPrintf ("0x%X Outstanding allocations after evaluation of %s\n", Allocations, AcpiGbl_DbMethodInfo.Pathname); } #endif if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Evaluation of %s failed with status %s\n", AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); } else { /* Display a return object, if any */ if (ReturnObj.Length) { AcpiOsPrintf ( "Evaluation of %s returned object %p, external buffer length %X\n", AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); /* Dump a _PLD buffer if present */ if (ACPI_COMPARE_NAME ((ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, AcpiGbl_DbMethodInfo.Method)->Name.Ascii), METHOD_NAME__PLD)) { AcpiDbDumpPldBuffer (ReturnObj.Pointer); } } else { AcpiOsPrintf ("No object was returned from evaluation of %s\n", AcpiGbl_DbMethodInfo.Pathname); } } AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); }
void AcpiDbCreateExecutionThreads ( char *NumThreadsArg, char *NumLoopsArg, char *MethodNameArg) { ACPI_STATUS Status; UINT32 NumThreads; UINT32 NumLoops; UINT32 i; UINT32 Size; ACPI_MUTEX MainThreadGate; ACPI_MUTEX ThreadCompleteGate; ACPI_MUTEX InfoGate; /* Get the arguments */ NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); if (!NumThreads || !NumLoops) { AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", NumThreads, NumLoops); return; } /* * Create the semaphore for synchronization of * the created threads with the main thread. */ Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", AcpiFormatException (Status)); return; } /* * Create the semaphore for synchronization * between the created threads. */ Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", AcpiFormatException (Status)); (void) AcpiOsDeleteSemaphore (MainThreadGate); return; } Status = AcpiOsCreateSemaphore (1, 1, &InfoGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n", AcpiFormatException (Status)); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (MainThreadGate); return; } ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); /* Array to store IDs of threads */ AcpiGbl_DbMethodInfo.NumThreads = NumThreads; Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads; AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size); if (AcpiGbl_DbMethodInfo.Threads == NULL) { AcpiOsPrintf ("No memory for thread IDs array\n"); (void) AcpiOsDeleteSemaphore (MainThreadGate); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (InfoGate); return; } ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); /* Setup the context to be passed to each thread */ AcpiGbl_DbMethodInfo.Name = MethodNameArg; AcpiGbl_DbMethodInfo.Flags = 0; AcpiGbl_DbMethodInfo.NumLoops = NumLoops; AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; AcpiGbl_DbMethodInfo.InfoGate = InfoGate; /* Init arguments to be passed to method */ AcpiGbl_DbMethodInfo.InitArgs = 1; AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[3] = NULL; AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes; AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER; AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER; AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER; AcpiDbUint32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { goto CleanupAndExit; } /* Get the NS node, determines existence also */ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname, &AcpiGbl_DbMethodInfo.Method); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("%s Could not get handle for %s\n", AcpiFormatException (Status), AcpiGbl_DbMethodInfo.Pathname); goto CleanupAndExit; } /* Create the threads */ AcpiOsPrintf ("Creating %X threads to execute %X times each\n", NumThreads, NumLoops); for (i = 0; i < (NumThreads); i++) { Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, &AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { break; } } /* Wait for all threads to complete */ (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); CleanupAndExit: /* Cleanup and exit */ (void) AcpiOsDeleteSemaphore (MainThreadGate); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (InfoGate); AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); AcpiGbl_DbMethodInfo.Threads = NULL; }
ACPI_STATUS AcpiDbUserCommands ( char Prompt, ACPI_PARSE_OBJECT *Op) { ACPI_STATUS Status = AE_OK; AcpiOsPrintf ("\n"); /* TBD: [Restructure] Need a separate command line buffer for step mode */ while (!AcpiGbl_DbTerminateThreads) { /* Force output to console until a command is entered */ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!AcpiGbl_MethodExecuting) { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); } else { AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); } /* Get the user input line */ Status = AcpiOsGetLine (AcpiGbl_DbLineBuf, ACPI_DB_LINE_BUFFER_SIZE, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line")); return (Status); } /* Check for single or multithreaded debug */ if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED) { /* * Signal the debug thread that we have a command to execute, * and wait for the command to complete. */ AcpiOsReleaseMutex (AcpiGbl_DbCommandReady); if (ACPI_FAILURE (Status)) { return (Status); } Status = AcpiOsAcquireMutex (AcpiGbl_DbCommandComplete, ACPI_WAIT_FOREVER); if (ACPI_FAILURE (Status)) { return (Status); } } else { /* Just call to the command line interpreter */ AcpiDbSingleThread (); } } /* Shut down the debugger */ AcpiTerminateDebugger (); /* * Only this thread (the original thread) should actually terminate the * subsystem, because all the semaphores are deleted during termination */ Status = AcpiTerminate (); return (Status); }