ReactOS 0.4.16-dev-2528-g7139e57
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/kdgdb/kdcom.c
5 * PURPOSE: COM port functions for the kernel debugger.
6 */
7
8#include "kdgdb.h"
9
10#include <arc/arc.h>
11#include <stdlib.h>
12#include <ndk/halfuncs.h>
13
14#include <cportlib/cportlib.h>
15#include <cportlib/uartinfo.h>
16
17/* GLOBALS ********************************************************************/
18
20#ifdef KDDEBUG
21CPPORT KdDebugComPort;
22#endif
23
24/* DEBUGGING ******************************************************************/
25
26#ifdef KDDEBUG
27ULONG KdpDbgPrint(const char *Format, ...)
28{
29 va_list ap;
30 int Length;
31 char* ptr;
32 CHAR Buffer[512];
33
35 Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
36 va_end(ap);
37
38 /* Check if we went past the buffer */
39 if (Length == -1)
40 {
41 /* Terminate it if we went over-board */
42 Buffer[sizeof(Buffer) - 1] = '\n';
43
44 /* Put maximum */
45 Length = sizeof(Buffer);
46 }
47
48 ptr = Buffer;
49 while (Length--)
50 {
51 if (*ptr == '\n')
52 CpPutByte(&KdDebugComPort, '\r');
53
54 CpPutByte(&KdDebugComPort, *ptr++);
55 }
56
57 return 0;
58}
59#endif
60
61/* FUNCTIONS ******************************************************************/
62
66{
67 return STATUS_SUCCESS;
68}
69
73{
74 return STATUS_SUCCESS;
75}
76
79KdSave(IN BOOLEAN SleepTransition)
80{
81 /* Nothing to do on COM ports */
82 return STATUS_SUCCESS;
83}
84
87KdRestore(IN BOOLEAN SleepTransition)
88{
89 /* Nothing to do on COM ports */
90 return STATUS_SUCCESS;
91}
92
96 _In_ PUCHAR PortAddress,
97 _In_ ULONG BaudRate)
98{
100
101 Status = CpInitialize(&KdComPort, PortAddress, BaudRate);
102 if (!NT_SUCCESS(Status))
104
106 return STATUS_SUCCESS;
107}
108
109/******************************************************************************
110 * \name KdDebuggerInitialize0
111 * \brief Phase 0 initialization.
112 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
113 * \return Status
114 */
116NTAPI
118{
119#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
120
121 ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
122 ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
123 PUCHAR ComPortAddress = NULL;
124
125 PSTR CommandLine, PortString, BaudString;
126 ULONG Value;
127
128 /* Check if we have a LoaderBlock */
129 if (LoaderBlock)
130 {
131 /* Get the Command Line */
132 CommandLine = LoaderBlock->LoadOptions;
133
134 /* Upcase it */
135 _strupr(CommandLine);
136
137 /* Get the port and baud rate */
138 PortString = strstr(CommandLine, "DEBUGPORT");
139 BaudString = strstr(CommandLine, "BAUDRATE");
140
141 /* Check if we got the DEBUGPORT parameter */
142 if (PortString)
143 {
144 /* Move past the actual string and any spaces */
145 PortString += CONST_STR_LEN("DEBUGPORT");
146 while (*PortString == ' ') ++PortString;
147 /* Skip the equals sign */
148 if (*PortString) ++PortString;
149
150 /* Do we have a serial port? Recognize both
151 * 'DEBUGPORT=GDB' and 'DEBUGPORT=COM' syntaxes. */
152 if (_strnicmp(PortString, "GDB", CONST_STR_LEN("GDB")) != 0 &&
153 _strnicmp(PortString, "COM", CONST_STR_LEN("COM")) != 0)
154 {
156 }
157
158 /* Check for a valid serial port */
159 PortString += CONST_STR_LEN("COM"); // Same as len("GDB")
160 if (*PortString != ':')
161 {
162 Value = (ULONG)atol(PortString);
163 if (Value > MAX_COM_PORTS)
165 // if (Value > 0 && Value <= MAX_COM_PORTS)
166 /* Set the port to use */
167 ComPortNumber = Value;
168 }
169 else
170 {
171 /* Retrieve and set its address */
172 Value = strtoul(PortString + 1, NULL, 0);
173 if (Value)
174 {
175 ComPortNumber = 0;
176 ComPortAddress = UlongToPtr(Value);
177 }
178 }
179 }
180
181 /* Check if we got a baud rate */
182 if (BaudString)
183 {
184 /* Move past the actual string and any spaces */
185 BaudString += CONST_STR_LEN("BAUDRATE");
186 while (*BaudString == ' ') ++BaudString;
187
188 /* Make sure we have a rate */
189 if (*BaudString)
190 {
191 /* Read and set it */
192 Value = (ULONG)atol(BaudString + 1);
193 if (Value) ComPortBaudRate = Value;
194 }
195 }
196 }
197
198 if (!ComPortAddress)
199 ComPortAddress = UlongToPtr(BaseArray[ComPortNumber]);
200
201#ifdef KDDEBUG
202 /*
203 * Try to find a free COM port and use it as the KD debugging port.
204 * NOTE: Inspired by freeldr/comm/rs232.c, Rs232PortInitialize(...)
205 */
206 {
207 /*
208 * Enumerate COM ports from the last to the first one, and stop
209 * when we find a valid port. If we reach the first list element
210 * (the undefined COM port), no valid port was found.
211 */
213 ULONG ComPort;
214 for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
215 {
216 /* Check if the port exist; skip the KD port */
217 Address = UlongToPtr(BaseArray[ComPort]);
218 if ((Address != ComPortAddress) && CpDoesPortExist(Address))
219 break;
220 }
221 if (ComPort != 0 && Address != NULL)
222 CpInitialize(&KdDebugComPort, Address, DEFAULT_BAUD_RATE);
223 }
224#endif
225
226 /* Initialize the port */
227 return KdpPortInitialize(ComPortAddress, ComPortBaudRate);
228}
229
230/******************************************************************************
231 * \name KdDebuggerInitialize1
232 * \brief Phase 1 initialization.
233 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
234 * \return Status
235 */
237NTAPI
239{
240 return STATUS_SUCCESS;
241}
242
243
244VOID
245NTAPI
247{
248 /* Send the byte */
250}
251
253NTAPI
255{
256 /* Poll the byte */
257 if (CpGetByte(&KdComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
258 {
259 return KdPacketReceived;
260 }
261 else
262 {
263 return KdPacketTimedOut;
264 }
265}
266
268NTAPI
270{
271 USHORT CpStatus;
272
273 do
274 {
275 CpStatus = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
276 } while (CpStatus == CP_GET_NODATA);
277
278 /* Get the byte */
279 if (CpStatus == CP_GET_SUCCESS)
280 {
281 return KdPacketReceived;
282 }
283
284 return KdPacketTimedOut;
285}
286
288NTAPI
290{
291 KDSTATUS KdStatus;
292 UCHAR Byte;
293
294 KdStatus = KdpPollByte(&Byte);
295 if (KdStatus == KdPacketReceived)
296 {
297 if (Byte == 0x03)
298 {
299 KDDBGPRINT("BreakIn Polled.\n");
300 return KdPacketReceived;
301 }
302 else if (Byte == '$')
303 {
304 /* GDB tried to send a new packet. N-ack it. */
305 KdpSendByte('-');
306 }
307 }
308 return KdPacketTimedOut;
309}
310
311/* 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 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
#define KDDBGPRINT(...)
Definition: kddll.h:19
#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
#define KdPacketReceived
Definition: kddll.h:5
ULONG KDSTATUS
Definition: kddll.h:4
#define KdPacketTimedOut
Definition: kddll.h:6
_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
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