1 /* $Id: kdebug.c,v 1.20 2001/03/07 08:57:08 dwelch 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 /* serial debug connection */
18 #define DEFAULT_DEBUG_PORT 2 /* COM2 */
19 #define DEFAULT_DEBUG_BAUD_RATE 19200 /* 19200 Baud */
21 /* bochs debug output */
22 #define BOCHS_LOGGER_PORT (0xe9)
25 /* TYPEDEFS ****************************************************************/
27 #define ScreenDebug (0x1)
28 #define SerialDebug (0x2)
29 #define BochsDebug (0x4)
30 #define FileLogDebug (0x8)
32 /* VARIABLES ***************************************************************/
36 KdDebuggerEnabled
= FALSE
; /* EXPORTED */
40 KdDebuggerNotPresent
= TRUE
; /* EXPORTED */
43 static BOOLEAN KdpBreakPending
= FALSE
;
44 static BOOLEAN KdpBreakRecieved
= FALSE
;
45 static ULONG KdpDebugType
= ScreenDebug
| BochsDebug
;
47 /* PRIVATE FUNCTIONS ********************************************************/
50 PrintString (char* fmt
,...)
56 vsprintf(buffer
, fmt
, ap
);
59 HalDisplayString (buffer
);
66 PLOADER_PARAMETER_BLOCK LoaderBlock
69 KD_PORT_INFORMATION PortInfo
;
73 /* set debug port default values */
74 PortInfo
.ComPort
= DEFAULT_DEBUG_PORT
;
75 PortInfo
.BaudRate
= DEFAULT_DEBUG_BAUD_RATE
;
78 * parse kernel command line
81 /* check for 'DEBUGPORT' */
82 p1
= (PCHAR
)LoaderBlock
->CommandLine
;
83 while (p1
&& (p2
= strchr (p1
, '/')))
86 if (!_strnicmp (p2
, "DEBUGPORT", 9))
92 if (!_strnicmp (p2
, "SCREEN", 6))
95 KdDebuggerEnabled
= TRUE
;
96 KdpDebugType
|= ScreenDebug
;
98 else if (!_strnicmp (p2
, "BOCHS", 5))
101 KdDebuggerEnabled
= TRUE
;
102 KdpDebugType
|= BochsDebug
;
104 else if (!_strnicmp (p2
, "COM", 3))
107 Value
= (ULONG
)atol (p2
);
108 if (Value
> 0 && Value
< 5)
110 KdDebuggerEnabled
= TRUE
;
111 KdpDebugType
|= SerialDebug
;
112 PortInfo
.ComPort
= Value
;
122 /* check for 'BAUDRATE' */
123 p1
= (PCHAR
)LoaderBlock
->CommandLine
;
124 while (p1
&& (p2
= strchr (p1
, '/')))
127 if (!_strnicmp (p2
, "BAUDRATE", 8))
133 Value
= (ULONG
)atol (p2
);
136 KdDebuggerEnabled
= TRUE
;
137 KdpDebugType
= KdpDebugType
| SerialDebug
;
138 PortInfo
.BaudRate
= Value
;
145 /* Check for 'DEBUG'. Dont' accept 'DEBUGPORT'!*/
146 p1
= (PCHAR
)LoaderBlock
->CommandLine
;
147 while (p1
&& (p2
= strchr (p1
, '/')))
150 if (!_strnicmp (p2
, "DEBUG", 5) &&
151 _strnicmp (p2
, "DEBUGPORT", 9))
154 KdDebuggerEnabled
= TRUE
;
155 KdpDebugType
= KdpDebugType
| SerialDebug
;
161 /* Check for 'NODEBUG' */
162 p1
= (PCHAR
)LoaderBlock
->CommandLine
;
163 while (p1
&& (p2
= strchr (p1
, '/')))
166 if (!_strnicmp (p2
, "NODEBUG", 7))
169 KdDebuggerEnabled
= FALSE
;
175 /* Check for 'CRASHDEBUG' */
176 p1
= (PCHAR
)LoaderBlock
->CommandLine
;
177 while (p1
&& (p2
= strchr (p1
, '/')))
180 if (!_strnicmp (p2
, "CRASHDEBUG", 10))
183 KdDebuggerEnabled
= FALSE
;
189 /* Check for 'BREAK' */
190 p1
= (PCHAR
)LoaderBlock
->CommandLine
;
191 while (p1
&& (p2
= strchr (p1
, '/')))
194 if (!_strnicmp (p2
, "BREAK", 5))
197 KdpBreakPending
= TRUE
;
203 #ifdef DBGPRINT_FILE_LOG
204 KdpDebugType
|= FileLogDebug
;
206 #endif /* DBGPRINT_FILE_LOG */
208 /* print some information */
209 if (KdDebuggerEnabled
== TRUE
)
211 if (KdpDebugType
& ScreenDebug
)
213 PrintString ("\n Screen debugging enabled\n\n");
215 if (KdpDebugType
& BochsDebug
)
217 PrintString ("\n Bochs debugging enabled\n\n");
219 if (KdpDebugType
& SerialDebug
)
221 PrintString ("\n Serial debugging enabled: COM%ld %ld Baud\n\n",
222 PortInfo
.ComPort
, PortInfo
.BaudRate
);
224 if (KdpDebugType
& FileLogDebug
)
226 PrintString("\n File log debugging enabled\n\n");
230 PrintString ("\n Debugging disabled\n\n");
233 /* initialize debug port */
234 if (KdDebuggerEnabled
&& (KdpDebugType
& SerialDebug
))
236 KdPortInitialize (&PortInfo
,
243 ULONG
KdpPrintString (PANSI_STRING String
)
245 PCH pch
= String
->Buffer
;
247 if (KdpDebugType
& ScreenDebug
)
249 HalDisplayString (String
->Buffer
);
251 if (KdpDebugType
& SerialDebug
)
257 KdPortPutByte ('\r');
259 KdPortPutByte (*pch
);
263 if (KdpDebugType
& BochsDebug
)
269 WRITE_PORT_UCHAR((PUCHAR
)BOCHS_LOGGER_PORT
, '\r');
271 WRITE_PORT_UCHAR((PUCHAR
)BOCHS_LOGGER_PORT
, *pch
);
275 #ifdef DBGPRINT_FILE_LOG
276 if (KdpDebugType
& FileLogDebug
)
278 DebugLogWrite(String
->Buffer
);
280 #endif /* DBGPRINT_FILE_LOG */
281 return (ULONG
)String
->Length
;
284 /* PUBLIC FUNCTIONS *********************************************************/
286 /* NTOSKRNL.KdPollBreakIn */
294 BOOLEAN Result
= FALSE
;
297 if (KdDebuggerEnabled
== FALSE
|| KdpDebugType
!= SerialDebug
)
300 // Flags = KiDisableInterrupts();
302 HalDisplayString ("Waiting for kernel debugger connection...\n");
304 if (KdPortPollByte (&ByteRead
))
306 if (ByteRead
== 0x62)
308 if (KdpBreakPending
== TRUE
)
310 KdpBreakPending
= FALSE
;
311 KdpBreakRecieved
= TRUE
;
314 HalDisplayString (" Kernel debugger connected\n");
318 HalDisplayString (" Kernel debugger connection failed\n");
322 // KiRestoreInterrupts (Flags);
328 KeEnterKernelDebugger (VOID
)
330 HalDisplayString ("\n\n *** Entered kernel debugger ***\n");
341 KdSystemDebugControl(ULONG Code
)
345 MiDebugDumpNonPagedPool();