mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[NTOS:KE/x64] Implement Kd processor switching
This commit is contained in:
parent
9229709312
commit
72fd54a7f4
7 changed files with 131 additions and 43 deletions
|
@ -72,14 +72,6 @@ BOOLEAN
|
||||||
IN BOOLEAN SecondChance
|
IN BOOLEAN SecondChance
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef
|
|
||||||
BOOLEAN
|
|
||||||
(NTAPI *PKDEBUG_SWITCH_ROUTINE)(
|
|
||||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
|
||||||
IN PCONTEXT Context,
|
|
||||||
IN BOOLEAN SecondChance
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialization Routines
|
// Initialization Routines
|
||||||
//
|
//
|
||||||
|
@ -110,13 +102,10 @@ KdIsThisAKdTrap(
|
||||||
//
|
//
|
||||||
// Multi-Processor Switch Support
|
// Multi-Processor Switch Support
|
||||||
//
|
//
|
||||||
BOOLEAN
|
KCONTINUE_STATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpSwitchProcessor(
|
KdReportProcessorChange(
|
||||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
VOID);
|
||||||
IN OUT PCONTEXT ContextRecord,
|
|
||||||
IN BOOLEAN SecondChanceException
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Time Slip Support
|
// Time Slip Support
|
||||||
|
@ -540,7 +529,6 @@ extern LARGE_INTEGER KdTimerStart;
|
||||||
extern ULONG KdDisableCount;
|
extern ULONG KdDisableCount;
|
||||||
extern KD_CONTEXT KdpContext;
|
extern KD_CONTEXT KdpContext;
|
||||||
extern PKDEBUG_ROUTINE KiDebugRoutine;
|
extern PKDEBUG_ROUTINE KiDebugRoutine;
|
||||||
extern PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
|
|
||||||
extern BOOLEAN KdBreakAfterSymbolLoad;
|
extern BOOLEAN KdBreakAfterSymbolLoad;
|
||||||
extern BOOLEAN KdPitchDebugger;
|
extern BOOLEAN KdPitchDebugger;
|
||||||
extern BOOLEAN KdAutoEnableOnEvent;
|
extern BOOLEAN KdAutoEnableOnEvent;
|
||||||
|
|
|
@ -1001,6 +1001,11 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KeThawExecution(IN BOOLEAN Enable);
|
KeThawExecution(IN BOOLEAN Enable);
|
||||||
|
|
||||||
|
KCONTINUE_STATUS
|
||||||
|
NTAPI
|
||||||
|
KxSwitchKdProcessor(
|
||||||
|
_In_ ULONG ProcessorIndex);
|
||||||
|
|
||||||
_IRQL_requires_min_(DISPATCH_LEVEL)
|
_IRQL_requires_min_(DISPATCH_LEVEL)
|
||||||
_Acquires_nonreentrant_lock_(*LockHandle->Lock)
|
_Acquires_nonreentrant_lock_(*LockHandle->Lock)
|
||||||
_Acquires_exclusive_lock_(*LockHandle->Lock)
|
_Acquires_exclusive_lock_(*LockHandle->Lock)
|
||||||
|
|
|
@ -1260,6 +1260,28 @@ KdpNotSupported(IN PDBGKD_MANIPULATE_STATE64 State)
|
||||||
&KdpContext);
|
&KdpContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
KCONTINUE_STATUS
|
||||||
|
KdpSwitchProcessor(
|
||||||
|
_In_ USHORT ProcessorIndex)
|
||||||
|
{
|
||||||
|
/* Make sure that the processor index is valid */
|
||||||
|
if (ProcessorIndex >= KeNumberProcessors)
|
||||||
|
{
|
||||||
|
KdpDprintf("%u is not a valid processor number\n", ProcessorIndex);
|
||||||
|
return ContinueProcessorReselected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the new processor is the current one, there is nothing to do */
|
||||||
|
if (ProcessorIndex == KeGetCurrentProcessorNumber())
|
||||||
|
{
|
||||||
|
return ContinueProcessorReselected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the architecture specific Ke routine */
|
||||||
|
return KxSwitchKdProcessor(ProcessorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
KCONTINUE_STATUS
|
KCONTINUE_STATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpSendWaitContinue(IN ULONG PacketType,
|
KdpSendWaitContinue(IN ULONG PacketType,
|
||||||
|
@ -1470,10 +1492,8 @@ SendPacket:
|
||||||
|
|
||||||
case DbgKdSwitchProcessor:
|
case DbgKdSwitchProcessor:
|
||||||
|
|
||||||
/* TODO */
|
/* Switch the processor and return */
|
||||||
KdpDprintf("Processor Switch support is unimplemented!\n");
|
return KdpSwitchProcessor(ManipulateState.Processor);
|
||||||
KdpNotSupported(&ManipulateState);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DbgKdPageInApi:
|
case DbgKdPageInApi:
|
||||||
|
|
||||||
|
@ -1785,6 +1805,33 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KCONTINUE_STATUS
|
||||||
|
NTAPI
|
||||||
|
KdReportProcessorChange(
|
||||||
|
VOID)
|
||||||
|
{
|
||||||
|
PKPRCB CurrentPrcb = KeGetCurrentPrcb();
|
||||||
|
PCONTEXT ContextRecord = &CurrentPrcb->ProcessorState.ContextFrame;
|
||||||
|
EXCEPTION_RECORD ExceptionRecord = {0};
|
||||||
|
KCONTINUE_STATUS Status;
|
||||||
|
|
||||||
|
/* Save the port data */
|
||||||
|
KdSave(FALSE);
|
||||||
|
|
||||||
|
ExceptionRecord.ExceptionAddress = (PVOID)KeGetContextPc(ContextRecord);
|
||||||
|
ExceptionRecord.ExceptionCode = STATUS_WAKE_SYSTEM_DEBUGGER;
|
||||||
|
|
||||||
|
/* Report the new state */
|
||||||
|
Status = KdpReportExceptionStateChange(&ExceptionRecord,
|
||||||
|
ContextRecord,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
/* Restore the port data */
|
||||||
|
KdRestore(FALSE);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpTimeSlipDpcRoutine(IN PKDPC Dpc,
|
KdpTimeSlipDpcRoutine(IN PKDPC Dpc,
|
||||||
|
@ -1833,27 +1880,6 @@ KdpTimeSlipWork(IN PVOID Context)
|
||||||
KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc);
|
KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
NTAPI
|
|
||||||
KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,
|
|
||||||
IN OUT PCONTEXT ContextRecord,
|
|
||||||
IN BOOLEAN SecondChanceException)
|
|
||||||
{
|
|
||||||
BOOLEAN Status;
|
|
||||||
|
|
||||||
/* Save the port data */
|
|
||||||
KdSave(FALSE);
|
|
||||||
|
|
||||||
/* Report a state change */
|
|
||||||
Status = KdpReportExceptionStateChange(ExceptionRecord,
|
|
||||||
ContextRecord,
|
|
||||||
SecondChanceException);
|
|
||||||
|
|
||||||
/* Restore the port data and return */
|
|
||||||
KdRestore(FALSE);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
LARGE_INTEGER
|
LARGE_INTEGER
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
|
KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
|
|
@ -72,7 +72,6 @@ BOOLEAN KdpContextSent;
|
||||||
// Debug Trap Handlers
|
// Debug Trap Handlers
|
||||||
//
|
//
|
||||||
PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;
|
PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;
|
||||||
PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Debugger Configuration Settings
|
// Debugger Configuration Settings
|
||||||
|
|
|
@ -360,9 +360,8 @@ KdInitSystem(
|
||||||
/* Check if we've already initialized our structures */
|
/* Check if we've already initialized our structures */
|
||||||
if (!KdpDebuggerStructuresInitialized)
|
if (!KdpDebuggerStructuresInitialized)
|
||||||
{
|
{
|
||||||
/* Set the Debug Switch Routine and Retries */
|
/* Set Retries */
|
||||||
KdpContext.KdpDefaultRetries = 20;
|
KdpContext.KdpDefaultRetries = 20;
|
||||||
KiDebugSwitchRoutine = KdpSwitchProcessor;
|
|
||||||
|
|
||||||
/* Initialize breakpoints owed flag and table */
|
/* Initialize breakpoints owed flag and table */
|
||||||
KdpOweBreakpoint = FALSE;
|
KdpOweBreakpoint = FALSE;
|
||||||
|
|
|
@ -40,6 +40,25 @@ KiProcessorFreezeHandler(
|
||||||
/* Wait for the freeze owner to release us */
|
/* Wait for the freeze owner to release us */
|
||||||
while (CurrentPrcb->IpiFrozen != IPI_FROZEN_STATE_THAW)
|
while (CurrentPrcb->IpiFrozen != IPI_FROZEN_STATE_THAW)
|
||||||
{
|
{
|
||||||
|
/* Check for Kd processor switch */
|
||||||
|
if (CurrentPrcb->IpiFrozen & IPI_FROZEN_FLAG_ACTIVE)
|
||||||
|
{
|
||||||
|
KCONTINUE_STATUS ContinueStatus;
|
||||||
|
|
||||||
|
/* Enter the debugger */
|
||||||
|
ContinueStatus = KdReportProcessorChange();
|
||||||
|
|
||||||
|
/* Set the state back to frozen */
|
||||||
|
CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_FROZEN;
|
||||||
|
|
||||||
|
/* If the status is ContinueSuccess, we need to release the freeze owner */
|
||||||
|
if (ContinueStatus == ContinueSuccess)
|
||||||
|
{
|
||||||
|
/* Release the freeze owner */
|
||||||
|
KiFreezeOwner->IpiFrozen = IPI_FROZEN_STATE_THAW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
YieldProcessor();
|
YieldProcessor();
|
||||||
KeMemoryBarrier();
|
KeMemoryBarrier();
|
||||||
}
|
}
|
||||||
|
@ -159,3 +178,46 @@ KxThawExecution(
|
||||||
/* Release the freeze owner */
|
/* Release the freeze owner */
|
||||||
InterlockedExchangePointer(&KiFreezeOwner, NULL);
|
InterlockedExchangePointer(&KiFreezeOwner, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KCONTINUE_STATUS
|
||||||
|
NTAPI
|
||||||
|
KxSwitchKdProcessor(
|
||||||
|
_In_ ULONG ProcessorIndex)
|
||||||
|
{
|
||||||
|
PKPRCB CurrentPrcb = KeGetCurrentPrcb();
|
||||||
|
PKPRCB TargetPrcb;
|
||||||
|
|
||||||
|
/* Make sure that the processor index is valid */
|
||||||
|
ASSERT(ProcessorIndex < KeNumberProcessors);
|
||||||
|
|
||||||
|
/* Inform the target processor that it's his turn now */
|
||||||
|
TargetPrcb = KiProcessorBlock[ProcessorIndex];
|
||||||
|
TargetPrcb->IpiFrozen |= IPI_FROZEN_FLAG_ACTIVE;
|
||||||
|
|
||||||
|
/* If we are not the freeze owner, we return back to the freeze loop */
|
||||||
|
if (KiFreezeOwner != CurrentPrcb)
|
||||||
|
{
|
||||||
|
return ContinueNextProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop until it's our turn again */
|
||||||
|
while (CurrentPrcb->IpiFrozen == IPI_FROZEN_STATE_OWNER)
|
||||||
|
{
|
||||||
|
YieldProcessor();
|
||||||
|
KeMemoryBarrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have been thawed */
|
||||||
|
if (CurrentPrcb->IpiFrozen == IPI_FROZEN_STATE_THAW)
|
||||||
|
{
|
||||||
|
/* Another CPU has completed, we can leave the debugger now */
|
||||||
|
KdpDprintf("[%u] KxSwitchKdProcessor: ContinueSuccess\n", KeGetCurrentProcessorNumber());
|
||||||
|
CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_OWNER;
|
||||||
|
return ContinueSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have been reselected, return to Kd to continue in the debugger */
|
||||||
|
CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_OWNER;
|
||||||
|
|
||||||
|
return ContinueProcessorReselected;
|
||||||
|
}
|
||||||
|
|
|
@ -26,3 +26,12 @@ KxThawExecution(
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KCONTINUE_STATUS
|
||||||
|
NTAPI
|
||||||
|
KxSwitchKdProcessor(
|
||||||
|
_In_ ULONG ProcessorIndex)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
return ContinueError;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue