[MSI]
[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 <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 KdpKdbgInit};
42
43 /* PRIVATE FUNCTIONS *********************************************************/
44
45 PCHAR
46 NTAPI
47 INIT_FUNCTION
48 KdpGetDebugMode(PCHAR Currentp2)
49 {
50 PCHAR p2 = Currentp2;
51 ULONG Value;
52
53 /* Check for Screen Debugging */
54 if (!_strnicmp(p2, "SCREEN", 6))
55 {
56 /* Enable It */
57 p2 += 6;
58 KdpDebugMode.Screen = TRUE;
59 }
60 /* Check for Serial Debugging */
61 else if (!_strnicmp(p2, "COM", 3))
62 {
63 /* Gheck for a valid Serial Port */
64 p2 += 3;
65 Value = (ULONG)atol(p2);
66 if (Value > 0 && Value < 5)
67 {
68 /* Valid port found, enable Serial Debugging */
69 KdpDebugMode.Serial = TRUE;
70
71 /* Set the port to use */
72 SerialPortInfo.ComPort = Value;
73 KdpPort = Value;
74 }
75 }
76 /* Check for Debug Log Debugging */
77 else if (!_strnicmp(p2, "FILE", 4))
78 {
79 /* Enable It */
80 p2 += 4;
81 KdpDebugMode.File = TRUE;
82 }
83
84 /* Check for BOCHS Debugging */
85 else if (!_strnicmp(p2, "BOCHS", 5))
86 {
87 /* Enable It */
88 p2 += 5;
89 KdpDebugMode.Bochs = TRUE;
90 }
91
92 /* Check for GDB Debugging */
93 else if (!_strnicmp(p2, "GDB", 3))
94 {
95 /* Enable it */
96 p2 += 3;
97 KdpDebugMode.Gdb = TRUE;
98
99 /* Enable Debugging */
100 KdDebuggerEnabled = TRUE;
101 KdDebuggerNotPresent = FALSE;
102 WrapperInitRoutine = KdpGdbStubInit;
103 }
104
105 /* Check for PICE Debugging */
106 else if (!_strnicmp(p2, "PICE", 4))
107 {
108 /* Enable it */
109 p2 += 4;
110 KdpDebugMode.Pice = TRUE;
111
112 /* Enable Debugging */
113 KdDebuggerEnabled = TRUE;
114 KdDebuggerNotPresent = FALSE;
115 }
116
117 return p2;
118 }
119
120 VOID
121 NTAPI
122 INIT_FUNCTION
123 KdpCallInitRoutine(ULONG BootPhase)
124 {
125 PLIST_ENTRY CurrentEntry;
126 PKD_DISPATCH_TABLE CurrentTable;
127
128 /* Call the registered handlers */
129 CurrentEntry = KdProviders.Flink;
130 while (CurrentEntry != &KdProviders)
131 {
132 /* Get the current table */
133 CurrentTable = CONTAINING_RECORD(CurrentEntry,
134 KD_DISPATCH_TABLE,
135 KdProvidersList);
136
137 /* Call it */
138 CurrentTable->KdpInitRoutine(CurrentTable, BootPhase);
139
140 /* Next Table */
141 CurrentEntry = CurrentEntry->Flink;
142 }
143
144 /* Call the Wrapper Init Routine */
145 if (WrapperInitRoutine)
146 WrapperTable.KdpInitRoutine(&WrapperTable, BootPhase);
147 }
148
149 BOOLEAN
150 INIT_FUNCTION
151 NTAPI
152 KdInitSystem(ULONG BootPhase,
153 PLOADER_PARAMETER_BLOCK LoaderBlock)
154 {
155 ULONG Value;
156 ULONG i;
157 PCHAR CommandLine, Port, BaudRate, Irq;
158
159 /* Set Default Port Options */
160 if (BootPhase == 0)
161 {
162 /* Get the Command Line */
163 CommandLine = LoaderBlock->LoadOptions;
164
165 /* Upcase it */
166 _strupr(CommandLine);
167
168 /* XXX Check for settings that we support */
169 if (strstr(CommandLine, "BREAK")) KdpEarlyBreak = TRUE;
170 if (strstr(CommandLine, "NODEBUG")) KdDebuggerEnabled = FALSE;
171 else if (strstr(CommandLine, "CRASHDEBUG")) KdDebuggerEnabled = FALSE;
172 else if (strstr(CommandLine, "DEBUG"))
173 {
174 /* Enable on the serial port */
175 KdDebuggerEnabled = TRUE;
176 KdDebuggerNotPresent = FALSE;
177 KdpDebugMode.Serial = TRUE;
178
179 #ifdef KDBG
180 /* Get the KDBG Settings */
181 KdbpGetCommandLineSettings(LoaderBlock->LoadOptions);
182 #endif
183 }
184
185 /* Get the port and baud rate */
186 Port = strstr(CommandLine, "DEBUGPORT");
187 BaudRate = strstr(CommandLine, "BAUDRATE");
188 Irq = strstr(CommandLine, "IRQ");
189
190 /* Check if we got the /DEBUGPORT parameter(s) */
191 while (Port)
192 {
193 /* Move past the actual string, to reach the port*/
194 Port += sizeof("DEBUGPORT") - 1;
195
196 /* Now get past any spaces and skip the equal sign */
197 while (*Port == ' ') Port++;
198 Port++;
199
200 /* Get the debug mode and wrapper */
201 Port = KdpGetDebugMode(Port);
202 Port = strstr(Port, "DEBUGPORT");
203 }
204
205 /* Check if we got a baud rate */
206 if (BaudRate)
207 {
208 /* Move past the actual string, to reach the rate */
209 BaudRate += sizeof("BAUDRATE") - 1;
210
211 /* Now get past any spaces */
212 while (*BaudRate == ' ') BaudRate++;
213
214 /* And make sure we have a rate */
215 if (*BaudRate)
216 {
217 /* Read and set it */
218 Value = atol(BaudRate + 1);
219 if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
220 }
221 }
222
223 /* Check Serial Port Settings [IRQ] */
224 if (Irq)
225 {
226 /* Move past the actual string, to reach the rate */
227 Irq += sizeof("IRQ") - 1;
228
229 /* Now get past any spaces */
230 while (*Irq == ' ') Irq++;
231
232 /* And make sure we have an IRQ */
233 if (*Irq)
234 {
235 /* Read and set it */
236 Value = atol(Irq + 1);
237 if (Value) KdpPortIrq = Value;
238 }
239 }
240
241 /* Call Providers at Phase 0 */
242 for (i = 0; i < KdMax; i++)
243 {
244 InitRoutines[i](&DispatchTable[i], 0);
245 }
246
247 /* Call Wrapper at Phase 0 */
248 if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
249 return TRUE;
250 }
251 else /* BootPhase > 0 */
252 {
253 #ifdef _M_IX86
254 KdpEnableSafeMem();
255 #endif
256 }
257
258 /* Call the Initialization Routines of the Registered Providers */
259 KdpCallInitRoutine(BootPhase);
260
261 /* Return success */
262 return TRUE;
263 }
264
265 /* EOF */