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