ReactOS  0.4.15-dev-1367-g07cc0b5
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)
32 const ULONG BaseArray[] = {0, 0x30, 0x238};
33 #else
34 const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
35 #endif
36 #elif defined(_M_PPC)
37 const ULONG BaseArray[] = {0, 0x800003F8};
38 #elif defined(_M_MIPS)
39 const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
40 #elif defined(_M_ARM)
41 const 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 
51 ULONG KdComPortIrq = 0; // Not used at the moment.
52 #ifdef KDDEBUG
53 CPPORT KdDebugComPort;
54 #endif
55 
56 /* DEBUGGING ******************************************************************/
57 
58 #ifdef KDDEBUG
59 ULONG KdpDbgPrint(const char *Format, ...)
60 {
61  va_list ap;
62  int Length;
63  char* ptr;
64  CHAR Buffer[512];
65 
66  va_start(ap, Format);
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 
96 NTAPI
98 {
99  return STATUS_SUCCESS;
100 }
101 
102 NTSTATUS
103 NTAPI
105 {
106  return STATUS_SUCCESS;
107 }
108 
109 NTSTATUS
110 NTAPI
111 KdSave(IN BOOLEAN SleepTransition)
112 {
113  /* Nothing to do on COM ports */
114  return STATUS_SUCCESS;
115 }
116 
117 NTSTATUS
118 NTAPI
119 KdRestore(IN BOOLEAN SleepTransition)
120 {
121  /* Nothing to do on COM ports */
122  return STATUS_SUCCESS;
123 }
124 
125 NTSTATUS
126 NTAPI
127 KdpPortInitialize(IN ULONG ComPortNumber,
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  */
150 NTSTATUS
151 NTAPI
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  */
273 NTSTATUS
274 NTAPI
276 {
277  return STATUS_SUCCESS;
278 }
279 
280 
281 VOID
282 NTAPI
284 {
285  /* Send the byte */
287 }
288 
289 KDSTATUS
290 NTAPI
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 
304 KDSTATUS
305 NTAPI
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 
324 KDSTATUS
325 NTAPI
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 */
signed char * PCHAR
Definition: retypes.h:7
NTSTATUS NTAPI KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:158
#define KdPacketReceived
Definition: kddll.h:5
#define IN
Definition: typedefs.h:39
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define DEFAULT_DEBUG_BAUD_RATE
Definition: kdcom.c:26
#define KDDBGPRINT(...)
Definition: kddll.h:19
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
#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:321
NTSTATUS NTAPI KdRestore(IN BOOLEAN SleepTransition)
Definition: kdcom.c:121
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:46
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
#define FALSE
Definition: types.h:117
KDP_STATUS NTAPI KdpPollBreakIn(VOID)
Definition: kdcom.c:343
NTSTATUS NTAPI KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
Definition: kdcom.c:283
static PVOID ptr
Definition: dispmode.c:27
CPPORT KdComPort
Definition: kdcom.c:52
unsigned char BOOLEAN
#define DEFAULT_BAUD_RATE
Definition: kdcom.c:27
#define _Out_
Definition: no_sal2.h:160
char * va_list
Definition: acmsvcex.h:78
Definition: bufpool.h:45
#define UlongToPtr(u)
Definition: config.h:106
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI KdD0Transition(VOID)
Definition: kdcom.c:99
KDP_STATUS NTAPI KdpPollByte(OUT PUCHAR OutByte)
Definition: kdcom.c:299
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:53
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
va_start(ap, x)
VOID NTAPI KdpSendByte(IN UCHAR Byte)
Definition: kdcom.c:291
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
#define _In_
Definition: no_sal2.h:158
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
NTSTATUS NTAPI KdD3Transition(VOID)
Definition: kdcom.c:106
unsigned short USHORT
Definition: pedump.c:61
ULONG KDSTATUS
Definition: kddll.h:4
static const ULONG BaseArray[]
Definition: hwide.c:41
#define CP_GET_SUCCESS
Definition: cportlib.h:18
#define _vsnprintf
Definition: xmlstorage.h:202
unsigned char Byte
Definition: zlib.h:37
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define DEFAULT_DEBUG_PORT
Definition: kdcom.c:23
NTSTATUS NTAPI KdSave(IN BOOLEAN SleepTransition)
Definition: kdcom.c:113
#define STATUS_SUCCESS
Definition: shellext.h:65
#define CP_GET_NODATA
Definition: cportlib.h:19
NTSTATUS NTAPI KdpPortInitialize(IN ULONG ComPortNumber, IN ULONG ComPortBaudRate)
Definition: kdcom.c:129
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68