register: support non-existent registers
This patch fixes a number of bugs caused by incomplete support for non-existent registers. This is needed for targets that provide optional registers or non-linear register numbers. Change-Id: I216196e0051f28887a2c3da410959382369eed80 Signed-off-by: Steven Stallion <stallion@squareup.com> Reviewed-on: http://openocd.zylin.com/4113 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>bscan_tunnel
parent
06589d2de4
commit
b5964191f0
|
@ -1179,8 +1179,11 @@ static int gdb_get_registers_packet(struct connection *connection,
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return gdb_error(connection, retval);
|
return gdb_error(connection, retval);
|
||||||
|
|
||||||
for (i = 0; i < reg_list_size; i++)
|
for (i = 0; i < reg_list_size; i++) {
|
||||||
|
if (reg_list[i] == NULL || reg_list[i]->exist == false)
|
||||||
|
continue;
|
||||||
reg_packet_size += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;
|
reg_packet_size += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
assert(reg_packet_size > 0);
|
assert(reg_packet_size > 0);
|
||||||
|
|
||||||
|
@ -1191,6 +1194,8 @@ static int gdb_get_registers_packet(struct connection *connection,
|
||||||
reg_packet_p = reg_packet;
|
reg_packet_p = reg_packet;
|
||||||
|
|
||||||
for (i = 0; i < reg_list_size; i++) {
|
for (i = 0; i < reg_list_size; i++) {
|
||||||
|
if (reg_list[i] == NULL || reg_list[i]->exist == false)
|
||||||
|
continue;
|
||||||
if (!reg_list[i]->valid) {
|
if (!reg_list[i]->valid) {
|
||||||
retval = reg_list[i]->type->get(reg_list[i]);
|
retval = reg_list[i]->type->get(reg_list[i]);
|
||||||
if (retval != ERROR_OK && gdb_report_register_access_error) {
|
if (retval != ERROR_OK && gdb_report_register_access_error) {
|
||||||
|
|
|
@ -44,6 +44,8 @@ struct reg *register_get_by_name(struct reg_cache *first,
|
||||||
|
|
||||||
while (cache) {
|
while (cache) {
|
||||||
for (i = 0; i < cache->num_regs; i++) {
|
for (i = 0; i < cache->num_regs; i++) {
|
||||||
|
if (cache->reg_list[i].exist == false)
|
||||||
|
continue;
|
||||||
if (strcmp(cache->reg_list[i].name, name) == 0)
|
if (strcmp(cache->reg_list[i].name, name) == 0)
|
||||||
return &(cache->reg_list[i]);
|
return &(cache->reg_list[i]);
|
||||||
}
|
}
|
||||||
|
@ -84,6 +86,8 @@ void register_cache_invalidate(struct reg_cache *cache)
|
||||||
struct reg *reg = cache->reg_list;
|
struct reg *reg = cache->reg_list;
|
||||||
|
|
||||||
for (unsigned n = cache->num_regs; n != 0; n--, reg++) {
|
for (unsigned n = cache->num_regs; n != 0; n--, reg++) {
|
||||||
|
if (reg->exist == false)
|
||||||
|
continue;
|
||||||
reg->valid = 0;
|
reg->valid = 0;
|
||||||
reg->dirty = 0;
|
reg->dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2804,6 +2804,8 @@ COMMAND_HANDLER(handle_reg_command)
|
||||||
for (i = 0, reg = cache->reg_list;
|
for (i = 0, reg = cache->reg_list;
|
||||||
i < cache->num_regs;
|
i < cache->num_regs;
|
||||||
i++, reg++, count++) {
|
i++, reg++, count++) {
|
||||||
|
if (reg->exist == false)
|
||||||
|
continue;
|
||||||
/* only print cached values if they are valid */
|
/* only print cached values if they are valid */
|
||||||
if (reg->valid) {
|
if (reg->valid) {
|
||||||
value = buf_to_str(reg->value,
|
value = buf_to_str(reg->value,
|
||||||
|
@ -2857,14 +2859,15 @@ COMMAND_HANDLER(handle_reg_command)
|
||||||
/* access a single register by its name */
|
/* access a single register by its name */
|
||||||
reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], 1);
|
reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], 1);
|
||||||
|
|
||||||
if (!reg) {
|
if (!reg)
|
||||||
command_print(CMD_CTX, "register %s not found in current target", CMD_ARGV[0]);
|
goto not_found;
|
||||||
return ERROR_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(reg != NULL); /* give clang a hint that we *know* reg is != NULL here */
|
assert(reg != NULL); /* give clang a hint that we *know* reg is != NULL here */
|
||||||
|
|
||||||
|
if (!reg->exist)
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
/* display a register */
|
/* display a register */
|
||||||
if ((CMD_ARGC == 1) || ((CMD_ARGC == 2) && !((CMD_ARGV[1][0] >= '0')
|
if ((CMD_ARGC == 1) || ((CMD_ARGC == 2) && !((CMD_ARGV[1][0] >= '0')
|
||||||
&& (CMD_ARGV[1][0] <= '9')))) {
|
&& (CMD_ARGV[1][0] <= '9')))) {
|
||||||
|
@ -2898,6 +2901,10 @@ COMMAND_HANDLER(handle_reg_command)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
command_print(CMD_CTX, "register %s not found in current target", CMD_ARGV[0]);
|
||||||
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(handle_poll_command)
|
COMMAND_HANDLER(handle_poll_command)
|
||||||
|
|
Loading…
Reference in New Issue