rtos: facilitate RTOS SMP handling
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>
Fri, 17 Feb 2017 13:45:00 +0000 (14:45 +0100)
committerMatthias Welwarsky <matthias@welwarsky.de>
Wed, 21 Feb 2018 12:10:02 +0000 (12:10 +0000)
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
src/rtos/rtos.c
src/rtos/rtos.h
src/server/gdb_server.c

index 84ee498beaa1af2b0ca19b5ae656bda04f6d00eb..4552a87d150c353388cfc888d3040fb8d8cbb5e5 100644 (file)
@@ -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;
 }
index 87aa5027d231ecb3f9260047796752e115e74dce..9978b34ff279734194afc8ec324548c4cd09de07 100644 (file)
@@ -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;
 };
 
index d866fc6e2a4641167875f2294e4aae2bcd2cb980..42ac8a5e2e7a2bfea4798a4109049651fb8796ad 100644 (file)
@@ -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;