2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/kd/kdinit.c
5 * PURPOSE: Kernel Debugger Initializtion
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
14 /* Make bochs debug output in the very early boot phase available */
15 //#define AUTO_ENABLE_BOCHS
17 /* VARIABLES ***************************************************************/
19 ULONG PortNumber
= DEFAULT_DEBUG_PORT
;
20 CPPORT PortInfo
= {0, DEFAULT_DEBUG_BAUD_RATE
, 0};
22 #ifdef AUTO_ENABLE_BOCHS
23 KDP_DEBUG_MODE KdpDebugMode
= {{{.Bochs
=TRUE
}}};
25 KDP_DEBUG_MODE KdpDebugMode
;
27 PKDP_INIT_ROUTINE WrapperInitRoutine
;
28 KD_DISPATCH_TABLE WrapperTable
;
29 LIST_ENTRY KdProviders
= {&KdProviders
, &KdProviders
};
30 KD_DISPATCH_TABLE DispatchTable
[KdMax
];
32 PKDP_INIT_ROUTINE InitRoutines
[KdMax
] = {KdpScreenInit
,
38 extern ANSI_STRING KdpLogFileName
;
40 /* PRIVATE FUNCTIONS *********************************************************/
45 KdpGetDebugMode(PCHAR Currentp2
)
47 PCHAR p1
, p2
= Currentp2
;
50 /* Check for Screen Debugging */
51 if (!_strnicmp(p2
, "SCREEN", 6))
55 KdpDebugMode
.Screen
= TRUE
;
57 /* Check for Serial Debugging */
58 else if (!_strnicmp(p2
, "COM", 3))
60 /* Gheck for a valid Serial Port */
64 Value
= (ULONG
)atol(p2
);
65 if (Value
> 0 && Value
< 5)
67 /* Valid port found, enable Serial Debugging */
68 KdpDebugMode
.Serial
= TRUE
;
70 /* Set the port to use */
71 SerialPortNumber
= Value
;
77 Value
= strtoul(p2
+ 1, NULL
, 0);
80 KdpDebugMode
.Serial
= TRUE
;
81 SerialPortInfo
.Address
= UlongToPtr(Value
);
88 /* Check for Debug Log Debugging */
89 else if (!_strnicmp(p2
, "FILE", 4))
93 KdpDebugMode
.File
= TRUE
;
98 while (*p2
!= '\0' && *p2
!= ' ') p2
++;
99 KdpLogFileName
.MaximumLength
= KdpLogFileName
.Length
= p2
- p1
;
100 KdpLogFileName
.Buffer
= p1
;
104 /* Check for BOCHS Debugging */
105 else if (!_strnicmp(p2
, "BOCHS", 5))
109 KdpDebugMode
.Bochs
= TRUE
;
112 /* Check for GDB Debugging */
113 else if (!_strnicmp(p2
, "GDB", 3))
117 KdpDebugMode
.Gdb
= TRUE
;
119 /* Enable Debugging */
120 KdDebuggerNotPresent
= FALSE
;
121 KdDebuggerEnabled
= TRUE
;
122 SharedUserData
->KdDebuggerEnabled
= TRUE
;
123 WrapperInitRoutine
= KdpGdbStubInit
;
126 /* Check for PICE Debugging */
127 else if (!_strnicmp(p2
, "PICE", 4))
131 KdpDebugMode
.Pice
= TRUE
;
133 /* Enable Debugging */
134 KdDebuggerNotPresent
= FALSE
;
135 KdDebuggerEnabled
= TRUE
;
136 SharedUserData
->KdDebuggerEnabled
= TRUE
;
145 KdpCallInitRoutine(ULONG BootPhase
)
147 PLIST_ENTRY CurrentEntry
;
148 PKD_DISPATCH_TABLE CurrentTable
;
150 /* Call the registered handlers */
151 CurrentEntry
= KdProviders
.Flink
;
152 while (CurrentEntry
!= &KdProviders
)
154 /* Get the current table */
155 CurrentTable
= CONTAINING_RECORD(CurrentEntry
,
160 CurrentTable
->KdpInitRoutine(CurrentTable
, BootPhase
);
163 CurrentEntry
= CurrentEntry
->Flink
;
166 /* Call the Wrapper Init Routine */
167 if (WrapperInitRoutine
)
168 WrapperTable
.KdpInitRoutine(&WrapperTable
, BootPhase
);
173 KdInitSystem(ULONG BootPhase
,
174 PLOADER_PARAMETER_BLOCK LoaderBlock
)
178 PCHAR CommandLine
, Port
, BaudRate
, Irq
;
180 /* Set Default Port Options */
183 /* Get the Command Line */
184 CommandLine
= LoaderBlock
->LoadOptions
;
187 _strupr(CommandLine
);
189 /* XXX Check for settings that we support */
190 if (strstr(CommandLine
, "NODEBUG")) KdDebuggerEnabled
= FALSE
;
191 else if (strstr(CommandLine
, "CRASHDEBUG")) KdDebuggerEnabled
= FALSE
;
192 else if (strstr(CommandLine
, "DEBUG"))
194 /* Enable the kernel debugger */
195 KdDebuggerNotPresent
= FALSE
;
196 KdDebuggerEnabled
= TRUE
;
198 /* Get the KDBG Settings */
199 KdbpGetCommandLineSettings(LoaderBlock
->LoadOptions
);
203 /* Let user-mode know our state */
204 SharedUserData
->KdDebuggerEnabled
= KdDebuggerEnabled
;
206 /* Get the port and baud rate */
207 Port
= strstr(CommandLine
, "DEBUGPORT");
208 BaudRate
= strstr(CommandLine
, "BAUDRATE");
209 Irq
= strstr(CommandLine
, "IRQ");
211 /* Check if we got the /DEBUGPORT parameter(s) */
214 /* Move past the actual string, to reach the port*/
215 Port
+= sizeof("DEBUGPORT") - 1;
217 /* Now get past any spaces and skip the equal sign */
218 while (*Port
== ' ') Port
++;
221 /* Get the debug mode and wrapper */
222 Port
= KdpGetDebugMode(Port
);
223 Port
= strstr(Port
, "DEBUGPORT");
226 /* Use serial port then */
227 if (KdDebuggerEnabled
&& KdpDebugMode
.Value
== 0)
228 KdpDebugMode
.Serial
= TRUE
;
230 /* Check if we got a baud rate */
233 /* Move past the actual string, to reach the rate */
234 BaudRate
+= sizeof("BAUDRATE") - 1;
236 /* Now get past any spaces */
237 while (*BaudRate
== ' ') BaudRate
++;
239 /* And make sure we have a rate */
242 /* Read and set it */
243 Value
= atol(BaudRate
+ 1);
244 if (Value
) PortInfo
.BaudRate
= SerialPortInfo
.BaudRate
= Value
;
248 /* Check Serial Port Settings [IRQ] */
251 /* Move past the actual string, to reach the rate */
252 Irq
+= sizeof("IRQ") - 1;
254 /* Now get past any spaces */
255 while (*Irq
== ' ') Irq
++;
257 /* And make sure we have an IRQ */
260 /* Read and set it */
261 Value
= atol(Irq
+ 1);
262 if (Value
) KdpPortIrq
= Value
;
266 /* Call Providers at Phase 0 */
267 for (i
= 0; i
< KdMax
; i
++)
269 InitRoutines
[i
](&DispatchTable
[i
], 0);
272 /* Call Wrapper at Phase 0 */
273 if (WrapperInitRoutine
) WrapperInitRoutine(&WrapperTable
, 0);
276 else /* BootPhase > 0 */
283 /* Call the Initialization Routines of the Registered Providers */
284 KdpCallInitRoutine(BootPhase
);