This is an automated email from Gerrit.

Tim Newsome (t...@sifive.com) just uploaded a new patch set to Gerrit, which 
you can find at http://openocd.zylin.com/5101

-- gerrit

commit 9b7c17f28de1412f8ba6ceedbe689b4ab21395a6
Author: Tim Newsome <t...@sifive.com>
Date:   Mon Apr 8 16:42:48 2019 -0700

    gdb_server, rtos: Numerous hwthread improvements
    
    1. Change hwthread_update_threads() to preserve current_threadid.
    Arguably hwthread_update_threads() should always be a nop after the
    initial call, since the number of threads is static, configured in the
    startup script.
    2. Add get_thread_reg() to rtos. It's used in rtos_get_gdb_reg() to read
    the value of a single register, instead of reading all register values
    by calling get_thread_reg_list().
    3. Add set_reg() to rtos. gdb_server uses this to change a single
    register value for a specific thread.
    4. Add target_get_gdb_reg_list_noread() so it's possible for gdb to get
    a list of registers without attempting to read their contents.
    
    The clang static checker doesn't find any new problems with this change.
    
    Signed-off-by: Tim Newsome <t...@sifive.com>
    Change-Id: I7d040790268cd942ae3b66ec2781b0124f1bde8d

diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index 2d9e42f..4d05d19 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -31,10 +31,13 @@
 static bool hwthread_detect_rtos(struct target *target);
 static int hwthread_create(struct target *target);
 static int hwthread_update_threads(struct rtos *rtos);
+static int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id,
+               uint32_t reg_num, struct rtos_reg *rtos_reg);
 static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
-                                       struct rtos_reg **reg_list, int 
*num_regs);
+               struct rtos_reg **reg_list, int *num_regs);
 static int hwthread_get_symbol_list_to_lookup(symbol_table_elem_t 
*symbol_list[]);
 static int hwthread_smp_init(struct target *target);
+int hwthread_set_reg(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value);
 
 #define HW_THREAD_NAME_STR_SIZE (32)
 
@@ -51,8 +54,10 @@ const struct rtos_type hwthread_rtos = {
        .create = hwthread_create,
        .update_threads = hwthread_update_threads,
        .get_thread_reg_list = hwthread_get_thread_reg_list,
+       .get_thread_reg = hwthread_get_thread_reg,
        .get_symbol_list_to_lookup = hwthread_get_symbol_list_to_lookup,
        .smp_init = hwthread_smp_init,
+       .set_reg = hwthread_set_reg,
 };
 
 struct hwthread_params {
@@ -87,13 +92,10 @@ static int hwthread_update_threads(struct rtos *rtos)
        enum target_debug_reason current_reason = DBG_REASON_UNDEFINED;
 
        if (rtos == NULL)
-               return -1;
+               return ERROR_FAIL;
 
        target = rtos->target;
 
-       /* wipe out previous thread details if any */
-       rtos_free_threadlist(rtos);
-
        /* determine the number of "threads" */
        if (target->smp) {
                for (head = target->head; head != NULL; head = head->next) {
@@ -104,9 +106,16 @@ static int hwthread_update_threads(struct rtos *rtos)
 
                        ++thread_list_size;
                }
+
+               assert(thread_list_size);
        } else
                thread_list_size = 1;
 
+       /* Wipe out previous thread details if any, but preserve threadid. */
+       int64_t current_threadid = rtos->current_threadid;
+       rtos_free_threadlist(rtos);
+       rtos->current_threadid = current_threadid;
+
        /* create space for new thread details */
        rtos->thread_details = malloc(sizeof(struct thread_detail) * 
thread_list_size);
 
@@ -201,64 +210,114 @@ static int hwthread_smp_init(struct target *target)
        return hwthread_update_threads(target->rtos);
 }
 
-static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
-                                       struct rtos_reg **rtos_reg_list, int 
*num_regs)
+static struct target *find_thread(struct target *target, int64_t thread_id)
 {
-       struct target_list *head;
-       struct target *target;
-       struct target *curr;
-       struct reg **reg_list;
-       int retval;
-
-       if (rtos == NULL)
-               return ERROR_FAIL;
-
-       target = rtos->target;
-
        /* Find the thread with that thread_id */
+       if (target == NULL)
+               return NULL;
        if (target->smp) {
-               curr = NULL;
-               for (head = target->head; head != NULL; head = head->next) {
-                       curr = head->target;
-
-                       if (thread_id == threadid_from_target(curr))
-                               break;
+               for (struct target_list *head = target->head; head != NULL; 
head = head->next) {
+                       if (thread_id == threadid_from_target(head->target))
+                               return head->target;
                }
+       } else if (thread_id == threadid_from_target(target)) {
+               return target;
+       }
+       return NULL;
+}
 
-               if (head == NULL)
-                       return ERROR_FAIL;
-       } else {
-               curr = target;
-               if (thread_id != threadid_from_target(curr))
-                       return ERROR_FAIL;
+static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
+               struct rtos_reg **rtos_reg_list, int *rtos_reg_list_size)
+{
+       if (rtos == NULL)
+               return ERROR_FAIL;
 
-       }
+       struct target *target = rtos->target;
+
+       struct target *curr = find_thread(target, thread_id);
+       if (curr == NULL)
+               return ERROR_FAIL;
 
        if (!target_was_examined(curr))
                return ERROR_FAIL;
 
-       retval = target_get_gdb_reg_list(curr, &reg_list, num_regs,
+       struct reg **reg_list;
+       int retval = target_get_gdb_reg_list(curr, &reg_list, 
rtos_reg_list_size,
                        REG_CLASS_GENERAL);
        if (retval != ERROR_OK)
                return retval;
 
-       *rtos_reg_list = calloc(*num_regs, sizeof(struct rtos_reg));
+       *rtos_reg_list = calloc(*rtos_reg_list_size, sizeof(struct rtos_reg));
        if (*rtos_reg_list == NULL) {
                free(reg_list);
                return ERROR_FAIL;
        }
 
-       for (int i = 0; i < *num_regs; i++) {
+       for (int i = 0; i < *rtos_reg_list_size; i++) {
                (*rtos_reg_list)[i].number = (*reg_list)[i].number;
                (*rtos_reg_list)[i].size = (*reg_list)[i].size;
                memcpy((*rtos_reg_list)[i].value, (*reg_list)[i].value,
-                      ((*reg_list)[i].size + 7) / 8);
+                               ((*reg_list)[i].size + 7) / 8);
        }
-
        free(reg_list);
 
        return ERROR_OK;
+}
+
+static int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id,
+               uint32_t reg_num, struct rtos_reg *rtos_reg)
+{
+       if (rtos == NULL)
+               return ERROR_FAIL;
 
+       struct target *target = rtos->target;
+
+       struct target *curr = find_thread(target, thread_id);
+       if (curr == NULL) {
+               LOG_ERROR("Couldn't find RTOS thread for id %" PRId64 ".", 
thread_id);
+               return ERROR_FAIL;
+       }
+
+       if (!target_was_examined(curr)) {
+               LOG_ERROR("Target %d hasn't been examined yet.", curr->coreid);
+               return ERROR_FAIL;
+       }
+
+       struct reg *reg = register_get_by_number(curr->reg_cache, reg_num, 
true);
+       if (!reg) {
+               LOG_ERROR("Couldn't find register %d in thread %" PRId64 ".", 
reg_num,
+                               thread_id);
+               return ERROR_FAIL;
+       }
+
+       if (reg->type->get(reg) != ERROR_OK)
+               return ERROR_FAIL;
+
+       rtos_reg->number = reg->number;
+       rtos_reg->size = reg->size;
+       unsigned bytes = (reg->size + 7) / 8;
+       assert(bytes <= sizeof(rtos_reg->value));
+       memcpy(rtos_reg->value, reg->value, bytes);
+
+       return ERROR_OK;
+}
+
+int hwthread_set_reg(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value)
+{
+       if (rtos == NULL)
+               return ERROR_FAIL;
+
+       struct target *target = rtos->target;
+
+       struct target *curr = find_thread(target, rtos->current_thread);
+       if (curr == NULL)
+               return ERROR_FAIL;
+
+       struct reg *reg = register_get_by_number(curr->reg_cache, reg_num, 
true);
+       if (!reg)
+               return ERROR_FAIL;
+
+       return reg->type->set(reg, reg_value);
 }
 
 static int hwthread_get_symbol_list_to_lookup(symbol_table_elem_t 
*symbol_list[])
@@ -272,26 +331,10 @@ static int 
hwthread_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]
 static int hwthread_target_for_threadid(struct connection *connection, int64_t 
thread_id, struct target **p_target)
 {
        struct target *target = get_target_from_connection(connection);
-       struct target_list *head;
-       struct target *curr;
 
-       if (target->smp) {
-               /* Find the thread with that thread_id */
-               curr = NULL;
-               for (head = target->head; head != NULL; head = head->next) {
-                       curr = head->target;
-
-                       if (thread_id == threadid_from_target(curr))
-                               break;
-               }
-
-               if (head == NULL)
-                       return ERROR_FAIL;
-       } else {
-               curr = target;
-               if (thread_id != threadid_from_target(curr))
-                       return ERROR_FAIL;
-       }
+       struct target *curr = find_thread(target, thread_id);
+       if (curr == NULL)
+               return ERROR_FAIL;
 
        *p_target = curr;
 
@@ -312,6 +355,7 @@ static int hwthread_thread_packet(struct connection 
*connection, const char *pac
        int64_t current_threadid;
 
        if (packet[0] == 'H' && packet[1] == 'g') {
+               /* Never reached, because this case is handled by 
rtos_thread_packet(). */
                sscanf(packet, "Hg%16" SCNx64, &current_threadid);
 
                if (current_threadid > 0) {
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index da0a503..4dcc54f 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -462,6 +462,7 @@ static int rtos_put_gdb_reg_list(struct connection 
*connection,
        return ERROR_OK;
 }
 
+/** Look through all registers to find this register. */
 int rtos_get_gdb_reg(struct connection *connection, int reg_num)
 {
        struct target *target = get_target_from_connection(connection);
@@ -473,19 +474,31 @@ int rtos_get_gdb_reg(struct connection *connection, int 
reg_num)
                struct rtos_reg *reg_list;
                int num_regs;
 
-               LOG_DEBUG("RTOS: getting register %d for thread 0x%" PRIx64
-                                 ", target->rtos->current_thread=0x%" PRIx64 
"\r\n",
+               LOG_DEBUG("getting register %d for thread 0x%" PRIx64
+                                 ", target->rtos->current_thread=0x%" PRIx64,
                                                                                
reg_num,
                                                                                
current_threadid,
                                                                                
target->rtos->current_thread);
 
-               int retval = 
target->rtos->type->get_thread_reg_list(target->rtos,
-                               current_threadid,
-                               &reg_list,
-                               &num_regs);
-               if (retval != ERROR_OK) {
-                       LOG_ERROR("RTOS: failed to get register list");
-                       return retval;
+               int retval;
+               if (target->rtos->type->get_thread_reg) {
+                       reg_list = calloc(1, sizeof(*reg_list));
+                       num_regs = 1;
+                       retval = 
target->rtos->type->get_thread_reg(target->rtos,
+                                       current_threadid, reg_num, 
&reg_list[0]);
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR("RTOS: failed to get register %d", 
reg_num);
+                               return retval;
+                       }
+               } else {
+                       retval = 
target->rtos->type->get_thread_reg_list(target->rtos,
+                                       current_threadid,
+                                       &reg_list,
+                                       &num_regs);
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR("RTOS: failed to get register list");
+                               return retval;
+                       }
                }
 
                for (int i = 0; i < num_regs; ++i) {
@@ -501,6 +514,7 @@ int rtos_get_gdb_reg(struct connection *connection, int 
reg_num)
        return ERROR_FAIL;
 }
 
+/** Return a list of general registers. */
 int rtos_get_gdb_reg_list(struct connection *connection)
 {
        struct target *target = get_target_from_connection(connection);
@@ -534,6 +548,20 @@ int rtos_get_gdb_reg_list(struct connection *connection)
        return ERROR_FAIL;
 }
 
+int rtos_set_reg(struct connection *connection, int reg_num,
+               uint8_t *reg_value)
+{
+       struct target *target = get_target_from_connection(connection);
+       int64_t current_threadid = target->rtos->current_threadid;
+       if ((target->rtos != NULL) &&
+                       (target->rtos->type->set_reg != NULL) &&
+                       (current_threadid != -1) &&
+                       (current_threadid != 0)) {
+               return target->rtos->type->set_reg(target->rtos, reg_num, 
reg_value);
+       }
+       return ERROR_FAIL;
+}
+
 int rtos_generic_stack_read(struct target *target,
        const struct rtos_register_stacking *stacking,
        int64_t stack_ptr,
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
index b346047..517b321 100644
--- a/src/rtos/rtos.h
+++ b/src/rtos/rtos.h
@@ -20,6 +20,7 @@
 #define OPENOCD_RTOS_RTOS_H
 
 #include "server/server.h"
+#include "target/target.h"
 #include <jim-nvp.h>
 
 typedef int64_t threadid_t;
@@ -49,7 +50,9 @@ struct rtos {
        symbol_table_elem_t *symbols;
        struct target *target;
        /*  add a context variable instead of global variable */
+       /* The thread currently selected by gdb. */
        int64_t current_threadid;
+       /* The currently selected thread according to the target. */
        threadid_t current_thread;
        struct thread_detail *thread_details;
        int thread_count;
@@ -70,11 +73,15 @@ struct rtos_type {
        int (*create)(struct target *target);
        int (*smp_init)(struct target *target);
        int (*update_threads)(struct rtos *rtos);
+       /** Return a list of general registers, with their values filled out. */
        int (*get_thread_reg_list)(struct rtos *rtos, int64_t thread_id,
                        struct rtos_reg **reg_list, int *num_regs);
+       int (*get_thread_reg)(struct rtos *rtos, int64_t thread_id,
+                       uint32_t reg_num, struct rtos_reg *reg);
        int (*get_symbol_list_to_lookup)(symbol_table_elem_t *symbol_list[]);
        int (*clean)(struct target *target);
        char * (*ps_command)(struct target *target);
+       int (*set_reg)(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value);
 };
 
 struct stack_register_offset {
@@ -104,6 +111,8 @@ struct rtos_register_stacking {
 #define GDB_THREAD_PACKET_NOT_CONSUMED (-40)
 
 int rtos_create(Jim_GetOptInfo *goi, struct target *target);
+int rtos_set_reg(struct connection *connection, int reg_num,
+               uint8_t *reg_value);
 int rtos_generic_stack_read(struct target *target,
                const struct rtos_register_stacking *stacking,
                int64_t stack_ptr,
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 95e6c04..dc912c9 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -724,7 +724,7 @@ static int gdb_output(struct command_context *context, 
const char *line)
 static void gdb_signal_reply(struct target *target, struct connection 
*connection)
 {
        struct gdb_connection *gdb_connection = connection->priv;
-       char sig_reply[45];
+       char sig_reply[65];
        char stop_reason[20];
        char current_thread[25];
        int sig_reply_len;
@@ -735,17 +735,25 @@ static void gdb_signal_reply(struct target *target, 
struct connection *connectio
        if (target->debug_reason == DBG_REASON_EXIT) {
                sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "W00");
        } else {
+               struct target *ct;
+               if (target->rtos != NULL) {
+                       target->rtos->current_threadid = 
target->rtos->current_thread;
+                       target->rtos->gdb_target_for_threadid(connection, 
target->rtos->current_threadid, &ct);
+               } else {
+                       ct = target;
+               }
+
                if (gdb_connection->ctrl_c) {
                        signal_var = 0x2;
                } else
-                       signal_var = gdb_last_signal(target);
+                       signal_var = gdb_last_signal(ct);
 
                stop_reason[0] = '\0';
-               if (target->debug_reason == DBG_REASON_WATCHPOINT) {
+               if (ct->debug_reason == DBG_REASON_WATCHPOINT) {
                        enum watchpoint_rw hit_wp_type;
                        target_addr_t hit_wp_address;
 
-                       if (watchpoint_hit(target, &hit_wp_type, 
&hit_wp_address) == ERROR_OK) {
+                       if (watchpoint_hit(ct, &hit_wp_type, &hit_wp_address) 
== ERROR_OK) {
 
                                switch (hit_wp_type) {
                                        case WPT_WRITE:
@@ -767,15 +775,9 @@ static void gdb_signal_reply(struct target *target, struct 
connection *connectio
                }
 
                current_thread[0] = '\0';
-               if (target->rtos != NULL) {
-                       struct target *ct;
-                       snprintf(current_thread, sizeof(current_thread), 
"thread:%016" PRIx64 ";",
+               if (target->rtos != NULL)
+                       snprintf(current_thread, sizeof(current_thread), 
"thread:%" 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);
-                       if (!gdb_connection->ctrl_c)
-                               signal_var = gdb_last_signal(ct);
-               }
 
                sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), 
"T%2.2x%s%s",
                                signal_var, stop_reason, current_thread);
@@ -1306,7 +1308,7 @@ static int gdb_get_register_packet(struct connection 
*connection,
        if ((target->rtos != NULL) && (ERROR_OK == rtos_get_gdb_reg(connection, 
reg_num)))
                return ERROR_OK;
 
-       retval = target_get_gdb_reg_list(target, &reg_list, &reg_list_size,
+       retval = target_get_gdb_reg_list_noread(target, &reg_list, 
&reg_list_size,
                        REG_CLASS_ALL);
        if (retval != ERROR_OK)
                return gdb_error(connection, retval);
@@ -1342,37 +1344,49 @@ static int gdb_set_register_packet(struct connection 
*connection,
 {
        struct target *target = get_target_from_connection(connection);
        char *separator;
-       uint8_t *bin_buf;
        int reg_num = strtoul(packet + 1, &separator, 16);
        struct reg **reg_list;
        int reg_list_size;
        int retval;
 
+#ifdef _DEBUG_GDB_IO_
        LOG_DEBUG("-");
+#endif
 
-       retval = target_get_gdb_reg_list(target, &reg_list, &reg_list_size,
+       if (*separator != '=') {
+               LOG_ERROR("GDB 'set register packet', but no '=' following the 
register number");
+               return ERROR_SERVER_REMOTE_CLOSED;
+       }
+       size_t chars = strlen(separator + 1);
+       uint8_t *bin_buf = malloc(chars / 2);
+       gdb_target_to_reg(target, separator + 1, chars, bin_buf);
+
+       if ((target->rtos != NULL) &&
+                       (ERROR_OK == rtos_set_reg(connection, reg_num, 
bin_buf))) {
+               free(bin_buf);
+               gdb_put_packet(connection, "OK", 2);
+               return ERROR_OK;
+       }
+
+       retval = target_get_gdb_reg_list_noread(target, &reg_list, 
&reg_list_size,
                        REG_CLASS_ALL);
-       if (retval != ERROR_OK)
+       if (retval != ERROR_OK) {
+               free(bin_buf);
                return gdb_error(connection, retval);
+       }
 
        if (reg_list_size <= reg_num) {
                LOG_ERROR("gdb requested a non-existing register");
+               free(bin_buf);
+               free(reg_list);
                return ERROR_SERVER_REMOTE_CLOSED;
        }
 
-       if (*separator != '=') {
-               LOG_ERROR("GDB 'set register packet', but no '=' following the 
register number");
-               return ERROR_SERVER_REMOTE_CLOSED;
-       }
-
-       /* convert from GDB-string (target-endian) to hex-string (big-endian) */
-       bin_buf = malloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8));
-       int chars = (DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2);
-
-       if ((unsigned int)chars != strlen(separator + 1)) {
-               LOG_ERROR("gdb sent %zu bits for a %d-bit register (%s)",
-                               strlen(separator + 1) * 4, chars * 4, 
reg_list[reg_num]->name);
+       if (chars != (DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2)) {
+               LOG_ERROR("gdb sent %d bits for a %d-bit register (%s)",
+                               (int) chars * 4, reg_list[reg_num]->size, 
reg_list[reg_num]->name);
                free(bin_buf);
+               free(reg_list);
                return ERROR_SERVER_REMOTE_CLOSED;
        }
 
@@ -1642,7 +1656,7 @@ static int gdb_breakpoint_watchpoint_packet(struct 
connection *connection,
        char *separator;
        int retval;
 
-       LOG_DEBUG("-");
+       LOG_DEBUG("[%d]", target->coreid);
 
        type = strtoul(packet + 1, &separator, 16);
 
@@ -2208,7 +2222,7 @@ static int gdb_generate_target_description(struct target 
*target, char **tdesc_o
 
        arch_defined_types = calloc(1, sizeof(char *));
 
-       retval = target_get_gdb_reg_list(target, &reg_list,
+       retval = target_get_gdb_reg_list_noread(target, &reg_list,
                        &reg_list_size, REG_CLASS_ALL);
 
        if (retval != ERROR_OK) {
@@ -2396,10 +2410,11 @@ static int gdb_target_description_supported(struct 
target *target, int *supporte
 
        char const *architecture = target_get_gdb_arch(target);
 
-       retval = target_get_gdb_reg_list(target, &reg_list,
+       retval = target_get_gdb_reg_list_noread(target, &reg_list,
                        &reg_list_size, REG_CLASS_ALL);
        if (retval != ERROR_OK) {
                LOG_ERROR("get register list failed");
+               reg_list = NULL;
                goto error;
        }
 
@@ -2791,13 +2806,11 @@ static bool gdb_handle_vcont_packet(struct connection 
*connection, const char *p
 
                                if (parse[0] == 'c') {
                                        parse += 1;
-                                       packet_size -= 1;
 
                                        /* check if thread-id follows */
                                        if (parse[0] == ':') {
                                                int64_t tid;
                                                parse += 1;
-                                               packet_size -= 1;
 
                                                tid = strtoll(parse, &endp, 16);
                                                if (tid == thread_id) {
@@ -2887,10 +2900,9 @@ static int gdb_v_packet(struct connection *connection,
                char const *packet, int packet_size)
 {
        struct gdb_connection *gdb_connection = connection->priv;
-       struct target *target;
        int result;
 
-       target = get_target_from_connection(connection);
+       struct target *target = get_target_from_connection(connection);
 
        if (strncmp(packet, "vCont", 5) == 0) {
                bool handled;
diff --git a/src/target/register.c b/src/target/register.c
index 5352d2f..4ddda6e 100644
--- a/src/target/register.c
+++ b/src/target/register.c
@@ -36,6 +36,29 @@
  * may be separate registers associated with debug or trace modules.
  */
 
+struct reg *register_get_by_number(struct reg_cache *first,
+               uint32_t reg_num, bool search_all)
+{
+       unsigned i;
+       struct reg_cache *cache = first;
+
+       while (cache) {
+               for (i = 0; i < cache->num_regs; i++) {
+                       if (cache->reg_list[i].exist == false)
+                               continue;
+                       if (cache->reg_list[i].number == reg_num)
+                               return &(cache->reg_list[i]);
+               }
+
+               if (search_all)
+                       cache = cache->next;
+               else
+                       break;
+       }
+
+       return NULL;
+}
+
 struct reg *register_get_by_name(struct reg_cache *first,
                const char *name, bool search_all)
 {
diff --git a/src/target/register.h b/src/target/register.h
index 32c1f39..7c53d6e 100644
--- a/src/target/register.h
+++ b/src/target/register.h
@@ -159,6 +159,8 @@ struct reg_arch_type {
        int (*set)(struct reg *reg, uint8_t *buf);
 };
 
+struct reg *register_get_by_number(struct reg_cache *first,
+               uint32_t reg_num, bool search_all);
 struct reg *register_get_by_name(struct reg_cache *first,
                const char *name, bool search_all);
 struct reg_cache **register_get_last_cache_p(struct reg_cache **first);
diff --git a/src/target/target.c b/src/target/target.c
index 380a9fc..0af8dd2 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1224,6 +1224,17 @@ int target_get_gdb_reg_list(struct target *target,
        return target->type->get_gdb_reg_list(target, reg_list, reg_list_size, 
reg_class);
 }
 
+int target_get_gdb_reg_list_noread(struct target *target,
+               struct reg **reg_list[], int *reg_list_size,
+               enum target_register_class reg_class)
+{
+       if (target->type->get_gdb_reg_list_noread &&
+                       target->type->get_gdb_reg_list_noread(target, reg_list,
+                               reg_list_size, reg_class) == ERROR_OK)
+               return ERROR_OK;
+       return target_get_gdb_reg_list(target, reg_list, reg_list_size, 
reg_class);
+}
+
 bool target_supports_gdb_connection(struct target *target)
 {
        /*
@@ -1593,8 +1604,9 @@ int target_call_event_callbacks(struct target *target, 
enum target_event event)
                target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
        }
 
-       LOG_DEBUG("target event %i (%s)", event,
-                       Jim_Nvp_value2name_simple(nvp_target_event, 
event)->name);
+       LOG_DEBUG("target event %i (%s) for core %d", event,
+                       Jim_Nvp_value2name_simple(nvp_target_event, 
event)->name,
+                       target->coreid);
 
        target_handle_event(target, event);
 
diff --git a/src/target/target.h b/src/target/target.h
index 65494af..8dde03d 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -502,6 +502,16 @@ int target_get_gdb_reg_list(struct target *target,
                enum target_register_class reg_class);
 
 /**
+ * Obtain the registers for GDB, but don't read register values from the
+ * target.
+ *
+ * This routine is a wrapper for target->type->get_gdb_reg_list_noread.
+ */
+int target_get_gdb_reg_list_noread(struct target *target,
+               struct reg **reg_list[], int *reg_list_size,
+               enum target_register_class reg_class);
+
+/**
  * Check if @a target allows GDB connections.
  *
  * Some target do not implement the necessary code required by GDB.
diff --git a/src/target/target_type.h b/src/target/target_type.h
index 95745c9..4bdea72 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -111,6 +111,13 @@ struct target_type {
        int (*get_gdb_reg_list)(struct target *target, struct reg **reg_list[],
                        int *reg_list_size, enum target_register_class 
reg_class);
 
+       /**
+        * Same as get_gdb_reg_list, but doesn't read the register values.
+        * */
+       int (*get_gdb_reg_list_noread)(struct target *target,
+                       struct reg **reg_list[], int *reg_list_size,
+                       enum target_register_class reg_class);
+
        /* target memory access
        * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
        * count: number of items of <size>

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to