rtos : smp support
[fw/openocd] / src / rtos / rtos.c
index ac7f89c7f14ed1c28b9c8820c2ed5f4f902e4e22..815025704df1168d6880027c185a628f5ea3f01b 100644 (file)
@@ -29,7 +29,6 @@
 #include "server/gdb_server.h"
 
 
-static int64_t current_threadid = -1;
 
 static void hex_to_str( char* dst, char * hex_src );
 static int str_to_hex( char* hex_dst, char* src );
@@ -48,12 +47,20 @@ static struct rtos_type *rtos_types[] =
        NULL
 };
 
+int rtos_thread_packet(struct connection *connection, char *packet, int packet_size);
+
+int rtos_smp_init(struct target *target)
+{
+       if (target->rtos->type->smp_init)
+               return target->rtos->type->smp_init(target);
+       return ERROR_TARGET_INIT_FAILED;
+}
+
 
 int rtos_create(Jim_GetOptInfo *goi, struct target * target)
 {
        int x;
        char *cp;
-
        if (! goi->isconfigure) {
                if (goi->argc != 0) {
                        if (goi->argc != 0) {
@@ -113,9 +120,12 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target)
        /* Create it */
        target->rtos = calloc(1,sizeof(struct rtos));
        target->rtos->type = rtos_types[x];
+       target->rtos->current_threadid = -1;
        target->rtos->current_thread = 0;
        target->rtos->symbols = NULL;
        target->rtos->target = target;
+       /* put default thread handler in linux usecase it is overloaded*/
+       target->rtos->gdb_thread_packet = rtos_thread_packet;
 
        if ( 0 != strcmp( cp, "auto") )
        {
@@ -125,10 +135,18 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target)
        return JIM_OK;
 }
 
+int gdb_thread_packet(struct connection *connection, char *packet, int packet_size)
+{
+       struct target *target = get_target_from_connection(connection);
+       if (target->rtos == NULL)
+               return rtos_thread_packet(connection, packet, packet_size); /* thread not found*/
+       return target->rtos->gdb_thread_packet(connection, packet, packet_size);
+}
+
 
 
 
-int gdb_thread_packet(struct connection *connection, char *packet, int packet_size)
+int rtos_thread_packet(struct connection *connection, char *packet, int packet_size)
 {
        struct target *target = get_target_from_connection(connection);
 
@@ -413,10 +431,8 @@ int gdb_thread_packet(struct connection *connection, char *packet, int packet_si
        }
        else if ( packet[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
        {
-               if (packet[1] == 'g')
-               {
-                       sscanf(packet, "Hg%16" SCNx64, &current_threadid);
-               }
+               if ((packet[1] == 'g') && (target->rtos != NULL))
+                       sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid);
                gdb_put_packet(connection, "OK", 2);
                return ERROR_OK;
        }
@@ -424,14 +440,15 @@ int gdb_thread_packet(struct connection *connection, char *packet, int packet_si
        return GDB_THREAD_PACKET_NOT_CONSUMED;
 }
 
-int rtos_get_gdb_reg_list(struct connection *connection, struct reg **reg_list[], int *reg_list_size)
+int rtos_get_gdb_reg_list(struct connection *connection)
 {
        struct target *target = get_target_from_connection(connection);
-
-       if ( ( target->rtos != NULL ) &&
-                ( current_threadid != -1 ) &&
-                ( current_threadid != 0 ) &&
-                ( current_threadid != target->rtos->current_thread ) )
+       int64_t current_threadid = target->rtos->current_threadid;
+       if ((target->rtos != NULL) &&
+                (current_threadid != -1) &&
+                (current_threadid != 0) &&
+                ((current_threadid != target->rtos->current_thread) ||
+                (target->smp))) /* in smp several current thread are possible */
        {
                char * hex_reg_list;
                target->rtos->type->get_thread_reg_list( target->rtos, current_threadid, &hex_reg_list );