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)
12 #include <ddk/ntddk.h>
13 #include <internal/ntoskrnl.h>
14 #include <internal/kd.h>
15 #include <internal/mm.h>
17 #include "../dbg/kdb.h"
19 /* serial debug connection */
20 #define DEFAULT_DEBUG_PORT 2 /* COM2 */
21 #define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
22 #define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
23 #define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
25 /* bochs debug output */
26 #define BOCHS_LOGGER_PORT (0xe9)
28 /* VARIABLES ***************************************************************/
32 KdDebuggerEnabled = FALSE; /* EXPORTED */
36 KdDebuggerNotPresent = TRUE; /* EXPORTED */
39 static BOOLEAN KdpBreakPending = FALSE;
40 ULONG KdDebugState = KD_DEBUG_DISABLED;
43 KD_PORT_INFORMATION GdbPortInfo;
44 KD_PORT_INFORMATION LogPortInfo;
46 /* PRIVATE FUNCTIONS ********************************************************/
49 PrintString(char* fmt,...)
55 vsprintf(buffer, fmt, ap);
58 HalDisplayString(buffer);
63 KdInitSystem(ULONG Reserved,
64 PLOADER_PARAMETER_BLOCK LoaderBlock)
66 KD_PORT_INFORMATION PortInfo;
71 /* Initialize runtime debugging if available */
76 /* Initialize the local kernel debugger. */
77 KdDebuggerEnabled = TRUE;
78 KdDebugState |= KD_DEBUG_KDB;
81 /* Set debug port default values */
82 PortInfo.ComPort = DEFAULT_DEBUG_PORT;
83 PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
84 KdpPortIrq = DEFAULT_DEBUG_COM2_IRQ;
86 /* Set serial log port default values */
87 LogPortInfo.ComPort = DEFAULT_DEBUG_PORT;
88 LogPortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
90 /* Parse kernel command line */
92 /* Check for 'DEBUGPORT' */
93 p1 = (PCHAR)LoaderBlock->CommandLine;
94 while (p1 && (p2 = strchr(p1, '/')))
97 if (!_strnicmp(p2, "DEBUGPORT", 9))
103 if (!_strnicmp(p2, "SCREEN", 6))
106 KdDebuggerEnabled = TRUE;
107 KdDebugState |= KD_DEBUG_SCREEN;
109 else if (!_strnicmp(p2, "BOCHS", 5))
112 KdDebuggerEnabled = TRUE;
113 KdDebugState |= KD_DEBUG_BOCHS;
115 else if (!_strnicmp(p2, "GDB", 3))
118 KdDebuggerEnabled = TRUE;
119 KdDebugState |= KD_DEBUG_GDB;
121 /* Reset port information to defaults */
122 RtlMoveMemory(&GdbPortInfo, &PortInfo, sizeof(KD_PORT_INFORMATION));
123 PortInfo.ComPort = DEFAULT_DEBUG_PORT;
124 PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
126 else if (!_strnicmp(p2, "PICE", 4))
129 KdDebuggerEnabled = TRUE;
130 KdDebugState |= KD_DEBUG_PICE;
132 else if (!_strnicmp(p2, "COM", 3))
135 Value = (ULONG)atol(p2);
136 if (Value > 0 && Value < 5)
138 KdDebuggerEnabled = TRUE;
139 KdDebugState |= KD_DEBUG_SERIAL;
140 LogPortInfo.ComPort = Value;
143 else if (!_strnicmp(p2, "FILE", 4))
146 KdDebuggerEnabled = TRUE;
147 KdDebugState |= KD_DEBUG_FILELOG;
149 else if (!_strnicmp(p2, "MDA", 3))
152 KdDebuggerEnabled = TRUE;
153 KdDebugState |= KD_DEBUG_MDA;
157 else if (!_strnicmp(p2, "DEBUG", 5))
160 KdDebuggerEnabled = TRUE;
161 KdDebugState |= KD_DEBUG_SERIAL;
163 else if (!_strnicmp(p2, "NODEBUG", 7))
166 KdDebuggerEnabled = FALSE;
167 KdDebugState = KD_DEBUG_DISABLED;
169 else if (!_strnicmp(p2, "CRASHDEBUG", 10))
172 KdDebuggerEnabled = FALSE;
173 KdDebugState = KD_DEBUG_DISABLED;
175 else if (!_strnicmp(p2, "BREAK", 5))
178 KdpBreakPending = TRUE;
180 else if (!_strnicmp(p2, "COM", 3))
186 Value = (ULONG)atol(p2);
187 if (Value > 0 && Value < 5)
189 PortInfo.ComPort = Value;
193 else if (!_strnicmp(p2, "BAUDRATE", 8))
199 Value = (ULONG)atol(p2);
202 PortInfo.BaudRate = Value;
205 else if (!_strnicmp(p2, "IRQ", 3))
211 Value = (ULONG)atol(p2);
220 else if (!_strnicmp(p2, "PROFILE", 7))
228 /* Print some information */
229 if (KdDebuggerEnabled == TRUE)
231 if (KdDebugState & KD_DEBUG_GDB)
232 PrintString("\n GDB debugging enabled. COM%ld %ld Baud\n\n",
233 GdbPortInfo.ComPort, GdbPortInfo.BaudRate);
235 if (KdDebugState & KD_DEBUG_PICE)
236 PrintString("\n Private ICE debugger enabled\n\n");
238 if (KdDebugState & KD_DEBUG_SCREEN)
239 PrintString("\n Screen debugging enabled\n\n");
241 if (KdDebugState & KD_DEBUG_BOCHS)
242 PrintString("\n Bochs debugging enabled\n\n");
244 if (KdDebugState & KD_DEBUG_SERIAL)
245 PrintString("\n Serial debugging enabled. COM%ld %ld Baud\n\n",
246 LogPortInfo.ComPort, LogPortInfo.BaudRate);
248 if (KdDebugState & KD_DEBUG_FILELOG)
249 PrintString("\n File log debugging enabled\n\n");
250 if (KdDebugState & KD_DEBUG_MDA)
251 PrintString("\n MDA debugging enabled\n\n");
254 /* Perform any initialization nescessary */
255 if (KdDebuggerEnabled == TRUE)
257 if (KdDebugState & KD_DEBUG_GDB)
258 KdPortInitializeEx(&GdbPortInfo, 0, 0);
260 if (KdDebugState & KD_DEBUG_SERIAL)
261 KdPortInitializeEx(&LogPortInfo, 0, 0);
263 if (KdDebugState & KD_DEBUG_FILELOG)
266 if (KdDebugState & KD_DEBUG_MDA)
275 /* Initialize kernel debugger (phase 0) */
276 if ((KdDebuggerEnabled == TRUE) &&
277 (KdDebugState & KD_DEBUG_GDB))
286 /* Initialize kernel debugger (phase 1) */
287 if ((KdDebuggerEnabled == TRUE) &&
288 (KdDebugState & KD_DEBUG_GDB))
295 KdSerialDebugPrint (LPSTR Message)
297 PCHAR pch = (PCHAR) Message;
303 KdPortPutByteEx (&LogPortInfo, '\r');
305 KdPortPutByteEx (&LogPortInfo, *pch);
312 KdBochsDebugPrint(IN LPSTR Message)
314 while (*Message != 0)
316 if (*Message == '\n')
318 WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, '\r');
320 WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, *Message);
327 KdpPrintString(PANSI_STRING String)
329 PCH pch = String->Buffer;
331 if (KdDebugState & KD_DEBUG_GDB)
332 KdGdbDebugPrint(pch);
334 if (KdDebugState & KD_DEBUG_SCREEN)
335 HalDisplayString(pch);
337 if (KdDebugState & KD_DEBUG_SERIAL)
338 KdSerialDebugPrint(pch);
340 if (KdDebugState & KD_DEBUG_BOCHS)
341 KdBochsDebugPrint(pch);
343 if (KdDebugState & KD_DEBUG_FILELOG)
346 if (KdDebugState & KD_DEBUG_MDA)
349 return((ULONG)String->Length);
352 /* PUBLIC FUNCTIONS *********************************************************/
354 /* NTOSKRNL.KdPollBreakIn */
359 if ((!KdDebuggerEnabled) || (!(KdDebugState & KD_DEBUG_SERIAL)))
361 return KdpBreakPending;
365 KeEnterKernelDebugger(VOID)
367 HalDisplayString("\n\n *** Entered kernel debugger ***\n");
374 KdSystemDebugControl(ULONG Code)
376 extern VOID PsDumpThreads(BOOLEAN IncludeSystem);
378 /* A - Dump the entire contents of the non-paged pool. */
381 MiDebugDumpNonPagedPool(FALSE);
383 /* B - Bug check the system. */
389 * C - Dump statistics about the distribution of tagged blocks in
390 * the non-paged pool.
394 MiDebugDumpNonPagedPoolStats(FALSE);
397 * D - Dump the blocks created in the non-paged pool since the last
398 * SysRq + D and SysRq + E command.
402 MiDebugDumpNonPagedPool(TRUE);
404 /* E - Dump statistics about the tags of newly created blocks. */
407 MiDebugDumpNonPagedPoolStats(TRUE);
417 PsDumpThreads(FALSE);
431 /* K - Enter the system debugger. */
437 DbgPrint("No local kernel debugger\n");
438 #endif /* not KDBG */
443 /* Support routines for the GDB stubs */
446 KdPutChar(UCHAR Value)
448 KdPortPutByteEx (&GdbPortInfo, Value);
457 while (!KdPortGetByteEx (&GdbPortInfo, &Value));