ReactOS  0.4.14-dev-342-gdc047f9
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 #define DEFAULT_DEBUG_PORT 2 /* COM2 */
17 #define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
18 #define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
19 #define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
20 
21 #define DEFAULT_BAUD_RATE 19200
22 
23 #if defined(_M_IX86) || defined(_M_AMD64)
24 const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
25 #elif defined(_M_PPC)
26 const ULONG BaseArray[] = {0, 0x800003F8};
27 #elif defined(_M_MIPS)
28 const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
29 #elif defined(_M_ARM)
30 const ULONG BaseArray[] = {0, 0xF1012000};
31 #else
32 #error Unknown architecture
33 #endif
34 
35 #define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
36 
37 /* GLOBALS ********************************************************************/
38 
40 ULONG KdComPortIrq = 0; // Not used at the moment.
41 #ifdef KDDEBUG
42 CPPORT KdDebugComPort;
43 #endif
44 
45 /* DEBUGGING ******************************************************************/
46 
47 #ifdef KDDEBUG
48 ULONG KdpDbgPrint(const char *Format, ...)
49 {
50  va_list ap;
51  int Length;
52  char* ptr;
53  CHAR Buffer[512];
54 
55  va_start(ap, Format);
56  Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
57  va_end(ap);
58 
59  /* Check if we went past the buffer */
60  if (Length == -1)
61  {
62  /* Terminate it if we went over-board */
63  Buffer[sizeof(Buffer) - 1] = '\n';
64 
65  /* Put maximum */
66  Length = sizeof(Buffer);
67  }
68 
69  ptr = Buffer;
70  while (Length--)
71  {
72  if (*ptr == '\n')
73  CpPutByte(&KdDebugComPort, '\r');
74 
75  CpPutByte(&KdDebugComPort, *ptr++);
76  }
77 
78  return 0;
79 }
80 #endif
81 
82 /* FUNCTIONS ******************************************************************/
83 
85 NTAPI
87 {
88  return STATUS_SUCCESS;
89 }
90 
92 NTAPI
94 {
95  return STATUS_SUCCESS;
96 }
97 
99 NTAPI
100 KdSave(IN BOOLEAN SleepTransition)
101 {
102  /* Nothing to do on COM ports */
103  return STATUS_SUCCESS;
104 }
105 
106 NTSTATUS
107 NTAPI
108 KdRestore(IN BOOLEAN SleepTransition)
109 {
110  /* Nothing to do on COM ports */
111  return STATUS_SUCCESS;
112 }
113 
114 NTSTATUS
115 NTAPI
116 KdpPortInitialize(IN ULONG ComPortNumber,
117  IN ULONG ComPortBaudRate)
118 {
120 
122  UlongToPtr(BaseArray[ComPortNumber]),
123  ComPortBaudRate);
124  if (!NT_SUCCESS(Status))
125  {
127  }
128  else
129  {
131  return STATUS_SUCCESS;
132  }
133 }
134 
135 /******************************************************************************
136  * \name KdDebuggerInitialize0
137  * \brief Phase 0 initialization.
138  * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
139  * \return Status
140  */
141 NTSTATUS
142 NTAPI
144 {
145  ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
146  ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
147 
148  PCHAR CommandLine, PortString, BaudString, IrqString;
149  ULONG Value;
150 
151  /* Check if we have a LoaderBlock */
152  if (LoaderBlock)
153  {
154  /* Get the Command Line */
155  CommandLine = LoaderBlock->LoadOptions;
156 
157  /* Upcase it */
158  _strupr(CommandLine);
159 
160  /* Get the port and baud rate */
161  PortString = strstr(CommandLine, "DEBUGPORT");
162  BaudString = strstr(CommandLine, "BAUDRATE");
163  IrqString = strstr(CommandLine, "IRQ");
164 
165  /* Check if we got the /DEBUGPORT parameter */
166  if (PortString)
167  {
168  /* Move past the actual string, to reach the port*/
169  PortString += strlen("DEBUGPORT");
170 
171  /* Now get past any spaces and skip the equal sign */
172  while (*PortString == ' ') PortString++;
173  PortString++;
174 
175  /* Do we have a serial port? */
176  if (strncmp(PortString, "COM", 3) != 0)
177  {
179  }
180 
181  /* Check for a valid Serial Port */
182  PortString += 3;
183  Value = atol(PortString);
184  if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
185  {
187  }
188 
189  /* Set the port to use */
190  ComPortNumber = Value;
191  }
192 
193  /* Check if we got a baud rate */
194  if (BaudString)
195  {
196  /* Move past the actual string, to reach the rate */
197  BaudString += strlen("BAUDRATE");
198 
199  /* Now get past any spaces */
200  while (*BaudString == ' ') BaudString++;
201 
202  /* And make sure we have a rate */
203  if (*BaudString)
204  {
205  /* Read and set it */
206  Value = atol(BaudString + 1);
207  if (Value) ComPortBaudRate = Value;
208  }
209  }
210 
211  /* Check Serial Port Settings [IRQ] */
212  if (IrqString)
213  {
214  /* Move past the actual string, to reach the rate */
215  IrqString += strlen("IRQ");
216 
217  /* Now get past any spaces */
218  while (*IrqString == ' ') IrqString++;
219 
220  /* And make sure we have an IRQ */
221  if (*IrqString)
222  {
223  /* Read and set it */
224  Value = atol(IrqString + 1);
225  if (Value) KdComPortIrq = Value;
226  }
227  }
228  }
229 
230 #ifdef KDDEBUG
231  /*
232  * Try to find a free COM port and use it as the KD debugging port.
233  * NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
234  */
235  {
236  /*
237  * Start enumerating COM ports from the last one to the first one,
238  * and break when we find a valid port.
239  * If we reach the first element of the list, the invalid COM port,
240  * then it means that no valid port was found.
241  */
242  ULONG ComPort;
243  for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
244  {
245  /* Check if the port exist; skip the KD port */
246  if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
247  break;
248  }
249  if (ComPort != 0)
250  CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
251  }
252 #endif
253 
254  /* Initialize the port */
255  return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
256 }
257 
258 /******************************************************************************
259  * \name KdDebuggerInitialize1
260  * \brief Phase 1 initialization.
261  * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
262  * \return Status
263  */
264 NTSTATUS
265 NTAPI
267 {
268  return STATUS_SUCCESS;
269 }
270 
271 
272 VOID
273 NTAPI
275 {
276  /* Send the byte */
278 }
279 
280 KDSTATUS
281 NTAPI
283 {
284  /* Poll the byte */
285  if (CpGetByte(&KdComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
286  {
287  return KdPacketReceived;
288  }
289  else
290  {
291  return KdPacketTimedOut;
292  }
293 }
294 
295 KDSTATUS
296 NTAPI
298 {
299  USHORT CpStatus = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
300  /* Get the byte */
301  if (CpStatus == CP_GET_SUCCESS)
302  {
303  return KdPacketReceived;
304  }
305 
306  return KdPacketTimedOut;
307 }
308 
309 KDSTATUS
310 NTAPI
312 {
313  KDSTATUS KdStatus;
314  UCHAR Byte;
315 
316  KdStatus = KdpPollByte(&Byte);
317  if (KdStatus == KdPacketReceived)
318  {
319  if (Byte == 0x03)
320  {
321  KDDBGPRINT("BreakIn Polled.\n");
322  return KdPacketReceived;
323  }
324  else if (Byte == '$')
325  {
326  /* GDB tried to send a new packet. N-ack it. */
327  KdpSendByte('-');
328  }
329  }
330  return KdPacketTimedOut;
331 }
332 
333 /* EOF */
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
signed char * PCHAR
Definition: retypes.h:7
NTSTATUS NTAPI KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:147
#define KdPacketReceived
Definition: kddll.h:5
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define DEFAULT_DEBUG_BAUD_RATE
Definition: kdcom.c:19
#define KDDBGPRINT(...)
Definition: kddll.h:19
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
unsigned char Byte
Definition: zconf.h:391
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
KDP_STATUS NTAPI KdpReceiveByte(OUT PUCHAR OutByte)
Definition: kdcom.c:310
NTSTATUS NTAPI KdRestore(IN BOOLEAN SleepTransition)
Definition: kdcom.c:110
USHORT NTAPI CpGetByte(IN PCPPORT Port, OUT PUCHAR Byte, IN BOOLEAN Wait, IN BOOLEAN Poll)
Definition: cport.c:256
PFNDBGPRNT KdpDbgPrint
Definition: kdvm.c:22
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:227
#define MAX_COM_PORTS
Definition: kdcom.c:35
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define va_end(ap)
Definition: acmsvcex.h:90
KDP_STATUS NTAPI KdpPollBreakIn(VOID)
Definition: kdcom.c:332
NTSTATUS NTAPI KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:272
static PVOID ptr
Definition: dispmode.c:27
CPPORT KdComPort
Definition: kdcom.c:41
unsigned char BOOLEAN
#define DEFAULT_BAUD_RATE
Definition: kdcom.c:21
#define _Out_
Definition: no_sal2.h:323
char * va_list
Definition: acmsvcex.h:78
Definition: bufpool.h:45
#define UlongToPtr(u)
Definition: config.h:106
NTSTATUS NTAPI KdD0Transition(VOID)
Definition: kdcom.c:88
KDP_STATUS NTAPI KdpPollByte(OUT PUCHAR OutByte)
Definition: kdcom.c:288
PUCHAR KdComPortInUse
Definition: usage.c:17
#define KdPacketTimedOut
Definition: kddll.h:6
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG KdComPortIrq
Definition: kdcom.c:42
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID NTAPI KdpSendByte(IN UCHAR Byte)
Definition: kdcom.c:280
VOID NTAPI CpPutByte(IN PCPPORT Port, IN UCHAR Byte)
Definition: cport.c:306
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI CpInitialize(IN PCPPORT Port, IN PUCHAR Address, IN ULONG BaudRate)
Definition: cport.c:88
PUCHAR Address
Definition: cportlib.h:29
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
NTSTATUS NTAPI KdD3Transition(VOID)
Definition: kdcom.c:95
unsigned short USHORT
Definition: pedump.c:61
ULONG KDSTATUS
Definition: kddll.h:4
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define CP_GET_SUCCESS
Definition: cportlib.h:18
#define _vsnprintf
Definition: xmlstorage.h:202
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define DEFAULT_DEBUG_PORT
Definition: kdcom.c:16
NTSTATUS NTAPI KdSave(IN BOOLEAN SleepTransition)
Definition: kdcom.c:102
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSTATUS NTAPI KdpPortInitialize(IN ULONG ComPortNumber, IN ULONG ComPortBaudRate)
Definition: kdcom.c:118
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68