m3dev

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 2af38d26b65b706ba19a2023681eda7430ad973f
parent 282fc014ab0b315a89563883334d9d164c4bf220
Author: Brian Swetland <swetland@frotz.net>
Date:   Mon, 13 Jul 2015 18:19:13 -0700

lkdebug: provide "threads clear" to nuke thread state

Useful for calling after a target reset to ensure there's no stale
thread list data to confuse things before the kernel creates threads
in the new session.

Diffstat:
Mtools/debugger-commands.c | 9+++++++++
Mtools/lkdebug.c | 46++++++++++++++++++++++++++++++----------------
Mtools/lkdebug.h | 5+++++
3 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/tools/debugger-commands.c b/tools/debugger-commands.c @@ -762,6 +762,15 @@ int do_maskints(int argc, param *argv) { } int do_threads(int argc, param *argv) { + if (argc == 1) { + if (strcmp(argv[0].s, "clear")) { + xprintf("usage: threads [clear]\n"); + return -1; + } + swdp_core_halt(); + clear_lk_threads(); + return 0; + } lkthread_t *t; swdp_core_halt(); t = find_lk_threads(1); diff --git a/tools/lkdebug.c b/tools/lkdebug.c @@ -141,32 +141,46 @@ void free_lk_threads(lkthread_t *list) { } } -lkthread_t *find_lk_threads(int verbose) { - lkdebuginfo_t di; - lkthread_t *list = NULL; - lkthread_t *current = NULL; - lkthread_t *t; +static int load_debuginfo(lkdebuginfo_t *di, int verbose) { u32 x; - u32 rtp; - if (swdp_ahb_read(DI_OFF_MAGIC, &x)) goto fail; + if (swdp_ahb_read(DI_OFF_MAGIC, &x)) return -1; if (x != DI_MAGIC) { if (verbose) xprintf("debuginfo: bad magic\n"); - goto fail; + return -1; } - if (swdp_ahb_read(DI_OFF_PTR, &x)) goto fail; - if (x & 3) goto fail; + if (swdp_ahb_read(DI_OFF_PTR, &x)) return -1; + if (x & 3) return -1; if (verbose) xprintf("debuginfo @ %08x\n", x); - if (swdp_ahb_read32(x, (void*) &di, sizeof(di) / 4)) goto fail; + if (swdp_ahb_read32(x, (void*) di, sizeof(lkdebuginfo_t) / 4)) return -1; if (verbose) { xprintf("di %08x %08x %08x %d %d %d %d %d %d\n", - di.version, di.thread_list_ptr, di.current_thread_ptr, - di.off_list_node, di.off_state, di.off_saved_sp, - di.off_was_preempted, di.off_name, di.off_waitq); + di->version, di->thread_list_ptr, di->current_thread_ptr, + di->off_list_node, di->off_state, di->off_saved_sp, + di->off_was_preempted, di->off_name, di->off_waitq); } - if (di.version != 0x0100) { + if (di->version != 0x0100) { if (verbose) xprintf("debuginfo: unsupported version\n"); - goto fail; + return -1; } + return 0; +} + +void clear_lk_threads(void) { + lkdebuginfo_t di; + if (load_debuginfo(&di, 0)) return; + swdp_ahb_write(di.current_thread_ptr, 0xffffffff); + swdp_ahb_write(di.thread_list_ptr + 0, 0xffffffff); + swdp_ahb_write(di.thread_list_ptr + 4, 0xffffffff); +} + +lkthread_t *find_lk_threads(int verbose) { + lkdebuginfo_t di; + lkthread_t *list = NULL; + lkthread_t *current = NULL; + lkthread_t *t; + u32 x; + u32 rtp; + if (load_debuginfo(&di, verbose)) goto fail; if (swdp_ahb_read(di.current_thread_ptr, &x)) goto fail; current = read_lk_thread(&di, x, 1); if (current == NULL) goto fail; diff --git a/tools/lkdebug.h b/tools/lkdebug.h @@ -40,4 +40,9 @@ void free_lk_threads(lkthread_t *list); lkthread_t *find_lk_thread(lkthread_t *list, u32 tptr); void get_lk_thread_name(lkthread_t *t, char *out, size_t max); +// Invalidate current thread and threadlist +// Intended for use after target reset, etc. +// Will corrupt a running image. +void clear_lk_threads(void); + #endif