Skip to content

Commit

Permalink
break from long loops on shutdown request
Browse files Browse the repository at this point in the history
In loops that typically take longer time to complete, check if there is
a pending shutdown request. If so, terminate the loop.

This allows to respond to a signal requesting a shutdown during some
loops which do not return control to main OpenOCD loop.

Change-Id: Iace0b58eddde1237832d0f9333a7c7b930565674
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
  • Loading branch information
en-sc committed Jan 9, 2024
1 parent 6a61446 commit 8dbb125
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/server/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,6 @@ COMMAND_HELPER(server_port_command, unsigned short *out);

#define ERROR_SERVER_REMOTE_CLOSED (-400)
#define ERROR_CONNECTION_REJECTED (-401)
#define ERROR_SERVER_INTERRUPTED (-402)

#endif /* OPENOCD_SERVER_SERVER_H */
3 changes: 3 additions & 0 deletions src/target/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "image.h"
#include "target.h"
#include <helper/log.h>
#include <server/server.h>

/* convert ELF header field to host endianness */
#define field16(elf, field) \
Expand Down Expand Up @@ -1295,6 +1296,8 @@ int image_calculate_checksum(const uint8_t *buffer, uint32_t nbytes, uint32_t *c
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
}
keep_alive();
if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;
}

LOG_DEBUG("Calculating checksum done; checksum=0x%" PRIx32, crc);
Expand Down
3 changes: 3 additions & 0 deletions src/target/riscv/batch.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ int riscv_batch_run(struct riscv_batch *batch)

keep_alive();

if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;

if (bscan_tunnel_ir_width != 0) {
/* need to right-shift "in" by one bit, because of clock skew between BSCAN TAP and DM TAP */
for (size_t i = 0; i < batch->used_scans; ++i) {
Expand Down
3 changes: 3 additions & 0 deletions src/target/riscv/program.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
{
keep_alive();

if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;

p->execution_result = RISCV_PROGBUF_EXEC_RESULT_UNKNOWN;
riscv_reg_t saved_registers[GDB_REGNO_XPR31 + 1];
for (size_t i = GDB_REGNO_ZERO + 1; i <= GDB_REGNO_XPR31; ++i) {
Expand Down
6 changes: 6 additions & 0 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,9 @@ static int dmi_op_timeout(struct target *target, uint32_t *data_in,

keep_alive();

if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;

time_t start = time(NULL);
/* This first loop performs the request. Note that if for some reason this
* stays busy, it is actually due to the previous access. */
Expand Down Expand Up @@ -3241,6 +3244,9 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
return ERROR_FAIL;
}
keep_alive();
if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;

dmi_status_t status = dmi_scan(target, NULL, &sbvalue[next_read_j],
DMI_OP_READ, sbdata[j], 0, false);
/* By reading from sbdata0, we have just initiated another system bus read.
Expand Down
6 changes: 6 additions & 0 deletions src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -5141,6 +5141,9 @@ static int riscv_set_or_write_register(struct target *target,

keep_alive();

if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;

if (regid == GDB_REGNO_PC) {
return riscv_set_or_write_register(target, GDB_REGNO_DPC, value, write_through);
} else if (regid == GDB_REGNO_PRIV) {
Expand Down Expand Up @@ -5238,6 +5241,9 @@ int riscv_get_register(struct target *target, riscv_reg_t *value,

keep_alive();

if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;

if (regid == GDB_REGNO_PC) {
return riscv_get_register(target, value, GDB_REGNO_DPC);
} else if (regid == GDB_REGNO_PRIV) {
Expand Down
20 changes: 19 additions & 1 deletion src/target/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,10 @@ int target_run_read_async_algorithm(struct target *target,
/* Avoid GDB timeouts */
keep_alive();

if (openocd_is_shutdown_pending()) {
retval = ERROR_SERVER_INTERRUPTED;
break;
}
}

if (retval != ERROR_OK) {
Expand Down Expand Up @@ -3225,8 +3229,11 @@ int target_wait_state(struct target *target, enum target_state state, unsigned i
nvp_value2name(nvp_target_state, state)->name);
}

if (cur-then > 500)
if (cur - then > 500) {
keep_alive();
if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;
}

if ((cur-then) > ms) {
LOG_ERROR("timed out while waiting for target %s",
Expand Down Expand Up @@ -3509,6 +3516,11 @@ static int target_fill_mem(struct target *target,
break;
/* avoid GDB timeouts */
keep_alive();

if (openocd_is_shutdown_pending()) {
retval = ERROR_SERVER_INTERRUPTED;
break;
}
}
free(target_buf);

Expand Down Expand Up @@ -3851,6 +3863,12 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver
}
}
keep_alive();
if (openocd_is_shutdown_pending()) {
retval = ERROR_SERVER_INTERRUPTED;
free(data);
free(buffer);
goto done;
}
}
}
free(data);
Expand Down

0 comments on commit 8dbb125

Please sign in to comment.