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