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