ReactOS 0.4.15-dev-7942-gd23573b
kdcom.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/base/kddll/kdcom.c
5 * PURPOSE: COM port functions for the kernel debugger.
6 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9#include "kddll.h"
10
11#include <cportlib/cportlib.h>
12#include <arc/arc.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <ndk/halfuncs.h>
16
17/* Serial debug connection */
18#if defined(SARCH_PC98)
19#define DEFAULT_DEBUG_PORT 2 /* COM2 */
20#define DEFAULT_DEBUG_COM1_IRQ 4
21#define DEFAULT_DEBUG_COM2_IRQ 5
22#define DEFAULT_DEBUG_BAUD_RATE 9600
23#define DEFAULT_BAUD_RATE 9600
24#else
25#define DEFAULT_DEBUG_PORT 2 /* COM2 */
26#define DEFAULT_DEBUG_COM1_IRQ 4
27#define DEFAULT_DEBUG_COM2_IRQ 3
28#define DEFAULT_DEBUG_BAUD_RATE 115200
29#define DEFAULT_BAUD_RATE 19200
30#endif
31
32#if defined(_M_IX86) || defined(_M_AMD64)
33#if defined(SARCH_PC98)
34const ULONG BaseArray[] = {0, 0x30, 0x238};
35#else
36const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
37#endif
38#elif defined(_M_PPC)
39const ULONG BaseArray[] = {0, 0x800003F8};
40#elif defined(_M_MIPS)
41const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
42#elif defined(_M_ARM)
43const ULONG BaseArray[] = {0, 0xF1012000};
44#else
45#error Unknown architecture
46#endif
47
48#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
49
50/* GLOBALS ********************************************************************/
51
53ULONG KdComPortIrq = 0; // Not used at the moment.
54#ifdef KDDEBUG
55CPPORT KdDebugComPort;
56#endif
57
58/* DEBUGGING ******************************************************************/
59
60#ifdef KDDEBUG
61ULONG KdpDbgPrint(const char *Format, ...)
62{
63 va_list ap;
64 int Length;
65 char* ptr;
66 CHAR Buffer[512];
67
69 Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
70 va_end(ap);
71
72 /* Check if we went past the buffer */
73 if (Length == -1)
74 {
75 /* Terminate it if we went over-board */
76 Buffer[sizeof(Buffer) - 1] = '\n';
77
78 /* Put maximum */
79 Length = sizeof(Buffer);
80 }
81
82 ptr = Buffer;
83 while (Length--)
84 {
85 if (*ptr == '\n')
86 CpPutByte(&KdDebugComPort, '\r');
87
88 CpPutByte(&KdDebugComPort, *ptr++);
89 }
90
91 return 0;
92}
93#endif
94
95/* FUNCTIONS ******************************************************************/
96
100{
101 return STATUS_SUCCESS;
102}
103
105NTAPI
107{
108 return STATUS_SUCCESS;
109}
110
112NTAPI
113KdSave(IN BOOLEAN SleepTransition)
114{
115 /* Nothing to do on COM ports */
116 return STATUS_SUCCESS;
117}
118
120NTAPI
121KdRestore(IN BOOLEAN SleepTransition)
122{
123 /* Nothing to do on COM ports */
124 return STATUS_SUCCESS;
125}
126
128NTAPI
130 IN ULONG ComPortBaudRate)
131{
133
134 KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
135
137 UlongToPtr(BaseArray[ComPortNumber]),
138 ComPortBaudRate);
139 if (!NT_SUCCESS(Status))
140 {
142 }
143 else
144 {
146 return STATUS_SUCCESS;
147 }
148}
149
150/******************************************************************************
151 * \name KdDebuggerInitialize0
152 * \brief Phase 0 initialization.
153 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
154 * \return Status
155 */
157NTAPI
159{
160 ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
161 ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
162
163 PCHAR CommandLine, PortString, BaudString, IrqString;
164 ULONG Value;
165
166 /* Check if we have a LoaderBlock */
167 if (LoaderBlock)
168 {
169 /* Get the Command Line */
170 CommandLine = LoaderBlock->LoadOptions;
171
172 /* Upcase it */
173 _strupr(CommandLine);
174
175 /* Get the port and baud rate */
176 PortString = strstr(CommandLine, "DEBUGPORT");
177 BaudString = strstr(CommandLine, "BAUDRATE");
178 IrqString = strstr(CommandLine, "IRQ");
179
180 /* Check if we got the /DEBUGPORT parameter */
181 if (PortString)
182 {
183 /* Move past the actual string, to reach the port*/
184 PortString += strlen("DEBUGPORT");
185
186 /* Now get past any spaces and skip the equal sign */
187 while (*PortString == ' ') PortString++;
188 PortString++;
189
190 /* Do we have a serial port? */
191 if (strncmp(PortString, "COM", 3) != 0)
192 {
194 }
195
196 /* Check for a valid Serial Port */
197 PortString += 3;
198 Value = atol(PortString);
199 if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
200 {
202 }
203
204 /* Set the port to use */
205 ComPortNumber = Value;
206 }
207
208 /* Check if we got a baud rate */
209 if (BaudString)
210 {
211 /* Move past the actual string, to reach the rate */
212 BaudString += strlen("BAUDRATE");
213
214 /* Now get past any spaces */
215 while (*BaudString == ' ') BaudString++;
216
217 /* And make sure we have a rate */
218 if (*BaudString)
219 {
220 /* Read and set it */
221 Value = atol(BaudString + 1);
222 if (Value) ComPortBaudRate = Value;
223 }
224 }
225
226 /* Check Serial Port Settings [IRQ] */
227 if (IrqString)
228 {
229 /* Move past the actual string, to reach the rate */
230 IrqString += strlen("IRQ");
231
232 /* Now get past any spaces */
233 while (*IrqString == ' ') IrqString++;
234
235 /* And make sure we have an IRQ */
236 if (*IrqString)
237 {
238 /* Read and set it */
239 Value = atol(IrqString + 1);
240 if (Value) KdComPortIrq = Value;
241 }
242 }
243 }
244
245#ifdef KDDEBUG
246 /*
247 * Try to find a free COM port and use it as the KD debugging port.
248 * NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
249 */
250 {
251 /*
252 * Start enumerating COM ports from the last one to the first one,
253 * and break when we find a valid port.
254 * If we reach the first element of the list, the invalid COM port,
255 * then it means that no valid port was found.
256 */
257 ULONG ComPort;
258 for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
259 {
260 /* Check if the port exist; skip the KD port */
261 if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
262 break;
263 }
264 if (ComPort != 0)
265 CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
266 }
267#endif
268
269 KDDBGPRINT("KdDebuggerInitialize0\n");
270
271 /* Initialize the port */
272 return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
273}
274
275/******************************************************************************
276 * \name KdDebuggerInitialize1
277 * \brief Phase 1 initialization.
278 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
279 * \return Status
280 */
282NTAPI
284{
285 return STATUS_SUCCESS;
286}
287
288
289VOID
290NTAPI
292{
293 /* Send the byte */
295}
296
298NTAPI
300{
302
303 /* Poll the byte */
304 Status = CpGetByte(&KdComPort, OutByte, FALSE, FALSE);
305 switch (Status)
306 {
307 case CP_GET_SUCCESS:
308 return KDP_PACKET_RECEIVED;
309
310 case CP_GET_NODATA:
311 return KDP_PACKET_TIMEOUT;
312
313 case CP_GET_ERROR:
314 default:
315 return KDP_PACKET_RESEND;
316 }
317}
318
320NTAPI
322{
324
325 /* Get the byte */
326 Status = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
327 switch (Status)
328 {
329 case CP_GET_SUCCESS:
330 return KDP_PACKET_RECEIVED;
331
332 case CP_GET_NODATA:
333 return KDP_PACKET_TIMEOUT;
334
335 case CP_GET_ERROR:
336 default:
337 return KDP_PACKET_RESEND;
338 }
339}
340
342NTAPI
344{
345 KDP_STATUS KdStatus;
346 UCHAR Byte;
347
348 KdStatus = KdpPollByte(&Byte);
349 if ((KdStatus == KDP_PACKET_RECEIVED) && (Byte == BREAKIN_PACKET_BYTE))
350 {
351 return KDP_PACKET_RECEIVED;
352 }
353 return KDP_PACKET_TIMEOUT;
354}
355
356/* EOF */
unsigned char BOOLEAN
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
VOID NTAPI CpPutByte(IN PCPPORT Port, IN UCHAR Byte)
Definition: cport.c:303
NTSTATUS NTAPI CpInitialize(IN PCPPORT Port, IN PUCHAR Address, IN ULONG BaudRate)
Definition: cport.c:85
#define CP_GET_SUCCESS
Definition: cportlib.h:18
USHORT NTAPI CpGetByte(IN PCPPORT Port, OUT PUCHAR Byte, IN BOOLEAN Wait, IN BOOLEAN Poll)
Definition: cport.c:253
#define CP_GET_NODATA
Definition: cportlib.h:19
#define CP_GET_ERROR
Definition: cportlib.h:20
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:224
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char Byte
Definition: zlib.h:37
#define KDDBGPRINT(...)
Definition: kddll.h:19
KDP_STATUS
Definition: kddll.h:26
@ KDP_PACKET_TIMEOUT
Definition: kddll.h:28
@ KDP_PACKET_RESEND
Definition: kddll.h:29
@ KDP_PACKET_RECEIVED
Definition: kddll.h:27
#define UlongToPtr(u)
Definition: config.h:106
Status
Definition: gdiplustypes.h:25
PUCHAR KdComPortInUse
Definition: usage.c:17
static const ULONG BaseArray[]
Definition: hwide.c:41
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
NTSTATUS NTAPI KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:283
#define DEFAULT_DEBUG_PORT
Definition: kdcom.c:25
NTSTATUS NTAPI KdD0Transition(VOID)
Definition: kdcom.c:99
NTSTATUS NTAPI KdRestore(IN BOOLEAN SleepTransition)
Definition: kdcom.c:121
#define DEFAULT_DEBUG_BAUD_RATE
Definition: kdcom.c:28
NTSTATUS NTAPI KdD3Transition(VOID)
Definition: kdcom.c:106
KDP_STATUS NTAPI KdpReceiveByte(OUT PUCHAR OutByte)
Definition: kdcom.c:321
KDP_STATUS NTAPI KdpPollByte(OUT PUCHAR OutByte)
Definition: kdcom.c:299
NTSTATUS NTAPI KdpPortInitialize(IN ULONG ComPortNumber, IN ULONG ComPortBaudRate)
Definition: kdcom.c:129
#define DEFAULT_BAUD_RATE
Definition: kdcom.c:29
VOID NTAPI KdpSendByte(IN UCHAR Byte)
Definition: kdcom.c:291
#define MAX_COM_PORTS
Definition: kdcom.c:48
ULONG KdComPortIrq
Definition: kdcom.c:53
KDP_STATUS NTAPI KdpPollBreakIn(VOID)
Definition: kdcom.c:343
CPPORT KdComPort
Definition: kdcom.c:52
NTSTATUS NTAPI KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:158
NTSTATUS NTAPI KdSave(IN BOOLEAN SleepTransition)
Definition: kdcom.c:113
PFNDBGPRNT KdpDbgPrint
Definition: kdvm.c:22
static PVOID ptr
Definition: dispmode.c:27
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PUCHAR Address
Definition: cportlib.h:29
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define BREAKIN_PACKET_BYTE
Definition: windbgkd.h:31
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define _vsnprintf
Definition: xmlstorage.h:202
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175