1 /* $Id: kdbg.c,v 1.7 2003/12/28 22:38:09 fireball Exp $
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
13 /* INCLUDES *****************************************************************/
15 #include <ddk/ntddk.h>
18 #include <internal/debug.h>
21 #define DEFAULT_BAUD_RATE 19200
24 /* MACROS *******************************************************************/
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_LCR(x) ((x)+3)
38 #define SR_LCR_CS5 0x00
39 #define SR_LCR_CS6 0x01
40 #define SR_LCR_CS7 0x02
41 #define SR_LCR_CS8 0x03
42 #define SR_LCR_ST1 0x00
43 #define SR_LCR_ST2 0x04
44 #define SR_LCR_PNO 0x00
45 #define SR_LCR_POD 0x08
46 #define SR_LCR_PEV 0x18
47 #define SR_LCR_PMK 0x28
48 #define SR_LCR_PSP 0x38
49 #define SR_LCR_BRK 0x40
50 #define SR_LCR_DLAB 0x80
51 #define SER_MCR(x) ((x)+4)
52 #define SR_MCR_DTR 0x01
53 #define SR_MCR_RTS 0x02
54 #define SR_MCR_OUT1 0x04
55 #define SR_MCR_OUT2 0x08
56 #define SR_MCR_LOOP 0x10
57 #define SER_LSR(x) ((x)+5)
58 #define SR_LSR_DR 0x01
59 #define SR_LSR_TBE 0x20
60 #define SER_MSR(x) ((x)+6)
61 #define SR_MSR_CTS 0x10
62 #define SR_MSR_DSR 0x20
63 #define SER_SCR(x) ((x)+7)
66 /* GLOBAL VARIABLES *********************************************************/
68 ULONG EXPORTED KdComPortInUse
= 0;
71 /* STATIC VARIABLES *********************************************************/
73 static ULONG ComPort
= 0;
74 static ULONG BaudRate
= 0;
75 static PUCHAR PortBase
= (PUCHAR
)0;
77 /* The com port must only be initialized once! */
78 static BOOLEAN PortInitialized
= FALSE
;
81 /* STATIC FUNCTIONS *********************************************************/
84 KdpDoesComPortExist (PUCHAR BaseAddress
)
92 /* save Modem Control Register (MCR) */
93 mcr
= READ_PORT_UCHAR (SER_MCR(BaseAddress
));
95 /* enable loop mode (set Bit 4 of the MCR) */
96 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x10);
98 /* clear all modem output bits */
99 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x10);
101 /* read the Modem Status Register */
102 msr
= READ_PORT_UCHAR (SER_MSR(BaseAddress
));
105 * the upper nibble of the MSR (modem output bits) must be
106 * equal to the lower nibble of the MCR (modem input bits)
108 if ((msr
& 0xF0) == 0x00)
110 /* set all modem output bits */
111 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x1F);
113 /* read the Modem Status Register */
114 msr
= READ_PORT_UCHAR (SER_MSR(BaseAddress
));
117 * the upper nibble of the MSR (modem output bits) must be
118 * equal to the lower nibble of the MCR (modem input bits)
120 if ((msr
& 0xF0) == 0xF0)
125 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), mcr
);
131 /* FUNCTIONS ****************************************************************/
133 /* HAL.KdPortInitialize */
137 PKD_PORT_INFORMATION PortInformation
,
142 ULONG BaseArray
[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
147 if (PortInitialized
== FALSE
)
149 if (PortInformation
->BaudRate
!= 0)
151 BaudRate
= PortInformation
->BaudRate
;
155 BaudRate
= DEFAULT_BAUD_RATE
;
158 if (PortInformation
->ComPort
== 0)
160 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[2]))
162 PortBase
= (PUCHAR
)BaseArray
[2];
164 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
165 PortInformation
->ComPort
= ComPort
;
168 "\nSerial port COM%ld found at 0x%lx\n",
171 HalDisplayString (buffer
);
174 else if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[1]))
176 PortBase
= (PUCHAR
)BaseArray
[1];
178 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
179 PortInformation
->ComPort
= ComPort
;
182 "\nSerial port COM%ld found at 0x%lx\n",
185 HalDisplayString (buffer
);
191 "\nKernel Debugger: No COM port found!!!\n\n");
192 HalDisplayString (buffer
);
198 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[PortInformation
->ComPort
]))
200 PortBase
= (PUCHAR
)BaseArray
[PortInformation
->ComPort
];
201 ComPort
= PortInformation
->ComPort
;
202 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
205 "\nSerial port COM%ld found at 0x%lx\n",
208 HalDisplayString (buffer
);
214 "\nKernel Debugger: No serial port found!!!\n\n");
215 HalDisplayString (buffer
);
220 PortInitialized
= TRUE
;
224 * set baud rate and data format (8N1)
227 /* turn on DTR and RTS */
228 WRITE_PORT_UCHAR (SER_MCR(PortBase
), SR_MCR_DTR
| SR_MCR_RTS
);
231 lcr
= READ_PORT_UCHAR (SER_LCR(PortBase
)) | SR_LCR_DLAB
;
232 WRITE_PORT_UCHAR (SER_LCR(PortBase
), lcr
);
235 divisor
= 115200 / BaudRate
;
236 WRITE_PORT_UCHAR (SER_DLL(PortBase
), (UCHAR
)(divisor
& 0xff));
237 WRITE_PORT_UCHAR (SER_DLM(PortBase
), (UCHAR
)((divisor
>> 8) & 0xff));
239 /* reset DLAB and set 8N1 format */
240 WRITE_PORT_UCHAR (SER_LCR(PortBase
),
241 SR_LCR_CS8
| SR_LCR_ST1
| SR_LCR_PNO
);
243 /* read junk out of the RBR */
244 lcr
= READ_PORT_UCHAR (SER_RBR(PortBase
));
249 KdComPortInUse
= (ULONG
)PortBase
;
252 * print message to blue screen
255 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
260 HalDisplayString (buffer
);
266 /* HAL.KdPortInitializeEx */
270 PKD_PORT_INFORMATION PortInformation
,
275 ULONG BaseArray
[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
281 if (PortInformation
->BaudRate
== 0)
283 PortInformation
->BaudRate
= DEFAULT_BAUD_RATE
;
286 if (PortInformation
->ComPort
== 0)
292 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[PortInformation
->ComPort
]))
294 ComPortBase
= (PUCHAR
)BaseArray
[PortInformation
->ComPort
];
295 PortInformation
->BaseAddress
= (ULONG
)ComPortBase
;
298 "\nSerial port COM%ld found at 0x%lx\n",
299 PortInformation
->ComPort
,
301 HalDisplayString (buffer
);
307 "\nKernel Debugger: Serial port not found!!!\n\n");
308 HalDisplayString (buffer
);
314 * set baud rate and data format (8N1)
317 /* turn on DTR and RTS */
318 WRITE_PORT_UCHAR (SER_MCR(ComPortBase
), SR_MCR_DTR
| SR_MCR_RTS
);
321 lcr
= READ_PORT_UCHAR (SER_LCR(ComPortBase
)) | SR_LCR_DLAB
;
322 WRITE_PORT_UCHAR (SER_LCR(ComPortBase
), lcr
);
325 divisor
= 115200 / PortInformation
->BaudRate
;
326 WRITE_PORT_UCHAR (SER_DLL(ComPortBase
), (UCHAR
)(divisor
& 0xff));
327 WRITE_PORT_UCHAR (SER_DLM(ComPortBase
), (UCHAR
)((divisor
>> 8) & 0xff));
329 /* reset DLAB and set 8N1 format */
330 WRITE_PORT_UCHAR (SER_LCR(ComPortBase
),
331 SR_LCR_CS8
| SR_LCR_ST1
| SR_LCR_PNO
);
333 /* read junk out of the RBR */
334 lcr
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
339 * print message to blue screen
342 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
343 PortInformation
->ComPort
,
345 PortInformation
->BaudRate
);
347 HalDisplayString (buffer
);
355 /* HAL.KdPortGetByte */
362 if (PortInitialized
== FALSE
)
365 if ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_DR
))
367 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(PortBase
));
375 /* HAL.KdPortGetByteEx */
379 PKD_PORT_INFORMATION PortInformation
,
383 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
385 if ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_DR
))
387 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
395 /* HAL.KdPortPollByte */
402 if (PortInitialized
== FALSE
)
405 while ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_DR
) == 0)
408 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(PortBase
));
414 /* HAL.KdPortPollByteEx */
418 PKD_PORT_INFORMATION PortInformation
,
422 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
424 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_DR
) == 0)
427 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
435 /* HAL.KdPortPutByte */
442 if (PortInitialized
== FALSE
)
445 while ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_TBE
) == 0)
448 WRITE_PORT_UCHAR (SER_THR(PortBase
), ByteToSend
);
451 /* HAL.KdPortPutByteEx */
455 PKD_PORT_INFORMATION PortInformation
,
459 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
461 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_TBE
) == 0)
464 WRITE_PORT_UCHAR (SER_THR(ComPortBase
), ByteToSend
);
468 /* HAL.KdPortRestore */
488 /* HAL.KdPortDisableInterrupts */
491 KdPortDisableInterrupts()
495 if (PortInitialized
== FALSE
)
498 ch
= READ_PORT_UCHAR (SER_MCR (PortBase
));
499 ch
&= (~(SR_MCR_OUT1
| SR_MCR_OUT2
));
500 WRITE_PORT_UCHAR (SER_MCR (PortBase
), ch
);
502 ch
= READ_PORT_UCHAR (SER_IER (PortBase
));
504 WRITE_PORT_UCHAR (SER_IER (PortBase
), ch
);
510 /* HAL.KdPortEnableInterrupts */
513 KdPortEnableInterrupts()
517 if (PortInitialized
== FALSE
)
520 ch
= READ_PORT_UCHAR (SER_IER (PortBase
));
523 WRITE_PORT_UCHAR (SER_IER (PortBase
), ch
);
525 ch
= READ_PORT_UCHAR (SER_MCR (PortBase
));
526 ch
&= (~SR_MCR_LOOP
);
527 ch
|= (SR_MCR_OUT1
| SR_MCR_OUT2
);
528 WRITE_PORT_UCHAR (SER_MCR (PortBase
), ch
);