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