1 /* $Id: kdbg.c 23907 2006-09-04 05:52:23Z arty $
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 *****************************************************************/
20 #define DEFAULT_BAUD_RATE 19200
23 /* MACROS *******************************************************************/
25 #define SER_RBR(x) ((x)+0)
26 #define SER_THR(x) ((x)+0)
27 #define SER_DLL(x) ((x)+0)
28 #define SER_IER(x) ((x)+1)
29 #define SR_IER_ERDA 0x01
30 #define SR_IER_ETHRE 0x02
31 #define SR_IER_ERLSI 0x04
32 #define SR_IER_EMS 0x08
33 #define SR_IER_ALL 0x0F
34 #define SER_DLM(x) ((x)+1)
35 #define SER_IIR(x) ((x)+2)
36 #define SER_FCR(x) ((x)+2)
37 #define SR_FCR_ENABLE_FIFO 0x01
38 #define SR_FCR_CLEAR_RCVR 0x02
39 #define SR_FCR_CLEAR_XMIT 0x04
40 #define SER_LCR(x) ((x)+3)
41 #define SR_LCR_CS5 0x00
42 #define SR_LCR_CS6 0x01
43 #define SR_LCR_CS7 0x02
44 #define SR_LCR_CS8 0x03
45 #define SR_LCR_ST1 0x00
46 #define SR_LCR_ST2 0x04
47 #define SR_LCR_PNO 0x00
48 #define SR_LCR_POD 0x08
49 #define SR_LCR_PEV 0x18
50 #define SR_LCR_PMK 0x28
51 #define SR_LCR_PSP 0x38
52 #define SR_LCR_BRK 0x40
53 #define SR_LCR_DLAB 0x80
54 #define SER_MCR(x) ((x)+4)
55 #define SR_MCR_DTR 0x01
56 #define SR_MCR_RTS 0x02
57 #define SR_MCR_OUT1 0x04
58 #define SR_MCR_OUT2 0x08
59 #define SR_MCR_LOOP 0x10
60 #define SER_LSR(x) ((x)+5)
61 #define SR_LSR_DR 0x01
62 #define SR_LSR_TBE 0x20
63 #define SER_MSR(x) ((x)+6)
64 #define SR_MSR_CTS 0x10
65 #define SR_MSR_DSR 0x20
66 #define SER_SCR(x) ((x)+7)
69 /* GLOBAL VARIABLES *********************************************************/
71 #define KdComPortInUse _KdComPortInUse
72 ULONG KdComPortInUse
= 0;
74 /* STATIC VARIABLES *********************************************************/
76 static ULONG ComPort
= 0;
77 static ULONG BaudRate
= 0;
78 static PUCHAR PortBase
= (PUCHAR
)0;
80 /* The com port must only be initialized once! */
81 static BOOLEAN PortInitialized
= FALSE
;
84 /* STATIC FUNCTIONS *********************************************************/
87 KdpDoesComPortExist (PUCHAR BaseAddress
)
95 /* save Modem Control Register (MCR) */
96 mcr
= READ_PORT_UCHAR (SER_MCR(BaseAddress
));
98 /* enable loop mode (set Bit 4 of the MCR) */
99 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x10);
101 /* clear all modem output bits */
102 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x10);
104 /* read the Modem Status Register */
105 msr
= READ_PORT_UCHAR (SER_MSR(BaseAddress
));
108 * the upper nibble of the MSR (modem output bits) must be
109 * equal to the lower nibble of the MCR (modem input bits)
111 if ((msr
& 0xF0) == 0x00)
113 /* set all modem output bits */
114 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), 0x1F);
116 /* read the Modem Status Register */
117 msr
= READ_PORT_UCHAR (SER_MSR(BaseAddress
));
120 * the upper nibble of the MSR (modem output bits) must be
121 * equal to the lower nibble of the MCR (modem input bits)
123 if ((msr
& 0xF0) == 0xF0)
126 * setup a resonable state for the port:
127 * enable fifo and clear recieve/transmit buffers
129 WRITE_PORT_UCHAR (SER_FCR(BaseAddress
),
130 (SR_FCR_ENABLE_FIFO
| SR_FCR_CLEAR_RCVR
| SR_FCR_CLEAR_XMIT
));
131 WRITE_PORT_UCHAR (SER_FCR(BaseAddress
), 0);
132 READ_PORT_UCHAR (SER_RBR(BaseAddress
));
133 WRITE_PORT_UCHAR (SER_IER(BaseAddress
), 0);
139 WRITE_PORT_UCHAR (SER_MCR(BaseAddress
), mcr
);
145 /* FUNCTIONS ****************************************************************/
147 /* HAL.KdPortInitialize */
151 PKD_PORT_INFORMATION PortInformation
,
156 ULONG BaseArray
[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
161 if (PortInitialized
== FALSE
)
163 if (PortInformation
->BaudRate
!= 0)
165 BaudRate
= PortInformation
->BaudRate
;
169 BaudRate
= DEFAULT_BAUD_RATE
;
172 if (PortInformation
->ComPort
== 0)
174 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[2]))
176 PortBase
= (PUCHAR
)BaseArray
[2];
178 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
179 PortInformation
->ComPort
= ComPort
;
182 "\nSerial port COM%ld found at 0x%lx\n",
185 HalDisplayString (buffer
);
188 else if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[1]))
190 PortBase
= (PUCHAR
)BaseArray
[1];
192 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
193 PortInformation
->ComPort
= ComPort
;
196 "\nSerial port COM%ld found at 0x%lx\n",
199 HalDisplayString (buffer
);
205 "\nKernel Debugger: No COM port found!!!\n\n");
206 HalDisplayString (buffer
);
212 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[PortInformation
->ComPort
]))
214 PortBase
= (PUCHAR
)BaseArray
[PortInformation
->ComPort
];
215 ComPort
= PortInformation
->ComPort
;
216 PortInformation
->BaseAddress
= (ULONG
)PortBase
;
219 "\nSerial port COM%ld found at 0x%lx\n",
222 HalDisplayString (buffer
);
228 "\nKernel Debugger: No serial port found!!!\n\n");
229 HalDisplayString (buffer
);
234 PortInitialized
= TRUE
;
238 * set baud rate and data format (8N1)
241 /* turn on DTR and RTS */
242 WRITE_PORT_UCHAR (SER_MCR(PortBase
), SR_MCR_DTR
| SR_MCR_RTS
);
245 lcr
= READ_PORT_UCHAR (SER_LCR(PortBase
)) | SR_LCR_DLAB
;
246 WRITE_PORT_UCHAR (SER_LCR(PortBase
), lcr
);
249 divisor
= 115200 / BaudRate
;
250 WRITE_PORT_UCHAR (SER_DLL(PortBase
), (UCHAR
)(divisor
& 0xff));
251 WRITE_PORT_UCHAR (SER_DLM(PortBase
), (UCHAR
)((divisor
>> 8) & 0xff));
253 /* reset DLAB and set 8N1 format */
254 WRITE_PORT_UCHAR (SER_LCR(PortBase
),
255 SR_LCR_CS8
| SR_LCR_ST1
| SR_LCR_PNO
);
257 /* read junk out of the RBR */
258 lcr
= READ_PORT_UCHAR (SER_RBR(PortBase
));
263 KdComPortInUse
= (ULONG
)PortBase
;
266 * print message to blue screen
269 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
274 HalDisplayString (buffer
);
280 /* HAL.KdPortInitializeEx */
284 PKD_PORT_INFORMATION PortInformation
,
289 ULONG BaseArray
[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
295 if (PortInformation
->BaudRate
== 0)
297 PortInformation
->BaudRate
= DEFAULT_BAUD_RATE
;
300 if (PortInformation
->ComPort
== 0)
306 if (KdpDoesComPortExist ((PUCHAR
)BaseArray
[PortInformation
->ComPort
]))
308 ComPortBase
= (PUCHAR
)BaseArray
[PortInformation
->ComPort
];
309 PortInformation
->BaseAddress
= (ULONG
)ComPortBase
;
312 "\nSerial port COM%ld found at 0x%lx\n",
313 PortInformation
->ComPort
,
315 HalDisplayString (buffer
);
321 "\nKernel Debugger: Serial port not found!!!\n\n");
322 HalDisplayString (buffer
);
328 * set baud rate and data format (8N1)
331 /* turn on DTR and RTS */
332 WRITE_PORT_UCHAR (SER_MCR(ComPortBase
), SR_MCR_DTR
| SR_MCR_RTS
);
335 lcr
= READ_PORT_UCHAR (SER_LCR(ComPortBase
)) | SR_LCR_DLAB
;
336 WRITE_PORT_UCHAR (SER_LCR(ComPortBase
), lcr
);
339 divisor
= 115200 / PortInformation
->BaudRate
;
340 WRITE_PORT_UCHAR (SER_DLL(ComPortBase
), (UCHAR
)(divisor
& 0xff));
341 WRITE_PORT_UCHAR (SER_DLM(ComPortBase
), (UCHAR
)((divisor
>> 8) & 0xff));
343 /* reset DLAB and set 8N1 format */
344 WRITE_PORT_UCHAR (SER_LCR(ComPortBase
),
345 SR_LCR_CS8
| SR_LCR_ST1
| SR_LCR_PNO
);
347 /* read junk out of the RBR */
348 lcr
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
353 * print message to blue screen
356 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
357 PortInformation
->ComPort
,
359 PortInformation
->BaudRate
);
361 HalDisplayString (buffer
);
369 /* HAL.KdPortGetByte */
376 if (PortInitialized
== FALSE
)
379 if ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_DR
))
381 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(PortBase
));
389 /* HAL.KdPortGetByteEx */
393 PKD_PORT_INFORMATION PortInformation
,
397 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
399 if ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_DR
))
401 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
409 /* HAL.KdPortPollByte */
416 if (PortInitialized
== FALSE
)
419 while ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_DR
) == 0)
422 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(PortBase
));
428 /* HAL.KdPortPollByteEx */
432 PKD_PORT_INFORMATION PortInformation
,
436 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
438 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_DR
) == 0)
441 *ByteRecieved
= READ_PORT_UCHAR (SER_RBR(ComPortBase
));
449 /* HAL.KdPortPutByte */
456 if (PortInitialized
== FALSE
)
459 while ((READ_PORT_UCHAR (SER_LSR(PortBase
)) & SR_LSR_TBE
) == 0)
462 WRITE_PORT_UCHAR (SER_THR(PortBase
), ByteToSend
);
465 /* HAL.KdPortPutByteEx */
469 PKD_PORT_INFORMATION PortInformation
,
473 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
475 while ((READ_PORT_UCHAR (SER_LSR(ComPortBase
)) & SR_LSR_TBE
) == 0)
478 WRITE_PORT_UCHAR (SER_THR(ComPortBase
), ByteToSend
);
482 /* HAL.KdPortRestore */
502 /* HAL.KdPortDisableInterrupts */
505 KdPortDisableInterrupts()
509 if (PortInitialized
== FALSE
)
512 ch
= READ_PORT_UCHAR (SER_MCR (PortBase
));
513 ch
&= (~(SR_MCR_OUT1
| SR_MCR_OUT2
));
514 WRITE_PORT_UCHAR (SER_MCR (PortBase
), ch
);
516 ch
= READ_PORT_UCHAR (SER_IER (PortBase
));
518 WRITE_PORT_UCHAR (SER_IER (PortBase
), ch
);
524 /* HAL.KdPortEnableInterrupts */
527 KdPortEnableInterrupts()
531 if (PortInitialized
== FALSE
)
534 ch
= READ_PORT_UCHAR (SER_IER (PortBase
));
537 WRITE_PORT_UCHAR (SER_IER (PortBase
), ch
);
539 ch
= READ_PORT_UCHAR (SER_MCR (PortBase
));
540 ch
&= (~SR_MCR_LOOP
);
541 ch
|= (SR_MCR_OUT1
| SR_MCR_OUT2
);
542 WRITE_PORT_UCHAR (SER_MCR (PortBase
), ch
);