Sync to trunk revision 61757.
[reactos.git] / drivers / base / kdcom / kdcom.c
1 /*
2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/base/kddll/kdcom.c
5 * PURPOSE: COM port functions for the kernel debugger.
6 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org)
7 */
8
9 #include "kddll.h"
10 #include <cportlib/cportlib.h>
11 #include <stdlib.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* Serial debug connection */
17 #define DEFAULT_DEBUG_PORT 2 /* COM2 */
18 #define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
19 #define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
20 #define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
21
22 #define DEFAULT_BAUD_RATE 19200
23
24 #if defined(_M_IX86) || defined(_M_AMD64)
25 const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
26 #elif defined(_M_PPC)
27 const ULONG BaseArray[] = {0, 0x800003F8};
28 #elif defined(_M_MIPS)
29 const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
30 #elif defined(_M_ARM)
31 const ULONG BaseArray[] = {0, 0xF1012000};
32 #else
33 #error Unknown architecture
34 #endif
35
36 /* GLOBALS ********************************************************************/
37
38 CPPORT KdDebugComPort;
39 ULONG KdDebugComPortIrq = 0; // Not used at the moment.
40
41
42 /* FUNCTIONS ******************************************************************/
43
44 NTSTATUS
45 NTAPI
46 KdD0Transition(VOID)
47 {
48 return STATUS_SUCCESS;
49 }
50
51 NTSTATUS
52 NTAPI
53 KdD3Transition(VOID)
54 {
55 return STATUS_SUCCESS;
56 }
57
58 NTSTATUS
59 NTAPI
60 KdSave(IN BOOLEAN SleepTransition)
61 {
62 /* Nothing to do on COM ports */
63 return STATUS_SUCCESS;
64 }
65
66 NTSTATUS
67 NTAPI
68 KdRestore(IN BOOLEAN SleepTransition)
69 {
70 /* Nothing to do on COM ports */
71 return STATUS_SUCCESS;
72 }
73
74 NTSTATUS
75 NTAPI
76 KdpPortInitialize(IN ULONG ComPortNumber,
77 IN ULONG ComPortBaudRate)
78 {
79 NTSTATUS Status;
80
81 KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
82
83 Status = CpInitialize(&KdDebugComPort,
84 UlongToPtr(BaseArray[ComPortNumber]),
85 ComPortBaudRate);
86 if (!NT_SUCCESS(Status))
87 {
88 return STATUS_INVALID_PARAMETER;
89 }
90 else
91 {
92 KdComPortInUse = KdDebugComPort.Address;
93 return STATUS_SUCCESS;
94 }
95 }
96
97 /******************************************************************************
98 * \name KdDebuggerInitialize0
99 * \brief Phase 0 initialization.
100 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
101 * \return Status
102 */
103 NTSTATUS
104 NTAPI
105 KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
106 {
107 ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
108 ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
109
110 PCHAR CommandLine, PortString, BaudString, IrqString;
111 ULONG Value;
112
113 /* Check if e have a LoaderBlock */
114 if (LoaderBlock)
115 {
116 /* HACK */
117 KdpDbgPrint = LoaderBlock->u.I386.CommonDataArea;
118 KDDBGPRINT("KdDebuggerInitialize0\n");
119
120 /* Get the Command Line */
121 CommandLine = LoaderBlock->LoadOptions;
122
123 /* Upcase it */
124 _strupr(CommandLine);
125
126 /* Get the port and baud rate */
127 PortString = strstr(CommandLine, "DEBUGPORT");
128 BaudString = strstr(CommandLine, "BAUDRATE");
129 IrqString = strstr(CommandLine, "IRQ");
130
131 /* Check if we got the /DEBUGPORT parameter */
132 if (PortString)
133 {
134 /* Move past the actual string, to reach the port*/
135 PortString += strlen("DEBUGPORT");
136
137 /* Now get past any spaces and skip the equal sign */
138 while (*PortString == ' ') PortString++;
139 PortString++;
140
141 /* Do we have a serial port? */
142 if (strncmp(PortString, "COM", 3) != 0)
143 {
144 return STATUS_INVALID_PARAMETER;
145 }
146
147 /* Check for a valid Serial Port */
148 PortString += 3;
149 Value = atol(PortString);
150 if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
151 {
152 return STATUS_INVALID_PARAMETER;
153 }
154
155 /* Set the port to use */
156 ComPortNumber = Value;
157 }
158
159 /* Check if we got a baud rate */
160 if (BaudString)
161 {
162 /* Move past the actual string, to reach the rate */
163 BaudString += strlen("BAUDRATE");
164
165 /* Now get past any spaces */
166 while (*BaudString == ' ') BaudString++;
167
168 /* And make sure we have a rate */
169 if (*BaudString)
170 {
171 /* Read and set it */
172 Value = atol(BaudString + 1);
173 if (Value) ComPortBaudRate = Value;
174 }
175 }
176
177 /* Check Serial Port Settings [IRQ] */
178 if (IrqString)
179 {
180 /* Move past the actual string, to reach the rate */
181 IrqString += strlen("IRQ");
182
183 /* Now get past any spaces */
184 while (*IrqString == ' ') IrqString++;
185
186 /* And make sure we have an IRQ */
187 if (*IrqString)
188 {
189 /* Read and set it */
190 Value = atol(IrqString + 1);
191 if (Value) KdDebugComPortIrq = Value;
192 }
193 }
194 }
195
196 /* Initialize the port */
197 return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
198 }
199
200 /******************************************************************************
201 * \name KdDebuggerInitialize1
202 * \brief Phase 1 initialization.
203 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
204 * \return Status
205 */
206 NTSTATUS
207 NTAPI
208 KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
209 {
210 return STATUS_SUCCESS;
211 }
212
213
214 VOID
215 NTAPI
216 KdpSendByte(IN UCHAR Byte)
217 {
218 /* Send the byte */
219 CpPutByte(&KdDebugComPort, Byte);
220 }
221
222 KDP_STATUS
223 NTAPI
224 KdpPollByte(OUT PUCHAR OutByte)
225 {
226 /* Poll the byte */
227 if (CpGetByte(&KdDebugComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
228 {
229 return KDP_PACKET_RECEIVED;
230 }
231 else
232 {
233 return KDP_PACKET_TIMEOUT;
234 }
235 }
236
237 KDP_STATUS
238 NTAPI
239 KdpReceiveByte(OUT PUCHAR OutByte)
240 {
241 /* Get the byte */
242 if (CpGetByte(&KdDebugComPort, OutByte, TRUE, FALSE) == CP_GET_SUCCESS)
243 {
244 return KDP_PACKET_RECEIVED;
245 }
246 else
247 {
248 return KDP_PACKET_TIMEOUT;
249 }
250 }
251
252 KDP_STATUS
253 NTAPI
254 KdpPollBreakIn(VOID)
255 {
256 KDP_STATUS KdStatus;
257 UCHAR Byte;
258
259 KdStatus = KdpPollByte(&Byte);
260 if ((KdStatus == KDP_PACKET_RECEIVED) && (Byte == BREAKIN_PACKET_BYTE))
261 {
262 return KDP_PACKET_RECEIVED;
263 }
264 return KDP_PACKET_TIMEOUT;
265 }
266
267 /* EOF */