aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>2017-02-17 14:45:00 +0100
committerMatthias Welwarsky <matthias@welwarsky.de>2018-02-21 12:10:02 +0000
commit293fb9b25faf8c89a9d06d73b83526b86d4c14d8 (patch)
treeb1a30e24dbf56dae66f1c8a1ec3337cc8c6fd256
parentd301d8b42f0bfe67d76d6f340db6570cc71c876e (diff)
downloadriscv-openocd-293fb9b25faf8c89a9d06d73b83526b86d4c14d8.zip
riscv-openocd-293fb9b25faf8c89a9d06d73b83526b86d4c14d8.tar.gz
riscv-openocd-293fb9b25faf8c89a9d06d73b83526b86d4c14d8.tar.bz2
rtos: facilitate RTOS SMP handling
The RTOS handlers present OS threads to gdb but the openocd target layer only knows about CPU cores (hardware threads). This patch allows closing this gap inside the RTOS handler. The default implementation just returns the current core, but a RTOS handler can provide its own function that associates a an OS thread with a core. Change-Id: I12cafe50b38a38b28057bc5d3a708aa20bf60515 Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com> Reviewed-on: http://openocd.zylin.com/3997 Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de> Tested-by: jenkins
-rw-r--r--src/rtos/rtos.c10
-rw-r--r--src/rtos/rtos.h1
-rw-r--r--src/server/gdb_server.c14
3 files changed, 23 insertions, 2 deletions
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index 84ee498..4552a87 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -57,6 +57,15 @@ int rtos_smp_init(struct target *target)
return ERROR_TARGET_INIT_FAILED;
}
+static int rtos_target_for_threadid(struct connection *connection, int64_t threadid, struct target **t)
+{
+ struct target *curr = get_target_from_connection(connection);
+ if (t)
+ *t = curr;
+
+ return ERROR_OK;
+}
+
static int os_alloc(struct target *target, struct rtos_type *ostype)
{
struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos));
@@ -72,6 +81,7 @@ static int os_alloc(struct target *target, struct rtos_type *ostype)
/* RTOS drivers can override the packet handler in _create(). */
os->gdb_thread_packet = rtos_thread_packet;
+ os->gdb_target_for_threadid = rtos_target_for_threadid;
return JIM_OK;
}
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
index 87aa502..9978b34 100644
--- a/src/rtos/rtos.h
+++ b/src/rtos/rtos.h
@@ -54,6 +54,7 @@ struct rtos {
struct thread_detail *thread_details;
int thread_count;
int (*gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size);
+ int (*gdb_target_for_threadid)(struct connection *connection, int64_t thread_id, struct target **p_target);
void *rtos_specific_params;
};
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index d866fc6..42ac8a5 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -764,8 +764,12 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio
current_thread[0] = '\0';
if (target->rtos != NULL) {
- snprintf(current_thread, sizeof(current_thread), "thread:%016" PRIx64 ";", target->rtos->current_thread);
+ struct target *ct;
+ snprintf(current_thread, sizeof(current_thread), "thread:%016" PRIx64 ";",
+ target->rtos->current_thread);
target->rtos->current_threadid = target->rtos->current_thread;
+ target->rtos->gdb_target_for_threadid(connection, target->rtos->current_threadid, &ct);
+ signal_var = gdb_last_signal(ct);
}
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s%s",
@@ -2614,6 +2618,9 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
parse = endp;
}
+ if (target->rtos != NULL)
+ target->rtos->gdb_target_for_threadid(connection, thread_id, &ct);
+
if (parse[0] == ';') {
++parse;
--packet_size;
@@ -3108,7 +3115,10 @@ static int gdb_input_inner(struct connection *connection)
if (gdb_con->ctrl_c) {
if (target->state == TARGET_RUNNING) {
- retval = target_halt(target);
+ struct target *t = target;
+ if (target->rtos)
+ target->rtos->gdb_target_for_threadid(connection, target->rtos->current_threadid, &t);
+ retval = target_halt(t);
if (retval != ERROR_OK)
target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
gdb_con->ctrl_c = 0;