1 /* $Id: kdebug.c,v 1.46 2003/08/11 18:50:12 chorns Exp $
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 (0 < Value
&& Value
< 5)
189 PortInfo
.ComPort
= Value
;
193 else if (!_strnicmp(p2
, "BAUDRATE", 8))
199 Value
= (ULONG
)atol(p2
);
202 PortInfo
.BaudRate
= Value
;
206 else if (!_strnicmp(p2
, "IRQ", 3))
212 Value
= (ULONG
)atol(p2
);
220 else if (!_strnicmp(p2
, "PROFILE", 7))
228 /* Perform any initialization nescessary */
229 if (KdDebuggerEnabled
== TRUE
)
231 if (KdDebugState
& KD_DEBUG_GDB
)
232 KdPortInitializeEx(&GdbPortInfo
, 0, 0);
234 if (KdDebugState
& KD_DEBUG_SERIAL
)
235 KdPortInitializeEx(&LogPortInfo
, 0, 0);
237 if (KdDebugState
& KD_DEBUG_FILELOG
)
240 if (KdDebugState
& KD_DEBUG_MDA
)
249 /* Initialize kernel debugger (phase 0) */
250 if ((KdDebuggerEnabled
== TRUE
) &&
251 (KdDebugState
& KD_DEBUG_GDB
))
260 /* Initialize kernel debugger (phase 1) */
261 if ((KdDebuggerEnabled
== TRUE
) &&
262 (KdDebugState
& KD_DEBUG_GDB
))
272 /* Print some information */
273 if (KdDebuggerEnabled
== TRUE
)
275 if (KdDebugState
& KD_DEBUG_GDB
)
276 PrintString("\n GDB debugging enabled. COM%ld %ld Baud\n\n",
277 GdbPortInfo
.ComPort
, GdbPortInfo
.BaudRate
);
279 if (KdDebugState
& KD_DEBUG_PICE
)
280 PrintString("\n Private ICE debugger enabled\n\n");
282 if (KdDebugState
& KD_DEBUG_SCREEN
)
283 PrintString("\n Screen debugging enabled\n\n");
285 if (KdDebugState
& KD_DEBUG_BOCHS
)
286 PrintString("\n Bochs debugging enabled\n\n");
288 if (KdDebugState
& KD_DEBUG_SERIAL
)
289 PrintString("\n Serial debugging enabled. COM%ld %ld Baud\n\n",
290 LogPortInfo
.ComPort
, LogPortInfo
.BaudRate
);
292 if (KdDebugState
& KD_DEBUG_FILELOG
)
293 PrintString("\n File log debugging enabled\n\n");
294 if (KdDebugState
& KD_DEBUG_MDA
)
295 PrintString("\n MDA debugging enabled\n\n");
301 KdSerialDebugPrint (LPSTR Message
)
303 PCHAR pch
= (PCHAR
) Message
;
309 KdPortPutByteEx (&LogPortInfo
, '\r');
311 KdPortPutByteEx (&LogPortInfo
, *pch
);
318 KdBochsDebugPrint(IN LPSTR Message
)
320 while (*Message
!= 0)
322 if (*Message
== '\n')
324 WRITE_PORT_UCHAR((PUCHAR
)BOCHS_LOGGER_PORT
, '\r');
326 WRITE_PORT_UCHAR((PUCHAR
)BOCHS_LOGGER_PORT
, *Message
);
333 KdpPrintString(PANSI_STRING String
)
335 PCH pch
= String
->Buffer
;
337 if (KdDebugState
& KD_DEBUG_GDB
)
338 KdGdbDebugPrint(pch
);
340 if (KdDebugState
& KD_DEBUG_SCREEN
)
341 HalDisplayString(pch
);
343 if (KdDebugState
& KD_DEBUG_SERIAL
)
344 KdSerialDebugPrint(pch
);
346 if (KdDebugState
& KD_DEBUG_BOCHS
)
347 KdBochsDebugPrint(pch
);
349 if (KdDebugState
& KD_DEBUG_FILELOG
)
352 if (KdDebugState
& KD_DEBUG_MDA
)
355 return((ULONG
)String
->Length
);
358 /* PUBLIC FUNCTIONS *********************************************************/
360 /* NTOSKRNL.KdPollBreakIn */
368 if ((!KdDebuggerEnabled
) || (!(KdDebugState
& KD_DEBUG_SERIAL
)))
370 return KdpBreakPending
;
377 KeEnterKernelDebugger(VOID
)
379 HalDisplayString("\n\n *** Entered kernel debugger ***\n");
386 KdSystemDebugControl(ULONG Code
)
388 extern VOID
PsDumpThreads(BOOLEAN IncludeSystem
);
390 /* A - Dump the entire contents of the non-paged pool. */
393 MiDebugDumpNonPagedPool(FALSE
);
395 /* B - Bug check the system. */
401 * C - Dump statistics about the distribution of tagged blocks in
402 * the non-paged pool.
406 MiDebugDumpNonPagedPoolStats(FALSE
);
409 * D - Dump the blocks created in the non-paged pool since the last
410 * SysRq + D and SysRq + E command.
414 MiDebugDumpNonPagedPool(TRUE
);
416 /* E - Dump statistics about the tags of newly created blocks. */
419 MiDebugDumpNonPagedPoolStats(TRUE
);
429 PsDumpThreads(FALSE
);
443 /* K - Enter the system debugger. */
449 DbgPrint("No local kernel debugger\n");
450 #endif /* not KDBG */
455 /* Support routines for the GDB stubs */
458 KdPutChar(UCHAR Value
)
460 KdPortPutByteEx (&GdbPortInfo
, Value
);
469 while (!KdPortGetByteEx (&GdbPortInfo
, &Value
));