Correct problem with keyboard input not being accepted
[reactos.git] / reactos / ntoskrnl / kd / kdebug.c
1 /* $Id: kdebug.c,v 1.23 2001/04/10 17:48:17 dwelch Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/kd/kdebug.c
6 * PURPOSE: Kernel debugger
7 * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
8 * UPDATE HISTORY:
9 * 21/10/99: Created
10 */
11
12 #include <ddk/ntddk.h>
13 #include <internal/ntoskrnl.h>
14 #include <internal/kd.h>
15 #include <internal/mm.h>
16 #include <internal/config.h>
17 #include "../dbg/kdb.h"
18
19 /* serial debug connection */
20 #define DEFAULT_DEBUG_PORT 2 /* COM2 */
21 #define DEFAULT_DEBUG_BAUD_RATE 19200 /* 19200 Baud */
22
23 /* bochs debug output */
24 #define BOCHS_LOGGER_PORT (0xe9)
25
26
27 /* TYPEDEFS ****************************************************************/
28
29 #define ScreenDebug (0x1)
30 #define SerialDebug (0x2)
31 #define BochsDebug (0x4)
32 #define FileLogDebug (0x8)
33
34 /* VARIABLES ***************************************************************/
35
36 BOOLEAN
37 __declspec(dllexport)
38 KdDebuggerEnabled = FALSE; /* EXPORTED */
39
40 BOOLEAN
41 __declspec(dllexport)
42 KdDebuggerNotPresent = TRUE; /* EXPORTED */
43
44
45 static BOOLEAN KdpBreakPending = FALSE;
46 static BOOLEAN KdpBreakRecieved = FALSE;
47 static ULONG KdpDebugType = ScreenDebug | BochsDebug;
48
49 /* PRIVATE FUNCTIONS ********************************************************/
50
51 static void
52 PrintString (char* fmt,...)
53 {
54 char buffer[512];
55 va_list ap;
56
57 va_start(ap, fmt);
58 vsprintf(buffer, fmt, ap);
59 va_end(ap);
60
61 HalDisplayString (buffer);
62 }
63
64
65 VOID
66 KdInitSystem (
67 ULONG Reserved,
68 PLOADER_PARAMETER_BLOCK LoaderBlock
69 )
70 {
71 KD_PORT_INFORMATION PortInfo;
72 ULONG Value;
73 PCHAR p1, p2;
74
75 /* set debug port default values */
76 PortInfo.ComPort = DEFAULT_DEBUG_PORT;
77 PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
78
79 /*
80 * parse kernel command line
81 */
82
83 /* check for 'DEBUGPORT' */
84 p1 = (PCHAR)LoaderBlock->CommandLine;
85 while (p1 && (p2 = strchr (p1, '/')))
86 {
87 p2++;
88 if (!_strnicmp (p2, "DEBUGPORT", 9))
89 {
90 p2 += 9;
91 if (*p2 != '=')
92 break;
93 p2++;
94 if (!_strnicmp (p2, "SCREEN", 6))
95 {
96 p2 += 6;
97 KdDebuggerEnabled = TRUE;
98 KdpDebugType |= ScreenDebug;
99 }
100 else if (!_strnicmp (p2, "BOCHS", 5))
101 {
102 p2 += 5;
103 KdDebuggerEnabled = TRUE;
104 KdpDebugType |= BochsDebug;
105 }
106 else if (!_strnicmp (p2, "COM", 3))
107 {
108 p2 += 3;
109 Value = (ULONG)atol (p2);
110 if (Value > 0 && Value < 5)
111 {
112 KdDebuggerEnabled = TRUE;
113 KdpDebugType |= SerialDebug;
114 PortInfo.ComPort = Value;
115 }
116 }
117 break;
118 }
119 p1 = p2;
120 }
121
122
123
124 /* check for 'BAUDRATE' */
125 p1 = (PCHAR)LoaderBlock->CommandLine;
126 while (p1 && (p2 = strchr (p1, '/')))
127 {
128 p2++;
129 if (!_strnicmp (p2, "BAUDRATE", 8))
130 {
131 p2 += 8;
132 if (*p2 != '=')
133 break;
134 p2++;
135 Value = (ULONG)atol (p2);
136 if (Value > 0)
137 {
138 KdDebuggerEnabled = TRUE;
139 KdpDebugType = KdpDebugType | SerialDebug;
140 PortInfo.BaudRate = Value;
141 }
142 break;
143 }
144 p1 = p2;
145 }
146
147 /* Check for 'DEBUG'. Dont' accept 'DEBUGPORT'!*/
148 p1 = (PCHAR)LoaderBlock->CommandLine;
149 while (p1 && (p2 = strchr (p1, '/')))
150 {
151 p2++;
152 if (!_strnicmp (p2, "DEBUG", 5) &&
153 _strnicmp (p2, "DEBUGPORT", 9))
154 {
155 p2 += 5;
156 KdDebuggerEnabled = TRUE;
157 KdpDebugType = KdpDebugType | SerialDebug;
158 break;
159 }
160 p1 = p2;
161 }
162
163 /* Check for 'NODEBUG' */
164 p1 = (PCHAR)LoaderBlock->CommandLine;
165 while (p1 && (p2 = strchr (p1, '/')))
166 {
167 p2++;
168 if (!_strnicmp (p2, "NODEBUG", 7))
169 {
170 p2 += 7;
171 KdDebuggerEnabled = FALSE;
172 break;
173 }
174 p1 = p2;
175 }
176
177 /* Check for 'CRASHDEBUG' */
178 p1 = (PCHAR)LoaderBlock->CommandLine;
179 while (p1 && (p2 = strchr (p1, '/')))
180 {
181 p2++;
182 if (!_strnicmp (p2, "CRASHDEBUG", 10))
183 {
184 p2 += 10;
185 KdDebuggerEnabled = FALSE;
186 break;
187 }
188 p1 = p2;
189 }
190
191 /* Check for 'BREAK' */
192 p1 = (PCHAR)LoaderBlock->CommandLine;
193 while (p1 && (p2 = strchr (p1, '/')))
194 {
195 p2++;
196 if (!_strnicmp (p2, "BREAK", 5))
197 {
198 p2 += 7;
199 KdpBreakPending = TRUE;
200 break;
201 }
202 p1 = p2;
203 }
204
205 #ifdef DBGPRINT_FILE_LOG
206 KdpDebugType |= FileLogDebug;
207 DebugLogInit();
208 #endif /* DBGPRINT_FILE_LOG */
209
210 /* print some information */
211 if (KdDebuggerEnabled == TRUE)
212 {
213 if (KdpDebugType & ScreenDebug)
214 {
215 PrintString ("\n Screen debugging enabled\n\n");
216 }
217 if (KdpDebugType & BochsDebug)
218 {
219 PrintString ("\n Bochs debugging enabled\n\n");
220 }
221 if (KdpDebugType & SerialDebug)
222 {
223 PrintString ("\n Serial debugging enabled: COM%ld %ld Baud\n\n",
224 PortInfo.ComPort, PortInfo.BaudRate);
225 }
226 if (KdpDebugType & FileLogDebug)
227 {
228 PrintString("\n File log debugging enabled\n\n");
229 }
230 }
231 else
232 PrintString ("\n Debugging disabled\n\n");
233
234
235 /* initialize debug port */
236 if (KdDebuggerEnabled && (KdpDebugType & SerialDebug))
237 {
238 KdPortInitialize (&PortInfo,
239 0,
240 0);
241 }
242 }
243
244
245 ULONG KdpPrintString (PANSI_STRING String)
246 {
247 PCH pch = String->Buffer;
248
249 if (KdpDebugType & ScreenDebug)
250 {
251 HalDisplayString (String->Buffer);
252 }
253 if (KdpDebugType & SerialDebug)
254 {
255 while (*pch != 0)
256 {
257 if (*pch == '\n')
258 {
259 KdPortPutByte ('\r');
260 }
261 KdPortPutByte (*pch);
262 pch++;
263 }
264 }
265 if (KdpDebugType & BochsDebug)
266 {
267 while (*pch != 0)
268 {
269 if (*pch == '\n')
270 {
271 WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, '\r');
272 }
273 WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, *pch);
274 pch++;
275 }
276 }
277 #ifdef DBGPRINT_FILE_LOG
278 if (KdpDebugType & FileLogDebug)
279 {
280 DebugLogWrite(String->Buffer);
281 }
282 #endif /* DBGPRINT_FILE_LOG */
283 return (ULONG)String->Length;
284 }
285
286 /* PUBLIC FUNCTIONS *********************************************************/
287
288 /* NTOSKRNL.KdPollBreakIn */
289
290 BOOLEAN
291 STDCALL
292 KdPollBreakIn (
293 VOID
294 )
295 {
296 BOOLEAN Result = FALSE;
297 UCHAR ByteRead;
298
299 if (KdDebuggerEnabled == FALSE || KdpDebugType != SerialDebug)
300 return Result;
301
302 // Flags = KiDisableInterrupts();
303
304 HalDisplayString ("Waiting for kernel debugger connection...\n");
305
306 if (KdPortPollByte (&ByteRead))
307 {
308 if (ByteRead == 0x62)
309 {
310 if (KdpBreakPending == TRUE)
311 {
312 KdpBreakPending = FALSE;
313 KdpBreakRecieved = TRUE;
314 Result = TRUE;
315 }
316 HalDisplayString (" Kernel debugger connected\n");
317 }
318 else
319 {
320 HalDisplayString (" Kernel debugger connection failed\n");
321 }
322 }
323
324 // KiRestoreInterrupts (Flags);
325
326 return Result;
327 }
328
329 VOID STDCALL
330 KeEnterKernelDebugger (VOID)
331 {
332 HalDisplayString ("\n\n *** Entered kernel debugger ***\n");
333
334 #if 1
335 for (;;)
336 __asm__("hlt\n\t");
337 #else
338 for(;;);
339 #endif
340 }
341
342 VOID STDCALL
343 KdSystemDebugControl(ULONG Code)
344 {
345 /* A - Dump the entire contents of the non-paged pool. */
346 if (Code == 0)
347 {
348 MiDebugDumpNonPagedPool(FALSE);
349 }
350 /* B - Bug check the system. */
351 else if (Code == 1)
352 {
353 KeBugCheck(0);
354 }
355 /*
356 * C - Dump statistics about the distribution of tagged blocks in
357 * the non-paged pool.
358 */
359 else if (Code == 2)
360 {
361 MiDebugDumpNonPagedPoolStats(FALSE);
362 }
363 /*
364 * D - Dump the blocks created in the non-paged pool since the last
365 * SysRq + D and SysRq + E command.
366 */
367 else if (Code == 3)
368 {
369 MiDebugDumpNonPagedPool(TRUE);
370 }
371 /* E - Dump statistics about the tags of newly created blocks. */
372 else if (Code == 4)
373 {
374 MiDebugDumpNonPagedPoolStats(TRUE);
375 }
376 /* F */
377 else if (Code == 5)
378 {
379 }
380 /* G */
381 else if (Code == 6)
382 {
383 }
384 /* H */
385 else if (Code == 7)
386 {
387 }
388 /* I */
389 else if (Code == 8)
390 {
391 }
392 /* J */
393 else if (Code == 9)
394 {
395 }
396 /* K - Enter the system debugger. */
397 else if (Code == 10)
398 {
399 #ifdef KDBG
400 KdbEnter();
401 #else /* KDBG */
402 DbgPrint("No local kernel debugger\n");
403 #endif /* not KDBG */
404 }
405 }
406
407 /* EOF */