ReactOS 0.4.15-dev-7842-g558ab78
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 <cportlib/cportlib.h>
11#include <arc/arc.h>
12#include <stdlib.h>
13#include <ndk/halfuncs.h>
14
15/* Serial debug connection */
16#if defined(SARCH_PC98)
17#define DEFAULT_DEBUG_PORT 2 /* COM2 */
18#define DEFAULT_DEBUG_COM1_IRQ 4
19#define DEFAULT_DEBUG_COM2_IRQ 5
20#define DEFAULT_DEBUG_BAUD_RATE 9600
21#define DEFAULT_BAUD_RATE 9600
22#else
23#define DEFAULT_DEBUG_PORT 2 /* COM2 */
24#define DEFAULT_DEBUG_COM1_IRQ 4
25#define DEFAULT_DEBUG_COM2_IRQ 3
26#define DEFAULT_DEBUG_BAUD_RATE 115200
27#define DEFAULT_BAUD_RATE 19200
28#endif
29
30#if defined(_M_IX86) || defined(_M_AMD64)
31#if defined(SARCH_PC98)
32const ULONG BaseArray[] = {0, 0x30, 0x238};
33#else
34const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
35#endif
36#elif defined(_M_PPC)
37const ULONG BaseArray[] = {0, 0x800003F8};
38#elif defined(_M_MIPS)
39const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
40#elif defined(_M_ARM)
41const ULONG BaseArray[] = {0, 0xF1012000};
42#else
43#error Unknown architecture
44#endif
45
46#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
47
48/* GLOBALS ********************************************************************/
49
51ULONG KdComPortIrq = 0; // Not used at the moment.
52#ifdef KDDEBUG
53CPPORT KdDebugComPort;
54#endif
55
56/* DEBUGGING ******************************************************************/
57
58#ifdef KDDEBUG
59ULONG KdpDbgPrint(const char *Format, ...)
60{
61 va_list ap;
62 int Length;
63 char* ptr;
64 CHAR Buffer[512];
65
67 Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
68 va_end(ap);
69
70 /* Check if we went past the buffer */
71 if (Length == -1)
72 {
73 /* Terminate it if we went over-board */
74 Buffer[sizeof(Buffer) - 1] = '\n';
75
76 /* Put maximum */
77 Length = sizeof(Buffer);
78 }
79
80 ptr = Buffer;
81 while (Length--)
82 {
83 if (*ptr == '\n')
84 CpPutByte(&KdDebugComPort, '\r');
85
86 CpPutByte(&KdDebugComPort, *ptr++);
87 }
88
89 return 0;
90}
91#endif
92
93/* FUNCTIONS ******************************************************************/
94
98{
99 return STATUS_SUCCESS;
100}
101
103NTAPI
105{
106 return STATUS_SUCCESS;
107}
108
110NTAPI
111KdSave(IN BOOLEAN SleepTransition)
112{
113 /* Nothing to do on COM ports */
114 return STATUS_SUCCESS;
115}
116
118NTAPI
119KdRestore(IN BOOLEAN SleepTransition)
120{
121 /* Nothing to do on COM ports */
122 return STATUS_SUCCESS;
123}
124
126NTAPI
128 IN ULONG ComPortBaudRate)
129{
131
133 UlongToPtr(BaseArray[ComPortNumber]),
134 ComPortBaudRate);
135 if (!NT_SUCCESS(Status))
136 {
138 }
139
141 return STATUS_SUCCESS;
142}
143
144/******************************************************************************
145 * \name KdDebuggerInitialize0
146 * \brief Phase 0 initialization.
147 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
148 * \return Status
149 */
151NTAPI
153{
154 ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
155 ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
156
157 PCHAR CommandLine, PortString, BaudString, IrqString;
158 ULONG Value;
159
160 /* Check if we have a LoaderBlock */
161 if (LoaderBlock)
162 {
163 /* Get the Command Line */
164 CommandLine = LoaderBlock->LoadOptions;
165
166 /* Upcase it */
167 _strupr(CommandLine);
168
169 /* Get the port and baud rate */
170 PortString = strstr(CommandLine, "DEBUGPORT");
171 BaudString = strstr(CommandLine, "BAUDRATE");
172 IrqString = strstr(CommandLine, "IRQ");
173
174 /* Check if we got the /DEBUGPORT parameter */
175 if (PortString)
176 {
177 /* Move past the actual string, to reach the port*/
178 PortString += strlen("DEBUGPORT");
179
180 /* Now get past any spaces and skip the equal sign */
181 while (*PortString == ' ') PortString++;
182 PortString++;
183
184 /* Do we have a serial port? */
185 if (strncmp(PortString, "COM", 3) != 0)
186 {
188 }
189
190 /* Check for a valid Serial Port */
191 PortString += 3;
192 Value = atol(PortString);
193 if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
194 {
196 }
197
198 /* Set the port to use */
199 ComPortNumber = Value;
200 }
201
202 /* Check if we got a baud rate */
203 if (BaudString)
204 {
205 /* Move past the actual string, to reach the rate */
206 BaudString += strlen("BAUDRATE");
207
208 /* Now get past any spaces */
209 while (*BaudString == ' ') BaudString++;
210
211 /* And make sure we have a rate */
212 if (*BaudString)
213 {
214 /* Read and set it */
215 Value = atol(BaudString + 1);
216 if (Value) ComPortBaudRate = Value;
217 }
218 }
219
220 /* Check Serial Port Settings [IRQ] */
221 if (IrqString)
222 {
223 /* Move past the actual string, to reach the rate */
224 IrqString += strlen("IRQ");
225
226 /* Now get past any spaces */
227 while (*IrqString == ' ') IrqString++;
228
229 /* And make sure we have an IRQ */
230 if (*IrqString)
231 {
232 /* Read and set it */
233 Value = atol(IrqString + 1);
234 if (Value) KdComPortIrq = Value;
235 }
236 }
237 }
238
239#ifdef KDDEBUG
240 /*
241 * Try to find a free COM port and use it as the KD debugging port.
242 * NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
243 */
244 {
245 /*
246 * Start enumerating COM ports from the last one to the first one,
247 * and break when we find a valid port.
248 * If we reach the first element of the list, the invalid COM port,
249 * then it means that no valid port was found.
250 */
251 ULONG ComPort;
252 for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
253 {
254 /* Check if the port exist; skip the KD port */
255 if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
256 break;
257 }
258 if (ComPort != 0)
259 CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
260 }
261#endif
262
263 /* Initialize the port */
264 return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
265}
266
267/******************************************************************************
268 * \name KdDebuggerInitialize1
269 * \brief Phase 1 initialization.
270 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
271 * \return Status
272 */
274NTAPI
276{
277 return STATUS_SUCCESS;
278}
279
280
281VOID
282NTAPI
284{
285 /* Send the byte */
287}
288
290NTAPI
292{
293 /* Poll the byte */
294 if (CpGetByte(&KdComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
295 {
296 return KdPacketReceived;
297 }
298 else
299 {
300 return KdPacketTimedOut;
301 }
302}
303
305NTAPI
307{
308 USHORT CpStatus;
309
310 do
311 {
312 CpStatus = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
313 } while (CpStatus == CP_GET_NODATA);
314
315 /* Get the byte */
316 if (CpStatus == CP_GET_SUCCESS)
317 {
318 return KdPacketReceived;
319 }
320
321 return KdPacketTimedOut;
322}
323
325NTAPI
327{
328 KDSTATUS KdStatus;
329 UCHAR Byte;
330
331 KdStatus = KdpPollByte(&Byte);
332 if (KdStatus == KdPacketReceived)
333 {
334 if (Byte == 0x03)
335 {
336 KDDBGPRINT("BreakIn Polled.\n");
337 return KdPacketReceived;
338 }
339 else if (Byte == '$')
340 {
341 /* GDB tried to send a new packet. N-ack it. */
342 KdpSendByte('-');
343 }
344 }
345 return KdPacketTimedOut;
346}
347
348/* 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
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
#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
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
_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 KdPacketReceived
Definition: kddll.h:5
ULONG KDSTATUS
Definition: kddll.h:4
#define KdPacketTimedOut
Definition: kddll.h:6
#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
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