diff --git a/thermosphere/src/debug_manager.c b/thermosphere/src/debug_manager.c index 00b517b47..66074762c 100644 --- a/thermosphere/src/debug_manager.c +++ b/thermosphere/src/debug_manager.c @@ -69,7 +69,7 @@ void debugManagerPauseSgiHandler(void) barrierWait(&g_debugManager.pauseBarrier); } -void debugManagerHandlePause(void) +bool debugManagerHandlePause(void) { u32 coreId = currentCoreCtx->coreId; __builtin_prefetch(&g_debugManager.pausedCoreList, 0, 3); @@ -80,6 +80,13 @@ void debugManagerHandlePause(void) __wfe(); } while (atomic_load(&g_debugManager.pausedCoreList) & BIT(coreId)); maskIrq(); + + if (!g_debugManager.debugEventInfos[coreId].handled) { + // Do we still have an unhandled debug event? + // TODO build + //GDB_TrySignalDebugEvent(&g_gdbContext, &g_debugManager.debugEventInfos[coreId]); + return false; + } } currentCoreCtx->wasPaused = false; @@ -92,6 +99,8 @@ void debugManagerHandlePause(void) } else if (!ssReqd && singleStepState != SingleStepState_Inactive) { singleStepSetNextState(currentCoreCtx->guestFrame, SingleStepState_Inactive); } + + return true; } void debugManagerPauseCores(u32 coreList) @@ -105,7 +114,12 @@ void debugManagerUnpauseCores(u32 coreList, u32 singleStepList) { singleStepList &= coreList; - __builtin_prefetch(&g_debugManager.pausedCoreList, 1, 0); + FOREACH_BIT (tmp, coreId, coreList) { + if (&g_debugManager.debugEventInfos[coreId].handled) { + // Discard already handled debug events + g_debugManager.debugEventInfos[coreId].type = DBGEVENT_NONE; + } + } // Since we're using a debugger lock, a simple stlr should be fine... atomic_store(&g_debugManager.singleStepCoreList, singleStepList); @@ -156,7 +170,7 @@ void debugManagerReportEvent(DebugEventType type, ...) exceptionEnterInterruptibleHypervisorCode(); unmaskIrq(); - GDB_TrySignalDebugEvent(&g_gdbContext, info); + // TODO GDB_TrySignalDebugEvent(&g_gdbContext, info); restoreInterruptFlags(flags); } diff --git a/thermosphere/src/debug_manager.h b/thermosphere/src/debug_manager.h index 30b8ee83f..07df9640e 100644 --- a/thermosphere/src/debug_manager.h +++ b/thermosphere/src/debug_manager.h @@ -22,7 +22,8 @@ extern GDBContext g_gdbContext; typedef enum DebugEventType { - DBGEVENT_DEBUGGER_BREAK = 0, + DBGEVENT_NONE = 0, + DBGEVENT_DEBUGGER_BREAK, DBGEVENT_EXCEPTION, DBGEVENT_CORE_ON, DBGEVENT_CORE_OFF, @@ -48,7 +49,7 @@ typedef struct DebugEventInfo { void debugManagerPauseSgiHandler(void); // Hypervisor interrupts will be serviced during the pause-wait -void debugManagerHandlePause(void); +bool debugManagerHandlePause(void); // Note: these functions are not reentrant EXCEPT debugPauseCores(1 << currentCoreId) // "Pause" makes sure all cores reaches the pause function before proceeding. diff --git a/thermosphere/src/exceptions.c b/thermosphere/src/exceptions.c index dcd649264..2e26729d8 100644 --- a/thermosphere/src/exceptions.c +++ b/thermosphere/src/exceptions.c @@ -122,7 +122,7 @@ void exceptionReturnPreprocess(ExceptionStackFrame *frame) if (currentCoreCtx->wasPaused && frame == currentCoreCtx->guestFrame) { // Were we paused & are we about to return to the guest? exceptionEnterInterruptibleHypervisorCode(); - debugManagerHandlePause(); + while (!debugManagerHandlePause()); fpuCleanInvalidateRegisterCache(); }