2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/base/kdcom/kdbg.c
5 * PURPOSE: Serial i/o functions for the kernel debugger.
6 * PROGRAMMER: Alex Ionescu
10 /* INCLUDES *****************************************************************/
19 #include <ioaccess.h> /* port intrinsics */
20 #include <cportlib/cportlib.h>
26 typedef struct _KD_PORT_INFORMATION
31 } KD_PORT_INFORMATION
, *PKD_PORT_INFORMATION
;
36 IN PKD_PORT_INFORMATION PortInformation
,
43 IN PKD_PORT_INFORMATION PortInformation
,
44 OUT PUCHAR ByteReceived
);
49 IN PKD_PORT_INFORMATION PortInformation
,
50 OUT PUCHAR ByteReceived
);
55 IN PKD_PORT_INFORMATION PortInformation
,
58 #define DEFAULT_BAUD_RATE 19200
60 #if defined(_M_IX86) || defined(_M_AMD64)
61 const ULONG BaseArray
[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
63 const ULONG BaseArray
[] = {0, 0x800003F8};
64 #elif defined(_M_MIPS)
65 const ULONG BaseArray
[] = {0, 0x80006000, 0x80007000};
67 const ULONG BaseArray
[] = {0, 0xF1012000};
69 #error Unknown architecture
72 /* MACROS *******************************************************************/
74 #define SER_RBR(x) ((PUCHAR)(x)+0)
75 #define SER_THR(x) ((PUCHAR)(x)+0)
76 #define SER_DLL(x) ((PUCHAR)(x)+0)
77 #define SER_IER(x) ((PUCHAR)(x)+1)
78 #define SR_IER_ERDA 0x01
79 #define SR_IER_ETHRE 0x02
80 #define SR_IER_ERLSI 0x04
81 #define SR_IER_EMS 0x08
82 #define SR_IER_ALL 0x0F
83 #define SER_DLM(x) ((PUCHAR)(x)+1)
84 #define SER_IIR(x) ((PUCHAR)(x)+2)
85 #define SER_FCR(x) ((PUCHAR)(x)+2)
86 #define SR_FCR_ENABLE_FIFO 0x01
87 #define SR_FCR_CLEAR_RCVR 0x02
88 #define SR_FCR_CLEAR_XMIT 0x04
89 #define SER_LCR(x) ((PUCHAR)(x)+3)
90 #define SR_LCR_CS5 0x00
91 #define SR_LCR_CS6 0x01
92 #define SR_LCR_CS7 0x02
93 #define SR_LCR_CS8 0x03
94 #define SR_LCR_ST1 0x00
95 #define SR_LCR_ST2 0x04
96 #define SR_LCR_PNO 0x00
97 #define SR_LCR_POD 0x08
98 #define SR_LCR_PEV 0x18
99 #define SR_LCR_PMK 0x28
100 #define SR_LCR_PSP 0x38
101 #define SR_LCR_BRK 0x40
102 #define SR_LCR_DLAB 0x80
103 #define SER_MCR(x) ((PUCHAR)(x)+4)
104 #define SR_MCR_DTR 0x01
105 #define SR_MCR_RTS 0x02
106 #define SR_MCR_OUT1 0x04
107 #define SR_MCR_OUT2 0x08
108 #define SR_MCR_LOOP 0x10
109 #define SER_LSR(x) ((PUCHAR)(x)+5)
110 #define SR_LSR_DR 0x01
111 #define SR_LSR_TBE 0x20
112 #define SER_MSR(x) ((PUCHAR)(x)+6)
113 #define SR_MSR_CTS 0x10
114 #define SR_MSR_DSR 0x20
115 #define SER_SCR(x) ((PUCHAR)(x)+7)
118 /* GLOBAL VARIABLES *********************************************************/
120 /* STATIC VARIABLES *********************************************************/
122 static KD_PORT_INFORMATION DefaultPort
= { 0, 0, 0 };
124 /* The com port must only be initialized once! */
125 static BOOLEAN PortInitialized
= FALSE
;
128 /* FUNCTIONS ****************************************************************/
130 /* HAL.KdPortInitialize */
134 IN PKD_PORT_INFORMATION PortInformation
,
141 if (!PortInitialized
)
143 DefaultPort
.BaudRate
= PortInformation
->BaudRate
;
145 if (PortInformation
->ComPort
== 0)
148 * Start enumerating COM ports from the last one to the first one,
149 * and break when we find a valid port.
150 * If we reach the first element of the list, the invalid COM port,
151 * then it means that no valid port was found.
153 for (i
= sizeof(BaseArray
) / sizeof(BaseArray
[0]) - 1; i
> 0; i
--)
155 if (CpDoesPortExist(UlongToPtr(BaseArray
[i
])))
157 PortInformation
->BaseAddress
= DefaultPort
.BaseAddress
= BaseArray
[i
];
158 PortInformation
->ComPort
= DefaultPort
.ComPort
= i
;
165 "\nKernel Debugger: No COM port found!\n\n");
166 HalDisplayString(buffer
);
171 PortInitialized
= TRUE
;
174 /* initialize port */
175 if (!KdPortInitializeEx(&DefaultPort
, Unknown1
, Unknown2
))
178 /* set global info */
179 KdComPortInUse
= (PUCHAR
)DefaultPort
.BaseAddress
;
185 /* HAL.KdPortInitializeEx ; ReactOS-specific */
189 IN PKD_PORT_INFORMATION PortInformation
,
203 if (PortInformation
->BaudRate
== 0)
204 PortInformation
->BaudRate
= DEFAULT_BAUD_RATE
;
206 if (PortInformation
->ComPort
!= 0)
208 if (!CpDoesPortExist(UlongToPtr(BaseArray
[PortInformation
->ComPort
])))
211 "\nKernel Debugger: Serial port not found!\n\n");
212 HalDisplayString(buffer
);
216 ComPortBase
= BaseArray
[PortInformation
->ComPort
];
217 PortInformation
->BaseAddress
= ComPortBase
;
221 ComPortBase
= PortInformation
->BaseAddress
;
224 if (ComPortBase
== 0)
229 "\nSerial port COM%ld found at 0x%lx\n",
230 PortInformation
->ComPort
,
232 HalDisplayString(buffer
);
235 /* set baud rate and data format (8N1) */
237 /* turn on DTR and RTS */
238 WRITE_PORT_UCHAR(SER_MCR(ComPortBase
), SR_MCR_DTR
| SR_MCR_RTS
);
241 lcr
= READ_PORT_UCHAR(SER_LCR(ComPortBase
)) | SR_LCR_DLAB
;
242 WRITE_PORT_UCHAR(SER_LCR(ComPortBase
), lcr
);
245 divisor
= 115200 / PortInformation
->BaudRate
;
246 WRITE_PORT_UCHAR(SER_DLL(ComPortBase
), (UCHAR
)(divisor
& 0xff));
247 WRITE_PORT_UCHAR(SER_DLM(ComPortBase
), (UCHAR
)((divisor
>> 8) & 0xff));
249 /* reset DLAB and set 8N1 format */
250 WRITE_PORT_UCHAR(SER_LCR(ComPortBase
),
251 SR_LCR_CS8
| SR_LCR_ST1
| SR_LCR_PNO
);
253 /* read junk out of the RBR */
254 lcr
= READ_PORT_UCHAR(SER_RBR(ComPortBase
));
257 /* print message to blue screen */
259 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
260 PortInformation
->ComPort
,
262 PortInformation
->BaudRate
);
264 HalDisplayString(buffer
);
271 /* HAL.KdPortGetByte */
275 OUT PUCHAR ByteReceived
)
277 if (!PortInitialized
)
279 return KdPortGetByteEx(&DefaultPort
, ByteReceived
);
283 /* HAL.KdPortGetByteEx ; ReactOS-specific */
287 IN PKD_PORT_INFORMATION PortInformation
,
288 OUT PUCHAR ByteReceived
)
290 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
292 if ((READ_PORT_UCHAR(SER_LSR(ComPortBase
)) & SR_LSR_DR
))
294 *ByteReceived
= READ_PORT_UCHAR(SER_RBR(ComPortBase
));
302 /* HAL.KdPortPollByte */
306 OUT PUCHAR ByteReceived
)
308 if (!PortInitialized
)
310 return KdPortPollByteEx(&DefaultPort
, ByteReceived
);
314 /* HAL.KdPortPollByteEx ; ReactOS-specific */
318 IN PKD_PORT_INFORMATION PortInformation
,
319 OUT PUCHAR ByteReceived
)
321 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
323 while ((READ_PORT_UCHAR(SER_LSR(ComPortBase
)) & SR_LSR_DR
) == 0)
326 *ByteReceived
= READ_PORT_UCHAR(SER_RBR(ComPortBase
));
332 /* HAL.KdPortPutByte */
338 if (!PortInitialized
)
340 KdPortPutByteEx(&DefaultPort
, ByteToSend
);
343 /* HAL.KdPortPutByteEx ; ReactOS-specific */
347 IN PKD_PORT_INFORMATION PortInformation
,
350 PUCHAR ComPortBase
= (PUCHAR
)PortInformation
->BaseAddress
;
352 while ((READ_PORT_UCHAR(SER_LSR(ComPortBase
)) & SR_LSR_TBE
) == 0)
355 WRITE_PORT_UCHAR(SER_THR(ComPortBase
), ByteToSend
);
359 /* HAL.KdPortRestore */
377 /* HAL.KdPortDisableInterrupts */
380 KdPortDisableInterrupts(VOID
)
384 if (!PortInitialized
)
387 ch
= READ_PORT_UCHAR(SER_MCR(DefaultPort
.BaseAddress
));
388 ch
&= (~(SR_MCR_OUT1
| SR_MCR_OUT2
));
389 WRITE_PORT_UCHAR(SER_MCR(DefaultPort
.BaseAddress
), ch
);
391 ch
= READ_PORT_UCHAR(SER_IER(DefaultPort
.BaseAddress
));
393 WRITE_PORT_UCHAR(SER_IER(DefaultPort
.BaseAddress
), ch
);
399 /* HAL.KdPortEnableInterrupts */
402 KdPortEnableInterrupts(VOID
)
406 if (PortInitialized
== FALSE
)
409 ch
= READ_PORT_UCHAR(SER_IER(DefaultPort
.BaseAddress
));
412 WRITE_PORT_UCHAR(SER_IER(DefaultPort
.BaseAddress
), ch
);
414 ch
= READ_PORT_UCHAR(SER_MCR(DefaultPort
.BaseAddress
));
415 ch
&= (~SR_MCR_LOOP
);
416 ch
|= (SR_MCR_OUT1
| SR_MCR_OUT2
);
417 WRITE_PORT_UCHAR(SER_MCR(DefaultPort
.BaseAddress
), ch
);
427 KdDebuggerInitialize0(
428 IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL
)
430 return STATUS_NOT_IMPLEMENTED
;
438 KdDebuggerInitialize1(
439 IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL
)
441 return STATUS_NOT_IMPLEMENTED
;
450 IN BOOLEAN SleepTransition
)
452 /* Nothing to do on COM ports */
453 return STATUS_SUCCESS
;
462 IN BOOLEAN SleepTransition
)
464 /* Nothing to do on COM ports */
465 return STATUS_SUCCESS
;
475 IN PSTRING MessageHeader
,
476 IN PSTRING MessageData
,
477 IN OUT PKD_CONTEXT Context
)
490 OUT PSTRING MessageHeader
,
491 OUT PSTRING MessageData
,
492 OUT PULONG DataLength
,
493 IN OUT PKD_CONTEXT Context
)