Implemented kernel parameter line
[reactos.git] / reactos / ntoskrnl / kd / kdebug.c
1 /* $Id: kdebug.c,v 1.8 2000/03/04 22:02:13 ekohl 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 <stdlib.h>
16 #include <ctype.h>
17
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 typedef enum
30 {
31 ScreenDebug,
32 SerialDebug,
33 BochsDebug
34 } DEBUGTYPE;
35
36
37 /* VARIABLES ***************************************************************/
38
39 BOOLEAN
40 __declspec(dllexport)
41 KdDebuggerEnabled = FALSE; /* EXPORTED */
42
43 BOOLEAN
44 __declspec(dllexport)
45 KdDebuggerNotPresent = TRUE; /* EXPORTED */
46
47
48 static BOOLEAN KdpBreakPending = FALSE;
49 static BOOLEAN KdpBreakRecieved = FALSE;
50 static DEBUGTYPE KdpDebugType = ScreenDebug;
51
52
53 /* PRIVATE FUNCTIONS ********************************************************/
54
55 static void
56 PrintString (char* fmt,...)
57 {
58 char buffer[512];
59 va_list ap;
60
61 va_start(ap, fmt);
62 vsprintf(buffer, fmt, ap);
63 va_end(ap);
64
65 HalDisplayString (buffer);
66 }
67
68
69 VOID
70 KdInitSystem (
71 ULONG Reserved,
72 boot_param* BootParam
73 )
74 {
75 KD_PORT_INFORMATION PortInfo;
76 ULONG Value;
77 PCHAR p1, p2;
78
79 /* set debug port default values */
80 PortInfo.ComPort = DEFAULT_DEBUG_PORT;
81 PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
82
83 /*
84 * parse kernel command line
85 */
86
87 /* check for 'DEBUGPORT' */
88 p1 = BootParam->kernel_parameters;
89 while (p1 && (p2 = strchr (p1, '/')))
90 {
91 p2++;
92 if (!_strnicmp (p2, "DEBUGPORT", 9))
93 {
94 p2 += 9;
95 if (*p2 != '=')
96 break;
97 p2++;
98 if (!_strnicmp (p2, "SCREEN", 6))
99 {
100 p2 += 6;
101 KdDebuggerEnabled = TRUE;
102 KdpDebugType = ScreenDebug;
103 }
104 else if (!_strnicmp (p2, "BOCHS", 5))
105 {
106 p2 += 5;
107 KdDebuggerEnabled = TRUE;
108 KdpDebugType = BochsDebug;
109 }
110 else if (!_strnicmp (p2, "COM", 3))
111 {
112 p2 += 3;
113 Value = (ULONG)atol (p2);
114 if (Value > 0 && Value < 5)
115 {
116 KdDebuggerEnabled = TRUE;
117 KdpDebugType = SerialDebug;
118 PortInfo.ComPort = Value;
119 }
120 }
121 break;
122 }
123 p1 = p2;
124 }
125
126 /* check for 'BAUDRATE' */
127 p1 = BootParam->kernel_parameters;
128 while (p1 && (p2 = strchr (p1, '/')))
129 {
130 p2++;
131 if (!_strnicmp (p2, "BAUDRATE", 8))
132 {
133 p2 += 8;
134 if (*p2 != '=')
135 break;
136 p2++;
137 Value = (ULONG)atol (p2);
138 if (Value > 0)
139 {
140 KdDebuggerEnabled = TRUE;
141 KdpDebugType = SerialDebug;
142 PortInfo.BaudRate = Value;
143 }
144 break;
145 }
146 p1 = p2;
147 }
148
149 /* Check for 'DEBUG'. Dont' accept 'DEBUGPORT'!*/
150 p1 = BootParam->kernel_parameters;
151 while (p1 && (p2 = strchr (p1, '/')))
152 {
153 p2++;
154 if (!_strnicmp (p2, "DEBUG", 5) &&
155 _strnicmp (p2, "DEBUGPORT", 9))
156 {
157 p2 += 5;
158 KdDebuggerEnabled = TRUE;
159 KdpDebugType = SerialDebug;
160 break;
161 }
162 p1 = p2;
163 }
164
165 /* Check for 'NODEBUG' */
166 p1 = BootParam->kernel_parameters;
167 while (p1 && (p2 = strchr (p1, '/')))
168 {
169 p2++;
170 if (!_strnicmp (p2, "NODEBUG", 7))
171 {
172 p2 += 7;
173 KdDebuggerEnabled = FALSE;
174 break;
175 }
176 p1 = p2;
177 }
178
179 /* Check for 'CRASHDEBUG' */
180 p1 = BootParam->kernel_parameters;
181 while (p1 && (p2 = strchr (p1, '/')))
182 {
183 p2++;
184 if (!_strnicmp (p2, "CRASHDEBUG", 10))
185 {
186 p2 += 10;
187 KdDebuggerEnabled = FALSE;
188 break;
189 }
190 p1 = p2;
191 }
192
193 /* Check for 'BREAK' */
194 p1 = BootParam->kernel_parameters;
195 while (p1 && (p2 = strchr (p1, '/')))
196 {
197 p2++;
198 if (!_strnicmp (p2, "BREAK", 5))
199 {
200 p2 += 7;
201 KdpBreakPending = TRUE;
202 break;
203 }
204 p1 = p2;
205 }
206
207
208 /* print some information */
209 if (KdDebuggerEnabled == TRUE)
210 {
211 if (KdpDebugType == ScreenDebug)
212 {
213 PrintString ("\n Screen debugging enabled\n\n");
214 }
215 else if (KdpDebugType == BochsDebug)
216 {
217 PrintString ("\n Bochs debugging enabled\n\n");
218 }
219 else if (KdpDebugType == SerialDebug)
220 {
221 PrintString ("\n Serial debugging enabled: COM%ld %ld Baud\n\n",
222 PortInfo.ComPort, PortInfo.BaudRate);
223 }
224 }
225 else
226 PrintString ("\n Debugging disabled\n\n");
227
228
229 /* initialize debug port */
230 if (KdDebuggerEnabled && KdpDebugType == SerialDebug)
231 {
232 KdPortInitialize (&PortInfo,
233 0,
234 0);
235 }
236 }
237
238
239 ULONG
240 KdpPrintString (PANSI_STRING String)
241 {
242 PCH pch = String->Buffer;
243
244 if (KdpDebugType == ScreenDebug)
245 {
246 HalDisplayString (String->Buffer);
247 }
248 else if (KdpDebugType == SerialDebug)
249 {
250 while (*pch != 0)
251 {
252 if (*pch == '\n')
253 {
254 KdPortPutByte ('\r');
255 }
256 KdPortPutByte (*pch);
257 pch++;
258 }
259 }
260 else if (KdpDebugType == BochsDebug)
261 {
262 while (*pch != 0)
263 {
264 if (*pch == '\n')
265 {
266 WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, '\r');
267 }
268 WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, *pch);
269 pch++;
270 }
271 }
272
273 return (ULONG)String->Length;
274 }
275
276 /* PUBLIC FUNCTIONS *********************************************************/
277
278 /* NTOSKRNL.KdPollBreakIn */
279
280 BOOLEAN
281 STDCALL
282 KdPollBreakIn (
283 VOID
284 )
285 {
286 BOOLEAN Result = FALSE;
287 UCHAR ByteRead;
288
289 if (KdDebuggerEnabled == FALSE || KdpDebugType != SerialDebug)
290 return Result;
291
292 // Flags = KiDisableInterrupts();
293
294 HalDisplayString ("Waiting for kernel debugger connection...\n");
295
296 if (KdPortPollByte (&ByteRead))
297 {
298 if (ByteRead == 0x62)
299 {
300 if (KdpBreakPending == TRUE)
301 {
302 KdpBreakPending = FALSE;
303 KdpBreakRecieved = TRUE;
304 Result = TRUE;
305 }
306 HalDisplayString (" Kernel debugger connected\n");
307 }
308 else
309 {
310 HalDisplayString (" Kernel debugger connection failed\n");
311 }
312 }
313
314 // KiRestoreInterrupts (Flags);
315
316 return Result;
317 }
318
319 VOID
320 STDCALL
321 KeEnterKernelDebugger (
322 VOID
323 )
324 {
325 HalDisplayString ("\n\n *** Entered kernel debugger ***\n");
326
327 for (;;)
328 __asm__("hlt\n\t");
329 }
330
331 /* EOF */