This is an automated email from Gerrit. "Kirill Radkin <kirill.rad...@syntacore.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7827
-- gerrit commit b807b4d09cd2cb857476eb6cfa9ca6d6d2efd107 Author: Kirill Radkin <kirill.rad...@syntacore.com> Date: Tue Jul 25 14:09:20 2023 +0300 target: OpenOCD fails with assert during running "reset" command OpenOCD fails in the presence of inactive/unresponsive cores I faced with case when inactive core returns 0 while reading dtmcontrol. This leads to failure on assert: "addrbits != 0" in "dbus_scan". Also change "read_bits","poll_target" funcs to avoid a lot lines in logs Change-Id: If852126755317789602b7372c5c5732183fff6c5 Signed-off-by: Kirill Radkin <kirill.rad...@syntacore.com> diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index be296cdd8c..057f1a16ae 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -432,7 +432,10 @@ static dbus_status_t dbus_scan(struct target *target, uint16_t *address_in, .in_value = in }; - assert(info->addrbits != 0); + if (info->addrbits == 0) { + LOG_ERROR("scan failed; addrbits=0"); + return DBUS_STATUS_FAILED; + } buf_set_u64(out, DBUS_OP_START, DBUS_OP_SIZE, op); buf_set_u64(out, DBUS_DATA_START, DBUS_DATA_SIZE, data_out); @@ -686,18 +689,13 @@ static void dram_write32(struct target *target, unsigned int index, uint32_t val } /** Read the haltnot and interrupt bits. */ -static bits_t read_bits(struct target *target) +static int read_bits(struct target *target, bits_t *result) { uint64_t value; dbus_status_t status; uint16_t address_in; riscv011_info_t *info = get_info(target); - bits_t err_result = { - .haltnot = 0, - .interrupt = 0 - }; - do { unsigned i = 0; do { @@ -706,26 +704,23 @@ static bits_t read_bits(struct target *target) if (address_in == (1<<info->addrbits) - 1 && value == (1ULL<<DBUS_DATA_SIZE) - 1) { LOG_ERROR("TDO seems to be stuck high."); - return err_result; + return ERROR_FAIL; } increase_dbus_busy_delay(target); - } else if (status == DBUS_STATUS_FAILED) { - /* TODO: return an actual error */ - return err_result; } } while (status == DBUS_STATUS_BUSY && i++ < 256); - if (i >= 256) { + if (status != DBUS_STATUS_SUCCESS) { LOG_ERROR("Failed to read from 0x%x; status=%d", address_in, status); - return err_result; + return ERROR_FAIL; } } while (address_in > 0x10 && address_in != DMCONTROL); - bits_t result = { - .haltnot = get_field(value, DMCONTROL_HALTNOT), - .interrupt = get_field(value, DMCONTROL_INTERRUPT) - }; - return result; + if (result) { + result->haltnot = get_field(value, DMCONTROL_HALTNOT); + result->interrupt = get_field(value, DMCONTROL_INTERRUPT); + } + return ERROR_OK; } static int wait_for_debugint_clear(struct target *target, bool ignore_first) @@ -736,10 +731,17 @@ static int wait_for_debugint_clear(struct target *target, bool ignore_first) * result of the read that happened just before debugint was set. * (Assuming the last scan before calling this function was one that * sets debugint.) */ - read_bits(target); + read_bits(target, NULL); } while (1) { - bits_t bits = read_bits(target); + bits_t bits = { + .haltnot = 0, + .interrupt = 0 + }; + if (read_bits(target, &bits) != ERROR_OK) { + LOG_ERROR("read_bits fails"); + return ERROR_FAIL; + } if (!bits.interrupt) return ERROR_OK; if (time(NULL) - start > riscv_command_timeout_sec) { @@ -1905,7 +1907,15 @@ static int poll_target(struct target *target, bool announce) int old_debug_level = debug_level; if (debug_level >= LOG_LVL_DEBUG) debug_level = LOG_LVL_INFO; - bits_t bits = read_bits(target); + bits_t bits = { + .haltnot = 0, + .interrupt = 0 + }; + if (read_bits(target, &bits) != ERROR_OK) { + LOG_ERROR("read_bits fails"); + return ERROR_FAIL; + } + debug_level = old_debug_level; if (bits.haltnot && bits.interrupt) { --