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)
13 #include "../dbg/kdb.h"
14 #include <internal/debug.h>
16 /* serial debug connection */
17 #define DEFAULT_DEBUG_PORT 2 /* COM2 */
18 #define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
19 #define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
20 #define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
22 /* bochs debug output */
23 #define BOCHS_LOGGER_PORT (0xe9)
25 /* VARIABLES ***************************************************************/
29 KdDebuggerEnabled
= FALSE
; /* EXPORTED */
33 KdEnteredDebugger
= FALSE
; /* EXPORTED */
37 KdDebuggerNotPresent
= TRUE
; /* EXPORTED */
41 KiBugCheckData
; /* EXPORTED */
45 KiEnableTimerWatchdog
= FALSE
; /* EXPORTED */
48 static BOOLEAN KdpBreakPending
= FALSE
;
49 ULONG KdDebugState
= KD_DEBUG_DISABLED
;
52 KD_PORT_INFORMATION GdbPortInfo
;
53 KD_PORT_INFORMATION LogPortInfo
;
55 /* PRIVATE FUNCTIONS ********************************************************/
58 PrintString(char* fmt
,...)
64 vsprintf(buffer
, fmt
, ap
);
67 HalDisplayString(buffer
);
72 KdInitSystem(ULONG BootPhase
,
73 PLOADER_PARAMETER_BLOCK LoaderBlock
)
75 KD_PORT_INFORMATION PortInfo
;
82 /* Initialize runtime debugging if available */
87 /* Initialize the local kernel debugger. */
88 KdDebuggerEnabled
= TRUE
;
89 KdDebugState
|= KD_DEBUG_KDB
;
95 /* Set debug port default values */
96 PortInfo
.ComPort
= DEFAULT_DEBUG_PORT
;
97 PortInfo
.BaudRate
= DEFAULT_DEBUG_BAUD_RATE
;
98 KdpPortIrq
= DEFAULT_DEBUG_COM2_IRQ
;
100 /* Set serial log port default values */
101 LogPortInfo
.ComPort
= DEFAULT_DEBUG_PORT
;
102 LogPortInfo
.BaudRate
= DEFAULT_DEBUG_BAUD_RATE
;
105 /* Parse kernel command line */
107 /* Check for 'DEBUGPORT' */
108 p1
= (PCHAR
)LoaderBlock
->CommandLine
;
109 while (p1
&& (p2
= strchr(p1
, '/')))
112 if (!_strnicmp(p2
, "DEBUGPORT", 9))
118 if (!_strnicmp(p2
, "SCREEN", 6) && BootPhase
> 0)
121 KdDebuggerEnabled
= TRUE
;
122 KdDebugState
|= KD_DEBUG_SCREEN
;
124 else if (!_strnicmp(p2
, "BOCHS", 5) && BootPhase
== 0)
127 KdDebuggerEnabled
= TRUE
;
128 KdDebugState
|= KD_DEBUG_BOCHS
;
130 else if (!_strnicmp(p2
, "GDB", 3) && BootPhase
== 0)
133 KdDebuggerEnabled
= TRUE
;
134 KdDebugState
|= KD_DEBUG_GDB
;
136 /* Reset port information to defaults */
137 RtlMoveMemory(&GdbPortInfo
, &PortInfo
, sizeof(KD_PORT_INFORMATION
));
138 PortInfo
.ComPort
= DEFAULT_DEBUG_PORT
;
139 PortInfo
.BaudRate
= DEFAULT_DEBUG_BAUD_RATE
;
141 else if (!_strnicmp(p2
, "PICE", 4) && BootPhase
> 0)
144 KdDebuggerEnabled
= TRUE
;
145 KdDebugState
|= KD_DEBUG_PICE
;
147 else if (!_strnicmp(p2
, "COM", 3) && BootPhase
== 0)
150 Value
= (ULONG
)atol(p2
);
151 if (Value
> 0 && Value
< 5)
153 KdDebuggerEnabled
= TRUE
;
154 KdDebugState
|= KD_DEBUG_SERIAL
;
155 LogPortInfo
.ComPort
= Value
;
158 else if (!_strnicmp(p2
, "BOOTLOG", 4) && BootPhase
> 0)
161 KdDebuggerEnabled
= TRUE
;
162 KdDebugState
|= KD_DEBUG_BOOTLOG
;
164 else if (!_strnicmp(p2
, "MDA", 3) && BootPhase
> 0)
167 KdDebuggerEnabled
= TRUE
;
168 KdDebugState
|= KD_DEBUG_MDA
;
172 else if (!_strnicmp(p2
, "KDSERIAL", 8) && BootPhase
> 0)
175 KdDebuggerEnabled
= TRUE
;
176 KdDebugState
|= KD_DEBUG_SERIAL
| KD_DEBUG_KDSERIAL
;
178 else if (!_strnicmp(p2
, "KDNOECHO", 8) && BootPhase
> 0)
181 KdDebuggerEnabled
= TRUE
;
182 KdDebugState
|= KD_DEBUG_KDNOECHO
;
184 else if (!_strnicmp(p2
, "DEBUG", 5) && BootPhase
== 0)
187 KdDebuggerEnabled
= TRUE
;
188 KdDebugState
|= KD_DEBUG_SERIAL
;
190 else if (!_strnicmp(p2
, "NODEBUG", 7) && BootPhase
== 0)
193 KdDebuggerEnabled
= FALSE
;
194 KdDebugState
= KD_DEBUG_DISABLED
;
196 else if (!_strnicmp(p2
, "CRASHDEBUG", 10) && BootPhase
== 0)
199 KdDebuggerEnabled
= FALSE
;
200 KdDebugState
= KD_DEBUG_DISABLED
;
202 else if (!_strnicmp(p2
, "BREAK", 5) && BootPhase
> 0)
205 KdpBreakPending
= TRUE
;
207 else if (!_strnicmp(p2
, "COM", 3) && BootPhase
== 0)
213 Value
= (ULONG
)atol(p2
);
214 if (0 < Value
&& Value
< 5)
216 PortInfo
.ComPort
= Value
;
220 else if (!_strnicmp(p2
, "BAUDRATE", 8) && BootPhase
== 0)
226 Value
= (ULONG
)atol(p2
);
229 PortInfo
.BaudRate
= Value
;
233 else if (!_strnicmp(p2
, "IRQ", 3) && BootPhase
== 0)
239 Value
= (ULONG
)atol(p2
);
247 else if (!_strnicmp(p2
, "PROFILE", 7) && BootPhase
> 0)
255 /* Perform any initialization nescessary */
256 if (KdDebuggerEnabled
== TRUE
)
258 if (KdDebugState
& KD_DEBUG_GDB
&& BootPhase
== 0)
259 KdPortInitializeEx(&GdbPortInfo
, 0, 0);
261 if (KdDebugState
& KD_DEBUG_SERIAL
&& BootPhase
== 0)
262 KdPortInitializeEx(&LogPortInfo
, 0, 0);
264 if (KdDebugState
& KD_DEBUG_BOOTLOG
&& BootPhase
> 0)
267 if (KdDebugState
& KD_DEBUG_MDA
&& BootPhase
> 0)
276 /* Initialize kernel debugger (phase 0) */
277 if ((KdDebuggerEnabled
== TRUE
) &&
278 (KdDebugState
& KD_DEBUG_GDB
))
288 /* Initialize kernel debugger (phase 1) */
289 if ((KdDebuggerEnabled
== TRUE
) &&
290 (KdDebugState
& KD_DEBUG_GDB
))
300 /* Print some information */
301 if (KdDebuggerEnabled
== TRUE
)
303 if (KdDebugState
& KD_DEBUG_GDB
)
304 PrintString("\n GDB debugging enabled. COM%ld %ld Baud\n\n",
305 GdbPortInfo
.ComPort
, GdbPortInfo
.BaudRate
);
307 if (KdDebugState
& KD_DEBUG_PICE
)
308 PrintString("\n Private ICE debugger enabled\n\n");
310 if (KdDebugState
& KD_DEBUG_SCREEN
)
311 PrintString("\n Screen debugging enabled\n\n");
313 if (KdDebugState
& KD_DEBUG_BOCHS
)
314 PrintString("\n Bochs debugging enabled\n\n");
316 if (KdDebugState
& KD_DEBUG_SERIAL
)
317 PrintString("\n Serial debugging enabled. COM%ld %ld Baud\n\n",
318 LogPortInfo
.ComPort
, LogPortInfo
.BaudRate
);
320 if (KdDebugState
& KD_DEBUG_BOOTLOG
)
321 PrintString("\n File log debugging enabled\n\n");
322 if (KdDebugState
& KD_DEBUG_MDA
)
323 PrintString("\n MDA debugging enabled\n\n");
329 KdSerialDebugPrint (LPSTR Message
)
331 PCHAR pch
= (PCHAR
) Message
;
337 KdPortPutByteEx (&LogPortInfo
, '\r');
339 KdPortPutByteEx (&LogPortInfo
, *pch
);
346 KdBochsDebugPrint(IN LPSTR Message
)
348 while (*Message
!= 0)
350 if (*Message
== '\n')
352 WRITE_PORT_UCHAR((PUCHAR
)BOCHS_LOGGER_PORT
, '\r');
354 WRITE_PORT_UCHAR((PUCHAR
)BOCHS_LOGGER_PORT
, *Message
);
361 KdpPrintString(PANSI_STRING String
)
363 PCH pch
= String
->Buffer
;
365 if (KdDebugState
& KD_DEBUG_GDB
)
366 KdGdbDebugPrint(pch
);
368 if (KdDebugState
& KD_DEBUG_SCREEN
)
369 HalDisplayString(pch
);
371 if (KdDebugState
& KD_DEBUG_SERIAL
)
372 KdSerialDebugPrint(pch
);
374 if (KdDebugState
& KD_DEBUG_BOCHS
)
375 KdBochsDebugPrint(pch
);
377 if (KdDebugState
& KD_DEBUG_BOOTLOG
)
380 if (KdDebugState
& KD_DEBUG_MDA
)
383 return((ULONG
)String
->Length
);
386 /* PUBLIC FUNCTIONS *********************************************************/
388 /* NTOSKRNL.KdPollBreakIn */
420 if ((!KdDebuggerEnabled
) || (!(KdDebugState
& KD_DEBUG_SERIAL
)))
422 return KdpBreakPending
;
429 KeEnterKernelDebugger(VOID
)
431 HalDisplayString("\n\n *** Entered kernel debugger ***\n");
435 #if defined(__GNUC__)
437 #elif defined(_MSC_VER)
440 #error Unknown compiler for inline assembler
446 KdSystemDebugControl(ULONG Code
)
448 extern VOID
PsDumpThreads(BOOLEAN IncludeSystem
);
450 /* A - Dump the entire contents of the non-paged pool. */
453 MiDebugDumpNonPagedPool(FALSE
);
455 /* B - Bug check the system. */
458 KEBUGCHECK(0xDEADDEAD);
461 * C - Dump statistics about the distribution of tagged blocks in
462 * the non-paged pool.
466 MiDebugDumpNonPagedPoolStats(FALSE
);
469 * D - Dump the blocks created in the non-paged pool since the last
470 * SysRq + D and SysRq + E command.
474 MiDebugDumpNonPagedPool(TRUE
);
476 /* E - Dump statistics about the tags of newly created blocks. */
479 MiDebugDumpNonPagedPoolStats(TRUE
);
489 PsDumpThreads(FALSE
);
503 /* K - Enter the system debugger. */
509 DbgPrint("No local kernel debugger\n");
510 #endif /* not KDBG */
524 return STATUS_NOT_IMPLEMENTED
;
527 /* Support routines for the GDB stubs */
530 KdPutChar(UCHAR Value
)
532 KdPortPutByteEx (&GdbPortInfo
, Value
);
541 while (!KdPortGetByteEx (&GdbPortInfo
, &Value
));