mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +00:00
thermosphere: fix break/continue (?), fix attach/detach
This commit is contained in:
parent
f0b9162d5e
commit
175f16627b
5 changed files with 54 additions and 13 deletions
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "debug_manager.h"
|
#include "debug_manager.h"
|
||||||
#include "core_ctx.h"
|
#include "core_ctx.h"
|
||||||
|
@ -64,6 +65,8 @@ static void debugManagerDoPauseCores(u32 coreList)
|
||||||
if (remainingList & BIT(currentCoreCtx->coreId)) {
|
if (remainingList & BIT(currentCoreCtx->coreId)) {
|
||||||
currentCoreCtx->wasPaused = true;
|
currentCoreCtx->wasPaused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__sev();
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugManagerPauseSgiHandler(void)
|
void debugManagerPauseSgiHandler(void)
|
||||||
|
@ -168,6 +171,7 @@ void debugManagerReportEvent(DebugEventType type, ...)
|
||||||
u32 coreId = currentCoreCtx->coreId;
|
u32 coreId = currentCoreCtx->coreId;
|
||||||
|
|
||||||
DebugEventInfo *info = &g_debugManager.debugEventInfos[coreId];
|
DebugEventInfo *info = &g_debugManager.debugEventInfos[coreId];
|
||||||
|
memset(info, 0 , sizeof(DebugEventInfo));
|
||||||
|
|
||||||
info->type = type;
|
info->type = type;
|
||||||
info->coreId = coreId;
|
info->coreId = coreId;
|
||||||
|
@ -207,6 +211,12 @@ void debugManagerBreakCores(u32 coreList)
|
||||||
if (coreList & BIT(coreId) && !debugManagerIsCorePaused(coreId)) {
|
if (coreList & BIT(coreId) && !debugManagerIsCorePaused(coreId)) {
|
||||||
debugManagerReportEvent(DBGEVENT_DEBUGGER_BREAK);
|
debugManagerReportEvent(DBGEVENT_DEBUGGER_BREAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for all cores
|
||||||
|
__sevl();
|
||||||
|
do {
|
||||||
|
__wfe();
|
||||||
|
} while ((atomic_load(&g_debugManager.pausedCoreList) & coreList) != coreList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugManagerContinueCores(u32 coreList)
|
void debugManagerContinueCores(u32 coreList)
|
||||||
|
@ -218,4 +228,10 @@ void debugManagerContinueCores(u32 coreList)
|
||||||
if (coreList & BIT(coreId) && debugManagerIsCorePaused(coreId)) {
|
if (coreList & BIT(coreId) && debugManagerIsCorePaused(coreId)) {
|
||||||
debugManagerUnpauseCores(BIT(coreId));
|
debugManagerUnpauseCores(BIT(coreId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for all cores
|
||||||
|
__sevl();
|
||||||
|
do {
|
||||||
|
__wfe();
|
||||||
|
} while ((atomic_load(&g_debugManager.pausedCoreList) & coreList) != 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef struct OutputStringDebugEventInfo {
|
||||||
|
|
||||||
typedef struct DebugEventInfo {
|
typedef struct DebugEventInfo {
|
||||||
DebugEventType type;
|
DebugEventType type;
|
||||||
|
bool preprocessed;
|
||||||
bool handled;
|
bool handled;
|
||||||
u32 coreId;
|
u32 coreId;
|
||||||
ExceptionStackFrame *frame;
|
ExceptionStackFrame *frame;
|
||||||
|
|
|
@ -50,8 +50,8 @@ static const struct{
|
||||||
} gdbCommandHandlers[] = {
|
} gdbCommandHandlers[] = {
|
||||||
{ '?', GDB_HANDLER(GetStopReason) },
|
{ '?', GDB_HANDLER(GetStopReason) },
|
||||||
{ '!', GDB_HANDLER(EnableExtendedMode) },
|
{ '!', GDB_HANDLER(EnableExtendedMode) },
|
||||||
{ 'c', GDB_HANDLER(Continue) },
|
{ 'c', GDB_HANDLER(ContinueOrStepDeprecated) },
|
||||||
{ 'C', GDB_HANDLER(Continue) },
|
{ 'C', GDB_HANDLER(ContinueOrStepDeprecated) },
|
||||||
{ 'D', GDB_HANDLER(Detach) },
|
{ 'D', GDB_HANDLER(Detach) },
|
||||||
{ 'F', GDB_HANDLER(HioReply) },
|
{ 'F', GDB_HANDLER(HioReply) },
|
||||||
{ 'g', GDB_HANDLER(ReadRegisters) },
|
{ 'g', GDB_HANDLER(ReadRegisters) },
|
||||||
|
@ -184,14 +184,27 @@ void GDB_InitializeContext(GDBContext *ctx, TransportInterfaceType ifaceType, u3
|
||||||
|
|
||||||
void GDB_AttachToContext(GDBContext *ctx)
|
void GDB_AttachToContext(GDBContext *ctx)
|
||||||
{
|
{
|
||||||
if (!(ctx->flags & GDB_FLAG_ATTACHED_AT_START)) {
|
|
||||||
// TODO: debug pause
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: move the debug traps enable here?
|
// 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->state = GDB_STATE_ATTACHED;
|
||||||
|
|
||||||
|
ctx->sendOwnDebugEventDisallowed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDB_DetachFromContext(GDBContext *ctx)
|
void GDB_DetachFromContext(GDBContext *ctx)
|
||||||
|
@ -212,6 +225,9 @@ void GDB_DetachFromContext(GDBContext *ctx)
|
||||||
|
|
||||||
ctx->currentHioRequestTargetAddr = 0;
|
ctx->currentHioRequestTargetAddr = 0;
|
||||||
memset(&ctx->currentHioRequest, 0, sizeof(PackedGdbHioRequest));
|
memset(&ctx->currentHioRequest, 0, sizeof(PackedGdbHioRequest));
|
||||||
|
|
||||||
|
debugManagerSetReportingFalse(true);
|
||||||
|
debugManagerContinueCores(getActiveCoreMask());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDB_AcquireContext(GDBContext *ctx)
|
void GDB_AcquireContext(GDBContext *ctx)
|
||||||
|
|
|
@ -31,13 +31,13 @@ static bool GDB_PreprocessDebugEvent(GDBContext *ctx, DebugEventInfo *info)
|
||||||
switch (info->type) {
|
switch (info->type) {
|
||||||
case DBGEVENT_CORE_ON: {
|
case DBGEVENT_CORE_ON: {
|
||||||
shouldSignal = ctx->catchThreadEvents;
|
shouldSignal = ctx->catchThreadEvents;
|
||||||
if (!info->handled) {
|
if (!info->preprocessed) {
|
||||||
ctx->attachedCoreList |= BIT(info->coreId);
|
ctx->attachedCoreList |= BIT(info->coreId);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DBGEVENT_CORE_OFF: {
|
case DBGEVENT_CORE_OFF: {
|
||||||
if (!info->handled) {
|
if (!info->preprocessed) {
|
||||||
u32 newLst = ctx->attachedCoreList & ~BIT(info->coreId);
|
u32 newLst = ctx->attachedCoreList & ~BIT(info->coreId);
|
||||||
if (ctx->selectedThreadId == info->coreId && newLst != 0) {
|
if (ctx->selectedThreadId == info->coreId && newLst != 0) {
|
||||||
ctx->selectedThreadId = __builtin_ctz(newLst);
|
ctx->selectedThreadId = __builtin_ctz(newLst);
|
||||||
|
@ -46,7 +46,7 @@ static bool GDB_PreprocessDebugEvent(GDBContext *ctx, DebugEventInfo *info)
|
||||||
ctx->attachedCoreList = newLst;
|
ctx->attachedCoreList = newLst;
|
||||||
shouldSignal = ctx->catchThreadEvents || newLst == 0;
|
shouldSignal = ctx->catchThreadEvents || newLst == 0;
|
||||||
} else {
|
} else {
|
||||||
shouldSignal = ctx->catchThreadEvents;
|
shouldSignal = ctx->catchThreadEvents || ctx->attachedCoreList == 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ static bool GDB_PreprocessDebugEvent(GDBContext *ctx, DebugEventInfo *info)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->handled = true;
|
info->preprocessed = true;
|
||||||
restoreInterruptFlags(irqFlags);
|
restoreInterruptFlags(irqFlags);
|
||||||
return shouldSignal;
|
return shouldSignal;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,14 @@ void GDB_BreakAllCores(GDBContext *ctx)
|
||||||
if (ctx->flags & GDB_FLAG_NONSTOP) {
|
if (ctx->flags & GDB_FLAG_NONSTOP) {
|
||||||
debugManagerBreakCores(ctx->attachedCoreList);
|
debugManagerBreakCores(ctx->attachedCoreList);
|
||||||
} else {
|
} 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,11 @@
|
||||||
#include "../core_ctx.h"
|
#include "../core_ctx.h"
|
||||||
#include "../debug_manager.h"
|
#include "../debug_manager.h"
|
||||||
|
|
||||||
void GDB_ContinueExecution(GDBContext *ctx);
|
|
||||||
int GDB_SendStopReply(GDBContext *ctx, DebugEventInfo *info, bool asNotification);
|
int GDB_SendStopReply(GDBContext *ctx, DebugEventInfo *info, bool asNotification);
|
||||||
int GDB_TrySignalDebugEvent(GDBContext *ctx, DebugEventInfo *info);
|
int GDB_TrySignalDebugEvent(GDBContext *ctx, DebugEventInfo *info);
|
||||||
|
|
||||||
|
void GDB_BreakAllCores(GDBContext *ctx);
|
||||||
|
|
||||||
GDB_DECLARE_VERBOSE_HANDLER(Stopped);
|
GDB_DECLARE_VERBOSE_HANDLER(Stopped);
|
||||||
|
|
||||||
GDB_DECLARE_HANDLER(Detach);
|
GDB_DECLARE_HANDLER(Detach);
|
||||||
|
|
Loading…
Reference in a new issue