https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6025df33a572417841533…
commit 6025df33a57241784153307e98c7e765ba68a0a7
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sat Mar 7 17:18:33 2020 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Mon Nov 16 08:55:02 2020 +0100
[NTOS:KD] Make implementation of KdInitSystem more similar with the kd64 one
Move some kd initializations into KdDebuggerInitialize0() function.
---
ntoskrnl/kd/kdinit.c | 308 ++++++++++++++++++++++---------------------------
ntoskrnl/kd/kdmain.c | 157 ++++++++++++++++++++++++-
ntoskrnl/kd64/kdapi.c | 7 ++
ntoskrnl/kd64/kddata.c | 2 +-
4 files changed, 305 insertions(+), 169 deletions(-)
diff --git a/ntoskrnl/kd/kdinit.c b/ntoskrnl/kd/kdinit.c
index 21e21162416..a2ed88ca6ee 100644
--- a/ntoskrnl/kd/kdinit.c
+++ b/ntoskrnl/kd/kdinit.c
@@ -39,76 +39,11 @@ extern ANSI_STRING KdpLogFileName;
/* PRIVATE FUNCTIONS *********************************************************/
-CODE_SEG("INIT")
-PCHAR
+BOOLEAN
NTAPI
-KdpGetDebugMode(PCHAR Currentp2)
-{
- PCHAR p1, p2 = Currentp2;
- ULONG Value;
-
- /* Check for Screen Debugging */
- if (!_strnicmp(p2, "SCREEN", 6))
- {
- /* Enable It */
- p2 += 6;
- KdpDebugMode.Screen = TRUE;
- }
- /* Check for Serial Debugging */
- else if (!_strnicmp(p2, "COM", 3))
- {
- /* Gheck for a valid Serial Port */
- p2 += 3;
- if (*p2 != ':')
- {
- Value = (ULONG)atol(p2);
- if (Value > 0 && Value < 5)
- {
- /* Valid port found, enable Serial Debugging */
- KdpDebugMode.Serial = TRUE;
-
- /* Set the port to use */
- SerialPortNumber = Value;
- KdpPort = Value;
- }
- }
- else
- {
- Value = strtoul(p2 + 1, NULL, 0);
- if (Value)
- {
- KdpDebugMode.Serial = TRUE;
- SerialPortInfo.Address = UlongToPtr(Value);
- SerialPortNumber = 0;
- KdpPort = 0;
- }
- }
- }
- /* Check for Debug Log Debugging */
- else if (!_strnicmp(p2, "FILE", 4))
- {
- /* Enable It */
- p2 += 4;
- KdpDebugMode.File = TRUE;
- if (*p2 == ':')
- {
- p2++;
- p1 = p2;
- while (*p2 != '\0' && *p2 != ' ') p2++;
- KdpLogFileName.MaximumLength = KdpLogFileName.Length = p2 - p1;
- KdpLogFileName.Buffer = p1;
- }
- }
- /* Check for BOCHS Debugging */
- else if (!_strnicmp(p2, "BOCHS", 5))
- {
- /* Enable It */
- p2 += 5;
- KdpDebugMode.Bochs = TRUE;
- }
-
- return p2;
-}
+KdRegisterDebuggerDataBlock(IN ULONG Tag,
+ IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader,
+ IN ULONG Size);
CODE_SEG("INIT")
VOID
@@ -141,133 +76,172 @@ KdpCallInitRoutine(ULONG BootPhase)
BOOLEAN
NTAPI
-KdInitSystem(ULONG BootPhase,
- PLOADER_PARAMETER_BLOCK LoaderBlock)
+KdInitSystem(IN ULONG BootPhase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
- ULONG Value;
+ BOOLEAN EnableKd;
+ LPSTR DebugLine;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
ULONG i;
- PCHAR CommandLine, Port = NULL, BaudRate = NULL, Irq = NULL;
+ PCHAR CommandLine;
- /* Set Default Port Options */
- if (BootPhase == 0)
+ /* Check if this is Phase 1 */
+ if (BootPhase)
{
- /* Check if we have a loader block */
- if (LoaderBlock)
- {
- /* Check if we have a command line */
- CommandLine = LoaderBlock->LoadOptions;
- if (CommandLine)
- {
- /* Upcase it */
- _strupr(CommandLine);
-
- /* XXX Check for settings that we support */
- if (strstr(CommandLine, "NODEBUG")) KdDebuggerEnabled = FALSE;
- else if (strstr(CommandLine, "CRASHDEBUG")) KdDebuggerEnabled =
FALSE;
- else if (strstr(CommandLine, "DEBUG"))
- {
- /* Enable the kernel debugger */
- KdDebuggerNotPresent = FALSE;
- KdDebuggerEnabled = TRUE;
-#ifdef KDBG
- /* Get the KDBG Settings */
- KdbpGetCommandLineSettings(LoaderBlock->LoadOptions);
-#endif
- }
+ /* Call the Initialization Routines of the Registered Providers */
+ KdpCallInitRoutine(BootPhase);
+ return TRUE;
+ }
- /* Get the port and baud rate */
- Port = strstr(CommandLine, "DEBUGPORT");
- BaudRate = strstr(CommandLine, "BAUDRATE");
- Irq = strstr(CommandLine, "IRQ");
- }
- else
- {
- /* No command line options? Disable debugger by default */
- KdDebuggerEnabled = FALSE;
- }
- }
- else
- {
- /* Called from a bugcheck or a re-enable. Unconditionally enable KD. */
- KdDebuggerEnabled = TRUE;
- }
+ /* Check if we already initialized once */
+ if (KdDebuggerEnabled) return TRUE;
- /* Let user-mode know our state */
- SharedUserData->KdDebuggerEnabled = KdDebuggerEnabled;
+ /* Disable break after symbol load for now */
+ KdBreakAfterSymbolLoad = FALSE;
- /* Check if we got the /DEBUGPORT parameter(s) */
- while (Port)
- {
- /* Move past the actual string, to reach the port*/
- Port += sizeof("DEBUGPORT") - 1;
+ /* Check if the Debugger Data Block was already initialized */
+ if (!KdpDebuggerDataListHead.Flink)
+ {
+ /* It wasn't...Initialize the KD Data Listhead */
+ InitializeListHead(&KdpDebuggerDataListHead);
- /* Now get past any spaces and skip the equal sign */
- while (*Port == ' ') Port++;
- Port++;
+ /* Register the Debugger Data Block */
+ KdRegisterDebuggerDataBlock(KDBG_TAG,
+ &KdDebuggerDataBlock.Header,
+ sizeof(KdDebuggerDataBlock));
- /* Get the debug mode and wrapper */
- Port = KdpGetDebugMode(Port);
- Port = strstr(Port, "DEBUGPORT");
- }
+ /* Fill out the KD Version Block */
+ KdVersionBlock.MajorVersion = (USHORT)((DBGKD_MAJOR_NT << 8) |
(NtBuildNumber >> 28));
+ KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);
+
+#ifdef CONFIG_SMP
+ /* This is an MP Build */
+ KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP;
+#endif
+
+ /* Save Pointers to Loaded Module List and Debugger Data */
+ KdVersionBlock.PsLoadedModuleList = (ULONG64)(LONG_PTR)&PsLoadedModuleList;
+ KdVersionBlock.DebuggerDataList =
(ULONG64)(LONG_PTR)&KdpDebuggerDataListHead;
- /* Use serial port then */
- if (KdDebuggerEnabled && KdpDebugMode.Value == 0)
- KdpDebugMode.Serial = TRUE;
+ /* Set protocol limits */
+ KdVersionBlock.MaxStateChange = DbgKdMaximumStateChange -
+ DbgKdMinimumStateChange;
+ KdVersionBlock.MaxManipulate = DbgKdMaximumManipulate -
+ DbgKdMinimumManipulate;
+ KdVersionBlock.Unused[0] = 0;
- /* Check if we got a baud rate */
- if (BaudRate)
+ /* Link us in the KPCR */
+ KeGetPcr()->KdVersionBlock = &KdVersionBlock;
+ }
+
+ /* Check if we have a loader block */
+ if (LoaderBlock)
+ {
+ /* Get the image entry */
+ LdrEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* Save the Kernel Base */
+ PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
+ KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)LdrEntry->DllBase;
+
+ /* Check if we have a command line */
+ CommandLine = LoaderBlock->LoadOptions;
+ if (CommandLine)
{
- /* Move past the actual string, to reach the rate */
- BaudRate += sizeof("BAUDRATE") - 1;
+ /* Upcase it */
+ _strupr(CommandLine);
- /* Now get past any spaces */
- while (*BaudRate == ' ') BaudRate++;
+ /* Assume we'll disable KD */
+ EnableKd = FALSE;
- /* And make sure we have a rate */
- if (*BaudRate)
+ /* Check for CRASHDEBUG, NODEBUG and just DEBUG */
+ if (strstr(CommandLine, "CRASHDEBUG"))
+ {
+ /* Don't enable KD now, but allow it to be enabled later */
+ KdPitchDebugger = FALSE;
+ }
+ else if (strstr(CommandLine, "NODEBUG"))
{
- /* Read and set it */
- Value = atol(BaudRate + 1);
- if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
+ /* Don't enable KD and don't let it be enabled later */
+ KdPitchDebugger = TRUE;
+ }
+ else if ((DebugLine = strstr(CommandLine, "DEBUG")) != NULL)
+ {
+ /* Enable KD */
+ EnableKd = TRUE;
+ KdDebuggerNotPresent = FALSE;
+#ifdef KDBG
+ /* Get the KDBG Settings */
+ KdbpGetCommandLineSettings(LoaderBlock->LoadOptions);
+#endif
}
}
-
- /* Check Serial Port Settings [IRQ] */
- if (Irq)
+ else
{
- /* Move past the actual string, to reach the rate */
- Irq += sizeof("IRQ") - 1;
+ /* No command line options? Disable debugger by default */
+ KdPitchDebugger = TRUE;
+ EnableKd = FALSE;
+ }
+ }
+ else
+ {
+ /* Called from a bugcheck or a re-enable. Save the Kernel Base. */
+ KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase;
- /* Now get past any spaces */
- while (*Irq == ' ') Irq++;
+ /* Unconditionally enable KD */
+ EnableKd = TRUE;
+ }
+
+ /* Set the Kernel Base in the Data Block */
+ KdDebuggerDataBlock.KernBase = (ULONG_PTR)KdVersionBlock.KernBase;
- /* And make sure we have an IRQ */
- if (*Irq)
+ /* Initialize the debugger if requested */
+ if (EnableKd && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock))))
+ {
+ /* Check if we've already initialized our structures */
+ if (!KdpDebuggerStructuresInitialized)
+ {
+ /* Set the Debug Switch Routine and Retries */
+ KdpContext.KdpDefaultRetries = 20;
+ KiDebugSwitchRoutine = KdpSwitchProcessor;
+
+ /* Initialize breakpoints owed flag and table */
+ KdpOweBreakpoint = FALSE;
+ for (i = 0; i < KD_BREAKPOINT_MAX; i++)
{
- /* Read and set it */
- Value = atol(Irq + 1);
- if (Value) KdpPortIrq = Value;
+ KdpBreakpointTable[i].Flags = 0;
+ KdpBreakpointTable[i].DirectoryTableBase = 0;
+ KdpBreakpointTable[i].Address = NULL;
}
- }
- /* Call Providers at Phase 0 */
- for (i = 0; i < KdMax; i++)
- {
- InitRoutines[i](&DispatchTable[i], 0);
+ /* Initialize the Time Slip DPC */
+ KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);
+ KeInitializeTimer(&KdpTimeSlipTimer);
+ ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);
+
+ /* First-time initialization done! */
+ KdpDebuggerStructuresInitialized = TRUE;
}
- /* Call Wrapper at Phase 0 */
- if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
- return TRUE;
+ /* Initialize the timer */
+ KdTimerStart.QuadPart = 0;
+
+ /* Officially enable KD */
+ KdPitchDebugger = FALSE;
+ KdDebuggerEnabled = TRUE;
+
+ /* Let user-mode know that it's enabled as well */
+ SharedUserData->KdDebuggerEnabled = TRUE;
}
- else /* BootPhase > 0 */
+ else
{
+ /* Disable debugger */
+ KdDebuggerNotPresent = TRUE;
}
- /* Call the Initialization Routines of the Registered Providers */
- KdpCallInitRoutine(BootPhase);
-
- /* Return success */
+ /* Return initialized */
return TRUE;
}
diff --git a/ntoskrnl/kd/kdmain.c b/ntoskrnl/kd/kdmain.c
index 92a47a9cc91..5cf6e00bd57 100644
--- a/ntoskrnl/kd/kdmain.c
+++ b/ntoskrnl/kd/kdmain.c
@@ -58,6 +58,9 @@ VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
ULONG Kd_DEFAULT_MASK = 1 << DPFLTR_ERROR_LEVEL;
#endif
+extern CPPORT PortInfo;
+extern ANSI_STRING KdpLogFileName;
+
/* PRIVATE FUNCTIONS *********************************************************/
ULONG
@@ -413,12 +416,164 @@ KdSystemDebugControl(IN SYSDBG_COMMAND Command,
PKDEBUG_ROUTINE KiDebugRoutine = KdpEnterDebuggerException;
+CODE_SEG("INIT")
+PCHAR
+NTAPI
+KdpGetDebugMode(PCHAR Currentp2)
+{
+ PCHAR p1, p2 = Currentp2;
+ ULONG Value;
+
+ /* Check for Screen Debugging */
+ if (!_strnicmp(p2, "SCREEN", 6))
+ {
+ /* Enable It */
+ p2 += 6;
+ KdpDebugMode.Screen = TRUE;
+ }
+ /* Check for Serial Debugging */
+ else if (!_strnicmp(p2, "COM", 3))
+ {
+ /* Gheck for a valid Serial Port */
+ p2 += 3;
+ if (*p2 != ':')
+ {
+ Value = (ULONG)atol(p2);
+ if (Value > 0 && Value < 5)
+ {
+ /* Valid port found, enable Serial Debugging */
+ KdpDebugMode.Serial = TRUE;
+
+ /* Set the port to use */
+ SerialPortNumber = Value;
+ KdpPort = Value;
+ }
+ }
+ else
+ {
+ Value = strtoul(p2 + 1, NULL, 0);
+ if (Value)
+ {
+ KdpDebugMode.Serial = TRUE;
+ SerialPortInfo.Address = UlongToPtr(Value);
+ SerialPortNumber = 0;
+ KdpPort = 0;
+ }
+ }
+ }
+ /* Check for Debug Log Debugging */
+ else if (!_strnicmp(p2, "FILE", 4))
+ {
+ /* Enable It */
+ p2 += 4;
+ KdpDebugMode.File = TRUE;
+ if (*p2 == ':')
+ {
+ p2++;
+ p1 = p2;
+ while (*p2 != '\0' && *p2 != ' ') p2++;
+ KdpLogFileName.MaximumLength = KdpLogFileName.Length = p2 - p1;
+ KdpLogFileName.Buffer = p1;
+ }
+ }
+ /* Check for BOCHS Debugging */
+ else if (!_strnicmp(p2, "BOCHS", 5))
+ {
+ /* Enable It */
+ p2 += 5;
+ KdpDebugMode.Bochs = TRUE;
+ }
+
+ return p2;
+}
+
NTSTATUS
NTAPI
KdDebuggerInitialize0(
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{
- return STATUS_NOT_IMPLEMENTED;
+ ULONG Value;
+ ULONG i;
+ PCHAR CommandLine, Port = NULL, BaudRate = NULL, Irq = NULL;
+
+ if (LoaderBlock)
+ {
+ /* Check if we have a command line */
+ CommandLine = LoaderBlock->LoadOptions;
+ if (CommandLine)
+ {
+ /* Upcase it */
+ _strupr(CommandLine);
+
+ /* Get the port and baud rate */
+ Port = strstr(CommandLine, "DEBUGPORT");
+ BaudRate = strstr(CommandLine, "BAUDRATE");
+ Irq = strstr(CommandLine, "IRQ");
+ }
+ }
+
+ /* Check if we got the /DEBUGPORT parameter(s) */
+ while (Port)
+ {
+ /* Move past the actual string, to reach the port*/
+ Port += sizeof("DEBUGPORT") - 1;
+
+ /* Now get past any spaces and skip the equal sign */
+ while (*Port == ' ') Port++;
+ Port++;
+
+ /* Get the debug mode and wrapper */
+ Port = KdpGetDebugMode(Port);
+ Port = strstr(Port, "DEBUGPORT");
+ }
+
+ /* Use serial port then */
+ if (KdpDebugMode.Value == 0)
+ KdpDebugMode.Serial = TRUE;
+
+ /* Check if we got a baud rate */
+ if (BaudRate)
+ {
+ /* Move past the actual string, to reach the rate */
+ BaudRate += sizeof("BAUDRATE") - 1;
+
+ /* Now get past any spaces */
+ while (*BaudRate == ' ') BaudRate++;
+
+ /* And make sure we have a rate */
+ if (*BaudRate)
+ {
+ /* Read and set it */
+ Value = atol(BaudRate + 1);
+ if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
+ }
+ }
+
+ /* Check Serial Port Settings [IRQ] */
+ if (Irq)
+ {
+ /* Move past the actual string, to reach the rate */
+ Irq += sizeof("IRQ") - 1;
+
+ /* Now get past any spaces */
+ while (*Irq == ' ') Irq++;
+
+ /* And make sure we have an IRQ */
+ if (*Irq)
+ {
+ /* Read and set it */
+ Value = atol(Irq + 1);
+ if (Value) KdpPortIrq = Value;
+ }
+ }
+
+ /* Call Providers at Phase 0 */
+ for (i = 0; i < KdMax; i++)
+ {
+ InitRoutines[i](&DispatchTable[i], 0);
+ }
+
+ return STATUS_SUCCESS;
}
NTSTATUS
diff --git a/ntoskrnl/kd64/kdapi.c b/ntoskrnl/kd64/kdapi.c
index f9205be480f..69fae2c450c 100644
--- a/ntoskrnl/kd64/kdapi.c
+++ b/ntoskrnl/kd64/kdapi.c
@@ -1726,6 +1726,7 @@ KdpReportCommandStringStateChange(IN PSTRING NameString,
Context);
} while (Status == ContinueProcessorReselected);
}
+#endif
BOOLEAN
NTAPI
@@ -1733,6 +1734,7 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
IN OUT PCONTEXT Context,
IN BOOLEAN SecondChanceException)
{
+#ifdef _WINKD_
STRING Header, Data;
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
KCONTINUE_STATUS Status;
@@ -1780,6 +1782,10 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD
ExceptionRecord,
/* Return */
return Status;
+#else
+ UNIMPLEMENTED;
+ return FALSE;
+#endif
}
VOID
@@ -1851,6 +1857,7 @@ KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,
return Status;
}
+#ifdef _WINKD_
LARGE_INTEGER
NTAPI
KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
diff --git a/ntoskrnl/kd64/kddata.c b/ntoskrnl/kd64/kddata.c
index d0acd10a2af..b11ea0fa98e 100644
--- a/ntoskrnl/kd64/kddata.c
+++ b/ntoskrnl/kd64/kddata.c
@@ -73,8 +73,8 @@ BOOLEAN KdpContextSent;
//
#ifdef _WINKD_
PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;
-PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
#endif
+PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
//
// Debugger Configuration Settings