Fix and add missing files, and will allow the use of bison as an option of choice.
[reactos.git] / reactos / hal / halx86 / kdbg.c
1 /* $Id: kdbg.c,v 1.8 2004/04/29 17:06:21 navaraf Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/hal/x86/kdbg.c
6 * PURPOSE: Serial i/o functions for the kernel debugger.
7 * PROGRAMMER: Emanuele Aliberti
8 * Eric Kohl
9 * UPDATE HISTORY:
10 * Created 05/09/99
11 */
12
13 /* INCLUDES *****************************************************************/
14
15 #include <ddk/ntddk.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20
21 #define DEFAULT_BAUD_RATE 19200
22
23
24 /* MACROS *******************************************************************/
25
26 #define SER_RBR(x) ((x)+0)
27 #define SER_THR(x) ((x)+0)
28 #define SER_DLL(x) ((x)+0)
29 #define SER_IER(x) ((x)+1)
30 #define SR_IER_ERDA 0x01
31 #define SR_IER_ETHRE 0x02
32 #define SR_IER_ERLSI 0x04
33 #define SR_IER_EMS 0x08
34 #define SR_IER_ALL 0x0F
35 #define SER_DLM(x) ((x)+1)
36 #define SER_IIR(x) ((x)+2)
37 #define SER_FCR(x) ((x)+2)
38 #define SR_FCR_ENABLE_FIFO 0x01
39 #define SR_FCR_CLEAR_RCVR 0x02
40 #define SR_FCR_CLEAR_XMIT 0x04
41 #define SER_LCR(x) ((x)+3)
42 #define SR_LCR_CS5 0x00
43 #define SR_LCR_CS6 0x01
44 #define SR_LCR_CS7 0x02
45 #define SR_LCR_CS8 0x03
46 #define SR_LCR_ST1 0x00
47 #define SR_LCR_ST2 0x04
48 #define SR_LCR_PNO 0x00
49 #define SR_LCR_POD 0x08
50 #define SR_LCR_PEV 0x18
51 #define SR_LCR_PMK 0x28
52 #define SR_LCR_PSP 0x38
53 #define SR_LCR_BRK 0x40
54 #define SR_LCR_DLAB 0x80
55 #define SER_MCR(x) ((x)+4)
56 #define SR_MCR_DTR 0x01
57 #define SR_MCR_RTS 0x02
58 #define SR_MCR_OUT1 0x04
59 #define SR_MCR_OUT2 0x08
60 #define SR_MCR_LOOP 0x10
61 #define SER_LSR(x) ((x)+5)
62 #define SR_LSR_DR 0x01
63 #define SR_LSR_TBE 0x20
64 #define SER_MSR(x) ((x)+6)
65 #define SR_MSR_CTS 0x10
66 #define SR_MSR_DSR 0x20
67 #define SER_SCR(x) ((x)+7)
68
69
70 /* GLOBAL VARIABLES *********************************************************/
71
72 ULONG EXPORTED KdComPortInUse = 0;
73
74
75 /* STATIC VARIABLES *********************************************************/
76
77 static ULONG ComPort = 0;
78 static ULONG BaudRate = 0;
79 static PUCHAR PortBase = (PUCHAR)0;
80
81 /* The com port must only be initialized once! */
82 static BOOLEAN PortInitialized = FALSE;
83
84
85 /* STATIC FUNCTIONS *********************************************************/
86
87 static BOOLEAN
88 KdpDoesComPortExist (PUCHAR BaseAddress)
89 {
90 BOOLEAN found;
91 BYTE mcr;
92 BYTE msr;
93
94 found = FALSE;
95
96 /* save Modem Control Register (MCR) */
97 mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
98
99 /* enable loop mode (set Bit 4 of the MCR) */
100 WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
101
102 /* clear all modem output bits */
103 WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
104
105 /* read the Modem Status Register */
106 msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
107
108 /*
109 * the upper nibble of the MSR (modem output bits) must be
110 * equal to the lower nibble of the MCR (modem input bits)
111 */
112 if ((msr & 0xF0) == 0x00)
113 {
114 /* set all modem output bits */
115 WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
116
117 /* read the Modem Status Register */
118 msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
119
120 /*
121 * the upper nibble of the MSR (modem output bits) must be
122 * equal to the lower nibble of the MCR (modem input bits)
123 */
124 if ((msr & 0xF0) == 0xF0)
125 {
126 /*
127 * setup a resonable state for the port:
128 * enable fifo and clear recieve/transmit buffers
129 */
130 WRITE_PORT_UCHAR (SER_FCR(BaseAddress),
131 (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
132 WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0);
133 READ_PORT_UCHAR (SER_RBR(BaseAddress));
134 WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0);
135 found = TRUE;
136 }
137 }
138
139 /* restore MCR */
140 WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
141
142 return (found);
143 }
144
145
146 /* FUNCTIONS ****************************************************************/
147
148 /* HAL.KdPortInitialize */
149 BOOLEAN
150 STDCALL
151 KdPortInitialize (
152 PKD_PORT_INFORMATION PortInformation,
153 DWORD Unknown1,
154 DWORD Unknown2
155 )
156 {
157 ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
158 char buffer[80];
159 ULONG divisor;
160 BYTE lcr;
161
162 if (PortInitialized == FALSE)
163 {
164 if (PortInformation->BaudRate != 0)
165 {
166 BaudRate = PortInformation->BaudRate;
167 }
168 else
169 {
170 BaudRate = DEFAULT_BAUD_RATE;
171 }
172
173 if (PortInformation->ComPort == 0)
174 {
175 if (KdpDoesComPortExist ((PUCHAR)BaseArray[2]))
176 {
177 PortBase = (PUCHAR)BaseArray[2];
178 ComPort = 2;
179 PortInformation->BaseAddress = (ULONG)PortBase;
180 PortInformation->ComPort = ComPort;
181 #ifndef NDEBUG
182 sprintf (buffer,
183 "\nSerial port COM%ld found at 0x%lx\n",
184 ComPort,
185 (ULONG)PortBase);
186 HalDisplayString (buffer);
187 #endif /* NDEBUG */
188 }
189 else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1]))
190 {
191 PortBase = (PUCHAR)BaseArray[1];
192 ComPort = 1;
193 PortInformation->BaseAddress = (ULONG)PortBase;
194 PortInformation->ComPort = ComPort;
195 #ifndef NDEBUG
196 sprintf (buffer,
197 "\nSerial port COM%ld found at 0x%lx\n",
198 ComPort,
199 (ULONG)PortBase);
200 HalDisplayString (buffer);
201 #endif /* NDEBUG */
202 }
203 else
204 {
205 sprintf (buffer,
206 "\nKernel Debugger: No COM port found!!!\n\n");
207 HalDisplayString (buffer);
208 return FALSE;
209 }
210 }
211 else
212 {
213 if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
214 {
215 PortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
216 ComPort = PortInformation->ComPort;
217 PortInformation->BaseAddress = (ULONG)PortBase;
218 #ifndef NDEBUG
219 sprintf (buffer,
220 "\nSerial port COM%ld found at 0x%lx\n",
221 ComPort,
222 (ULONG)PortBase);
223 HalDisplayString (buffer);
224 #endif /* NDEBUG */
225 }
226 else
227 {
228 sprintf (buffer,
229 "\nKernel Debugger: No serial port found!!!\n\n");
230 HalDisplayString (buffer);
231 return FALSE;
232 }
233 }
234
235 PortInitialized = TRUE;
236 }
237
238 /*
239 * set baud rate and data format (8N1)
240 */
241
242 /* turn on DTR and RTS */
243 WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS);
244
245 /* set DLAB */
246 lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB;
247 WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr);
248
249 /* set baud rate */
250 divisor = 115200 / BaudRate;
251 WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff));
252 WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff));
253
254 /* reset DLAB and set 8N1 format */
255 WRITE_PORT_UCHAR (SER_LCR(PortBase),
256 SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
257
258 /* read junk out of the RBR */
259 lcr = READ_PORT_UCHAR (SER_RBR(PortBase));
260
261 /*
262 * set global info
263 */
264 KdComPortInUse = (ULONG)PortBase;
265
266 /*
267 * print message to blue screen
268 */
269 sprintf (buffer,
270 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
271 ComPort,
272 (ULONG)PortBase,
273 BaudRate);
274
275 HalDisplayString (buffer);
276
277 return TRUE;
278 }
279
280
281 /* HAL.KdPortInitializeEx */
282 BOOLEAN
283 STDCALL
284 KdPortInitializeEx (
285 PKD_PORT_INFORMATION PortInformation,
286 DWORD Unknown1,
287 DWORD Unknown2
288 )
289 {
290 ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
291 PUCHAR ComPortBase;
292 char buffer[80];
293 ULONG divisor;
294 BYTE lcr;
295
296 if (PortInformation->BaudRate == 0)
297 {
298 PortInformation->BaudRate = DEFAULT_BAUD_RATE;
299 }
300
301 if (PortInformation->ComPort == 0)
302 {
303 return FALSE;
304 }
305 else
306 {
307 if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
308 {
309 ComPortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
310 PortInformation->BaseAddress = (ULONG)ComPortBase;
311 #ifndef NDEBUG
312 sprintf (buffer,
313 "\nSerial port COM%ld found at 0x%lx\n",
314 PortInformation->ComPort,
315 (ULONG)ComPortBase];
316 HalDisplayString (buffer);
317 #endif /* NDEBUG */
318 }
319 else
320 {
321 sprintf (buffer,
322 "\nKernel Debugger: Serial port not found!!!\n\n");
323 HalDisplayString (buffer);
324 return FALSE;
325 }
326 }
327
328 /*
329 * set baud rate and data format (8N1)
330 */
331
332 /* turn on DTR and RTS */
333 WRITE_PORT_UCHAR (SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
334
335 /* set DLAB */
336 lcr = READ_PORT_UCHAR (SER_LCR(ComPortBase)) | SR_LCR_DLAB;
337 WRITE_PORT_UCHAR (SER_LCR(ComPortBase), lcr);
338
339 /* set baud rate */
340 divisor = 115200 / PortInformation->BaudRate;
341 WRITE_PORT_UCHAR (SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
342 WRITE_PORT_UCHAR (SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
343
344 /* reset DLAB and set 8N1 format */
345 WRITE_PORT_UCHAR (SER_LCR(ComPortBase),
346 SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
347
348 /* read junk out of the RBR */
349 lcr = READ_PORT_UCHAR (SER_RBR(ComPortBase));
350
351 #ifndef NDEBUG
352
353 /*
354 * print message to blue screen
355 */
356 sprintf (buffer,
357 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
358 PortInformation->ComPort,
359 (ULONG)ComPortBase,
360 PortInformation->BaudRate);
361
362 HalDisplayString (buffer);
363
364 #endif /* NDEBUG */
365
366 return TRUE;
367 }
368
369
370 /* HAL.KdPortGetByte */
371 BOOLEAN
372 STDCALL
373 KdPortGetByte (
374 PUCHAR ByteRecieved
375 )
376 {
377 if (PortInitialized == FALSE)
378 return FALSE;
379
380 if ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR))
381 {
382 *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
383 return TRUE;
384 }
385
386 return FALSE;
387 }
388
389
390 /* HAL.KdPortGetByteEx */
391 BOOLEAN
392 STDCALL
393 KdPortGetByteEx (
394 PKD_PORT_INFORMATION PortInformation,
395 PUCHAR ByteRecieved
396 )
397 {
398 PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
399
400 if ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR))
401 {
402 *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
403 return TRUE;
404 }
405
406 return FALSE;
407 }
408
409
410 /* HAL.KdPortPollByte */
411 BOOLEAN
412 STDCALL
413 KdPortPollByte (
414 PUCHAR ByteRecieved
415 )
416 {
417 if (PortInitialized == FALSE)
418 return FALSE;
419
420 while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR) == 0)
421 ;
422
423 *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
424
425 return TRUE;
426 }
427
428
429 /* HAL.KdPortPollByteEx */
430 BOOLEAN
431 STDCALL
432 KdPortPollByteEx (
433 PKD_PORT_INFORMATION PortInformation,
434 PUCHAR ByteRecieved
435 )
436 {
437 PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
438
439 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR) == 0)
440 ;
441
442 *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
443
444 return TRUE;
445 }
446
447
448
449
450 /* HAL.KdPortPutByte */
451 VOID
452 STDCALL
453 KdPortPutByte (
454 UCHAR ByteToSend
455 )
456 {
457 if (PortInitialized == FALSE)
458 return;
459
460 while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_TBE) == 0)
461 ;
462
463 WRITE_PORT_UCHAR (SER_THR(PortBase), ByteToSend);
464 }
465
466 /* HAL.KdPortPutByteEx */
467 VOID
468 STDCALL
469 KdPortPutByteEx (
470 PKD_PORT_INFORMATION PortInformation,
471 UCHAR ByteToSend
472 )
473 {
474 PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
475
476 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
477 ;
478
479 WRITE_PORT_UCHAR (SER_THR(ComPortBase), ByteToSend);
480 }
481
482
483 /* HAL.KdPortRestore */
484 VOID
485 STDCALL
486 KdPortRestore (
487 VOID
488 )
489 {
490 }
491
492
493 /* HAL.KdPortSave */
494 VOID
495 STDCALL
496 KdPortSave (
497 VOID
498 )
499 {
500 }
501
502
503 /* HAL.KdPortDisableInterrupts */
504 BOOLEAN
505 STDCALL
506 KdPortDisableInterrupts()
507 {
508 UCHAR ch;
509
510 if (PortInitialized == FALSE)
511 return FALSE;
512
513 ch = READ_PORT_UCHAR (SER_MCR (PortBase));
514 ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2));
515 WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
516
517 ch = READ_PORT_UCHAR (SER_IER (PortBase));
518 ch &= (~SR_IER_ALL);
519 WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
520
521 return TRUE;
522 }
523
524
525 /* HAL.KdPortEnableInterrupts */
526 BOOLEAN
527 STDCALL
528 KdPortEnableInterrupts()
529 {
530 UCHAR ch;
531
532 if (PortInitialized == FALSE)
533 return FALSE;
534
535 ch = READ_PORT_UCHAR (SER_IER (PortBase));
536 ch &= (~SR_IER_ALL);
537 ch |= SR_IER_ERDA;
538 WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
539
540 ch = READ_PORT_UCHAR (SER_MCR (PortBase));
541 ch &= (~SR_MCR_LOOP);
542 ch |= (SR_MCR_OUT1 | SR_MCR_OUT2);
543 WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
544
545 return TRUE;
546 }
547
548 /* EOF */