mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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
|
||||
);
|
||||
|
||||
typedef
|
||||
BOOLEAN
|
||||
(NTAPI *PKDEBUG_SWITCH_ROUTINE)(
|
||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN BOOLEAN SecondChance
|
||||
);
|
||||
|
||||
//
|
||||
// Initialization Routines
|
||||
//
|
||||
|
@ -110,13 +102,10 @@ KdIsThisAKdTrap(
|
|||
//
|
||||
// Multi-Processor Switch Support
|
||||
//
|
||||
BOOLEAN
|
||||
KCONTINUE_STATUS
|
||||
NTAPI
|
||||
KdpSwitchProcessor(
|
||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN OUT PCONTEXT ContextRecord,
|
||||
IN BOOLEAN SecondChanceException
|
||||
);
|
||||
KdReportProcessorChange(
|
||||
VOID);
|
||||
|
||||
//
|
||||
// Time Slip Support
|
||||
|
@ -540,7 +529,6 @@ extern LARGE_INTEGER KdTimerStart;
|
|||
extern ULONG KdDisableCount;
|
||||
extern KD_CONTEXT KdpContext;
|
||||
extern PKDEBUG_ROUTINE KiDebugRoutine;
|
||||
extern PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
|
||||
extern BOOLEAN KdBreakAfterSymbolLoad;
|
||||
extern BOOLEAN KdPitchDebugger;
|
||||
extern BOOLEAN KdAutoEnableOnEvent;
|
||||
|
|
|
@ -1001,6 +1001,11 @@ VOID
|
|||
NTAPI
|
||||
KeThawExecution(IN BOOLEAN Enable);
|
||||
|
||||
KCONTINUE_STATUS
|
||||
NTAPI
|
||||
KxSwitchKdProcessor(
|
||||
_In_ ULONG ProcessorIndex);
|
||||
|
||||
_IRQL_requires_min_(DISPATCH_LEVEL)
|
||||
_Acquires_nonreentrant_lock_(*LockHandle->Lock)
|
||||
_Acquires_exclusive_lock_(*LockHandle->Lock)
|
||||
|
|
|
@ -1260,6 +1260,28 @@ KdpNotSupported(IN PDBGKD_MANIPULATE_STATE64 State)
|
|||
&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
|
||||
NTAPI
|
||||
KdpSendWaitContinue(IN ULONG PacketType,
|
||||
|
@ -1470,10 +1492,8 @@ SendPacket:
|
|||
|
||||
case DbgKdSwitchProcessor:
|
||||
|
||||
/* TODO */
|
||||
KdpDprintf("Processor Switch support is unimplemented!\n");
|
||||
KdpNotSupported(&ManipulateState);
|
||||
break;
|
||||
/* Switch the processor and return */
|
||||
return KdpSwitchProcessor(ManipulateState.Processor);
|
||||
|
||||
case DbgKdPageInApi:
|
||||
|
||||
|
@ -1785,6 +1805,33 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
|
|||
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
|
||||
NTAPI
|
||||
KdpTimeSlipDpcRoutine(IN PKDPC Dpc,
|
||||
|
@ -1833,27 +1880,6 @@ KdpTimeSlipWork(IN PVOID Context)
|
|||
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
|
||||
NTAPI
|
||||
KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
|
||||
|
|
|
@ -72,7 +72,6 @@ BOOLEAN KdpContextSent;
|
|||
// Debug Trap Handlers
|
||||
//
|
||||
PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;
|
||||
PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
|
||||
|
||||
//
|
||||
// Debugger Configuration Settings
|
||||
|
|
|
@ -360,9 +360,8 @@ KdInitSystem(
|
|||
/* Check if we've already initialized our structures */
|
||||
if (!KdpDebuggerStructuresInitialized)
|
||||
{
|
||||
/* Set the Debug Switch Routine and Retries */
|
||||
/* Set Retries */
|
||||
KdpContext.KdpDefaultRetries = 20;
|
||||
KiDebugSwitchRoutine = KdpSwitchProcessor;
|
||||
|
||||
/* Initialize breakpoints owed flag and table */
|
||||
KdpOweBreakpoint = FALSE;
|
||||
|
|
|
@ -40,6 +40,25 @@ KiProcessorFreezeHandler(
|
|||
/* Wait for the freeze owner to release us */
|
||||
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();
|
||||
KeMemoryBarrier();
|
||||
}
|
||||
|
@ -159,3 +178,46 @@ KxThawExecution(
|
|||
/* Release the freeze owner */
|
||||
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;
|
||||
}
|
||||
|
||||
KCONTINUE_STATUS
|
||||
NTAPI
|
||||
KxSwitchKdProcessor(
|
||||
_In_ ULONG ProcessorIndex)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return ContinueError;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue