xref: /netbsd-src/sys/external/bsd/acpica/dist/os_specific/service_layers/osgendbg.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
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