1 /******************************************************************************
2 *
3 * Module Name: osgendbg - Generic debugger command signalling
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 #include "acpi.h"
45 #include "accommon.h"
46 #include "acdebug.h"
47
48
49 #define _COMPONENT ACPI_CA_DEBUGGER
50 ACPI_MODULE_NAME ("osgendbg")
51
52
53 /* Local prototypes */
54
55 static void
56 AcpiDbRunRemoteDebugger (
57 char *BatchBuffer);
58
59
60 static ACPI_MUTEX AcpiGbl_DbCommandReady;
61 static ACPI_MUTEX AcpiGbl_DbCommandComplete;
62 static BOOLEAN AcpiGbl_DbCommandSignalsInitialized = FALSE;
63
64
65 /******************************************************************************
66 *
67 * FUNCTION: AcpiDbRunRemoteDebugger
68 *
69 * PARAMETERS: BatchBuffer - Buffer containing commands running in
70 * the batch mode
71 *
72 * RETURN: None
73 *
74 * DESCRIPTION: Run multi-threading debugger remotely
75 *
76 *****************************************************************************/
77
78 static void
AcpiDbRunRemoteDebugger(char * BatchBuffer)79 AcpiDbRunRemoteDebugger (
80 char *BatchBuffer)
81 {
82 ACPI_STATUS Status;
83 char *Ptr = BatchBuffer;
84 char *Cmd = Ptr;
85
86
87 while (!AcpiGbl_DbTerminateLoop)
88 {
89 if (BatchBuffer)
90 {
91 if (*Ptr)
92 {
93 while (*Ptr)
94 {
95 if (*Ptr == ',')
96 {
97 /* Convert commas to spaces */
98 *Ptr = ' ';
99 }
100 else if (*Ptr == ';')
101 {
102 *Ptr = '\0';
103 continue;
104 }
105
106 Ptr++;
107 }
108
109 AcpiUtSafeStrncpy (AcpiGbl_DbLineBuf, Cmd, ACPI_DB_LINE_BUFFER_SIZE);
110 Ptr++;
111 Cmd = Ptr;
112 }
113 else
114 {
115 return;
116 }
117 }
118 else
119 {
120 /* Force output to console until a command is entered */
121
122 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
123
124 /* Different prompt if method is executing */
125
126 if (!AcpiGbl_MethodExecuting)
127 {
128 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
129 }
130 else
131 {
132 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
133 }
134
135 /* Get the user input line */
136
137 Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
138 ACPI_DB_LINE_BUFFER_SIZE, NULL);
139 if (ACPI_FAILURE (Status))
140 {
141 return;
142 }
143 }
144
145 /*
146 * Signal the debug thread that we have a command to execute,
147 * and wait for the command to complete.
148 */
149 AcpiOsReleaseMutex (AcpiGbl_DbCommandReady);
150
151 Status = AcpiOsAcquireMutex (AcpiGbl_DbCommandComplete,
152 ACPI_WAIT_FOREVER);
153 if (ACPI_FAILURE (Status))
154 {
155 return;
156 }
157 }
158 }
159
160
161 /******************************************************************************
162 *
163 * FUNCTION: AcpiOsWaitCommandReady
164 *
165 * PARAMETERS: None
166 *
167 * RETURN: Status
168 *
169 * DESCRIPTION: Negotiate with the debugger foreground thread (the user
170 * thread) to wait the readiness of a command.
171 *
172 *****************************************************************************/
173
174 ACPI_STATUS
AcpiOsWaitCommandReady(void)175 AcpiOsWaitCommandReady (
176 void)
177 {
178 ACPI_STATUS Status = AE_OK;
179
180
181 if (AcpiGbl_DebuggerConfiguration == DEBUGGER_MULTI_THREADED)
182 {
183 Status = AE_TIME;
184
185 while (Status == AE_TIME)
186 {
187 if (AcpiGbl_DbTerminateLoop)
188 {
189 Status = AE_CTRL_TERMINATE;
190 }
191 else
192 {
193 Status = AcpiOsAcquireMutex (AcpiGbl_DbCommandReady, 1000);
194 }
195 }
196 }
197 else
198 {
199 /* Force output to console until a command is entered */
200
201 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
202
203 /* Different prompt if method is executing */
204
205 if (!AcpiGbl_MethodExecuting)
206 {
207 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
208 }
209 else
210 {
211 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
212 }
213
214 /* Get the user input line */
215
216 Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
217 ACPI_DB_LINE_BUFFER_SIZE, NULL);
218 }
219
220 if (ACPI_FAILURE (Status) && Status != AE_CTRL_TERMINATE)
221 {
222 ACPI_EXCEPTION ((AE_INFO, Status,
223 "While parsing/handling command line"));
224 }
225 return (Status);
226 }
227
228
229 /******************************************************************************
230 *
231 * FUNCTION: AcpiOsNotifyCommandComplete
232 *
233 * PARAMETERS: void
234 *
235 * RETURN: Status
236 *
237 * DESCRIPTION: Negotiate with the debugger foreground thread (the user
238 * thread) to notify the completion of a command.
239 *
240 *****************************************************************************/
241
242 ACPI_STATUS
AcpiOsNotifyCommandComplete(void)243 AcpiOsNotifyCommandComplete (
244 void)
245 {
246
247 if (AcpiGbl_DebuggerConfiguration == DEBUGGER_MULTI_THREADED)
248 {
249 AcpiOsReleaseMutex (AcpiGbl_DbCommandComplete);
250 }
251 return (AE_OK);
252 }
253
254
255 /******************************************************************************
256 *
257 * FUNCTION: AcpiOsInitializeDebugger
258 *
259 * PARAMETERS: None
260 *
261 * RETURN: Status
262 *
263 * DESCRIPTION: Initialize OSPM specific part of the debugger
264 *
265 *****************************************************************************/
266
267 ACPI_STATUS
AcpiOsInitializeDebugger(void)268 AcpiOsInitializeDebugger (
269 void)
270 {
271 ACPI_STATUS Status;
272
273
274 /* Create command signals */
275
276 Status = AcpiOsCreateMutex (&AcpiGbl_DbCommandReady);
277 if (ACPI_FAILURE (Status))
278 {
279 return (Status);
280 }
281 Status = AcpiOsCreateMutex (&AcpiGbl_DbCommandComplete);
282 if (ACPI_FAILURE (Status))
283 {
284 goto ErrorReady;
285 }
286
287 /* Initialize the states of the command signals */
288
289 Status = AcpiOsAcquireMutex (AcpiGbl_DbCommandComplete,
290 ACPI_WAIT_FOREVER);
291 if (ACPI_FAILURE (Status))
292 {
293 goto ErrorComplete;
294 }
295 Status = AcpiOsAcquireMutex (AcpiGbl_DbCommandReady,
296 ACPI_WAIT_FOREVER);
297 if (ACPI_FAILURE (Status))
298 {
299 goto ErrorComplete;
300 }
301
302 AcpiGbl_DbCommandSignalsInitialized = TRUE;
303 return (Status);
304
305 ErrorComplete:
306 AcpiOsDeleteMutex (AcpiGbl_DbCommandComplete);
307 ErrorReady:
308 AcpiOsDeleteMutex (AcpiGbl_DbCommandReady);
309 return (Status);
310 }
311
312
313 /******************************************************************************
314 *
315 * FUNCTION: AcpiOsTerminateDebugger
316 *
317 * PARAMETERS: None
318 *
319 * RETURN: None
320 *
321 * DESCRIPTION: Terminate signals used by the multi-threading debugger
322 *
323 *****************************************************************************/
324
325 void
AcpiOsTerminateDebugger(void)326 AcpiOsTerminateDebugger (
327 void)
328 {
329
330 if (AcpiGbl_DbCommandSignalsInitialized)
331 {
332 AcpiOsDeleteMutex (AcpiGbl_DbCommandReady);
333 AcpiOsDeleteMutex (AcpiGbl_DbCommandComplete);
334 }
335 }
336
337
338 /******************************************************************************
339 *
340 * FUNCTION: AcpiRunDebugger
341 *
342 * PARAMETERS: BatchBuffer - Buffer containing commands running in
343 * the batch mode
344 *
345 * RETURN: None
346 *
347 * DESCRIPTION: Run a local/remote debugger
348 *
349 *****************************************************************************/
350
351 void
AcpiRunDebugger(char * BatchBuffer)352 AcpiRunDebugger (
353 char *BatchBuffer)
354 {
355 /* Check for single or multithreaded debug */
356
357 if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
358 {
359 AcpiDbRunRemoteDebugger (BatchBuffer);
360 }
361 else
362 {
363 AcpiDbUserCommands ();
364 }
365 }
366
367 ACPI_EXPORT_SYMBOL (AcpiRunDebugger)
368