1 /* $Id: kdbg.c,v 1.8 2004/04/29 17:06:21 navaraf 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_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)
70 /* GLOBAL VARIABLES *********************************************************/
72 ULONG EXPORTED KdComPortInUse
= 0;
75 /* STATIC VARIABLES *********************************************************/
77 static ULONG ComPort
= 0;
78 static ULONG BaudRate
= 0;
79 static PUCHAR PortBase
= (PUCHAR
)0;
81 /* The com port must only be initialized once! */
82 static BOOLEAN PortInitialized
= FALSE
;
85 /* STATIC FUNCTIONS *********************************************************/
88 KdpDoesComPortExist (PUCHAR BaseAddress
)
96 /* save Modem Control Register (MCR) */
97 mcr
= READ_PORT_UCHAR (SER_MCR(BaseAddress
));
99 /* enable loop mode (set Bit 4 of the MCR) */
100 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x10);
102 /* clear all modem output bits */
103 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x10);
105 /* read the Modem Status Register */
106 msr
= READ_PORT_UCHAR (SER_MSR(BaseAddress
));
109 * the upper nibble of the MSR (modem output bits) must be
110 * equal to the lower nibble of the MCR (modem input bits)
112 if ((msr
& 0xF0) == 0x00)
114 /* set all modem output bits */
115 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x1F);
117 /* read the Modem Status Register */
118 msr
= READ_PORT_UCHAR (SER_MSR(BaseAddress
));
121 * the upper nibble of the MSR (modem output bits) must be
122 * equal to the lower nibble of the MCR (modem input bits)
124 if ((msr
& 0xF0) == 0xF0)
127 * setup a resonable state for the port:
128 * enable fifo and clear recieve/transmit buffers
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);
140 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), mcr
);
146 /* FUNCTIONS ****************************************************************/
148 /* HAL.KdPortInitialize */
152 PKD_PORT_INFORMATION PortInformation
,
157 ULONG BaseArray
[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
162 if (PortInitialized
== FALSE
)
164 if (PortInformation
->BaudRate
!= 0)
166 BaudRate
= PortInformation
->BaudRate
;
170 BaudRate
= DEFAULT_BAUD_RATE
;
173 if (PortInformation
->ComPort
== 0)
175 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[2]))
177 PortBase
= (PUCHAR
)BaseArray
[2];
179 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
180 PortInformation
->ComPort
= ComPort
;
183 "\nSerial port COM%ld found at 0x%lx\n",
186 HalDisplayString (buffer
);
189 else if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[1]))
191 PortBase
= (PUCHAR
)BaseArray
[1];
193 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
194 PortInformation
->ComPort
= ComPort
;
197 "\nSerial port COM%ld found at 0x%lx\n",
200 HalDisplayString (buffer
);
206 "\nKernel Debugger: No COM port found!!!\n\n");
207 HalDisplayString (buffer
);
213 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[PortInformation
->ComPort
]))
215 PortBase
= (PUCHAR
)BaseArray
[PortInformation
->ComPort
];
216 ComPort
= PortInformation
->ComPort
;
217 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
220 "\nSerial port COM%ld found at 0x%lx\n",
223 HalDisplayString (buffer
);
229 "\nKernel Debugger: No serial port found!!!\n\n");
230 HalDisplayString (buffer
);
235 PortInitialized
= TRUE
;
239 * set baud rate and data format (8N1)
242 /* turn on DTR and RTS */
243 WRITE_PORT_UCHAR (SER_MCR(PortBase
), SR_MCR_DTR
| SR_MCR_RTS
);
246 lcr
= READ_PORT_UCHAR (SER_LCR(PortBase
)) | SR_LCR_DLAB
;
247 WRITE_PORT_UCHAR (SER_LCR(PortBase
), lcr
);
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));
254 /* reset DLAB and set 8N1 format */
255 WRITE_PORT_UCHAR (SER_LCR(PortBase
),
256 SR_LCR_CS8
| SR_LCR_ST1
| SR_LCR_PNO
);
258 /* read junk out of the RBR */
259 lcr
= READ_PORT_UCHAR (SER_RBR(PortBase
));
264 KdComPortInUse
= (ULONG
)PortBase
;
267 * print message to blue screen
270 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
275 HalDisplayString (buffer
);
281 /* HAL.KdPortInitializeEx */
285 PKD_PORT_INFORMATION PortInformation
,
290 ULONG BaseArray
[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
296 if (PortInformation
->BaudRate
== 0)
298 PortInformation
->BaudRate
= DEFAULT_BAUD_RATE
;
301 if (PortInformation
->ComPort
== 0)
307 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[PortInformation
->ComPort
]))
309 ComPortBase
= (PUCHAR
)BaseArray
[PortInformation
->ComPort
];
310 PortInformation
->BaseAddress
= (ULONG
)ComPortBase
;
313 "\nSerial port COM%ld found at 0x%lx\n",
314 PortInformation
->ComPort
,
316 HalDisplayString (buffer
);
322 "\nKernel Debugger: Serial port not found!!!\n\n");
323 HalDisplayString (buffer
);
329 * set baud rate and data format (8N1)
332 /* turn on DTR and RTS */
333 WRITE_PORT_UCHAR (SER_MCR(ComPortBase
), SR_MCR_DTR
| SR_MCR_RTS
);
336 lcr
= READ_PORT_UCHAR (SER_LCR(ComPortBase
)) | SR_LCR_DLAB
;
337 WRITE_PORT_UCHAR (SER_LCR(ComPortBase
), lcr
);
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));
344 /* reset DLAB and set 8N1 format */
345 WRITE_PORT_UCHAR (SER_LCR(ComPortBase
),
346 SR_LCR_CS8
| SR_LCR_ST1
| SR_LCR_PNO
);
348 /* read junk out of the RBR */
349 lcr
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
354 * print message to blue screen
357 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
358 PortInformation
->ComPort
,
360 PortInformation
->BaudRate
);
362 HalDisplayString (buffer
);
370 /* HAL.KdPortGetByte */
377 if (PortInitialized
== FALSE
)
380 if ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_DR
))
382 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(PortBase
));
390 /* HAL.KdPortGetByteEx */
394 PKD_PORT_INFORMATION PortInformation
,
398 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
400 if ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_DR
))
402 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
410 /* HAL.KdPortPollByte */
417 if (PortInitialized
== FALSE
)
420 while ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_DR
) == 0)
423 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(PortBase
));
429 /* HAL.KdPortPollByteEx */
433 PKD_PORT_INFORMATION PortInformation
,
437 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
439 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_DR
) == 0)
442 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
450 /* HAL.KdPortPutByte */
457 if (PortInitialized
== FALSE
)
460 while ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_TBE
) == 0)
463 WRITE_PORT_UCHAR (SER_THR(PortBase
), ByteToSend
);
466 /* HAL.KdPortPutByteEx */
470 PKD_PORT_INFORMATION PortInformation
,
474 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
476 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_TBE
) == 0)
479 WRITE_PORT_UCHAR (SER_THR(ComPortBase
), ByteToSend
);
483 /* HAL.KdPortRestore */
503 /* HAL.KdPortDisableInterrupts */
506 KdPortDisableInterrupts()
510 if (PortInitialized
== FALSE
)
513 ch
= READ_PORT_UCHAR (SER_MCR (PortBase
));
514 ch
&= (~(SR_MCR_OUT1
| SR_MCR_OUT2
));
515 WRITE_PORT_UCHAR (SER_MCR (PortBase
), ch
);
517 ch
= READ_PORT_UCHAR (SER_IER (PortBase
));
519 WRITE_PORT_UCHAR (SER_IER (PortBase
), ch
);
525 /* HAL.KdPortEnableInterrupts */
528 KdPortEnableInterrupts()
532 if (PortInitialized
== FALSE
)
535 ch
= READ_PORT_UCHAR (SER_IER (PortBase
));
538 WRITE_PORT_UCHAR (SER_IER (PortBase
), ch
);
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
);