From 175f16627b7b23e6fc6d55c2a300d9f64370affa Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Fri, 31 Jan 2020 01:12:59 +0000 Subject: [PATCH] thermosphere: fix break/continue (?), fix attach/detach --- thermosphere/src/debug_manager.c | 16 ++++++++++++++++ thermosphere/src/debug_manager.h | 1 + thermosphere/src/gdb/context.c | 30 +++++++++++++++++++++++------- thermosphere/src/gdb/debug.c | 17 ++++++++++++----- thermosphere/src/gdb/debug.h | 3 ++- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/thermosphere/src/debug_manager.c b/thermosphere/src/debug_manager.c index 269a0cc41..7b7ad1f2d 100644 --- a/thermosphere/src/debug_manager.c +++ b/thermosphere/src/debug_manager.c @@ -16,6 +16,7 @@ #include #include +#include #include "debug_manager.h" #include "core_ctx.h" @@ -64,6 +65,8 @@ static void debugManagerDoPauseCores(u32 coreList) if (remainingList & BIT(currentCoreCtx->coreId)) { currentCoreCtx->wasPaused = true; } + + __sev(); } void debugManagerPauseSgiHandler(void) @@ -168,6 +171,7 @@ void debugManagerReportEvent(DebugEventType type, ...) u32 coreId = currentCoreCtx->coreId; DebugEventInfo *info = &g_debugManager.debugEventInfos[coreId]; + memset(info, 0 , sizeof(DebugEventInfo)); info->type = type; info->coreId = coreId; @@ -207,6 +211,12 @@ void debugManagerBreakCores(u32 coreList) if (coreList & BIT(coreId) && !debugManagerIsCorePaused(coreId)) { debugManagerReportEvent(DBGEVENT_DEBUGGER_BREAK); } + + // Wait for all cores + __sevl(); + do { + __wfe(); + } while ((atomic_load(&g_debugManager.pausedCoreList) & coreList) != coreList); } void debugManagerContinueCores(u32 coreList) @@ -218,4 +228,10 @@ void debugManagerContinueCores(u32 coreList) if (coreList & BIT(coreId) && debugManagerIsCorePaused(coreId)) { debugManagerUnpauseCores(BIT(coreId)); } + + // Wait for all cores + __sevl(); + do { + __wfe(); + } while ((atomic_load(&g_debugManager.pausedCoreList) & coreList) != 0); } diff --git a/thermosphere/src/debug_manager.h b/thermosphere/src/debug_manager.h index 9c2aa2a80..031115f2a 100644 --- a/thermosphere/src/debug_manager.h +++ b/thermosphere/src/debug_manager.h @@ -38,6 +38,7 @@ typedef struct OutputStringDebugEventInfo { typedef struct DebugEventInfo { DebugEventType type; + bool preprocessed; bool handled; u32 coreId; ExceptionStackFrame *frame; diff --git a/thermosphere/src/gdb/context.c b/thermosphere/src/gdb/context.c index b9a526884..bd21d5c05 100644 --- a/thermosphere/src/gdb/context.c +++ b/thermosphere/src/gdb/context.c @@ -50,8 +50,8 @@ static const struct{ } gdbCommandHandlers[] = { { '?', GDB_HANDLER(GetStopReason) }, { '!', GDB_HANDLER(EnableExtendedMode) }, - { 'c', GDB_HANDLER(Continue) }, - { 'C', GDB_HANDLER(Continue) }, + { 'c', GDB_HANDLER(ContinueOrStepDeprecated) }, + { 'C', GDB_HANDLER(ContinueOrStepDeprecated) }, { 'D', GDB_HANDLER(Detach) }, { 'F', GDB_HANDLER(HioReply) }, { 'g', GDB_HANDLER(ReadRegisters) }, @@ -184,14 +184,27 @@ void GDB_InitializeContext(GDBContext *ctx, TransportInterfaceType ifaceType, u3 void GDB_AttachToContext(GDBContext *ctx) { - if (!(ctx->flags & GDB_FLAG_ATTACHED_AT_START)) { - // TODO: debug pause - } - // TODO: move the debug traps enable here? - // TODO: process the event + + ctx->attachedCoreList = getActiveCoreMask(); + + // We're in full-stop mode at this point + // Break cores, but don't send the debug event (it will be fetched with '?') + // Initialize lastDebugEvent + + debugManagerSetReportingEnabled(true); + ctx->sendOwnDebugEventDisallowed = true; + + GDB_BreakAllCores(ctx); + + DebugEventInfo *info = debugManagerGetCoreDebugEvent(currentCoreCtx->coreId); + info->preprocessed = true; + info->handled = true; + ctx->lastDebugEvent = info; ctx->state = GDB_STATE_ATTACHED; + + ctx->sendOwnDebugEventDisallowed = false; } void GDB_DetachFromContext(GDBContext *ctx) @@ -212,6 +225,9 @@ void GDB_DetachFromContext(GDBContext *ctx) ctx->currentHioRequestTargetAddr = 0; memset(&ctx->currentHioRequest, 0, sizeof(PackedGdbHioRequest)); + + debugManagerSetReportingFalse(true); + debugManagerContinueCores(getActiveCoreMask()); } void GDB_AcquireContext(GDBContext *ctx) diff --git a/thermosphere/src/gdb/debug.c b/thermosphere/src/gdb/debug.c index 38e167ae4..3a71e04bd 100644 --- a/thermosphere/src/gdb/debug.c +++ b/thermosphere/src/gdb/debug.c @@ -31,13 +31,13 @@ static bool GDB_PreprocessDebugEvent(GDBContext *ctx, DebugEventInfo *info) switch (info->type) { case DBGEVENT_CORE_ON: { shouldSignal = ctx->catchThreadEvents; - if (!info->handled) { + if (!info->preprocessed) { ctx->attachedCoreList |= BIT(info->coreId); } break; } case DBGEVENT_CORE_OFF: { - if (!info->handled) { + if (!info->preprocessed) { u32 newLst = ctx->attachedCoreList & ~BIT(info->coreId); if (ctx->selectedThreadId == info->coreId && newLst != 0) { ctx->selectedThreadId = __builtin_ctz(newLst); @@ -46,7 +46,7 @@ static bool GDB_PreprocessDebugEvent(GDBContext *ctx, DebugEventInfo *info) ctx->attachedCoreList = newLst; shouldSignal = ctx->catchThreadEvents || newLst == 0; } else { - shouldSignal = ctx->catchThreadEvents; + shouldSignal = ctx->catchThreadEvents || ctx->attachedCoreList == 0; } break; } @@ -56,7 +56,7 @@ static bool GDB_PreprocessDebugEvent(GDBContext *ctx, DebugEventInfo *info) break; } - info->handled = true; + info->preprocessed = true; restoreInterruptFlags(irqFlags); return shouldSignal; } @@ -287,7 +287,14 @@ void GDB_BreakAllCores(GDBContext *ctx) if (ctx->flags & GDB_FLAG_NONSTOP) { debugManagerBreakCores(ctx->attachedCoreList); } else { - debugManagerBreakCores(BIT(currentCoreCtx->coreId)); + // Break all cores too, but mark everything but the first has handled + debugManagerBreakCores(ctx->attachedCoreList); + u32 rem = ctx->attachedCoreList & ~BIT(currentCoreCtx->coreId); + FOREACH_BIT (tmp, coreId, rem) { + DebugEventInfo *info = debugManagerGetCoreDebugEvent(coreId); + info->handled = true; + info->preprocessed = true; + } } } diff --git a/thermosphere/src/gdb/debug.h b/thermosphere/src/gdb/debug.h index 7f612d707..e5e782e84 100644 --- a/thermosphere/src/gdb/debug.h +++ b/thermosphere/src/gdb/debug.h @@ -11,10 +11,11 @@ #include "../core_ctx.h" #include "../debug_manager.h" -void GDB_ContinueExecution(GDBContext *ctx); int GDB_SendStopReply(GDBContext *ctx, DebugEventInfo *info, bool asNotification); int GDB_TrySignalDebugEvent(GDBContext *ctx, DebugEventInfo *info); +void GDB_BreakAllCores(GDBContext *ctx); + GDB_DECLARE_VERBOSE_HANDLER(Stopped); GDB_DECLARE_HANDLER(Detach);