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 #if defined (ALLOC_PRAGMA)
15 #pragma alloc_text(INIT, KdInitSystem)
19 /* Make bochs debug output in the very early boot phase available */
20 //#define AUTO_ENABLE_BOCHS
22 /* VARIABLES ***************************************************************/
24 KD_PORT_INFORMATION PortInfo
= {DEFAULT_DEBUG_PORT
, DEFAULT_DEBUG_BAUD_RATE
, 0};
26 #ifdef AUTO_ENABLE_BOCHS
27 KDP_DEBUG_MODE KdpDebugMode
= {{{.Bochs
=TRUE
}}};
29 KDP_DEBUG_MODE KdpDebugMode
;
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
];
37 PKDP_INIT_ROUTINE InitRoutines
[KdMax
] = {KdpScreenInit
,
43 extern ANSI_STRING KdpLogFileName
;
45 /* PRIVATE FUNCTIONS *********************************************************/
50 KdpGetDebugMode(PCHAR Currentp2
)
52 PCHAR p1
, p2
= Currentp2
;
55 /* Check for Screen Debugging */
56 if (!_strnicmp(p2
, "SCREEN", 6))
60 KdpDebugMode
.Screen
= TRUE
;
62 /* Check for Serial Debugging */
63 else if (!_strnicmp(p2
, "COM", 3))
65 /* Gheck for a valid Serial Port */
69 Value
= (ULONG
)atol(p2
);
70 if (Value
> 0 && Value
< 5)
72 /* Valid port found, enable Serial Debugging */
73 KdpDebugMode
.Serial
= TRUE
;
75 /* Set the port to use */
76 SerialPortInfo
.ComPort
= Value
;
82 Value
= strtoul(p2
+ 1, NULL
, 0);
85 KdpDebugMode
.Serial
= TRUE
;
86 SerialPortInfo
.BaseAddress
= Value
;
87 SerialPortInfo
.ComPort
= 0;
93 /* Check for Debug Log Debugging */
94 else if (!_strnicmp(p2
, "FILE", 4))
98 KdpDebugMode
.File
= TRUE
;
103 while (*p2
!= '\0' && *p2
!= ' ') p2
++;
104 KdpLogFileName
.MaximumLength
= KdpLogFileName
.Length
= p2
- p1
;
105 KdpLogFileName
.Buffer
= p1
;
109 /* Check for BOCHS Debugging */
110 else if (!_strnicmp(p2
, "BOCHS", 5))
114 KdpDebugMode
.Bochs
= TRUE
;
117 /* Check for GDB Debugging */
118 else if (!_strnicmp(p2
, "GDB", 3))
122 KdpDebugMode
.Gdb
= TRUE
;
124 /* Enable Debugging */
125 KdDebuggerEnabled
= TRUE
;
126 KdDebuggerNotPresent
= FALSE
;
127 WrapperInitRoutine
= KdpGdbStubInit
;
130 /* Check for PICE Debugging */
131 else if (!_strnicmp(p2
, "PICE", 4))
135 KdpDebugMode
.Pice
= TRUE
;
137 /* Enable Debugging */
138 KdDebuggerEnabled
= TRUE
;
139 KdDebuggerNotPresent
= FALSE
;
148 KdpCallInitRoutine(ULONG BootPhase
)
150 PLIST_ENTRY CurrentEntry
;
151 PKD_DISPATCH_TABLE CurrentTable
;
153 /* Call the registered handlers */
154 CurrentEntry
= KdProviders
.Flink
;
155 while (CurrentEntry
!= &KdProviders
)
157 /* Get the current table */
158 CurrentTable
= CONTAINING_RECORD(CurrentEntry
,
163 CurrentTable
->KdpInitRoutine(CurrentTable
, BootPhase
);
166 CurrentEntry
= CurrentEntry
->Flink
;
169 /* Call the Wrapper Init Routine */
170 if (WrapperInitRoutine
)
171 WrapperTable
.KdpInitRoutine(&WrapperTable
, BootPhase
);
177 KdInitSystem(ULONG BootPhase
,
178 PLOADER_PARAMETER_BLOCK LoaderBlock
)
182 PCHAR CommandLine
, Port
, BaudRate
, Irq
;
184 /* Set Default Port Options */
187 /* Get the Command Line */
188 CommandLine
= LoaderBlock
->LoadOptions
;
191 _strupr(CommandLine
);
193 /* XXX Check for settings that we support */
194 if (strstr(CommandLine
, "BREAK")) KdpEarlyBreak
= TRUE
;
195 if (strstr(CommandLine
, "NODEBUG")) KdDebuggerEnabled
= FALSE
;
196 else if (strstr(CommandLine
, "CRASHDEBUG")) KdDebuggerEnabled
= FALSE
;
197 else if (strstr(CommandLine
, "DEBUG"))
199 /* Enable the kernel debugger */
200 KdDebuggerEnabled
= TRUE
;
201 KdDebuggerNotPresent
= FALSE
;
203 /* Get the KDBG Settings */
204 KdbpGetCommandLineSettings(LoaderBlock
->LoadOptions
);
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
);