[KDGDB]
[reactos.git] / reactos / drivers / base / kdgdb / kdcom.c
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 /* GLOBALS ********************************************************************/
36
37 CPPORT KdDebugComPort;
38 ULONG KdDebugComPortIrq = 0; // Not used at the moment.
39
40
41 /* FUNCTIONS ******************************************************************/
42
43 NTSTATUS
44 NTAPI
45 KdD0Transition(VOID)
46 {
47 return STATUS_SUCCESS;
48 }
49
50 NTSTATUS
51 NTAPI
52 KdD3Transition(VOID)
53 {
54 return STATUS_SUCCESS;
55 }
56
57 NTSTATUS
58 NTAPI
59 KdSave(IN BOOLEAN SleepTransition)
60 {
61 /* Nothing to do on COM ports */
62 return STATUS_SUCCESS;
63 }
64
65 NTSTATUS
66 NTAPI
67 KdRestore(IN BOOLEAN SleepTransition)
68 {
69 /* Nothing to do on COM ports */
70 return STATUS_SUCCESS;
71 }
72
73 NTSTATUS
74 NTAPI
75 KdpPortInitialize(IN ULONG ComPortNumber,
76 IN ULONG ComPortBaudRate)
77 {
78 NTSTATUS Status;
79
80 Status = CpInitialize(&KdDebugComPort,
81 UlongToPtr(BaseArray[ComPortNumber]),
82 ComPortBaudRate);
83 if (!NT_SUCCESS(Status))
84 {
85 return STATUS_INVALID_PARAMETER;
86 }
87 else
88 {
89 KdComPortInUse = KdDebugComPort.Address;
90 return STATUS_SUCCESS;
91 }
92 }
93
94 /******************************************************************************
95 * \name KdDebuggerInitialize0
96 * \brief Phase 0 initialization.
97 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
98 * \return Status
99 */
100 NTSTATUS
101 NTAPI
102 KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
103 {
104 ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
105 ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
106
107 PCHAR CommandLine, PortString, BaudString, IrqString;
108 ULONG Value;
109
110 /* Check if e have a LoaderBlock */
111 if (LoaderBlock)
112 {
113
114 /* Get the Command Line */
115 CommandLine = LoaderBlock->LoadOptions;
116
117 /* Upcase it */
118 _strupr(CommandLine);
119
120 /* Get the port and baud rate */
121 PortString = strstr(CommandLine, "DEBUGPORT");
122 BaudString = strstr(CommandLine, "BAUDRATE");
123 IrqString = strstr(CommandLine, "IRQ");
124
125 /* Check if we got the /DEBUGPORT parameter */
126 if (PortString)
127 {
128 /* Move past the actual string, to reach the port*/
129 PortString += strlen("DEBUGPORT");
130
131 /* Now get past any spaces and skip the equal sign */
132 while (*PortString == ' ') PortString++;
133 PortString++;
134
135 /* Do we have a serial port? */
136 if (strncmp(PortString, "COM", 3) != 0)
137 {
138 return STATUS_INVALID_PARAMETER;
139 }
140
141 /* Check for a valid Serial Port */
142 PortString += 3;
143 Value = atol(PortString);
144 if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
145 {
146 return STATUS_INVALID_PARAMETER;
147 }
148
149 /* Set the port to use */
150 ComPortNumber = Value;
151 }
152
153 /* Check if we got a baud rate */
154 if (BaudString)
155 {
156 /* Move past the actual string, to reach the rate */
157 BaudString += strlen("BAUDRATE");
158
159 /* Now get past any spaces */
160 while (*BaudString == ' ') BaudString++;
161
162 /* And make sure we have a rate */
163 if (*BaudString)
164 {
165 /* Read and set it */
166 Value = atol(BaudString + 1);
167 if (Value) ComPortBaudRate = Value;
168 }
169 }
170
171 /* Check Serial Port Settings [IRQ] */
172 if (IrqString)
173 {
174 /* Move past the actual string, to reach the rate */
175 IrqString += strlen("IRQ");
176
177 /* Now get past any spaces */
178 while (*IrqString == ' ') IrqString++;
179
180 /* And make sure we have an IRQ */
181 if (*IrqString)
182 {
183 /* Read and set it */
184 Value = atol(IrqString + 1);
185 if (Value) KdDebugComPortIrq = Value;
186 }
187 }
188 }
189
190 /* Initialize the port */
191 return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
192 }
193
194 /******************************************************************************
195 * \name KdDebuggerInitialize1
196 * \brief Phase 1 initialization.
197 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
198 * \return Status
199 */
200 NTSTATUS
201 NTAPI
202 KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
203 {
204 return STATUS_SUCCESS;
205 }
206
207
208 VOID
209 NTAPI
210 KdpSendByte(_In_ UCHAR Byte)
211 {
212 /* Send the byte */
213 CpPutByte(&KdDebugComPort, Byte);
214 }
215
216 KDSTATUS
217 NTAPI
218 KdpPollByte(OUT PUCHAR OutByte)
219 {
220 /* Poll the byte */
221 if (CpGetByte(&KdDebugComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
222 {
223 return KdPacketReceived;
224 }
225 else
226 {
227 return KdPacketTimedOut;
228 }
229 }
230
231 KDSTATUS
232 NTAPI
233 KdpReceiveByte(_Out_ PUCHAR OutByte)
234 {
235 /* Get the byte */
236 if (CpGetByte(&KdDebugComPort, OutByte, TRUE, FALSE) == CP_GET_SUCCESS)
237 {
238 return KdPacketReceived;
239 }
240 else
241 {
242 return KdPacketTimedOut;
243 }
244 }
245
246 KDSTATUS
247 NTAPI
248 KdpPollBreakIn(VOID)
249 {
250 KDSTATUS KdStatus;
251 UCHAR Byte;
252
253 KdStatus = KdpPollByte(&Byte);
254 if (KdStatus == KdPacketReceived)
255 {
256 if (Byte == 0x03)
257 {
258 return KdPacketReceived;
259 }
260 else if (Byte == '$')
261 {
262 /* GDB tried to send a new packet. N-ack it. */
263 KdpSendByte('-');
264 }
265 }
266 return KdPacketTimedOut;
267 }
268
269 /* EOF */