aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/flash/nor/em357.c2
-rw-r--r--src/flash/nor/nrf5.c126
-rw-r--r--src/flash/nor/psoc6.c7
-rw-r--r--src/flash/nor/stm32l4x.c56
-rw-r--r--src/flash/nor/stm32l4x.h2
-rw-r--r--src/flash/startup.tcl6
-rw-r--r--src/helper/binarybuffer.c158
-rw-r--r--src/helper/binarybuffer.h17
-rw-r--r--src/helper/command.c40
-rw-r--r--src/helper/command.h11
-rw-r--r--src/helper/jep106.inc37
-rw-r--r--src/jtag/commands.c30
-rw-r--r--src/jtag/commands.h12
-rw-r--r--src/jtag/core.c106
-rw-r--r--src/jtag/drivers/amt_jtagaccel.c2
-rw-r--r--src/jtag/drivers/angie.c11
-rw-r--r--src/jtag/drivers/arm-jtag-ew.c20
-rw-r--r--src/jtag/drivers/bitbang.c21
-rw-r--r--src/jtag/drivers/bitq.c28
-rw-r--r--src/jtag/drivers/buspirate.c29
-rw-r--r--src/jtag/drivers/cmsis_dap.c20
-rw-r--r--src/jtag/drivers/driver.c8
-rw-r--r--src/jtag/drivers/ft232r.c18
-rw-r--r--src/jtag/drivers/ftdi.c25
-rw-r--r--src/jtag/drivers/gw16012.c7
-rw-r--r--src/jtag/drivers/jlink.c124
-rw-r--r--src/jtag/drivers/jtag_dpi.c10
-rw-r--r--src/jtag/drivers/jtag_vpi.c14
-rw-r--r--src/jtag/drivers/mpsse.c3
-rw-r--r--src/jtag/drivers/mpsse.h1
-rw-r--r--src/jtag/drivers/opendous.c20
-rw-r--r--src/jtag/drivers/openjtag.c10
-rw-r--r--src/jtag/drivers/osbdm.c12
-rw-r--r--src/jtag/drivers/rlink.c10
-rw-r--r--src/jtag/drivers/ulink.c11
-rw-r--r--src/jtag/drivers/usb_blaster/usb_blaster.c18
-rw-r--r--src/jtag/drivers/usbprog.c14
-rw-r--r--src/jtag/drivers/vdebug.c22
-rw-r--r--src/jtag/drivers/vsllink.c20
-rw-r--r--src/jtag/drivers/xds110.c12
-rw-r--r--src/jtag/drivers/xlnx-pcie-xvc.c11
-rw-r--r--src/jtag/hla/hla_interface.c23
-rw-r--r--src/jtag/jtag.h38
-rw-r--r--src/jtag/minidriver.h6
-rw-r--r--src/jtag/startup.tcl30
-rw-r--r--src/jtag/tcl.c21
-rw-r--r--src/rtos/hwthread.c53
-rw-r--r--src/server/gdb_server.c37
-rw-r--r--src/server/startup.tcl72
-rw-r--r--src/server/tcl_server.c21
-rw-r--r--src/server/telnet_server.c4
-rw-r--r--src/target/arm.h11
-rw-r--r--src/target/avrt.c26
-rw-r--r--src/target/cortex_m.c96
-rw-r--r--src/target/cortex_m.h43
-rw-r--r--src/target/esirisc.c2
-rw-r--r--src/target/esirisc_jtag.c5
-rw-r--r--src/target/lakemont.c4
-rw-r--r--src/target/riscv/asm.h6
-rw-r--r--src/target/riscv/batch.c11
-rw-r--r--src/target/riscv/batch.h32
-rw-r--r--src/target/riscv/debug_reg_printer.h5
-rw-r--r--src/target/riscv/field_helpers.h6
-rw-r--r--src/target/riscv/gdb_regs.h6
-rw-r--r--src/target/riscv/opcodes.h4
-rw-r--r--src/target/riscv/program.c4
-rw-r--r--src/target/riscv/program.h6
-rw-r--r--src/target/riscv/riscv-011.c46
-rw-r--r--src/target/riscv/riscv-011.h2
-rw-r--r--src/target/riscv/riscv-011_reg.c4
-rw-r--r--src/target/riscv/riscv-011_reg.h6
-rw-r--r--src/target/riscv/riscv-013.c549
-rw-r--r--src/target/riscv/riscv-013.h6
-rw-r--r--src/target/riscv/riscv-013_reg.c280
-rw-r--r--src/target/riscv/riscv-013_reg.h13
-rw-r--r--src/target/riscv/riscv.c282
-rw-r--r--src/target/riscv/riscv.h32
-rw-r--r--src/target/riscv/riscv_reg.c47
-rw-r--r--src/target/riscv/riscv_reg_impl.h16
-rw-r--r--src/target/target.c70
-rw-r--r--src/target/target.h3
-rw-r--r--src/target/target_request.c4
-rw-r--r--src/target/xtensa/xtensa.c8
-rw-r--r--src/target/xtensa/xtensa_chip.c2
-rw-r--r--src/transport/transport.c2
86 files changed, 1737 insertions, 1322 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d79cd6..4d1c1a2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,8 +17,12 @@ bin_PROGRAMS += %D%/openocd
if INTERNAL_JIMTCL
%C%_openocd_LDADD += $(top_builddir)/jimtcl/libjim.a
else
+if HAVE_JIMTCL_PKG_CONFIG
+%C%_openocd_LDADD += $(JIMTCL_LIBS)
+else
%C%_openocd_LDADD += -ljim
endif
+endif
%C%_libopenocd_la_CPPFLAGS =
diff --git a/src/flash/nor/em357.c b/src/flash/nor/em357.c
index 043494c..207346f 100644
--- a/src/flash/nor/em357.c
+++ b/src/flash/nor/em357.c
@@ -709,7 +709,7 @@ static int em357_probe(struct flash_bank *bank)
em357_info->ppage_size = 4;
- LOG_INFO("flash size = %d KiB", num_pages*page_size/1024);
+ LOG_INFO("flash size = %d KiB", num_pages * page_size / 1024);
free(bank->sectors);
diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c
index f07433e..5cb552a 100644
--- a/src/flash/nor/nrf5.c
+++ b/src/flash/nor/nrf5.c
@@ -117,20 +117,24 @@ struct nrf5_map {
struct nrf5_info {
unsigned int refcount;
+ bool chip_probed;
struct nrf5_bank {
struct nrf5_info *chip;
bool probed;
} bank[2];
+
struct target *target;
- /* chip identification stored in nrf5_probe() for use in nrf5_info() */
+ /* chip identification stored in nrf5_probe_chip()
+ * for use in nrf5_info() and nrf5_setup_bank() */
bool ficr_info_valid;
struct nrf52_ficr_info ficr_info;
const struct nrf5_device_spec *spec;
uint16_t hwid;
enum nrf5_features features;
- unsigned int flash_size_kb;
+ uint32_t flash_page_size;
+ uint32_t flash_num_sectors;
unsigned int ram_size_kb;
const struct nrf5_map *map;
@@ -341,16 +345,19 @@ const struct flash_driver nrf5_flash, nrf51_flash;
static bool nrf5_bank_is_probed(const struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
-
return nbank->probed;
}
-static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
+static bool nrf5_chip_is_probed(const struct flash_bank *bank)
{
+ struct nrf5_bank *nbank = bank->driver_priv;
struct nrf5_info *chip = nbank->chip;
- assert(chip);
+ return chip->chip_probed;
+}
+static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
+{
+ struct nrf5_info *chip = nbank->chip;
return nbank == &chip->bank[1];
}
@@ -470,9 +477,7 @@ static int nrf51_protect_check_clenr0(struct flash_bank *bank)
uint32_t clenr0;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
res = target_read_u32(chip->target, NRF51_FICR_CLENR0,
&clenr0);
@@ -501,9 +506,7 @@ static int nrf51_protect_check_clenr0(struct flash_bank *bank)
static int nrf52_protect_check_bprot(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
static uint32_t nrf5_bprot_offsets[4] = { 0x600, 0x604, 0x610, 0x614 };
uint32_t bprot_reg = 0;
@@ -528,9 +531,7 @@ static int nrf52_protect_check_bprot(struct flash_bank *bank)
static int nrf5_protect_check(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
/* UICR cannot be write protected so just return early */
if (nrf5_bank_is_uicr(nbank))
@@ -554,9 +555,7 @@ static int nrf51_protect_clenr0(struct flash_bank *bank, int set, unsigned int f
uint32_t clenr0, ppfc;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
if (first != 0) {
LOG_ERROR("Code region 0 must start at the beginning of the bank");
@@ -614,9 +613,7 @@ static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first,
unsigned int last)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
/* UICR cannot be write protected so just bail out early */
if (nrf5_bank_is_uicr(nbank)) {
@@ -701,16 +698,15 @@ static int nrf5_get_chip_type_str(const struct nrf5_info *chip, char *buf, unsig
static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
char chip_type_str[256];
if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
return ERROR_FAIL;
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
command_print_sameline(cmd, "%s %ukB Flash, %ukB RAM",
- chip_type_str, chip->flash_size_kb, chip->ram_size_kb);
+ chip_type_str, flash_size_kb, chip->ram_size_kb);
return ERROR_OK;
}
@@ -838,14 +834,12 @@ static int nrf51_get_ram_size(struct target *target, uint32_t *ram_size)
return res;
}
-static int nrf5_probe(struct flash_bank *bank)
+static int nrf5_probe_chip(struct flash_bank *bank)
{
int res = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
struct target *target = chip->target;
chip->spec = NULL;
@@ -968,9 +962,8 @@ static int nrf5_probe(struct flash_bank *bank)
}
/* The value stored in FICR CODEPAGESIZE is the number of bytes in one page of FLASH. */
- uint32_t flash_page_size;
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codepagesize,
- &flash_page_size);
+ &chip->flash_page_size);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code page size");
return res;
@@ -978,69 +971,93 @@ static int nrf5_probe(struct flash_bank *bank)
/* Note the register name is misleading,
* FICR CODESIZE is the number of pages in flash memory, not the number of bytes! */
- uint32_t num_sectors;
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codesize,
- &num_sectors);
+ &chip->flash_num_sectors);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code memory size");
return res;
}
- chip->flash_size_kb = num_sectors * flash_page_size / 1024;
+ char chip_type_str[256];
+ if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
+ return ERROR_FAIL;
- if (!chip->bank[0].probed && !chip->bank[1].probed) {
- char chip_type_str[256];
- if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
- return ERROR_FAIL;
- const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);
- LOG_INFO("%s%s %ukB Flash, %ukB RAM",
- device_is_unknown ? "Unknown device: " : "",
- chip_type_str,
- chip->flash_size_kb,
- chip->ram_size_kb);
- }
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
+ const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);
+ LOG_INFO("%s%s %ukB Flash, %ukB RAM",
+ device_is_unknown ? "Unknown device: " : "",
+ chip_type_str,
+ flash_size_kb,
+ chip->ram_size_kb);
- free(bank->sectors);
+ chip->chip_probed = true;
+ return ERROR_OK;
+}
+
+static int nrf5_setup_bank(struct flash_bank *bank)
+{
+ struct nrf5_bank *nbank = bank->driver_priv;
+ struct nrf5_info *chip = nbank->chip;
if (bank->base == chip->map->flash_base) {
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
/* Sanity check */
- if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb)
+ if (chip->spec && flash_size_kb != chip->spec->flash_size_kb)
LOG_WARNING("Chip's reported Flash capacity does not match expected one");
- if (chip->ficr_info_valid && chip->flash_size_kb != chip->ficr_info.flash)
+ if (chip->ficr_info_valid && flash_size_kb != chip->ficr_info.flash)
LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
- bank->num_sectors = num_sectors;
- bank->size = num_sectors * flash_page_size;
+ bank->num_sectors = chip->flash_num_sectors;
+ bank->size = chip->flash_num_sectors * chip->flash_page_size;
- bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
+ bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
chip->bank[0].probed = true;
- } else {
+ } else if (bank->base == chip->map->uicr_base) {
/* UICR bank */
bank->num_sectors = 1;
- bank->size = flash_page_size;
+ bank->size = chip->flash_page_size;
- bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
+ bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
bank->sectors[0].is_protected = 0;
chip->bank[1].probed = true;
+ } else {
+ LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FLASH_BANK_INVALID;
}
return ERROR_OK;
}
+static int nrf5_probe(struct flash_bank *bank)
+{
+ /* probe always reads actual info from the device */
+ int res = nrf5_probe_chip(bank);
+ if (res != ERROR_OK)
+ return res;
+
+ return nrf5_setup_bank(bank);
+}
+
static int nrf5_auto_probe(struct flash_bank *bank)
{
if (nrf5_bank_is_probed(bank))
return ERROR_OK;
- return nrf5_probe(bank);
+ if (!nrf5_chip_is_probed(bank)) {
+ int res = nrf5_probe_chip(bank);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ return nrf5_setup_bank(bank);
}
@@ -1214,9 +1231,7 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer,
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
assert(offset % 4 == 0);
assert(count % 4 == 0);
@@ -1276,9 +1291,7 @@ static int nrf5_erase(struct flash_bank *bank, unsigned int first,
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
/* UICR CLENR0 based protection used on nRF51 prevents erase
* absolutely silently. NVMC has no flag to indicate the protection
@@ -1322,7 +1335,6 @@ error:
static void nrf5_free_driver_priv(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
if (!chip)
return;
@@ -1372,8 +1384,8 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)
case NRF53NET_UICR_BASE:
break;
default:
- LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
- return ERROR_FAIL;
+ LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FLASH_BANK_INVALID;
}
chip = nrf5_get_chip(bank->target);
@@ -1418,17 +1430,13 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command)
if (res != ERROR_OK)
return res;
- assert(bank);
-
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
if (chip->features & NRF5_FEATURE_SERIES_51) {
uint32_t ppfc;
diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c
index 859b3e9..47f3ac6 100644
--- a/src/flash/nor/psoc6.c
+++ b/src/flash/nor/psoc6.c
@@ -223,6 +223,8 @@ static int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_
{
int hr;
uint32_t reg_val;
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ bool is_cm0 = (armv7m->arm.arch == ARM_ARCH_V6M);
struct timeout to;
timeout_init(&to, IPC_TIMEOUT_MS);
@@ -244,7 +246,7 @@ static int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_
return ERROR_OK;
}
- if (target->coreid) {
+ if (!is_cm0) {
LOG_WARNING("SROM API calls via CM4 target are supported on single-core PSoC6 devices only. "
"Please perform all Flash-related operations via CM0+ target on dual-core devices.");
}
@@ -886,7 +888,8 @@ static int handle_reset_halt(struct target *target)
{
int hr;
uint32_t reset_addr;
- bool is_cm0 = (target->coreid == 0);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ bool is_cm0 = (armv7m->arm.arch == ARM_ARCH_V6M);
/* Halt target device */
if (target->state != TARGET_HALTED) {
diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 0399385..bb6e9ef 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -120,6 +120,12 @@
* http://www.st.com/resource/en/reference_manual/dm00346336.pdf
*/
+/* STM32U5xxx series for reference.
+ *
+ * RM0456 (STM32U5xx)
+ * http://www.st.com/resource/en/reference_manual/dm00477635.pdf
+ */
+
/* Erase time can be as high as 25ms, 10x this and assume it's toast... */
#define FLASH_ERASE_TIMEOUT 250
@@ -344,9 +350,17 @@ static const struct stm32l4_rev stm32g49_g4axx_revs[] = {
{ 0x1000, "A" },
};
+static const struct stm32l4_rev stm32u53_u54xx_revs[] = {
+ { 0x1000, "A" }, { 0x1001, "Z" },
+};
+
static const struct stm32l4_rev stm32u57_u58xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2000, "B" },
- { 0x2001, "X" }, { 0x3000, "C" },
+ { 0x2001, "X" }, { 0x3000, "C" }, { 0x3001, "W" },
+};
+
+static const struct stm32l4_rev stm32u59_u5axx_revs[] = {
+ { 0x3001, "X" },
};
static const struct stm32l4_rev stm32wba5x_revs[] = {
@@ -419,6 +433,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_size = 1024,
},
{
+ .id = DEVID_STM32U53_U54XX,
+ .revs = stm32u53_u54xx_revs,
+ .num_revs = ARRAY_SIZE(stm32u53_u54xx_revs),
+ .device_str = "STM32U535/U545",
+ .max_flash_size_kb = 512,
+ .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x0BFA07A0,
+ .otp_base = 0x0BFA0000,
+ .otp_size = 512,
+ },
+ {
.id = DEVID_STM32G05_G06XX,
.revs = stm32g05_g06xx_revs,
.num_revs = ARRAY_SIZE(stm32g05_g06xx_revs),
@@ -575,6 +601,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_size = 1024,
},
{
+ .id = DEVID_STM32U59_U5AXX,
+ .revs = stm32u59_u5axx_revs,
+ .num_revs = ARRAY_SIZE(stm32u59_u5axx_revs),
+ .device_str = "STM32U59/U5Axx",
+ .max_flash_size_kb = 4096,
+ .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x0BFA07A0,
+ .otp_base = 0x0BFA0000,
+ .otp_size = 512,
+ },
+ {
.id = DEVID_STM32U57_U58XX,
.revs = stm32u57_u58xx_revs,
.num_revs = ARRAY_SIZE(stm32u57_u58xx_revs),
@@ -2000,10 +2038,22 @@ static int stm32l4_probe(struct flash_bank *bank)
stm32l4_info->bank1_sectors = num_pages / 2;
}
break;
+ case DEVID_STM32U53_U54XX:
case DEVID_STM32U57_U58XX:
- /* if flash size is max (2M) the device is always dual bank
- * otherwise check DUALBANK
+ case DEVID_STM32U59_U5AXX:
+ /* according to RM0456 Rev 4, Chapter 7.3.1 and 7.9.13
+ * U53x/U54x have 512K max flash size:
+ * 512K variants are always in DUAL BANK mode
+ * 256K and 128K variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * U57x/U58x have 2M max flash size:
+ * 2M variants are always in DUAL BANK mode
+ * 1M variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * U59x/U5Ax have 4M max flash size:
+ * 4M variants are always in DUAL BANK mode
+ * 2M variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * Note: flash banks are always contiguous
*/
+
page_size_kb = 8;
num_pages = flash_size_kb / page_size_kb;
stm32l4_info->bank1_sectors = num_pages;
diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h
index 3dc0909..5f3bc26 100644
--- a/src/flash/nor/stm32l4x.h
+++ b/src/flash/nor/stm32l4x.h
@@ -89,6 +89,7 @@
#define DEVID_STM32L43_L44XX 0x435
#define DEVID_STM32C01XX 0x443
#define DEVID_STM32C03XX 0x453
+#define DEVID_STM32U53_U54XX 0x455
#define DEVID_STM32G05_G06XX 0x456
#define DEVID_STM32G07_G08XX 0x460
#define DEVID_STM32L49_L4AXX 0x461
@@ -102,6 +103,7 @@
#define DEVID_STM32L4P_L4QXX 0x471
#define DEVID_STM32L55_L56XX 0x472
#define DEVID_STM32G49_G4AXX 0x479
+#define DEVID_STM32U59_U5AXX 0x481
#define DEVID_STM32U57_U58XX 0x482
#define DEVID_STM32WBA5X 0x492
#define DEVID_STM32WB1XX 0x494
diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl
index 654f201..0dd84ef 100644
--- a/src/flash/startup.tcl
+++ b/src/flash/startup.tcl
@@ -5,7 +5,7 @@
#
# program utility proc
# usage: program filename
-# optional args: verify, reset, exit and address
+# optional args: preverify, verify, reset, exit and address
#
lappend _telnet_autocomplete_skip program_error
@@ -101,8 +101,8 @@ proc program {filename args} {
return
}
-add_help_text program "write an image to flash, address is only required for binary images. verify, reset, exit are optional"
-add_usage_text program "<filename> \[address\] \[pre-verify\] \[verify\] \[reset\] \[exit\]"
+add_help_text program "write an image to flash, address is only required for binary images. preverify, verify, reset, exit are optional"
+add_usage_text program "<filename> \[address\] \[preverify\] \[verify\] \[reset\] \[exit\]"
# stm32[f0x|f3x] uses the same flash driver as the stm32f1x
proc stm32f0x args { eval stm32f1x $args }
diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c
index 5f38b43..3e09143 100644
--- a/src/helper/binarybuffer.c
+++ b/src/helper/binarybuffer.c
@@ -102,7 +102,6 @@ bool buf_cmp_mask(const void *_buf1, const void *_buf2,
return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);
}
-
void *buf_set_ones(void *_buf, unsigned size)
{
uint8_t *buf = _buf;
@@ -206,36 +205,75 @@ char *buf_to_hex_str(const void *_buf, unsigned buf_len)
return str;
}
-/** identify radix, and skip radix-prefix (0, 0x or 0X) */
-static void str_radix_guess(const char **_str, unsigned *_str_len,
- unsigned *_radix)
+static bool str_has_hex_prefix(const char *s)
+{
+ /* Starts with "0x" or "0X" */
+ return (s[0] == '0') && (s[1] == 'x' || s[1] == 'X');
+}
+
+static bool str_has_octal_prefix(const char *s)
+{
+ /* - starts with '0',
+ * - has at least two characters, and
+ * - the second character is not 'x' or 'X' */
+ return (s[0] == '0') && (s[1] != '\0') && (s[1] != 'x') && (s[1] != 'X');
+}
+
+/**
+ * Try to identify the radix of the number by looking at its prefix.
+ * No further validation of the number is preformed.
+ */
+static unsigned int str_radix_guess(const char *str)
+{
+ assert(str);
+
+ if (str_has_hex_prefix(str))
+ return 16;
+
+ if (str_has_octal_prefix(str))
+ return 8;
+
+ /* Otherwise assume a decadic number. */
+ return 10;
+}
+
+/** Strip leading "0x" or "0X" from hex numbers or "0" from octal numbers. */
+static void str_strip_number_prefix_if_present(const char **_str, unsigned int radix)
{
- unsigned radix = *_radix;
- if (radix != 0)
- return;
+ assert(radix == 16 || radix == 10 || radix == 8);
+ assert(_str);
+
const char *str = *_str;
- unsigned str_len = *_str_len;
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
- radix = 16;
+ assert(str);
+
+ if (radix == 16 && str_has_hex_prefix(str))
str += 2;
- str_len -= 2;
- } else if ((str[0] == '0') && (str_len != 1)) {
- radix = 8;
+ else if (radix == 8 && str_has_octal_prefix(str))
str += 1;
- str_len -= 1;
- } else
- radix = 10;
+
+ /* No prefix to strip for radix == 10. */
+
*_str = str;
- *_str_len = str_len;
- *_radix = radix;
}
-int str_to_buf(const char *str, unsigned str_len,
- void *_buf, unsigned buf_len, unsigned radix)
+int str_to_buf(const char *str, void *_buf, unsigned int buf_len,
+ unsigned int radix, unsigned int *_detected_radix)
{
- str_radix_guess(&str, &str_len, &radix);
+ assert(radix == 0 || radix == 8 || radix == 10 || radix == 16);
+
+ if (radix == 0)
+ radix = str_radix_guess(str);
- float factor;
+ if (_detected_radix)
+ *_detected_radix = radix;
+
+ str_strip_number_prefix_if_present(&str, radix);
+
+ const size_t str_len = strlen(str);
+ if (str_len == 0)
+ return ERROR_INVALID_NUMBER;
+
+ float factor = 0.0;
if (radix == 16)
factor = 0.5; /* log(16) / log(256) = 0.5 */
else if (radix == 10)
@@ -243,41 +281,69 @@ int str_to_buf(const char *str, unsigned str_len,
else if (radix == 8)
factor = 0.375; /* log(8) / log(256) = 0.375 */
else
- return 0;
+ assert(false);
- /* copy to zero-terminated buffer */
- char *charbuf = strndup(str, str_len);
+ const unsigned int b256_len = ceil_f_to_u32(str_len * factor);
- /* number of digits in base-256 notation */
- unsigned b256_len = ceil_f_to_u32(str_len * factor);
+ /* Allocate a buffer for digits in base-256 notation */
uint8_t *b256_buf = calloc(b256_len, 1);
+ if (!b256_buf) {
+ LOG_ERROR("Unable to allocate memory");
+ return ERROR_FAIL;
+ }
- /* go through zero terminated buffer
- * input digits (ASCII) */
- unsigned i;
- for (i = 0; charbuf[i]; i++) {
- uint32_t tmp = charbuf[i];
- if ((tmp >= '0') && (tmp <= '9'))
+ /* Go through the zero-terminated buffer
+ * of input digits (ASCII) */
+ for (unsigned int i = 0; str[i]; i++) {
+ uint32_t tmp = str[i];
+ if ((tmp >= '0') && (tmp <= '9')) {
tmp = (tmp - '0');
- else if ((tmp >= 'a') && (tmp <= 'f'))
+ } else if ((tmp >= 'a') && (tmp <= 'f')) {
tmp = (tmp - 'a' + 10);
- else if ((tmp >= 'A') && (tmp <= 'F'))
+ } else if ((tmp >= 'A') && (tmp <= 'F')) {
tmp = (tmp - 'A' + 10);
- else
- continue; /* skip characters other than [0-9,a-f,A-F] */
+ } else {
+ /* Characters other than [0-9,a-f,A-F] are invalid */
+ free(b256_buf);
+ return ERROR_INVALID_NUMBER;
+ }
- if (tmp >= radix)
- continue; /* skip digits invalid for the current radix */
+ if (tmp >= radix) {
+ /* Encountered a digit that is invalid for the current radix */
+ free(b256_buf);
+ return ERROR_INVALID_NUMBER;
+ }
- /* base-256 digits */
- for (unsigned j = 0; j < b256_len; j++) {
+ /* Add the current digit (tmp) to the intermediate result
+ * in b256_buf (base-256 digits) */
+ for (unsigned int j = 0; j < b256_len; j++) {
tmp += (uint32_t)b256_buf[j] * radix;
- b256_buf[j] = (uint8_t)(tmp & 0xFF);
+ b256_buf[j] = (uint8_t)(tmp & 0xFFu);
tmp >>= 8;
}
+ /* The b256_t buffer is large enough to contain the whole result. */
+ assert(tmp == 0);
}
+ /* The result must not contain more bits than buf_len. */
+ /* Check the whole bytes: */
+ for (unsigned int j = DIV_ROUND_UP(buf_len, 8); j < b256_len; j++) {
+ if (b256_buf[j] != 0x0) {
+ free(b256_buf);
+ return ERROR_NUMBER_EXCEEDS_BUFFER;
+ }
+ }
+ /* Check the partial byte: */
+ if (buf_len % 8) {
+ const uint8_t mask = 0xFFu << (buf_len % 8);
+ if ((b256_buf[(buf_len / 8)] & mask) != 0x0) {
+ free(b256_buf);
+ return ERROR_NUMBER_EXCEEDS_BUFFER;
+ }
+ }
+
+ /* Copy the digits to the output buffer */
uint8_t *buf = _buf;
for (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++) {
if (j < b256_len)
@@ -286,14 +352,8 @@ int str_to_buf(const char *str, unsigned str_len,
buf[j] = 0;
}
- /* mask out bits that don't belong to the buffer */
- if (buf_len % 8)
- buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));
-
free(b256_buf);
- free(charbuf);
-
- return i;
+ return ERROR_OK;
}
void bit_copy_queue_init(struct bit_copy_queue *q)
diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h
index 3446296..4413743 100644
--- a/src/helper/binarybuffer.h
+++ b/src/helper/binarybuffer.h
@@ -14,6 +14,9 @@
#include <helper/list.h>
#include <helper/types.h>
+#define ERROR_INVALID_NUMBER (-1700)
+#define ERROR_NUMBER_EXCEEDS_BUFFER (-1701)
+
/** @file
* Support functions to access arbitrary bits in a byte array
*/
@@ -189,8 +192,18 @@ void *buf_set_ones(void *buf, unsigned size);
void *buf_set_buf(const void *src, unsigned src_start,
void *dst, unsigned dst_start, unsigned len);
-int str_to_buf(const char *str, unsigned len,
- void *bin_buf, unsigned buf_size, unsigned radix);
+/**
+ * Parse an unsigned number (provided as a zero-terminated string)
+ * into a bit buffer whose size is buf_len bits.
+ * @param str Input number, zero-terminated string
+ * @param _buf Output buffer, allocated by the caller
+ * @param buf_len Output buffer size in bits
+ * @param radix Base of the input number - 16, 10, 8 or 0.
+ * 0 means auto-detect the radix.
+ */
+int str_to_buf(const char *str, void *_buf, unsigned int buf_len,
+ unsigned int radix, unsigned int *_detected_radix);
+
char *buf_to_hex_str(const void *buf, unsigned size);
/* read a uint32_t from a buffer in target memory endianness */
diff --git a/src/helper/command.c b/src/helper/command.c
index a775c73..15a9b4a 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -1360,6 +1360,46 @@ int command_parse_bool_arg(const char *in, bool *out)
return ERROR_COMMAND_SYNTAX_ERROR;
}
+static const char *radix_to_str(unsigned int radix)
+{
+ switch (radix) {
+ case 16: return "hexadecimal";
+ case 10: return "decadic";
+ case 8: return "octal";
+ }
+ assert(false);
+ return "";
+}
+
+COMMAND_HELPER(command_parse_str_to_buf, const char *str, void *buf, unsigned int buf_len,
+ unsigned int radix)
+{
+ assert(str);
+ assert(buf);
+
+ int ret = str_to_buf(str, buf, buf_len, radix, NULL);
+ if (ret == ERROR_OK)
+ return ret;
+
+ /* Provide a clear error message to the user */
+ if (ret == ERROR_INVALID_NUMBER) {
+ if (radix == 0) {
+ /* Any radix is accepted, so don't include it in the error message. */
+ command_print(CMD, "'%s' is not a valid number", str);
+ } else {
+ /* Specific radix is required - tell the user what it is. */
+ command_print(CMD, "'%s' is not a valid number (requiring %s number)",
+ str, radix_to_str(radix));
+ }
+ } else if (ret == ERROR_NUMBER_EXCEEDS_BUFFER) {
+ command_print(CMD, "Number %s exceeds %u bits", str, buf_len);
+ } else {
+ command_print(CMD, "Could not parse number '%s'", str);
+ }
+
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+}
+
COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label)
{
switch (CMD_ARGC) {
diff --git a/src/helper/command.h b/src/helper/command.h
index fc26dda..7a044e6 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -517,6 +517,17 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t);
int command_parse_bool_arg(const char *in, bool *out);
COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label);
+/**
+ * Parse a number (base 10, base 16 or base 8) and store the result
+ * into a bit buffer.
+ *
+ * In case of parsing error, a user-readable error message is produced.
+ *
+ * If radix = 0 is given, the function guesses the radix by looking at the number prefix.
+ */
+COMMAND_HELPER(command_parse_str_to_buf, const char *str, void *buf, unsigned int buf_len,
+ unsigned int radix);
+
/** parses an on/off command argument */
#define COMMAND_PARSE_ON_OFF(in, out) \
COMMAND_PARSE_BOOL(in, out, "on", "off")
diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc
index 958dc4e..b74cda8 100644
--- a/src/helper/jep106.inc
+++ b/src/helper/jep106.inc
@@ -8,9 +8,7 @@
* identification code list, please visit the JEDEC website at www.jedec.org .
*/
-/* This file is aligned to revision JEP106BI January 2024. */
-
-/* "NXP (Philips)" is reported below, while missing since JEP106BG */
+/* This file is aligned to revision JEP106BJ.01 July 2024. */
[0][0x01 - 1] = "AMD",
[0][0x02 - 1] = "AMI",
@@ -30,7 +28,7 @@
[0][0x10 - 1] = "NEC",
[0][0x11 - 1] = "RCA",
[0][0x12 - 1] = "Raytheon",
-[0][0x13 - 1] = "Conexant (Rockwell)",
+[0][0x13 - 1] = "Synaptics",
[0][0x14 - 1] = "Seeq",
[0][0x15 - 1] = "NXP (Philips)",
[0][0x16 - 1] = "Synertek",
@@ -1045,7 +1043,7 @@
[8][0x17 - 1] = "Axell Corporation",
[8][0x18 - 1] = "Essencore Limited",
[8][0x19 - 1] = "Phytium",
-[8][0x1a - 1] = "Xi'an UniIC Semiconductors Co Ltd",
+[8][0x1a - 1] = "UniIC Semiconductors Co Ltd",
[8][0x1b - 1] = "Ambiq Micro",
[8][0x1c - 1] = "eveRAM Technology Inc",
[8][0x1d - 1] = "Infomax",
@@ -1452,7 +1450,7 @@
[11][0x34 - 1] = "Acacia Communications",
[11][0x35 - 1] = "Beijinjinshengyihe Technology Co Ltd",
[11][0x36 - 1] = "Zyzyx",
-[11][0x37 - 1] = "T-HEAD Semiconductor Co Ltd",
+[11][0x37 - 1] = "C-SKY Microsystems Co Ltd",
[11][0x38 - 1] = "Shenzhen Hystou Technology Co Ltd",
[11][0x39 - 1] = "Syzexion",
[11][0x3a - 1] = "Kembona",
@@ -1938,4 +1936,31 @@
[15][0x22 - 1] = "SkyeChip",
[15][0x23 - 1] = "Guangzhou Kaishile Trading Co Ltd",
[15][0x24 - 1] = "Jing Pai Digital Technology (Shenzhen) Co",
+[15][0x25 - 1] = "Memoritek",
+[15][0x26 - 1] = "Zhejiang Hikstor Technology Co Ltd",
+[15][0x27 - 1] = "Memoritek PTE Ltd",
+[15][0x28 - 1] = "Longsailing Semiconductor Co Ltd",
+[15][0x29 - 1] = "LX Semicon",
+[15][0x2a - 1] = "Shenzhen Techwinsemi Technology Co Ltd",
+[15][0x2b - 1] = "AOC",
+[15][0x2c - 1] = "GOEPEL Electronic GmbH",
+[15][0x2d - 1] = "Shenzhen G-Bong Technology Co Ltd",
+[15][0x2e - 1] = "Openedges Technology Inc",
+[15][0x2f - 1] = "EA Semi Shangahi Limited",
+[15][0x30 - 1] = "EMBCORF",
+[15][0x31 - 1] = "Shenzhen MicroBT Electronics Technology",
+[15][0x32 - 1] = "Shanghai Simor Chip Semiconductor Co",
+[15][0x33 - 1] = "Xllbyte",
+[15][0x34 - 1] = "Guangzhou Maidite Electronics Co Ltd.",
+[15][0x35 - 1] = "Zhejiang Changchun Technology Co Ltd",
+[15][0x36 - 1] = "Beijing Cloud Security Technology Co Ltd",
+[15][0x37 - 1] = "SSTC Technology and Distribution Inc",
+[15][0x38 - 1] = "Shenzhen Panmin Technology Co Ltd",
+[15][0x39 - 1] = "ITE Tech Inc",
+[15][0x3a - 1] = "Beijing Zettastone Technology Co Ltd",
+[15][0x3b - 1] = "Powerchip Micro Device",
+[15][0x3c - 1] = "Shenzhen Ysemi Computing Co Ltd",
+[15][0x3d - 1] = "Shenzhen Titan Micro Electronics Co Ltd",
+[15][0x3e - 1] = "Shenzhen Macroflash Technology Co Ltd",
+[15][0x3f - 1] = "Advantech Group",
/* EOF */
diff --git a/src/jtag/commands.c b/src/jtag/commands.c
index a60684c..1bca4e8 100644
--- a/src/jtag/commands.c
+++ b/src/jtag/commands.c
@@ -166,10 +166,9 @@ void jtag_scan_field_clone(struct scan_field *dst, const struct scan_field *src)
enum scan_type jtag_scan_type(const struct scan_command *cmd)
{
- int i;
int type = 0;
- for (i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
if (cmd->fields[i].in_value)
type |= SCAN_IN;
if (cmd->fields[i].out_value)
@@ -179,13 +178,12 @@ enum scan_type jtag_scan_type(const struct scan_command *cmd)
return type;
}
-int jtag_scan_size(const struct scan_command *cmd)
+unsigned int jtag_scan_size(const struct scan_command *cmd)
{
- int bit_count = 0;
- int i;
+ unsigned int bit_count = 0;
/* count bits in scan command */
- for (i = 0; i < cmd->num_fields; i++)
+ for (unsigned int i = 0; i < cmd->num_fields; i++)
bit_count += cmd->fields[i].num_bits;
return bit_count;
@@ -193,19 +191,16 @@ int jtag_scan_size(const struct scan_command *cmd)
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
{
- int bit_count = 0;
- int i;
-
- bit_count = jtag_scan_size(cmd);
+ unsigned int bit_count = jtag_scan_size(cmd);
*buffer = calloc(1, DIV_ROUND_UP(bit_count, 8));
bit_count = 0;
- LOG_DEBUG_IO("%s num_fields: %i",
+ LOG_DEBUG_IO("%s num_fields: %u",
cmd->ir_scan ? "IRSCAN" : "DRSCAN",
cmd->num_fields);
- for (i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
if (cmd->fields[i].out_value) {
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {
char *char_buf = buf_to_hex_str(cmd->fields[i].out_value,
@@ -213,14 +208,14 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
? DEBUG_JTAG_IOZ
: cmd->fields[i].num_bits);
- LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i,
+ LOG_DEBUG("fields[%u].out_value[%u]: 0x%s", i,
cmd->fields[i].num_bits, char_buf);
free(char_buf);
}
buf_set_buf(cmd->fields[i].out_value, 0, *buffer,
bit_count, cmd->fields[i].num_bits);
} else {
- LOG_DEBUG_IO("fields[%i].out_value[%i]: NULL",
+ LOG_DEBUG_IO("fields[%u].out_value[%u]: NULL",
i, cmd->fields[i].num_bits);
}
@@ -234,19 +229,18 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)
{
- int i;
int bit_count = 0;
int retval;
/* we return ERROR_OK, unless a check fails, or a handler reports a problem */
retval = ERROR_OK;
- for (i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
/* if neither in_value nor in_handler
* are specified we don't have to examine this field
*/
if (cmd->fields[i].in_value) {
- int num_bits = cmd->fields[i].num_bits;
+ const unsigned int num_bits = cmd->fields[i].num_bits;
uint8_t *captured = buf_set_buf(buffer, bit_count,
malloc(DIV_ROUND_UP(num_bits, 8)), 0, num_bits);
@@ -256,7 +250,7 @@ int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)
? DEBUG_JTAG_IOZ
: num_bits);
- LOG_DEBUG("fields[%i].in_value[%i]: 0x%s",
+ LOG_DEBUG("fields[%u].in_value[%u]: 0x%s",
i, num_bits, char_buf);
free(char_buf);
}
diff --git a/src/jtag/commands.h b/src/jtag/commands.h
index 8259077..29fa842 100644
--- a/src/jtag/commands.h
+++ b/src/jtag/commands.h
@@ -36,7 +36,7 @@ struct scan_command {
/** instruction/not data scan */
bool ir_scan;
/** number of fields in *fields array */
- int num_fields;
+ unsigned int num_fields;
/** pointer to an array of data scan fields */
struct scan_field *fields;
/** state in which JTAG commands should finish */
@@ -50,14 +50,14 @@ struct statemove_command {
struct pathmove_command {
/** number of states in *path */
- int num_states;
+ unsigned int num_states;
/** states that have to be passed */
tap_state_t *path;
};
struct runtest_command {
/** number of cycles to spend in Run-Test/Idle state */
- int num_cycles;
+ unsigned int num_cycles;
/** state in which JTAG commands should finish */
tap_state_t end_state;
};
@@ -65,7 +65,7 @@ struct runtest_command {
struct stableclocks_command {
/** number of clock cycles that should be sent */
- int num_cycles;
+ unsigned int num_cycles;
};
@@ -100,7 +100,7 @@ struct sleep_command {
*/
struct tms_command {
/** How many bits should be clocked out. */
- unsigned num_bits;
+ unsigned int num_bits;
/** The bits to clock out; the LSB is bit 0 of bits[0]. */
const uint8_t *bits;
};
@@ -157,7 +157,7 @@ struct jtag_command *jtag_command_queue_get(void);
void jtag_scan_field_clone(struct scan_field *dst, const struct scan_field *src);
enum scan_type jtag_scan_type(const struct scan_command *cmd);
-int jtag_scan_size(const struct scan_command *cmd);
+unsigned int jtag_scan_size(const struct scan_command *cmd);
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd);
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer);
diff --git a/src/jtag/core.c b/src/jtag/core.c
index c84d5aa..9eae5e7 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -39,7 +39,7 @@
#include "server/ipdbg.h"
/** The number of JTAG queue flushes (for profiling and debugging purposes). */
-static int jtag_flush_queue_count;
+static unsigned int jtag_flush_queue_count;
/* Sleep this # of ms after flushing the queue */
static int jtag_flush_queue_sleep;
@@ -88,14 +88,14 @@ static enum reset_types jtag_reset_config = RESET_NONE;
tap_state_t cmd_queue_cur_state = TAP_RESET;
static bool jtag_verify_capture_ir = true;
-static int jtag_verify = 1;
+static bool jtag_verify = true;
/* how long the OpenOCD should wait before attempting JTAG communication after reset lines
*deasserted (in ms) */
-static int adapter_nsrst_delay; /* default to no nSRST delay */
-static int jtag_ntrst_delay;/* default to no nTRST delay */
-static int adapter_nsrst_assert_width; /* width of assertion */
-static int jtag_ntrst_assert_width; /* width of assertion */
+static unsigned int adapter_nsrst_delay; /* default to no nSRST delay */
+static unsigned int jtag_ntrst_delay;/* default to no nTRST delay */
+static unsigned int adapter_nsrst_assert_width; /* width of assertion */
+static unsigned int jtag_ntrst_assert_width; /* width of assertion */
/**
* Contains a single callback along with a pointer that will be passed
@@ -186,10 +186,10 @@ struct jtag_tap *jtag_all_taps(void)
return __jtag_all_taps;
};
-unsigned jtag_tap_count(void)
+unsigned int jtag_tap_count(void)
{
struct jtag_tap *t = jtag_all_taps();
- unsigned n = 0;
+ unsigned int n = 0;
while (t) {
n++;
t = t->next_tap;
@@ -197,10 +197,10 @@ unsigned jtag_tap_count(void)
return n;
}
-unsigned jtag_tap_count_enabled(void)
+unsigned int jtag_tap_count_enabled(void)
{
struct jtag_tap *t = jtag_all_taps();
- unsigned n = 0;
+ unsigned int n = 0;
while (t) {
if (t->enabled)
n++;
@@ -212,7 +212,7 @@ unsigned jtag_tap_count_enabled(void)
/** Append a new TAP to the chain of all taps. */
static void jtag_tap_add(struct jtag_tap *t)
{
- unsigned jtag_num_taps = 0;
+ unsigned int jtag_num_taps = 0;
struct jtag_tap **tap = &__jtag_all_taps;
while (*tap) {
@@ -499,7 +499,7 @@ void jtag_add_tlr(void)
*
* @todo Update naming conventions to stop assuming everything is JTAG.
*/
-int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state)
+int jtag_add_tms_seq(unsigned int nbits, const uint8_t *seq, enum tap_state state)
{
int retval;
@@ -514,7 +514,7 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state)
return retval;
}
-void jtag_add_pathmove(int num_states, const tap_state_t *path)
+void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path)
{
tap_state_t cur_state = cmd_queue_cur_state;
@@ -525,7 +525,7 @@ void jtag_add_pathmove(int num_states, const tap_state_t *path)
return;
}
- for (int i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == TAP_RESET) {
LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences");
jtag_set_error(ERROR_JTAG_STATE_INVALID);
@@ -567,12 +567,12 @@ int jtag_add_statemove(tap_state_t goal_state)
/* nothing to do */;
else if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state)) {
- unsigned tms_bits = tap_get_tms_path(cur_state, goal_state);
- unsigned tms_count = tap_get_tms_path_len(cur_state, goal_state);
+ unsigned int tms_bits = tap_get_tms_path(cur_state, goal_state);
+ unsigned int tms_count = tap_get_tms_path_len(cur_state, goal_state);
tap_state_t moves[8];
assert(tms_count < ARRAY_SIZE(moves));
- for (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1) {
+ for (unsigned int i = 0; i < tms_count; i++, tms_bits >>= 1) {
bool bit = tms_bits & 1;
cur_state = tap_state_transition(cur_state, bit);
@@ -589,14 +589,14 @@ int jtag_add_statemove(tap_state_t goal_state)
return ERROR_OK;
}
-void jtag_add_runtest(int num_cycles, tap_state_t state)
+void jtag_add_runtest(unsigned int num_cycles, tap_state_t state)
{
jtag_prelude(state);
jtag_set_error(interface_jtag_add_runtest(num_cycles, state));
}
-void jtag_add_clocks(int num_cycles)
+void jtag_add_clocks(unsigned int num_cycles)
{
if (!tap_is_state_stable(cmd_queue_cur_state)) {
LOG_ERROR("jtag_add_clocks() called with TAP in unstable state \"%s\"",
@@ -960,16 +960,16 @@ int default_interface_jtag_execute_queue(void)
LOG_DEBUG_IO("JTAG %s SCAN to %s",
cmd->cmd.scan->ir_scan ? "IR" : "DR",
tap_state_name(cmd->cmd.scan->end_state));
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++) {
struct scan_field *field = cmd->cmd.scan->fields + i;
if (field->out_value) {
char *str = buf_to_hex_str(field->out_value, field->num_bits);
- LOG_DEBUG_IO(" %db out: %s", field->num_bits, str);
+ LOG_DEBUG_IO(" %ub out: %s", field->num_bits, str);
free(str);
}
if (field->in_value) {
char *str = buf_to_hex_str(field->in_value, field->num_bits);
- LOG_DEBUG_IO(" %db in: %s", field->num_bits, str);
+ LOG_DEBUG_IO(" %ub in: %s", field->num_bits, str);
free(str);
}
}
@@ -1029,7 +1029,7 @@ void jtag_execute_queue_noclear(void)
}
}
-int jtag_get_flush_queue_count(void)
+unsigned int jtag_get_flush_queue_count(void)
{
return jtag_flush_queue_count;
}
@@ -1081,7 +1081,7 @@ void jtag_sleep(uint32_t us)
/* a larger IR length than we ever expect to autoprobe */
#define JTAG_IRLEN_MAX 60
-static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode)
+static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned int num_idcode)
{
struct scan_field field = {
.num_bits = num_idcode * 32,
@@ -1090,7 +1090,7 @@ static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcod
};
/* initialize to the end of chain ID value */
- for (unsigned i = 0; i < num_idcode; i++)
+ for (unsigned int i = 0; i < num_idcode; i++)
buf_set_u32(idcode_buffer, i * 32, 32, END_OF_CHAIN_FLAG);
jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, TAP_DRPAUSE);
@@ -1098,12 +1098,12 @@ static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcod
return jtag_execute_queue();
}
-static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned count)
+static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned int count)
{
uint8_t zero_check = 0x0;
uint8_t one_check = 0xff;
- for (unsigned i = 0; i < count * 4; i++) {
+ for (unsigned int i = 0; i < count * 4; i++) {
zero_check |= idcodes[i];
one_check &= idcodes[i];
}
@@ -1158,7 +1158,8 @@ static bool jtag_idcode_is_final(uint32_t idcode)
* with the JTAG chain earlier, gives more helpful/explicit error messages.
* Returns TRUE iff garbage was found.
*/
-static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned max)
+static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned int count,
+ unsigned int max)
{
bool triggered = false;
for (; count < max - 31; count += 32) {
@@ -1185,26 +1186,26 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
uint32_t idcode = tap->idcode & mask;
/* Loop over the expected identification codes and test for a match */
- for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
- uint32_t expected = tap->expected_ids[ii] & mask;
+ for (unsigned int i = 0; i < tap->expected_ids_cnt; i++) {
+ uint32_t expected = tap->expected_ids[i] & mask;
if (idcode == expected)
return true;
/* treat "-expected-id 0" as a "don't-warn" wildcard */
- if (tap->expected_ids[ii] == 0)
+ if (tap->expected_ids[i] == 0)
return true;
}
/* If none of the expected ids matched, warn */
jtag_examine_chain_display(LOG_LVL_WARNING, "UNEXPECTED",
tap->dotted_name, tap->idcode);
- for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
+ for (unsigned int i = 0; i < tap->expected_ids_cnt; i++) {
char msg[32];
- snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, tap->expected_ids_cnt);
+ snprintf(msg, sizeof(msg), "expected %u of %u", i + 1, tap->expected_ids_cnt);
jtag_examine_chain_display(LOG_LVL_ERROR, msg,
- tap->dotted_name, tap->expected_ids[ii]);
+ tap->dotted_name, tap->expected_ids[i]);
}
return false;
}
@@ -1215,7 +1216,7 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
static int jtag_examine_chain(void)
{
int retval;
- unsigned max_taps = jtag_tap_count();
+ unsigned int max_taps = jtag_tap_count();
/* Autoprobe up to this many. */
if (max_taps < JTAG_MAX_AUTO_TAPS)
@@ -1243,9 +1244,9 @@ static int jtag_examine_chain(void)
/* Point at the 1st predefined tap, if any */
struct jtag_tap *tap = jtag_tap_next_enabled(NULL);
- unsigned bit_count = 0;
- unsigned autocount = 0;
- for (unsigned i = 0; i < max_taps; i++) {
+ unsigned int bit_count = 0;
+ unsigned int autocount = 0;
+ for (unsigned int i = 0; i < max_taps; i++) {
assert(bit_count < max_taps * 32);
uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);
@@ -1337,7 +1338,7 @@ static int jtag_validate_ircapture(void)
int retval;
/* when autoprobing, accommodate huge IR lengths */
- int total_ir_length = 0;
+ unsigned int total_ir_length = 0;
for (tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {
if (tap->ir_length == 0)
total_ir_length += JTAG_IRLEN_MAX;
@@ -1396,7 +1397,7 @@ static int jtag_validate_ircapture(void)
&& tap->ir_length < JTAG_IRLEN_MAX) {
tap->ir_length++;
}
- LOG_WARNING("AUTO %s - use \"jtag newtap %s %s -irlen %d "
+ LOG_WARNING("AUTO %s - use \"jtag newtap %s %s -irlen %u "
"-expected-id 0x%08" PRIx32 "\"",
tap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode);
}
@@ -1445,8 +1446,8 @@ done:
void jtag_tap_init(struct jtag_tap *tap)
{
- unsigned ir_len_bits;
- unsigned ir_len_bytes;
+ unsigned int ir_len_bits;
+ unsigned int ir_len_bytes;
/* if we're autoprobing, cope with potentially huge ir_length */
ir_len_bits = tap->ir_length ? tap->ir_length : JTAG_IRLEN_MAX;
@@ -1471,8 +1472,8 @@ void jtag_tap_init(struct jtag_tap *tap)
jtag_register_event_callback(&jtag_reset_callback, tap);
jtag_tap_add(tap);
- LOG_DEBUG("Created Tap: %s @ abs position %d, "
- "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name,
+ LOG_DEBUG("Created Tap: %s @ abs position %u, "
+ "irlen %u, capture: 0x%x mask: 0x%x", tap->dotted_name,
tap->abs_chain_position, tap->ir_length,
(unsigned) tap->ir_capture_value,
(unsigned) tap->ir_capture_mask);
@@ -1749,37 +1750,36 @@ int jtag_get_srst(void)
return jtag_srst == 1;
}
-void jtag_set_nsrst_delay(unsigned delay)
+void jtag_set_nsrst_delay(unsigned int delay)
{
adapter_nsrst_delay = delay;
}
-unsigned jtag_get_nsrst_delay(void)
+unsigned int jtag_get_nsrst_delay(void)
{
return adapter_nsrst_delay;
}
-void jtag_set_ntrst_delay(unsigned delay)
+void jtag_set_ntrst_delay(unsigned int delay)
{
jtag_ntrst_delay = delay;
}
-unsigned jtag_get_ntrst_delay(void)
+unsigned int jtag_get_ntrst_delay(void)
{
return jtag_ntrst_delay;
}
-
-void jtag_set_nsrst_assert_width(unsigned delay)
+void jtag_set_nsrst_assert_width(unsigned int delay)
{
adapter_nsrst_assert_width = delay;
}
-unsigned jtag_get_nsrst_assert_width(void)
+unsigned int jtag_get_nsrst_assert_width(void)
{
return adapter_nsrst_assert_width;
}
-void jtag_set_ntrst_assert_width(unsigned delay)
+void jtag_set_ntrst_assert_width(unsigned int delay)
{
jtag_ntrst_assert_width = delay;
}
-unsigned jtag_get_ntrst_assert_width(void)
+unsigned int jtag_get_ntrst_assert_width(void)
{
return jtag_ntrst_assert_width;
}
diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c
index b28ce62..489cb24 100644
--- a/src/jtag/drivers/amt_jtagaccel.c
+++ b/src/jtag/drivers/amt_jtagaccel.c
@@ -203,7 +203,7 @@ static void amt_jtagaccel_state_move(void)
tap_set_state(end_state);
}
-static void amt_jtagaccel_runtest(int num_cycles)
+static void amt_jtagaccel_runtest(unsigned int num_cycles)
{
int i = 0;
uint8_t aw_scan_tms_5;
diff --git a/src/jtag/drivers/angie.c b/src/jtag/drivers/angie.c
index 81dd1af..47628fe 100644
--- a/src/jtag/drivers/angie.c
+++ b/src/jtag/drivers/angie.c
@@ -1836,15 +1836,17 @@ static int angie_reset(int trst, int srst)
*/
static int angie_queue_pathmove(struct angie *device, struct jtag_command *cmd)
{
- int ret, i, num_states, batch_size, state_count;
+ int ret, state_count;
tap_state_t *path;
uint8_t tms_sequence;
- num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
path = cmd->cmd.pathmove->path;
state_count = 0;
while (num_states > 0) {
+ unsigned int batch_size;
+
tms_sequence = 0;
/* Determine batch size */
@@ -1853,7 +1855,7 @@ static int angie_queue_pathmove(struct angie *device, struct jtag_command *cmd)
else
batch_size = num_states;
- for (i = 0; i < batch_size; i++) {
+ for (unsigned int i = 0; i < batch_size; i++) {
if (tap_state_transition(tap_get_state(), false) == path[state_count]) {
/* Append '0' transition: clear bit 'i' in tms_sequence */
buf_set_u32(&tms_sequence, i, 1, 0x0);
@@ -1908,14 +1910,13 @@ static int angie_queue_sleep(struct angie *device, struct jtag_command *cmd)
static int angie_queue_stableclocks(struct angie *device, struct jtag_command *cmd)
{
int ret;
- unsigned int num_cycles;
if (!tap_is_state_stable(tap_get_state())) {
LOG_ERROR("JTAG_STABLECLOCKS: state not stable");
return ERROR_FAIL;
}
- num_cycles = cmd->cmd.stableclocks->num_cycles;
+ unsigned int num_cycles = cmd->cmd.stableclocks->num_cycles;
/* TMS stays either high (Test Logic Reset state) or low (all other states) */
if (tap_get_state() == TAP_RESET)
diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c
index 4c50c54..aaed16d 100644
--- a/src/jtag/drivers/arm-jtag-ew.c
+++ b/src/jtag/drivers/arm-jtag-ew.c
@@ -44,8 +44,8 @@ static uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE];
/* Queue command functions */
static void armjtagew_end_state(tap_state_t state);
static void armjtagew_state_move(void);
-static void armjtagew_path_move(int num_states, tap_state_t *path);
-static void armjtagew_runtest(int num_cycles);
+static void armjtagew_path_move(unsigned int num_states, tap_state_t *path);
+static void armjtagew_runtest(unsigned int num_cycles);
static void armjtagew_scan(bool ir_scan,
enum scan_type type,
uint8_t *buffer,
@@ -95,7 +95,7 @@ static int armjtagew_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i",
+ LOG_DEBUG_IO("runtest %u cycles, end in %i",
cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
@@ -111,7 +111,7 @@ static int armjtagew_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
@@ -279,11 +279,9 @@ static void armjtagew_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void armjtagew_path_move(int num_states, tap_state_t *path)
+static void armjtagew_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
-
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
/*
* TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.
* Either handle that here, or update the documentation with examples
@@ -305,10 +303,8 @@ static void armjtagew_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-static void armjtagew_runtest(int num_cycles)
+static void armjtagew_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -318,7 +314,7 @@ static void armjtagew_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
armjtagew_tap_append_step(0, 0);
/* finish in end_state */
diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c
index 3d839e6..e416592 100644
--- a/src/jtag/drivers/bitbang.c
+++ b/src/jtag/drivers/bitbang.c
@@ -33,7 +33,7 @@
* this function checks the current stable state to decide on the value of TMS
* to use.
*/
-static int bitbang_stableclocks(int num_cycles);
+static int bitbang_stableclocks(unsigned int num_cycles);
static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
@@ -95,7 +95,7 @@ static int bitbang_execute_tms(struct jtag_command *cmd)
unsigned num_bits = cmd->cmd.tms->num_bits;
const uint8_t *bits = cmd->cmd.tms->bits;
- LOG_DEBUG_IO("TMS: %d bits", num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", num_bits);
int tms = 0;
for (unsigned i = 0; i < num_bits; i++) {
@@ -113,7 +113,7 @@ static int bitbang_execute_tms(struct jtag_command *cmd)
static int bitbang_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
int tms = 0;
@@ -147,10 +147,8 @@ static int bitbang_path_move(struct pathmove_command *cmd)
return ERROR_OK;
}
-static int bitbang_runtest(int num_cycles)
+static int bitbang_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -161,7 +159,7 @@ static int bitbang_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
if (bitbang_interface->write(0, 0, 0) != ERROR_OK)
return ERROR_FAIL;
if (bitbang_interface->write(1, 0, 0) != ERROR_OK)
@@ -179,13 +177,12 @@ static int bitbang_runtest(int num_cycles)
return ERROR_OK;
}
-static int bitbang_stableclocks(int num_cycles)
+static int bitbang_stableclocks(unsigned int num_cycles)
{
int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
- int i;
/* send num_cycles clocks onto the cable */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
return ERROR_FAIL;
if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
@@ -319,7 +316,7 @@ int bitbang_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
bitbang_end_state(cmd->cmd.runtest->end_state);
@@ -343,7 +340,7 @@ int bitbang_execute_queue(struct jtag_command *cmd_queue)
return ERROR_FAIL;
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s",
+ LOG_DEBUG_IO("pathmove: %u states, end in %s",
cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
if (bitbang_path_move(cmd->cmd.pathmove) != ERROR_OK)
diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c
index 2e5cca2..ef870e6 100644
--- a/src/jtag/drivers/bitq.c
+++ b/src/jtag/drivers/bitq.c
@@ -18,8 +18,8 @@ struct bitq_interface *bitq_interface; /* low level bit queue interface */
/* state of input queue */
struct bitq_state {
struct jtag_command *cmd; /* command currently processed */
- int field_idx; /* index of field currently being processed */
- int bit_pos; /* position of bit currently being processed */
+ unsigned int field_idx; /* index of field currently being processed */
+ unsigned int bit_pos; /* position of bit currently being processed */
int status; /* processing status */
};
static struct bitq_state bitq_in_state;
@@ -108,9 +108,7 @@ static void bitq_state_move(tap_state_t new_state)
static void bitq_path_move(struct pathmove_command *cmd)
{
- int i;
-
- for (i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
bitq_io(0, 0, 0);
else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
@@ -127,16 +125,14 @@ static void bitq_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void bitq_runtest(int num_cycles)
+static void bitq_runtest(unsigned int num_cycles)
{
- int i;
-
/* only do a state_move when we're not already in IDLE */
if (tap_get_state() != TAP_IDLE)
bitq_state_move(TAP_IDLE);
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
bitq_io(0, 0, 0);
/* finish in end_state */
@@ -146,11 +142,10 @@ static void bitq_runtest(int num_cycles)
static void bitq_scan_field(struct scan_field *field, int do_pause)
{
- int bit_cnt;
int tdo_req;
const uint8_t *out_ptr;
- uint8_t out_mask;
+ uint8_t out_mask;
if (field->in_value)
tdo_req = 1;
@@ -159,7 +154,7 @@ static void bitq_scan_field(struct scan_field *field, int do_pause)
if (!field->out_value) {
/* just send zeros and request data from TDO */
- for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
+ for (unsigned int i = 0; i < (field->num_bits - 1); i++)
bitq_io(0, 0, tdo_req);
bitq_io(do_pause, 0, tdo_req);
@@ -167,7 +162,7 @@ static void bitq_scan_field(struct scan_field *field, int do_pause)
/* send data, and optionally request TDO */
out_mask = 0x01;
out_ptr = field->out_value;
- for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--) {
+ for (unsigned int i = 0; i < (field->num_bits - 1); i++) {
bitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req);
if (out_mask == 0x80) {
out_mask = 0x01;
@@ -190,13 +185,12 @@ static void bitq_scan_field(struct scan_field *field, int do_pause)
static void bitq_scan(struct scan_command *cmd)
{
- int i;
-
if (cmd->ir_scan)
bitq_state_move(TAP_IRSHIFT);
else
bitq_state_move(TAP_DRSHIFT);
+ unsigned int i;
for (i = 0; i < cmd->num_fields - 1; i++)
bitq_scan_field(&cmd->fields[i], 0);
@@ -226,7 +220,7 @@ int bitq_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
bitq_end_state(cmd->cmd.runtest->end_state);
bitq_runtest(cmd->cmd.runtest->num_cycles);
break;
@@ -238,7 +232,7 @@ int bitq_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
+ LOG_DEBUG_IO("pathmove: %u states, end in %i", cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
bitq_path_move(cmd->cmd.pathmove);
break;
diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c
index 3b03337..b01a796 100644
--- a/src/jtag/drivers/buspirate.c
+++ b/src/jtag/drivers/buspirate.c
@@ -27,11 +27,11 @@ static int buspirate_reset(int trst, int srst);
static void buspirate_end_state(tap_state_t state);
static void buspirate_state_move(void);
-static void buspirate_path_move(int num_states, tap_state_t *path);
-static void buspirate_runtest(int num_cycles);
+static void buspirate_path_move(unsigned int num_states, tap_state_t *path);
+static void buspirate_runtest(unsigned int num_cycles);
static void buspirate_scan(bool ir_scan, enum scan_type type,
uint8_t *buffer, int scan_size, struct scan_command *command);
-static void buspirate_stableclocks(int num_cycles);
+static void buspirate_stableclocks(unsigned int num_cycles);
#define CMD_UNKNOWN 0x00
#define CMD_PORT_MODE 0x01
@@ -162,7 +162,7 @@ static int buspirate_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest
->end_state));
@@ -180,7 +180,7 @@ static int buspirate_execute_queue(struct jtag_command *cmd_queue)
buspirate_state_move();
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s",
+ LOG_DEBUG_IO("pathmove: %u states, end in %s",
cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove
->path[cmd->cmd.pathmove
@@ -210,7 +210,7 @@ static int buspirate_execute_queue(struct jtag_command *cmd_queue)
jtag_sleep(cmd->cmd.sleep->us);
break;
case JTAG_STABLECLOCKS:
- LOG_DEBUG_IO("stable clock %i cycles", cmd->cmd.stableclocks->num_cycles);
+ LOG_DEBUG_IO("stable clock %u cycles", cmd->cmd.stableclocks->num_cycles);
buspirate_stableclocks(cmd->cmd.stableclocks->num_cycles);
break;
default:
@@ -580,11 +580,9 @@ static void buspirate_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void buspirate_path_move(int num_states, tap_state_t *path)
+static void buspirate_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
-
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (tap_state_transition(tap_get_state(), false) == path[i]) {
buspirate_tap_append(0, 0);
} else if (tap_state_transition(tap_get_state(), true)
@@ -604,10 +602,8 @@ static void buspirate_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-static void buspirate_runtest(int num_cycles)
+static void buspirate_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -616,7 +612,7 @@ static void buspirate_runtest(int num_cycles)
buspirate_state_move();
}
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
buspirate_tap_append(0, 0);
LOG_DEBUG_IO("runtest: cur_state %s end_state %s",
@@ -658,14 +654,13 @@ static void buspirate_scan(bool ir_scan, enum scan_type type,
buspirate_state_move();
}
-static void buspirate_stableclocks(int num_cycles)
+static void buspirate_stableclocks(unsigned int num_cycles)
{
- int i;
int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
buspirate_tap_make_space(0, num_cycles);
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
buspirate_tap_append(tms, 0);
}
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index d7367d8..a6dcfcd 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -1752,7 +1752,7 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd)
LOG_DEBUG("discarding trailing empty field");
}
- if (cmd->cmd.scan->num_fields == 0) {
+ if (!cmd->cmd.scan->num_fields) {
LOG_DEBUG("empty scan, doing nothing");
return;
}
@@ -1772,11 +1772,11 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd)
cmsis_dap_end_state(cmd->cmd.scan->end_state);
struct scan_field *field = cmd->cmd.scan->fields;
- unsigned scan_size = 0;
+ unsigned int scan_size = 0;
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
scan_size += field->num_bits;
- LOG_DEBUG_IO("%s%s field %d/%d %d bits",
+ LOG_DEBUG_IO("%s%s field %u/%u %u bits",
field->in_value ? "in" : "",
field->out_value ? "out" : "",
i,
@@ -1872,16 +1872,16 @@ static void cmsis_dap_execute_pathmove(struct jtag_command *cmd)
cmsis_dap_pathmove(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
}
-static void cmsis_dap_stableclocks(int num_cycles)
+static void cmsis_dap_stableclocks(unsigned int num_cycles)
{
uint8_t tms = tap_get_state() == TAP_RESET;
/* TODO: Perform optimizations? */
/* Execute num_cycles. */
- for (int i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
cmsis_dap_add_tms_sequence(&tms, 1);
}
-static void cmsis_dap_runtest(int num_cycles)
+static void cmsis_dap_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
@@ -1901,7 +1901,7 @@ static void cmsis_dap_runtest(int num_cycles)
static void cmsis_dap_execute_runtest(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
cmsis_dap_end_state(cmd->cmd.runtest->end_state);
@@ -1910,13 +1910,13 @@ static void cmsis_dap_execute_runtest(struct jtag_command *cmd)
static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("stableclocks %i cycles", cmd->cmd.runtest->num_cycles);
+ LOG_DEBUG_IO("stableclocks %u cycles", cmd->cmd.runtest->num_cycles);
cmsis_dap_stableclocks(cmd->cmd.runtest->num_cycles);
}
static void cmsis_dap_execute_tms(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", cmd->cmd.tms->num_bits);
cmsis_dap_cmd_dap_swj_sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
}
diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c
index e52816d..2aad4a0 100644
--- a/src/jtag/drivers/driver.c
+++ b/src/jtag/drivers/driver.c
@@ -259,7 +259,7 @@ int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state
return ERROR_OK;
}
-int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
+int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path)
{
/* allocate memory for a new list member */
struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
@@ -272,13 +272,13 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
cmd->cmd.pathmove->num_states = num_states;
cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);
- for (int i = 0; i < num_states; i++)
+ for (unsigned int i = 0; i < num_states; i++)
cmd->cmd.pathmove->path[i] = path[i];
return ERROR_OK;
}
-int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
+int interface_jtag_add_runtest(unsigned int num_cycles, tap_state_t state)
{
/* allocate memory for a new list member */
struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
@@ -294,7 +294,7 @@ int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
return ERROR_OK;
}
-int interface_jtag_add_clocks(int num_cycles)
+int interface_jtag_add_clocks(unsigned int num_cycles)
{
/* allocate memory for a new list member */
struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c
index 766f6dd..a4d072c 100644
--- a/src/jtag/drivers/ft232r.c
+++ b/src/jtag/drivers/ft232r.c
@@ -657,7 +657,7 @@ static int syncbb_execute_tms(struct jtag_command *cmd)
unsigned num_bits = cmd->cmd.tms->num_bits;
const uint8_t *bits = cmd->cmd.tms->bits;
- LOG_DEBUG_IO("TMS: %d bits", num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", num_bits);
int tms = 0;
for (unsigned i = 0; i < num_bits; i++) {
@@ -672,7 +672,7 @@ static int syncbb_execute_tms(struct jtag_command *cmd)
static void syncbb_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
int tms = 0;
@@ -702,9 +702,8 @@ static void syncbb_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void syncbb_runtest(int num_cycles)
+static void syncbb_runtest(unsigned int num_cycles)
{
- int i;
tap_state_t saved_end_state = tap_get_end_state();
@@ -715,7 +714,7 @@ static void syncbb_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
ft232r_write(0, 0, 0);
ft232r_write(1, 0, 0);
}
@@ -735,13 +734,12 @@ static void syncbb_runtest(int num_cycles)
* this function checks the current stable state to decide on the value of TMS
* to use.
*/
-static void syncbb_stableclocks(int num_cycles)
+static void syncbb_stableclocks(unsigned int num_cycles)
{
int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
- int i;
/* send num_cycles clocks onto the cable */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
ft232r_write(1, tms, 0);
ft232r_write(0, tms, 0);
}
@@ -832,7 +830,7 @@ static int syncbb_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %s", cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
syncbb_end_state(cmd->cmd.runtest->end_state);
@@ -854,7 +852,7 @@ static int syncbb_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
+ LOG_DEBUG_IO("pathmove: %u states, end in %s", cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
syncbb_path_move(cmd->cmd.pathmove);
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index 1793cbf..66d0d50 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -383,10 +383,9 @@ static void ftdi_end_state(tap_state_t state)
static void ftdi_execute_runtest(struct jtag_command *cmd)
{
- int i;
- static const uint8_t zero;
+ uint8_t zero = 0;
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
@@ -394,7 +393,7 @@ static void ftdi_execute_runtest(struct jtag_command *cmd)
move_to_state(TAP_IDLE);
/* TODO: Reuse ftdi_execute_stableclocks */
- i = cmd->cmd.runtest->num_cycles;
+ unsigned int i = cmd->cmd.runtest->num_cycles;
while (i > 0) {
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = i > 7 ? 7 : i;
@@ -407,7 +406,7 @@ static void ftdi_execute_runtest(struct jtag_command *cmd)
if (tap_get_state() != tap_get_end_state())
move_to_state(tap_get_end_state());
- LOG_DEBUG_IO("runtest: %i, end in %s",
+ LOG_DEBUG_IO("runtest: %u, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(tap_get_end_state()));
}
@@ -430,7 +429,7 @@ static void ftdi_execute_statemove(struct jtag_command *cmd)
*/
static void ftdi_execute_tms(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", cmd->cmd.tms->num_bits);
/* TODO: Missing tap state tracking, also missing from ft2232.c! */
DO_CLOCK_TMS_CS_OUT(mpsse_ctx,
@@ -444,9 +443,9 @@ static void ftdi_execute_tms(struct jtag_command *cmd)
static void ftdi_execute_pathmove(struct jtag_command *cmd)
{
tap_state_t *path = cmd->cmd.pathmove->path;
- int num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
- LOG_DEBUG_IO("pathmove: %i states, current: %s end: %s", num_states,
+ LOG_DEBUG_IO("pathmove: %u states, current: %s end: %s", num_states,
tap_state_name(tap_get_state()),
tap_state_name(path[num_states-1]));
@@ -504,7 +503,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
LOG_DEBUG_IO("discarding trailing empty field");
}
- if (cmd->cmd.scan->num_fields == 0) {
+ if (!cmd->cmd.scan->num_fields) {
LOG_DEBUG_IO("empty scan, doing nothing");
return;
}
@@ -522,9 +521,9 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
struct scan_field *field = cmd->cmd.scan->fields;
unsigned scan_size = 0;
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
scan_size += field->num_bits;
- LOG_DEBUG_IO("%s%s field %d/%d %d bits",
+ LOG_DEBUG_IO("%s%s field %u/%u %u bits",
field->in_value ? "in" : "",
field->out_value ? "out" : "",
i,
@@ -644,7 +643,7 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd)
/* this is only allowed while in a stable state. A check for a stable
* state was done in jtag_add_clocks()
*/
- int num_cycles = cmd->cmd.stableclocks->num_cycles;
+ unsigned int num_cycles = cmd->cmd.stableclocks->num_cycles;
/* 7 bits of either ones or zeros. */
uint8_t tms = tap_get_state() == TAP_RESET ? 0x7f : 0x00;
@@ -658,7 +657,7 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd)
num_cycles -= this_len;
}
- LOG_DEBUG_IO("clocks %i while in %s",
+ LOG_DEBUG_IO("clocks %u while in %s",
cmd->cmd.stableclocks->num_cycles,
tap_state_name(tap_get_state()));
}
diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c
index a4c6fd0..d0fe43f 100644
--- a/src/jtag/drivers/gw16012.c
+++ b/src/jtag/drivers/gw16012.c
@@ -185,10 +185,9 @@ static void gw16012_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void gw16012_runtest(int num_cycles)
+static void gw16012_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
- int i;
/* only do a state_move when we're not already in IDLE */
if (tap_get_state() != TAP_IDLE) {
@@ -196,7 +195,7 @@ static void gw16012_runtest(int num_cycles)
gw16012_state_move();
}
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
gw16012_control(0x0); /* single-bit mode */
gw16012_data(0x0); /* TMS cycle with TMS low */
}
@@ -292,7 +291,7 @@ static int gw16012_execute_queue(struct jtag_command *cmd_queue)
gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
gw16012_end_state(cmd->cmd.runtest->end_state);
gw16012_runtest(cmd->cmd.runtest->num_cycles);
diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index 1874557..a94f3a4 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -80,9 +80,9 @@ static struct device_config tmp_config;
/* Queue command functions */
static void jlink_end_state(tap_state_t state);
static void jlink_state_move(void);
-static void jlink_path_move(int num_states, tap_state_t *path);
-static void jlink_stableclocks(int num_cycles);
-static void jlink_runtest(int num_cycles);
+static void jlink_path_move(unsigned int num_states, tap_state_t *path);
+static void jlink_stableclocks(unsigned int num_cycles);
+static void jlink_runtest(unsigned int num_cycles);
static void jlink_reset(int trst, int srst);
static int jlink_reset_safe(int trst, int srst);
static int jlink_swd_run_queue(void);
@@ -140,7 +140,7 @@ static void jlink_execute_statemove(struct jtag_command *cmd)
static void jlink_execute_pathmove(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
@@ -159,7 +159,7 @@ static void jlink_execute_scan(struct jtag_command *cmd)
LOG_DEBUG("discarding trailing empty field");
}
- if (cmd->cmd.scan->num_fields == 0) {
+ if (!cmd->cmd.scan->num_fields) {
LOG_DEBUG("empty scan, doing nothing");
return;
}
@@ -181,9 +181,9 @@ static void jlink_execute_scan(struct jtag_command *cmd)
struct scan_field *field = cmd->cmd.scan->fields;
unsigned scan_size = 0;
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
scan_size += field->num_bits;
- LOG_DEBUG_IO("%s%s field %d/%d %d bits",
+ LOG_DEBUG_IO("%s%s field %u/%u %u bits",
field->in_value ? "in" : "",
field->out_value ? "out" : "",
i,
@@ -885,12 +885,11 @@ static void jlink_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void jlink_path_move(int num_states, tap_state_t *path)
+static void jlink_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
uint8_t tms = 0xff;
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false))
jlink_clock_data(NULL, 0, NULL, 0, NULL, 0, 1);
else if (path[i] == tap_state_transition(tap_get_state(), true))
@@ -907,17 +906,15 @@ static void jlink_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-static void jlink_stableclocks(int num_cycles)
+static void jlink_stableclocks(unsigned int num_cycles)
{
- int i;
-
uint8_t tms = tap_get_state() == TAP_RESET;
/* Execute num_cycles. */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1);
}
-static void jlink_runtest(int num_cycles)
+static void jlink_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
@@ -964,23 +961,18 @@ static int jlink_reset_safe(int trst, int srst)
COMMAND_HANDLER(jlink_usb_command)
{
- int tmp;
-
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) {
- command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
- }
+ unsigned int tmp;
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], tmp);
- if (tmp < JAYLINK_USB_ADDRESS_0 || tmp > JAYLINK_USB_ADDRESS_3) {
+ if (tmp > JAYLINK_USB_ADDRESS_3) {
command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
usb_address = tmp;
-
use_usb_address = true;
return ERROR_OK;
@@ -1038,38 +1030,35 @@ COMMAND_HANDLER(jlink_handle_free_memory_command)
COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
{
- int tmp;
- int version;
-
if (!CMD_ARGC) {
+ unsigned int version;
+
switch (jtag_command_version) {
- case JAYLINK_JTAG_VERSION_2:
- version = 2;
- break;
- case JAYLINK_JTAG_VERSION_3:
- version = 3;
- break;
- default:
- return ERROR_FAIL;
+ case JAYLINK_JTAG_VERSION_2:
+ version = 2;
+ break;
+ case JAYLINK_JTAG_VERSION_3:
+ version = 3;
+ break;
+ default:
+ return ERROR_FAIL;
}
- command_print(CMD, "JTAG command version: %i", version);
+ command_print(CMD, "JTAG command version: %u", version);
} else if (CMD_ARGC == 1) {
- if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) {
- command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
- }
+ uint8_t tmp;
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], tmp);
switch (tmp) {
- case 2:
- jtag_command_version = JAYLINK_JTAG_VERSION_2;
- break;
- case 3:
- jtag_command_version = JAYLINK_JTAG_VERSION_3;
- break;
- default:
- command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
+ case 2:
+ jtag_command_version = JAYLINK_JTAG_VERSION_2;
+ break;
+ case 3:
+ jtag_command_version = JAYLINK_JTAG_VERSION_3;
+ break;
+ default:
+ command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
+ return ERROR_COMMAND_ARGUMENT_INVALID;
}
} else {
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1080,10 +1069,7 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
COMMAND_HANDLER(jlink_handle_target_power_command)
{
- int ret;
- int enable;
-
- if (CMD_ARGC != 1)
+ if (CMD_ARGC > 1)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) {
@@ -1092,16 +1078,24 @@ COMMAND_HANDLER(jlink_handle_target_power_command)
return ERROR_OK;
}
- if (!strcmp(CMD_ARGV[0], "on")) {
- enable = true;
- } else if (!strcmp(CMD_ARGV[0], "off")) {
- enable = false;
- } else {
- command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
- return ERROR_FAIL;
+ if (!CMD_ARGC) {
+ uint32_t state;
+ int ret = jaylink_get_hardware_info(devh, JAYLINK_HW_INFO_TARGET_POWER,
+ &state);
+
+ if (ret != JAYLINK_OK) {
+ command_print(CMD, "Failed to retrieve target power state");
+ return ERROR_FAIL;
+ }
+
+ command_print(CMD, "%d", (bool)state);
+ return ERROR_OK;
}
- ret = jaylink_set_target_power(devh, enable);
+ bool enable;
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
+
+ int ret = jaylink_set_target_power(devh, enable);
if (ret != JAYLINK_OK) {
command_print(CMD, "jaylink_set_target_power() failed: %s",
@@ -1410,8 +1404,6 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
COMMAND_HANDLER(jlink_handle_config_usb_address_command)
{
- uint8_t tmp;
-
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
command_print(CMD, "Reading configuration is not supported by the "
"device");
@@ -1421,10 +1413,8 @@ COMMAND_HANDLER(jlink_handle_config_usb_address_command)
if (!CMD_ARGC) {
show_config_usb_address(CMD);
} else if (CMD_ARGC == 1) {
- if (sscanf(CMD_ARGV[0], "%" SCNd8, &tmp) != 1) {
- command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
- }
+ uint8_t tmp;
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], tmp);
if (tmp > JAYLINK_USB_ADDRESS_3) {
command_print(CMD, "Invalid USB address: %u", tmp);
@@ -1883,7 +1873,7 @@ static const struct command_registration jlink_subcommand_handlers[] = {
.handler = &jlink_handle_target_power_command,
.mode = COMMAND_EXEC,
.help = "set the target power supply",
- .usage = "<on|off>"
+ .usage = "[0|1|on|off]"
},
{
.name = "freemem",
diff --git a/src/jtag/drivers/jtag_dpi.c b/src/jtag/drivers/jtag_dpi.c
index 285f96e..046186a 100644
--- a/src/jtag/drivers/jtag_dpi.c
+++ b/src/jtag/drivers/jtag_dpi.c
@@ -163,7 +163,7 @@ out:
return ret;
}
-static int jtag_dpi_runtest(int cycles)
+static int jtag_dpi_runtest(unsigned int num_cycles)
{
char buf[20];
uint8_t *data_buf = last_ir_buf, *read_scan;
@@ -189,7 +189,7 @@ static int jtag_dpi_runtest(int cycles)
return ERROR_FAIL;
}
snprintf(buf, sizeof(buf), "ib %d\n", num_bits);
- while (cycles > 0) {
+ while (num_cycles > 0) {
ret = write_sock(buf, strlen(buf));
if (ret != ERROR_OK) {
LOG_ERROR("write_sock() fail, file %s, line %d",
@@ -209,7 +209,7 @@ static int jtag_dpi_runtest(int cycles)
goto out;
}
- cycles -= num_bits + 6;
+ num_cycles -= num_bits + 6;
}
out:
@@ -217,9 +217,9 @@ out:
return ret;
}
-static int jtag_dpi_stableclocks(int cycles)
+static int jtag_dpi_stableclocks(unsigned int num_cycles)
{
- return jtag_dpi_runtest(cycles);
+ return jtag_dpi_runtest(num_cycles);
}
static int jtag_dpi_execute_queue(struct jtag_command *cmd_queue)
diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c
index 9dec0d1..a19060c 100644
--- a/src/jtag/drivers/jtag_vpi.c
+++ b/src/jtag/drivers/jtag_vpi.c
@@ -254,7 +254,7 @@ static int jtag_vpi_path_move(struct pathmove_command *cmd)
memset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8));
- for (int i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
buf_set_u32(trans, i, 1, 1);
tap_set_state(cmd->path[i]);
@@ -440,7 +440,7 @@ static int jtag_vpi_scan(struct scan_command *cmd)
return ERROR_OK;
}
-static int jtag_vpi_runtest(int cycles, tap_state_t state)
+static int jtag_vpi_runtest(unsigned int num_cycles, tap_state_t state)
{
int retval;
@@ -448,22 +448,20 @@ static int jtag_vpi_runtest(int cycles, tap_state_t state)
if (retval != ERROR_OK)
return retval;
- retval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT);
+ retval = jtag_vpi_queue_tdi(NULL, num_cycles, NO_TAP_SHIFT);
if (retval != ERROR_OK)
return retval;
return jtag_vpi_state_move(state);
}
-static int jtag_vpi_stableclocks(int cycles)
+static int jtag_vpi_stableclocks(unsigned int num_cycles)
{
uint8_t tms_bits[4];
- int cycles_remain = cycles;
+ unsigned int cycles_remain = num_cycles;
int nb_bits;
int retval;
- const int CYCLES_ONE_BATCH = sizeof(tms_bits) * 8;
-
- assert(cycles >= 0);
+ const unsigned int CYCLES_ONE_BATCH = sizeof(tms_bits) * 8;
/* use TMS=1 in TAP RESET state, TMS=0 in all other stable states */
memset(&tms_bits, (tap_get_state() == TAP_RESET) ? 0xff : 0x00, sizeof(tms_bits));
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index f3499e3..3decddb 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -283,6 +283,9 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t vids[], c
case 0x3300:
ctx->type = TYPE_FT232HP;
break;
+ case 0x3600:
+ ctx->type = TYPE_FT4232HA;
+ break;
default:
LOG_ERROR("unsupported FTDI chip type: 0x%04x", desc.bcdDevice);
goto error;
diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h
index e92a9bb..737560d 100644
--- a/src/jtag/drivers/mpsse.h
+++ b/src/jtag/drivers/mpsse.h
@@ -30,6 +30,7 @@ enum ftdi_chip_type {
TYPE_FT4232HP,
TYPE_FT233HP,
TYPE_FT232HP,
+ TYPE_FT4232HA,
};
struct mpsse_ctx;
diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c
index 81b74d4..e828d46 100644
--- a/src/jtag/drivers/opendous.c
+++ b/src/jtag/drivers/opendous.c
@@ -106,8 +106,8 @@ static int opendous_quit(void);
/* Queue command functions */
static void opendous_end_state(tap_state_t state);
static void opendous_state_move(void);
-static void opendous_path_move(int num_states, tap_state_t *path);
-static void opendous_runtest(int num_cycles);
+static void opendous_path_move(unsigned int num_states, tap_state_t *path);
+static void opendous_runtest(unsigned int num_cycles);
static void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer,
int scan_size, struct scan_command *command);
static void opendous_reset(int trst, int srst);
@@ -248,7 +248,7 @@ static int opendous_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
if (cmd->cmd.runtest->end_state != -1)
@@ -265,7 +265,7 @@ static int opendous_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
@@ -419,11 +419,9 @@ void opendous_state_move(void)
tap_set_state(tap_get_end_state());
}
-void opendous_path_move(int num_states, tap_state_t *path)
+void opendous_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
-
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false))
opendous_tap_append_step(0, 0);
else if (path[i] == tap_state_transition(tap_get_state(), true))
@@ -440,10 +438,8 @@ void opendous_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-void opendous_runtest(int num_cycles)
+void opendous_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -453,7 +449,7 @@ void opendous_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
opendous_tap_append_step(0, 0);
/* finish in end_state */
diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c
index ea78ca8..0ae885e 100644
--- a/src/jtag/drivers/openjtag.c
+++ b/src/jtag/drivers/openjtag.c
@@ -760,15 +760,17 @@ static void openjtag_execute_runtest(struct jtag_command *cmd)
if (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 ||
cmd->cmd.runtest->num_cycles) {
uint8_t command;
- int cycles = cmd->cmd.runtest->num_cycles;
+ unsigned int num_cycles = cmd->cmd.runtest->num_cycles;
do {
+ const unsigned int num_cycles_cmd = MIN(num_cycles, 16);
+
command = 7;
- command |= (((cycles > 16 ? 16 : cycles) - 1) & 0x0F) << 4;
+ command |= ((num_cycles_cmd - 1) & 0x0F) << 4;
openjtag_add_byte(command);
- cycles -= 16;
- } while (cycles > 0);
+ num_cycles -= num_cycles_cmd;
+ } while (num_cycles > 0);
}
tap_set_end_state(end_state);
diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c
index 8d4fc90..c41a0e1 100644
--- a/src/jtag/drivers/osbdm.c
+++ b/src/jtag/drivers/osbdm.c
@@ -381,7 +381,7 @@ static int osbdm_quit(void)
static int osbdm_add_pathmove(
struct queue *queue,
tap_state_t *path,
- int num_states)
+ unsigned int num_states)
{
assert(num_states <= 32);
@@ -392,7 +392,7 @@ static int osbdm_add_pathmove(
}
uint32_t tms = 0;
- for (int i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (tap_state_transition(tap_get_state(), 1) == path[i]) {
tms |= (1 << i);
} else if (tap_state_transition(tap_get_state(), 0) == path[i]) {
@@ -451,7 +451,7 @@ static int osbdm_add_statemove(
static int osbdm_add_stableclocks(
struct queue *queue,
- int count)
+ unsigned int count)
{
if (!tap_is_state_stable(tap_get_state())) {
LOG_ERROR("BUG: current state (%s) is not stable",
@@ -489,7 +489,7 @@ static int osbdm_add_tms(
static int osbdm_add_scan(
struct queue *queue,
struct scan_field *fields,
- int num_fields,
+ unsigned int num_fields,
tap_state_t end_state,
bool ir_scan)
{
@@ -508,7 +508,7 @@ static int osbdm_add_scan(
/* Add scan */
tap_set_end_state(end_state);
- for (int idx = 0; idx < num_fields; idx++) {
+ for (unsigned int idx = 0; idx < num_fields; idx++) {
struct sequence *next = queue_add_tail(queue, fields[idx].num_bits);
if (!next) {
LOG_ERROR("Can't allocate bit sequence");
@@ -536,7 +536,7 @@ static int osbdm_add_scan(
static int osbdm_add_runtest(
struct queue *queue,
- int num_cycles,
+ unsigned int num_cycles,
tap_state_t end_state)
{
if (osbdm_add_statemove(queue, TAP_IDLE, 0) != ERROR_OK)
diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c
index afdf16e..f4a4fcb 100644
--- a/src/jtag/drivers/rlink.c
+++ b/src/jtag/drivers/rlink.c
@@ -869,7 +869,7 @@ static void rlink_state_move(void)
static void rlink_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
int tms = 0;
@@ -896,10 +896,8 @@ static void rlink_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void rlink_runtest(int num_cycles)
+static void rlink_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in RTI */
@@ -909,7 +907,7 @@ static void rlink_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
tap_state_queue_append(0);
/* finish in end_state */
@@ -1323,7 +1321,7 @@ static int rlink_execute_queue(struct jtag_command *cmd_queue)
rlink_state_move();
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
rlink_path_move(cmd->cmd.pathmove);
diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c
index 0fe8989..ad3bc6e 100644
--- a/src/jtag/drivers/ulink.c
+++ b/src/jtag/drivers/ulink.c
@@ -1701,15 +1701,17 @@ static int ulink_queue_reset(struct ulink *device, struct jtag_command *cmd)
*/
static int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd)
{
- int ret, i, num_states, batch_size, state_count;
+ int ret, state_count;
tap_state_t *path;
uint8_t tms_sequence;
- num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
path = cmd->cmd.pathmove->path;
state_count = 0;
while (num_states > 0) {
+ unsigned int batch_size;
+
tms_sequence = 0;
/* Determine batch size */
@@ -1718,7 +1720,7 @@ static int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd)
else
batch_size = num_states;
- for (i = 0; i < batch_size; i++) {
+ for (unsigned int i = 0; i < batch_size; i++) {
if (tap_state_transition(tap_get_state(), false) == path[state_count]) {
/* Append '0' transition: clear bit 'i' in tms_sequence */
buf_set_u32(&tms_sequence, i, 1, 0x0);
@@ -1774,14 +1776,13 @@ static int ulink_queue_sleep(struct ulink *device, struct jtag_command *cmd)
static int ulink_queue_stableclocks(struct ulink *device, struct jtag_command *cmd)
{
int ret;
- unsigned num_cycles;
if (!tap_is_state_stable(tap_get_state())) {
LOG_ERROR("JTAG_STABLECLOCKS: state not stable");
return ERROR_FAIL;
}
- num_cycles = cmd->cmd.stableclocks->num_cycles;
+ unsigned int num_cycles = cmd->cmd.stableclocks->num_cycles;
/* TMS stays either high (Test Logic Reset state) or low (all other states) */
if (tap_get_state() == TAP_RESET)
diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c
index c84055c..53dd158 100644
--- a/src/jtag/drivers/usb_blaster/usb_blaster.c
+++ b/src/jtag/drivers/usb_blaster/usb_blaster.c
@@ -474,11 +474,9 @@ static void ublast_tms(struct tms_command *cmd)
*/
static void ublast_path_move(struct pathmove_command *cmd)
{
- int i;
-
- LOG_DEBUG_IO("(num_states=%d, last_state=%d)",
+ LOG_DEBUG_IO("(num_states=%u, last_state=%d)",
cmd->num_states, cmd->path[cmd->num_states - 1]);
- for (i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
ublast_clock_tms(0);
if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
@@ -675,19 +673,19 @@ static void ublast_queue_tdi(uint8_t *bits, int nb_bits, enum scan_type scan)
ublast_idle_clock();
}
-static void ublast_runtest(int cycles, tap_state_t state)
+static void ublast_runtest(unsigned int num_cycles, tap_state_t state)
{
- LOG_DEBUG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state);
+ LOG_DEBUG_IO("%s(cycles=%u, end_state=%d)", __func__, num_cycles, state);
ublast_state_move(TAP_IDLE, 0);
- ublast_queue_tdi(NULL, cycles, SCAN_OUT);
+ ublast_queue_tdi(NULL, num_cycles, SCAN_OUT);
ublast_state_move(state, 0);
}
-static void ublast_stableclocks(int cycles)
+static void ublast_stableclocks(unsigned int num_cycles)
{
- LOG_DEBUG_IO("%s(cycles=%i)", __func__, cycles);
- ublast_queue_tdi(NULL, cycles, SCAN_OUT);
+ LOG_DEBUG_IO("%s(cycles=%u)", __func__, num_cycles);
+ ublast_queue_tdi(NULL, num_cycles, SCAN_OUT);
}
/**
diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c
index 2d666d0..6e3b3ba 100644
--- a/src/jtag/drivers/usbprog.c
+++ b/src/jtag/drivers/usbprog.c
@@ -37,7 +37,7 @@
static void usbprog_end_state(tap_state_t state);
static void usbprog_state_move(void);
static void usbprog_path_move(struct pathmove_command *cmd);
-static void usbprog_runtest(int num_cycles);
+static void usbprog_runtest(unsigned int num_cycles);
static void usbprog_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size);
#define UNKNOWN_COMMAND 0x00
@@ -101,7 +101,7 @@ static int usbprog_execute_queue(struct jtag_command *cmd_queue)
usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i",
+ LOG_DEBUG_IO("runtest %u cycles, end in %i",
cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
usbprog_end_state(cmd->cmd.runtest->end_state);
@@ -113,7 +113,7 @@ static int usbprog_execute_queue(struct jtag_command *cmd_queue)
usbprog_state_move();
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
usbprog_path_move(cmd->cmd.pathmove);
@@ -189,7 +189,7 @@ static void usbprog_state_move(void)
static void usbprog_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
/* There may be queued transitions, and before following a specified
@@ -222,10 +222,8 @@ static void usbprog_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void usbprog_runtest(int num_cycles)
+static void usbprog_runtest(unsigned int num_cycles)
{
- int i;
-
/* only do a state_move when we're not already in IDLE */
if (tap_get_state() != TAP_IDLE) {
usbprog_end_state(TAP_IDLE);
@@ -241,7 +239,7 @@ static void usbprog_runtest(int num_cycles)
/* LOG_INFO("NUM CYCLES %i",num_cycles); */
}
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
usbprog_write(1, 0, 0);
usbprog_write(0, 0, 0);
}
diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c
index f1fc453..691e576 100644
--- a/src/jtag/drivers/vdebug.c
+++ b/src/jtag/drivers/vdebug.c
@@ -931,11 +931,11 @@ static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush)
static int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush)
{
uint8_t tms[DIV_ROUND_UP(cmd->num_states, 8)];
- LOG_DEBUG_IO("path num states %d", cmd->num_states);
+ LOG_DEBUG_IO("path num states %u", cmd->num_states);
memset(tms, 0, DIV_ROUND_UP(cmd->num_states, 8));
- for (uint8_t i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
buf_set_u32(tms, i, 1, 1);
tap_set_state(cmd->path[i]);
@@ -970,10 +970,10 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)
uint8_t num_pre = tap_get_tms_path_len(cur, state);
uint8_t tms_post = tap_get_tms_path(state, cmd->end_state);
uint8_t num_post = tap_get_tms_path_len(state, cmd->end_state);
- int num_bits = jtag_scan_size(cmd);
- LOG_DEBUG_IO("scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x",
+ const unsigned int num_bits = jtag_scan_size(cmd);
+ LOG_DEBUG_IO("scan len:%u fields:%u ir/!dr:%d state cur:%x end:%x",
num_bits, cmd->num_fields, cmd->ir_scan, cur, cmd->end_state);
- for (int i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
uint8_t cur_num_pre = i == 0 ? num_pre : 0;
uint8_t cur_tms_pre = i == 0 ? tms_pre : 0;
uint8_t cur_num_post = i == cmd->num_fields - 1 ? num_post : 0;
@@ -992,24 +992,24 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)
return rc;
}
-static int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush)
+static int vdebug_jtag_runtest(unsigned int num_cycles, tap_state_t state, uint8_t f_flush)
{
tap_state_t cur = tap_get_state();
uint8_t tms_pre = tap_get_tms_path(cur, state);
uint8_t num_pre = tap_get_tms_path_len(cur, state);
- LOG_DEBUG_IO("idle len:%d state cur:%x end:%x", cycles, cur, state);
- int rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, cycles, NULL, 0, 0, NULL, f_flush);
+ LOG_DEBUG_IO("idle len:%u state cur:%x end:%x", num_cycles, cur, state);
+ int rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, num_cycles, NULL, 0, 0, NULL, f_flush);
if (cur != state)
tap_set_state(state);
return rc;
}
-static int vdebug_jtag_stableclocks(int num, uint8_t f_flush)
+static int vdebug_jtag_stableclocks(unsigned int num_cycles, uint8_t f_flush)
{
- LOG_DEBUG("stab len:%d state cur:%x", num, tap_get_state());
+ LOG_DEBUG("stab len:%u state cur:%x", num_cycles, tap_get_state());
- return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num, NULL, 0, 0, NULL, f_flush);
+ return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num_cycles, NULL, 0, 0, NULL, f_flush);
}
static int vdebug_sleep(int us)
diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c
index 34525d5..ca14217 100644
--- a/src/jtag/drivers/vsllink.c
+++ b/src/jtag/drivers/vsllink.c
@@ -43,10 +43,10 @@ static struct pending_scan_result
/* Queue command functions */
static void vsllink_end_state(tap_state_t state);
static void vsllink_state_move(void);
-static void vsllink_path_move(int num_states, tap_state_t *path);
+static void vsllink_path_move(unsigned int num_states, tap_state_t *path);
static void vsllink_tms(int num_bits, const uint8_t *bits);
-static void vsllink_runtest(int num_cycles);
-static void vsllink_stableclocks(int num_cycles, int tms);
+static void vsllink_runtest(unsigned int num_cycles);
+static void vsllink_stableclocks(unsigned int num_cycles, int tms);
static void vsllink_scan(bool ir_scan, enum scan_type type,
uint8_t *buffer, int scan_size, struct scan_command *command);
static int vsllink_reset(int trst, int srst);
@@ -98,7 +98,7 @@ static int vsllink_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
@@ -115,7 +115,7 @@ static int vsllink_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s",
+ LOG_DEBUG_IO("pathmove: %u states, end in %s",
cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
@@ -161,7 +161,7 @@ static int vsllink_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_STABLECLOCKS:
- LOG_DEBUG_IO("add %d clocks",
+ LOG_DEBUG_IO("add %u clocks",
cmd->cmd.stableclocks->num_cycles);
switch (tap_get_state()) {
@@ -371,9 +371,9 @@ static void vsllink_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void vsllink_path_move(int num_states, tap_state_t *path)
+static void vsllink_path_move(unsigned int num_states, tap_state_t *path)
{
- for (int i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false))
vsllink_tap_append_step(0, 0);
else if (path[i] == tap_state_transition(tap_get_state(), true))
@@ -397,7 +397,7 @@ static void vsllink_tms(int num_bits, const uint8_t *bits)
vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
}
-static void vsllink_stableclocks(int num_cycles, int tms)
+static void vsllink_stableclocks(unsigned int num_cycles, int tms)
{
while (num_cycles > 0) {
vsllink_tap_append_step(tms, 0);
@@ -405,7 +405,7 @@ static void vsllink_stableclocks(int num_cycles, int tms)
}
}
-static void vsllink_runtest(int num_cycles)
+static void vsllink_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c
index 11fbaaa..f252087 100644
--- a/src/jtag/drivers/xds110.c
+++ b/src/jtag/drivers/xds110.c
@@ -1669,7 +1669,6 @@ static void xds110_execute_tlr_reset(struct jtag_command *cmd)
static void xds110_execute_pathmove(struct jtag_command *cmd)
{
- uint32_t i;
uint32_t num_states;
uint8_t *path;
@@ -1685,7 +1684,7 @@ static void xds110_execute_pathmove(struct jtag_command *cmd)
}
/* Convert requested path states into XDS API states */
- for (i = 0; i < num_states; i++)
+ for (unsigned int i = 0; i < num_states; i++)
path[i] = (uint8_t)xds_jtag_state[cmd->cmd.pathmove->path[i]];
if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
@@ -1704,7 +1703,6 @@ static void xds110_execute_pathmove(struct jtag_command *cmd)
static void xds110_queue_scan(struct jtag_command *cmd)
{
- int i;
uint32_t offset;
uint32_t total_fields;
uint32_t total_bits;
@@ -1715,7 +1713,7 @@ static void xds110_queue_scan(struct jtag_command *cmd)
/* Calculate the total number of bits to scan */
total_bits = 0;
total_fields = 0;
- for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++) {
total_fields++;
total_bits += (uint32_t)cmd->cmd.scan->fields[i].num_bits;
}
@@ -1756,7 +1754,7 @@ static void xds110_queue_scan(struct jtag_command *cmd)
buffer = &xds110.txn_requests[xds110.txn_request_size];
/* Clear data out buffer to default value of all zeros */
memset((void *)buffer, 0x00, total_bytes);
- for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++) {
if (cmd->cmd.scan->fields[i].out_value) {
/* Copy over data to scan out into request buffer */
bit_copy(buffer, offset, cmd->cmd.scan->fields[i].out_value, 0,
@@ -1775,7 +1773,7 @@ static void xds110_queue_scan(struct jtag_command *cmd)
static void xds110_queue_runtest(struct jtag_command *cmd)
{
- uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
+ uint32_t clocks = cmd->cmd.stableclocks->num_cycles;
uint8_t end_state = (uint8_t)xds_jtag_state[cmd->cmd.runtest->end_state];
/* Check if new request would be too large to fit */
@@ -1794,7 +1792,7 @@ static void xds110_queue_runtest(struct jtag_command *cmd)
static void xds110_queue_stableclocks(struct jtag_command *cmd)
{
- uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
+ uint32_t clocks = cmd->cmd.stableclocks->num_cycles;
/* Check if new request would be too large to fit */
if ((xds110.txn_request_size + 1 + sizeof(clocks) + 1) > MAX_DATA_BLOCK)
diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c
index 233ade3..b5c7e2f 100644
--- a/src/jtag/drivers/xlnx-pcie-xvc.c
+++ b/src/jtag/drivers/xlnx-pcie-xvc.c
@@ -128,7 +128,7 @@ static int xlnx_pcie_xvc_execute_stableclocks(struct jtag_command *cmd)
size_t write;
int err;
- LOG_DEBUG("stableclocks %i cycles", cmd->cmd.runtest->num_cycles);
+ LOG_DEBUG("stableclocks %u cycles", cmd->cmd.runtest->num_cycles);
while (left) {
write = MIN(XLNX_XVC_MAX_BITS, left);
@@ -167,7 +167,7 @@ static int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd)
{
int err = ERROR_OK;
- LOG_DEBUG("runtest %i cycles, end in %i",
+ LOG_DEBUG("runtest %u cycles, end in %i",
cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
@@ -200,16 +200,15 @@ static int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd)
static int xlnx_pcie_xvc_execute_pathmove(struct jtag_command *cmd)
{
- size_t num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
tap_state_t *path = cmd->cmd.pathmove->path;
int err = ERROR_OK;
- size_t i;
- LOG_DEBUG("pathmove: %i states, end in %i",
+ LOG_DEBUG("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false)) {
err = xlnx_pcie_xvc_transact(1, 1, 0, NULL);
} else if (path[i] == tap_state_transition(tap_get_state(), true)) {
diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c
index 6ac6801..c73f6c8 100644
--- a/src/jtag/hla/hla_interface.c
+++ b/src/jtag/hla/hla_interface.c
@@ -319,37 +319,37 @@ COMMAND_HANDLER(interface_handle_hla_command)
return ERROR_OK;
}
-static const struct command_registration hl_interface_command_handlers[] = {
+static const struct command_registration hl_interface_subcommand_handlers[] = {
{
- .name = "hla_device_desc",
+ .name = "device_desc",
.handler = &hl_interface_handle_device_desc_command,
.mode = COMMAND_CONFIG,
.help = "set the device description of the adapter",
.usage = "description_string",
},
{
- .name = "hla_layout",
+ .name = "layout",
.handler = &hl_interface_handle_layout_command,
.mode = COMMAND_CONFIG,
.help = "set the layout of the adapter",
.usage = "layout_name",
},
{
- .name = "hla_vid_pid",
+ .name = "vid_pid",
.handler = &hl_interface_handle_vid_pid_command,
.mode = COMMAND_CONFIG,
.help = "the vendor and product ID of the adapter",
.usage = "(vid pid)*",
},
{
- .name = "hla_stlink_backend",
+ .name = "stlink_backend",
.handler = &hl_interface_handle_stlink_backend_command,
.mode = COMMAND_CONFIG,
.help = "select which ST-Link backend to use",
.usage = "usb | tcp [port]",
},
{
- .name = "hla_command",
+ .name = "command",
.handler = &interface_handle_hla_command,
.mode = COMMAND_EXEC,
.help = "execute a custom adapter-specific command",
@@ -358,6 +358,17 @@ static const struct command_registration hl_interface_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration hl_interface_command_handlers[] = {
+ {
+ .name = "hla",
+ .mode = COMMAND_ANY,
+ .help = "perform hla management",
+ .chain = hl_interface_subcommand_handlers,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
struct adapter_driver hl_adapter_driver = {
.name = "hla",
.transports = hl_transports,
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 470ae18..b9d37b3 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -86,7 +86,7 @@ extern tap_state_t cmd_queue_cur_state;
*/
struct scan_field {
/** The number of bits this field specifies */
- int num_bits;
+ unsigned int num_bits;
/** A pointer to value to be scanned into the device */
const uint8_t *out_value;
/** A pointer to a 32-bit memory location for data scanned out */
@@ -102,12 +102,12 @@ struct jtag_tap {
char *chip;
char *tapname;
char *dotted_name;
- int abs_chain_position;
+ unsigned int abs_chain_position;
/** Is this TAP disabled after JTAG reset? */
bool disabled_after_reset;
/** Is this TAP currently enabled? */
bool enabled;
- int ir_length; /**< size of instruction register */
+ unsigned int ir_length; /**< size of instruction register */
uint32_t ir_capture_value;
uint8_t *expected; /**< Capture-IR expected value */
uint32_t ir_capture_mask;
@@ -150,10 +150,10 @@ struct jtag_tap *jtag_all_taps(void);
const char *jtag_tap_name(const struct jtag_tap *tap);
struct jtag_tap *jtag_tap_by_string(const char *dotted_name);
struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *obj);
-struct jtag_tap *jtag_tap_by_position(unsigned abs_position);
+struct jtag_tap *jtag_tap_by_position(unsigned int abs_position);
struct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p);
-unsigned jtag_tap_count_enabled(void);
-unsigned jtag_tap_count(void);
+unsigned int jtag_tap_count_enabled(void);
+unsigned int jtag_tap_count(void);
/*
* - TRST_ASSERTED triggers two sets of callbacks, after operations to
@@ -229,17 +229,17 @@ enum reset_types {
enum reset_types jtag_get_reset_config(void);
void jtag_set_reset_config(enum reset_types type);
-void jtag_set_nsrst_delay(unsigned delay);
-unsigned jtag_get_nsrst_delay(void);
+void jtag_set_nsrst_delay(unsigned int delay);
+unsigned int jtag_get_nsrst_delay(void);
-void jtag_set_ntrst_delay(unsigned delay);
-unsigned jtag_get_ntrst_delay(void);
+void jtag_set_ntrst_delay(unsigned int delay);
+unsigned int jtag_get_ntrst_delay(void);
-void jtag_set_nsrst_assert_width(unsigned delay);
-unsigned jtag_get_nsrst_assert_width(void);
+void jtag_set_nsrst_assert_width(unsigned int delay);
+unsigned int jtag_get_nsrst_assert_width(void);
-void jtag_set_ntrst_assert_width(unsigned delay);
-unsigned jtag_get_ntrst_assert_width(void);
+void jtag_set_ntrst_assert_width(unsigned int delay);
+unsigned int jtag_get_ntrst_assert_width(void);
/** @returns The current state of TRST. */
int jtag_get_trst(void);
@@ -436,7 +436,7 @@ void jtag_add_tlr(void);
* - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid
* state transitions.
*/
-void jtag_add_pathmove(int num_states, const tap_state_t *path);
+void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path);
/**
* jtag_add_statemove() moves from the current state to @a goal_state.
@@ -459,7 +459,7 @@ int jtag_add_statemove(tap_state_t goal_state);
* via TAP_IDLE.
* @param endstate The final state.
*/
-void jtag_add_runtest(int num_cycles, tap_state_t endstate);
+void jtag_add_runtest(unsigned int num_cycles, tap_state_t endstate);
/**
* A reset of the TAP state machine can be requested.
@@ -488,14 +488,14 @@ void jtag_add_reset(int req_tlr_or_trst, int srst);
void jtag_add_sleep(uint32_t us);
-int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state t);
+int jtag_add_tms_seq(unsigned int nbits, const uint8_t *seq, enum tap_state t);
/**
* Function jtag_add_clocks
* first checks that the state in which the clocks are to be issued is
* stable, then queues up num_cycles clocks for transmission.
*/
-void jtag_add_clocks(int num_cycles);
+void jtag_add_clocks(unsigned int num_cycles);
/**
* For software FIFO implementations, the queued commands can be executed
@@ -523,7 +523,7 @@ int jtag_execute_queue(void);
void jtag_execute_queue_noclear(void);
/** @returns the number of times the scan queue has been flushed */
-int jtag_get_flush_queue_count(void);
+unsigned int jtag_get_flush_queue_count(void);
/** Report Tcl event to all TAPs */
void jtag_notify_event(enum jtag_event);
diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h
index a40cffa..45b0bf6 100644
--- a/src/jtag/minidriver.h
+++ b/src/jtag/minidriver.h
@@ -51,8 +51,8 @@ int interface_jtag_add_plain_dr_scan(
tap_state_t endstate);
int interface_jtag_add_tlr(void);
-int interface_jtag_add_pathmove(int num_states, const tap_state_t *path);
-int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate);
+int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path);
+int interface_jtag_add_runtest(unsigned int num_cycles, tap_state_t endstate);
int interface_add_tms_seq(unsigned num_bits,
const uint8_t *bits, enum tap_state state);
@@ -67,7 +67,7 @@ int interface_add_tms_seq(unsigned num_bits,
*/
int interface_jtag_add_reset(int trst, int srst);
int interface_jtag_add_sleep(uint32_t us);
-int interface_jtag_add_clocks(int num_cycles);
+int interface_jtag_add_clocks(unsigned int num_cycles);
int interface_jtag_execute_queue(void);
/**
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index 41db38e..2d8ebf0 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -1126,6 +1126,36 @@ proc "cmsis_dap_usb" {args} {
eval cmsis-dap usb $args
}
+lappend _telnet_autocomplete_skip "hla_layout"
+proc "hla_layout" {layout} {
+ echo "DEPRECATED! use 'hla layout', not 'hla_layout'"
+ eval hla layout $layout
+}
+
+lappend _telnet_autocomplete_skip "hla_device_desc"
+proc "hla_device_desc" {desc} {
+ echo "DEPRECATED! use 'hla device_desc', not 'hla_device_desc'"
+ eval hla device_desc $desc
+}
+
+lappend _telnet_autocomplete_skip "hla_vid_pid"
+proc "hla_vid_pid" {args} {
+ echo "DEPRECATED! use 'hla vid_pid', not 'hla_vid_pid'"
+ eval hla vid_pid $args
+}
+
+lappend _telnet_autocomplete_skip "hla_command"
+proc "hla_command" {command} {
+ echo "DEPRECATED! use 'hla command', not 'hla_command'"
+ eval hla command $command
+}
+
+lappend _telnet_autocomplete_skip "hla_stlink_backend"
+proc "hla_stlink_backend" {args} {
+ echo "DEPRECATED! use 'hla stlink_backend', not 'hla_stlink_backend'"
+ eval hla stlink_backend $args
+}
+
lappend _telnet_autocomplete_skip "kitprog_init_acquire_psoc"
proc "kitprog_init_acquire_psoc" {} {
echo "DEPRECATED! use 'kitprog init_acquire_psoc', not 'kitprog_init_acquire_psoc'"
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 1a4c4b7..10a7dd3 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -87,8 +87,11 @@ static COMMAND_HELPER(handle_jtag_command_drscan_fields, struct scan_field *fiel
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
+
fields[field_count].out_value = t;
- str_to_buf(CMD_ARGV[i + 1], strlen(CMD_ARGV[i + 1]), t, bits, 0);
+ int ret = CALL_COMMAND_HANDLER(command_parse_str_to_buf, CMD_ARGV[i + 1], t, bits, 0);
+ if (ret != ERROR_OK)
+ return ret;
fields[field_count].in_value = t;
field_count++;
}
@@ -209,8 +212,8 @@ COMMAND_HANDLER(handle_jtag_flush_count)
if (CMD_ARGC != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
- int count = jtag_get_flush_queue_count();
- command_print_sameline(CMD, "%d", count);
+ const unsigned int count = jtag_get_flush_queue_count();
+ command_print_sameline(CMD, "%u", count);
return ERROR_OK;
}
@@ -445,11 +448,11 @@ static COMMAND_HELPER(handle_jtag_newtap_args, struct jtag_tap *tap)
if (!CMD_ARGC)
return ERROR_COMMAND_ARGUMENT_INVALID;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tap->ir_length);
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], tap->ir_length);
CMD_ARGC--;
CMD_ARGV++;
- if (tap->ir_length > (int)(8 * sizeof(tap->ir_capture_value)))
- LOG_WARNING("%s: huge IR length %d", tap->dotted_name, tap->ir_length);
+ if (tap->ir_length > (8 * sizeof(tap->ir_capture_value)))
+ LOG_WARNING("%s: huge IR length %u", tap->dotted_name, tap->ir_length);
break;
case NTAP_OPT_IRMASK:
@@ -811,13 +814,13 @@ COMMAND_HANDLER(handle_scan_chain_command)
expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
command_print(CMD,
- "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
+ "%2u %-18s %c 0x%08x %s %5u 0x%02x 0x%02x",
tap->abs_chain_position,
tap->dotted_name,
tap->enabled ? 'Y' : 'n',
(unsigned int)(tap->idcode),
expected_id,
- (unsigned int)(tap->ir_length),
+ tap->ir_length,
(unsigned int)(expected),
(unsigned int)(expected_mask));
@@ -969,7 +972,7 @@ COMMAND_HANDLER(handle_irscan_command)
if (retval != ERROR_OK)
goto error_return;
- int field_size = tap->ir_length;
+ unsigned int field_size = tap->ir_length;
fields[i].num_bits = field_size;
uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8));
if (!v) {
diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index f256bc2..b2339bb 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -36,7 +36,18 @@ struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address,
static inline threadid_t threadid_from_target(const struct target *target)
{
- return target->coreid + 1;
+ if (!target->smp)
+ return 1;
+
+ threadid_t threadid = 1;
+ struct target_list *head;
+ foreach_smp_target(head, target->smp_targets) {
+ if (target == head->target)
+ return threadid;
+ ++threadid;
+ }
+ assert(0 && "Target is not found in it's own SMP group!");
+ return -1;
}
const struct rtos_type hwthread_rtos = {
@@ -59,14 +70,13 @@ struct hwthread_params {
int dummy_param;
};
-static int hwthread_fill_thread(struct rtos *rtos, struct target *curr, int thread_num)
+static int hwthread_fill_thread(struct rtos *rtos, struct target *curr, int thread_num, threadid_t tid)
{
char tmp_str[HW_THREAD_NAME_STR_SIZE];
- threadid_t tid = threadid_from_target(curr);
memset(tmp_str, 0, HW_THREAD_NAME_STR_SIZE);
- /* thread-id is the core-id of this core inside the SMP group plus 1 */
+ /* thread-id is the index of this core inside the SMP group plus 1 */
rtos->thread_details[thread_num].threadid = tid;
/* create the thread name */
rtos->thread_details[thread_num].exists = true;
@@ -130,9 +140,8 @@ static int hwthread_update_threads(struct rtos *rtos)
curr->state == TARGET_UNAVAILABLE)
continue;
- threadid_t tid = threadid_from_target(curr);
-
- hwthread_fill_thread(rtos, curr, threads_found);
+ threadid_t tid = threads_found + 1;
+ hwthread_fill_thread(rtos, curr, threads_found, tid);
/* find an interesting thread to set as current */
switch (current_reason) {
@@ -189,8 +198,8 @@ static int hwthread_update_threads(struct rtos *rtos)
threads_found++;
}
} else {
- hwthread_fill_thread(rtos, target, threads_found);
- current_thread = threadid_from_target(target);
+ current_thread = 1;
+ hwthread_fill_thread(rtos, target, threads_found, current_thread);
threads_found++;
}
@@ -213,19 +222,17 @@ static int hwthread_smp_init(struct target *target)
return hwthread_update_threads(target->rtos);
}
-static struct target *hwthread_find_thread(struct target *target, int64_t thread_id)
+static struct target *hwthread_find_thread(struct target *target, threadid_t thread_id)
{
- /* Find the thread with that thread_id */
- if (!target)
- return NULL;
- if (target->smp) {
- struct target_list *head;
- foreach_smp_target(head, target->smp_targets) {
- if (thread_id == threadid_from_target(head->target))
- return head->target;
- }
- } else if (thread_id == threadid_from_target(target)) {
+ /* Find the thread with that thread_id (index in SMP group plus 1)*/
+ if (!(target && target->smp))
return target;
+ struct target_list *head;
+ threadid_t tid = 1;
+ foreach_smp_target(head, target->smp_targets) {
+ if (thread_id == tid)
+ return head->target;
+ ++tid;
}
return NULL;
}
@@ -304,7 +311,7 @@ static int hwthread_get_thread_reg_value(struct rtos *rtos, int64_t thread_id,
}
if (!target_was_examined(curr)) {
- LOG_ERROR("Target %d hasn't been examined yet.", curr->coreid);
+ LOG_TARGET_ERROR(curr, "Target hasn't been examined yet.");
return ERROR_FAIL;
}
@@ -392,9 +399,9 @@ static int hwthread_thread_packet(struct connection *connection, const char *pac
return ERROR_FAIL;
}
target->rtos->current_thread = current_threadid;
- } else
- if (current_threadid == 0 || current_threadid == -1)
+ } else if (current_threadid == 0 || current_threadid == -1) {
target->rtos->current_thread = threadid_from_target(target);
+ }
target->rtos->current_threadid = current_threadid;
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index f4ce5df..6c4931b 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1599,7 +1599,7 @@ static int gdb_read_memory_packet(struct connection *connection,
* cmd = view%20audit-trail&database = gdb&pr = 2395
*
* For now, the default is to fix up things to make current GDB versions work.
- * This can be overwritten using the gdb_report_data_abort <'enable'|'disable'> command.
+ * This can be overwritten using the "gdb report_data_abort <'enable'|'disable'>" command.
*/
memset(buffer, 0, len);
retval = ERROR_OK;
@@ -4034,7 +4034,7 @@ COMMAND_HANDLER(handle_gdb_sync_command)
if (!current_gdb_connection) {
command_print(CMD,
- "gdb_sync command can only be run from within gdb using \"monitor gdb_sync\"");
+ "gdb sync command can only be run from within gdb using \"monitor gdb sync\"");
return ERROR_FAIL;
}
@@ -4043,7 +4043,6 @@ COMMAND_HANDLER(handle_gdb_sync_command)
return ERROR_OK;
}
-/* daemon configuration command gdb_port */
COMMAND_HANDLER(handle_gdb_port_command)
{
int retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port);
@@ -4090,7 +4089,6 @@ COMMAND_HANDLER(handle_gdb_report_register_access_error)
return ERROR_OK;
}
-/* gdb_breakpoint_override */
COMMAND_HANDLER(handle_gdb_breakpoint_override_command)
{
if (CMD_ARGC == 0) {
@@ -4167,9 +4165,9 @@ out:
return retval;
}
-static const struct command_registration gdb_command_handlers[] = {
+static const struct command_registration gdb_subcommand_handlers[] = {
{
- .name = "gdb_sync",
+ .name = "sync",
.handler = handle_gdb_sync_command,
.mode = COMMAND_ANY,
.help = "next stepi will return immediately allowing "
@@ -4178,7 +4176,7 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = ""
},
{
- .name = "gdb_port",
+ .name = "port",
.handler = handle_gdb_port_command,
.mode = COMMAND_CONFIG,
.help = "Normally gdb listens to a TCP/IP port. Each subsequent GDB "
@@ -4191,35 +4189,35 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = "[port_num]",
},
{
- .name = "gdb_memory_map",
+ .name = "memory_map",
.handler = handle_gdb_memory_map_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable memory map",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_flash_program",
+ .name = "flash_program",
.handler = handle_gdb_flash_program_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable flash program",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_report_data_abort",
+ .name = "report_data_abort",
.handler = handle_gdb_report_data_abort_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable reporting data aborts",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_report_register_access_error",
+ .name = "report_register_access_error",
.handler = handle_gdb_report_register_access_error,
.mode = COMMAND_CONFIG,
.help = "enable or disable reporting register access errors",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_breakpoint_override",
+ .name = "breakpoint_override",
.handler = handle_gdb_breakpoint_override_command,
.mode = COMMAND_ANY,
.help = "Display or specify type of breakpoint "
@@ -4227,14 +4225,14 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = "('hard'|'soft'|'disable')"
},
{
- .name = "gdb_target_description",
+ .name = "target_description",
.handler = handle_gdb_target_description_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable target description",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_save_tdesc",
+ .name = "save_tdesc",
.handler = handle_gdb_save_tdesc_command,
.mode = COMMAND_EXEC,
.help = "Save the target description file",
@@ -4243,6 +4241,17 @@ static const struct command_registration gdb_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration gdb_command_handlers[] = {
+ {
+ .name = "gdb",
+ .mode = COMMAND_ANY,
+ .help = "GDB commands",
+ .chain = gdb_subcommand_handlers,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
int gdb_register_commands(struct command_context *cmd_ctx)
{
gdb_port = strdup("3333");
diff --git a/src/server/startup.tcl b/src/server/startup.tcl
index 1d30b1d..ebfb056 100644
--- a/src/server/startup.tcl
+++ b/src/server/startup.tcl
@@ -41,3 +41,75 @@ proc _telnet_autocomplete_helper pattern {
return [lsort $cmds]
}
+
+lappend _telnet_autocomplete_skip "gdb_sync"
+proc "gdb_sync" {} {
+ echo "DEPRECATED! use 'gdb sync', not 'gdb_sync'"
+ eval gdb sync
+}
+
+lappend _telnet_autocomplete_skip "gdb_port"
+proc "gdb_port" {args} {
+ echo "DEPRECATED! use 'gdb port', not 'gdb_port'"
+ eval gdb port $args
+}
+
+lappend _telnet_autocomplete_skip "gdb_memory_map"
+proc "gdb_memory_map" {state} {
+ echo "DEPRECATED! use 'gdb memory_map', not 'gdb_memory_map'"
+ eval gdb memory_map $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_flash_program"
+proc "gdb_flash_program" {state} {
+ echo "DEPRECATED! use 'gdb flash_program', not 'gdb_flash_program'"
+ eval gdb flash_program $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_report_data_abort"
+proc "gdb_report_data_abort" {state} {
+ echo "DEPRECATED! use 'gdb report_data_abort', not 'gdb_report_data_abort'"
+ eval gdb report_data_abort $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_report_register_access_error"
+proc "gdb_report_register_access_error" {state} {
+ echo "DEPRECATED! use 'gdb report_register_access_error', not 'gdb_report_register_access_error'"
+ eval gdb report_register_access_error $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_breakpoint_override"
+proc "gdb_breakpoint_override" {override} {
+ echo "DEPRECATED! use 'gdb breakpoint_override', not 'gdb_breakpoint_override'"
+ eval gdb breakpoint_override $override
+}
+
+lappend _telnet_autocomplete_skip "gdb_target_description"
+proc "gdb_target_description" {state} {
+ echo "DEPRECATED! use 'gdb target_description', not 'gdb_target_description'"
+ eval gdb target_description $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_save_tdesc"
+proc "gdb_save_tdesc" {} {
+ echo "DEPRECATED! use 'gdb save_tdesc', not 'gdb_save_tdesc'"
+ eval gdb save_tdesc
+}
+
+lappend _telnet_autocomplete_skip "tcl_port"
+proc "tcl_port" {args} {
+ echo "DEPRECATED! use 'tcl port' not 'tcl_port'"
+ eval tcl port $args
+}
+
+lappend _telnet_autocomplete_skip "tcl_notifications"
+proc "tcl_notifications" {state} {
+ echo "DEPRECATED! use 'tcl notifications' not 'tcl_notifications'"
+ eval tcl notifications $state
+}
+
+lappend _telnet_autocomplete_skip "tcl_trace"
+proc "tcl_trace" {state} {
+ echo "DEPRECATED! use 'tcl trace' not 'tcl_trace'"
+ eval tcl trace $state
+}
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index 16cbedc..16cc55e 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -323,25 +323,25 @@ COMMAND_HANDLER(handle_tcl_trace_command)
}
}
-static const struct command_registration tcl_command_handlers[] = {
+static const struct command_registration tcl_subcommand_handlers[] = {
{
- .name = "tcl_port",
+ .name = "port",
.handler = handle_tcl_port_command,
.mode = COMMAND_CONFIG,
.help = "Specify port on which to listen "
"for incoming Tcl syntax. "
- "Read help on 'gdb_port'.",
+ "Read help on 'gdb port'.",
.usage = "[port_num]",
},
{
- .name = "tcl_notifications",
+ .name = "notifications",
.handler = handle_tcl_notifications_command,
.mode = COMMAND_EXEC,
.help = "Target Notification output",
.usage = "[on|off]",
},
{
- .name = "tcl_trace",
+ .name = "trace",
.handler = handle_tcl_trace_command,
.mode = COMMAND_EXEC,
.help = "Target trace output",
@@ -350,6 +350,17 @@ static const struct command_registration tcl_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration tcl_command_handlers[] = {
+ {
+ .name = "tcl",
+ .mode = COMMAND_ANY,
+ .help = "tcl command group",
+ .usage = "",
+ .chain = tcl_subcommand_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
int tcl_register_commands(struct command_context *cmd_ctx)
{
tcl_port = strdup("6666");
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 938bc5b..02d450f 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -982,7 +982,7 @@ static const struct command_registration telnet_command_handlers[] = {
{
.name = "exit",
.handler = handle_exit_command,
- .mode = COMMAND_EXEC,
+ .mode = COMMAND_ANY,
.usage = "",
.help = "exit telnet session",
},
@@ -992,7 +992,7 @@ static const struct command_registration telnet_command_handlers[] = {
.mode = COMMAND_CONFIG,
.help = "Specify port on which to listen "
"for incoming telnet connections. "
- "Read help on 'gdb_port'.",
+ "Read help on 'gdb port'.",
.usage = "[port_num]",
},
COMMAND_REGISTRATION_DONE
diff --git a/src/target/arm.h b/src/target/arm.h
index 486666b..0de322a 100644
--- a/src/target/arm.h
+++ b/src/target/arm.h
@@ -58,11 +58,12 @@ enum arm_arch {
ARM_ARCH_V8M,
};
-/** Known ARM implementor IDs */
-enum arm_implementor {
- ARM_IMPLEMENTOR_ARM = 0x41,
- ARM_IMPLEMENTOR_INFINEON = 0x49,
- ARM_IMPLEMENTOR_REALTEK = 0x72,
+/** Known ARM implementer IDs */
+enum arm_implementer {
+ ARM_IMPLEMENTER_ARM = 0x41,
+ ARM_IMPLEMENTER_INFINEON = 0x49,
+ ARM_IMPLEMENTER_ARM_CHINA = 0x63,
+ ARM_IMPLEMENTER_REALTEK = 0x72,
};
/**
diff --git a/src/target/avrt.c b/src/target/avrt.c
index 61bef32..8886a46 100644
--- a/src/target/avrt.c
+++ b/src/target/avrt.c
@@ -31,10 +31,10 @@ static int avr_assert_reset(struct target *target);
static int avr_deassert_reset(struct target *target);
/* IR and DR functions */
-static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti);
-static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len, int rti);
-static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti);
-static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti);
+static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len);
+static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len);
+static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len);
+static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len);
struct target_type avr_target = {
.name = "avr",
@@ -137,23 +137,23 @@ static int avr_deassert_reset(struct target *target)
int avr_jtag_senddat(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out,
int len)
{
- return mcu_write_dr_u32(tap, dr_in, dr_out, len, 1);
+ return mcu_write_dr_u32(tap, dr_in, dr_out, len);
}
int avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out)
{
- return mcu_write_ir_u8(tap, ir_in, ir_out, AVR_JTAG_INS_LEN, 1);
+ return mcu_write_ir_u8(tap, ir_in, ir_out, AVR_JTAG_INS_LEN);
}
/* IR and DR functions */
static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out,
- int ir_len, int rti)
+ int ir_len)
{
if (!tap) {
LOG_ERROR("invalid tap");
return ERROR_FAIL;
}
- if (ir_len != tap->ir_length) {
+ if ((unsigned int)ir_len != tap->ir_length) {
LOG_ERROR("invalid ir_len");
return ERROR_FAIL;
}
@@ -166,7 +166,7 @@ static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out,
}
static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out,
- int dr_len, int rti)
+ int dr_len)
{
if (!tap) {
LOG_ERROR("invalid tap");
@@ -181,27 +181,27 @@ static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out,
}
static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in,
- uint8_t ir_out, int ir_len, int rti)
+ uint8_t ir_out, int ir_len)
{
if (ir_len > 8) {
LOG_ERROR("ir_len overflow, maximum is 8");
return ERROR_FAIL;
}
- mcu_write_ir(tap, ir_in, &ir_out, ir_len, rti);
+ mcu_write_ir(tap, ir_in, &ir_out, ir_len);
return ERROR_OK;
}
static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in,
- uint32_t dr_out, int dr_len, int rti)
+ uint32_t dr_out, int dr_len)
{
if (dr_len > 32) {
LOG_ERROR("dr_len overflow, maximum is 32");
return ERROR_FAIL;
}
- mcu_write_dr(tap, (uint8_t *)dr_in, (uint8_t *)&dr_out, dr_len, rti);
+ mcu_write_dr(tap, (uint8_t *)dr_in, (uint8_t *)&dr_out, dr_len);
return ERROR_OK;
}
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 34c7cd4..3b95b64 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -100,6 +100,12 @@ static const struct cortex_m_part_info cortex_m_parts[] = {
.flags = CORTEX_M_F_HAS_FPV5,
},
{
+ .impl_part = CORTEX_M52_PARTNO,
+ .name = "Cortex-M52",
+ .arch = ARM_ARCH_V8M,
+ .flags = CORTEX_M_F_HAS_FPV5,
+ },
+ {
.impl_part = CORTEX_M55_PARTNO,
.name = "Cortex-M55",
.arch = ARM_ARCH_V8M,
@@ -273,7 +279,8 @@ static int cortex_m_fast_read_all_regs(struct target *target)
/* because the DCB_DCRDR is used for the emulated dcc channel
* we have to save/restore the DCB_DCRDR when used */
- if (target->dbg_msg_enabled) {
+ bool dbg_msg_enabled = target->dbg_msg_enabled;
+ if (dbg_msg_enabled) {
retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);
if (retval != ERROR_OK)
return retval;
@@ -326,7 +333,7 @@ static int cortex_m_fast_read_all_regs(struct target *target)
if (retval != ERROR_OK)
return retval;
- if (target->dbg_msg_enabled) {
+ if (dbg_msg_enabled) {
/* restore DCB_DCRDR - this needs to be in a separate
* transaction otherwise the emulated DCC channel breaks */
retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);
@@ -797,6 +804,42 @@ static int cortex_m_examine_exception_reason(struct target *target)
return retval;
}
+/* Errata 3092511 workaround
+ * Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+static int cortex_m_erratum_check_breakpoint(struct target *target)
+{
+ struct cortex_m_common *cortex_m = target_to_cm(target);
+ struct armv7m_common *armv7m = &cortex_m->armv7m;
+ struct arm *arm = &armv7m->arm;
+
+ uint32_t pc = buf_get_u32(arm->pc->value, 0, 32);
+
+ /* To reduce the workaround processing cost we assume FPB is in sync
+ * with OpenOCD breakpoints. If the target app writes to FPB
+ * OpenOCD will resume after the break set by app */
+ struct breakpoint *bkpt = breakpoint_find(target, pc);
+ if (bkpt) {
+ LOG_TARGET_DEBUG(target, "Erratum 3092511: breakpoint confirmed");
+ return ERROR_OK;
+ }
+ if (pc >= 0xe0000000u)
+ /* not executable area, do not read instruction @ pc */
+ return ERROR_OK;
+
+ uint16_t insn;
+ int retval = target_read_u16(target, pc, &insn);
+ if (retval != ERROR_OK)
+ return ERROR_OK; /* do not propagate the error, just avoid workaround */
+
+ if ((insn & 0xff00) == (ARMV5_T_BKPT(0) & 0xff00)) {
+ LOG_TARGET_DEBUG(target, "Erratum 3092511: breakpoint embedded in code confirmed");
+ return ERROR_OK;
+ }
+ LOG_TARGET_DEBUG(target, "Erratum 3092511: breakpoint not found, proceed with resume");
+ return ERROR_TARGET_HALTED_DO_RESUME;
+}
+
static int cortex_m_debug_entry(struct target *target)
{
uint32_t xpsr;
@@ -883,6 +926,17 @@ static int cortex_m_debug_entry(struct target *target)
secure_state ? "Secure" : "Non-Secure",
target_state_name(target));
+ /* Errata 3092511 workaround
+ * Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+ if (cortex_m->incorrect_halt_erratum
+ && armv7m->exception_number
+ && cortex_m->nvic_dfsr == (DFSR_BKPT | DFSR_HALTED)) {
+ retval = cortex_m_erratum_check_breakpoint(target);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
if (armv7m->post_debug_entry) {
retval = armv7m->post_debug_entry(target);
if (retval != ERROR_OK)
@@ -960,6 +1014,28 @@ static int cortex_m_poll_one(struct target *target)
if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) {
retval = cortex_m_debug_entry(target);
+ /* Errata 3092511 workaround
+ * Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+ if (retval == ERROR_TARGET_HALTED_DO_RESUME) {
+ struct arm *arm = &armv7m->arm;
+ LOG_TARGET_INFO(target, "Resuming after incorrect halt @ PC 0x%08" PRIx32
+ ", ARM Cortex-M7 erratum 3092511",
+ buf_get_u32(arm->pc->value, 0, 32));
+ /* We don't need to restore registers, just restart the core */
+ cortex_m_set_maskints_for_run(target);
+ retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT);
+ if (retval != ERROR_OK)
+ return retval;
+
+ target->debug_reason = DBG_REASON_NOTHALTED;
+ /* registers are now invalid */
+ register_cache_invalidate(armv7m->arm.core_cache);
+
+ target->state = TARGET_RUNNING;
+ return ERROR_OK;
+ }
+
/* arm_semihosting needs to know registers, don't run if debug entry returned error */
if (retval == ERROR_OK && arm_semihosting(target, &retval) != 0)
return retval;
@@ -1582,7 +1658,7 @@ static int cortex_m_step(struct target *target, int current,
cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
retval = cortex_m_debug_entry(target);
- if (retval != ERROR_OK)
+ if (retval != ERROR_OK && retval != ERROR_TARGET_HALTED_DO_RESUME)
return retval;
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
@@ -2537,8 +2613,8 @@ int cortex_m_examine(struct target *target)
if (retval != ERROR_OK)
return retval;
- /* Inspect implementor/part to look for recognized cores */
- unsigned int impl_part = cpuid & (ARM_CPUID_IMPLEMENTOR_MASK | ARM_CPUID_PARTNO_MASK);
+ /* Inspect implementer/part to look for recognized cores */
+ unsigned int impl_part = cpuid & (ARM_CPUID_IMPLEMENTER_MASK | ARM_CPUID_PARTNO_MASK);
for (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) {
if (impl_part == cortex_m_parts[n].impl_part) {
@@ -2560,14 +2636,22 @@ int cortex_m_examine(struct target *target)
(uint8_t)((cpuid >> 0) & 0xf));
cortex_m->maskints_erratum = false;
+ cortex_m->incorrect_halt_erratum = false;
if (impl_part == CORTEX_M7_PARTNO) {
uint8_t rev, patch;
rev = (cpuid >> 20) & 0xf;
patch = (cpuid >> 0) & 0xf;
if ((rev == 0) && (patch < 2)) {
- LOG_TARGET_WARNING(target, "Silicon bug: single stepping may enter pending exception handler!");
+ LOG_TARGET_WARNING(target, "Erratum 702596: single stepping may enter pending exception handler!");
cortex_m->maskints_erratum = true;
}
+ /* TODO: add revision check when a Cortex-M7 revision with fixed 3092511 is out */
+ LOG_TARGET_WARNING(target, "Erratum 3092511: Cortex-M7 can halt in an incorrect address when breakpoint and exception occurs simultaneously");
+ cortex_m->incorrect_halt_erratum = true;
+ if (armv7m->is_hla_target)
+ LOG_WARNING("No erratum 3092511 workaround on hla adapter");
+ else
+ LOG_INFO("The erratum 3092511 workaround will resume after an incorrect halt");
}
LOG_TARGET_DEBUG(target, "cpuid: 0x%8.8" PRIx32 "", cpuid);
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index a585b78..726fca2 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -31,35 +31,36 @@
#define CPUID 0xE000ED00
-#define ARM_CPUID_IMPLEMENTOR_POS 24
-#define ARM_CPUID_IMPLEMENTOR_MASK (0xFF << ARM_CPUID_IMPLEMENTOR_POS)
+#define ARM_CPUID_IMPLEMENTER_POS 24
+#define ARM_CPUID_IMPLEMENTER_MASK (0xFF << ARM_CPUID_IMPLEMENTER_POS)
#define ARM_CPUID_PARTNO_POS 4
#define ARM_CPUID_PARTNO_MASK (0xFFF << ARM_CPUID_PARTNO_POS)
-#define ARM_MAKE_CPUID(impl, partno) ((((impl) << ARM_CPUID_IMPLEMENTOR_POS) & ARM_CPUID_IMPLEMENTOR_MASK) | \
+#define ARM_MAKE_CPUID(impl, partno) ((((impl) << ARM_CPUID_IMPLEMENTER_POS) & ARM_CPUID_IMPLEMENTER_MASK) | \
(((partno) << ARM_CPUID_PARTNO_POS) & ARM_CPUID_PARTNO_MASK))
/** Known Arm Cortex masked CPU Ids
- * This includes the implementor and part number, but _not_ the revision or
+ * This includes the implementer and part number, but _not_ the revision or
* patch fields.
*/
enum cortex_m_impl_part {
CORTEX_M_PARTNO_INVALID,
- STAR_MC1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0x132), /* FIXME - confirm implementor! */
- CORTEX_M0_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC20),
- CORTEX_M1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC21),
- CORTEX_M3_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC23),
- CORTEX_M4_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC24),
- CORTEX_M7_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC27),
- CORTEX_M0P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC60),
- CORTEX_M23_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD20),
- CORTEX_M33_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD21),
- CORTEX_M35P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD31),
- CORTEX_M55_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD22),
- CORTEX_M85_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD23),
- INFINEON_SLX2_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_INFINEON, 0xDB0),
- REALTEK_M200_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd20),
- REALTEK_M300_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd22),
+ STAR_MC1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM_CHINA, 0x132),
+ CORTEX_M0_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC20),
+ CORTEX_M1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC21),
+ CORTEX_M3_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC23),
+ CORTEX_M4_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC24),
+ CORTEX_M7_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC27),
+ CORTEX_M0P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC60),
+ CORTEX_M23_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD20),
+ CORTEX_M33_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD21),
+ CORTEX_M35P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD31),
+ CORTEX_M52_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM_CHINA, 0xD24),
+ CORTEX_M55_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD22),
+ CORTEX_M85_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD23),
+ INFINEON_SLX2_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_INFINEON, 0xDB0),
+ REALTEK_M200_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_REALTEK, 0xd20),
+ REALTEK_M300_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_REALTEK, 0xd22),
};
/* Relevant Cortex-M flags, used in struct cortex_m_part_info.flags */
@@ -256,6 +257,10 @@ struct cortex_m_common {
/* Whether this target has the erratum that makes C_MASKINTS not apply to
* already pending interrupts */
bool maskints_erratum;
+
+ /* Errata 3092511 Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+ bool incorrect_halt_erratum;
};
static inline bool is_cortex_m_or_hla(const struct cortex_m_common *cortex_m)
diff --git a/src/target/esirisc.c b/src/target/esirisc.c
index 0f76b59..14d34ff 100644
--- a/src/target/esirisc.c
+++ b/src/target/esirisc.c
@@ -483,7 +483,7 @@ static int esirisc_add_breakpoint(struct target *target, struct breakpoint *brea
* The default linker scripts provided by the eSi-RISC toolchain do
* not specify attributes on memory regions, which results in
* incorrect application of software breakpoints by GDB. Targets
- * must be configured with `gdb_breakpoint_override hard` as
+ * must be configured with `gdb breakpoint_override hard` as
* software breakpoints are not supported.
*/
if (breakpoint->type != BKPT_HARD)
diff --git a/src/target/esirisc_jtag.c b/src/target/esirisc_jtag.c
index 1ec1726..5960e26 100644
--- a/src/target/esirisc_jtag.c
+++ b/src/target/esirisc_jtag.c
@@ -58,11 +58,12 @@ static int esirisc_jtag_get_padding(void)
return padding;
}
-static int esirisc_jtag_count_bits(int num_fields, struct scan_field *fields)
+static int esirisc_jtag_count_bits(unsigned int num_fields,
+ struct scan_field *fields)
{
int bit_count = 0;
- for (int i = 0; i < num_fields; ++i)
+ for (unsigned int i = 0; i < num_fields; ++i)
bit_count += fields[i].num_bits;
return bit_count;
diff --git a/src/target/lakemont.c b/src/target/lakemont.c
index 6c0964b..1fcd642 100644
--- a/src/target/lakemont.c
+++ b/src/target/lakemont.c
@@ -224,10 +224,10 @@ static int irscan(struct target *t, uint8_t *out,
if (ir_len != t->tap->ir_length) {
retval = ERROR_FAIL;
if (t->tap->enabled)
- LOG_ERROR("%s tap enabled but tap irlen=%d",
+ LOG_ERROR("%s tap enabled but tap irlen=%u",
__func__, t->tap->ir_length);
else
- LOG_ERROR("%s tap not enabled and irlen=%d",
+ LOG_ERROR("%s tap not enabled and irlen=%u",
__func__, t->tap->ir_length);
return retval;
}
diff --git a/src/target/riscv/asm.h b/src/target/riscv/asm.h
index 6ceb8c9..828cd86 100644
--- a/src/target/riscv/asm.h
+++ b/src/target/riscv/asm.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__ASM_H
-#define TARGET__RISCV__ASM_H
+#ifndef OPENOCD_TARGET_RISCV_ASM_H
+#define OPENOCD_TARGET_RISCV_ASM_H
#include "riscv.h"
@@ -37,4 +37,4 @@ static uint32_t store(const struct target *target, unsigned int src,
return 0; /* Silence -Werror=return-type */
}
-#endif
+#endif /* OPENOCD_TARGET_RISCV_ASM_H */
diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c
index bb1070a..afea316 100644
--- a/src/target/riscv/batch.c
+++ b/src/target/riscv/batch.c
@@ -190,8 +190,7 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
for (size_t i = start_idx; i < batch->used_scans; ++i) {
const int delay = get_delay(batch, i, delays);
- riscv_log_dmi_scan(batch->target, delay, batch->fields + i,
- /*discard_in*/ false);
+ riscv_log_dmi_scan(batch->target, delay, batch->fields + i);
}
batch->was_run = true;
@@ -199,14 +198,14 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
return ERROR_OK;
}
-void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
+void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
bool read_back, enum riscv_scan_delay_class delay_class)
{
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
field->num_bits = riscv_get_dmi_scan_length(batch->target);
field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
- riscv_fill_dm_write(batch->target, (char *)field->out_value, address, data);
+ riscv_fill_dmi_write(batch->target, (char *)field->out_value, address, data);
if (read_back) {
field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
riscv_fill_dm_nop(batch->target, (char *)field->in_value);
@@ -218,7 +217,7 @@ void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint3
batch->used_scans++;
}
-size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
+size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint64_t address,
enum riscv_scan_delay_class delay_class)
{
assert(batch->used_scans < batch->allocated_scans);
@@ -226,7 +225,7 @@ size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
field->num_bits = riscv_get_dmi_scan_length(batch->target);
field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
- riscv_fill_dm_read(batch->target, (char *)field->out_value, address);
+ riscv_fill_dmi_read(batch->target, (char *)field->out_value, address);
riscv_fill_dm_nop(batch->target, (char *)field->in_value);
batch->delay_classes[batch->used_scans] = delay_class;
batch->last_scan = RISCV_SCAN_TYPE_READ;
diff --git a/src/target/riscv/batch.h b/src/target/riscv/batch.h
index 327406c..660a63f 100644
--- a/src/target/riscv/batch.h
+++ b/src/target/riscv/batch.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__SCANS_H
-#define TARGET__RISCV__SCANS_H
+#ifndef OPENOCD_TARGET_RISCV_BATCH_H
+#define OPENOCD_TARGET_RISCV_BATCH_H
#include "target/target.h"
#include "jtag/jtag.h"
@@ -190,14 +190,32 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
size_t riscv_batch_finished_scans(const struct riscv_batch *batch);
/* Adds a DM register write to this batch. */
-void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
+void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
bool read_back, enum riscv_scan_delay_class delay_class);
+static inline void
+riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
+ bool read_back, enum riscv_scan_delay_class delay_type)
+{
+ return riscv_batch_add_dmi_write(batch,
+ riscv_get_dmi_address(batch->target, address), data,
+ read_back, delay_type);
+}
+
/* DM register reads must be handled in two parts: the first one schedules a read and
* provides a key, the second one actually obtains the result of the read -
* status (op) and the actual data. */
-size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
+size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint64_t address,
enum riscv_scan_delay_class delay_class);
+
+static inline size_t
+riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
+ enum riscv_scan_delay_class delay_type)
+{
+ return riscv_batch_add_dmi_read(batch,
+ riscv_get_dmi_address(batch->target, address), delay_type);
+}
+
unsigned int riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key);
uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key);
@@ -213,7 +231,7 @@ bool riscv_batch_was_batch_busy(const struct riscv_batch *batch);
/* TODO: The function is defined in `riscv-013.c`. This is done to reduce the
* diff of the commit. The intention is to move the function definition to
* a separate module (e.g. `riscv013-jtag-dtm.c/h`) in another commit. */
-void riscv_log_dmi_scan(const struct target *target, int idle, const struct scan_field *field,
- bool discard_in);
+void riscv_log_dmi_scan(const struct target *target, int idle,
+ const struct scan_field *field);
-#endif
+#endif /* OPENOCD_TARGET_RISCV_BATCH_H */
diff --git a/src/target/riscv/debug_reg_printer.h b/src/target/riscv/debug_reg_printer.h
index 98226b7..5089ff8 100644
--- a/src/target/riscv/debug_reg_printer.h
+++ b/src/target/riscv/debug_reg_printer.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef OPENOCD_TARGET_RISCV_DEBUG_REG_PRINTER_H
+#define OPENOCD_TARGET_RISCV_DEBUG_REG_PRINTER_H
+
#include "debug_defines.h"
enum riscv_debug_reg_show {
@@ -33,3 +36,5 @@ enum riscv_debug_reg_show {
unsigned int riscv_debug_reg_to_s(char *buf, enum riscv_debug_reg_ordinal reg_ordinal,
riscv_debug_reg_ctx_t context, uint64_t value,
enum riscv_debug_reg_show show);
+
+#endif /* OPENOCD_TARGET_RISCV_DEBUG_REG_PRINTER_H */
diff --git a/src/target/riscv/field_helpers.h b/src/target/riscv/field_helpers.h
index 16578f1..abf19f6 100644
--- a/src/target/riscv/field_helpers.h
+++ b/src/target/riscv/field_helpers.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef FIELD_HELPERS_H
-#define FIELD_HELPERS_H
+#ifndef OPENOCD_TARGET_RISCV_FIELD_HELPERS_H
+#define OPENOCD_TARGET_RISCV_FIELD_HELPERS_H
#include <stdint.h>
#include <assert.h>
@@ -44,4 +44,4 @@ static inline uint32_t field_value32(uint32_t mask, uint32_t val)
return set_field32(0, mask, val);
}
-#endif
+#endif /* OPENOCD_TARGET_RISCV_FIELD_HELPERS_H */
diff --git a/src/target/riscv/gdb_regs.h b/src/target/riscv/gdb_regs.h
index d606f73..0d03929 100644
--- a/src/target/riscv/gdb_regs.h
+++ b/src/target/riscv/gdb_regs.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__GDB_REGS_H
-#define TARGET__RISCV__GDB_REGS_H
+#ifndef OPENOCD_TARGET_RISCV_GDB_REGS_H
+#define OPENOCD_TARGET_RISCV_GDB_REGS_H
#include "encoding.h"
@@ -125,4 +125,4 @@ enum gdb_regno {
GDB_REGNO_COUNT
};
-#endif
+#endif /* OPENOCD_TARGET_RISCV_GDB_REGS_H */
diff --git a/src/target/riscv/opcodes.h b/src/target/riscv/opcodes.h
index 59c3413..99ae90f 100644
--- a/src/target/riscv/opcodes.h
+++ b/src/target/riscv/opcodes.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef OPENOCD_TARGET_RISCV_OPCODES_H
+#define OPENOCD_TARGET_RISCV_OPCODES_H
+
#include "encoding.h"
#define ZERO 0
@@ -339,3 +342,4 @@ static uint32_t vslide1down_vx(unsigned int vd, unsigned int vs2,
return ((vm & 1) << 25) | inst_rs2(vs2) | inst_rs1(rs1) | inst_rd(vd) | MATCH_VSLIDE1DOWN_VX;
}
+#endif /* OPENOCD_TARGET_RISCV_OPCODES_H */
diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c
index c4ffb3f..85c3d16 100644
--- a/src/target/riscv/program.c
+++ b/src/target/riscv/program.c
@@ -183,8 +183,8 @@ int riscv_program_ebreak(struct riscv_program *p)
{
struct target *target = p->target;
RISCV_INFO(r);
- if (p->instruction_count == riscv_progbuf_size(p->target) &&
- r->impebreak) {
+ if (p->instruction_count == riscv_progbuf_size(target) &&
+ r->get_impebreak(target)) {
return ERROR_OK;
}
return riscv_program_insert(p, ebreak());
diff --git a/src/target/riscv/program.h b/src/target/riscv/program.h
index 93dbdbf..91f0dab 100644
--- a/src/target/riscv/program.h
+++ b/src/target/riscv/program.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__PROGRAM_H
-#define TARGET__RISCV__PROGRAM_H
+#ifndef OPENOCD_TARGET_RISCV_PROGRAM_H
+#define OPENOCD_TARGET_RISCV_PROGRAM_H
#include "riscv.h"
@@ -77,4 +77,4 @@ int riscv_program_ebreak(struct riscv_program *p);
int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t i);
-#endif
+#endif /* OPENOCD_TARGET_RISCV_PROGRAM_H */
diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c
index 0715de5..1da7182 100644
--- a/src/target/riscv/riscv-011.c
+++ b/src/target/riscv/riscv-011.c
@@ -273,38 +273,6 @@ static uint16_t dram_address(unsigned int index)
return 0x40 + index - 0x10;
}
-static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
-{
- struct scan_field field;
- uint8_t in_value[4];
- uint8_t out_value[4] = { 0 };
-
- buf_set_u32(out_value, 0, 32, out);
-
- jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);
-
- field.num_bits = 32;
- field.out_value = out_value;
- field.in_value = in_value;
- jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
-
- /* Always return to dbus. */
- jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
-
- int retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("failed jtag scan: %d", retval);
- return retval;
- }
-
- uint32_t in = buf_get_u32(field.in_value, 0, 32);
- LOG_DEBUG("DTMCONTROL: 0x%x -> 0x%x", out, in);
-
- if (in_ptr)
- *in_ptr = in;
- return ERROR_OK;
-}
-
static uint32_t idcode_scan(struct target *target)
{
struct scan_field field;
@@ -408,7 +376,7 @@ static void dump_field(const struct scan_field *field)
log_printf_lf(LOG_LVL_DEBUG,
__FILE__, __LINE__, "scan",
- "%db %s %c%c:%08x @%02x -> %s %c%c:%08x @%02x",
+ "%ub %s %c%c:%08x @%02x -> %s %c%c:%08x @%02x",
field->num_bits,
op_string[out_op], out_interrupt, out_haltnot, out_data,
out_address,
@@ -2388,6 +2356,16 @@ static int riscv011_authdata_write(struct target *target, uint32_t value, unsign
return ERROR_OK;
}
+static bool riscv011_get_impebreak(const struct target *target)
+{
+ return false;
+}
+
+static unsigned int riscv011_get_progbufsize(const struct target *target)
+{
+ return 0;
+}
+
static int init_target(struct command_context *cmd_ctx,
struct target *target)
{
@@ -2397,6 +2375,8 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->authdata_read = &riscv011_authdata_read;
generic_info->authdata_write = &riscv011_authdata_write;
generic_info->print_info = &riscv011_print_info;
+ generic_info->get_impebreak = &riscv011_get_impebreak;
+ generic_info->get_progbufsize = &riscv011_get_progbufsize;
generic_info->version_specific = calloc(1, sizeof(riscv011_info_t));
if (!generic_info->version_specific)
diff --git a/src/target/riscv/riscv-011.h b/src/target/riscv/riscv-011.h
index 8d1d06a..bbbc194 100644
--- a/src/target/riscv/riscv-011.h
+++ b/src/target/riscv/riscv-011.h
@@ -12,4 +12,4 @@ int riscv011_get_register(struct target *target, riscv_reg_t *value,
int riscv011_set_register(struct target *target, enum gdb_regno regid,
riscv_reg_t value);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_011_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_011_H */
diff --git a/src/target/riscv/riscv-011_reg.c b/src/target/riscv/riscv-011_reg.c
index 7f29064..44ea1a4 100644
--- a/src/target/riscv/riscv-011_reg.c
+++ b/src/target/riscv/riscv-011_reg.c
@@ -38,7 +38,9 @@ static const struct reg_arch_type *riscv011_gdb_regno_reg_type(uint32_t regno)
static int riscv011_init_reg(struct target *target, uint32_t regno)
{
- return riscv_reg_impl_init_one(target, regno, riscv011_gdb_regno_reg_type(regno));
+ return riscv_reg_impl_init_cache_entry(target, regno,
+ riscv_reg_impl_gdb_regno_exist(target, regno),
+ riscv011_gdb_regno_reg_type(regno));
}
int riscv011_reg_init_all(struct target *target)
diff --git a/src/target/riscv/riscv-011_reg.h b/src/target/riscv/riscv-011_reg.h
index ee00c9b..4f7911a 100644
--- a/src/target/riscv/riscv-011_reg.h
+++ b/src/target/riscv/riscv-011_reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef OPENOCD_TARGET_RISCV_RISCV_REG_011_H
-#define OPENOCD_TARGET_RISCV_RISCV_REG_011_H
+#ifndef OPENOCD_TARGET_RISCV_RISCV_011_REG_H
+#define OPENOCD_TARGET_RISCV_RISCV_011_REG_H
#include "target/target.h"
@@ -16,4 +16,4 @@
*/
int riscv011_reg_init_all(struct target *target);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_REG_011_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_011_REG_H */
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 7898cae..f2c4676 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -16,6 +16,7 @@
#include "target/target.h"
#include "target/algorithm.h"
#include "target/target_type.h"
+#include <helper/align.h>
#include <helper/log.h>
#include "jtag/jtag.h"
#include "target/register.h"
@@ -56,10 +57,7 @@ static int riscv013_invalidate_cached_progbuf(struct target *target);
static int riscv013_execute_progbuf(struct target *target, uint32_t *cmderr);
static void riscv013_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d);
static void riscv013_fill_dmi_read(struct target *target, char *buf, uint64_t a);
-static void riscv013_fill_dmi_nop(struct target *target, char *buf);
static int riscv013_get_dmi_scan_length(struct target *target);
-static void riscv013_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d);
-static void riscv013_fill_dm_read(struct target *target, char *buf, uint64_t a);
static void riscv013_fill_dm_nop(struct target *target, char *buf);
static unsigned int register_size(struct target *target, enum gdb_regno number);
static int register_read_direct(struct target *target, riscv_reg_t *value,
@@ -70,6 +68,8 @@ static int read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment);
static int write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
+static bool riscv013_get_impebreak(const struct target *target);
+static unsigned int riscv013_get_progbufsize(const struct target *target);
typedef enum {
HALT_GROUP,
@@ -115,7 +115,7 @@ typedef enum {
typedef struct {
struct list_head list;
- int abs_chain_position;
+ unsigned int abs_chain_position;
/* The base address to access this DM on DMI */
uint32_t base;
/* The number of harts connected to this DM. */
@@ -156,7 +156,9 @@ typedef struct {
/* Number of abstract command data registers. */
unsigned datacount;
/* Number of words in the Program Buffer. */
- unsigned progbufsize;
+ unsigned int progbufsize;
+ /* Hart contains an implicit ebreak at the end of the program buffer. */
+ bool impebreak;
/* We cache the read-only bits of sbcs here. */
uint32_t sbcs;
@@ -223,7 +225,7 @@ static dm013_info_t *get_dm(struct target *target)
if (info->dm)
return info->dm;
- int abs_chain_position = target->tap->abs_chain_position;
+ unsigned int abs_chain_position = target->tap->abs_chain_position;
dm013_info_t *entry;
dm013_info_t *dm = NULL;
@@ -376,7 +378,9 @@ static unsigned int decode_dmi(const struct target *target, char *text, uint32_t
return 0;
}
-void riscv_log_dmi_scan(const struct target *target, int idle, const struct scan_field *field, bool discard_in)
+/* TODO: Move this function to "batch.c" and make it static. */
+void riscv_log_dmi_scan(const struct target *target, int idle,
+ const struct scan_field *field)
{
static const char * const op_string[] = {"-", "r", "w", "?"};
static const char * const status_string[] = {"+", "?", "F", "b"};
@@ -400,7 +404,7 @@ void riscv_log_dmi_scan(const struct target *target, int idle, const struct scan
field->num_bits, op_string[out_op], out_data, out_address,
status_string[in_op], in_data, in_address, idle);
- if (!discard_in && in_op == DTM_DMI_OP_SUCCESS) {
+ if (in_op == DTM_DMI_OP_SUCCESS) {
char in_decoded[decode_dmi(target, NULL, in_address, in_data) + 1];
decode_dmi(target, in_decoded, in_address, in_data);
/* FIXME: The current code assumes that the hardware
@@ -431,44 +435,12 @@ static void select_dmi(struct target *target)
select_dmi_via_bscan(target);
return;
}
+ if (buf_cmp(target->tap->cur_instr, select_dbus.out_value,
+ target->tap->ir_length) == 0)
+ return;
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
}
-static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
-{
- struct scan_field field;
- uint8_t in_value[4];
- uint8_t out_value[4] = { 0 };
-
- if (bscan_tunnel_ir_width != 0)
- return dtmcontrol_scan_via_bscan(target, out, in_ptr);
-
- buf_set_u32(out_value, 0, 32, out);
-
- jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);
-
- field.num_bits = 32;
- field.out_value = out_value;
- field.in_value = in_value;
- jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
-
- /* Always return to dmi. */
- select_dmi(target);
-
- int retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("failed jtag scan: %d", retval);
- return retval;
- }
-
- uint32_t in = buf_get_u32(field.in_value, 0, 32);
- LOG_DEBUG("DTMCS: 0x%x -> 0x%x", out, in);
-
- if (in_ptr)
- *in_ptr = in;
- return ERROR_OK;
-}
-
static int increase_dmi_busy_delay(struct target *target)
{
RISCV013_INFO(info);
@@ -506,220 +478,6 @@ static void decrement_reset_delays_counter(struct target *target, size_t finishe
"resetting learned delays (reset_delays_wait counter expired)");
reset_learned_delays(target);
}
-/**
- * exec: If this is set, assume the scan results in an execution, so more
- * run-test/idle cycles may be required.
- */
-static dmi_status_t dmi_scan(struct target *target, uint32_t *address_in,
- uint32_t *data_in, dmi_op_t op, uint32_t address_out, uint32_t data_out,
- bool exec)
-{
- riscv013_info_t *info = get_info(target);
- unsigned num_bits = info->abits + DTM_DMI_OP_LENGTH + DTM_DMI_DATA_LENGTH;
- size_t num_bytes = (num_bits + 7) / 8;
- uint8_t in[num_bytes];
- uint8_t out[num_bytes];
- struct scan_field field = {
- .num_bits = num_bits,
- .out_value = out,
- .in_value = in
- };
- riscv_bscan_tunneled_scan_context_t bscan_ctxt;
-
- decrement_reset_delays_counter(target, 1);
-
- memset(in, 0, num_bytes);
- memset(out, 0, num_bytes);
-
- if (info->abits == 0) {
- LOG_TARGET_ERROR(target, "Can't access DMI because addrbits=0.");
- return DMI_STATUS_FAILED;
- }
-
- buf_set_u32(out, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, op);
- buf_set_u32(out, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH, data_out);
- buf_set_u32(out, DTM_DMI_ADDRESS_OFFSET, info->abits, address_out);
-
- /* I wanted to place this code in a different function, but the way JTAG command
- queueing works in the jtag handling functions, the scan fields either have to be
- heap allocated, global/static, or else they need to stay on the stack until
- the jtag_execute_queue() call. Heap or static fields in this case doesn't seem
- the best fit. Declaring stack based field values in a subsidiary function call wouldn't
- work. */
- if (bscan_tunnel_ir_width != 0) {
- riscv_add_bscan_tunneled_scan(target, &field, &bscan_ctxt);
- } else {
- /* Assume dbus is already selected. */
- jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
- }
-
- int idle_count = exec
- ? riscv_scan_get_delay(&info->learned_delays, RISCV_DELAY_ABSTRACT_COMMAND)
- : riscv_scan_get_delay(&info->learned_delays, RISCV_DELAY_BASE);
-
- if (idle_count)
- jtag_add_runtest(idle_count, TAP_IDLE);
-
- int retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("dmi_scan failed jtag scan");
- if (data_in)
- *data_in = ~0;
- return DMI_STATUS_FAILED;
- }
-
- if (bscan_tunnel_ir_width != 0) {
- /* need to right-shift "in" by one bit, because of clock skew between BSCAN TAP and DM TAP */
- buffer_shr(in, num_bytes, 1);
- }
-
- if (data_in)
- *data_in = buf_get_u32(in, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);
-
- if (address_in)
- *address_in = buf_get_u32(in, DTM_DMI_ADDRESS_OFFSET, info->abits);
- riscv_log_dmi_scan(target, idle_count, &field, /*discard_in*/ !data_in);
- return buf_get_u32(in, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH);
-}
-
-/**
- * @param target
- * @param data_in The data we received from the target.
- * @param dmi_busy_encountered
- * If non-NULL, will be updated to reflect whether DMI busy was
- * encountered while executing this operation or not.
- * @param op The operation to perform (read/write/nop).
- * @param address The address argument to that operation.
- * @param data_out The data to send to the target.
- * @param timeout_sec
- * @param exec When true, this scan will execute something, so extra RTI
- * cycles may be added.
- * @param ensure_success
- * Scan a nop after the requested operation, ensuring the
- * DMI operation succeeded.
- */
-static int dmi_op_timeout(struct target *target, uint32_t *data_in,
- bool *dmi_busy_encountered, int op, uint32_t address,
- uint32_t data_out, int timeout_sec, bool exec, bool ensure_success)
-{
- select_dmi(target);
-
- dmi_status_t status;
-
- if (dmi_busy_encountered)
- *dmi_busy_encountered = false;
-
- const char *op_name;
- switch (op) {
- case DMI_OP_NOP:
- op_name = "nop";
- break;
- case DMI_OP_READ:
- op_name = "read";
- break;
- case DMI_OP_WRITE:
- op_name = "write";
- break;
- default:
- LOG_ERROR("Invalid DMI operation: %d", op);
- return ERROR_FAIL;
- }
-
- keep_alive();
-
- 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. */
- while (1) {
- status = dmi_scan(target, NULL, NULL, op, address, data_out,
- exec);
- if (status == DMI_STATUS_BUSY) {
- int result = increase_dmi_busy_delay(target);
- if (result != ERROR_OK)
- return result;
- if (dmi_busy_encountered)
- *dmi_busy_encountered = true;
- } else if (status == DMI_STATUS_SUCCESS) {
- break;
- } else {
- dtmcontrol_scan(target, DTM_DTMCS_DMIRESET, NULL /* discard result */);
- break;
- }
- if (time(NULL) - start > timeout_sec)
- return ERROR_TIMEOUT_REACHED;
- }
-
- if (status != DMI_STATUS_SUCCESS) {
- LOG_TARGET_ERROR(target, "Failed DMI %s at 0x%x; status=%d", op_name, address, status);
- return ERROR_FAIL;
- }
-
- if (ensure_success) {
- /* This second loop ensures the request succeeded, and gets back data.
- * Note that NOP can result in a 'busy' result as well, but that would be
- * noticed on the next DMI access we do. */
- while (1) {
- status = dmi_scan(target, NULL, data_in, DMI_OP_NOP, address, 0,
- false);
- if (status == DMI_STATUS_BUSY) {
- int result = increase_dmi_busy_delay(target);
- if (result != ERROR_OK)
- return result;
- if (dmi_busy_encountered)
- *dmi_busy_encountered = true;
- } else if (status == DMI_STATUS_SUCCESS) {
- break;
- } else {
- if (data_in) {
- LOG_TARGET_ERROR(target,
- "Failed DMI %s (NOP) at 0x%x; value=0x%x, status=%d",
- op_name, address, *data_in, status);
- } else {
- LOG_TARGET_ERROR(target,
- "Failed DMI %s (NOP) at 0x%x; status=%d", op_name, address,
- status);
- }
- dtmcontrol_scan(target, DTM_DTMCS_DMIRESET, NULL /* discard result */);
- return ERROR_FAIL;
- }
- if (time(NULL) - start > timeout_sec)
- return ERROR_TIMEOUT_REACHED;
- }
- }
-
- return ERROR_OK;
-}
-
-static int dmi_op(struct target *target, uint32_t *data_in,
- bool *dmi_busy_encountered, int op, uint32_t address,
- uint32_t data_out, bool exec, bool ensure_success)
-{
- int result = dmi_op_timeout(target, data_in, dmi_busy_encountered, op,
- address, data_out, riscv_get_command_timeout_sec(), exec, ensure_success);
- if (result == ERROR_TIMEOUT_REACHED) {
- LOG_TARGET_ERROR(target, "DMI operation didn't complete in %d seconds. The target is "
- "either really slow or broken. You could increase the "
- "timeout with riscv set_command_timeout_sec.",
- riscv_get_command_timeout_sec());
- return ERROR_FAIL;
- }
- return result;
-}
-
-static int dmi_read(struct target *target, uint32_t *value, uint32_t address)
-{
- return dmi_op(target, value, NULL, DMI_OP_READ, address, 0, false, true);
-}
-
-static int dmi_read_exec(struct target *target, uint32_t *value, uint32_t address)
-{
- return dmi_op(target, value, NULL, DMI_OP_READ, address, 0, true, true);
-}
-
-static int dmi_write(struct target *target, uint32_t address, uint32_t value)
-{
- return dmi_op(target, NULL, NULL, DMI_OP_WRITE, address, value, false, true);
-}
static uint32_t riscv013_get_dmi_address(const struct target *target, uint32_t address)
{
@@ -731,23 +489,22 @@ static uint32_t riscv013_get_dmi_address(const struct target *target, uint32_t a
return address + base;
}
-static int dm_op(struct target *target, uint32_t *data_in,
- bool *dmi_busy_encountered, int op, uint32_t address,
- uint32_t data_out, bool exec, bool ensure_success)
+static int batch_run_timeout(struct target *target, struct riscv_batch *batch);
+
+static int dmi_read(struct target *target, uint32_t *value, uint32_t address)
{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return ERROR_FAIL;
- return dmi_op(target, data_in, dmi_busy_encountered, op, address + dm->base,
- data_out, exec, ensure_success);
+ struct riscv_batch *batch = riscv_batch_alloc(target, 1);
+ riscv_batch_add_dmi_read(batch, address, RISCV_DELAY_BASE);
+ int res = batch_run_timeout(target, batch);
+ if (res == ERROR_OK && value)
+ *value = riscv_batch_get_dmi_read_data(batch, 0);
+ riscv_batch_free(batch);
+ return res;
}
static int dm_read(struct target *target, uint32_t *value, uint32_t address)
{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return ERROR_FAIL;
- return dmi_read(target, value, address + dm->base);
+ return dmi_read(target, value, riscv013_get_dmi_address(target, address));
}
static int dm_read_exec(struct target *target, uint32_t *value, uint32_t address)
@@ -755,16 +512,29 @@ static int dm_read_exec(struct target *target, uint32_t *value, uint32_t address
dm013_info_t *dm = get_dm(target);
if (!dm)
return ERROR_FAIL;
+ struct riscv_batch *batch = riscv_batch_alloc(target, 1);
+ riscv_batch_add_dm_read(batch, address, RISCV_DELAY_ABSTRACT_COMMAND);
dm->abstract_cmd_maybe_busy = true;
- return dmi_read_exec(target, value, address + dm->base);
+ int res = batch_run_timeout(target, batch);
+ if (res == ERROR_OK && value)
+ *value = riscv_batch_get_dmi_read_data(batch, 0);
+ riscv_batch_free(batch);
+ return res;
+}
+
+static int dmi_write(struct target *target, uint32_t address, uint32_t value)
+{
+ struct riscv_batch *batch = riscv_batch_alloc(target, 1);
+ riscv_batch_add_dmi_write(batch, address, value, /*read_back*/ true,
+ RISCV_DELAY_BASE);
+ int res = batch_run_timeout(target, batch);
+ riscv_batch_free(batch);
+ return res;
}
static int dm_write(struct target *target, uint32_t address, uint32_t value)
{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return ERROR_FAIL;
- return dmi_write(target, address + dm->base, value);
+ return dmi_write(target, riscv013_get_dmi_address(target, address), value);
}
static bool check_dbgbase_exists(struct target *target)
@@ -930,9 +700,7 @@ clear_cmderr:
return res;
}
-static int batch_run_timeout(struct target *target, struct riscv_batch *batch);
-
-static int execute_abstract_command(struct target *target, uint32_t command,
+int riscv013_execute_abstract_command(struct target *target, uint32_t command,
uint32_t *cmderr)
{
assert(cmderr);
@@ -1068,7 +836,7 @@ static int write_abstract_arg(struct target *target, unsigned index,
/**
* @par size in bits
*/
-static uint32_t access_register_command(struct target *target, uint32_t number,
+uint32_t riscv013_access_register_command(struct target *target, uint32_t number,
unsigned size, uint32_t flags)
{
uint32_t command = set_field(0, DM_COMMAND_CMDTYPE, 0);
@@ -1125,11 +893,11 @@ static int register_read_abstract_with_size(struct target *target,
if (number >= GDB_REGNO_V0 && number <= GDB_REGNO_V31)
return ERROR_FAIL;
- uint32_t command = access_register_command(target, number, size,
+ uint32_t command = riscv013_access_register_command(target, number, size,
AC_ACCESS_REGISTER_TRANSFER);
uint32_t cmderr;
- int result = execute_abstract_command(target, command, &cmderr);
+ int result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result != ERROR_OK) {
if (cmderr == CMDERR_NOT_SUPPORTED) {
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
@@ -1174,7 +942,7 @@ static int register_write_abstract(struct target *target, enum gdb_regno number,
return ERROR_FAIL;
const unsigned int size_bits = register_size(target, number);
- const uint32_t command = access_register_command(target, number, size_bits,
+ const uint32_t command = riscv013_access_register_command(target, number, size_bits,
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);
LOG_DEBUG_REG(target, AC_ACCESS_REGISTER, command);
@@ -1550,9 +1318,7 @@ static unsigned int register_size(struct target *target, enum gdb_regno number)
static bool has_sufficient_progbuf(struct target *target, unsigned size)
{
RISCV013_INFO(info);
- RISCV_INFO(r);
-
- return info->progbufsize + r->impebreak >= size;
+ return info->progbufsize + info->impebreak >= size;
}
/**
@@ -2277,14 +2043,13 @@ static int examine(struct target *target)
LOG_TARGET_INFO(target, "datacount=%d progbufsize=%d",
info->datacount, info->progbufsize);
- RISCV_INFO(r);
- r->impebreak = get_field(dmstatus, DM_DMSTATUS_IMPEBREAK);
+ info->impebreak = get_field(dmstatus, DM_DMSTATUS_IMPEBREAK);
if (!has_sufficient_progbuf(target, 2)) {
LOG_TARGET_WARNING(target, "We won't be able to execute fence instructions on this "
"target. Memory may not always appear consistent. "
"(progbufsize=%d, impebreak=%d)", info->progbufsize,
- r->impebreak);
+ info->impebreak);
}
if (info->progbufsize < 4 && riscv_enable_virtual) {
@@ -2300,6 +2065,8 @@ static int examine(struct target *target)
enum riscv_hart_state state_at_examine_start;
if (riscv_get_hart_state(target, &state_at_examine_start) != ERROR_OK)
return ERROR_FAIL;
+
+ RISCV_INFO(r);
const bool hart_halted_at_examine_start = state_at_examine_start == RISCV_STATE_HALTED;
if (!hart_halted_at_examine_start) {
r->prepped = true;
@@ -2313,74 +2080,9 @@ static int examine(struct target *target)
target->state = TARGET_HALTED;
target->debug_reason = hart_halted_at_examine_start ? DBG_REASON_UNDEFINED : DBG_REASON_DBGRQ;
- /* Without knowing anything else we can at least mess with the
- * program buffer. */
- r->progbuf_size = info->progbufsize;
-
- result = register_read_abstract_with_size(target, NULL, GDB_REGNO_S0, 64);
- if (result == ERROR_OK)
- r->xlen = 64;
- else
- r->xlen = 32;
-
- /* Save s0 and s1. The register cache hasn't be initialized yet so we
- * need to take care of this manually. */
- uint64_t s0, s1;
- if (register_read_abstract(target, &s0, GDB_REGNO_S0) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to read s0.");
- return ERROR_FAIL;
- }
- if (register_read_abstract(target, &s1, GDB_REGNO_S1) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to read s1.");
- return ERROR_FAIL;
- }
-
- if (register_read_direct(target, &r->misa, GDB_REGNO_MISA)) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to read MISA.");
- return ERROR_FAIL;
- }
-
- uint64_t value;
- if (register_read_direct(target, &value, GDB_REGNO_VLENB) != ERROR_OK) {
- if (riscv_supports_extension(target, 'V'))
- LOG_TARGET_WARNING(target, "Couldn't read vlenb; vector register access won't work.");
- r->vlenb = 0;
- } else {
- r->vlenb = value;
- LOG_TARGET_INFO(target, "Vector support with vlenb=%d", r->vlenb);
- }
-
- if (register_read_direct(target, &value, GDB_REGNO_MTOPI) == ERROR_OK) {
- r->mtopi_readable = true;
-
- if (register_read_direct(target, &value, GDB_REGNO_MTOPEI) == ERROR_OK) {
- LOG_TARGET_INFO(target, "S?aia detected with IMSIC");
- r->mtopei_readable = true;
- } else {
- r->mtopei_readable = false;
- LOG_TARGET_INFO(target, "S?aia detected without IMSIC");
- }
- } else {
- r->mtopi_readable = false;
- }
-
- /* Display this as early as possible to help people who are using
- * really slow simulators. */
- LOG_TARGET_DEBUG(target, " XLEN=%d, misa=0x%" PRIx64, r->xlen, r->misa);
-
- /* Restore s0 and s1. */
- if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to write back s0.");
- return ERROR_FAIL;
- }
- if (register_write_direct(target, GDB_REGNO_S1, s1) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to write back s1.");
- return ERROR_FAIL;
- }
-
- /* Now init registers based on what we discovered. */
- if (riscv013_reg_init_all(target) != ERROR_OK)
- return ERROR_FAIL;
+ result = riscv013_reg_examine_all(target);
+ if (result != ERROR_OK)
+ return result;
if (set_dcsr_ebreak(target, false) != ERROR_OK)
return ERROR_FAIL;
@@ -2716,21 +2418,42 @@ static uint32_t sb_sbaccess(unsigned int size_bytes)
return 0;
}
-static int sb_write_address(struct target *target, target_addr_t address,
- bool ensure_success)
+static unsigned int get_sbaadress_reg_count(const struct target *target)
{
RISCV013_INFO(info);
- unsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);
+ const unsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);
+ return DIV_ROUND_UP(sbasize, 32);
+}
+
+static void batch_fill_sb_write_address(const struct target *target,
+ struct riscv_batch *batch, target_addr_t address,
+ enum riscv_scan_delay_class sbaddr0_delay)
+{
/* There currently is no support for >64-bit addresses in OpenOCD. */
- if (sbasize > 96)
- dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS3, 0, false, false);
- if (sbasize > 64)
- dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS2, 0, false, false);
- if (sbasize > 32)
- dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS1,
- (uint32_t)(address >> 32), false, false);
- return dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS0,
- (uint32_t)address, false, ensure_success);
+ assert(sizeof(target_addr_t) == sizeof(uint64_t));
+ const uint32_t addresses[] = {DM_SBADDRESS0, DM_SBADDRESS1, DM_SBADDRESS2, DM_SBADDRESS3};
+ const uint32_t values[] = {(uint32_t)address, (uint32_t)(address >> 32), 0, 0};
+ const unsigned int reg_count = get_sbaadress_reg_count(target);
+ assert(reg_count > 0);
+ assert(reg_count <= ARRAY_SIZE(addresses));
+ assert(ARRAY_SIZE(addresses) == ARRAY_SIZE(values));
+
+ for (unsigned int i = reg_count - 1; i > 0; --i)
+ riscv_batch_add_dm_write(batch, addresses[i], values[i], /* read back */ true,
+ RISCV_DELAY_BASE);
+ riscv_batch_add_dm_write(batch, addresses[0], values[0], /* read back */ true,
+ sbaddr0_delay);
+}
+
+static int sb_write_address(struct target *target, target_addr_t address,
+ enum riscv_scan_delay_class sbaddr0_delay)
+{
+ struct riscv_batch *batch = riscv_batch_alloc(target,
+ get_sbaadress_reg_count(target));
+ batch_fill_sb_write_address(target, batch, address, sbaddr0_delay);
+ const int res = batch_run_timeout(target, batch);
+ riscv_batch_free(batch);
+ return res;
}
static int batch_run(struct target *target, struct riscv_batch *batch)
@@ -3085,8 +2808,8 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->write_progbuf = &riscv013_write_progbuf;
generic_info->execute_progbuf = &riscv013_execute_progbuf;
generic_info->invalidate_cached_progbuf = &riscv013_invalidate_cached_progbuf;
- generic_info->fill_dm_write = &riscv013_fill_dm_write;
- generic_info->fill_dm_read = &riscv013_fill_dm_read;
+ generic_info->fill_dmi_write = &riscv013_fill_dmi_write;
+ generic_info->fill_dmi_read = &riscv013_fill_dmi_read;
generic_info->fill_dm_nop = &riscv013_fill_dm_nop;
generic_info->get_dmi_scan_length = &riscv013_get_dmi_scan_length;
generic_info->authdata_read = &riscv013_authdata_read;
@@ -3097,6 +2820,8 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->read_memory = read_memory;
generic_info->data_bits = &riscv013_data_bits;
generic_info->print_info = &riscv013_print_info;
+ generic_info->get_impebreak = &riscv013_get_impebreak;
+ generic_info->get_progbufsize = &riscv013_get_progbufsize;
generic_info->handle_became_unavailable = &handle_became_unavailable;
generic_info->tick = &tick;
@@ -3533,6 +3258,9 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
return ERROR_NOT_IMPLEMENTED;
}
+ assert(size <= 16);
+ assert(IS_PWR_OF_2(size));
+
dm013_info_t *dm = get_dm(target);
if (!dm)
return ERROR_FAIL;
@@ -3555,21 +3283,9 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
return ERROR_FAIL;
/* This address write will trigger the first read. */
- if (sb_write_address(target, next_address, true) != ERROR_OK)
+ if (sb_write_address(target, next_address, RISCV_DELAY_SYSBUS_READ) != ERROR_OK)
return ERROR_FAIL;
- unsigned int bus_master_read_delay = riscv_scan_get_delay(&info->learned_delays,
- RISCV_DELAY_SYSBUS_READ);
- if (bus_master_read_delay) {
- LOG_TARGET_DEBUG(target, "Waiting %d cycles for bus master read delay",
- bus_master_read_delay);
- jtag_add_runtest(bus_master_read_delay, TAP_IDLE);
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Failed to scan idle sequence");
- return ERROR_FAIL;
- }
- }
-
/* First read has been started. Optimistically assume that it has
* completed. */
@@ -3580,7 +3296,6 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
* be unnecessary.
*/
uint32_t sbvalue[4] = {0};
- assert(size <= 16);
for (uint32_t i = (next_address - address) / size; i < count - 1; i++) {
const uint32_t size_in_words = DIV_ROUND_UP(size, 4);
struct riscv_batch *batch = riscv_batch_alloc(target, size_in_words);
@@ -3601,10 +3316,10 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
const size_t last_key = batch->read_keys_used - 1;
for (size_t k = 0; k <= last_key; ++k) {
- sbvalue[k] = riscv_batch_get_dmi_read_data(batch,
- last_key - k);
- buf_set_u32(buffer + i * size + k * 4, 0, 8 * size, sbvalue[k]);
+ sbvalue[k] = riscv_batch_get_dmi_read_data(batch, last_key - k);
+ buf_set_u32(buffer + i * size + k * 4, 0, MIN(32, 8 * size), sbvalue[k]);
}
+
riscv_batch_free(batch);
const target_addr_t read_addr = address + i * increment;
log_memory_access(read_addr, sbvalue, size, true);
@@ -3847,7 +3562,7 @@ static int read_memory_abstract(struct target *target, target_addr_t address,
/* Execute the command */
uint32_t cmderr;
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
@@ -3869,7 +3584,7 @@ static int read_memory_abstract(struct target *target, target_addr_t address,
} else {
/* Try the same access but with postincrement disabled. */
command = access_memory_command(target, false, width, false, false);
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result == ERROR_OK) {
LOG_TARGET_DEBUG(target, "aampostincrement is not supported on this target.");
info->has_aampostincrement = YNM_NO;
@@ -3940,7 +3655,7 @@ static int write_memory_abstract(struct target *target, target_addr_t address,
/* Execute the command */
uint32_t cmderr;
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
@@ -3962,7 +3677,7 @@ static int write_memory_abstract(struct target *target, target_addr_t address,
} else {
/* Try the same access but with postincrement disabled. */
command = access_memory_command(target, false, width, false, true);
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result == ERROR_OK) {
LOG_TARGET_DEBUG(target, "aampostincrement is not supported on this target.");
info->has_aampostincrement = YNM_NO;
@@ -4008,11 +3723,11 @@ static int read_memory_progbuf_inner_startup(struct target *target,
/* AC_ACCESS_REGISTER_POSTEXEC is used to trigger first stage of the
* pipeline (memory -> s1) whenever this command is executed.
*/
- const uint32_t startup_command = access_register_command(target,
+ const uint32_t startup_command = riscv013_access_register_command(target,
GDB_REGNO_S1, riscv_xlen(target),
AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);
uint32_t cmderr;
- if (execute_abstract_command(target, startup_command, &cmderr) != ERROR_OK)
+ if (riscv013_execute_abstract_command(target, startup_command, &cmderr) != ERROR_OK)
return ERROR_FAIL;
/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
@@ -4495,11 +4210,11 @@ static int read_memory_progbuf_inner_one(struct target *target,
if (write_abstract_arg(target, 0, access.target_address, riscv_xlen(target))
!= ERROR_OK)
return ERROR_FAIL;
- uint32_t command = access_register_command(target, GDB_REGNO_S1,
+ uint32_t command = riscv013_access_register_command(target, GDB_REGNO_S1,
riscv_xlen(target), AC_ACCESS_REGISTER_WRITE |
AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);
uint32_t cmderr;
- if (execute_abstract_command(target, command, &cmderr) != ERROR_OK)
+ if (riscv013_execute_abstract_command(target, command, &cmderr) != ERROR_OK)
return ERROR_FAIL;
return read_word_from_s1(target, access, 0);
@@ -4681,9 +4396,10 @@ static int write_memory_bus_v1(struct target *target, target_addr_t address,
target_addr_t next_address = address;
target_addr_t end_address = address + count * size;
- int result;
+ int result = sb_write_address(target, next_address, RISCV_DELAY_BASE);
+ if (result != ERROR_OK)
+ return result;
- sb_write_address(target, next_address, true);
while (next_address < end_address) {
LOG_TARGET_DEBUG(target, "Transferring burst starting at address 0x%" TARGET_PRIxADDR,
next_address);
@@ -4837,14 +4553,14 @@ static int write_memory_progbuf_startup(struct target *target, target_addr_t *ad
/* Write and execute command that moves the value from data0 [, data1]
* into S1 and executes program buffer. */
- uint32_t command = access_register_command(target,
+ uint32_t command = riscv013_access_register_command(target,
GDB_REGNO_S1, riscv_xlen(target),
AC_ACCESS_REGISTER_POSTEXEC |
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);
uint32_t cmderr;
- if (execute_abstract_command(target, command, &cmderr) != ERROR_OK)
+ if (riscv013_execute_abstract_command(target, command, &cmderr) != ERROR_OK)
return ERROR_FAIL;
log_memory_access64(*address_p, value, size, /*is_read*/ false);
@@ -5163,6 +4879,18 @@ static int write_memory(struct target *target, target_addr_t address,
return ret;
}
+static bool riscv013_get_impebreak(const struct target *target)
+{
+ RISCV013_INFO(r);
+ return r->impebreak;
+}
+
+static unsigned int riscv013_get_progbufsize(const struct target *target)
+{
+ RISCV013_INFO(r);
+ return r->progbufsize;
+}
+
static int arch_state(struct target *target)
{
return ERROR_OK;
@@ -5515,7 +5243,7 @@ static int riscv013_execute_progbuf(struct target *target, uint32_t *cmderr)
run_program = set_field(run_program, AC_ACCESS_REGISTER_TRANSFER, 0);
run_program = set_field(run_program, AC_ACCESS_REGISTER_REGNO, 0x1000);
- return execute_abstract_command(target, run_program, cmderr);
+ return riscv013_execute_abstract_command(target, run_program, cmderr);
}
static void riscv013_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d)
@@ -5534,7 +5262,7 @@ static void riscv013_fill_dmi_read(struct target *target, char *buf, uint64_t a)
buf_set_u64((unsigned char *)buf, DTM_DMI_ADDRESS_OFFSET, info->abits, a);
}
-static void riscv013_fill_dmi_nop(struct target *target, char *buf)
+static void riscv013_fill_dm_nop(struct target *target, char *buf)
{
RISCV013_INFO(info);
buf_set_u64((unsigned char *)buf, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, DMI_OP_NOP);
@@ -5548,27 +5276,6 @@ static int riscv013_get_dmi_scan_length(struct target *target)
return info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH;
}
-void riscv013_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d)
-{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return;
- riscv013_fill_dmi_write(target, buf, a + dm->base, d);
-}
-
-void riscv013_fill_dm_read(struct target *target, char *buf, uint64_t a)
-{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return;
- riscv013_fill_dmi_read(target, buf, a + dm->base);
-}
-
-void riscv013_fill_dm_nop(struct target *target, char *buf)
-{
- riscv013_fill_dmi_nop(target, buf);
-}
-
static int maybe_execute_fence_i(struct target *target)
{
if (has_sufficient_progbuf(target, 2))
diff --git a/src/target/riscv/riscv-013.h b/src/target/riscv/riscv-013.h
index be508f7..ca2d4ae 100644
--- a/src/target/riscv/riscv-013.h
+++ b/src/target/riscv/riscv-013.h
@@ -19,5 +19,9 @@ int riscv013_set_register(struct target *target, enum gdb_regno rid,
riscv_reg_t value);
int riscv013_set_register_buf(struct target *target, enum gdb_regno regno,
const uint8_t *value);
+uint32_t riscv013_access_register_command(struct target *target, uint32_t number,
+ unsigned int size, uint32_t flags);
+int riscv013_execute_abstract_command(struct target *target, uint32_t command,
+ uint32_t *cmderr);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_013_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_013_H */
diff --git a/src/target/riscv/riscv-013_reg.c b/src/target/riscv/riscv-013_reg.c
index a71a01c..514103b 100644
--- a/src/target/riscv/riscv-013_reg.c
+++ b/src/target/riscv/riscv-013_reg.c
@@ -5,10 +5,12 @@
#endif
#include "riscv-013_reg.h"
+#include "field_helpers.h"
#include "riscv_reg.h"
#include "riscv_reg_impl.h"
#include "riscv-013.h"
+#include "debug_defines.h"
#include <helper/time_support.h>
static int riscv013_reg_get(struct reg *reg)
@@ -44,7 +46,6 @@ static int riscv013_reg_get(struct reg *reg)
static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
{
struct target *target = riscv_reg_impl_get_target(reg);
- RISCV_INFO(r);
char *str = buf_to_hex_str(buf, reg->size);
LOG_TARGET_DEBUG(target, "Write 0x%s to %s (valid=%d).", str, reg->name,
@@ -57,17 +58,6 @@ static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
buf_get_u64(buf, 0, reg->size) == 0)
return ERROR_OK;
- if (reg->number == GDB_REGNO_TDATA1 ||
- reg->number == GDB_REGNO_TDATA2) {
- r->manual_hwbp_set = true;
- /* When enumerating triggers, we clear any triggers with DMODE set,
- * assuming they were left over from a previous debug session. So make
- * sure that is done before a user might be setting their own triggers.
- */
- if (riscv_enumerate_triggers(target) != ERROR_OK)
- return ERROR_FAIL;
- }
-
if (reg->number >= GDB_REGNO_V0 && reg->number <= GDB_REGNO_V31) {
if (riscv013_set_register_buf(target, reg->number, buf) != ERROR_OK)
return ERROR_FAIL;
@@ -85,33 +75,277 @@ static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
static const struct reg_arch_type *riscv013_gdb_regno_reg_type(uint32_t regno)
{
- static const struct reg_arch_type riscv011_reg_type = {
+ static const struct reg_arch_type riscv013_reg_type = {
.get = riscv013_reg_get,
.set = riscv013_reg_set
};
- return &riscv011_reg_type;
+ return &riscv013_reg_type;
}
-static int riscv013_init_reg(struct target *target, uint32_t regno)
+static int init_cache_entry(struct target *target, uint32_t regno)
+{
+ struct reg * const reg = riscv_reg_impl_cache_entry(target, regno);
+ if (riscv_reg_impl_is_initialized(reg))
+ return ERROR_OK;
+ return riscv_reg_impl_init_cache_entry(target, regno,
+ riscv_reg_impl_gdb_regno_exist(target, regno),
+ riscv013_gdb_regno_reg_type(regno));
+}
+
+/**
+ * Some registers are optional (e.g. "misa"). For such registers it is first
+ * assumed they exist (via "assume_reg_exist()"), then the read is attempted
+ * (via the usual "riscv_reg_get()") and if the read fails, the register is
+ * marked as non-existing (via "riscv_reg_impl_set_exist()").
+ */
+static int assume_reg_exist(struct target *target, uint32_t regno)
{
- return riscv_reg_impl_init_one(target, regno, riscv013_gdb_regno_reg_type(regno));
+ return riscv_reg_impl_init_cache_entry(target, regno,
+ /* exist */ true, riscv013_gdb_regno_reg_type(regno));
}
-int riscv013_reg_init_all(struct target *target)
+static int examine_xlen(struct target *target)
{
- if (riscv_reg_impl_init_cache(target) != ERROR_OK)
+ RISCV_INFO(r);
+ unsigned int cmderr;
+
+ const uint32_t command = riscv013_access_register_command(target,
+ GDB_REGNO_S0, /* size */ 64, AC_ACCESS_REGISTER_TRANSFER);
+ int res = riscv013_execute_abstract_command(target, command, &cmderr);
+ if (res == ERROR_OK) {
+ r->xlen = 64;
+ return ERROR_OK;
+ }
+ if (res == ERROR_TIMEOUT_REACHED)
return ERROR_FAIL;
+ r->xlen = 32;
+
+ return ERROR_OK;
+}
+
+static int examine_vlenb(struct target *target)
+{
+ RISCV_INFO(r);
+
+ /* Reading "vlenb" requires "mstatus.vs" to be set, so "mstatus" should
+ * be accessible.*/
+ int res = init_cache_entry(target, GDB_REGNO_MSTATUS);
+ if (res != ERROR_OK)
+ return res;
+
+ res = assume_reg_exist(target, GDB_REGNO_VLENB);
+ if (res != ERROR_OK)
+ return res;
+
+ riscv_reg_t vlenb_val;
+ if (riscv_reg_get(target, &vlenb_val, GDB_REGNO_VLENB) != ERROR_OK) {
+ if (riscv_supports_extension(target, 'V'))
+ LOG_TARGET_WARNING(target, "Couldn't read vlenb; vector register access won't work.");
+ r->vlenb = 0;
+ return riscv_reg_impl_set_exist(target, GDB_REGNO_VLENB, false);
+ }
+ /* As defined by RISC-V V extension specification:
+ * https://github.com/riscv/riscv-v-spec/blob/2f68ef7256d6ec53e4d2bd7cb12862f406d64e34/v-spec.adoc?plain=1#L67-L72 */
+ const unsigned int vlen_max = 65536;
+ const unsigned int vlenb_max = vlen_max / 8;
+ if (vlenb_val > vlenb_max) {
+ LOG_TARGET_WARNING(target, "'vlenb == %" PRIu64
+ "' is greater than maximum allowed by specification (%u); vector register access won't work.",
+ vlenb_val, vlenb_max);
+ r->vlenb = 0;
+ return ERROR_OK;
+ }
+ assert(vlenb_max <= UINT_MAX);
+ r->vlenb = (unsigned int)vlenb_val;
+
+ LOG_TARGET_INFO(target, "Vector support with vlenb=%u", r->vlenb);
+ return ERROR_OK;
+}
+
+enum misa_mxl {
+ MISA_MXL_INVALID = 0,
+ MISA_MXL_32 = 1,
+ MISA_MXL_64 = 2,
+ MISA_MXL_128 = 3
+};
+
+unsigned int mxl_to_xlen(enum misa_mxl mxl)
+{
+ switch (mxl) {
+ case MISA_MXL_32:
+ return 32;
+ case MISA_MXL_64:
+ return 64;
+ case MISA_MXL_128:
+ return 128;
+ case MISA_MXL_INVALID:
+ assert(0);
+ }
+ return 0;
+}
+
+static int check_misa_mxl(const struct target *target)
+{
+ RISCV_INFO(r);
+
+ if (r->misa == 0) {
+ LOG_TARGET_WARNING(target, "'misa' register is read as zero."
+ "OpenOCD will not be able to determine some hart's capabilities.");
+ return ERROR_OK;
+ }
+ const unsigned int dxlen = riscv_xlen(target);
+ assert(dxlen <= sizeof(riscv_reg_t) * CHAR_BIT);
+ assert(dxlen >= 2);
+ const riscv_reg_t misa_mxl_mask = (riscv_reg_t)0x3 << (dxlen - 2);
+ const unsigned int mxl = get_field(r->misa, misa_mxl_mask);
+ if (mxl == MISA_MXL_INVALID) {
+ /* This is not an error!
+ * Imagine the platform that:
+ * - Has no abstract access to CSRs, so that CSRs are read
+ * through Program Buffer via "csrr" instruction.
+ * - Complies to v1.10 of the Priveleged Spec, so that misa.mxl
+ * is WARL and MXLEN may be chainged.
+ * https://github.com/riscv/riscv-isa-manual/commit/9a7dd2fe29011587954560b5dcf1875477b27ad8
+ * - DXLEN == MXLEN on reset == 64.
+ * In a following scenario:
+ * - misa.mxl was written, so that MXLEN is 32.
+ * - Debugger connects to the target.
+ * - Debugger observes DXLEN == 64.
+ * - Debugger reads misa:
+ * - Abstract access fails with "cmderr == not supported".
+ * - Access via Program Buffer involves reading "misa" to an
+ * "xreg" via "csrr", so that the "xreg" is filled with
+ * zero-extended value of "misa" (since "misa" is
+ * MXLEN-wide).
+ * - Debugger derives "misa.mxl" assumig "misa" is DXLEN-bit
+ * wide (64) while MXLEN is 32 and therefore erroneously
+ * assumes "misa.mxl" to be zero (invalid).
+ */
+ LOG_TARGET_WARNING(target, "Detected DXLEN (%u) does not match "
+ "MXLEN: misa.mxl == 0, misa == 0x%" PRIx64 ".",
+ dxlen, r->misa);
+ return ERROR_OK;
+ }
+ const unsigned int mxlen = mxl_to_xlen(mxl);
+ if (dxlen < mxlen) {
+ LOG_TARGET_ERROR(target,
+ "MXLEN (%u) reported in misa.mxl field exceeds "
+ "the detected DXLEN (%u)",
+ mxlen, dxlen);
+ return ERROR_FAIL;
+ }
+ /* NOTE:
+ * The value of "misa.mxl" may stil not coincide with "xlen".
+ * "misa[26:XLEN-3]" bits are marked as WIRI in at least version 1.10
+ * of RISC-V Priveleged Spec. Therefore, if "xlen" is erroneously
+ * assumed to be 32 when it actually is 64, "mxl" will be read from
+ * this WIRI field and may be equal to "MISA_MXL_32" by coincidence.
+ * This is not an issue though from the version 1.11 onward, since
+ * "misa[26:XLEN-3]" became WARL and equal to 0.
+ */
+
+ /* Display this as early as possible to help people who are using
+ * really slow simulators. */
+ LOG_TARGET_DEBUG(target, " XLEN=%d, misa=0x%" PRIx64, riscv_xlen(target), r->misa);
+ return ERROR_OK;
+}
+
+static int examine_misa(struct target *target)
+{
+ RISCV_INFO(r);
+
+ int res = init_cache_entry(target, GDB_REGNO_MISA);
+ if (res != ERROR_OK)
+ return res;
+
+ res = riscv_reg_get(target, &r->misa, GDB_REGNO_MISA);
+ if (res != ERROR_OK)
+ return res;
+ return check_misa_mxl(target);
+}
+
+static int examine_mtopi(struct target *target)
+{
+ RISCV_INFO(r);
+
+ /* Assume the registers exist */
+ r->mtopi_readable = true;
+ r->mtopei_readable = true;
+
+ int res = assume_reg_exist(target, GDB_REGNO_MTOPI);
+ if (res != ERROR_OK)
+ return res;
+ res = assume_reg_exist(target, GDB_REGNO_MTOPEI);
+ if (res != ERROR_OK)
+ return res;
+
+ riscv_reg_t value;
+ if (riscv_reg_get(target, &value, GDB_REGNO_MTOPI) != ERROR_OK) {
+ r->mtopi_readable = false;
+ r->mtopei_readable = false;
+ } else if (riscv_reg_get(target, &value, GDB_REGNO_MTOPEI) != ERROR_OK) {
+ LOG_TARGET_INFO(target, "S?aia detected without IMSIC");
+ r->mtopei_readable = false;
+ } else {
+ LOG_TARGET_INFO(target, "S?aia detected with IMSIC");
+ }
+ res = riscv_reg_impl_set_exist(target, GDB_REGNO_MTOPI, r->mtopi_readable);
+ if (res != ERROR_OK)
+ return res;
+
+ return riscv_reg_impl_set_exist(target, GDB_REGNO_MTOPEI, r->mtopei_readable);
+}
+
+/**
+ * This function assumes target's DM to be initialized (target is able to
+ * access DMs registers, execute program buffer, etc.)
+ */
+int riscv013_reg_examine_all(struct target *target)
+{
+ int res = riscv_reg_impl_init_cache(target);
+ if (res != ERROR_OK)
+ return res;
init_shared_reg_info(target);
+ assert(target->state == TARGET_HALTED);
+
+ res = examine_xlen(target);
+ if (res != ERROR_OK)
+ return res;
+
+ /* Reading CSRs may clobber "s0", "s1", so it should be possible to
+ * save them in cache. */
+ res = init_cache_entry(target, GDB_REGNO_S0);
+ if (res != ERROR_OK)
+ return res;
+ res = init_cache_entry(target, GDB_REGNO_S1);
+ if (res != ERROR_OK)
+ return res;
+
+ res = examine_misa(target);
+ if (res != ERROR_OK)
+ return res;
+
+ res = examine_vlenb(target);
+ if (res != ERROR_OK)
+ return res;
+
riscv_reg_impl_init_vector_reg_type(target);
- for (uint32_t regno = 0; regno < target->reg_cache->num_regs; ++regno)
- if (riscv013_init_reg(target, regno) != ERROR_OK)
- return ERROR_FAIL;
+ res = examine_mtopi(target);
+ if (res != ERROR_OK)
+ return res;
- if (riscv_reg_impl_expose_csrs(target) != ERROR_OK)
- return ERROR_FAIL;
+ for (uint32_t regno = 0; regno < target->reg_cache->num_regs; ++regno) {
+ res = init_cache_entry(target, regno);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ res = riscv_reg_impl_expose_csrs(target);
+ if (res != ERROR_OK)
+ return res;
riscv_reg_impl_hide_csrs(target);
diff --git a/src/target/riscv/riscv-013_reg.h b/src/target/riscv/riscv-013_reg.h
index 2bdaaa0..e542a35 100644
--- a/src/target/riscv/riscv-013_reg.h
+++ b/src/target/riscv/riscv-013_reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef OPENOCD_TARGET_RISCV_RISCV_REG_013_H
-#define OPENOCD_TARGET_RISCV_RISCV_REG_013_H
+#ifndef OPENOCD_TARGET_RISCV_RISCV_013_REG_H
+#define OPENOCD_TARGET_RISCV_RISCV_013_REG_H
#include "target/target.h"
#include "gdb_regs.h"
@@ -13,10 +13,11 @@
*/
/**
- * Init initialize register cache. After this function all registers can be
- * safely accessed via functions described here and in `riscv_reg.h`.
+ * This function assumes target is halted.
+ * After this function all registers can be safely accessed via functions
+ * described here and in `riscv_reg.h`.
*/
-int riscv013_reg_init_all(struct target *target);
+int riscv013_reg_examine_all(struct target *target);
/**
* This function is used to save the value of a register in cache. The register
@@ -28,4 +29,4 @@ int riscv013_reg_init_all(struct target *target);
*/
int riscv013_reg_save(struct target *target, enum gdb_regno regid);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_REG_013_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_013_REG_H */
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index a57c709..11f3956 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -54,7 +54,8 @@ struct scan_field select_idcode = {
};
static bscan_tunnel_type_t bscan_tunnel_type;
-int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
+#define BSCAN_TUNNEL_IR_WIDTH_NBITS 7
+uint8_t bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
static int bscan_tunnel_ir_id; /* IR ID of the JTAG TAP to access the tunnel. Valid when not 0 */
static const uint8_t bscan_zero[4] = {0};
@@ -67,7 +68,6 @@ static struct scan_field select_user4 = {
};
-static uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */
static struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
{
.num_bits = 3,
@@ -80,8 +80,8 @@ static struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
.in_value = NULL,
},
{
- .num_bits = 7,
- .out_value = bscan_tunneled_ir_width,
+ .num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS,
+ .out_value = &bscan_tunnel_ir_width,
.in_value = NULL,
},
{
@@ -98,8 +98,8 @@ static struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = {
.in_value = NULL,
},
{
- .num_bits = 7,
- .out_value = bscan_tunneled_ir_width,
+ .num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS,
+ .out_value = &bscan_tunnel_ir_width,
.in_value = NULL,
},
{
@@ -300,7 +300,6 @@ void select_dmi_via_bscan(struct target *target)
int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_ptr)
{
/* On BSCAN TAP: Select IR=USER4, issue tunneled IR scan via BSCAN TAP's DR */
- uint8_t tunneled_ir_width[4] = {bscan_tunnel_ir_width};
uint8_t tunneled_dr_width[4] = {32};
uint8_t out_value[5] = {0};
uint8_t in_value[5] = {0};
@@ -316,8 +315,8 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
tunneled_ir[1].num_bits = bscan_tunnel_ir_width;
tunneled_ir[1].out_value = ir_dtmcontrol;
tunneled_ir[1].in_value = NULL;
- tunneled_ir[2].num_bits = 7;
- tunneled_ir[2].out_value = tunneled_ir_width;
+ tunneled_ir[2].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
+ tunneled_ir[2].out_value = &bscan_tunnel_ir_width;
tunneled_ir[2].in_value = NULL;
tunneled_ir[3].num_bits = 1;
tunneled_ir[3].out_value = bscan_zero;
@@ -329,7 +328,7 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
tunneled_dr[1].num_bits = 32 + 1;
tunneled_dr[1].out_value = out_value;
tunneled_dr[1].in_value = in_value;
- tunneled_dr[2].num_bits = 7;
+ tunneled_dr[2].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
tunneled_dr[2].out_value = tunneled_dr_width;
tunneled_dr[2].in_value = NULL;
tunneled_dr[3].num_bits = 1;
@@ -343,8 +342,8 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
tunneled_ir[2].num_bits = bscan_tunnel_ir_width;
tunneled_ir[2].out_value = ir_dtmcontrol;
tunneled_ir[1].in_value = NULL;
- tunneled_ir[1].num_bits = 7;
- tunneled_ir[1].out_value = tunneled_ir_width;
+ tunneled_ir[1].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
+ tunneled_ir[1].out_value = &bscan_tunnel_ir_width;
tunneled_ir[2].in_value = NULL;
tunneled_ir[0].num_bits = 1;
tunneled_ir[0].out_value = bscan_zero;
@@ -383,22 +382,23 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
return ERROR_OK;
}
-static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
+/* TODO: rename "dtmcontrol"-> "dtmcs" */
+int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
{
- struct scan_field field;
- uint8_t in_value[4];
- uint8_t out_value[4] = { 0 };
+ uint8_t value[4];
if (bscan_tunnel_ir_width != 0)
return dtmcontrol_scan_via_bscan(target, out, in_ptr);
- buf_set_u32(out_value, 0, 32, out);
+ buf_set_u32(value, 0, 32, out);
jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);
- field.num_bits = 32;
- field.out_value = out_value;
- field.in_value = in_value;
+ struct scan_field field = {
+ .num_bits = 32,
+ .out_value = value,
+ .in_value = in_ptr ? value : NULL
+ };
jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
/* Always return to dbus. */
@@ -406,15 +406,18 @@ static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr
int retval = jtag_execute_queue();
if (retval != ERROR_OK) {
- LOG_TARGET_ERROR(target, "dtmcontrol scan failed, error code = %d", retval);
+ LOG_TARGET_ERROR(target, "dtmcs scan failed, error code = %d", retval);
return retval;
}
- uint32_t in = buf_get_u32(field.in_value, 0, 32);
- LOG_DEBUG("DTMCONTROL: 0x%x -> 0x%x", out, in);
-
- if (in_ptr)
+ if (in_ptr) {
+ assert(field.in_value);
+ uint32_t in = buf_get_u32(field.in_value, 0, 32);
+ LOG_TARGET_DEBUG(target, "DTMCS: 0x%" PRIx32 " -> 0x%" PRIx32, out, in);
*in_ptr = in;
+ } else {
+ LOG_TARGET_DEBUG(target, "DTMCS: 0x%" PRIx32 " -> ?", out);
+ }
return ERROR_OK;
}
@@ -473,7 +476,6 @@ static int riscv_init_target(struct command_context *cmd_ctx,
}
h_u32_to_le(ir_user4, ir_user4_raw);
select_user4.num_bits = target->tap->ir_length;
- bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width;
if (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)
bscan_tunnel_data_register_select_dmi[1].num_bits = bscan_tunnel_ir_width;
else /* BSCAN_TUNNEL_NESTED_TAP */
@@ -527,6 +529,8 @@ static void riscv_deinit_target(struct target *target)
if (!info)
return;
+ free(info->reserved_triggers);
+
range_list_t *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &info->hide_csr, list) {
free(entry->name);
@@ -620,6 +624,15 @@ static int find_first_trigger_by_id(struct target *target, int unique_id)
static int set_trigger(struct target *target, unsigned int idx, riscv_reg_t tdata1, riscv_reg_t tdata2,
riscv_reg_t tdata1_ignore_mask)
{
+ RISCV_INFO(r);
+ assert(r->reserved_triggers);
+ assert(idx < r->trigger_count);
+ if (r->reserved_triggers[idx]) {
+ LOG_TARGET_DEBUG(target,
+ "Trigger %u is reserved by 'reserve_trigger' command.", idx);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
riscv_reg_t tdata1_rb, tdata2_rb;
// Select which trigger to use
if (riscv_reg_set(target, GDB_REGNO_TSELECT, idx) != ERROR_OK)
@@ -2453,87 +2466,48 @@ static int riscv_deassert_reset(struct target *target)
return tt->deassert_reset(target);
}
-/* state must be riscv_reg_t state[RISCV_MAX_HWBPS] = {0}; */
-static int disable_triggers(struct target *target, riscv_reg_t *state)
+/* "wp_is_set" array must have at least "r->trigger_count" items. */
+static int disable_watchpoints(struct target *target, bool *wp_is_set)
{
RISCV_INFO(r);
-
LOG_TARGET_DEBUG(target, "Disabling triggers.");
- if (riscv_enumerate_triggers(target) != ERROR_OK)
- return ERROR_FAIL;
-
- if (r->manual_hwbp_set) {
- /* Look at every trigger that may have been set. */
- riscv_reg_t tselect;
- if (riscv_reg_get(target, &tselect, GDB_REGNO_TSELECT) != ERROR_OK)
- return ERROR_FAIL;
- for (unsigned int t = 0; t < r->trigger_count; t++) {
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, t) != ERROR_OK)
- return ERROR_FAIL;
- riscv_reg_t tdata1;
- if (riscv_reg_get(target, &tdata1, GDB_REGNO_TDATA1) != ERROR_OK)
+ /* TODO: The algorithm is flawed and may result in a situation described in
+ * https://github.com/riscv-collab/riscv-openocd/issues/1108
+ */
+ memset(wp_is_set, false, r->trigger_count);
+ struct watchpoint *watchpoint = target->watchpoints;
+ int i = 0;
+ while (watchpoint) {
+ LOG_TARGET_DEBUG(target, "Watchpoint %" PRIu32 ": set=%s",
+ watchpoint->unique_id,
+ wp_is_set[i] ? "true" : "false");
+ wp_is_set[i] = watchpoint->is_set;
+ if (watchpoint->is_set) {
+ if (riscv_remove_watchpoint(target, watchpoint) != ERROR_OK)
return ERROR_FAIL;
- if (tdata1 & CSR_TDATA1_DMODE(riscv_xlen(target))) {
- state[t] = tdata1;
- if (riscv_reg_set(target, GDB_REGNO_TDATA1, 0) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, tselect) != ERROR_OK)
- return ERROR_FAIL;
-
- } else {
- /* Just go through the triggers we manage. */
- struct watchpoint *watchpoint = target->watchpoints;
- int i = 0;
- while (watchpoint) {
- LOG_TARGET_DEBUG(target, "Watchpoint %d: set=%d", i, watchpoint->is_set);
- state[i] = watchpoint->is_set;
- if (watchpoint->is_set) {
- if (riscv_remove_watchpoint(target, watchpoint) != ERROR_OK)
- return ERROR_FAIL;
- }
- watchpoint = watchpoint->next;
- i++;
}
+ watchpoint = watchpoint->next;
+ i++;
}
return ERROR_OK;
}
-static int enable_triggers(struct target *target, riscv_reg_t *state)
+static int enable_watchpoints(struct target *target, bool *wp_is_set)
{
- RISCV_INFO(r);
-
- if (r->manual_hwbp_set) {
- /* Look at every trigger that may have been set. */
- riscv_reg_t tselect;
- if (riscv_reg_get(target, &tselect, GDB_REGNO_TSELECT) != ERROR_OK)
- return ERROR_FAIL;
- for (unsigned int t = 0; t < r->trigger_count; t++) {
- if (state[t] != 0) {
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, t) != ERROR_OK)
- return ERROR_FAIL;
- if (riscv_reg_set(target, GDB_REGNO_TDATA1, state[t]) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, tselect) != ERROR_OK)
- return ERROR_FAIL;
-
- } else {
- struct watchpoint *watchpoint = target->watchpoints;
- int i = 0;
- while (watchpoint) {
- LOG_TARGET_DEBUG(target, "Watchpoint %d: cleared=%" PRId64, i, state[i]);
- if (state[i]) {
- if (riscv_add_watchpoint(target, watchpoint) != ERROR_OK)
- return ERROR_FAIL;
- }
- watchpoint = watchpoint->next;
- i++;
+ struct watchpoint *watchpoint = target->watchpoints;
+ int i = 0;
+ while (watchpoint) {
+ LOG_TARGET_DEBUG(target, "Watchpoint %" PRIu32
+ ": %s to be re-enabled.", watchpoint->unique_id,
+ wp_is_set[i] ? "needs " : "does not need");
+ if (wp_is_set[i]) {
+ if (riscv_add_watchpoint(target, watchpoint) != ERROR_OK)
+ return ERROR_FAIL;
}
+ watchpoint = watchpoint->next;
+ i++;
}
return ERROR_OK;
@@ -3781,9 +3755,16 @@ static int riscv_openocd_step_impl(struct target *target, int current,
return ERROR_FAIL;
}
- riscv_reg_t trigger_state[RISCV_MAX_HWBPS] = {0};
- if (disable_triggers(target, trigger_state) != ERROR_OK)
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+
+ RISCV_INFO(r);
+ bool *wps_to_enable = calloc(r->trigger_count, sizeof(*wps_to_enable));
+ if (disable_watchpoints(target, wps_to_enable) != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Failed to temporarily disable "
+ "watchpoints before single-step.");
return ERROR_FAIL;
+ }
bool success = true;
uint64_t current_mstatus;
@@ -3814,9 +3795,10 @@ static int riscv_openocd_step_impl(struct target *target, int current,
}
_exit:
- if (enable_triggers(target, trigger_state) != ERROR_OK) {
+ if (enable_watchpoints(target, wps_to_enable) != ERROR_OK) {
success = false;
- LOG_TARGET_ERROR(target, "Unable to enable triggers.");
+ LOG_TARGET_ERROR(target, "Failed to re-enable watchpoints "
+ "after single-step.");
}
if (breakpoint && (riscv_add_breakpoint(target, breakpoint) != ERROR_OK)) {
@@ -4382,18 +4364,23 @@ COMMAND_HANDLER(riscv_resume_order)
COMMAND_HANDLER(riscv_use_bscan_tunnel)
{
- int irwidth = 0;
+ uint8_t irwidth = 0;
int tunnel_type = BSCAN_TUNNEL_NESTED_TAP;
- if (CMD_ARGC > 2) {
- LOG_ERROR("Command takes at most two arguments");
+ if (CMD_ARGC < 1 || CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- } else if (CMD_ARGC == 1) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);
- } else if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tunnel_type);
+
+ if (CMD_ARGC >= 1) {
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], irwidth);
+ assert(BSCAN_TUNNEL_IR_WIDTH_NBITS < 8);
+ if (irwidth >= (uint8_t)1 << BSCAN_TUNNEL_IR_WIDTH_NBITS) {
+ command_print(CMD, "'value' does not fit into %d bits.",
+ BSCAN_TUNNEL_IR_WIDTH_NBITS);
+ return ERROR_COMMAND_ARGUMENT_OVERFLOW;
+ }
}
+ if (CMD_ARGC == 2)
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tunnel_type);
if (tunnel_type == BSCAN_TUNNEL_NESTED_TAP)
LOG_INFO("Nested Tap based Bscan Tunnel Selected");
else if (tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)
@@ -5031,6 +5018,57 @@ COMMAND_HANDLER(riscv_set_enable_trigger_feature)
return ERROR_OK;
}
+static COMMAND_HELPER(report_reserved_triggers, struct target *target)
+{
+ RISCV_INFO(r);
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+ const char *separator = "";
+ for (riscv_reg_t t = 0; t < r->trigger_count; ++t) {
+ if (r->reserved_triggers[t]) {
+ command_print_sameline(CMD, "%s%" PRIu64, separator, t);
+ separator = " ";
+ }
+ }
+ command_print_sameline(CMD, "\n");
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_reserve_trigger)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (CMD_ARGC == 0)
+ return CALL_COMMAND_HANDLER(report_reserved_triggers, target);
+
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ riscv_reg_t t;
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], t);
+
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+ RISCV_INFO(r);
+ if (r->trigger_count == 0) {
+ command_print(CMD, "Error: There are no triggers on the target.");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ if (t >= r->trigger_count) {
+ command_print(CMD, "Error: trigger with index %" PRIu64
+ " does not exist. There are only %u triggers"
+ " on the target (with indexes 0 .. %u).",
+ t, r->trigger_count, r->trigger_count - 1);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ if (r->trigger_unique_id[t] != -1) {
+ command_print(CMD, "Error: trigger with index %" PRIu64
+ " is already in use and can not be reserved.", t);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[1], r->reserved_triggers[t]);
+ return ERROR_OK;
+}
+
static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "dump_sample_buf",
@@ -5195,18 +5233,14 @@ static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "use_bscan_tunnel",
.handler = riscv_use_bscan_tunnel,
- .mode = COMMAND_ANY,
+ .mode = COMMAND_CONFIG,
.usage = "value [type]",
- .help = "Enable or disable use of a BSCAN tunnel to reach DM. Supply "
- "the width of the DM transport TAP's instruction register to "
- "enable. Supply a value of 0 to disable. Pass A second argument "
- "(optional) to indicate Bscan Tunnel Type {0:(default) NESTED_TAP , "
- "1: DATA_REGISTER}"
+ .help = "Enable or disable use of a BSCAN tunnel to reach DM."
},
{
.name = "set_bscan_tunnel_ir",
.handler = riscv_set_bscan_tunnel_ir,
- .mode = COMMAND_ANY,
+ .mode = COMMAND_CONFIG,
.usage = "value",
.help = "Specify the JTAG TAP IR used to access the bscan tunnel. "
"By default it is 0x23 << (ir_length - 6), which map some "
@@ -5287,6 +5321,14 @@ static const struct command_registration riscv_exec_command_handlers[] = {
.usage = "[('eq'|'napot'|'ge_lt'|'all') ('wp'|'none')]",
.help = "Control whether OpenOCD is allowed to use certain RISC-V trigger features for watchpoints."
},
+ {
+ .name = "reserve_trigger",
+ .handler = handle_reserve_trigger,
+ /* TODO: Move this to COMMAND_ANY */
+ .mode = COMMAND_EXEC,
+ .usage = "[index ('on'|'off')]",
+ .help = "Controls which RISC-V triggers shall not be touched by OpenOCD.",
+ },
COMMAND_REGISTRATION_DONE
};
@@ -5565,7 +5607,7 @@ static enum riscv_halt_reason riscv_halt_reason(struct target *target)
size_t riscv_progbuf_size(struct target *target)
{
RISCV_INFO(r);
- return r->progbuf_size;
+ return r->get_progbufsize(target);
}
int riscv_write_progbuf(struct target *target, int index, riscv_insn_t insn)
@@ -5587,16 +5629,16 @@ int riscv_execute_progbuf(struct target *target, uint32_t *cmderr)
return r->execute_progbuf(target, cmderr);
}
-void riscv_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d)
+void riscv_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d)
{
RISCV_INFO(r);
- r->fill_dm_write(target, buf, a, d);
+ r->fill_dmi_write(target, buf, a, d);
}
-void riscv_fill_dm_read(struct target *target, char *buf, uint64_t a)
+void riscv_fill_dmi_read(struct target *target, char *buf, uint64_t a)
{
RISCV_INFO(r);
- r->fill_dm_read(target, buf, a);
+ r->fill_dmi_read(target, buf, a);
}
void riscv_fill_dm_nop(struct target *target, char *buf)
@@ -5711,6 +5753,8 @@ int riscv_enumerate_triggers(struct target *target)
"Assuming that triggers are not implemented.");
r->triggers_enumerated = true;
r->trigger_count = 0;
+ free(r->reserved_triggers);
+ r->reserved_triggers = NULL;
return ERROR_OK;
}
@@ -5745,6 +5789,8 @@ int riscv_enumerate_triggers(struct target *target)
r->triggers_enumerated = true;
r->trigger_count = t;
LOG_TARGET_INFO(target, "Found %d triggers", r->trigger_count);
+ free(r->reserved_triggers);
+ r->reserved_triggers = calloc(t, sizeof(*r->reserved_triggers));
create_wp_trigger_cache(target);
return ERROR_OK;
}
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 5b75bf6..635e672 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef RISCV_H
-#define RISCV_H
+#ifndef OPENOCD_TARGET_RISCV_RISCV_H
+#define OPENOCD_TARGET_RISCV_RISCV_H
struct riscv_program;
@@ -167,12 +167,6 @@ struct riscv_info {
* most recent halt was not caused by a trigger, then this is -1. */
int64_t trigger_hit;
- /* The number of entries in the program buffer. */
- int progbuf_size;
-
- /* This hart contains an implicit ebreak at the end of the program buffer. */
- bool impebreak;
-
bool triggers_enumerated;
/* Decremented every scan, and when it reaches 0 we clear the learned
@@ -226,8 +220,8 @@ struct riscv_info {
int (*execute_progbuf)(struct target *target, uint32_t *cmderr);
int (*invalidate_cached_progbuf)(struct target *target);
int (*get_dmi_scan_length)(struct target *target);
- void (*fill_dm_write)(struct target *target, char *buf, uint64_t a, uint32_t d);
- void (*fill_dm_read)(struct target *target, char *buf, uint64_t a);
+ void (*fill_dmi_write)(struct target *target, char *buf, uint64_t a, uint32_t d);
+ void (*fill_dmi_read)(struct target *target, char *buf, uint64_t a);
void (*fill_dm_nop)(struct target *target, char *buf);
int (*authdata_read)(struct target *target, uint32_t *value, unsigned int index);
@@ -236,6 +230,9 @@ struct riscv_info {
int (*dmi_read)(struct target *target, uint32_t *value, uint32_t address);
int (*dmi_write)(struct target *target, uint32_t address, uint32_t value);
+ bool (*get_impebreak)(const struct target *target);
+ unsigned int (*get_progbufsize)(const struct target *target);
+
/* Get the DMI address of target's DM's register.
* The function should return the passed address
* if the target is not assigned a DM yet.
@@ -272,9 +269,7 @@ struct riscv_info {
struct reg_data_type_union vector_union;
struct reg_data_type type_vector;
- /* Set when trigger registers are changed by the user. This indicates we need
- * to beware that we may hit a trigger that we didn't realize had been set. */
- bool manual_hwbp_set;
+ bool *reserved_triggers;
/* Memory access methods to use, ordered by priority, highest to lowest. */
int mem_access_methods[RISCV_NUM_MEM_ACCESS_METHODS];
@@ -362,12 +357,13 @@ extern struct scan_field select_dtmcontrol;
extern struct scan_field select_dbus;
extern struct scan_field select_idcode;
+int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr);
+
extern struct scan_field *bscan_tunneled_select_dmi;
extern uint32_t bscan_tunneled_select_dmi_num_fields;
typedef enum { BSCAN_TUNNEL_NESTED_TAP, BSCAN_TUNNEL_DATA_REGISTER } bscan_tunnel_type_t;
-extern int bscan_tunnel_ir_width;
+extern uint8_t bscan_tunnel_ir_width;
-int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_ptr);
void select_dmi_via_bscan(struct target *target);
/*** OpenOCD Interface */
@@ -408,8 +404,8 @@ int riscv_write_progbuf(struct target *target, int index, riscv_insn_t insn);
int riscv_execute_progbuf(struct target *target, uint32_t *cmderr);
void riscv_fill_dm_nop(struct target *target, char *buf);
-void riscv_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d);
-void riscv_fill_dm_read(struct target *target, char *buf, uint64_t a);
+void riscv_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d);
+void riscv_fill_dmi_read(struct target *target, char *buf, uint64_t a);
int riscv_get_dmi_scan_length(struct target *target);
uint32_t riscv_get_dmi_address(const struct target *target, uint32_t dm_address);
@@ -433,4 +429,4 @@ int riscv_write_by_any_size(struct target *target, target_addr_t address, uint32
int riscv_interrupts_disable(struct target *target, uint64_t ie_mask, uint64_t *old_mstatus);
int riscv_interrupts_restore(struct target *target, uint64_t old_mstatus);
-#endif
+#endif /* OPENOCD_TARGET_RISCV_RISCV_H */
diff --git a/src/target/riscv/riscv_reg.c b/src/target/riscv/riscv_reg.c
index 6cf67dd..4f386f4 100644
--- a/src/target/riscv/riscv_reg.c
+++ b/src/target/riscv/riscv_reg.c
@@ -376,8 +376,19 @@ static bool is_known_standard_csr(unsigned int csr_num)
return is_csr_in_buf[csr_num];
}
-static bool gdb_regno_exist(const struct target *target, uint32_t regno)
-{
+bool riscv_reg_impl_gdb_regno_exist(const struct target *target, uint32_t regno)
+{
+ switch (regno) {
+ case GDB_REGNO_VLENB:
+ case GDB_REGNO_MTOPI:
+ case GDB_REGNO_MTOPEI:
+ assert(false
+ && "Existence of other registers is determined "
+ "depending on existence of these ones, so "
+ "whether these register exist or not should be "
+ "set explicitly.");
+ };
+
if (regno <= GDB_REGNO_XPR15 ||
regno == GDB_REGNO_PC ||
regno == GDB_REGNO_PRIV)
@@ -403,7 +414,6 @@ static bool gdb_regno_exist(const struct target *target, uint32_t regno)
case CSR_VL:
case CSR_VCSR:
case CSR_VTYPE:
- case CSR_VLENB:
return vlenb_exists(target);
case CSR_SCOUNTEREN:
case CSR_SSTATUS:
@@ -599,14 +609,15 @@ static int resize_reg(const struct target *target, uint32_t regno, bool exist,
return ERROR_OK;
}
-static int set_reg_exist(const struct target *target, uint32_t regno, bool exist)
+int riscv_reg_impl_set_exist(const struct target *target, uint32_t regno, bool exist)
{
const struct reg *reg = riscv_reg_impl_cache_entry(target, regno);
assert(riscv_reg_impl_is_initialized(reg));
return resize_reg(target, regno, exist, reg->size);
}
-int riscv_reg_impl_init_one(struct target *target, uint32_t regno, const struct reg_arch_type *reg_type)
+int riscv_reg_impl_init_cache_entry(struct target *target, uint32_t regno,
+ bool exist, const struct reg_arch_type *reg_type)
{
struct reg * const reg = riscv_reg_impl_cache_entry(target, regno);
if (riscv_reg_impl_is_initialized(reg))
@@ -634,8 +645,7 @@ int riscv_reg_impl_init_one(struct target *target, uint32_t regno, const struct
reg_arch_info->target = target;
reg_arch_info->custom_number = gdb_regno_custom_number(target, regno);
}
- return resize_reg(target, regno, gdb_regno_exist(target, regno),
- gdb_regno_size(target, regno));
+ return resize_reg(target, regno, exist, gdb_regno_size(target, regno));
}
static int init_custom_register_names(struct list_head *expose_custom,
@@ -725,7 +735,7 @@ int riscv_reg_impl_expose_csrs(const struct target *target)
csr_number);
continue;
}
- if (set_reg_exist(target, regno, /*exist*/ true) != ERROR_OK)
+ if (riscv_reg_impl_set_exist(target, regno, /*exist*/ true) != ERROR_OK)
return ERROR_FAIL;
LOG_TARGET_DEBUG(target, "Exposing additional CSR %d (name=%s)",
csr_number, reg->name);
@@ -746,7 +756,7 @@ void riscv_reg_impl_hide_csrs(const struct target *target)
struct reg * const reg = riscv_reg_impl_cache_entry(target, regno);
const unsigned int csr_number = regno - GDB_REGNO_CSR0;
if (!reg->exist) {
- LOG_TARGET_WARNING(target,
+ LOG_TARGET_DEBUG(target,
"Not hiding CSR %d: register does not exist.",
csr_number);
continue;
@@ -834,15 +844,8 @@ static int riscv_set_or_write_register(struct target *target,
return riscv_set_or_write_register(target, GDB_REGNO_DCSR, dcsr, write_through);
}
- if (!target->reg_cache) {
- assert(!target_was_examined(target));
- LOG_TARGET_DEBUG(target,
- "No cache, writing to target: %s <- 0x%" PRIx64,
- riscv_reg_gdb_regno_name(target, regid), value);
- return riscv013_set_register(target, regid, value);
- }
-
struct reg *reg = riscv_reg_impl_cache_entry(target, regid);
+ assert(riscv_reg_impl_is_initialized(reg));
if (!reg->exist) {
LOG_TARGET_DEBUG(target, "Register %s does not exist.", reg->name);
@@ -935,21 +938,15 @@ int riscv_reg_get(struct target *target, riscv_reg_t *value,
RISCV_INFO(r);
assert(r);
if (r->dtm_version == DTM_DTMCS_VERSION_0_11)
- return riscv013_get_register(target, value, regid);
+ return riscv011_get_register(target, value, regid);
keep_alive();
if (regid == GDB_REGNO_PC)
return riscv_reg_get(target, value, GDB_REGNO_DPC);
- if (!target->reg_cache) {
- assert(!target_was_examined(target));
- LOG_TARGET_DEBUG(target, "No cache, reading %s from target",
- riscv_reg_gdb_regno_name(target, regid));
- return riscv013_get_register(target, value, regid);
- }
-
struct reg *reg = riscv_reg_impl_cache_entry(target, regid);
+ assert(riscv_reg_impl_is_initialized(reg));
if (!reg->exist) {
LOG_TARGET_DEBUG(target, "Register %s does not exist.", reg->name);
return ERROR_FAIL;
diff --git a/src/target/riscv/riscv_reg_impl.h b/src/target/riscv/riscv_reg_impl.h
index 906a5b6..7a483ad 100644
--- a/src/target/riscv/riscv_reg_impl.h
+++ b/src/target/riscv/riscv_reg_impl.h
@@ -13,7 +13,7 @@
* This file describes the helpers to use during register cache initialization
* of a RISC-V target. Each cache entry proceedes through the following stages:
* - not allocated before `riscv_reg_impl_init_cache()`
- * - not initialized before the call to `riscv_reg_impl_init_one()` with appropriate regno.
+ * - not initialized before the call to `riscv_reg_impl_init_cache_entry()` with appropriate regno.
* - initialized until `riscv_reg_free_all()` is called.
*/
static inline bool riscv_reg_impl_is_initialized(const struct reg *reg)
@@ -37,8 +37,18 @@ static inline bool riscv_reg_impl_is_initialized(const struct reg *reg)
int riscv_reg_impl_init_cache(struct target *target);
/** Initialize register. */
-int riscv_reg_impl_init_one(struct target *target, uint32_t regno,
- const struct reg_arch_type *reg_type);
+int riscv_reg_impl_init_cache_entry(struct target *target, uint32_t regno,
+ bool exist, const struct reg_arch_type *reg_type);
+
+/**
+ * For most registers, returns whether they exist or not.
+ * For some registers the "exist" bit should be set explicitly.
+ */
+bool riscv_reg_impl_gdb_regno_exist(const struct target *target, uint32_t regno);
+
+/** Mark register as existing or not. */
+int riscv_reg_impl_set_exist(const struct target *target,
+ uint32_t regno, bool exist);
/** Return the entry in the register cache of the target. */
struct reg *riscv_reg_impl_cache_entry(const struct target *target,
diff --git a/src/target/target.c b/src/target/target.c
index fd9c34f..b51f066 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -3125,11 +3125,18 @@ COMMAND_HANDLER(handle_reg_command)
/* set register value */
if (CMD_ARGC == 2) {
uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));
- if (!buf)
+ if (!buf) {
+ LOG_ERROR("Failed to allocate memory");
return ERROR_FAIL;
- str_to_buf(CMD_ARGV[1], strlen(CMD_ARGV[1]), buf, reg->size, 0);
+ }
+
+ int retval = CALL_COMMAND_HANDLER(command_parse_str_to_buf, CMD_ARGV[1], buf, reg->size, 0);
+ if (retval != ERROR_OK) {
+ free(buf);
+ return retval;
+ }
- int retval = reg->type->set(reg, buf);
+ retval = reg->type->set(reg, buf);
if (retval != ERROR_OK) {
LOG_ERROR("Could not write to register '%s'", reg->name);
} else {
@@ -3898,7 +3905,7 @@ static int handle_bp_command_list(struct command_invocation *cmd)
while (breakpoint) {
if (breakpoint->type == BKPT_SOFT) {
char *buf = buf_to_hex_str(breakpoint->orig_instr,
- breakpoint->length);
+ breakpoint->length * 8);
command_print(cmd, "Software breakpoint(IVA): addr=" TARGET_ADDR_FMT ", len=0x%x, orig_instr=0x%s",
breakpoint->address,
breakpoint->length,
@@ -4772,63 +4779,64 @@ static int target_jim_get_reg(Jim_Interp *interp, int argc,
return JIM_OK;
}
-static int target_jim_set_reg(Jim_Interp *interp, int argc,
- Jim_Obj * const *argv)
+COMMAND_HANDLER(handle_set_reg_command)
{
- if (argc != 2) {
- Jim_WrongNumArgs(interp, 1, argv, "dict");
- return JIM_ERR;
- }
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
int tmp;
#if JIM_VERSION >= 80
- Jim_Obj **dict = Jim_DictPairs(interp, argv[1], &tmp);
+ Jim_Obj **dict = Jim_DictPairs(CMD_CTX->interp, CMD_JIMTCL_ARGV[0], &tmp);
if (!dict)
- return JIM_ERR;
+ return ERROR_FAIL;
#else
Jim_Obj **dict;
- int ret = Jim_DictPairs(interp, argv[1], &dict, &tmp);
+ int ret = Jim_DictPairs(CMD_CTX->interp, CMD_JIMTCL_ARGV[0], &dict, &tmp);
if (ret != JIM_OK)
- return ret;
+ return ERROR_FAIL;
#endif
const unsigned int length = tmp;
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx);
- const struct target *target = get_current_target(cmd_ctx);
+
+ const struct target *target = get_current_target(CMD_CTX);
+ assert(target);
for (unsigned int i = 0; i < length; i += 2) {
const char *reg_name = Jim_String(dict[i]);
const char *reg_value = Jim_String(dict[i + 1]);
- struct reg *reg = register_get_by_name(target->reg_cache, reg_name,
- false);
+ struct reg *reg = register_get_by_name(target->reg_cache, reg_name, false);
if (!reg || !reg->exist) {
- Jim_SetResultFormatted(interp, "unknown register '%s'", reg_name);
- return JIM_ERR;
+ command_print(CMD, "unknown register '%s'", reg_name);
+ return ERROR_FAIL;
}
uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));
-
if (!buf) {
LOG_ERROR("Failed to allocate memory");
- return JIM_ERR;
+ return ERROR_FAIL;
}
- str_to_buf(reg_value, strlen(reg_value), buf, reg->size, 0);
- int retval = reg->type->set(reg, buf);
+ int retval = CALL_COMMAND_HANDLER(command_parse_str_to_buf,
+ reg_value, buf, reg->size, 0);
+ if (retval != ERROR_OK) {
+ free(buf);
+ return retval;
+ }
+
+ retval = reg->type->set(reg, buf);
free(buf);
if (retval != ERROR_OK) {
- Jim_SetResultFormatted(interp, "failed to set '%s' to register '%s'",
+ command_print(CMD, "failed to set '%s' to register '%s'",
reg_value, reg_name);
- return JIM_ERR;
+ return retval;
}
}
- return JIM_OK;
+ return ERROR_OK;
}
/**
@@ -5568,7 +5576,7 @@ static const struct command_registration target_instance_command_handlers[] = {
{
.name = "set_reg",
.mode = COMMAND_EXEC,
- .jim_handler = target_jim_set_reg,
+ .handler = handle_set_reg_command,
.help = "Set target register values",
.usage = "dict",
},
@@ -5789,7 +5797,7 @@ static int target_create(struct jim_getopt_info *goi)
}
target->dbgmsg = NULL;
- target->dbg_msg_enabled = 0;
+ target->dbg_msg_enabled = false;
target->endianness = TARGET_ENDIAN_UNKNOWN;
@@ -6703,7 +6711,7 @@ static const struct command_registration target_exec_command_handlers[] = {
{
.name = "set_reg",
.mode = COMMAND_EXEC,
- .jim_handler = target_jim_set_reg,
+ .handler = handle_set_reg_command,
.help = "Set target register values",
.usage = "dict",
},
diff --git a/src/target/target.h b/src/target/target.h
index c74b8c2..9ff2f78 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -163,7 +163,7 @@ struct target {
struct watchpoint *watchpoints; /* list of watchpoints */
struct trace *trace_info; /* generic trace information */
struct debug_msg_receiver *dbgmsg; /* list of debug message receivers */
- uint32_t dbg_msg_enabled; /* debug message status */
+ bool dbg_msg_enabled; /* debug message status */
void *arch_info; /* architecture specific information */
void *private_config; /* pointer to target specific config data (for jim_configure hook) */
struct target *next; /* next target in list */
@@ -805,6 +805,7 @@ int target_profiling_default(struct target *target, uint32_t *samples, uint32_t
#define ERROR_TARGET_ALGO_EXIT (-313)
#define ERROR_TARGET_SIZE_NOT_SUPPORTED (-314)
#define ERROR_TARGET_PACKING_NOT_SUPPORTED (-315)
+#define ERROR_TARGET_HALTED_DO_RESUME (-316) /* used to workaround incorrect debug halt */
extern bool get_target_reset_nag(void);
diff --git a/src/target/target_request.c b/src/target/target_request.c
index 72c8421..bccae07 100644
--- a/src/target/target_request.c
+++ b/src/target/target_request.c
@@ -164,7 +164,7 @@ static int add_debug_msg_receiver(struct command_context *cmd_ctx, struct target
(*p)->next = NULL;
/* enable callback */
- target->dbg_msg_enabled = 1;
+ target->dbg_msg_enabled = true;
return ERROR_OK;
}
@@ -225,7 +225,7 @@ int delete_debug_msg_receiver(struct command_context *cmd_ctx, struct target *ta
free(c);
if (!*p) {
/* disable callback */
- target->dbg_msg_enabled = 0;
+ target->dbg_msg_enabled = false;
}
return ERROR_OK;
} else
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index 702b8fc..8369cc4 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -540,7 +540,7 @@ static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint
for (int32_t i = oplenw - 1; i > 0; i--)
xtensa_queue_dbg_reg_write(xtensa,
XDMREG_DIR0 + i,
- target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t)*i]));
+ target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t) * i]));
/* Write DIR0EXEC last */
xtensa_queue_dbg_reg_write(xtensa,
XDMREG_DIR0EXEC,
@@ -3966,10 +3966,10 @@ COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
rptr->type = XT_REG_OTHER;
}
- /* Register flags */
+ /* Register flags: includes intsetN, intclearN for LX8 */
if ((strcmp(rptr->name, "mmid") == 0) || (strcmp(rptr->name, "eraccess") == 0) ||
- (strcmp(rptr->name, "ddr") == 0) || (strcmp(rptr->name, "intset") == 0) ||
- (strcmp(rptr->name, "intclear") == 0))
+ (strcmp(rptr->name, "ddr") == 0) || (strncmp(rptr->name, "intset", 6) == 0) ||
+ (strncmp(rptr->name, "intclear", 8) == 0) || (strcmp(rptr->name, "mesrclr") == 0))
rptr->flags = XT_REGF_NOREAD;
else
rptr->flags = 0;
diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c
index ac4a49c..ce6d35c 100644
--- a/src/target/xtensa/xtensa_chip.c
+++ b/src/target/xtensa/xtensa_chip.c
@@ -103,7 +103,7 @@ static int xtensa_chip_target_create(struct target *target, Jim_Interp *interp)
LOG_DEBUG("DAP: ap_num %" PRId64 " DAP %p\n", pc->ap_num, pc->dap);
} else {
xtensa_chip_dm_cfg.tap = target->tap;
- LOG_DEBUG("JTAG: %s:%s pos %d", target->tap->chip, target->tap->tapname,
+ LOG_DEBUG("JTAG: %s:%s pos %u", target->tap->chip, target->tap->tapname,
target->tap->abs_chain_position);
}
diff --git a/src/transport/transport.c b/src/transport/transport.c
index 81d3d58..bf306e7 100644
--- a/src/transport/transport.c
+++ b/src/transport/transport.c
@@ -278,7 +278,6 @@ COMMAND_HANDLER(handle_transport_select)
if (session) {
if (!strcmp(session->name, CMD_ARGV[0])) {
LOG_WARNING("Transport \"%s\" was already selected", session->name);
- command_print(CMD, "%s", session->name);
return ERROR_OK;
}
command_print(CMD, "Can't change session's transport after the initial selection was made");
@@ -301,7 +300,6 @@ COMMAND_HANDLER(handle_transport_select)
int retval = transport_select(CMD_CTX, CMD_ARGV[0]);
if (retval != ERROR_OK)
return retval;
- command_print(CMD, "%s", session->name);
return ERROR_OK;
}
}