mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 09:36:35 +00:00
thermosphere: implement stop point broadcast
This commit is contained in:
parent
b2c5ef2611
commit
1775d59977
3 changed files with 71 additions and 22 deletions
|
@ -39,6 +39,19 @@ void initBreakpoints(void)
|
||||||
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void commitAndBroadcastBreakpointHandler(void *p)
|
||||||
|
{
|
||||||
|
(void)p;
|
||||||
|
u64 flags = maskIrq();
|
||||||
|
loadBreakpointRegs(g_breakpointManager.breakpoints, g_breakpointManager.maxBreakpoints);
|
||||||
|
restoreInterruptFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void commitAndBroadcastBreakpoints(void)
|
||||||
|
{
|
||||||
|
executeFunctionOnAllCores(commitAndBroadcastBreakpointHandler, NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
static DebugRegisterPair *allocateBreakpoint(void)
|
static DebugRegisterPair *allocateBreakpoint(void)
|
||||||
{
|
{
|
||||||
u32 pos = __builtin_ffs(g_breakpointManager.allocationBitmap);
|
u32 pos = __builtin_ffs(g_breakpointManager.allocationBitmap);
|
||||||
|
@ -107,9 +120,9 @@ int addBreakpoint(u64 addr)
|
||||||
|
|
||||||
regs->vr = addr;
|
regs->vr = addr;
|
||||||
|
|
||||||
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
commitAndBroadcastBreakpoints();
|
||||||
|
|
||||||
// TODO commit & broadcast
|
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -126,9 +139,9 @@ int removeBreakpoint(u64 addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
freeBreakpoint(regs - &g_breakpointManager.breakpoints[0]);
|
freeBreakpoint(regs - &g_breakpointManager.breakpoints[0]);
|
||||||
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
|
||||||
|
|
||||||
// TODO commit & broadcast
|
commitAndBroadcastBreakpoints();
|
||||||
|
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +152,7 @@ int removeAllBreakpoints(void)
|
||||||
g_breakpointManager.allocationBitmap = BIT(g_breakpointManager.maxBreakpoints) - 1;
|
g_breakpointManager.allocationBitmap = BIT(g_breakpointManager.maxBreakpoints) - 1;
|
||||||
memset(g_breakpointManager.breakpoints, 0, sizeof(g_breakpointManager.breakpoints));
|
memset(g_breakpointManager.breakpoints, 0, sizeof(g_breakpointManager.breakpoints));
|
||||||
|
|
||||||
// TODO: commit & broadcast
|
commitAndBroadcastBreakpoints();
|
||||||
|
|
||||||
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
recursiveSpinlockUnlock(&g_breakpointManager.lock);
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ static size_t findClosestSoftwareBreakpointSlot(u64 address)
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool doApplySoftwareBreakpoint(size_t id)
|
static inline bool doApplySoftwareBreakpoint(size_t id)
|
||||||
{
|
{
|
||||||
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
||||||
if (bp->applied) {
|
if (bp->applied) {
|
||||||
|
@ -71,7 +71,19 @@ static bool doApplySoftwareBreakpoint(size_t id)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool doRevertSoftwareBreakpoint(size_t id)
|
static void applySoftwareBreakpointHandler(void *p)
|
||||||
|
{
|
||||||
|
u64 flags = maskIrq();
|
||||||
|
doApplySoftwareBreakpoint(*(size_t *)p);
|
||||||
|
restoreInterruptFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void applySoftwareBreakpoint(size_t id)
|
||||||
|
{
|
||||||
|
executeFunctionOnAllCores(applySoftwareBreakpointHandler, &id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool doRevertSoftwareBreakpoint(size_t id)
|
||||||
{
|
{
|
||||||
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
||||||
if (!bp->applied) {
|
if (!bp->applied) {
|
||||||
|
@ -86,30 +98,40 @@ static bool doRevertSoftwareBreakpoint(size_t id)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO write SGI handlers for those ^
|
static void revertSoftwareBreakpointHandler(void *p)
|
||||||
|
{
|
||||||
|
u64 flags = maskIrq();
|
||||||
|
doRevertSoftwareBreakpoint(*(size_t *)p);
|
||||||
|
restoreInterruptFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void revertSoftwareBreakpoint(size_t id)
|
||||||
|
{
|
||||||
|
executeFunctionOnAllCores(revertSoftwareBreakpointHandler, &id, true);
|
||||||
|
}
|
||||||
|
|
||||||
bool applyAllSoftwareBreakpoints(void)
|
bool applyAllSoftwareBreakpoints(void)
|
||||||
{
|
{
|
||||||
recursiveSpinlockLock(&g_softwareBreakpointManager.lock);
|
u64 flags = recursiveSpinlockLockMaskIrq(&g_softwareBreakpointManager.lock);
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
for (size_t i = 0; i < g_softwareBreakpointManager.numBreakpoints; i++) {
|
for (size_t i = 0; i < g_softwareBreakpointManager.numBreakpoints; i++) {
|
||||||
ret = ret && doApplySoftwareBreakpoint(i);
|
ret = ret && doApplySoftwareBreakpoint(i); // note: no broadcast intentional
|
||||||
}
|
}
|
||||||
|
|
||||||
recursiveSpinlockUnlock(&g_softwareBreakpointManager.lock);
|
recursiveSpinlockUnlockRestoreIrq(&g_softwareBreakpointManager.lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool revertAllSoftwareBreakpoints(void)
|
bool revertAllSoftwareBreakpoints(void)
|
||||||
{
|
{
|
||||||
recursiveSpinlockLock(&g_softwareBreakpointManager.lock);
|
u64 flags = recursiveSpinlockLockMaskIrq(&g_softwareBreakpointManager.lock);
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
for (size_t i = 0; i < g_softwareBreakpointManager.numBreakpoints; i++) {
|
for (size_t i = 0; i < g_softwareBreakpointManager.numBreakpoints; i++) {
|
||||||
ret = ret && doRevertSoftwareBreakpoint(i);
|
ret = ret && doRevertSoftwareBreakpoint(i); // note: no broadcast intentional
|
||||||
}
|
}
|
||||||
|
|
||||||
recursiveSpinlockUnlock(&g_softwareBreakpointManager.lock);
|
recursiveSpinlockUnlockRestoreIrq(&g_softwareBreakpointManager.lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +164,7 @@ int addSoftwareBreakpoint(u64 addr, bool persistent)
|
||||||
bp->applied = false;
|
bp->applied = false;
|
||||||
bp->uid = 0x2000 + g_softwareBreakpointManager.bpUniqueCounter++;
|
bp->uid = 0x2000 + g_softwareBreakpointManager.bpUniqueCounter++;
|
||||||
|
|
||||||
// TODO: write broadcast for apply
|
applySoftwareBreakpoint(id);
|
||||||
// Note: no way to handle breakpoint failing to apply on 1+ core but not all, we need to assume operation succeeds
|
// Note: no way to handle breakpoint failing to apply on 1+ core but not all, we need to assume operation succeeds
|
||||||
recursiveSpinlockUnlock(&g_softwareBreakpointManager.lock);
|
recursiveSpinlockUnlock(&g_softwareBreakpointManager.lock);
|
||||||
|
|
||||||
|
@ -166,7 +188,7 @@ int removeSoftwareBreakpoint(u64 addr, bool keepPersistent)
|
||||||
|
|
||||||
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
||||||
if (!keepPersistent || !bp->persistent) {
|
if (!keepPersistent || !bp->persistent) {
|
||||||
// TODO: write broadcast for 'revert'
|
revertSoftwareBreakpoint(id);
|
||||||
// Note: no way to handle breakpoint failing to revert on 1+ core but not all, we need to assume operation succeeds
|
// Note: no way to handle breakpoint failing to revert on 1+ core but not all, we need to assume operation succeeds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +211,7 @@ int removeAllSoftwareBreakpoints(bool keepPersistent)
|
||||||
for (size_t id = 0; id < g_softwareBreakpointManager.numBreakpoints; id++) {
|
for (size_t id = 0; id < g_softwareBreakpointManager.numBreakpoints; id++) {
|
||||||
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
SoftwareBreakpoint *bp = &g_softwareBreakpointManager.breakpoints[id];
|
||||||
if (!keepPersistent || !bp->persistent) {
|
if (!keepPersistent || !bp->persistent) {
|
||||||
// TODO: write broadcast for 'revert'
|
revertSoftwareBreakpoint(id);
|
||||||
// Note: no way to handle breakpoint failing to revert on 1+ core but not all, we need to assume operation succeeds
|
// Note: no way to handle breakpoint failing to revert on 1+ core but not all, we need to assume operation succeeds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,19 @@ void initWatchpoints(void)
|
||||||
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void commitAndBroadcastWatchpointHandler(void *p)
|
||||||
|
{
|
||||||
|
(void)p;
|
||||||
|
u64 flags = maskIrq();
|
||||||
|
loadWatchpointRegs(g_combinedWatchpoints, g_watchpointManager.maxWatchpoints);
|
||||||
|
restoreInterruptFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void commitAndBroadcastWatchpoints(void)
|
||||||
|
{
|
||||||
|
executeFunctionOnAllCores(commitAndBroadcastWatchpointHandler, NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
static DebugRegisterPair *findCombinedWatchpoint(u64 addr)
|
static DebugRegisterPair *findCombinedWatchpoint(u64 addr)
|
||||||
{
|
{
|
||||||
addr &= ~7ull;
|
addr &= ~7ull;
|
||||||
|
@ -256,9 +269,9 @@ int addWatchpoint(u64 addr, size_t size, WatchpointLoadStoreControl direction)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
commitAndBroadcastWatchpoints();
|
||||||
|
|
||||||
// TODO: commit and broadcast
|
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -294,9 +307,10 @@ int removeWatchpoint(u64 addr, size_t size, WatchpointLoadStoreControl direction
|
||||||
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
|
||||||
|
|
||||||
// TODO: commit and broadcast
|
commitAndBroadcastWatchpoints();
|
||||||
|
|
||||||
|
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -312,7 +326,7 @@ int removeAllWatchpoints(void)
|
||||||
memset(g_watchpointManager.splitWatchpoints, 0, sizeof(g_watchpointManager.splitWatchpoints));
|
memset(g_watchpointManager.splitWatchpoints, 0, sizeof(g_watchpointManager.splitWatchpoints));
|
||||||
memset(g_combinedWatchpoints, 0, sizeof(g_combinedWatchpoints));
|
memset(g_combinedWatchpoints, 0, sizeof(g_combinedWatchpoints));
|
||||||
|
|
||||||
// TODO: commit and broadcast
|
commitAndBroadcastWatchpoints();
|
||||||
|
|
||||||
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
recursiveSpinlockUnlock(&g_watchpointManager.lock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue