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 BOOLEAN KdpEarlyBreak
= FALSE
;
30 LIST_ENTRY KdProviders
= {&KdProviders
, &KdProviders
};
31 KD_DISPATCH_TABLE DispatchTable
[KdMax
];
33 PKDP_INIT_ROUTINE InitRoutines
[KdMax
] = {KdpScreenInit
,
39 extern ANSI_STRING KdpLogFileName
;
41 /* PRIVATE FUNCTIONS *********************************************************/
46 KdpGetDebugMode(PCHAR Currentp2
)
48 PCHAR p1
, p2
= Currentp2
;
51 /* Check for Screen Debugging */
52 if (!_strnicmp(p2
, "SCREEN", 6))
56 KdpDebugMode
.Screen
= TRUE
;
58 /* Check for Serial Debugging */
59 else if (!_strnicmp(p2
, "COM", 3))
61 /* Gheck for a valid Serial Port */
65 Value
= (ULONG
)atol(p2
);
66 if (Value
> 0 && Value
< 5)
68 /* Valid port found, enable Serial Debugging */
69 KdpDebugMode
.Serial
= TRUE
;
71 /* Set the port to use */
72 SerialPortNumber
= Value
;
78 Value
= strtoul(p2
+ 1, NULL
, 0);
81 KdpDebugMode
.Serial
= TRUE
;
82 SerialPortInfo
.Address
= UlongToPtr(Value
);
89 /* Check for Debug Log Debugging */
90 else if (!_strnicmp(p2
, "FILE", 4))
94 KdpDebugMode
.File
= TRUE
;
99 while (*p2
!= '\0' && *p2
!= ' ') p2
++;
100 KdpLogFileName
.MaximumLength
= KdpLogFileName
.Length
= p2
- p1
;
101 KdpLogFileName
.Buffer
= p1
;
105 /* Check for BOCHS Debugging */
106 else if (!_strnicmp(p2
, "BOCHS", 5))
110 KdpDebugMode
.Bochs
= TRUE
;
113 /* Check for GDB Debugging */
114 else if (!_strnicmp(p2
, "GDB", 3))
118 KdpDebugMode
.Gdb
= TRUE
;
120 /* Enable Debugging */
121 KdDebuggerEnabled
= TRUE
;
122 KdDebuggerNotPresent
= FALSE
;
123 WrapperInitRoutine
= KdpGdbStubInit
;
126 /* Check for PICE Debugging */
127 else if (!_strnicmp(p2
, "PICE", 4))
131 KdpDebugMode
.Pice
= TRUE
;
133 /* Enable Debugging */
134 KdDebuggerEnabled
= TRUE
;
135 KdDebuggerNotPresent
= FALSE
;
144 KdpCallInitRoutine(ULONG BootPhase
)
146 PLIST_ENTRY CurrentEntry
;
147 PKD_DISPATCH_TABLE CurrentTable
;
149 /* Call the registered handlers */
150 CurrentEntry
= KdProviders
.Flink
;
151 while (CurrentEntry
!= &KdProviders
)
153 /* Get the current table */
154 CurrentTable
= CONTAINING_RECORD(CurrentEntry
,
159 CurrentTable
->KdpInitRoutine(CurrentTable
, BootPhase
);
162 CurrentEntry
= CurrentEntry
->Flink
;
165 /* Call the Wrapper Init Routine */
166 if (WrapperInitRoutine
)
167 WrapperTable
.KdpInitRoutine(&WrapperTable
, BootPhase
);
172 KdInitSystem(ULONG BootPhase
,
173 PLOADER_PARAMETER_BLOCK LoaderBlock
)
177 PCHAR CommandLine
, Port
, BaudRate
, Irq
;
179 /* Set Default Port Options */
182 /* Get the Command Line */
183 CommandLine
= LoaderBlock
->LoadOptions
;
186 _strupr(CommandLine
);
188 /* XXX Check for settings that we support */
189 if (strstr(CommandLine
, "BREAK")) KdpEarlyBreak
= TRUE
;
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 KdDebuggerEnabled
= TRUE
;
196 KdDebuggerNotPresent
= FALSE
;
198 /* Get the KDBG Settings */
199 KdbpGetCommandLineSettings(LoaderBlock
->LoadOptions
);
203 /* Get the port and baud rate */
204 Port
= strstr(CommandLine
, "DEBUGPORT");
205 BaudRate
= strstr(CommandLine
, "BAUDRATE");
206 Irq
= strstr(CommandLine
, "IRQ");
208 /* Check if we got the /DEBUGPORT parameter(s) */
211 /* Move past the actual string, to reach the port*/
212 Port
+= sizeof("DEBUGPORT") - 1;
214 /* Now get past any spaces and skip the equal sign */
215 while (*Port
== ' ') Port
++;
218 /* Get the debug mode and wrapper */
219 Port
= KdpGetDebugMode(Port
);
220 Port
= strstr(Port
, "DEBUGPORT");
223 /* Use serial port then */
224 if (KdDebuggerEnabled
&& KdpDebugMode
.Value
== 0)
225 KdpDebugMode
.Serial
= TRUE
;
227 /* Check if we got a baud rate */
230 /* Move past the actual string, to reach the rate */
231 BaudRate
+= sizeof("BAUDRATE") - 1;
233 /* Now get past any spaces */
234 while (*BaudRate
== ' ') BaudRate
++;
236 /* And make sure we have a rate */
239 /* Read and set it */
240 Value
= atol(BaudRate
+ 1);
241 if (Value
) PortInfo
.BaudRate
= SerialPortInfo
.BaudRate
= Value
;
245 /* Check Serial Port Settings [IRQ] */
248 /* Move past the actual string, to reach the rate */
249 Irq
+= sizeof("IRQ") - 1;
251 /* Now get past any spaces */
252 while (*Irq
== ' ') Irq
++;
254 /* And make sure we have an IRQ */
257 /* Read and set it */
258 Value
= atol(Irq
+ 1);
259 if (Value
) KdpPortIrq
= Value
;
263 /* Call Providers at Phase 0 */
264 for (i
= 0; i
< KdMax
; i
++)
266 InitRoutines
[i
](&DispatchTable
[i
], 0);
269 /* Call Wrapper at Phase 0 */
270 if (WrapperInitRoutine
) WrapperInitRoutine(&WrapperTable
, 0);
273 else /* BootPhase > 0 */
280 /* Call the Initialization Routines of the Registered Providers */
281 KdpCallInitRoutine(BootPhase
);