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