ReactOS 0.4.16-dev-2491-g3dc6630
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/kdcom/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 <arc/arc.h>
12#include <stdlib.h>
13#include <ndk/halfuncs.h>
14
15#include <cportlib/cportlib.h>
16#include <cportlib/uartinfo.h>
17
18/* GLOBALS ********************************************************************/
19
21#ifdef KDDEBUG
22CPPORT KdDebugComPort;
23#endif
24
25/* DEBUGGING ******************************************************************/
26
27#ifdef KDDEBUG
28#include <stdio.h>
29ULONG KdpDbgPrint(const char *Format, ...)
30{
31 va_list ap;
32 int Length;
33 char* ptr;
34 CHAR Buffer[512];
35
37 Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
38 va_end(ap);
39
40 /* Check if we went past the buffer */
41 if (Length == -1)
42 {
43 /* Terminate it if we went over-board */
44 Buffer[sizeof(Buffer) - 1] = '\n';
45
46 /* Put maximum */
47 Length = sizeof(Buffer);
48 }
49
50 ptr = Buffer;
51 while (Length--)
52 {
53 if (*ptr == '\n')
54 CpPutByte(&KdDebugComPort, '\r');
55
56 CpPutByte(&KdDebugComPort, *ptr++);
57 }
58
59 return 0;
60}
61#endif
62
63/* FUNCTIONS ******************************************************************/
64
68{
69 return STATUS_SUCCESS;
70}
71
75{
76 return STATUS_SUCCESS;
77}
78
81KdSave(IN BOOLEAN SleepTransition)
82{
83 /* Nothing to do on COM ports */
84 return STATUS_SUCCESS;
85}
86
89KdRestore(IN BOOLEAN SleepTransition)
90{
91 /* Nothing to do on COM ports */
92 return STATUS_SUCCESS;
93}
94
98 _In_ PUCHAR PortAddress,
99 _In_ ULONG BaudRate)
100{
102
103 Status = CpInitialize(&KdComPort, PortAddress, BaudRate);
104 if (!NT_SUCCESS(Status))
106
108 return STATUS_SUCCESS;
109}
110
111/******************************************************************************
112 * \name KdDebuggerInitialize0
113 * \brief Phase 0 initialization.
114 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
115 * \return Status
116 */
118NTAPI
120{
121#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
122
123 ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
124 ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
125 PUCHAR ComPortAddress = NULL;
126
127 PSTR CommandLine, PortString, BaudString;
128 ULONG Value;
129
130 /* Check if we have a LoaderBlock */
131 if (LoaderBlock)
132 {
133 /* Get the Command Line */
134 CommandLine = LoaderBlock->LoadOptions;
135
136 /* Upcase it */
137 _strupr(CommandLine);
138
139 /* Get the port and baud rate */
140 PortString = strstr(CommandLine, "DEBUGPORT");
141 BaudString = strstr(CommandLine, "BAUDRATE");
142
143 /* Check if we got the DEBUGPORT parameter */
144 if (PortString)
145 {
146 /* Move past the actual string and any spaces */
147 PortString += CONST_STR_LEN("DEBUGPORT");
148 while (*PortString == ' ') ++PortString;
149 /* Skip the equals sign */
150 if (*PortString) ++PortString;
151
152 /* Do we have a serial port? */
153 if (_strnicmp(PortString, "COM", CONST_STR_LEN("COM")) != 0)
155
156 /* Check for a valid serial port */
157 PortString += CONST_STR_LEN("COM");
158 if (*PortString != ':')
159 {
160 Value = (ULONG)atol(PortString);
161 if (Value > MAX_COM_PORTS)
163 // if (Value > 0 && Value <= MAX_COM_PORTS)
164 /* Set the port to use */
165 ComPortNumber = Value;
166 }
167 else
168 {
169 /* Retrieve and set its address */
170 Value = strtoul(PortString + 1, NULL, 0);
171 if (Value)
172 {
173 ComPortNumber = 0;
174 ComPortAddress = UlongToPtr(Value);
175 }
176 }
177 }
178
179 /* Check if we got a baud rate */
180 if (BaudString)
181 {
182 /* Move past the actual string and any spaces */
183 BaudString += CONST_STR_LEN("BAUDRATE");
184 while (*BaudString == ' ') ++BaudString;
185
186 /* Make sure we have a rate */
187 if (*BaudString)
188 {
189 /* Read and set it */
190 Value = (ULONG)atol(BaudString + 1);
191 if (Value) ComPortBaudRate = Value;
192 }
193 }
194 }
195
196 if (!ComPortAddress)
197 ComPortAddress = UlongToPtr(BaseArray[ComPortNumber]);
198
199#ifdef KDDEBUG
200 /*
201 * Try to find a free COM port and use it as the KD debugging port.
202 * NOTE: Inspired by freeldr/comm/rs232.c, Rs232PortInitialize(...)
203 */
204 {
205 /*
206 * Enumerate COM ports from the last to the first one, and stop
207 * when we find a valid port. If we reach the first list element
208 * (the undefined COM port), no valid port was found.
209 */
211 ULONG ComPort;
212 for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
213 {
214 /* Check if the port exist; skip the KD port */
215 Address = UlongToPtr(BaseArray[ComPort]);
216 if ((Address != ComPortAddress) && CpDoesPortExist(Address))
217 break;
218 }
219 if (ComPort != 0 && Address != NULL)
220 CpInitialize(&KdDebugComPort, Address, DEFAULT_BAUD_RATE);
221 }
222#endif
223
224 /* Initialize the port */
225 return KdpPortInitialize(ComPortAddress, ComPortBaudRate);
226}
227
228/******************************************************************************
229 * \name KdDebuggerInitialize1
230 * \brief Phase 1 initialization.
231 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
232 * \return Status
233 */
235NTAPI
237{
238 return STATUS_SUCCESS;
239}
240
241
242VOID
243NTAPI
245{
246 /* Send the byte */
248}
249
251NTAPI
253{
255
256 /* Poll the byte */
257 Status = CpGetByte(&KdComPort, OutByte, FALSE, FALSE);
258 switch (Status)
259 {
260 case CP_GET_SUCCESS:
261 return KDP_PACKET_RECEIVED;
262
263 case CP_GET_NODATA:
264 return KDP_PACKET_TIMEOUT;
265
266 case CP_GET_ERROR:
267 default:
268 return KDP_PACKET_RESEND;
269 }
270}
271
273NTAPI
275{
277
278 /* Get the byte */
279 Status = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
280 switch (Status)
281 {
282 case CP_GET_SUCCESS:
283 return KDP_PACKET_RECEIVED;
284
285 case CP_GET_NODATA:
286 return KDP_PACKET_TIMEOUT;
287
288 case CP_GET_ERROR:
289 default:
290 return KDP_PACKET_RESEND;
291 }
292}
293
295NTAPI
297{
298 KDP_STATUS KdStatus;
299 UCHAR Byte;
300
301 KdStatus = KdpPollByte(&Byte);
302 if ((KdStatus == KDP_PACKET_RECEIVED) && (Byte == BREAKIN_PACKET_BYTE))
303 {
304 return KDP_PACKET_RECEIVED;
305 }
306 return KDP_PACKET_TIMEOUT;
307}
308
309/* EOF */
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
USHORT NTAPI CpGetByte(_Inout_ PCPPORT Port, _Out_ PUCHAR Byte, _In_ BOOLEAN Wait, _In_ BOOLEAN Poll)
Definition: cport.c:82
#define CP_GET_SUCCESS
Definition: cportlib.h:17
VOID NTAPI CpPutByte(_Inout_ PCPPORT Port, _In_ UCHAR Byte)
Definition: cport.c:93
#define CP_GET_NODATA
Definition: cportlib.h:18
NTSTATUS NTAPI CpInitialize(_Inout_ PCPPORT Port, _In_ PUCHAR Address, _In_ ULONG BaudRate)
Definition: cport.c:59
BOOLEAN NTAPI CpDoesPortExist(_In_ PUCHAR Address)
Definition: cport.c:33
#define CP_GET_ERROR
Definition: cportlib.h:19
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
unsigned char Byte
Definition: zlib.h:37
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
_ACRTIMP __msvcrt_long __cdecl atol(const char *)
Definition: string.c:1782
_ACRTIMP __msvcrt_ulong __cdecl strtoul(const char *, char **, int)
Definition: string.c:1859
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3415
char * va_list
Definition: vadefs.h:50
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
NTSTATUS NTAPI KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:236
NTSTATUS NTAPI KdD0Transition(VOID)
Definition: kdcom.c:67
NTSTATUS NTAPI KdRestore(IN BOOLEAN SleepTransition)
Definition: kdcom.c:89
NTSTATUS NTAPI KdD3Transition(VOID)
Definition: kdcom.c:74
KDP_STATUS NTAPI KdpReceiveByte(OUT PUCHAR OutByte)
Definition: kdcom.c:274
KDP_STATUS NTAPI KdpPollByte(OUT PUCHAR OutByte)
Definition: kdcom.c:252
#define CONST_STR_LEN(x)
VOID NTAPI KdpSendByte(IN UCHAR Byte)
Definition: kdcom.c:244
KDP_STATUS NTAPI KdpPollBreakIn(VOID)
Definition: kdcom.c:296
CPPORT KdComPort
Definition: kdcom.c:20
NTSTATUS NTAPI KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:119
NTSTATUS NTAPI KdpPortInitialize(_In_ PUCHAR PortAddress, _In_ ULONG BaudRate)
Definition: kdcom.c:97
NTSTATUS NTAPI KdSave(IN BOOLEAN SleepTransition)
Definition: kdcom.c:81
PFNDBGPRNT KdpDbgPrint
Definition: kdvm.c:22
#define MAX_COM_PORTS
Definition: machpc.c:29
static PVOID ptr
Definition: dispmode.c:27
#define _In_
Definition: no_sal2.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
_strupr
Definition: string.h:453
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PUCHAR Address
Definition: cportlib.h:28
char * PSTR
Definition: typedefs.h:51
#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
#define DEFAULT_DEBUG_PORT
Definition: uartinfo.h:16
#define DEFAULT_DEBUG_BAUD_RATE
Definition: uartinfo.h:17
#define DEFAULT_BAUD_RATE
Definition: uartinfo.h:24
#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