- Implemented InterlockedBitTestAndReset, InterlockedBitTestAndSet, InterlockedExchan...
[reactos.git] / reactos / ntoskrnl / kd / kdinit.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/kd/kdinit.c
5 * PURPOSE: Kernel Debugger Initializtion
6 *
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 */
9
10 #include <ntoskrnl.h>
11 #define NDEBUG
12 #include <internal/debug.h>
13
14 #if defined (ALLOC_PRAGMA)
15 #pragma alloc_text(INIT, KdInitSystem)
16 #endif
17
18
19 /* Make bochs debug output in the very early boot phase available */
20 //#define AUTO_ENABLE_BOCHS
21
22 /* VARIABLES ***************************************************************/
23
24 KD_PORT_INFORMATION PortInfo = {DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_BAUD_RATE, 0};
25 ULONG KdpPortIrq;
26 #ifdef AUTO_ENABLE_BOCHS
27 KDP_DEBUG_MODE KdpDebugMode = {{{.Bochs=TRUE}}};;
28 PKDP_INIT_ROUTINE WrapperInitRoutine = KdpBochsInit;
29 KD_DISPATCH_TABLE WrapperTable = {.KdpInitRoutine = KdpBochsInit, .KdpPrintRoutine = KdpBochsDebugPrint};
30 #else
31 KDP_DEBUG_MODE KdpDebugMode;
32 PKDP_INIT_ROUTINE WrapperInitRoutine;
33 KD_DISPATCH_TABLE WrapperTable;
34 #endif
35 BOOLEAN KdpEarlyBreak = FALSE;
36 LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
37 KD_DISPATCH_TABLE DispatchTable[KdMax];
38
39 PKDP_INIT_ROUTINE InitRoutines[KdMax] = {KdpScreenInit,
40 KdpSerialInit,
41 KdpInitDebugLog};
42
43 /* PRIVATE FUNCTIONS *********************************************************/
44
45 PCHAR
46 STDCALL
47 KdpGetWrapperDebugMode(PCHAR Currentp2,
48 PLOADER_PARAMETER_BLOCK LoaderBlock)
49 {
50 PCHAR p2 = Currentp2;
51
52 /* Check for BOCHS Debugging */
53 if (!_strnicmp(p2, "BOCHS", 5))
54 {
55 /* Enable It */
56 p2 += 5;
57 KdpDebugMode.Bochs = TRUE;
58 WrapperInitRoutine = KdpBochsInit;
59 }
60
61 /* Check for GDB Debugging */
62 if (!_strnicmp(p2, "GDB", 3))
63 {
64 /* Enable it */
65 p2 += 3;
66 KdpDebugMode.Gdb = TRUE;
67
68 /* Enable Debugging */
69 KdDebuggerEnabled = TRUE;
70 WrapperInitRoutine = KdpGdbStubInit;
71 }
72
73 /* Check for PICE Debugging */
74 else if (!_strnicmp(p2, "PICE", 4))
75 {
76 /* Enable it */
77 p2 += 4;
78 KdpDebugMode.Pice = TRUE;
79
80 /* Enable Debugging */
81 KdDebuggerEnabled = TRUE;
82 }
83
84 #ifdef KDBG
85 /* Get the KDBG Settings and enable it */
86 KdDebuggerEnabled = TRUE;
87 KdpDebugMode.Gdb = TRUE;
88 KdbpGetCommandLineSettings((PCHAR)LoaderBlock->CommandLine);
89 #endif
90 return p2;
91 }
92
93 PCHAR
94 STDCALL
95 KdpGetDebugMode(PCHAR Currentp2)
96 {
97 PCHAR p2 = Currentp2;
98 ULONG Value;
99
100 /* Check for Screen Debugging */
101 if (!_strnicmp(p2, "SCREEN", 6))
102 {
103 /* Enable It */
104 p2 += 6;
105 KdpDebugMode.Screen = TRUE;
106 }
107 /* Check for Serial Debugging */
108 else if (!_strnicmp(p2, "COM", 3))
109 {
110 /* Gheck for a valid Serial Port */
111 p2 += 3;
112 Value = (ULONG)atol(p2);
113 if (Value > 0 && Value < 5)
114 {
115 /* Valid port found, enable Serial Debugging */
116 KdpDebugMode.Serial = TRUE;
117
118 /* Set the port to use */
119 SerialPortInfo.ComPort = Value;
120 KdpPort = Value;
121 }
122 }
123 /* Check for Debug Log Debugging */
124 else if (!_strnicmp(p2, "FILE", 4))
125 {
126 /* Enable It */
127 p2 += 4;
128 KdpDebugMode.File = TRUE;
129 }
130
131 return p2;
132 }
133
134 VOID
135 STDCALL
136 KdpCallInitRoutine(ULONG BootPhase)
137 {
138 PLIST_ENTRY CurrentEntry;
139 PKD_DISPATCH_TABLE CurrentTable;
140
141 /* Call the registered handlers */
142 CurrentEntry = KdProviders.Flink;
143 while (CurrentEntry != &KdProviders)
144 {
145 /* Get the current table */
146 CurrentTable = CONTAINING_RECORD(CurrentEntry,
147 KD_DISPATCH_TABLE,
148 KdProvidersList);
149
150 /* Call it */
151 CurrentTable->KdpInitRoutine(CurrentTable, BootPhase);
152
153 /* Next Table */
154 CurrentEntry = CurrentEntry->Flink;
155 }
156
157 /* Call the Wrapper Init Routine */
158 if (WrapperInitRoutine)
159 WrapperTable.KdpInitRoutine(&WrapperTable, BootPhase);
160 }
161
162 VOID
163 INIT_FUNCTION
164 KdInitSystem(ULONG BootPhase,
165 PLOADER_PARAMETER_BLOCK LoaderBlock)
166 {
167 ULONG Value;
168 ULONG i;
169 PCHAR p1, p2;
170
171 /* Set Default Port Options */
172 if (BootPhase == 0)
173 {
174
175 /* Parse the Command Line */
176 p1 = (PCHAR)LoaderBlock->CommandLine;
177 while (p1 && (p2 = strchr(p1, '/')))
178 {
179 /* Move past the slash */
180 p2++;
181
182 /* Identify the Debug Type being Used */
183 if (!_strnicmp(p2, "DEBUGPORT=", 10))
184 {
185 p2 += 10;
186 p2 = KdpGetDebugMode(p2);
187 p2 = KdpGetWrapperDebugMode(p2, LoaderBlock);
188 }
189 /* Check for early breakpoint */
190 else if (!_strnicmp(p2, "BREAK", 5))
191 {
192 p2 += 5;
193 KdpEarlyBreak = TRUE;
194 }
195 /* Check for Kernel Debugging Enable */
196 else if (!_strnicmp(p2, "DEBUG", 5))
197 {
198 /* Enable it on the Serial Port */
199 p2 += 5;
200 KdDebuggerEnabled = TRUE;
201 KdpDebugMode.Serial = TRUE;
202 }
203 /* Check for Kernel Debugging Bypass */
204 else if (!_strnicmp(p2, "NODEBUG", 7))
205 {
206 /* Disable Debugging */
207 p2 += 7;
208 KdDebuggerEnabled = FALSE;
209 }
210 /* Check for Kernel Debugging Bypass unless STOP Error */
211 else if (!_strnicmp(p2, "CRASHDEBUG", 10))
212 {
213 /* Disable Debugging */
214 p2 += 10;
215 KdDebuggerEnabled = FALSE;
216 }
217 /* Check Serial Port Settings [Baud Rate] */
218 else if (!_strnicmp(p2, "BAUDRATE=", 9))
219 {
220 /* Get the Baud Rate */
221 p2 += 9;
222 Value = (ULONG)atol(p2);
223
224 /* Check if it's valid and Set it */
225 if (0 < Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
226 }
227 /* Check Serial Port Settings [IRQ] */
228 else if (!_strnicmp(p2, "IRQ=", 4))
229 {
230 /* Get the IRQ */
231 p2 += 3;
232 Value = (ULONG)atol(p2);
233
234 /* Check if it's valid and set it */
235 if (0 < Value) KdpPortIrq = Value;
236 }
237
238 /* Move to next */
239 p1 = p2;
240 }
241
242 /* Call Providers at Phase 0 */
243 for (i = 0; i < KdMax; i++)
244 {
245 InitRoutines[i](&DispatchTable[i], 0);
246 }
247
248 /* Call Wrapper at Phase 0 */
249 if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
250
251 return;
252 }
253
254 /* Call the Initialization Routines of the Registered Providers */
255 KdpCallInitRoutine(BootPhase);
256 }
257
258 /* EOF */