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 KdDebuggerNotPresent
= FALSE
;
122 KdDebuggerEnabled
= TRUE
;
123 SharedUserData
->KdDebuggerEnabled
= TRUE
;
124 WrapperInitRoutine
= KdpGdbStubInit
;
127 /* Check for PICE Debugging */
128 else if (!_strnicmp(p2
, "PICE", 4))
132 KdpDebugMode
.Pice
= TRUE
;
134 /* Enable Debugging */
135 KdDebuggerNotPresent
= FALSE
;
136 KdDebuggerEnabled
= TRUE
;
137 SharedUserData
->KdDebuggerEnabled
= TRUE
;
146 KdpCallInitRoutine(ULONG BootPhase
)
148 PLIST_ENTRY CurrentEntry
;
149 PKD_DISPATCH_TABLE CurrentTable
;
151 /* Call the registered handlers */
152 CurrentEntry
= KdProviders
.Flink
;
153 while (CurrentEntry
!= &KdProviders
)
155 /* Get the current table */
156 CurrentTable
= CONTAINING_RECORD(CurrentEntry
,
161 CurrentTable
->KdpInitRoutine(CurrentTable
, BootPhase
);
164 CurrentEntry
= CurrentEntry
->Flink
;
167 /* Call the Wrapper Init Routine */
168 if (WrapperInitRoutine
)
169 WrapperTable
.KdpInitRoutine(&WrapperTable
, BootPhase
);
174 KdInitSystem(ULONG BootPhase
,
175 PLOADER_PARAMETER_BLOCK LoaderBlock
)
179 PCHAR CommandLine
, Port
, BaudRate
, Irq
;
181 /* Set Default Port Options */
184 /* Get the Command Line */
185 CommandLine
= LoaderBlock
->LoadOptions
;
188 _strupr(CommandLine
);
190 /* XXX Check for settings that we support */
191 if (strstr(CommandLine
, "BREAK")) KdpEarlyBreak
= TRUE
;
192 if (strstr(CommandLine
, "NODEBUG")) KdDebuggerEnabled
= FALSE
;
193 else if (strstr(CommandLine
, "CRASHDEBUG")) KdDebuggerEnabled
= FALSE
;
194 else if (strstr(CommandLine
, "DEBUG"))
196 /* Enable the kernel debugger */
197 KdDebuggerNotPresent
= FALSE
;
198 KdDebuggerEnabled
= TRUE
;
200 /* Get the KDBG Settings */
201 KdbpGetCommandLineSettings(LoaderBlock
->LoadOptions
);
205 /* Let user-mode know our state */
206 SharedUserData
->KdDebuggerEnabled
= KdDebuggerEnabled
;
208 /* Get the port and baud rate */
209 Port
= strstr(CommandLine
, "DEBUGPORT");
210 BaudRate
= strstr(CommandLine
, "BAUDRATE");
211 Irq
= strstr(CommandLine
, "IRQ");
213 /* Check if we got the /DEBUGPORT parameter(s) */
216 /* Move past the actual string, to reach the port*/
217 Port
+= sizeof("DEBUGPORT") - 1;
219 /* Now get past any spaces and skip the equal sign */
220 while (*Port
== ' ') Port
++;
223 /* Get the debug mode and wrapper */
224 Port
= KdpGetDebugMode(Port
);
225 Port
= strstr(Port
, "DEBUGPORT");
228 /* Use serial port then */
229 if (KdDebuggerEnabled
&& KdpDebugMode
.Value
== 0)
230 KdpDebugMode
.Serial
= TRUE
;
232 /* Check if we got a baud rate */
235 /* Move past the actual string, to reach the rate */
236 BaudRate
+= sizeof("BAUDRATE") - 1;
238 /* Now get past any spaces */
239 while (*BaudRate
== ' ') BaudRate
++;
241 /* And make sure we have a rate */
244 /* Read and set it */
245 Value
= atol(BaudRate
+ 1);
246 if (Value
) PortInfo
.BaudRate
= SerialPortInfo
.BaudRate
= Value
;
250 /* Check Serial Port Settings [IRQ] */
253 /* Move past the actual string, to reach the rate */
254 Irq
+= sizeof("IRQ") - 1;
256 /* Now get past any spaces */
257 while (*Irq
== ' ') Irq
++;
259 /* And make sure we have an IRQ */
262 /* Read and set it */
263 Value
= atol(Irq
+ 1);
264 if (Value
) KdpPortIrq
= Value
;
268 /* Call Providers at Phase 0 */
269 for (i
= 0; i
< KdMax
; i
++)
271 InitRoutines
[i
](&DispatchTable
[i
], 0);
274 /* Call Wrapper at Phase 0 */
275 if (WrapperInitRoutine
) WrapperInitRoutine(&WrapperTable
, 0);
278 else /* BootPhase > 0 */
285 /* Call the Initialization Routines of the Registered Providers */
286 KdpCallInitRoutine(BootPhase
);