From 7901cf2124fbaffa85d589b67c580d6ad2e9beb6 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 23 Apr 2020 18:58:58 +0800 Subject: [PATCH 01/82] flash/nor/stm32lx: fixed writes at high adapter speeds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The busy flag must be polled after each half-page write. At low clock speeds, no issue is observed when the poll is omitted, because the writes complete before the next write begins. But at high clock speeds the subsequent writes would overlap and cause the operation to fail. The status polls are done on the target for efficiency, since the half-pages are very small. Change-Id: Ia1e9b4a6a71930549b3d84a902744ce6e596301b Signed-off-by: Jimmy Reviewed-on: https://review.openocd.org/c/openocd/+/5598 Tested-by: jenkins Reviewed-by: Jelle De Vleeschouwer Reviewed-by: Tomas Vanek Reviewed-by: Andrzej Sierżęga --- contrib/loaders/flash/stm32/stm32lx.S | 53 ++++++++++++++++--------- contrib/loaders/flash/stm32/stm32lx.inc | 3 +- src/flash/nor/stm32lx.c | 25 ++++++++++-- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/contrib/loaders/flash/stm32/stm32lx.S b/contrib/loaders/flash/stm32/stm32lx.S index bcae7a46c..7cfe48545 100644 --- a/contrib/loaders/flash/stm32/stm32lx.S +++ b/contrib/loaders/flash/stm32/stm32lx.S @@ -20,44 +20,61 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ - .text .syntax unified .cpu cortex-m0 .thumb /* +Parameters r0 - destination address r1 - source address - r2 - count + r2 - half pages + r3 - bytes per half page + r4 - flash base +Variables + r0 - destination write pointer + r1 - source read pointer + r2 - source limit address + r3 - bytes per half page + r4 - flash base + r5 - pages left in current half page + r6 - temporary r/w */ +/* offsets of registers from flash reg base */ +#define STM32_FLASH_SR_OFFSET 0x18 + .thumb_func .global _start _start: - // r2 = source + count * 4 - lsls r2, r2, #2 - adds r2, r1, r2 + // r2 = source + half pages * bytes per half page + muls r2, r2, r3 + add r2, r1, r2 // Go to compare - b test_done + b test_done +write_half_page: + // initialize pages left in current half page + mov r5, r3 write_word: // load word from address in r1 and increase r1 by 4 - ldmia r1!, {r3} + ldmia r1!, {r6} // store word to address in r0 and increase r0 by 4 - stmia r0!, {r3} + stmia r0!, {r6} + // check for end of half page + subs r5, r5, #4 + bne write_word +wait_busy: + // read status register into r6, loop while bottom bit is set + ldr r6, [r4, #STM32_FLASH_SR_OFFSET] + lsls r6, r6, #31 + bne wait_busy test_done: - // compare r1 and r2 + // compare r1 and r2, loop if not equal cmp r1, r2 - // loop if not equal - bne write_word + bne write_half_page // Set breakpoint to exit - bkpt #0x00 - + bkpt #0x00 diff --git a/contrib/loaders/flash/stm32/stm32lx.inc b/contrib/loaders/flash/stm32/stm32lx.inc index eaaf1848a..668de2778 100644 --- a/contrib/loaders/flash/stm32/stm32lx.inc +++ b/contrib/loaders/flash/stm32/stm32lx.inc @@ -1,2 +1,3 @@ /* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x92,0x00,0x8a,0x18,0x01,0xe0,0x08,0xc9,0x08,0xc0,0x91,0x42,0xfb,0xd1,0x00,0xbe, +0x5a,0x43,0x0a,0x44,0x07,0xe0,0x1d,0x46,0x40,0xc9,0x40,0xc0,0x04,0x3d,0xfb,0xd1, +0xa6,0x69,0xf6,0x07,0xfc,0xd1,0x91,0x42,0xf5,0xd1,0x00,0xbe, diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index 488dc978a..122119606 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -425,12 +425,12 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; uint32_t hp_nb = stm32lx_info->part_info.page_size / 2; - uint32_t buffer_size = 16384; + uint32_t buffer_size = (16384 / hp_nb) * hp_nb; /* must be multiple of hp_nb */ struct working_area *write_algorithm; struct working_area *source; uint32_t address = bank->base + offset; - struct reg_param reg_params[3]; + struct reg_param reg_params[5]; struct armv7m_algorithm armv7m_info; int retval = ERROR_OK; @@ -440,6 +440,10 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff }; /* Make sure we're performing a half-page aligned write. */ + if (offset % hp_nb) { + LOG_ERROR("The offset must be %" PRIu32 "B-aligned but it is %" PRIi32 "B)", hp_nb, offset); + return ERROR_FAIL; + } if (count % hp_nb) { LOG_ERROR("The byte count must be %" PRIu32 "B-aligned but count is %" PRIu32 "B)", hp_nb, count); return ERROR_FAIL; @@ -476,6 +480,9 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff LOG_WARNING("no large enough working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } else { + /* Make sure we're still asking for an integral number of half-pages */ + buffer_size -= buffer_size % hp_nb; } } @@ -484,6 +491,8 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff init_reg_param(®_params[0], "r0", 32, PARAM_OUT); init_reg_param(®_params[1], "r1", 32, PARAM_OUT); init_reg_param(®_params[2], "r2", 32, PARAM_OUT); + init_reg_param(®_params[3], "r3", 32, PARAM_OUT); + init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* Enable half-page write */ retval = stm32lx_enable_write_half_page(bank); @@ -494,6 +503,8 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); destroy_reg_param(®_params[2]); + destroy_reg_param(®_params[3]); + destroy_reg_param(®_params[4]); return retval; } @@ -524,8 +535,12 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff buf_set_u32(reg_params[0].value, 0, 32, address); /* The source address of the copy (R1) */ buf_set_u32(reg_params[1].value, 0, 32, source->address); - /* The length of the copy (R2) */ - buf_set_u32(reg_params[2].value, 0, 32, this_count / 4); + /* The number of half pages to copy (R2) */ + buf_set_u32(reg_params[2].value, 0, 32, this_count / hp_nb); + /* The size in byes of a half page (R3) */ + buf_set_u32(reg_params[3].value, 0, 32, hp_nb); + /* The flash base address (R4) */ + buf_set_u32(reg_params[4].value, 0, 32, stm32lx_info->flash_base); /* 5: Execute the bunch of code */ retval = target_run_algorithm(target, 0, NULL, @@ -593,6 +608,8 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); destroy_reg_param(®_params[2]); + destroy_reg_param(®_params[3]); + destroy_reg_param(®_params[4]); return retval; } From fd0b4dd15ff7217f3c70818c7fd2f0a5b88de89a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 25 Jul 2021 17:51:49 +0200 Subject: [PATCH 02/82] stlink: check buffer size on 16 and 32 bit memory transfer Both HLA and ADIv5 layers limit the memory transfer within blocks whose boundaries are aligned at 1024 or 4096 bytes. New stlink firmware handle the ADIv5 TAR autoincrement, making possible to send memory transfers across the boundary of 1024 or 4096 byte. OpenOCD doesn't use this feature yet. Use the correct buffer size in the code, even if it is not used. While there, split SWIM buffer size from JTAG/SWD case; stlink has a dedicated command to retrieve SWIM buffer size, but currently not implemented in OpenOCD. Change-Id: Id46c0356ef21cead08726c044a1cd9725fd4f923 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6600 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 43 ++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index a52370863..e83e84b95 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -79,7 +79,7 @@ #define STLINK_V2_1_TRACE_EP (2|ENDPOINT_IN) #define STLINK_SG_SIZE (31) -#define STLINK_DATA_SIZE (4096) +#define STLINK_DATA_SIZE (6144) #define STLINK_CMD_SIZE_V2 (16) #define STLINK_CMD_SIZE_V1 (10) @@ -97,9 +97,16 @@ * ST-Link/V1, ST-Link/V2 and ST-Link/V2.1 are full-speed USB devices and * this limits the bulk packet size and the 8bit read/writes to max 64 bytes. * STLINK-V3 is a high speed USB 2.0 and the limit is 512 bytes from FW V3J6. + * + * For 16 and 32bit read/writes stlink handles USB packet split and the limit + * is the internal buffer size of 6144 bytes. + * TODO: override ADIv5 layer's tar_autoincr_block that limits the transfer + * to 1024 or 4096 bytes */ -#define STLINK_MAX_RW8 (64) -#define STLINKV3_MAX_RW8 (512) +#define STLINK_MAX_RW8 (64) +#define STLINKV3_MAX_RW8 (512) +#define STLINK_MAX_RW16_32 STLINK_DATA_SIZE +#define STLINK_SWIM_DATA_SIZE STLINK_DATA_SIZE /* "WAIT" responses will be retried (with exponential backoff) at * most this many times before failing to caller. @@ -1807,7 +1814,7 @@ static int stlink_swim_writebytes(void *handle, uint32_t addr, uint32_t len, con unsigned int datalen = 0; int cmdsize = STLINK_CMD_SIZE_V2; - if (len > STLINK_DATA_SIZE) + if (len > STLINK_SWIM_DATA_SIZE) return ERROR_FAIL; if (h->version.stlink == 1) @@ -1840,7 +1847,7 @@ static int stlink_swim_readbytes(void *handle, uint32_t addr, uint32_t len, uint struct stlink_usb_handle_s *h = handle; int res; - if (len > STLINK_DATA_SIZE) + if (len > STLINK_SWIM_DATA_SIZE) return ERROR_FAIL; stlink_usb_init_buffer(handle, h->rx_ep, 0); @@ -2411,6 +2418,11 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, if (!(h->version.flags & STLINK_F_HAS_MEM_16BIT)) return ERROR_COMMAND_NOTFOUND; + if (len > STLINK_MAX_RW16_32) { + LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); + return ERROR_FAIL; + } + /* data must be a multiple of 2 and half-word aligned */ if (len % 2 || addr % 2) { LOG_DEBUG("Invalid data alignment"); @@ -2448,6 +2460,11 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, if (!(h->version.flags & STLINK_F_HAS_MEM_16BIT)) return ERROR_COMMAND_NOTFOUND; + if (len > STLINK_MAX_RW16_32) { + LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); + return ERROR_FAIL; + } + /* data must be a multiple of 2 and half-word aligned */ if (len % 2 || addr % 2) { LOG_DEBUG("Invalid data alignment"); @@ -2480,6 +2497,11 @@ static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, assert(handle); + if (len > STLINK_MAX_RW16_32) { + LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); + return ERROR_FAIL; + } + /* data must be a multiple of 4 and word aligned */ if (len % 4 || addr % 4) { LOG_DEBUG("Invalid data alignment"); @@ -2514,6 +2536,11 @@ static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, assert(handle); + if (len > STLINK_MAX_RW16_32) { + LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); + return ERROR_FAIL; + } + /* data must be a multiple of 4 and word aligned */ if (len % 4 || addr % 4) { LOG_DEBUG("Invalid data alignment"); @@ -3482,7 +3509,7 @@ static int stlink_open(struct hl_interface_param_s *param, enum stlink_mode mode goto error_open; } *fd = h; - h->max_mem_packet = STLINK_DATA_SIZE; + h->max_mem_packet = STLINK_SWIM_DATA_SIZE; return ERROR_OK; } @@ -4090,7 +4117,7 @@ static int stlink_swim_op_read_mem(uint32_t addr, uint32_t size, count *= size; while (count) { - bytes_remaining = (count > STLINK_DATA_SIZE) ? STLINK_DATA_SIZE : count; + bytes_remaining = (count > STLINK_SWIM_DATA_SIZE) ? STLINK_SWIM_DATA_SIZE : count; retval = stlink_swim_readbytes(stlink_dap_handle, addr, bytes_remaining, buffer); if (retval != ERROR_OK) return retval; @@ -4113,7 +4140,7 @@ static int stlink_swim_op_write_mem(uint32_t addr, uint32_t size, count *= size; while (count) { - bytes_remaining = (count > STLINK_DATA_SIZE) ? STLINK_DATA_SIZE : count; + bytes_remaining = (count > STLINK_SWIM_DATA_SIZE) ? STLINK_SWIM_DATA_SIZE : count; retval = stlink_swim_writebytes(stlink_dap_handle, addr, bytes_remaining, buffer); if (retval != ERROR_OK) return retval; From 76d109523199aa44bb36627ff46d91719566086a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 22 Jul 2021 15:08:36 +0200 Subject: [PATCH 03/82] stlink: add queue in dap-direct mode Implement a minimalist queue for DP/AP commands and reorganize the code to use it. There is no performance improvement; the queue elements are still sent one-by-one on USB or on TCP during dap_run(). Change-Id: I8353563e59f883624bcc0fbe8b54955e4f27ccfa Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6601 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 228 +++++++++++++++++++++++++++------- 1 file changed, 181 insertions(+), 47 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index e83e84b95..92eb06d3a 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -175,6 +175,43 @@ struct stlink_backend_s { int (*read_trace)(void *handle, const uint8_t *buf, int size); }; +/* TODO: make queue size dynamic */ +/* TODO: don't allocate queue for HLA */ +#define MAX_QUEUE_DEPTH (4096) + +enum queue_cmd { + CMD_DP_READ = 1, + CMD_DP_WRITE, + CMD_AP_READ, + CMD_AP_WRITE, +}; + +struct dap_queue { + enum queue_cmd cmd; + union { + struct dp_r { + unsigned int reg; + struct adiv5_dap *dap; + uint32_t *p_data; + } dp_r; + struct dp_w { + unsigned int reg; + struct adiv5_dap *dap; + uint32_t data; + } dp_w; + struct ap_r { + unsigned int reg; + struct adiv5_ap *ap; + uint32_t *p_data; + } ap_r; + struct ap_w { + unsigned int reg; + struct adiv5_ap *ap; + uint32_t data; + } ap_w; + }; +}; + /** */ struct stlink_usb_handle_s { /** */ @@ -218,6 +255,10 @@ struct stlink_usb_handle_s { /** reconnect is needed next time we try to query the * status */ bool reconnect_pending; + /** queue of dap_direct operations */ + struct dap_queue queue[MAX_QUEUE_DEPTH]; + /** first element available in the queue */ + unsigned int queue_index; }; /** */ @@ -3750,9 +3791,6 @@ static struct hl_interface_param_s stlink_dap_param; static DECLARE_BITMAP(opened_ap, DP_APSEL_MAX + 1); static int stlink_dap_error = ERROR_OK; -static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, - uint32_t *data); - /** */ static int stlink_dap_record_error(int error) { @@ -3769,6 +3807,11 @@ static int stlink_dap_get_and_clear_error(void) return retval; } +static int stlink_dap_get_error(void) +{ + return stlink_dap_error; +} + static int stlink_usb_open_ap(void *handle, unsigned short apsel) { struct stlink_usb_handle_s *h = handle; @@ -3914,8 +3957,7 @@ static int stlink_dap_op_send_sequence(struct adiv5_dap *dap, enum swd_special_s } /** */ -static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, - uint32_t *data) +static int stlink_dap_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data) { uint32_t dummy; int retval; @@ -3926,10 +3968,6 @@ static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, return ERROR_COMMAND_NOTFOUND; } - retval = stlink_dap_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - data = data ? data : &dummy; if (stlink_dap_handle->version.flags & STLINK_F_QUIRK_JTAG_DP_READ && stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) { @@ -3944,12 +3982,11 @@ static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, STLINK_DEBUG_PORT_ACCESS, reg, data); } - return stlink_dap_record_error(retval); + return retval; } /** */ -static int stlink_dap_op_queue_dp_write(struct adiv5_dap *dap, unsigned reg, - uint32_t data) +static int stlink_dap_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data) { int retval; @@ -3965,31 +4002,22 @@ static int stlink_dap_op_queue_dp_write(struct adiv5_dap *dap, unsigned reg, data &= ~DP_SELECT_DPBANK; } - retval = stlink_dap_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - /* ST-Link does not like that we set CORUNDETECT */ if (reg == DP_CTRL_STAT) data &= ~CORUNDETECT; retval = stlink_write_dap_register(stlink_dap_handle, STLINK_DEBUG_PORT_ACCESS, reg, data); - return stlink_dap_record_error(retval); + return retval; } /** */ -static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned reg, - uint32_t *data) +static int stlink_dap_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data) { struct adiv5_dap *dap = ap->dap; uint32_t dummy; int retval; - retval = stlink_dap_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - if (reg != AP_REG_IDR) { retval = stlink_dap_open_ap(ap->ap_num); if (retval != ERROR_OK) @@ -3999,20 +4027,15 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned reg, retval = stlink_read_dap_register(stlink_dap_handle, ap->ap_num, reg, data); dap->stlink_flush_ap_write = false; - return stlink_dap_record_error(retval); + return retval; } /** */ -static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned reg, - uint32_t data) +static int stlink_dap_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data) { struct adiv5_dap *dap = ap->dap; int retval; - retval = stlink_dap_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - retval = stlink_dap_open_ap(ap->ap_num); if (retval != ERROR_OK) return retval; @@ -4020,7 +4043,7 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned reg, retval = stlink_write_dap_register(stlink_dap_handle, ap->ap_num, reg, data); dap->stlink_flush_ap_write = true; - return stlink_dap_record_error(retval); + return retval; } /** */ @@ -4030,8 +4053,47 @@ static int stlink_dap_op_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) return ERROR_OK; } +static void stlink_dap_run_internal(struct adiv5_dap *dap) +{ + int retval = stlink_dap_check_reconnect(dap); + if (retval != ERROR_OK) { + stlink_dap_handle->queue_index = 0; + stlink_dap_record_error(retval); + return; + } + + unsigned int i = stlink_dap_handle->queue_index; + struct dap_queue *q = &stlink_dap_handle->queue[0]; + + while (i && stlink_dap_get_error() == ERROR_OK) { + switch (q->cmd) { + case CMD_DP_READ: + retval = stlink_dap_dp_read(q->dp_r.dap, q->dp_r.reg, q->dp_r.p_data); + break; + case CMD_DP_WRITE: + retval = stlink_dap_dp_write(q->dp_w.dap, q->dp_w.reg, q->dp_w.data); + break; + case CMD_AP_READ: + retval = stlink_dap_ap_read(q->ap_r.ap, q->ap_r.reg, q->ap_r.p_data); + break; + case CMD_AP_WRITE: + retval = stlink_dap_ap_write(q->ap_w.ap, q->ap_w.reg, q->ap_w.data); + break; + default: + LOG_ERROR("ST-Link: Unknown queue command %d", q->cmd); + retval = ERROR_FAIL; + break; + } + stlink_dap_record_error(retval); + q++; + i--; + } + + stlink_dap_handle->queue_index = 0; +} + /** */ -static int stlink_dap_op_run(struct adiv5_dap *dap) +static int stlink_dap_run_finalize(struct adiv5_dap *dap) { uint32_t ctrlstat, pwrmask; int retval, saved_retval; @@ -4046,7 +4108,7 @@ static int stlink_dap_op_run(struct adiv5_dap *dap) */ if (dap->stlink_flush_ap_write) { dap->stlink_flush_ap_write = false; - retval = stlink_dap_op_queue_dp_read(dap, DP_RDBUFF, NULL); + retval = stlink_dap_dp_read(dap, DP_RDBUFF, NULL); if (retval != ERROR_OK) { dap->do_reconnect = true; return retval; @@ -4055,12 +4117,7 @@ static int stlink_dap_op_run(struct adiv5_dap *dap) saved_retval = stlink_dap_get_and_clear_error(); - retval = stlink_dap_op_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat); - if (retval != ERROR_OK) { - dap->do_reconnect = true; - return retval; - } - retval = stlink_dap_get_and_clear_error(); + retval = stlink_dap_dp_read(dap, DP_CTRL_STAT, &ctrlstat); if (retval != ERROR_OK) { LOG_ERROR("Fail reading CTRL/STAT register. Force reconnect"); dap->do_reconnect = true; @@ -4069,15 +4126,10 @@ static int stlink_dap_op_run(struct adiv5_dap *dap) if (ctrlstat & SSTICKYERR) { if (stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) - retval = stlink_dap_op_queue_dp_write(dap, DP_CTRL_STAT, + retval = stlink_dap_dp_write(dap, DP_CTRL_STAT, ctrlstat & (dap->dp_ctrl_stat | SSTICKYERR)); else - retval = stlink_dap_op_queue_dp_write(dap, DP_ABORT, STKERRCLR); - if (retval != ERROR_OK) { - dap->do_reconnect = true; - return retval; - } - retval = stlink_dap_get_and_clear_error(); + retval = stlink_dap_dp_write(dap, DP_ABORT, STKERRCLR); if (retval != ERROR_OK) { dap->do_reconnect = true; return retval; @@ -4092,6 +4144,12 @@ static int stlink_dap_op_run(struct adiv5_dap *dap) return saved_retval; } +static int stlink_dap_op_queue_run(struct adiv5_dap *dap) +{ + stlink_dap_run_internal(dap); + return stlink_dap_run_finalize(dap); +} + /** */ static void stlink_dap_op_quit(struct adiv5_dap *dap) { @@ -4102,6 +4160,82 @@ static void stlink_dap_op_quit(struct adiv5_dap *dap) LOG_ERROR("Error closing APs"); } +static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, + uint32_t *data) +{ + if (stlink_dap_get_error() != ERROR_OK) + return ERROR_OK; + + unsigned int i = stlink_dap_handle->queue_index++; + struct dap_queue *q = &stlink_dap_handle->queue[i]; + q->cmd = CMD_DP_READ; + q->dp_r.reg = reg; + q->dp_r.dap = dap; + q->dp_r.p_data = data; + + if (i == MAX_QUEUE_DEPTH - 1) + stlink_dap_run_internal(dap); + + return ERROR_OK; +} + +static int stlink_dap_op_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, + uint32_t data) +{ + if (stlink_dap_get_error() != ERROR_OK) + return ERROR_OK; + + unsigned int i = stlink_dap_handle->queue_index++; + struct dap_queue *q = &stlink_dap_handle->queue[i]; + q->cmd = CMD_DP_WRITE; + q->dp_w.reg = reg; + q->dp_w.dap = dap; + q->dp_w.data = data; + + if (i == MAX_QUEUE_DEPTH - 1) + stlink_dap_run_internal(dap); + + return ERROR_OK; +} + +static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, + uint32_t *data) +{ + if (stlink_dap_get_error() != ERROR_OK) + return ERROR_OK; + + unsigned int i = stlink_dap_handle->queue_index++; + struct dap_queue *q = &stlink_dap_handle->queue[i]; + q->cmd = CMD_AP_READ; + q->ap_r.reg = reg; + q->ap_r.ap = ap; + q->ap_r.p_data = data; + + if (i == MAX_QUEUE_DEPTH - 1) + stlink_dap_run_internal(ap->dap); + + return ERROR_OK; +} + +static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, + uint32_t data) +{ + if (stlink_dap_get_error() != ERROR_OK) + return ERROR_OK; + + unsigned int i = stlink_dap_handle->queue_index++; + struct dap_queue *q = &stlink_dap_handle->queue[i]; + q->cmd = CMD_AP_WRITE; + q->ap_w.reg = reg; + q->ap_w.ap = ap; + q->ap_w.data = data; + + if (i == MAX_QUEUE_DEPTH - 1) + stlink_dap_run_internal(ap->dap); + + return ERROR_OK; +} + static int stlink_swim_op_srst(void) { return stlink_swim_generate_rst(stlink_dap_handle); @@ -4430,7 +4564,7 @@ static const struct dap_ops stlink_dap_ops = { .queue_ap_read = stlink_dap_op_queue_ap_read, .queue_ap_write = stlink_dap_op_queue_ap_write, .queue_ap_abort = stlink_dap_op_queue_ap_abort, - .run = stlink_dap_op_run, + .run = stlink_dap_op_queue_run, .sync = NULL, /* optional */ .quit = stlink_dap_op_quit, /* optional */ }; From 6f914cd8990435eafc85f8fc75fbecd7fbb96214 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 5 Feb 2020 16:20:37 +0100 Subject: [PATCH 04/82] stlink: expose ap number and csw in memory r/w Recent versions of stlink firmware allow accessing access port other than zero and setting the CSW. Modify the internal API to provide ap_num and csw. There is no interest to modify HLA to use ap_num and csw, so set and use some backward compatible defaults. Change-Id: I3f6dfc6c670d19467d9f5e717c6c956db6faf7f3 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6602 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 245 +++++++++++++++++++++------------- 1 file changed, 150 insertions(+), 95 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 92eb06d3a..3032ad4aa 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -113,6 +113,10 @@ */ #define MAX_WAIT_RETRIES 8 +/* HLA is currently limited at AP#0 and no control on CSW */ +#define STLINK_HLA_AP_NUM 0 +#define STLINK_HLA_CSW 0 + enum stlink_jtag_api_version { STLINK_JTAG_API_V1 = 1, STLINK_JTAG_API_V2, @@ -478,6 +482,7 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i /* aliases */ #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE #define STLINK_F_HAS_FPU_REG STLINK_F_HAS_GETLASTRWSTATUS2 +#define STLINK_F_HAS_CSW STLINK_F_HAS_DPBANKSEL #define STLINK_REGSEL_IS_FPU(x) ((x) > 0x1F) @@ -1306,6 +1311,7 @@ static int stlink_usb_version(void *handle) flags |= STLINK_F_FIX_CLOSE_AP; /* Banked regs (DPv1 & DPv2) support from V2J32 */ + /* Memory R/W supports CSW from V2J32 */ if (h->version.jtag >= 32) flags |= STLINK_F_HAS_DPBANKSEL; @@ -1336,6 +1342,7 @@ static int stlink_usb_version(void *handle) flags |= STLINK_F_FIX_CLOSE_AP; /* Banked regs (DPv1 & DPv2) support from V3J2 */ + /* Memory R/W supports CSW from V3J2 */ if (h->version.jtag >= 2) flags |= STLINK_F_HAS_DPBANKSEL; @@ -2377,8 +2384,8 @@ static int stlink_usb_get_rw_status(void *handle) } /** */ -static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, - uint8_t *buffer) +static int stlink_usb_read_mem8(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, uint8_t *buffer) { int res; uint16_t read_len = len; @@ -2386,6 +2393,9 @@ static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, assert(handle); + if ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW)) + return ERROR_COMMAND_NOTFOUND; + /* max 8 bit read/write is 64 bytes or 512 bytes for v3 */ if (len > stlink_usb_block(h)) { LOG_DEBUG("max buffer (%d) length exceeded", stlink_usb_block(h)); @@ -2400,6 +2410,9 @@ static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; /* we need to fix read length for single bytes */ if (read_len == 1) @@ -2416,14 +2429,17 @@ static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, } /** */ -static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, - const uint8_t *buffer) +static int stlink_usb_write_mem8(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; struct stlink_usb_handle_s *h = handle; assert(handle); + if ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW)) + return ERROR_COMMAND_NOTFOUND; + /* max 8 bit read/write is 64 bytes or 512 bytes for v3 */ if (len > stlink_usb_block(h)) { LOG_DEBUG("max buffer length (%d) exceeded", stlink_usb_block(h)); @@ -2438,6 +2454,9 @@ static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; res = stlink_usb_xfer_noerrcheck(handle, buffer, len); @@ -2448,8 +2467,8 @@ static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, } /** */ -static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, - uint8_t *buffer) +static int stlink_usb_read_mem16(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, uint8_t *buffer) { int res; struct stlink_usb_handle_s *h = handle; @@ -2459,6 +2478,9 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, if (!(h->version.flags & STLINK_F_HAS_MEM_16BIT)) return ERROR_COMMAND_NOTFOUND; + if ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW)) + return ERROR_COMMAND_NOTFOUND; + if (len > STLINK_MAX_RW16_32) { LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); return ERROR_FAIL; @@ -2478,6 +2500,9 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; res = stlink_usb_xfer_noerrcheck(handle, h->databuf, len); @@ -2490,8 +2515,8 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, } /** */ -static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, - const uint8_t *buffer) +static int stlink_usb_write_mem16(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; struct stlink_usb_handle_s *h = handle; @@ -2501,6 +2526,9 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, if (!(h->version.flags & STLINK_F_HAS_MEM_16BIT)) return ERROR_COMMAND_NOTFOUND; + if ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW)) + return ERROR_COMMAND_NOTFOUND; + if (len > STLINK_MAX_RW16_32) { LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); return ERROR_FAIL; @@ -2520,6 +2548,9 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; res = stlink_usb_xfer_noerrcheck(handle, buffer, len); @@ -2530,14 +2561,17 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, } /** */ -static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, - uint8_t *buffer) +static int stlink_usb_read_mem32(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, uint8_t *buffer) { int res; struct stlink_usb_handle_s *h = handle; assert(handle); + if ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW)) + return ERROR_COMMAND_NOTFOUND; + if (len > STLINK_MAX_RW16_32) { LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); return ERROR_FAIL; @@ -2557,6 +2591,9 @@ static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; res = stlink_usb_xfer_noerrcheck(handle, h->databuf, len); @@ -2569,14 +2606,17 @@ static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, } /** */ -static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, - const uint8_t *buffer) +static int stlink_usb_write_mem32(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; struct stlink_usb_handle_s *h = handle; assert(handle); + if ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW)) + return ERROR_COMMAND_NOTFOUND; + if (len > STLINK_MAX_RW16_32) { LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); return ERROR_FAIL; @@ -2596,6 +2636,9 @@ static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; res = stlink_usb_xfer_noerrcheck(handle, buffer, len); @@ -2613,8 +2656,93 @@ static uint32_t stlink_max_block_size(uint32_t tar_autoincr_block, uint32_t addr return max_tar_block; } +static int stlink_usb_read_ap_mem(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) +{ + int retval = ERROR_OK; + uint32_t bytes_remaining; + int retries = 0; + struct stlink_usb_handle_s *h = handle; + + /* calculate byte count */ + count *= size; + + /* switch to 8 bit if stlink does not support 16 bit memory read */ + if (size == 2 && !(h->version.flags & STLINK_F_HAS_MEM_16BIT)) + size = 1; + + while (count) { + bytes_remaining = (size != 1) ? + stlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h); + + if (count < bytes_remaining) + bytes_remaining = count; + + /* + * all stlink support 8/32bit memory read/writes and only from + * stlink V2J26 there is support for 16 bit memory read/write. + * Honour 32 bit and, if possible, 16 bit too. Otherwise, handle + * as 8bit access. + */ + if (size != 1) { + /* When in jtag mode the stlink uses the auto-increment functionality. + * However it expects us to pass the data correctly, this includes + * alignment and any page boundaries. We already do this as part of the + * adi_v5 implementation, but the stlink is a hla adapter and so this + * needs implementing manually. + * currently this only affects jtag mode, according to ST they do single + * access in SWD mode - but this may change and so we do it for both modes */ + + /* we first need to check for any unaligned bytes */ + if (addr & (size - 1)) { + uint32_t head_bytes = size - (addr & (size - 1)); + retval = stlink_usb_read_mem8(handle, ap_num, csw, addr, head_bytes, buffer); + if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { + usleep((1 << retries++) * 1000); + continue; + } + if (retval != ERROR_OK) + return retval; + buffer += head_bytes; + addr += head_bytes; + count -= head_bytes; + bytes_remaining -= head_bytes; + } + + if (bytes_remaining & (size - 1)) + retval = stlink_usb_read_ap_mem(handle, ap_num, csw, addr, 1, bytes_remaining, buffer); + else if (size == 2) + retval = stlink_usb_read_mem16(handle, ap_num, csw, addr, bytes_remaining, buffer); + else + retval = stlink_usb_read_mem32(handle, ap_num, csw, addr, bytes_remaining, buffer); + } else { + retval = stlink_usb_read_mem8(handle, ap_num, csw, addr, bytes_remaining, buffer); + } + + if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { + usleep((1 << retries++) * 1000); + continue; + } + if (retval != ERROR_OK) + return retval; + + buffer += bytes_remaining; + addr += bytes_remaining; + count -= bytes_remaining; + } + + return retval; +} + static int stlink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) +{ + return stlink_usb_read_ap_mem(handle, STLINK_HLA_AP_NUM, STLINK_HLA_CSW, + addr, size, count, buffer); +} + +static int stlink_usb_write_ap_mem(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer) { int retval = ERROR_OK; uint32_t bytes_remaining; @@ -2656,7 +2784,7 @@ static int stlink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, if (addr & (size - 1)) { uint32_t head_bytes = size - (addr & (size - 1)); - retval = stlink_usb_read_mem8(handle, addr, head_bytes, buffer); + retval = stlink_usb_write_mem8(handle, ap_num, csw, addr, head_bytes, buffer); if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { usleep((1<version.flags & STLINK_F_HAS_MEM_16BIT)) - size = 1; - - while (count) { - - bytes_remaining = (size != 1) ? - stlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h); - - if (count < bytes_remaining) - bytes_remaining = count; - - /* - * all stlink support 8/32bit memory read/writes and only from - * stlink V2J26 there is support for 16 bit memory read/write. - * Honour 32 bit and, if possible, 16 bit too. Otherwise, handle - * as 8bit access. - */ - if (size != 1) { - - /* When in jtag mode the stlink uses the auto-increment functionality. - * However it expects us to pass the data correctly, this includes - * alignment and any page boundaries. We already do this as part of the - * adi_v5 implementation, but the stlink is a hla adapter and so this - * needs implementing manually. - * currently this only affects jtag mode, according to ST they do single - * access in SWD mode - but this may change and so we do it for both modes */ - - /* we first need to check for any unaligned bytes */ - if (addr & (size - 1)) { - - uint32_t head_bytes = size - (addr & (size - 1)); - retval = stlink_usb_write_mem8(handle, addr, head_bytes, buffer); - if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { - usleep((1<max_mem_packet = (1 << 10); uint8_t buffer[4]; - stlink_usb_open_ap(h, 0); - err = stlink_usb_read_mem32(h, CPUID, 4, buffer); + stlink_usb_open_ap(h, STLINK_HLA_AP_NUM); + err = stlink_usb_read_mem32(h, STLINK_HLA_AP_NUM, STLINK_HLA_CSW, CPUID, 4, buffer); if (err == ERROR_OK) { uint32_t cpuid = le_to_h_u32(buffer); int i = (cpuid >> 4) & 0xf; From 7920110665630c8fdc42277ed17f6849597ea63e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 22 Jul 2021 23:50:33 +0200 Subject: [PATCH 05/82] stlink: detect mem_ap R/W and dequeue set TAR and CSW By using the stlink commands for memory read write we can gain some performance, but only when TAR and/or CSW are changed. During long transfers with constant CSW and TAR auto-incremented there is no gain, since the same amount of USB/TCP packet is used. Plus, by dropping ADIv5 packed transfers the performance is lower on 8 and 16 bits transfers. This changes opens the opportunity for collapsing memory burst accesses in a single stlink USB/TCP packet. Initialize the values of enum queue_cmd to easily extract the word size through a macro, even if this is not used here. Change-Id: I6661a00d468a1591a253cba9feb3bdb3f7474f5a Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6603 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 180 ++++++++++++++++++++++++++++++++-- 1 file changed, 172 insertions(+), 8 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 3032ad4aa..1cd68c50b 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -186,10 +186,25 @@ struct stlink_backend_s { enum queue_cmd { CMD_DP_READ = 1, CMD_DP_WRITE, + CMD_AP_READ, CMD_AP_WRITE, + + /* + * encode the bytes size in the enum's value. This makes easy to extract it + * with a simple logic AND, by using the macro CMD_MEM_AP_2_SIZE() below + */ + CMD_MEM_AP_READ8 = 0x10 + 1, + CMD_MEM_AP_READ16 = 0x10 + 2, + CMD_MEM_AP_READ32 = 0x10 + 4, + + CMD_MEM_AP_WRITE8 = 0x20 + 1, + CMD_MEM_AP_WRITE16 = 0x20 + 2, + CMD_MEM_AP_WRITE32 = 0x20 + 4, }; +#define CMD_MEM_AP_2_SIZE(cmd) ((cmd) & 7) + struct dap_queue { enum queue_cmd cmd; union { @@ -213,6 +228,15 @@ struct dap_queue { struct adiv5_ap *ap; uint32_t data; } ap_w; + struct mem_ap { + uint32_t addr; + struct adiv5_ap *ap; + union { + uint32_t *p_data; + uint32_t data; + }; + uint32_t csw; + } mem_ap; }; }; @@ -4119,6 +4143,7 @@ static void stlink_dap_run_internal(struct adiv5_dap *dap) unsigned int i = stlink_dap_handle->queue_index; struct dap_queue *q = &stlink_dap_handle->queue[0]; + uint8_t buf[4]; while (i && stlink_dap_get_error() == ERROR_OK) { switch (q->cmd) { @@ -4132,8 +4157,59 @@ static void stlink_dap_run_internal(struct adiv5_dap *dap) retval = stlink_dap_ap_read(q->ap_r.ap, q->ap_r.reg, q->ap_r.p_data); break; case CMD_AP_WRITE: + /* ignore increment packed, not supported */ + if (q->ap_w.reg == MEM_AP_REG_CSW) + q->ap_w.data &= ~CSW_ADDRINC_PACKED; retval = stlink_dap_ap_write(q->ap_w.ap, q->ap_w.reg, q->ap_w.data); break; + + case CMD_MEM_AP_READ8: + retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); + if (retval == ERROR_OK) + retval = stlink_usb_read_mem8(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, + 1, buf); + if (retval == ERROR_OK) + *q->mem_ap.p_data = *buf << 8 * (q->mem_ap.addr & 3); + break; + case CMD_MEM_AP_READ16: + retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); + if (retval == ERROR_OK) + retval = stlink_usb_read_mem16(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, + 2, buf); + if (retval == ERROR_OK) + *q->mem_ap.p_data = le_to_h_u16(buf) << 8 * (q->mem_ap.addr & 2); + break; + case CMD_MEM_AP_READ32: + retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); + if (retval == ERROR_OK) + retval = stlink_usb_read_mem32(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, + 4, buf); + if (retval == ERROR_OK) + *q->mem_ap.p_data = le_to_h_u32(buf); + break; + + case CMD_MEM_AP_WRITE8: + *buf = q->mem_ap.data >> 8 * (q->mem_ap.addr & 3); + retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); + if (retval == ERROR_OK) + retval = stlink_usb_write_mem8(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, + 1, buf); + break; + case CMD_MEM_AP_WRITE16: + h_u16_to_le(buf, q->mem_ap.data >> 8 * (q->mem_ap.addr & 2)); + retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); + if (retval == ERROR_OK) + retval = stlink_usb_write_mem16(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, + 2, buf); + break; + case CMD_MEM_AP_WRITE32: + h_u32_to_le(buf, q->mem_ap.data); + retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); + if (retval == ERROR_OK) + retval = stlink_usb_write_mem32(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, + 4, buf); + break; + default: LOG_ERROR("ST-Link: Unknown queue command %d", q->cmd); retval = ERROR_FAIL; @@ -4261,10 +4337,54 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, unsigned int i = stlink_dap_handle->queue_index++; struct dap_queue *q = &stlink_dap_handle->queue[i]; - q->cmd = CMD_AP_READ; - q->ap_r.reg = reg; - q->ap_r.ap = ap; - q->ap_r.p_data = data; + + if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && + (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || + reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { + /* de-queue previous write-TAR */ + struct dap_queue *prev_q = q - 1; + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_TAR) { + stlink_dap_handle->queue_index = i; + i--; + q = prev_q; + prev_q--; + } + /* de-queue previous write-CSW */ + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW) { + stlink_dap_handle->queue_index = i; + q = prev_q; + } + + switch (ap->csw_value & CSW_SIZE_MASK) { + case CSW_8BIT: + q->cmd = CMD_MEM_AP_READ8; + break; + case CSW_16BIT: + q->cmd = CMD_MEM_AP_READ16; + break; + case CSW_32BIT: + q->cmd = CMD_MEM_AP_READ32; + break; + default: + LOG_ERROR("ST-Link: Unsupported CSW size %d", ap->csw_value & CSW_SIZE_MASK); + stlink_dap_record_error(ERROR_FAIL); + return ERROR_FAIL; + } + + q->mem_ap.addr = (reg == MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c)); + q->mem_ap.ap = ap; + q->mem_ap.p_data = data; + q->mem_ap.csw = ap->csw_default; + + /* force TAR and CSW update */ + ap->tar_valid = false; + ap->csw_value = 0; + } else { + q->cmd = CMD_AP_READ; + q->ap_r.reg = reg; + q->ap_r.ap = ap; + q->ap_r.p_data = data; + } if (i == MAX_QUEUE_DEPTH - 1) stlink_dap_run_internal(ap->dap); @@ -4280,10 +4400,54 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, unsigned int i = stlink_dap_handle->queue_index++; struct dap_queue *q = &stlink_dap_handle->queue[i]; - q->cmd = CMD_AP_WRITE; - q->ap_w.reg = reg; - q->ap_w.ap = ap; - q->ap_w.data = data; + + if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && + (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || + reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { + /* de-queue previous write-TAR */ + struct dap_queue *prev_q = q - 1; + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_TAR) { + stlink_dap_handle->queue_index = i; + i--; + q = prev_q; + prev_q--; + } + /* de-queue previous write-CSW */ + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW) { + stlink_dap_handle->queue_index = i; + q = prev_q; + } + + switch (ap->csw_value & CSW_SIZE_MASK) { + case CSW_8BIT: + q->cmd = CMD_MEM_AP_WRITE8; + break; + case CSW_16BIT: + q->cmd = CMD_MEM_AP_WRITE16; + break; + case CSW_32BIT: + q->cmd = CMD_MEM_AP_WRITE32; + break; + default: + LOG_ERROR("ST-Link: Unsupported CSW size %d", ap->csw_value & CSW_SIZE_MASK); + stlink_dap_record_error(ERROR_FAIL); + return ERROR_FAIL; + } + + q->mem_ap.addr = (reg == MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c)); + q->mem_ap.ap = ap; + q->mem_ap.data = data; + q->mem_ap.csw = ap->csw_default; + + /* force TAR and CSW update */ + ap->tar_valid = false; + ap->csw_value = 0; + } else { + q->cmd = CMD_AP_WRITE; + q->ap_w.reg = reg; + q->ap_w.ap = ap; + q->ap_w.data = data; + } if (i == MAX_QUEUE_DEPTH - 1) stlink_dap_run_internal(ap->dap); From da15f9f8c29064f0124e60ac0ac21ddd11fdcc2c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 25 Jul 2021 17:31:53 +0200 Subject: [PATCH 06/82] stlink: collapse consecutive mem AP r/w in a single command Detect a sequence of memory AP operations that can be issued as a single stlink command. This improves the data throughput during memory transfer. Change-Id: Ifa4488513346fc7cd0c9317b7d24ef510ccfd959 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6604 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 136 +++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 42 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 1cd68c50b..818fccd33 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -4132,6 +4132,95 @@ static int stlink_dap_op_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) return ERROR_OK; } +static int stlink_usb_buf_rw_segment(void *handle, const struct dap_queue *q, unsigned int count) +{ + uint32_t bufsize = count * CMD_MEM_AP_2_SIZE(q[0].cmd); + uint8_t buf[bufsize]; + uint8_t ap_num = q[0].mem_ap.ap->ap_num; + uint32_t addr = q[0].mem_ap.addr; + uint32_t csw = q[0].mem_ap.csw; + + int retval = stlink_dap_open_ap(ap_num); + if (retval != ERROR_OK) + return retval; + + switch (q[0].cmd) { + case CMD_MEM_AP_WRITE8: + for (unsigned int i = 0; i < count; i++) + buf[i] = q[i].mem_ap.data >> 8 * (q[i].mem_ap.addr & 3); + return stlink_usb_write_mem8(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + + case CMD_MEM_AP_WRITE16: + for (unsigned int i = 0; i < count; i++) + h_u16_to_le(&buf[2 * i], q[i].mem_ap.data >> 8 * (q[i].mem_ap.addr & 2)); + return stlink_usb_write_mem16(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + + case CMD_MEM_AP_WRITE32: + for (unsigned int i = 0; i < count; i++) + h_u32_to_le(&buf[4 * i], q[i].mem_ap.data); + return stlink_usb_write_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + + case CMD_MEM_AP_READ8: + retval = stlink_usb_read_mem8(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + if (retval == ERROR_OK) + for (unsigned int i = 0; i < count; i++) + *q[i].mem_ap.p_data = buf[i] << 8 * (q[i].mem_ap.addr & 3); + return retval; + + case CMD_MEM_AP_READ16: + retval = stlink_usb_read_mem16(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + if (retval == ERROR_OK) + for (unsigned int i = 0; i < count; i++) + *q[i].mem_ap.p_data = le_to_h_u16(&buf[2 * i]) << 8 * (q[i].mem_ap.addr & 2); + return retval; + + case CMD_MEM_AP_READ32: + retval = stlink_usb_read_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + if (retval == ERROR_OK) + for (unsigned int i = 0; i < count; i++) + *q[i].mem_ap.p_data = le_to_h_u32(&buf[4 * i]); + return retval; + + default: + return ERROR_FAIL; + }; +} + +static int stlink_usb_count_buf_rw_queue(const struct dap_queue *q, unsigned int len) +{ + uint32_t incr = CMD_MEM_AP_2_SIZE(q[0].cmd); + unsigned int len_max; + + if (incr == 1) + len_max = stlink_usb_block(stlink_dap_handle); + else + len_max = STLINK_MAX_RW16_32 / incr; + + if (len > len_max) + len = len_max; + + for (unsigned int i = 1; i < len; i++) + if (q[i].cmd != q[0].cmd || + q[i].mem_ap.ap != q[0].mem_ap.ap || + q[i].mem_ap.csw != q[0].mem_ap.csw || + q[i].mem_ap.addr != q[i - 1].mem_ap.addr + incr) + return i; + + return len; +} + +static int stlink_usb_mem_rw_queue(void *handle, const struct dap_queue *q, unsigned int len, unsigned int *skip) +{ + unsigned int count = stlink_usb_count_buf_rw_queue(q, len); + + int retval = stlink_usb_buf_rw_segment(handle, q, count); + if (retval != ERROR_OK) + return retval; + + *skip = count; + return ERROR_OK; +} + static void stlink_dap_run_internal(struct adiv5_dap *dap) { int retval = stlink_dap_check_reconnect(dap); @@ -4143,9 +4232,10 @@ static void stlink_dap_run_internal(struct adiv5_dap *dap) unsigned int i = stlink_dap_handle->queue_index; struct dap_queue *q = &stlink_dap_handle->queue[0]; - uint8_t buf[4]; while (i && stlink_dap_get_error() == ERROR_OK) { + unsigned int skip = 1; + switch (q->cmd) { case CMD_DP_READ: retval = stlink_dap_dp_read(q->dp_r.dap, q->dp_r.reg, q->dp_r.p_data); @@ -4164,50 +4254,12 @@ static void stlink_dap_run_internal(struct adiv5_dap *dap) break; case CMD_MEM_AP_READ8: - retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); - if (retval == ERROR_OK) - retval = stlink_usb_read_mem8(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, - 1, buf); - if (retval == ERROR_OK) - *q->mem_ap.p_data = *buf << 8 * (q->mem_ap.addr & 3); - break; case CMD_MEM_AP_READ16: - retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); - if (retval == ERROR_OK) - retval = stlink_usb_read_mem16(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, - 2, buf); - if (retval == ERROR_OK) - *q->mem_ap.p_data = le_to_h_u16(buf) << 8 * (q->mem_ap.addr & 2); - break; case CMD_MEM_AP_READ32: - retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); - if (retval == ERROR_OK) - retval = stlink_usb_read_mem32(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, - 4, buf); - if (retval == ERROR_OK) - *q->mem_ap.p_data = le_to_h_u32(buf); - break; - case CMD_MEM_AP_WRITE8: - *buf = q->mem_ap.data >> 8 * (q->mem_ap.addr & 3); - retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); - if (retval == ERROR_OK) - retval = stlink_usb_write_mem8(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, - 1, buf); - break; case CMD_MEM_AP_WRITE16: - h_u16_to_le(buf, q->mem_ap.data >> 8 * (q->mem_ap.addr & 2)); - retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); - if (retval == ERROR_OK) - retval = stlink_usb_write_mem16(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, - 2, buf); - break; case CMD_MEM_AP_WRITE32: - h_u32_to_le(buf, q->mem_ap.data); - retval = stlink_dap_open_ap(q->mem_ap.ap->ap_num); - if (retval == ERROR_OK) - retval = stlink_usb_write_mem32(stlink_dap_handle, q->mem_ap.ap->ap_num, q->mem_ap.csw, q->mem_ap.addr, - 4, buf); + retval = stlink_usb_mem_rw_queue(stlink_dap_handle, q, i, &skip); break; default: @@ -4216,8 +4268,8 @@ static void stlink_dap_run_internal(struct adiv5_dap *dap) break; } stlink_dap_record_error(retval); - q++; - i--; + q += skip; + i -= skip; } stlink_dap_handle->queue_index = 0; From 9a534c4bb2a88fdc2ddaf7d4356faddba59736ea Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 25 Jul 2021 23:46:55 +0200 Subject: [PATCH 07/82] stlink: add support for native no_addr_incr commands Firmware versions V2J26 and V3J1 introduce the command STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC Firmware versions V2J32 and V3J2 introduce the command STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC These new commands can provide speed improvement to Cortex-A memory download (its debug port use a FIFO for data transfer). Add the low level commands and extend high level implementation. Change-Id: I3b65acbeaec3bd305f5568b9ee4bc9495b113448 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6605 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 108 +++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 818fccd33..e6fc7b624 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -434,6 +434,10 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i #define STLINK_DEBUG_APIV2_INIT_AP 0x4B #define STLINK_DEBUG_APIV2_CLOSE_AP_DBG 0x4C +#define STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC 0x50 + +#define STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC 0x54 + #define STLINK_APIV3_SET_COM_FREQ 0x61 #define STLINK_APIV3_GET_COM_FREQ 0x62 @@ -506,6 +510,8 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i /* aliases */ #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE #define STLINK_F_HAS_FPU_REG STLINK_F_HAS_GETLASTRWSTATUS2 +#define STLINK_F_HAS_MEM_WR_NO_INC STLINK_F_HAS_MEM_16BIT +#define STLINK_F_HAS_MEM_RD_NO_INC STLINK_F_HAS_DPBANKSEL #define STLINK_F_HAS_CSW STLINK_F_HAS_DPBANKSEL #define STLINK_REGSEL_IS_FPU(x) ((x) > 0x1F) @@ -1323,6 +1329,7 @@ static int stlink_usb_version(void *handle) flags |= STLINK_F_QUIRK_JTAG_DP_READ; /* API to read/write memory at 16 bit from J26 */ + /* API to write memory without address increment from J26 */ if (h->version.jtag >= 26) flags |= STLINK_F_HAS_MEM_16BIT; @@ -1335,6 +1342,7 @@ static int stlink_usb_version(void *handle) flags |= STLINK_F_FIX_CLOSE_AP; /* Banked regs (DPv1 & DPv2) support from V2J32 */ + /* API to read memory without address increment from V2J32 */ /* Memory R/W supports CSW from V2J32 */ if (h->version.jtag >= 32) flags |= STLINK_F_HAS_DPBANKSEL; @@ -1357,6 +1365,7 @@ static int stlink_usb_version(void *handle) flags |= STLINK_F_HAS_DAP_REG; /* API to read/write memory at 16 bit */ + /* API to write memory without address increment */ flags |= STLINK_F_HAS_MEM_16BIT; /* API required to init AP before any AP access */ @@ -1366,6 +1375,7 @@ static int stlink_usb_version(void *handle) flags |= STLINK_F_FIX_CLOSE_AP; /* Banked regs (DPv1 & DPv2) support from V3J2 */ + /* API to read memory without address increment from V3J2 */ /* Memory R/W supports CSW from V3J2 */ if (h->version.jtag >= 2) flags |= STLINK_F_HAS_DPBANKSEL; @@ -2672,6 +2682,88 @@ static int stlink_usb_write_mem32(void *handle, uint8_t ap_num, uint32_t csw, return stlink_usb_get_rw_status(handle); } +static int stlink_usb_read_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, uint8_t *buffer) +{ + struct stlink_usb_handle_s *h = handle; + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_MEM_RD_NO_INC)) + return ERROR_COMMAND_NOTFOUND; + + if (len > STLINK_MAX_RW16_32) { + LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); + return ERROR_FAIL; + } + + /* data must be a multiple of 4 and word aligned */ + if (len % 4 || addr % 4) { + LOG_DEBUG("Invalid data alignment"); + return ERROR_TARGET_UNALIGNED_ACCESS; + } + + stlink_usb_init_buffer(handle, h->rx_ep, len); + + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC; + h_u32_to_le(h->cmdbuf + h->cmdidx, addr); + h->cmdidx += 4; + h_u16_to_le(h->cmdbuf + h->cmdidx, len); + h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; + + int retval = stlink_usb_xfer_noerrcheck(handle, h->databuf, len); + if (retval != ERROR_OK) + return retval; + + memcpy(buffer, h->databuf, len); + + return stlink_usb_get_rw_status(handle); +} + +static int stlink_usb_write_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw, + uint32_t addr, uint16_t len, const uint8_t *buffer) +{ + struct stlink_usb_handle_s *h = handle; + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_MEM_WR_NO_INC)) + return ERROR_COMMAND_NOTFOUND; + + if (len > STLINK_MAX_RW16_32) { + LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32); + return ERROR_FAIL; + } + + /* data must be a multiple of 4 and word aligned */ + if (len % 4 || addr % 4) { + LOG_DEBUG("Invalid data alignment"); + return ERROR_TARGET_UNALIGNED_ACCESS; + } + + stlink_usb_init_buffer(handle, h->tx_ep, len); + + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC; + h_u32_to_le(h->cmdbuf + h->cmdidx, addr); + h->cmdidx += 4; + h_u16_to_le(h->cmdbuf + h->cmdidx, len); + h->cmdidx += 2; + h->cmdbuf[h->cmdidx++] = ap_num; + h_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8); + h->cmdidx += 3; + + int retval = stlink_usb_xfer_noerrcheck(handle, buffer, len); + if (retval != ERROR_OK) + return retval; + + return stlink_usb_get_rw_status(handle); +} + static uint32_t stlink_max_block_size(uint32_t tar_autoincr_block, uint32_t address) { uint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address)); @@ -4158,7 +4250,10 @@ static int stlink_usb_buf_rw_segment(void *handle, const struct dap_queue *q, un case CMD_MEM_AP_WRITE32: for (unsigned int i = 0; i < count; i++) h_u32_to_le(&buf[4 * i], q[i].mem_ap.data); - return stlink_usb_write_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + if (count > 1 && q[0].mem_ap.addr == q[1].mem_ap.addr) + return stlink_usb_write_mem32_noaddrinc(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + else + return stlink_usb_write_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); case CMD_MEM_AP_READ8: retval = stlink_usb_read_mem8(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); @@ -4175,7 +4270,10 @@ static int stlink_usb_buf_rw_segment(void *handle, const struct dap_queue *q, un return retval; case CMD_MEM_AP_READ32: - retval = stlink_usb_read_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + if (count > 1 && q[0].mem_ap.addr == q[1].mem_ap.addr) + retval = stlink_usb_read_mem32_noaddrinc(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); + else + retval = stlink_usb_read_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf); if (retval == ERROR_OK) for (unsigned int i = 0; i < count; i++) *q[i].mem_ap.p_data = le_to_h_u32(&buf[4 * i]); @@ -4196,6 +4294,10 @@ static int stlink_usb_count_buf_rw_queue(const struct dap_queue *q, unsigned int else len_max = STLINK_MAX_RW16_32 / incr; + /* check for no address increment, 32 bits only */ + if (len > 1 && incr == 4 && q[0].mem_ap.addr == q[1].mem_ap.addr) + incr = 0; + if (len > len_max) len = len_max; @@ -4390,6 +4492,7 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, unsigned int i = stlink_dap_handle->queue_index++; struct dap_queue *q = &stlink_dap_handle->queue[i]; + /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_RD_NO_INC */ if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { @@ -4453,6 +4556,7 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, unsigned int i = stlink_dap_handle->queue_index++; struct dap_queue *q = &stlink_dap_handle->queue[i]; + /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_WR_NO_INC */ if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { From 22c76a4fd536ba53f563d72d2b3402c45f925f85 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 29 Jul 2021 18:38:20 +0200 Subject: [PATCH 08/82] stlink: dequeue CSW write only if it doesn't change csw_default The stlink commands for buffer read/write carry the associated CSW value that has to be used. We can dequeue any CSW write request and add the CSW in the following buffer read/write. In preparation to next patch that uses stlink commands misc-rw (commands that don't handle CSW value), let's dequeue only those CSW write that don't change csw_default. Keep a local cache of last csw_default. Tag the queued CSW writes that change csw_default. Dequeue only the un-tagged CSW writes. On buffer read/write commands, limiting the dequeued CSW write surely adds a performance penalty. But csw_default is not changed often so the penalty is not significant. Change-Id: I538d257fe3c434fc97587846d759951384327f02 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6606 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index e6fc7b624..92ce1e801 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -227,6 +227,7 @@ struct dap_queue { unsigned int reg; struct adiv5_ap *ap; uint32_t data; + bool changes_csw_default; } ap_w; struct mem_ap { uint32_t addr; @@ -3960,6 +3961,7 @@ struct hl_layout_api_s stlink_usb_layout_api = { static struct stlink_usb_handle_s *stlink_dap_handle; static struct hl_interface_param_s stlink_dap_param; static DECLARE_BITMAP(opened_ap, DP_APSEL_MAX + 1); +static uint32_t last_csw_default[DP_APSEL_MAX + 1]; static int stlink_dap_error = ERROR_OK; /** */ @@ -4004,6 +4006,7 @@ static int stlink_usb_open_ap(void *handle, unsigned short apsel) LOG_DEBUG("AP %d enabled", apsel); set_bit(apsel, opened_ap); + last_csw_default[apsel] = 0; return ERROR_OK; } @@ -4087,6 +4090,8 @@ static int stlink_dap_op_connect(struct adiv5_dap *dap) dap->do_reconnect = false; dap_invalidate_cache(dap); + for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) + last_csw_default[i] = 0; retval = dap_dp_init(dap); if (retval != ERROR_OK) { @@ -4504,8 +4509,9 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, q = prev_q; prev_q--; } - /* de-queue previous write-CSW */ - if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW) { + /* de-queue previous write-CSW if it didn't changed ap->csw_default */ + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW && + !prev_q->ap_w.changes_csw_default) { stlink_dap_handle->queue_index = i; q = prev_q; } @@ -4568,8 +4574,9 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, q = prev_q; prev_q--; } - /* de-queue previous write-CSW */ - if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW) { + /* de-queue previous write-CSW if it didn't changed ap->csw_default */ + if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW && + !prev_q->ap_w.changes_csw_default) { stlink_dap_handle->queue_index = i; q = prev_q; } @@ -4603,6 +4610,12 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, q->ap_w.reg = reg; q->ap_w.ap = ap; q->ap_w.data = data; + if (reg == MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap->ap_num]) { + q->ap_w.changes_csw_default = true; + last_csw_default[ap->ap_num] = ap->csw_default; + } else { + q->ap_w.changes_csw_default = false; + } } if (i == MAX_QUEUE_DEPTH - 1) From 6df533abb89307da066335700856e9bfe8586b94 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 29 Jul 2021 17:54:31 +0200 Subject: [PATCH 09/82] stlink: add support for rw-misc commands Firmware versions V2J32 and V3J2 introduce the commands RW-MISC to put in a single USB packet a sequence of mem_ap read/write. These commands provide a significant speed improvement while accessing the debug unit at scattered addresses. Add the low level commands and extend high level implementation. Skip for the moment the command to read the max number of items allowed by the firmware and use some hardcoded values. Change-Id: I8adc630cc0de733511e9d94533cbfe9f3b301a83 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6607 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 197 +++++++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 4 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 92ce1e801..42b8cc2e8 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -33,6 +33,7 @@ #endif /* project specific includes */ +#include #include #include #include @@ -436,6 +437,8 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i #define STLINK_DEBUG_APIV2_CLOSE_AP_DBG 0x4C #define STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC 0x50 +#define STLINK_DEBUG_APIV2_RW_MISC_OUT 0x51 +#define STLINK_DEBUG_APIV2_RW_MISC_IN 0x52 #define STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC 0x54 @@ -513,6 +516,7 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i #define STLINK_F_HAS_FPU_REG STLINK_F_HAS_GETLASTRWSTATUS2 #define STLINK_F_HAS_MEM_WR_NO_INC STLINK_F_HAS_MEM_16BIT #define STLINK_F_HAS_MEM_RD_NO_INC STLINK_F_HAS_DPBANKSEL +#define STLINK_F_HAS_RW_MISC STLINK_F_HAS_DPBANKSEL #define STLINK_F_HAS_CSW STLINK_F_HAS_DPBANKSEL #define STLINK_REGSEL_IS_FPU(x) ((x) > 0x1F) @@ -3867,6 +3871,53 @@ static int stlink_usb_close_access_port(void *handle, unsigned char ap_num) } +static int stlink_usb_rw_misc_out(void *handle, uint32_t items, const uint8_t *buffer) +{ + struct stlink_usb_handle_s *h = handle; + unsigned int buflen = ALIGN_UP(items, 4) + 4 * items; + + LOG_DEBUG_IO("%s(%" PRIu32 ")", __func__, items); + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_RW_MISC)) + return ERROR_COMMAND_NOTFOUND; + + stlink_usb_init_buffer(handle, h->tx_ep, buflen); + + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RW_MISC_OUT; + h_u32_to_le(&h->cmdbuf[2], items); + + return stlink_usb_xfer_noerrcheck(handle, buffer, buflen); +} + +static int stlink_usb_rw_misc_in(void *handle, uint32_t items, uint8_t *buffer) +{ + struct stlink_usb_handle_s *h = handle; + unsigned int buflen = 2 * 4 * items; + + LOG_DEBUG_IO("%s(%" PRIu32 ")", __func__, items); + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_RW_MISC)) + return ERROR_COMMAND_NOTFOUND; + + stlink_usb_init_buffer(handle, h->rx_ep, buflen); + + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RW_MISC_IN; + + int res = stlink_usb_xfer_noerrcheck(handle, h->databuf, buflen); + if (res != ERROR_OK) + return res; + + memcpy(buffer, h->databuf, buflen); + + return ERROR_OK; +} + /** */ static int stlink_read_dap_register(void *handle, unsigned short dap_port, unsigned short addr, uint32_t *val) @@ -4229,6 +4280,97 @@ static int stlink_dap_op_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) return ERROR_OK; } +#define RW_MISC_CMD_ADDRESS 1 +#define RW_MISC_CMD_WRITE 2 +#define RW_MISC_CMD_READ 3 +#define RW_MISC_CMD_APNUM 5 + +static int stlink_usb_misc_rw_segment(void *handle, const struct dap_queue *q, unsigned int len, unsigned int items) +{ + uint8_t buf[2 * 4 * items]; + + LOG_DEBUG("Queue: %u commands in %u items", len, items); + + int ap_num = DP_APSEL_INVALID; + unsigned int cmd_index = 0; + unsigned int val_index = ALIGN_UP(items, 4); + for (unsigned int i = 0; i < len; i++) { + if (ap_num != q[i].mem_ap.ap->ap_num) { + ap_num = q[i].mem_ap.ap->ap_num; + buf[cmd_index++] = RW_MISC_CMD_APNUM; + h_u32_to_le(&buf[val_index], ap_num); + val_index += 4; + } + + switch (q[i].cmd) { + case CMD_MEM_AP_READ32: + buf[cmd_index++] = RW_MISC_CMD_READ; + h_u32_to_le(&buf[val_index], q[i].mem_ap.addr); + val_index += 4; + break; + case CMD_MEM_AP_WRITE32: + buf[cmd_index++] = RW_MISC_CMD_ADDRESS; + h_u32_to_le(&buf[val_index], q[i].mem_ap.addr); + val_index += 4; + buf[cmd_index++] = RW_MISC_CMD_WRITE; + h_u32_to_le(&buf[val_index], q[i].mem_ap.data); + val_index += 4; + break; + default: + /* Not supposed to happen */ + return ERROR_FAIL; + } + } + /* pad after last command */ + while (!IS_ALIGNED(cmd_index, 4)) + buf[cmd_index++] = 0; + + int retval = stlink_usb_rw_misc_out(handle, items, buf); + if (retval != ERROR_OK) + return retval; + + retval = stlink_usb_rw_misc_in(handle, items, buf); + if (retval != ERROR_OK) + return retval; + + ap_num = DP_APSEL_INVALID; + val_index = 0; + unsigned int err_index = 4 * items; + for (unsigned int i = 0; i < len; i++) { + uint32_t errcode = le_to_h_u32(&buf[err_index]); + if (errcode != STLINK_DEBUG_ERR_OK) { + LOG_ERROR("unknown/unexpected STLINK status code 0x%x", errcode); + return ERROR_FAIL; + } + if (ap_num != q[i].mem_ap.ap->ap_num) { + ap_num = q[i].mem_ap.ap->ap_num; + err_index += 4; + val_index += 4; + errcode = le_to_h_u32(&buf[err_index]); + if (errcode != STLINK_DEBUG_ERR_OK) { + LOG_ERROR("unknown/unexpected STLINK status code 0x%x", errcode); + return ERROR_FAIL; + } + } + + if (q[i].cmd == CMD_MEM_AP_READ32) { + *q[i].mem_ap.p_data = le_to_h_u32(&buf[val_index]); + } else { /* q[i]->cmd == CMD_MEM_AP_WRITE32 */ + err_index += 4; + val_index += 4; + errcode = le_to_h_u32(&buf[err_index]); + if (errcode != STLINK_DEBUG_ERR_OK) { + LOG_ERROR("unknown/unexpected STLINK status code 0x%x", errcode); + return ERROR_FAIL; + } + } + err_index += 4; + val_index += 4; + } + + return ERROR_OK; +} + static int stlink_usb_buf_rw_segment(void *handle, const struct dap_queue *q, unsigned int count) { uint32_t bufsize = count * CMD_MEM_AP_2_SIZE(q[0].cmd); @@ -4289,6 +4431,41 @@ static int stlink_usb_buf_rw_segment(void *handle, const struct dap_queue *q, un }; } +/* TODO: recover these values with cmd STLINK_DEBUG_APIV2_RW_MISC_GET_MAX (0x53) */ +#define STLINK_V2_RW_MISC_SIZE (64) +#define STLINK_V3_RW_MISC_SIZE (1227) + +static int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue *q, unsigned int len, + unsigned int *pkt_items) +{ + struct stlink_usb_handle_s *h = handle; + unsigned int i, items = 0; + int ap_num = DP_APSEL_INVALID; + unsigned int misc_max_items = (h->version.stlink == 2) ? STLINK_V2_RW_MISC_SIZE : STLINK_V3_RW_MISC_SIZE; + + if (!(h->version.flags & STLINK_F_HAS_RW_MISC)) + return 0; + + for (i = 0; i < len; i++) { + if (q[i].cmd != CMD_MEM_AP_READ32 && q[i].cmd != CMD_MEM_AP_WRITE32) + break; + unsigned int count = 1; + if (ap_num != q[i].mem_ap.ap->ap_num) { + count++; + ap_num = q[i].mem_ap.ap->ap_num; + } + if (q[i].cmd == CMD_MEM_AP_WRITE32) + count++; + if (items + count > misc_max_items) + break; + items += count; + } + + *pkt_items = items; + + return i; +} + static int stlink_usb_count_buf_rw_queue(const struct dap_queue *q, unsigned int len) { uint32_t incr = CMD_MEM_AP_2_SIZE(q[0].cmd); @@ -4318,9 +4495,19 @@ static int stlink_usb_count_buf_rw_queue(const struct dap_queue *q, unsigned int static int stlink_usb_mem_rw_queue(void *handle, const struct dap_queue *q, unsigned int len, unsigned int *skip) { - unsigned int count = stlink_usb_count_buf_rw_queue(q, len); + unsigned int count, misc_items = 0; + int retval; - int retval = stlink_usb_buf_rw_segment(handle, q, count); + unsigned int count_misc = stlink_usb_count_misc_rw_queue(handle, q, len, &misc_items); + unsigned int count_buf = stlink_usb_count_buf_rw_queue(q, len); + + if (count_misc > count_buf) { + count = count_misc; + retval = stlink_usb_misc_rw_segment(handle, q, count, misc_items); + } else { + count = count_buf; + retval = stlink_usb_buf_rw_segment(handle, q, count_buf); + } if (retval != ERROR_OK) return retval; @@ -4497,7 +4684,8 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, unsigned int i = stlink_dap_handle->queue_index++; struct dap_queue *q = &stlink_dap_handle->queue[i]; - /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_RD_NO_INC */ + /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_RD_NO_INC + * and STLINK_F_HAS_RW_MISC */ if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { @@ -4562,7 +4750,8 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, unsigned int i = stlink_dap_handle->queue_index++; struct dap_queue *q = &stlink_dap_handle->queue[i]; - /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_WR_NO_INC */ + /* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_WR_NO_INC + * and STLINK_F_HAS_RW_MISC */ if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) && (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 || reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) { From bac3ef96b79ac7b7b44585f2c3a2adcd8732f7a2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 14 Aug 2021 14:48:50 +0200 Subject: [PATCH 10/82] stlink: skip rw-misc commands with TCP server The main purpose of TCP server is to allow multiple clients to connect and share the same physical stlink. The commands RW MISC don't lock the communication between command and answer, thus cannot prevent another client to break this sequence. The commands are not supposed to be used in shared mode. Prevent the use of RW MISC commands on a (possibly) shared TCP backend. This degrades the overall performance, but the shared mode already adds its own overhead, so this is not really an issue. Change-Id: I713d912a269664859c8142932a9905d24b6d3caa Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6608 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 42b8cc2e8..b51a0c2ba 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -4445,6 +4445,13 @@ static int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue * if (!(h->version.flags & STLINK_F_HAS_RW_MISC)) return 0; + /* + * RW_MISC sequence doesn't lock the st-link, so are not safe in shared mode. + * Don't use it with TCP backend to prevent any issue in case of sharing. + * This further degrades the performance, on top of TCP server overhead. + */ + if (h->backend == &stlink_tcp_backend) + return 0; for (i = 0; i < len; i++) { if (q[i].cmd != CMD_MEM_AP_READ32 && q[i].cmd != CMD_MEM_AP_WRITE32) From 6fef2eca381ddcda593aca27290706873a9bcde2 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sat, 25 Sep 2021 08:52:50 -0700 Subject: [PATCH 11/82] drivers/linuxgpiod: add support for opendrain trst This is a follow-up to 2f424b7eb, which added support for opendrain srst, finishing up support for opendrain reset signals. Signed-off-by: Alex Crawford Change-Id: Ib79b2e12f2a9469fd6c53bb839c0d2e8e46103a4 Reviewed-on: https://review.openocd.org/c/openocd/+/6598 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/linuxgpiod.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c index dd50b4406..75f6152be 100644 --- a/src/jtag/drivers/linuxgpiod.c +++ b/src/jtag/drivers/linuxgpiod.c @@ -360,7 +360,11 @@ static int linuxgpiod_init(void) goto out_error; if (is_gpio_valid(trst_gpio)) { - gpiod_trst = helper_get_output_line("trst", trst_gpio, 1); + if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN) + gpiod_trst = helper_get_open_drain_output_line("trst", trst_gpio, 1); + else + gpiod_trst = helper_get_output_line("trst", trst_gpio, 1); + if (!gpiod_trst) goto out_error; } From 4afd8852bb320deea553504161bd2c79c434bb1b Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Tue, 12 Oct 2021 08:28:34 +0200 Subject: [PATCH 12/82] Remove remaining references to FTD2XX driver This includes a USB blaster configuration that only worked with that low-level access and some obsolete build-tests. Change-Id: I53d27cbf782ebbd131b1af25e358adf35f2b4500 Signed-off-by: Andreas Fritiofson Reviewed-on: https://review.openocd.org/c/openocd/+/6660 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- doc/openocd.texi | 9 +- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/usb_blaster/ublast_access.h | 1 - src/jtag/drivers/usb_blaster/usb_blaster.c | 21 +- testing/build.test1/Makefile | 95 ------ testing/build.test1/Makefile.confuse | 46 --- testing/build.test1/Makefile.ftd2xx | 88 ------ testing/build.test1/Makefile.libftdi | 51 --- testing/build.test1/Makefile.libusb | 55 ---- testing/build.test1/Makefile.openocd | 193 ----------- testing/build.test1/README.TXT | 38 --- testing/build.test1/local.uses | 39 --- .../build.test1/mingw32_help/include/elf.h | 38 --- .../mingw32_help/include/sys/cdefs.h | 22 -- .../mingw32_help/include/sys/elf32.h | 156 --------- .../mingw32_help/include/sys/elf64.h | 172 ---------- .../mingw32_help/include/sys/elf_common.h | 299 ------------------ .../mingw32_help/include/sys/elf_generic.h | 91 ------ testing/build.test2/Makefile | 193 ----------- testing/build.test2/README.txt | 58 ---- testing/build.test2/local.uses | 161 ---------- 21 files changed, 3 insertions(+), 1825 deletions(-) delete mode 100644 testing/build.test1/Makefile delete mode 100644 testing/build.test1/Makefile.confuse delete mode 100644 testing/build.test1/Makefile.ftd2xx delete mode 100644 testing/build.test1/Makefile.libftdi delete mode 100644 testing/build.test1/Makefile.libusb delete mode 100644 testing/build.test1/Makefile.openocd delete mode 100644 testing/build.test1/README.TXT delete mode 100644 testing/build.test1/local.uses delete mode 100644 testing/build.test1/mingw32_help/include/elf.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/cdefs.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf32.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf64.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf_common.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf_generic.h delete mode 100644 testing/build.test2/Makefile delete mode 100644 testing/build.test2/README.txt delete mode 100644 testing/build.test2/local.uses diff --git a/doc/openocd.texi b/doc/openocd.texi index 7bf0fe98b..cd64c7aec 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2459,7 +2459,7 @@ This driver is for adapters using the MPSSE (Multi-Protocol Synchronous Serial Engine) mode built into many FTDI chips, such as the FT2232, FT4232 and FT232H. The driver is using libusb-1.0 in asynchronous mode to talk to the FTDI device, -bypassing intermediate libraries like libftdi or D2XX. +bypassing intermediate libraries like libftdi. Support for new FTDI based adapters can be added completely through configuration files, without the need to patch and rebuild OpenOCD. @@ -2728,13 +2728,6 @@ USB JTAG/USB-Blaster compatibles over one of the userspace libraries for FTDI chips. These interfaces have several commands, used to configure the driver before initializing the JTAG scan chain: -@deffn {Config Command} {usb_blaster device_desc} description -Provides the USB device description (the @emph{iProduct string}) -of the FTDI FT245 device. If not -specified, the FTDI default value is used. This setting is only valid -if compiled with FTD2XX support. -@end deffn - @deffn {Config Command} {usb_blaster vid_pid} vid pid The vendor ID and product ID of the FTDI FT245 device. If not specified, default values are used. diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 123134f51..7340119a1 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -1,6 +1,6 @@ /******************************************************************************* * Driver for OpenJTAG Project (www.openjtag.org) * - * Compatible with libftdi and ftd2xx drivers. * + * Compatible with libftdi drivers. * * * * Cypress CY7C65215 support * * Copyright (C) 2015 Vianney le Clément de Saint-Marcq, Essensium NV * diff --git a/src/jtag/drivers/usb_blaster/ublast_access.h b/src/jtag/drivers/usb_blaster/ublast_access.h index ad20d65d4..ada764c1c 100644 --- a/src/jtag/drivers/usb_blaster/ublast_access.h +++ b/src/jtag/drivers/usb_blaster/ublast_access.h @@ -36,7 +36,6 @@ struct ublast_lowlevel { uint16_t ublast_pid; uint16_t ublast_vid_uninit; uint16_t ublast_pid_uninit; - char *ublast_device_desc; struct libusb_device_handle *libusb_dev; char *firmware_path; diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index cc1d4758f..049a24378 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -119,7 +119,6 @@ struct ublast_info { char *lowlevel_name; struct ublast_lowlevel *drv; - char *ublast_device_desc; uint16_t ublast_vid, ublast_pid; uint16_t ublast_vid_uninit, ublast_pid_uninit; int flags; @@ -140,7 +139,7 @@ static struct ublast_info info = { }; /* - * Available lowlevel drivers (FTDI, FTD2xx, ...) + * Available lowlevel drivers (FTDI, libusb, ...) */ struct drvs_map { char *name; @@ -874,7 +873,6 @@ static int ublast_init(void) info.drv->ublast_pid = info.ublast_pid; info.drv->ublast_vid_uninit = info.ublast_vid_uninit; info.drv->ublast_pid_uninit = info.ublast_pid_uninit; - info.drv->ublast_device_desc = info.ublast_device_desc; info.drv->firmware_path = info.firmware_path; info.flags |= info.drv->flags; @@ -908,16 +906,6 @@ static int ublast_quit(void) return info.drv->close(info.drv); } -COMMAND_HANDLER(ublast_handle_device_desc_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - info.ublast_device_desc = strdup(CMD_ARGV[0]); - - return ERROR_OK; -} - COMMAND_HANDLER(ublast_handle_vid_pid_command) { if (CMD_ARGC > 4) { @@ -1031,13 +1019,6 @@ COMMAND_HANDLER(ublast_firmware_command) static const struct command_registration ublast_subcommand_handlers[] = { - { - .name = "device_desc", - .handler = ublast_handle_device_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the USB device description of the USB-Blaster", - .usage = "description-string", - }, { .name = "vid_pid", .handler = ublast_handle_vid_pid_command, diff --git a/testing/build.test1/Makefile b/testing/build.test1/Makefile deleted file mode 100644 index 02b752307..000000000 --- a/testing/build.test1/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -# -*- mode: makefile -*- -# -default: _complain_ -include ./local.uses - -%: _complain_ - - -_complain_: - @echo "" - @echo " Try the target: cygwin.buildtest or linux.buildtest " - @echo "" - -remove.install: - rm -rf ${INSTALL_DIR} - -.PHONY: remove.install - -cygwin.buildtest: - ${MAKE} -f Makefile.ftd2xx clean all - ${MAKE} -f Makefile.openocd cygwin.easy.permutations - ${MAKE} -f Makefile.openocd mingw32.easy.permutations - ${MAKE} -f Makefile.libftdi all - ${MAKE} -f Makefile.openocd cygwin.libftdi - -linux.buildtest: - ${MAKE} linux.easy.buildtest - ${MAKE} linux.ftd2xx_installed - ${MAKE} linux.ft2232_libftdi - @echo "" - @echo "" - @echo "========================================" - @echo " Linux Build Tests Complete " - @echo "========================================" - @echo "" - @echo "" - - -linux.easy.buildtest: - @test -d openocd || (echo "Where the source to openocd?" && exit 1) - ${MAKE} -f Makefile.openocd bootstrap - ${MAKE} -f Makefile.ftd2xx all - ${MAKE} -f Makefile.openocd linux.easy.permutations - -linux.ftd2xx_installed: - ${MAKE} remove.install - ${MAKE} linux.ftd2xx_installed.setup - ${MAKE} -f Makefile.openocd $@ - - linux.ft2232_libftdi: - ${MAKE} remove.install - ${MAKE} -f Makefile.libusb all - ${MAKE} -f Makefile.confuse all - ${MAKE} -f Makefile.libftdi all - ${MAKE} -f Makefile.openocd $@ - -# This target is used to "install" files from -# the FTDICHIP.COM tar.gz unpack directory -# into "a proper place" - where they should be found. -linux.ftd2xx_installed.setup: - mkdir -p ${INSTALL_DIR}/include - mkdir -p ${EXEC_PREFIX}/lib - @# - @# Sanity check - make sure the .H file is findable - @# - @f=$(FTD2XX_LINUX_DIR)/ftd2xx.h && \ - test -f $$f || (echo "Error: $$f not found" ; exit 1) - @# - @# Header files are simple... just copy them. - @# - cp $(FTD2XX_LINUX_DIR)/ftd2xx.h $(PREFIX)/include/. - cp $(FTD2XX_LINUX_DIR)/WinTypes.h $(PREFIX)/include/. - @# - @# .SO files are harder. - @# (1) copy them, (2) make links - @# - cp $(FTD2XX_LINUX_DIR)/libftd2xx.so.$(FTD2XX_LINUX_VERSION) $(EXEC_PREFIX)/lib/. - cd $(EXEC_PREFIX)/lib && rm -f libftd2xx.so.0 - cd $(EXEC_PREFIX)/lib && ln -s libftd2xx.so.$(FTD2XX_LINUX_VERSION) libftd2xx.so.0 - cd $(EXEC_PREFIX)/lib && rm -f libftd2xx.so - cd $(EXEC_PREFIX)/lib && ln -s libftd2xx.so.$(FTD2XX_LINUX_VERSION) libftd2xx.so - - -all.download: - mkdir -p ${VIRGINS} - ${MAKE} -f Makefile.confuse download - ${MAKE} -f Makefile.libftdi download - ${MAKE} -f Makefile.ftd2xx download - ${MAKE} -f Makefile.libusb download - -.PHONY: linux.buildtest \ - linux.easy.buildtest \ - linux.ftd2xx_installed \ - linux.ft22232_libftdi \ - linux.ftd2xx_installed.setup diff --git a/testing/build.test1/Makefile.confuse b/testing/build.test1/Makefile.confuse deleted file mode 100644 index 9d5a0673f..000000000 --- a/testing/build.test1/Makefile.confuse +++ /dev/null @@ -1,46 +0,0 @@ -# -*- mode: makefile -*- -default: _complain_ -include ./local.uses - -TARFILE_LOCAL=${VIRGINS}/confuse-${LIBCONFUSE_VERSION}.tar.gz -TARFILE_URL =http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/confuse-${LIBCONFUSE_VERSION}.tar.gz - -CONFUSE_SRC_DIR =${HERE}/confuse-${LIBCONFUSE_VERSION} -CONFUSE_BUILD_DIR =${HERE}/confuse-build - -download: - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -unpack: - rm -rf ${CONFUSE_SRC_DIR} - tar xfz ${TARFILE_LOCAL} - -clean:: - rm -rf ${CONFUSE_SRC_DIR} - -configure: - rm -rf ${CONFUSE_BUILD_DIR} - mkdir ${CONFUSE_BUILD_DIR} - cd ${CONFUSE_BUILD_DIR} && ${CONFUSE_SRC_DIR}/configure \ - --prefix=${PREFIX} \ - --exec-prefix=${EXEC_PREFIX} - -clean:: - rm -rf ${CONFUSE_BUILD_DIR} - -build: - cd ${CONFUSE_BUILD_DIR} && ${MAKE} - -install: - cd ${CONFUSE_BUILD_DIR} && ${MAKE} install - -all: unpack configure build install - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.ftd2xx b/testing/build.test1/Makefile.ftd2xx deleted file mode 100644 index 3f19e7720..000000000 --- a/testing/build.test1/Makefile.ftd2xx +++ /dev/null @@ -1,88 +0,0 @@ -# -*- mode: makefile -*- -# -default: _complain_ - -include ./local.uses - -# WARNING... the file on the ftdi chip site has a SPACE in the filename GRRR!!! -# We fix that with the "-O" option to wget. -ZIPFILE_LOCAL=${VIRGINS}/cdm.${FTD2XX_WIN32_VERSION}.zip -ZIPFILE_URL ="http://www.ftdichip.com/Drivers/CDM/CDM ${FTD2XX_WIN32_VERSION}.zip" - -TARFILE_LOCAL=${VIRGINS}/libftd2xx${FTD2XX_LINUX_VERSION}.tar.gz -TARFILE_URL =http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx${FTD2XX_LINUX_VERSION}.tar.gz - -TARFILE_64_LOCAL=${VIRGINS}/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64.tar.gz -TARFILE_64_URL =http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64.tar.gz - - -download.win32: - mkdir -p ${VIRGINS} - wget -O ${ZIPFILE_LOCAL} ${ZIPFILE_URL} - -unpack.win32: - rm -rf ${FTD2XX_WIN32_DIR} - mkdir -p ${FTD2XX_WIN32_DIR} - cd ${FTD2XX_WIN32_DIR} && unzip ${ZIPFILE_LOCAL} - -clean:: - rm -rf ${FTD2XX_WIN32_DIR} - -download.linux: - mkdir -p ${VIRGINS} - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -clean:: - rm -rf ${FTD2XX_LINUX_DIR} - -unpack.linux: - rm -rf ${FTD2XX_LINUX_DIR} - mkdir -p ${FTD2XX_LINUX_DIR} - tar xfz ${TARFILE_LOCAL} - -download.linux.x86_64: - mkdir -p ${VIRGINS} - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -unpack.linux.x86_64: - rm -rf ${FTD2XX_LINUX_64_DIR} - mkdir -p ${FTD2XX_LINUX_64_DIR} - tar xfz ${TARFILE_64_LOCAL} - -clean:: - rm -rf ${FTD2XX_LINUX_64_DIR} - -download: download.win32 download.linux - -unpack.cygwin unpack.mingw32: unpack.win32 - -unpack: unpack.${BUILD_SYSNAME} - -# Nothing to do here -build: - @echo "Done" - -#Nothing to do here -configure: - @echo "Done" - -# Nothing to do here -install: - @echo "Done" - -all: unpack configure build install - -.PHONY: install - -# Nothing to do here -clean:: - @echo "Done" - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.libftdi b/testing/build.test1/Makefile.libftdi deleted file mode 100644 index 1a9612c05..000000000 --- a/testing/build.test1/Makefile.libftdi +++ /dev/null @@ -1,51 +0,0 @@ -# -*- mode: makefile -*- -default: _complain_ -include ./local.uses - -TARFILE_LOCAL = ${VIRGINS}/libftdi-${LIBFTDI_VERSION}.tar.gz -TARFILE_URL = http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/libftdi-${LIBFTDI_VERSION}.tar.gz - -LIBFTDI_SRC_DIR = ${HERE}/libftdi-${LIBFTDI_VERSION} -LIBFTDI_BUILD_DIR= ${HERE}/libftdi-build - -download: - mkdir -p virgins - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -clean:: - rm -rf ${LIBFTDI_SRC_DIR} - -unpack: - tar xf ${TARFILE_LOCAL} - -PATH := ${EXEC_PREFIX}/bin:${PATH} -export PATH - -clean:: - rm -rf ${LIBFTDI_BUILD_DIR} - -configure: - rm -rf ${LIBFTDI_BUILD_DIR} - mkdir -p ${LIBFTDI_BUILD_DIR} - cd ${LIBFTDI_BUILD_DIR} && ${LIBFTDI_SRC_DIR}/configure \ - --prefix=${PREFIX} \ - --exec-prefix=${EXEC_PREFIX} - -build: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} - -install: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} install - -all: unpack configure build install - -.PHONY: install - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.libusb b/testing/build.test1/Makefile.libusb deleted file mode 100644 index 815592a18..000000000 --- a/testing/build.test1/Makefile.libusb +++ /dev/null @@ -1,55 +0,0 @@ -# -*- mode: makefile -*- -default: _complain_ - -include ./local.uses - -ifeq (x"$BUILD_SYSNAME",x"cygwin") -$(error Please use the Win32 specific port of LibUSB not the Unix version) -endif -ifeq (x"$BUILD_SYSNAME",x"mingw32") -$(error Please use the win32 specific port of LibUSB not the Unix version) -endif - -TARFILE_LOCAL = ${VIRGINS}/libusb-${LIBUSB_VERSION_linux}.tar.bz2 -TARFILE_URL = http://downloads.sourceforge.net/libusb/libusb-${LIBUSB_VERSION_linux}.tar.gz - -LIBUSB_SRC_DIR = ${HERE}/libusb-${LIBUSB_VERSION} -LIBUSB_BUILD_DIR = ${HERE}/libusb-build - -download: - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -unpack: - rm -rf ${LIBUSB_SRC_DIR} - tar xfz ${TARFILE_LOCAL} - -clean:: - rm -rf ${LIBUSB_SRC_DIR} - -configure: - rm -rf ${LIBUSB_BUILD_DIR} - mkdir -p ${LIBUSB_BUILD_DIR} - cd ${LIBUSB_BUILD_DIR} && ${LIBUSB_SRC_DIR}/configure \ - --prefix=${PREFIX} --exec-prefix=${EXEC_PREFIX} - -clean:: - rm -rf ${LIBUSB_BUILD_DIR} - -build: - cd ${LIBUSB_BUILD_DIR} && ${MAKE} - -install: - cd ${LIBUSB_BUILD_DIR} && ${MAKE} install - -all: unpack configure build install - -.PHONY: install - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.openocd b/testing/build.test1/Makefile.openocd deleted file mode 100644 index 6b0cb56ff..000000000 --- a/testing/build.test1/Makefile.openocd +++ /dev/null @@ -1,193 +0,0 @@ -# -*- mode: makefile -*- -# -default: _complain_ - -include ./local.uses - - -SRC_DIR ?= $(HERE)/openocd -BUILD_SUFFIX ?= $(BUILD_MACHINE) -BUILD_DIR =$(HERE)/openocd.$(BUILD_SUFFIX) - -checkout: - svn co https://svn.berlios.de/svnroot/repos/openocd/trunk openocd - -remove.install: - rm -rf ${INSTALL_DIR} - -#======================================== -# Win32 Build Permutations -# none -# parport -# ftd2xx - (ftdichip) -# libftd -CONFIG_OPTIONS_win32_none = -CONFIG_OPTIONS_win32_parport = --enable-parport -CONFIG_OPTIONS_win32_ftd2xx = --enable-parport --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=$(FTD2XX_WIN32_DIR) - -CYGWIN_EASY_PERMUTATIONS += none -CYGWIN_EASY_PERMUTATIONS += parport -CYGWIN_EASY_PERMUTATIONS += ftd2xx - -MINGW32_EASY_PERMUTATIONS += none -MINGW32_EASY_PERMUTATIONS += parport -MINGW32_EASY_PERMUTATIONS += ftd2xx - - -# This is not a possible permutation, it is manual :-( -# Why? Because "libftdi" installs things into install/include -# which would efect the 'ftd2xx' win32 build -CONFIG_OPTIONS_win32_libftdi = --enable-parport --enable-ft2232_libftdi - -# Default build for win32... is the ftd2xx type build. -PERMUTE_win32 ?= ftd2xx -CONFIG_OPTIONS_win32 ?= $(CONFIG_OPTIONS_win32_$(PERMUTE_win32)) -CONFIG_OPTIONS_cygwin = $(CONFIG_OPTIONS_win32) -CONFIG_OPTIONS_mingw32 = $(CONFIG_OPTIONS_win32) - -#======================================== -# Linux Build Permuatations -# none -# parport -# ft2232_ftd2xx -# ft2232_libftdi -CONFIG_OPTIONS_linux_none = -LINUX_EASY_PERMUTATIONS += none - -CONFIG_OPTIONS_linux_parport = --enable-parport -LINUX_EASY_PERMUTATIONS += parport - -CONFIG_OPTIONS_linux_ft2232_libftdi = --enable-parport --enable-ft2232-libftdi -#this cannot be done as part of the permutations. -#LINUX_EASY_PERMUTATIONS += ft2232_libftdi - -CONFIG_OPTIONS_linux_ft2232_ftd2xx_static = \ - --enable-parport \ - --enable-ft2232-ftd2xx --with-ftd2xx-lib=static --with-ftd2xx-linux-tardir=$(FTD2XX_LINUX_DIR) -LINUX_EASY_PERMUTATIONS += ft2232_ftd2xx_static - -# this is not a possible permutation it is manual :-( -# why? because it interfers with the other permutations -# by "installing files" in the $(INSTALL_DIR) -CONFIG_OPTIONS_linux_ftd2xx_installed = \ - --enable-parport \ - --enable-ft2232-ftd2xx \ - --with-ftd2xx-lib=shared - -# The default build permutation is -PERMUTE_linux ?= ft2232_ftd2xx_static -CONFIG_OPTIONS_linux = $(CONFIG_OPTIONS_linux_$(PERMUTE_linux)) - -CONFIG_OPTIONS_darwin=\ - --enable-ftd2232-libftdi - -# Which build are we doing? -CONFIG_OPTIONS := $(CONFIG_OPTIONS_$(BUILD_SYSNAME)) - -bootstrap: - cd $(SRC_DIR) && bash ./bootstrap - -clean:: - rm -rf $(BUILD_DIR) - -ifndef CFLAGS -_CFLAGS=true -else -_CFLAGS=export CFLAGS="${CFLAGS}" -endif - - -# if this was given... then pass it on -configure: - @echo " Build Sysname: $(BUILD_SYSNAME)" - @echo " Config Options: $(CONFIG_OPTIONS)" - rm -rf $(BUILD_DIR) - mkdir $(BUILD_DIR) - ${_CFLAGS} && \ - cd $(BUILD_DIR) && \ - $(SRC_DIR)/configure \ - --prefix=$(PREFIX) \ - --exec-prefix=$(EXEC_PREFIX) \ - $(CONFIG_OPTIONS) - -build: - cd $(BUILD_DIR) && $(MAKE) - -install: - cd $(BUILD_DIR) && $(MAKE) install - -all: configure build install - -.PHONY: install - -# The "cygwin.libftdi" requires that libftdi be built -# and installed *PRIOR* to running this target. -# it is not part of the permutations because ... -# it interfers with the ftd2xx based builds -cygwin.libftdi: - $(MAKE) -f Makefile.openocd bootstrap - $(MAKE) BUILD_SUFFIX=$@ PERMUTE_win32=libftdi -f Makefile.openocd all - -cygwin.easy.permutations: remove.install ${CYGWIN_EASY_PERMUTATIONS:%=_cygwin.%} - -_cygwin.%: - @echo "" - @echo "" - @echo "========================================" - @echo "Permutation Build... $@" - @echo "========================================" - @echo "" - @echo "" - $(MAKE) PERMUTE_win32=$* BUILD_SUFFIX=cygwin.$* -f Makefile.openocd all - $(EXEC_PREFIX)/bin/openocd -v - -mingw32.easy.permutations: remove.install ${MINGW32_EASY_PERMUTATIONS:%=_mingw32.%} - -# I (duane) build openocd-mingw32 via Cygwin. -# Sadly, the "mingw32" buid for cygwin does not include -# the required "elf.h" header files... so ... -# we have them in our own private helper place. -_mingw32.%: - @echo "" - @echo "" - @echo "========================================" - @echo "Permutation Build... $@" - @echo "========================================" - @echo "" - @echo "" - CFLAGS="-mno-cygwin -I$(HERE)/mingw32_help/include" \ - $(MAKE) -f Makefile.openocd all ;\ - $(EXEC_PREFIX)/bin/openocd -v - -win32.permutations: mingw32.permutations cygwin.permutations - - -# SMOKE TEST - Build every linux permuation... -# If "openocd -v" does exit(0) we are good enough. - -linux.easy.permutations: remove.install ${LINUX_EASY_PERMUTATIONS:%=_linux.%} - - -_linux.%: - @echo "" - @echo "" - @echo "========================================" - @echo "Permutation Build... $@" - @echo "========================================" - @echo "" - @echo "" - $(MAKE) PERMUTE_linux=$* BUILD_SUFFIX=linux.$* -f Makefile.openocd all - $(EXEC_PREFIX)/bin/openocd -v - -linux.ftd2xx_installed: - ${MAKE} -f Makefile.openocd _$@ - -linux.ft2232_libftdi: - ${MAKE} -f Makefile.openocd _$@ - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @exit 1 diff --git a/testing/build.test1/README.TXT b/testing/build.test1/README.TXT deleted file mode 100644 index 7f4d401e8..000000000 --- a/testing/build.test1/README.TXT +++ /dev/null @@ -1,38 +0,0 @@ --- Duane Ellis'es test case for building numerous openocd configurations... -Dec 26,2008 ---------------------------------------------------------------------------- - -1) Make a directory some where.. - - mkdir ~/test - -2) Change to that directory - - cd ~/test - -3) Checkout OpenOCD in that directory. - - cd ~/test - svn co https://svn.berlios.de/svnroot/repos/openocd/trunk openocd - -4) Copy the "build.test1" directory to the "~/work" directory. - - - cd ~/test - cp ~/openocd/testing/build.test1/. ~/test/. - -5) If needed, download various components. - - cd ~/work - make all.download - - -6) For Linux - type: - - cd ~/work - make linux.buildtest - -7) For Cygwin - type: - - cd ~/work - make cygwin.buildtest diff --git a/testing/build.test1/local.uses b/testing/build.test1/local.uses deleted file mode 100644 index 6c6795b54..000000000 --- a/testing/build.test1/local.uses +++ /dev/null @@ -1,39 +0,0 @@ -# -*- mode: makefile -*- -HERE := $(shell pwd) - -# Solve problems on systems with DASH.. Grrr... -SHELL=/bin/bash -export SHELL - -VIRGINS=${HERE}/virgins - -# Determine the build platform. -BUILD_SYSNAME_Linux =linux -BUILD_SYSNAME_linux =linux -BUILD_SYSNAME_CYGWIN_NT =cygwin -BUILD_SYSNAME_MINGW32_NT =mingw32 -BUILD_SYSNAME_Darwin =darwin -BUILD_SYSNAME_darwin =darwin -BUILD_SYSNAME :=$(BUILD_SYSNAME_$(shell uname --sysname | cut -d'-' -f1)) - -# And machine (ie: i686, x86_64, or what) -BUILD_MACHINE :=$(BUILD_SYSNAME).$(shell uname -m) - - -INSTALL_DIR := $(HERE)/install -PREFIX := ${INSTALL_DIR} -EXEC_PREFIX := ${INSTALL_DIR}/${BUILD_MACHINE} - -LIBFTDI_VERSION=0.14 -LIBCONFUSE_VERSION=2.5 - -LIBUSB_VERSION_linux=0.1.12 - -LIBUSB_VERSION=${LIBUSB_VERSION_${BUILD_SYSNAME}} - -FTD2XX_WIN32_VERSION=2.04.14 -FTD2XX_WIN32_DIR = ${HERE}/ftd2xx.win32 - -FTD2XX_LINUX_VERSION=0.4.16 -FTD2XX_LINUX_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION} -FTD2XX_LINUX_64_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64 diff --git a/testing/build.test1/mingw32_help/include/elf.h b/testing/build.test1/mingw32_help/include/elf.h deleted file mode 100644 index 23d4aa2d5..000000000 --- a/testing/build.test1/mingw32_help/include/elf.h +++ /dev/null @@ -1,38 +0,0 @@ -/* elf.h - - Copyright 2005 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#ifndef _ELF_H_ -#define _ELF_H_ - -#include - -typedef signed char int8_t; -typedef unsigned char u_int8_t; -typedef short int16_t; -typedef unsigned short u_int16_t; -typedef int int32_t; -typedef unsigned int u_int32_t; -typedef long long int64_t; -typedef unsigned long long u_int64_t; -typedef int32_t register_t; - - -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -#include -#include -#ifdef __cplusplus -} -#endif - -#endif /*_ELF_H_*/ diff --git a/testing/build.test1/mingw32_help/include/sys/cdefs.h b/testing/build.test1/mingw32_help/include/sys/cdefs.h deleted file mode 100644 index 606205a58..000000000 --- a/testing/build.test1/mingw32_help/include/sys/cdefs.h +++ /dev/null @@ -1,22 +0,0 @@ -/* sys/cdefs.h - - Copyright 1998, 2000, 2001 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#ifndef _SYS_CDEFS_H -#define _SYS_CDEFS_H -#ifdef __cplusplus -#define __BEGIN_DECLS extern "C" { -#define __END_DECLS } -#else -#define __BEGIN_DECLS -#define __END_DECLS -#endif -#define __P(protos) protos /* full-blown ANSI C */ -#define __CONCAT(__x,__y) __x##__y -#endif diff --git a/testing/build.test1/mingw32_help/include/sys/elf32.h b/testing/build.test1/mingw32_help/include/sys/elf32.h deleted file mode 100644 index 5dfe9c8b0..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf32.h +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf32.h,v 1.8 2002/05/30 08:32:18 dfr Exp $ - */ - -#ifndef _SYS_ELF32_H_ -#define _SYS_ELF32_H_ 1 - -#include - -/* - * ELF definitions common to all 32-bit architectures. - */ - -typedef u_int32_t Elf32_Addr; -typedef u_int16_t Elf32_Half; -typedef u_int32_t Elf32_Off; -typedef int32_t Elf32_Sword; -typedef u_int32_t Elf32_Word; -typedef u_int32_t Elf32_Size; -typedef Elf32_Off Elf32_Hashelt; - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf32_Half e_type; /* File type. */ - Elf32_Half e_machine; /* Machine architecture. */ - Elf32_Word e_version; /* ELF format version. */ - Elf32_Addr e_entry; /* Entry point. */ - Elf32_Off e_phoff; /* Program header file offset. */ - Elf32_Off e_shoff; /* Section header file offset. */ - Elf32_Word e_flags; /* Architecture-specific flags. */ - Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf32_Half e_phentsize; /* Size of program header entry. */ - Elf32_Half e_phnum; /* Number of program header entries. */ - Elf32_Half e_shentsize; /* Size of section header entry. */ - Elf32_Half e_shnum; /* Number of section header entries. */ - Elf32_Half e_shstrndx; /* Section name strings section. */ -} Elf32_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf32_Word sh_name; /* Section name (index into the - section header string table). */ - Elf32_Word sh_type; /* Section type. */ - Elf32_Word sh_flags; /* Section flags. */ - Elf32_Addr sh_addr; /* Address in memory image. */ - Elf32_Off sh_offset; /* Offset in file. */ - Elf32_Size sh_size; /* Size in bytes. */ - Elf32_Word sh_link; /* Index of a related section. */ - Elf32_Word sh_info; /* Depends on section type. */ - Elf32_Size sh_addralign; /* Alignment in bytes. */ - Elf32_Size sh_entsize; /* Size of each entry in section. */ -} Elf32_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf32_Word p_type; /* Entry type. */ - Elf32_Off p_offset; /* File offset of contents. */ - Elf32_Addr p_vaddr; /* Virtual address in memory image. */ - Elf32_Addr p_paddr; /* Physical address (not used). */ - Elf32_Size p_filesz; /* Size of contents in file. */ - Elf32_Size p_memsz; /* Size of contents in memory. */ - Elf32_Word p_flags; /* Access permission flags. */ - Elf32_Size p_align; /* Alignment in memory and file. */ -} Elf32_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf32_Sword d_tag; /* Entry type. */ - union { - Elf32_Size d_val; /* Integer value. */ - Elf32_Addr d_ptr; /* Address value. */ - } d_un; -} Elf32_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ -} Elf32_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ - Elf32_Sword r_addend; /* Addend. */ -} Elf32_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF32_R_SYM(info) ((info) >> 8) -#define ELF32_R_TYPE(info) ((unsigned char)(info)) - -/* Macro for constructing r_info from field values. */ -#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) - -/* - * Symbol table entries. - */ - -typedef struct { - Elf32_Word st_name; /* String table index of name. */ - Elf32_Addr st_value; /* Symbol value. */ - Elf32_Size st_size; /* Size of associated object. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf32_Half st_shndx; /* Section index of symbol. */ -} Elf32_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF32_ST_BIND(info) ((info) >> 4) -#define ELF32_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -#endif /* !_SYS_ELF32_H_ */ diff --git a/testing/build.test1/mingw32_help/include/sys/elf64.h b/testing/build.test1/mingw32_help/include/sys/elf64.h deleted file mode 100644 index 48556be5f..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf64.h +++ /dev/null @@ -1,172 +0,0 @@ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf64.h,v 1.10 2002/05/30 08:32:18 dfr Exp $ - */ - -#ifndef _SYS_ELF64_H_ -#define _SYS_ELF64_H_ 1 - -#include - -/* - * ELF definitions common to all 64-bit architectures. - */ - -typedef uint64_t Elf64_Addr; -typedef uint16_t Elf64_Half; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Off; -typedef uint16_t Elf64_Section; -typedef Elf64_Half Elf64_Versym; -typedef uint16_t Elf64_Quarter; - -/* - * Types of dynamic symbol hash table bucket and chain elements. - * - * This is inconsistent among 64 bit architectures, so a machine dependent - * typedef is required. - */ - -#ifdef __alpha__ -typedef Elf64_Off Elf64_Hashelt; -#else -typedef Elf64_Half Elf64_Hashelt; -#endif - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf64_Half e_type; /* File type. */ - Elf64_Half e_machine; /* Machine architecture. */ - Elf64_Word e_version; /* ELF format version. */ - Elf64_Addr e_entry; /* Entry point. */ - Elf64_Off e_phoff; /* Program header file offset. */ - Elf64_Off e_shoff; /* Section header file offset. */ - Elf64_Word e_flags; /* Architecture-specific flags. */ - Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf64_Half e_phentsize; /* Size of program header entry. */ - Elf64_Half e_phnum; /* Number of program header entries. */ - Elf64_Half e_shentsize; /* Size of section header entry. */ - Elf64_Half e_shnum; /* Number of section header entries. */ - Elf64_Half e_shstrndx; /* Section name strings section. */ -} Elf64_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf64_Word sh_name; /* Section name (index into the - section header string table). */ - Elf64_Word sh_type; /* Section type. */ - Elf64_Xword sh_flags; /* Section flags. */ - Elf64_Addr sh_addr; /* Address in memory image. */ - Elf64_Off sh_offset; /* Offset in file. */ - Elf64_Xword sh_size; /* Size in bytes. */ - Elf64_Word sh_link; /* Index of a related section. */ - Elf64_Word sh_info; /* Depends on section type. */ - Elf64_Xword sh_addralign; /* Alignment in bytes. */ - Elf64_Xword sh_entsize; /* Size of each entry in section. */ -} Elf64_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf64_Word p_type; /* Entry type. */ - Elf64_Word p_flags; /* Access permission flags. */ - Elf64_Off p_offset; /* File offset of contents. */ - Elf64_Addr p_vaddr; /* Virtual address in memory image. */ - Elf64_Addr p_paddr; /* Physical address (not used). */ - Elf64_Xword p_filesz; /* Size of contents in file. */ - Elf64_Xword p_memsz; /* Size of contents in memory. */ - Elf64_Xword p_align; /* Alignment in memory and file. */ -} Elf64_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf64_Sxword d_tag; /* Entry type. */ - union { - Elf64_Xword d_val; /* Integer value. */ - Elf64_Addr d_ptr; /* Address value. */ - } d_un; -} Elf64_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ -} Elf64_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ - Elf64_Sxword r_addend; /* Addend. */ -} Elf64_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF64_R_SYM(info) ((info) >> 32) -#define ELF64_R_TYPE(info) ((unsigned char)(info)) - -/* Macro for constructing r_info from field values. */ -#define ELF64_R_INFO(sym, type) (((sym) << 32) + (unsigned char)(type)) - -/* - * Symbol table entries. - */ - -typedef struct { - Elf64_Word st_name; /* String table index of name. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf64_Section st_shndx; /* Section index of symbol. */ - Elf64_Addr st_value; /* Symbol value. */ - Elf64_Xword st_size; /* Size of associated object. */ -} Elf64_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF64_ST_BIND(info) ((info) >> 4) -#define ELF64_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -#endif /* !_SYS_ELF64_H_ */ diff --git a/testing/build.test1/mingw32_help/include/sys/elf_common.h b/testing/build.test1/mingw32_help/include/sys/elf_common.h deleted file mode 100644 index b864f0464..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf_common.h +++ /dev/null @@ -1,299 +0,0 @@ -/*- - * Copyright (c) 1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf_common.h,v 1.15 2004/05/05 02:38:54 marcel Exp $ - */ - -#ifndef _SYS_ELF_COMMON_H_ -#define _SYS_ELF_COMMON_H_ 1 - -/* - * ELF definitions that are independent of architecture or word size. - */ - -/* - * Note header. The ".note" section contains an array of notes. Each - * begins with this header, aligned to a word boundary. Immediately - * following the note header is n_namesz bytes of name, padded to the - * next word boundary. Then comes n_descsz bytes of descriptor, again - * padded to a word boundary. The values of n_namesz and n_descsz do - * not include the padding. - */ - -typedef struct { - u_int32_t n_namesz; /* Length of name. */ - u_int32_t n_descsz; /* Length of descriptor. */ - u_int32_t n_type; /* Type of this note. */ -} Elf_Note; - -/* Indexes into the e_ident array. Keep synced with - http://www.sco.com/developer/gabi/ch4.eheader.html */ -#define EI_MAG0 0 /* Magic number, byte 0. */ -#define EI_MAG1 1 /* Magic number, byte 1. */ -#define EI_MAG2 2 /* Magic number, byte 2. */ -#define EI_MAG3 3 /* Magic number, byte 3. */ -#define EI_CLASS 4 /* Class of machine. */ -#define EI_DATA 5 /* Data format. */ -#define EI_VERSION 6 /* ELF format version. */ -#define EI_OSABI 7 /* Operating system / ABI identification */ -#define EI_ABIVERSION 8 /* ABI version */ -#define OLD_EI_BRAND 8 /* Start of architecture identification. */ -#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ -#define EI_NIDENT 16 /* Size of e_ident array. */ - -/* Values for the magic number bytes. */ -#define ELFMAG0 0x7f -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" /* magic string */ -#define SELFMAG 4 /* magic string size */ - -/* Values for e_ident[EI_VERSION] and e_version. */ -#define EV_NONE 0 -#define EV_CURRENT 1 - -/* Values for e_ident[EI_CLASS]. */ -#define ELFCLASSNONE 0 /* Unknown class. */ -#define ELFCLASS32 1 /* 32-bit architecture. */ -#define ELFCLASS64 2 /* 64-bit architecture. */ - -/* Values for e_ident[EI_DATA]. */ -#define ELFDATANONE 0 /* Unknown data format. */ -#define ELFDATA2LSB 1 /* 2's complement little-endian. */ -#define ELFDATA2MSB 2 /* 2's complement big-endian. */ - -/* Values for e_ident[EI_OSABI]. */ -#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ -#define ELFOSABI_NONE ELFOSABI_SYSV /* symbol used in old spec */ -#define ELFOSABI_HPUX 1 /* HP-UX operating system */ -#define ELFOSABI_NETBSD 2 /* NetBSD */ -#define ELFOSABI_LINUX 3 /* GNU/Linux */ -#define ELFOSABI_HURD 4 /* GNU/Hurd */ -#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ -#define ELFOSABI_SOLARIS 6 /* Solaris */ -#define ELFOSABI_MONTEREY 7 /* Monterey */ -#define ELFOSABI_IRIX 8 /* IRIX */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD */ -#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -/* e_ident */ -#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ - (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ - (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ - (ehdr).e_ident[EI_MAG3] == ELFMAG3) - -/* Values for e_type. */ -#define ET_NONE 0 /* Unknown type. */ -#define ET_REL 1 /* Relocatable. */ -#define ET_EXEC 2 /* Executable. */ -#define ET_DYN 3 /* Shared object. */ -#define ET_CORE 4 /* Core file. */ - -/* Values for e_machine. */ -#define EM_NONE 0 /* Unknown machine. */ -#define EM_M32 1 /* AT&T WE32100. */ -#define EM_SPARC 2 /* Sun SPARC. */ -#define EM_386 3 /* Intel i386. */ -#define EM_68K 4 /* Motorola 68000. */ -#define EM_88K 5 /* Motorola 88000. */ -#define EM_486 6 /* Intel i486. */ -#define EM_860 7 /* Intel i860. */ -#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ - -/* Extensions. This list is not complete. */ -#define EM_S370 9 /* IBM System/370 */ -#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ /* Depreciated */ -#define EM_PARISC 15 /* HPPA */ -#define EM_SPARC32PLUS 18 /* SPARC v8plus */ -#define EM_PPC 20 /* PowerPC 32-bit */ -#define EM_PPC64 21 /* PowerPC 64-bit */ -#define EM_ARM 40 /* ARM */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_IA_64 50 /* Intel IA-64 Processor */ -#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ -#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI */ - -/* Special section indexes. */ -#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ -#define SHN_LORESERVE 0xff00 /* First of reserved range. */ -#define SHN_LOPROC 0xff00 /* First processor-specific. */ -#define SHN_HIPROC 0xff1f /* Last processor-specific. */ -#define SHN_ABS 0xfff1 /* Absolute values. */ -#define SHN_COMMON 0xfff2 /* Common data. */ -#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ - -/* sh_type */ -#define SHT_NULL 0 /* inactive */ -#define SHT_PROGBITS 1 /* program defined information */ -#define SHT_SYMTAB 2 /* symbol table section */ -#define SHT_STRTAB 3 /* string table section */ -#define SHT_RELA 4 /* relocation section with addends */ -#define SHT_HASH 5 /* symbol hash table section */ -#define SHT_DYNAMIC 6 /* dynamic section */ -#define SHT_NOTE 7 /* note section */ -#define SHT_NOBITS 8 /* no space section */ -#define SHT_REL 9 /* relocation section - no addends */ -#define SHT_SHLIB 10 /* reserved - purpose unknown */ -#define SHT_DYNSYM 11 /* dynamic symbol table section */ -#define SHT_NUM 12 /* number of section types */ -#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ -#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ -#define SHT_LOPROC 0x70000000 /* reserved range for processor */ -#define SHT_HIPROC 0x7fffffff /* specific section header types */ -#define SHT_LOUSER 0x80000000 /* reserved range for application */ -#define SHT_HIUSER 0xffffffff /* specific indexes */ - -/* Flags for sh_flags. */ -#define SHF_WRITE 0x1 /* Section contains writable data. */ -#define SHF_ALLOC 0x2 /* Section occupies memory. */ -#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ -#define SHF_TLS 0x400 /* Section contains TLS data. */ -#define SHF_MASKPROC 0xf0000000 /* Reserved for processor-specific. */ - -/* Values for p_type. */ -#define PT_NULL 0 /* Unused entry. */ -#define PT_LOAD 1 /* Loadable segment. */ -#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ -#define PT_INTERP 3 /* Pathname of interpreter. */ -#define PT_NOTE 4 /* Auxiliary information. */ -#define PT_SHLIB 5 /* Reserved (not used). */ -#define PT_PHDR 6 /* Location of program header itself. */ -#define PT_TLS 7 /* Thread local storage segment */ - -#define PT_COUNT 8 /* Number of defined p_type values. */ - -#define PT_LOOS 0x60000000 /* OS-specific */ -#define PT_HIOS 0x6fffffff /* OS-specific */ -#define PT_LOPROC 0x70000000 /* First processor-specific type. */ -#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for p_flags. */ -#define PF_X 0x1 /* Executable. */ -#define PF_W 0x2 /* Writable. */ -#define PF_R 0x4 /* Readable. */ - -/* Values for d_tag. */ -#define DT_NULL 0 /* Terminating entry. */ -#define DT_NEEDED 1 /* String table offset of a needed shared - library. */ -#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ -#define DT_PLTGOT 3 /* Processor-dependent address. */ -#define DT_HASH 4 /* Address of symbol hash table. */ -#define DT_STRTAB 5 /* Address of string table. */ -#define DT_SYMTAB 6 /* Address of symbol table. */ -#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ -#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ -#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ -#define DT_STRSZ 10 /* Size of string table. */ -#define DT_SYMENT 11 /* Size of each symbol table entry. */ -#define DT_INIT 12 /* Address of initialization function. */ -#define DT_FINI 13 /* Address of finalization function. */ -#define DT_SONAME 14 /* String table offset of shared object - name. */ -#define DT_RPATH 15 /* String table offset of library path. [sup] */ -#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ -#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ -#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ -#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ -#define DT_PLTREL 20 /* Type of relocation used for PLT. */ -#define DT_DEBUG 21 /* Reserved (not used). */ -#define DT_TEXTREL 22 /* Indicates there may be relocations in - non-writable segments. [sup] */ -#define DT_JMPREL 23 /* Address of PLT relocations. */ -#define DT_BIND_NOW 24 /* [sup] */ -#define DT_INIT_ARRAY 25 /* Address of the array of pointers to - initialization functions */ -#define DT_FINI_ARRAY 26 /* Address of the array of pointers to - termination functions */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of - initialization functions. */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of - terminationfunctions. */ -#define DT_RUNPATH 29 /* String table offset of a null-terminated - library search path string. */ -#define DT_FLAGS 30 /* Object specific flag values. */ -#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING - and less than DT_LOOS follow the rules for - the interpretation of the d_un union - as follows: even == 'd_ptr', even == 'd_val' - or none */ -#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to - pre-initialization functions. */ -#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of - pre-initialization functions. */ - -#define DT_COUNT 33 /* Number of defined d_tag values. */ - -#define DT_LOOS 0x6000000d /* First OS-specific */ -#define DT_HIOS 0x6fff0000 /* Last OS-specific */ -#define DT_LOPROC 0x70000000 /* First processor-specific type. */ -#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for DT_FLAGS */ -#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may - make reference to the $ORIGIN substitution - string */ -#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ -#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in - non-writable segments. */ -#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should - process all relocations for the object - containing this entry before transferring - control to the program. */ -#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or - executable contains code using a static - thread-local storage scheme. */ - -/* Values for n_type. Used in core files. */ -#define NT_PRSTATUS 1 /* Process status. */ -#define NT_FPREGSET 2 /* Floating point registers. */ -#define NT_PRPSINFO 3 /* Process state info. */ - -/* Symbol Binding - ELFNN_ST_BIND - st_info */ -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* like global - lower precedence */ -#define STB_LOPROC 13 /* reserved range for processor */ -#define STB_HIPROC 15 /* specific symbol bindings */ - -/* Symbol type - ELFNN_ST_TYPE - st_info */ -#define STT_NOTYPE 0 /* Unspecified type. */ -#define STT_OBJECT 1 /* Data object. */ -#define STT_FUNC 2 /* Function. */ -#define STT_SECTION 3 /* Section. */ -#define STT_FILE 4 /* Source file. */ -#define STT_TLS 6 /* TLS object. */ -#define STT_LOPROC 13 /* reserved range for processor */ -#define STT_HIPROC 15 /* specific symbol types */ - -/* Special symbol table indexes. */ -#define STN_UNDEF 0 /* Undefined symbol index. */ - -#endif /* !_SYS_ELF_COMMON_H_ */ diff --git a/testing/build.test1/mingw32_help/include/sys/elf_generic.h b/testing/build.test1/mingw32_help/include/sys/elf_generic.h deleted file mode 100644 index dbe9f1e83..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf_generic.h +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (c) 1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf_generic.h,v 1.6 2002/07/20 02:56:11 peter Exp $ - */ - -#ifndef _SYS_ELF_GENERIC_H_ -#define _SYS_ELF_GENERIC_H_ 1 - -#include - -/* - * Definitions of generic ELF names which relieve applications from - * needing to know the word size. - */ - -#ifndef __ELF_WORD_SIZE -# define __ELF_WORD_SIZE 32 -#endif - -#if __ELF_WORD_SIZE != 32 && __ELF_WORD_SIZE != 64 -#error "__ELF_WORD_SIZE must be defined as 32 or 64" -#endif - -#define ELF_CLASS __CONCAT(ELFCLASS,__ELF_WORD_SIZE) - -#if BYTE_ORDER == LITTLE_ENDIAN -#define ELF_DATA ELFDATA2LSB -#elif BYTE_ORDER == BIG_ENDIAN -#define ELF_DATA ELFDATA2MSB -#else -#error "Unknown byte order" -#endif - -#if __ELF_WORD_SIZE == 32 -#define __elfN(x) elf32_##x -#define __ElfN(x) Elf32_##x -#define __ELFN(x) ELF32_##x -#else -#define __elfN(x) elf364_##x -#define __ElfN(x) Elf364_##x -#define __ELFN(x) ELF364_##x -#endif -#define __ElfType(x) typedef __ElfN(x) Elf_##x - -#define FOO -__ElfType(Addr); -__ElfType(Half); -__ElfType(Off); -__ElfType(Sword); -__ElfType(Word); -__ElfType(Size); -__ElfType(Hashelt); -__ElfType(Ehdr); -__ElfType(Shdr); -__ElfType(Phdr); -__ElfType(Dyn); -__ElfType(Rel); -__ElfType(Rela); -__ElfType(Sym); - -#define ELF_R_SYM __ELFN(R_SYM) -#define ELF_R_TYPE __ELFN(R_TYPE) -#define ELF_R_INFO __ELFN(R_INFO) -#define ELF_ST_BIND __ELFN(ST_BIND) -#define ELF_ST_TYPE __ELFN(ST_TYPE) -#define ELF_ST_INFO __ELFN(ST_INFO) - -#endif /* !_SYS_ELF_GENERIC_H_ */ diff --git a/testing/build.test2/Makefile b/testing/build.test2/Makefile deleted file mode 100644 index d4c428edd..000000000 --- a/testing/build.test2/Makefile +++ /dev/null @@ -1,193 +0,0 @@ -# -*- mode: makefile -*- -#======================================== -# DO NOT DELETE THE LINE BELOW -_default: default -# DO NOT DELETE THE LINE_ABOVE -#======================================== - -#======================================== -# -# There are no user configurable options here. -# -# All user configurable options are in local.uses -# -include ./local.uses -# -#======================================== - -#======================================== -# This is the USB driver for the FTDI2XX chips. -# It is a "closed" solution from FTDICHIP.COM -# Some claim it is faster then the open/free -# solution: win32-libusb+libftdi. -# -ftd2xx.download: - mkdir -p ${VIRGINS} - wget -O ${FTD2XX_ZIPFILE_LOCAL} \ - ${FTD2XX_ZIPFILE_URL} - -ftd2xx.unpack: - rm -rf ${FTD2XX_WIN32_DIR} - mkdir -p ${FTD2XX_WIN32_DIR} - cd ${FTD2XX_WIN32_DIR} && unzip \ - ${FTD2XX_ZIPFILE_LOCAL} - -ftd2xx.build: - @echo "Nothing to do for: $@" - -ftd2xx.configure: - @echo "Nothing to do for: $@" - -ftd2xx.install: - @echo "Nothing to do for: $@" - -clean:: - rm -rf ${FTD2XX_WIN32_DIR} - -ftd2xx.all: ftd2xx.unpack ftd2xx.configure \ - ftd2xx.build ftd2xx.install - - -#========================================- -# LIBFTDI - requires LIBCONFUSE.. -# So we handle it here :-( - -libconfuse.download: - mkdir -p virgins - wget -O ${LIBCONFUSE_TARFILE_LOCAL} \ - ${LIBCONFUSE_TARFILE_URL} - -libconfuse.unpack: - tar xfz ${LIBCONFUSE_TARFILE_LOCAL} - -clean:: - rm -rf ${LIBCONFUSE_SRC_DIR} - -libconfuse.configure: - rm -rf ${LIBCONFUSE_BUILD_DIR} - mkdir -p ${LIBCONFUSE_BUILD_DIR} - cd ${LIBCONFUSE_BUILD_DIR} && \ - ${LIBCONFUSE_SRC_DIR}/configure \ - --prefix=${PREFIX} - -clean:: - rm -rf ${LIBCONFUSE_BUILD_DIR} - -libconfuse.build: - cd ${LIBCONFUSE_BUILD_DIR} && ${MAKE} - -libconfuse.install: - cd ${LIBCONFUSE_BUILD_DIR} && ${MAKE} install - -libconfuse.all: libconfuse.unpack libconfuse.configure \ - libconfuse.build libconfuse.install - -#======================================== -# LIBFTDI - the open source (and free) -# alternative to (closed) FTD2XX drivers. - -libftdi.download: - mkdir -p virgins - wget -O ${LIBFTDI_TARFILE_LOCAL} \ - ${LIBFTDI_TARFILE_URL} - -libftdi.unpack: - tar xfz ${LIBFTDI_TARFILE_LOCAL} - -clean:: - rm -rf ${LIBFTDI_SRC_DIR} - -libftdi.configure: - rm -rf ${LIBFTDI_BUILD_DIR} - mkdir -p ${LIBFTDI_BUILD_DIR} - cd ${LIBFTDI_BUILD_DIR} && \ - ${LIBFTDI_SRC_DIR}/configure \ - --prefix=${PREFIX} - -clean:: - rm -rf ${LIBFTDI_BUILD_DIR} - -libftdi.build: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} - -libftdi.install: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} install - -libftdi.all: libftdi.unpack libftdi.configure \ - libftdi.build libftdi.install - -#======================================== -# Openocd... - -openocd.bootstrap: - cd ${OPENOCD_SRC_DIR} && bash ./bootstrap - -openocd.configure: - rm -rf ${OPENOCD_BUILD_DIR} - mkdir -p ${OPENOCD_BUILD_DIR} - cd ${OPENOCD_BUILD_DIR} && ${OPENOCD_SRC_DIR}/configure \ - --prefix=${INSTALL_DIR} \ - ${OPENOCD_CONFIG_OPTIONS} - -openocd.build: - cd ${OPENOCD_BUILD_DIR} && ${MAKE} - -openocd.docs: - cd ${OPENOCD_BUILD_DIR}/docs && ${MAKE} - -openocd.docs.pdf: - cd ${OPENOCD_BUILD_DIR}/docs && ${MAKE} pdf - -openocd.docs.html: - cd ${OPENOCD_BUILD_DIR}/docs && ${MAKE} html - -# fixme: -# need to add a "make one huge html file target" - -openocd.install: - cd ${OPENOCD_BUILD_DIR} && ${MAKE} install - -#======================================== -# The world... - -# Manual step. -download.all: \ - ftd2xx.download \ - libconfuse.download \ - libftdi.download - -ifeq (x"${FT2232_DRIVER}",x"ftd2xx") -prebuild: ftd2xx.all -endif - -ifeq (x"${FT2232_DRIVER}",x"libftdi") -prebuild: libconfuse.all libftdi.all -endif - -remake: \ - openocd.bootstrap \ - openocd.configure \ - openocd.build \ - openocd.install - -initial.build : download.all prebuild remake - -all: - @echo "" - @echo " This makefile does not support an 'all' target" - @echo "" - @echo " If this is your *FIRST* time building... " - @echo " Then use this command: \"make initial.build\"" - @echo "" - @echo " The \"default\" target is for openocd developers" - @echo " and rebuilds openocd completely.." - @echo "" - -default: - test -d ${OPENOCD_SRC_DIR} || (echo "Where is: The OPENOCD source?"; exit 1) - ${MAKE} remake - -whatis_%: - @echo "" - @echo "Makevariable: $* => ${${*}}" - @echo "" diff --git a/testing/build.test2/README.txt b/testing/build.test2/README.txt deleted file mode 100644 index 382105ef0..000000000 --- a/testing/build.test2/README.txt +++ /dev/null @@ -1,58 +0,0 @@ - -This makefile is how I Duane Ellis (openocd@duaneellis.com) builds -openocd test purposes on Cygwin. I have included it here so others -might also make use of the same configuration that I use to develop -Openocd. - ---Duane Ellis - -To make use of it do the following: - -(1) Check out openocd in the standard way. - -For example - in cygwin, type this: - - bash$ mkdir -p /home/duane/test - bash$ cd /home/duane/test - bash$ svn co https://svn.berlios.de/svnroot/repos/openocd/trunk openocd - -(2) COPY this folder "right above" where you have OpenOCD. - - bash$ cd /home/duane/test - bash$ cp ./openocd/testing/build.test2/* /home/duane/test/. - -(3) OPTIONALLY - - You might want to review the file "local.uses" - Change options and so forth at the top of the file. - -(4) Initially, you need to download some additional files. - These include "libftdi", "libconfuse", and the ftd2xx drivers. - -(5) You also need to build the supporting libraries and install them - (They are installed "locally" only) - - Type this command: - - bash$ cd /home/duane/test - - bash$ make initial.build - - which: (1) downloads files - (2) builds the libs - (3) builds OpenOCD - -(6) As you hack upon OpenOCD... to rebuild OpenOCD... - - bash$ cd /home/duane/test - - bash$ make remake - - which: (1) re-bootstraps - (2) re-configures - (3) re-builds - (4) re-installs. - -======= -**END** -======= diff --git a/testing/build.test2/local.uses b/testing/build.test2/local.uses deleted file mode 100644 index edde31b0c..000000000 --- a/testing/build.test2/local.uses +++ /dev/null @@ -1,161 +0,0 @@ -# -*- mode: makefile -*- -#======================================== -# DO NOT REMOVE THE LINE BELOW -HERE := $(shell pwd) -# DO NOT REMOVE THE LINE ABOVE -#======================================== - -# These are common CYGWIN build settings. -# Comment out things you do not want. -# Or unComment things you want. - -# PCs always have printer ports... -X86_PRINTER_PORT ?= y - -# Chose *ONE* of these three solutions. -#FTD2232_DRIVER = none -FT2232_DRIVER = ftd2xx -#FT2232_DRIVER = libftdi - -# Do you have "libusb" installed? -ifeq (x"${FT2232_DRIVER}",x"libftdi") -# With LIBFTDI... LIBUSB is manditory. -USE_LIBUSB = y -endif - -# By default... we assume libusb not present. -USE_LIBUSB ?= n - -#======================================== -# DO NOT EDIT SETTINGS BELOW THIS LINE -#======================================== - - - -#======================================== -# House keeping... - -# Solve problems on systems with DASH.. Grrr... -SHELL=/bin/bash -export SHELL - -VIRGINS ?= ${HERE}/virgins -INSTALL_DIR ?= $(HERE)/install -PREFIX ?= ${INSTALL_DIR} - -# Determine the build platform. -BUILD_SYSNAME_Linux =linux -BUILD_SYSNAME_linux =linux -BUILD_SYSNAME_CYGWIN_NT =cygwin -BUILD_SYSNAME_MINGW32_NT =mingw32 -BUILD_SYSNAME_Darwin =darwin -BUILD_SYSNAME_darwin =darwin -BUILD_SYSNAME :=$(BUILD_SYSNAME_$(shell uname --sysname | cut -d'-' -f1)) - -# And machine (ie: i686, x86_64, or what ever) -BUILD_MACHINE :=$(BUILD_SYSNAME).$(shell uname -m) - - -#======================================== -# - -FTD2XX_LINUX_VERSION=0.4.16 -FTD2XX_LINUX_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION} -FTD2XX_LINUX_64_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64 - - -# Wiggler type interfaces are here. -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-parport -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-parport-giveio -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-gw16012 -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-parport-giveio -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-amtjtagaccel - - -# FTD2XX only supports these -OPENOCD_CONFIG_OPTIONS_ft2232_none = -OPENOCD_CONFIG_OPTIONS_ft2232_ftd2xx = --enable-ft2232_ftd2xx --enable-presto_ftd2xx --with-ftd2xx-win32-zipdir=${FTD2XX_WIN32_DIR} -OPENOCD_CONFIG_OPTIONS_ft2232_libftdi = --enable-ft2232_libftdi --enable-presto_libftdi - -# LIBUSB - adds support for these. -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-jlink -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-usbprog -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-rlink -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-vsllink -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-usbprog - -#======================================== -# EXPLICITY NOT SUPPORTED INTERFACES -# -# zy1000.c -# This is a standalone hardware box -# it is *NOT* a cygwin thing. -# -# at91rm9200.c -# This is a uC/Linux (or linux) that -# runs uC/Linux and uses the gpio pins -# to bit-bang JTAG stuff. -# -# ep93xx.c -# Just like at91rm9200 - different chip. - -#======================================== -# Build OPENOCD config options... -# Always enable "dummy" -OPENOCD_CONFIG_OPTIONS += --enable-dummy -# -# Today: Cannot enable 'oocd_trace' on cygwin. -# it assumes/uses termios functions like -# cfmakeraw() which do not exist on cygwin. -# -#OPENOCD_CONFIG_OPTIONS += --enable-oocd-trace -# -# Add printer options.. -OPENOCD_CONFIG_OPTIONS += ${OPENOCD_CONFIG_OPTIONS_printer_${X86_PRINTER_PORT}} - -# Add the FTD2232 based options. -OPENOCD_CONFIG_OPTIONS += ${OPENOCD_CONFIG_OPTIONS_ft2232_${FT2232_DRIVER}} - -# Add LIBUSB based options. -OPENOCD_CONFIG_OPTIONS += ${OPENOCD_CONFIG_OPTIONS_libusb_${USE_LIBUSB}} - - -#======================================== -# WARNING... the file on the ftdi chip site has a SPACE in the filename GRRR!!! -# We fix that with the "-O" option to wget. -FTD2XX_WIN32_VERSION=2.04.14 -FTD2XX_WIN32_DIR = ${HERE}/ftd2xx.win32 - -FTD2XX_ZIPFILE_LOCAL=${VIRGINS}/cdm.${FTD2XX_WIN32_VERSION}.zip -# Damn thing has a space in the F-ing filename! -FTD2XX_ZIPFILE_URL ="http://www.ftdichip.com/Drivers/CDM/CDM ${FTD2XX_WIN32_VERSION}.zip" - - -#======================================== -# LIBCONFUSE - used by LIBFTDI.. -LIBCONFUSE_VERSION=2.5 -LIBCONFUSE_TARFILE_LOCAL=${VIRGINS}/confuse-${LIBCONFUSE_VERSION}.tar.gz -LIBCONFUSE_TARFILE_URL =http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/confuse-${LIBCONFUSE_VERSION}.tar.gz - -LIBCONFUSE_SRC_DIR =${HERE}/confuse-${LIBCONFUSE_VERSION} -LIBCONFUSE_BUILD_DIR =${HERE}/confuse-build - - -#======================================== -# LIBFTDI... (which uses libusb, and libconfuse) -LIBFTDI_VERSION=0.14 -LIBFTDI_TARFILE_LOCAL = ${VIRGINS}/libftdi-${LIBFTDI_VERSION}.tar.gz -LIBFTDI_TARFILE_URL = http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/libftdi-${LIBFTDI_VERSION}.tar.gz - -LIBFTDI_SRC_DIR = ${HERE}/libftdi-${LIBFTDI_VERSION} -LIBFTDI_BUILD_DIR= ${HERE}/libftdi-build - -#======================================== -# Finally - OpenOCD... -# -OPENOCD_BUILD_DIR =${HERE}/openocd-build -OPENOCD_SRC_DIR =${HERE}/openocd - -#======================================== -# END .. -#======================================== From da434d7d5975c1c7ebae8e35eb71b6d2d6ad062e Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Sat, 9 Oct 2021 23:32:01 +0300 Subject: [PATCH 13/82] jtag: drivers: bcm2835gpio: don't allow GPIOs > 31 Current code assumes all the GPIO signals are manipulated via a single 32-bit register so using higher GPIOs silently fails. Fix the check instead of trying to handle additional GPIOs (available on Raspberry Pi Compute Modules) as that would slow the driver down. Change-Id: Ib3b5864afb3b972d952f9b74665201cd93924959 Signed-off-by: Paul Fertser Reviewed-on: https://review.openocd.org/c/openocd/+/6658 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 2 ++ src/jtag/drivers/bcm2835gpio.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index cd64c7aec..01bb4f21d 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3207,6 +3207,8 @@ able to coexist nicely with both sysfs bitbanging and various peripherals' kernel drivers. The driver restores the previous configuration on exit. +GPIO numbers >= 32 can't be used for performance reasons. + See @file{interface/raspberrypi-native.cfg} for a sample config and pinout. diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index 95e077c33..fd6c28b96 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -198,7 +198,7 @@ static int bcm2835gpio_speed(int speed) static int is_gpio_valid(int gpio) { - return gpio >= 0 && gpio <= 53; + return gpio >= 0 && gpio <= 31; } COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums) From 5148a1324aeef62d85aaeaa1c061df8e874e4c12 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 11 Oct 2021 09:56:39 -0700 Subject: [PATCH 14/82] rtos: use struct member names instead of comments This is more readable, and as a bonus the compiler will help out if the definition of the struct changes. Change-Id: Ibf660134d9900173f6592407d5cc2203654a4a1b Signed-off-by: Tim Newsome Reviewed-on: https://review.openocd.org/c/openocd/+/6659 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/rtos/ThreadX.c | 18 +++++------ src/rtos/nuttx.c | 18 +++++------ src/rtos/rtos_chibios_stackings.c | 18 +++++------ src/rtos/rtos_ecos_stackings.c | 10 +++--- src/rtos/rtos_embkernel_stackings.c | 10 +++--- src/rtos/rtos_mqx_stackings.c | 9 +++--- src/rtos/rtos_riot_stackings.c | 20 ++++++------ src/rtos/rtos_standard_stackings.c | 50 ++++++++++++++--------------- src/rtos/rtos_ucos_iii_stackings.c | 19 ++++++----- 9 files changed, 82 insertions(+), 90 deletions(-) diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c index 788edc0b4..441b7abc5 100644 --- a/src/rtos/ThreadX.c +++ b/src/rtos/ThreadX.c @@ -112,18 +112,16 @@ static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_i static const struct rtos_register_stacking rtos_threadx_arm926ejs_stacking[] = { { - ARM926EJS_REGISTERS_SIZE_SOLICITED, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 17, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_threadx_arm926ejs_stack_offsets_solicited /* register_offsets */ + .stack_registers_size = ARM926EJS_REGISTERS_SIZE_SOLICITED, + .stack_growth_direction = -1, + .num_output_registers = 17, + .register_offsets = rtos_threadx_arm926ejs_stack_offsets_solicited }, { - ARM926EJS_REGISTERS_SIZE_INTERRUPT, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 17, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_threadx_arm926ejs_stack_offsets_interrupt /* register_offsets */ + .stack_registers_size = ARM926EJS_REGISTERS_SIZE_INTERRUPT, + .stack_growth_direction = -1, + .num_output_registers = 17, + .register_offsets = rtos_threadx_arm926ejs_stack_offsets_interrupt }, }; diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c index cc352d180..f0b304861 100644 --- a/src/rtos/nuttx.c +++ b/src/rtos/nuttx.c @@ -119,11 +119,10 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = { static const struct rtos_register_stacking nuttx_stacking_cortex_m = { - 0x48, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 17, /* num_output_registers */ - 0, /* stack_alignment */ - nuttx_stack_offsets_cortex_m /* register_offsets */ + .stack_registers_size = 0x48, + .stack_growth_direction = -1, + .num_output_registers = 17, + .register_offsets = nuttx_stack_offsets_cortex_m }; static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = { @@ -147,11 +146,10 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = { }; static const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = { - 0x8c, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 17, /* num_output_registers */ - 0, /* stack_alignment */ - nuttx_stack_offsets_cortex_m_fpu /* register_offsets */ + .stack_registers_size = 0x8c, + .stack_growth_direction = -1, + .num_output_registers = 17, + .register_offsets = nuttx_stack_offsets_cortex_m_fpu }; static int pid_offset = PID; diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c index 2887930bd..77bcb86cb 100644 --- a/src/rtos/rtos_chibios_stackings.c +++ b/src/rtos/rtos_chibios_stackings.c @@ -47,11 +47,10 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARM }; const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = { - 0x24, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_chibios_arm_v7m_stack_offsets /* register_offsets */ + .stack_registers_size = 0x24, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .register_offsets = rtos_chibios_arm_v7m_stack_offsets }; static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_fpu[ARMV7M_NUM_CORE_REGS] = { @@ -75,9 +74,8 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_f }; const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = { - 0x64, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_chibios_arm_v7m_stack_offsets_w_fpu /* register_offsets */ + .stack_registers_size = 0x64, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .register_offsets = rtos_chibios_arm_v7m_stack_offsets_w_fpu }; diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c index e2119423a..4745470ce 100644 --- a/src/rtos/rtos_ecos_stackings.c +++ b/src/rtos/rtos_ecos_stackings.c @@ -43,9 +43,9 @@ static const struct stack_register_offset rtos_ecos_cortex_m3_stack_offsets[ARMV }; const struct rtos_register_stacking rtos_ecos_cortex_m3_stacking = { - 0x44, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_ecos_cortex_m3_stack_offsets /* register_offsets */ + .stack_registers_size = 0x44, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = rtos_ecos_cortex_m3_stack_offsets }; diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c index cd4c22eac..df1fc51f2 100644 --- a/src/rtos/rtos_embkernel_stackings.c +++ b/src/rtos/rtos_embkernel_stackings.c @@ -45,9 +45,9 @@ static const struct stack_register_offset rtos_embkernel_cortex_m_stack_offsets[ }; const struct rtos_register_stacking rtos_embkernel_cortex_m_stacking = { - 0x40, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_embkernel_cortex_m_stack_offsets /* register_offsets */ + .stack_registers_size = 0x40, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = rtos_embkernel_cortex_m_stack_offsets }; diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c index f2d3b2227..f99190ea5 100644 --- a/src/rtos/rtos_mqx_stackings.c +++ b/src/rtos/rtos_mqx_stackings.c @@ -71,9 +71,8 @@ static const struct stack_register_offset rtos_mqx_arm_v7m_stack_offsets[ARMV7M_ }; const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = { - 0x4C, /* stack_registers_size, calculate offset base address */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_mqx_arm_v7m_stack_offsets /* register_offsets */ + .stack_registers_size = 0x4C, /* calculate offset base address */ + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .register_offsets = rtos_mqx_arm_v7m_stack_offsets }; diff --git a/src/rtos/rtos_riot_stackings.c b/src/rtos/rtos_riot_stackings.c index abf08c8ff..84e1f7ff8 100644 --- a/src/rtos/rtos_riot_stackings.c +++ b/src/rtos/rtos_riot_stackings.c @@ -58,11 +58,11 @@ static const struct stack_register_offset rtos_riot_cortex_m0_stack_offsets[ARMV }; const struct rtos_register_stacking rtos_riot_cortex_m0_stacking = { - 0x44, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_riot_cortex_m_stack_align, /* stack_alignment */ - rtos_riot_cortex_m0_stack_offsets /* register_offsets */ + .stack_registers_size = 0x44, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_riot_cortex_m_stack_align, + .register_offsets = rtos_riot_cortex_m0_stack_offsets }; /* see thread_arch.c */ @@ -87,9 +87,9 @@ static const struct stack_register_offset rtos_riot_cortex_m34_stack_offsets[ARM }; const struct rtos_register_stacking rtos_riot_cortex_m34_stacking = { - 0x44, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_riot_cortex_m_stack_align, /* stack_alignment */ - rtos_riot_cortex_m34_stack_offsets /* register_offsets */ + .stack_registers_size = 0x44, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_riot_cortex_m_stack_align, + .register_offsets = rtos_riot_cortex_m34_stack_offsets }; diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c index c3eef5c06..fe890413f 100644 --- a/src/rtos/rtos_standard_stackings.c +++ b/src/rtos/rtos_standard_stackings.c @@ -249,41 +249,41 @@ static target_addr_t rtos_standard_cortex_m4f_fpu_stack_align(struct target *tar const struct rtos_register_stacking rtos_standard_cortex_m3_stacking = { - 0x40, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_standard_cortex_m3_stack_align, /* stack_alignment */ - rtos_standard_cortex_m3_stack_offsets /* register_offsets */ + .stack_registers_size = 0x40, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_standard_cortex_m3_stack_align, + .register_offsets = rtos_standard_cortex_m3_stack_offsets }; const struct rtos_register_stacking rtos_standard_cortex_m4f_stacking = { - 0x44, /* stack_registers_size 4 more for LR*/ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_standard_cortex_m4f_stack_align, /* stack_alignment */ - rtos_standard_cortex_m4f_stack_offsets /* register_offsets */ + .stack_registers_size = 0x44, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_standard_cortex_m4f_stack_align, + .register_offsets = rtos_standard_cortex_m4f_stack_offsets }; const struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking = { - 0xcc, /* stack_registers_size 4 more for LR + 48 more for FPU S0-S15 register*/ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_standard_cortex_m4f_fpu_stack_align, /* stack_alignment */ - rtos_standard_cortex_m4f_fpu_stack_offsets /* register_offsets */ + .stack_registers_size = 0xcc, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_standard_cortex_m4f_fpu_stack_align, + .register_offsets = rtos_standard_cortex_m4f_fpu_stack_offsets }; const struct rtos_register_stacking rtos_standard_cortex_r4_stacking = { - 0x48, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 26, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_standard_cortex_r4_stack_offsets /* register_offsets */ + .stack_registers_size = 0x48, + .stack_growth_direction = -1, + .num_output_registers = 26, + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = rtos_standard_cortex_r4_stack_offsets }; const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking = { - 0x90, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 32, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_standard_nds32_n1068_stack_offsets /* register_offsets */ + .stack_registers_size = 0x90, + .stack_growth_direction = -1, + .num_output_registers = 32, + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = rtos_standard_nds32_n1068_stack_offsets }; diff --git a/src/rtos/rtos_ucos_iii_stackings.c b/src/rtos/rtos_ucos_iii_stackings.c index 4ae0d7dc8..0d533b55e 100644 --- a/src/rtos/rtos_ucos_iii_stackings.c +++ b/src/rtos/rtos_ucos_iii_stackings.c @@ -68,17 +68,16 @@ static const struct stack_register_offset rtos_ucos_iii_esi_risc_stack_offsets[] }; const struct rtos_register_stacking rtos_ucos_iii_cortex_m_stacking = { - 0x40, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARRAY_SIZE(rtos_ucos_iii_cortex_m_stack_offsets), /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_ucos_iii_cortex_m_stack_offsets /* register_offsets */ + .stack_registers_size = 0x40, + .stack_growth_direction = -1, + .num_output_registers = ARRAY_SIZE(rtos_ucos_iii_cortex_m_stack_offsets), + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = rtos_ucos_iii_cortex_m_stack_offsets }; const struct rtos_register_stacking rtos_ucos_iii_esi_risc_stacking = { - 0x4c, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARRAY_SIZE(rtos_ucos_iii_esi_risc_stack_offsets), /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_ucos_iii_esi_risc_stack_offsets /* register_offsets */ + .stack_registers_size = 0x4c, + .stack_growth_direction = -1, + .num_output_registers = ARRAY_SIZE(rtos_ucos_iii_esi_risc_stack_offsets), + .register_offsets = rtos_ucos_iii_esi_risc_stack_offsets }; From 8b1ee1b1f6d41a0f7d588b128a22e8d5abeb85a7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 11 Apr 2021 23:58:57 +0200 Subject: [PATCH 15/82] Makefile: remove workaround for jimtcl 0.80 Commit 266a945ad3e8 ("jimtcl: update to version 0.80 (2020-10-29)") adds a workaround to permit 'make distcheck' with jimtcl 0.80. This has been fixed in jimtcl with commit d224c9a2b7b2 ("Makefile: remove examples.api/Makefile while 'distclean'"). By using jimtcl from latest master branch, the workaround is not required anymore. Remove the workaround. Change-Id: I10d91371b5a89d2a3c8599bce766f97eac44f0d9 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6227 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7e5e22973..a18c572fb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -125,8 +125,6 @@ uninstall-hook: distclean-local: rm -rf Doxyfile doxygen rm -f $(srcdir)/jimtcl/configure.gnu -# FIXME: workaround for jimtcl 0.80 only. Remove from jimtcl 0.81 - rm -f jimtcl/examples.api/Makefile DISTCLEANFILES = doxygen.log From b2ab2241f20fd3da11c92f8edde4639ab8ce996f Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 12 Apr 2021 00:04:19 +0200 Subject: [PATCH 16/82] jimtcl: revert temporary workaround for memory leak in jimtcl 0.80 By using jimtcl from latest master branch, the workaround added in commit 36ae487ed04b ("jimtcl: add temporary workaround for memory leak in jimtcl 0.80") is not needed anymore. Revert the workaround. Change-Id: Ia1b5804be15362d0400740c375455ee19ac09f04 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6228 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/helper/command.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index 7c29f73e6..53ee2508a 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -137,41 +137,6 @@ static void command_log_capture_finish(struct log_capture_state *state) free(state); } -/* - * FIXME: workaround for memory leak in jimtcl 0.80 - * Jim API Jim_CreateCommand() converts the command name in a Jim object and - * does not free the object. Fixed for jimtcl 0.81 by e4416cf86f0b - * Use the internal jimtcl API Jim_CreateCommandObj, not exported by jim.h, - * and override the bugged API through preprocessor's macro. - * This workaround works only when jimtcl is compiled as OpenOCD submodule. - * It's broken on macOS, so it's currently restricted on Linux only. - * If jimtcl is linked-in from a precompiled library, either static or dynamic, - * the symbol Jim_CreateCommandObj is not exported and the build will use the - * bugged API. - * To be removed when OpenOCD will switch to jimtcl 0.81 - */ -#if JIM_VERSION == 80 && defined __linux__ -static int workaround_createcommand(Jim_Interp *interp, const char *cmdName, - Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc); -int Jim_CreateCommandObj(Jim_Interp *interp, Jim_Obj *cmdNameObj, - Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc) -__attribute__((weak, alias("workaround_createcommand"))); -static int workaround_createcommand(Jim_Interp *interp, const char *cmdName, - Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc) -{ - if ((void *)Jim_CreateCommandObj == (void *)workaround_createcommand) - return Jim_CreateCommand(interp, cmdName, cmdProc, privData, delProc); - - Jim_Obj *cmd_name = Jim_NewStringObj(interp, cmdName, -1); - Jim_IncrRefCount(cmd_name); - int retval = Jim_CreateCommandObj(interp, cmd_name, cmdProc, privData, delProc); - Jim_DecrRefCount(interp, cmd_name); - return retval; -} -#define Jim_CreateCommand workaround_createcommand -#endif /* JIM_VERSION == 80 && defined __linux__*/ -/* FIXME: end of workaround for memory leak in jimtcl 0.80 */ - static int command_retval_set(Jim_Interp *interp, int retval) { int *return_retval = Jim_GetAssocData(interp, "retval"); From be57b0ab847e8246b354ca9203024737cdec403b Mon Sep 17 00:00:00 2001 From: Andreas Bolsch Date: Mon, 28 Jan 2019 10:37:53 +0100 Subject: [PATCH 17/82] Update jtagspi driver for 1-, 2- and 4-byte addresses jtagspi driver always used 3-byte addresses regardless of actual device capcity. Now select 1- to 4-byte addresses depending on device capacity. Some devices need a special command to activate the 4-byte address mode, a special command to accomplish this, and a further command for setting device properties are added. Additionally, restriction (start of range had to be page aligned) removed. Tested with XCS6SLX16 board and W25Q256FV in 3- and 4-byte address modes. Change-Id: I88b2877517a18dac460253ae6d97f3dded054e6c Signed-off-by: Andreas Bolsch Reviewed-on: https://review.openocd.org/c/openocd/+/4876 Reviewed-by: Jan Matyas Reviewed-by: Tomas Vanek Reviewed-by: zapb Tested-by: jenkins --- doc/openocd.texi | 27 ++ src/flash/nor/jtagspi.c | 533 +++++++++++++++++++++++++++++++++------- 2 files changed, 470 insertions(+), 90 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 01bb4f21d..c7ffc4f42 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5580,6 +5580,10 @@ will not work. These include all @command{*_image} and functionality is available through the @command{flash write_bank}, @command{flash read_bank}, and @command{flash verify_bank} commands. +According to device size, 1- to 4-byte addresses are sent. However, some +flash chips additionally have to be switched to 4-byte addresses by an extra +command, see below. + @itemize @item @var{ir} ... is loaded into the JTAG IR to map the flash as the JTAG DR. For the bitstreams generated from @file{xilinx_bscan_spi.py} this is the @@ -5592,6 +5596,29 @@ set _XILINX_USER1 0x02 flash bank $_FLASHNAME spi 0x0 0 0 0 \ $_TARGETNAME $_XILINX_USER1 @end example + +@deffn Command {jtagspi set} bank_id name total_size page_size read_cmd unused pprg_cmd mass_erase_cmd sector_size sector_erase_cmd +Sets flash parameters: @var{name} human readable string, @var{total_size} +size in bytes, @var{page_size} is write page size. @var{read_cmd} and @var{pprg_cmd} +are commands for read and page program, respectively. @var{mass_erase_cmd}, +@var{sector_size} and @var{sector_erase_cmd} are optional. +@example +jtagspi set 0 w25q128 0x1000000 0x100 0x03 0 0x02 0xC7 0x10000 0xD8 +@end example +@end deffn + +@deffn Command {jtagspi cmd} bank_id resp_num cmd_byte ... +Sends command @var{cmd_byte} and at most 20 following bytes and reads +@var{resp_num} bytes afterwards. E.g. for 'Enter 4-byte address mode' +@example +jtagspi cmd 0 0 0xB7 +@end example +@end deffn + +@deffn Command {jtagspi always_4byte} bank_id [ on | off ] +Some devices use 4-byte addresses for all commands except the legacy 0x03 read +regardless of device size. This command controls the corresponding hack. +@end deffn @end deffn @deffn {Flash Driver} {xcf} diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index dc49fda61..9d377ce70 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -29,9 +29,12 @@ struct jtagspi_flash_bank { struct jtag_tap *tap; - const struct flash_device *dev; + struct flash_device dev; + char devname[32]; bool probed; + bool always_4byte; /* use always 4-byte address except for basic read 0x03 */ uint32_t ir; + unsigned int addr_len; /* address length in bytes */ }; FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command) @@ -46,6 +49,7 @@ FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command) LOG_ERROR("no memory for flash bank info"); return ERROR_FAIL; } + bank->sectors = NULL; bank->driver_priv = info; info->tap = NULL; @@ -69,70 +73,59 @@ static void jtagspi_set_ir(struct flash_bank *bank) jtag_add_ir_scan(info->tap, &field, TAP_IDLE); } -static void flip_u8(uint8_t *in, uint8_t *out, int len) +static void flip_u8(const uint8_t *in, uint8_t *out, unsigned int len) { - for (int i = 0; i < len; i++) + for (unsigned int i = 0; i < len; i++) out[i] = flip_u32(in[i], 8); } static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd, - uint32_t *addr, uint8_t *data, int len) + uint8_t *write_buffer, unsigned int write_len, uint8_t *data_buffer, int data_len) { - struct jtagspi_flash_bank *info = bank->driver_priv; + assert(write_buffer || write_len == 0); + assert(data_buffer || data_len == 0); + struct scan_field fields[6]; - uint8_t marker = 1; - uint8_t xfer_bits_buf[4]; - uint8_t addr_buf[3]; - uint8_t *data_buf; - uint32_t xfer_bits; - int is_read, lenb, n; - /* LOG_DEBUG("cmd=0x%02x len=%i", cmd, len); */ + LOG_DEBUG("cmd=0x%02x write_len=%d data_len=%d", cmd, write_len, data_len); - is_read = (len < 0); + /* negative data_len == read operation */ + const bool is_read = (data_len < 0); if (is_read) - len = -len; - - n = 0; + data_len = -data_len; + int n = 0; + const uint8_t marker = 1; fields[n].num_bits = 1; fields[n].out_value = ▮ fields[n].in_value = NULL; n++; - xfer_bits = 8 + len - 1; - /* cmd + read/write - 1 due to the counter implementation */ - if (addr) - xfer_bits += 24; - h_u32_to_be(xfer_bits_buf, xfer_bits); - flip_u8(xfer_bits_buf, xfer_bits_buf, 4); - fields[n].num_bits = 32; - fields[n].out_value = xfer_bits_buf; + /* transfer length = cmd + address + read/write, + * -1 due to the counter implementation */ + uint8_t xfer_bits[4]; + h_u32_to_be(xfer_bits, ((sizeof(cmd) + write_len + data_len) * CHAR_BIT) - 1); + flip_u8(xfer_bits, xfer_bits, sizeof(xfer_bits)); + fields[n].num_bits = sizeof(xfer_bits) * CHAR_BIT; + fields[n].out_value = xfer_bits; fields[n].in_value = NULL; n++; - cmd = flip_u32(cmd, 8); - fields[n].num_bits = 8; + flip_u8(&cmd, &cmd, sizeof(cmd)); + fields[n].num_bits = sizeof(cmd) * CHAR_BIT; fields[n].out_value = &cmd; fields[n].in_value = NULL; n++; - if (addr) { - h_u24_to_be(addr_buf, *addr); - flip_u8(addr_buf, addr_buf, 3); - fields[n].num_bits = 24; - fields[n].out_value = addr_buf; + if (write_len) { + flip_u8(write_buffer, write_buffer, write_len); + fields[n].num_bits = write_len * CHAR_BIT; + fields[n].out_value = write_buffer; fields[n].in_value = NULL; n++; } - lenb = DIV_ROUND_UP(len, 8); - data_buf = malloc(lenb); - if (lenb > 0) { - if (!data_buf) { - LOG_ERROR("no memory for spi buffer"); - return ERROR_FAIL; - } + if (data_len > 0) { if (is_read) { fields[n].num_bits = jtag_tap_count_enabled(); fields[n].out_value = NULL; @@ -140,36 +133,263 @@ static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd, n++; fields[n].out_value = NULL; - fields[n].in_value = data_buf; + fields[n].in_value = data_buffer; } else { - flip_u8(data, data_buf, lenb); - fields[n].out_value = data_buf; + flip_u8(data_buffer, data_buffer, data_len); + fields[n].out_value = data_buffer; fields[n].in_value = NULL; } - fields[n].num_bits = len; + fields[n].num_bits = data_len * CHAR_BIT; n++; } jtagspi_set_ir(bank); /* passing from an IR scan to SHIFT-DR clears BYPASS registers */ + struct jtagspi_flash_bank *info = bank->driver_priv; jtag_add_dr_scan(info->tap, n, fields, TAP_IDLE); int retval = jtag_execute_queue(); if (is_read) - flip_u8(data_buf, data, lenb); - free(data_buf); + flip_u8(data_buffer, data_buffer, data_len); return retval; } +COMMAND_HANDLER(jtagspi_handle_set) +{ + struct flash_bank *bank = NULL; + struct jtagspi_flash_bank *info = NULL; + struct flash_sector *sectors = NULL; + uint32_t temp; + unsigned int index = 1; + int retval; + + LOG_DEBUG("%s", __func__); + + /* there are 6 mandatory arguments: + * devname, size_in_bytes, pagesize, read_cmd, unused, pprog_cmd */ + if (index + 6 > CMD_ARGC) { + command_print(CMD, "jtagspi: not enough arguments"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (ERROR_OK != retval) + return retval; + info = bank->driver_priv; + + /* invalidate all old info */ + if (info->probed) { + bank->size = 0; + bank->num_sectors = 0; + if (bank->sectors) + free(bank->sectors); + bank->sectors = NULL; + info->always_4byte = false; + info->probed = false; + } + memset(&info->dev, 0, sizeof(info->dev)); + + strncpy(info->devname, CMD_ARGV[index++], sizeof(info->devname) - 1); + info->devname[sizeof(info->devname) - 1] = '\0'; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], temp); + info->dev.size_in_bytes = temp; + if ((temp & (temp - 1)) || (temp < (1UL << 8))) { + command_print(CMD, "jtagspi: device size must be 2^n with n >= 8"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], temp); + info->dev.pagesize = temp; + if (info->dev.pagesize == 0) + info->dev.pagesize = SPIFLASH_DEF_PAGESIZE; + if ((temp & (temp - 1)) || (temp > info->dev.size_in_bytes)) { + command_print(CMD, "jtagspi: page size must be 2^n and <= device size"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.read_cmd); + if ((info->dev.read_cmd != 0x03) && + (info->dev.read_cmd != 0x13)) { + command_print(CMD, "jtagspi: only 0x03/0x13 READ allowed"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.qread_cmd); + + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.pprog_cmd); + if ((info->dev.pprog_cmd != 0x02) && + (info->dev.pprog_cmd != 0x12)) { + command_print(CMD, "jtagspi: only 0x02/0x12 PPRG allowed"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + /* remaining params are optional */ + if (index < CMD_ARGC) + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.chip_erase_cmd); + else + info->dev.chip_erase_cmd = 0x00; + + if (index < CMD_ARGC) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], temp); + info->dev.sectorsize = temp; + if ((info->dev.sectorsize > info->dev.size_in_bytes) || + (info->dev.sectorsize < info->dev.pagesize) || (temp & (temp - 1))) { + command_print(CMD, "jtagspi: sector size must be 2^n and <= device size"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (index < CMD_ARGC) + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.erase_cmd); + else { + command_print(CMD, "jtagspi: erase command missing"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + } else { + /* no sector size / sector erase cmd given, treat whole bank as a single sector */ + info->dev.erase_cmd = 0x00; + info->dev.sectorsize = info->dev.size_in_bytes; + } + + if (index < CMD_ARGC) { + command_print(CMD, "jtagspi: extra arguments"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + /* set correct size value */ + bank->size = info->dev.size_in_bytes; + + /* calculate address length in bytes */ + if (bank->size <= (1UL << 8)) + info->addr_len = 1; + else if (bank->size <= (1UL << 16)) + info->addr_len = 2; + else if (bank->size <= (1UL << 24)) + info->addr_len = 3; + else { + info->addr_len = 4; + LOG_WARNING("4-byte addresses needed, might need extra command to enable"); + } + + /* create and fill sectors array */ + bank->num_sectors = + info->dev.size_in_bytes / info->dev.sectorsize; + sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + if (!sectors) { + LOG_ERROR("Not enough memory"); + return ERROR_FAIL; + } + + for (unsigned int sector = 0; sector < bank->num_sectors; sector++) { + sectors[sector].offset = sector * (info->dev.sectorsize); + sectors[sector].size = info->dev.sectorsize; + sectors[sector].is_erased = -1; + sectors[sector].is_protected = 0; + } + + bank->sectors = sectors; + info->dev.name = info->devname; + if (info->dev.size_in_bytes / 4096) + LOG_INFO("flash \'%s\' id = unknown\nflash size = %" PRIu32 " kbytes", + info->dev.name, info->dev.size_in_bytes / 1024); + else + LOG_INFO("flash \'%s\' id = unknown\nflash size = %" PRIu32 " bytes", + info->dev.name, info->dev.size_in_bytes); + info->probed = true; + + return ERROR_OK; +} + +COMMAND_HANDLER(jtagspi_handle_cmd) +{ + struct flash_bank *bank; + unsigned int index = 1; + const int max = 21; + uint8_t num_write, num_read, write_buffer[max], read_buffer[1 << CHAR_BIT]; + uint8_t data, *ptr; + char temp[4], output[(2 + max + (1 << CHAR_BIT)) * 3 + 8]; + int retval; + + LOG_DEBUG("%s", __func__); + + if (CMD_ARGC < 3) { + command_print(CMD, "jtagspi: not enough arguments"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + num_write = CMD_ARGC - 2; + if (num_write > max) { + LOG_ERROR("at most %d bytes may be send", max); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (ERROR_OK != retval) + return retval; + + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], num_read); + + snprintf(output, sizeof(output), "spi: "); + for (ptr = &write_buffer[0] ; index < CMD_ARGC; index++) { + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index], data); + *ptr++ = data; + snprintf(temp, sizeof(temp), "%02" PRIx8 " ", data); + strncat(output, temp, sizeof(output) - strlen(output) - 1); + } + strncat(output, "-> ", sizeof(output) - strlen(output) - 1); + + /* process command */ + ptr = &read_buffer[0]; + jtagspi_cmd(bank, write_buffer[0], &write_buffer[1], num_write - 1, ptr, -num_read); + if (retval != ERROR_OK) + return retval; + + for ( ; num_read > 0; num_read--) { + snprintf(temp, sizeof(temp), "%02" PRIx8 " ", *ptr++); + strncat(output, temp, sizeof(output) - strlen(output) - 1); + } + command_print(CMD, "%s", output); + + return ERROR_OK; +} + +COMMAND_HANDLER(jtagspi_handle_always_4byte) +{ + struct flash_bank *bank; + struct jtagspi_flash_bank *jtagspi_info; + int retval; + + LOG_DEBUG("%s", __func__); + + if ((CMD_ARGC != 1) && (CMD_ARGC != 2)) + return ERROR_COMMAND_SYNTAX_ERROR; + + retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (ERROR_OK != retval) + return retval; + + jtagspi_info = bank->driver_priv; + + if (CMD_ARGC == 1) + command_print(CMD, jtagspi_info->always_4byte ? "on" : "off"); + else + COMMAND_PARSE_BOOL(CMD_ARGV[1], jtagspi_info->always_4byte, "on", "off"); + + return ERROR_OK; +} + static int jtagspi_probe(struct flash_bank *bank) { struct jtagspi_flash_bank *info = bank->driver_priv; struct flash_sector *sectors; + const struct flash_device *p; uint8_t in_buf[3]; uint32_t id, sectorsize; - if (info->probed) + if (bank->sectors) { free(bank->sectors); + bank->sectors = NULL; + } info->probed = false; if (!bank->target->tap) { @@ -178,38 +398,46 @@ static int jtagspi_probe(struct flash_bank *bank) } info->tap = bank->target->tap; - jtagspi_cmd(bank, SPIFLASH_READ_ID, NULL, in_buf, -24); + jtagspi_cmd(bank, SPIFLASH_READ_ID, NULL, 0, in_buf, -3); /* the table in spi.c has the manufacturer byte (first) as the lsb */ id = le_to_h_u24(in_buf); - info->dev = NULL; - for (const struct flash_device *p = flash_devices; p->name ; p++) + memset(&info->dev, 0, sizeof(info->dev)); + for (p = flash_devices; p->name ; p++) if (p->device_id == id) { - info->dev = p; + memcpy(&info->dev, p, sizeof(info->dev)); break; } - if (!(info->dev)) { - LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id); + if (!(p->name)) { + LOG_ERROR("Unknown flash device (ID 0x%06" PRIx32 ")", id & 0xFFFFFF); return ERROR_FAIL; } - LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", - info->dev->name, info->dev->device_id); + LOG_INFO("Found flash device \'%s\' (ID 0x%06" PRIx32 ")", + info->dev.name, info->dev.device_id & 0xFFFFFF); /* Set correct size value */ - bank->size = info->dev->size_in_bytes; - if (bank->size <= (1UL << 16)) - LOG_WARNING("device needs 2-byte addresses - not implemented"); - if (bank->size > (1UL << 24)) - LOG_WARNING("device needs paging or 4-byte addresses - not implemented"); + bank->size = info->dev.size_in_bytes; + + /* calculate address length in bytes */ + if (bank->size <= (1UL << 8)) + info->addr_len = 1; + else if (bank->size <= (1UL << 16)) + info->addr_len = 2; + else if (bank->size <= (1UL << 24)) + info->addr_len = 3; + else { + info->addr_len = 4; + LOG_WARNING("4-byte addresses needed, might need extra command to enable"); + } /* if no sectors, treat whole bank as single sector */ - sectorsize = info->dev->sectorsize ? - info->dev->sectorsize : info->dev->size_in_bytes; + sectorsize = info->dev.sectorsize ? + info->dev.sectorsize : info->dev.size_in_bytes; /* create and fill sectors array */ - bank->num_sectors = info->dev->size_in_bytes / sectorsize; + bank->num_sectors = info->dev.size_in_bytes / sectorsize; sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); if (!sectors) { LOG_ERROR("not enough memory"); @@ -228,27 +456,35 @@ static int jtagspi_probe(struct flash_bank *bank) return ERROR_OK; } +static int jtagspi_auto_probe(struct flash_bank *bank) +{ + struct jtagspi_flash_bank *info = bank->driver_priv; + + if (info->probed) + return ERROR_OK; + return jtagspi_probe(bank); +} + static int jtagspi_read_status(struct flash_bank *bank, uint32_t *status) { uint8_t buf; - int err = jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, &buf, -8); + int err = jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, 0, &buf, -1); if (err == ERROR_OK) { *status = buf; - /* LOG_DEBUG("status=0x%08" PRIx32, *status); */ + LOG_DEBUG("status=0x%02" PRIx8, *status); } - return err; } static int jtagspi_wait(struct flash_bank *bank, int timeout_ms) { - uint32_t status; int64_t t0 = timeval_ms(); int64_t dt; do { dt = timeval_ms() - t0; + uint32_t status = (uint32_t)-1; int retval = jtagspi_read_status(bank, &status); if (retval != ERROR_OK) return retval; @@ -266,16 +502,15 @@ static int jtagspi_wait(struct flash_bank *bank, int timeout_ms) static int jtagspi_write_enable(struct flash_bank *bank) { - uint32_t status; - - jtagspi_cmd(bank, SPIFLASH_WRITE_ENABLE, NULL, NULL, 0); + jtagspi_cmd(bank, SPIFLASH_WRITE_ENABLE, NULL, 0, NULL, 0); + uint32_t status = (uint32_t)-1; int retval = jtagspi_read_status(bank, &status); if (retval != ERROR_OK) return retval; if ((status & SPIFLASH_WE_BIT) == 0) { - LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status); + LOG_ERROR("Cannot enable write to flash. Status=0x%02" PRIx8, status); return ERROR_FAIL; } return ERROR_OK; @@ -287,28 +522,51 @@ static int jtagspi_bulk_erase(struct flash_bank *bank) int retval; int64_t t0 = timeval_ms(); - if (info->dev->chip_erase_cmd == 0x00) + if (info->dev.chip_erase_cmd == 0x00) return ERROR_FLASH_OPER_UNSUPPORTED; retval = jtagspi_write_enable(bank); if (retval != ERROR_OK) return retval; - jtagspi_cmd(bank, info->dev->chip_erase_cmd, NULL, NULL, 0); - retval = jtagspi_wait(bank, bank->num_sectors*JTAGSPI_MAX_TIMEOUT); + + jtagspi_cmd(bank, info->dev.chip_erase_cmd, NULL, 0, NULL, 0); + if (retval != ERROR_OK) + return retval; + + retval = jtagspi_wait(bank, bank->num_sectors * JTAGSPI_MAX_TIMEOUT); LOG_INFO("took %" PRId64 " ms", timeval_ms() - t0); return retval; } +static uint8_t *fill_addr(uint32_t addr, unsigned int addr_len, uint8_t *buffer) +{ + for (buffer += addr_len; addr_len > 0; --addr_len) { + *--buffer = addr; + addr >>= 8; + } + + return buffer; +} + static int jtagspi_sector_erase(struct flash_bank *bank, unsigned int sector) { struct jtagspi_flash_bank *info = bank->driver_priv; int retval; + uint8_t addr[sizeof(uint32_t)]; int64_t t0 = timeval_ms(); retval = jtagspi_write_enable(bank); if (retval != ERROR_OK) return retval; - jtagspi_cmd(bank, info->dev->erase_cmd, &bank->sectors[sector].offset, NULL, 0); + + /* ATXP032/064/128 use always 4-byte addresses except for 0x03 read */ + unsigned int addr_len = info->always_4byte ? 4 : info->addr_len; + + retval = jtagspi_cmd(bank, info->dev.erase_cmd, fill_addr(bank->sectors[sector].offset, addr_len, addr), + addr_len, NULL, 0); + if (retval != ERROR_OK) + return retval; + retval = jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT); LOG_INFO("sector %u took %" PRId64 " ms", sector, timeval_ms() - t0); return retval; @@ -339,8 +597,9 @@ static int jtagspi_erase(struct flash_bank *bank, unsigned int first, } } - if (first == 0 && last == (bank->num_sectors - 1) - && info->dev->chip_erase_cmd != info->dev->erase_cmd) { + if (first == 0 && last == (bank->num_sectors - 1) && + info->dev.chip_erase_cmd != 0x00 && + info->dev.chip_erase_cmd != info->dev.erase_cmd) { LOG_DEBUG("Trying bulk erase."); retval = jtagspi_bulk_erase(bank); if (retval == ERROR_OK) @@ -349,7 +608,7 @@ static int jtagspi_erase(struct flash_bank *bank, unsigned int first, LOG_WARNING("Bulk flash erase failed. Falling back to sector erase."); } - if (info->dev->erase_cmd == 0x00) + if (info->dev.erase_cmd == 0x00) return ERROR_FLASH_OPER_UNSUPPORTED; for (unsigned int sector = first; sector <= last; sector++) { @@ -374,49 +633,93 @@ static int jtagspi_protect(struct flash_bank *bank, int set, unsigned int first, static int jtagspi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { struct jtagspi_flash_bank *info = bank->driver_priv; + uint32_t pagesize, currsize; + uint8_t addr[sizeof(uint32_t)]; + int retval; if (!(info->probed)) { - LOG_ERROR("Flash bank not yet probed."); + LOG_ERROR("Flash bank not probed."); return ERROR_FLASH_BANK_NOT_PROBED; } - jtagspi_cmd(bank, SPIFLASH_READ, &offset, buffer, -count*8); + /* if no sectorsize, use reasonable default */ + pagesize = info->dev.sectorsize ? info->dev.sectorsize : info->dev.pagesize; + if (pagesize == 0) + pagesize = (info->dev.size_in_bytes <= SPIFLASH_DEF_PAGESIZE) ? + info->dev.size_in_bytes : SPIFLASH_DEF_PAGESIZE; + + /* ATXP032/064/128 use always 4-byte addresses except for 0x03 read */ + unsigned int addr_len = ((info->dev.read_cmd != 0x03) && info->always_4byte) ? 4 : info->addr_len; + + while (count > 0) { + /* length up to end of current page */ + currsize = ((offset + pagesize) & ~(pagesize - 1)) - offset; + /* but no more than remaining size */ + currsize = (count < currsize) ? count : currsize; + + retval = jtagspi_cmd(bank, info->dev.read_cmd, fill_addr(offset, addr_len, addr), + addr_len, buffer, -currsize); + if (retval != ERROR_OK) { + LOG_ERROR("page read error"); + return retval; + } + LOG_DEBUG("read page at 0x%08" PRIx32, offset); + offset += currsize; + buffer += currsize; + count -= currsize; + } return ERROR_OK; } static int jtagspi_page_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { + struct jtagspi_flash_bank *info = bank->driver_priv; + uint8_t addr[sizeof(uint32_t)]; int retval; retval = jtagspi_write_enable(bank); if (retval != ERROR_OK) return retval; - jtagspi_cmd(bank, SPIFLASH_PAGE_PROGRAM, &offset, (uint8_t *) buffer, count*8); + + /* ATXP032/064/128 use always 4-byte addresses except for 0x03 read */ + unsigned int addr_len = ((info->dev.read_cmd != 0x03) && info->always_4byte) ? 4 : info->addr_len; + + retval = jtagspi_cmd(bank, info->dev.pprog_cmd, fill_addr(offset, addr_len, addr), + addr_len, (uint8_t *) buffer, count); + if (retval != ERROR_OK) + return retval; return jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT); } static int jtagspi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct jtagspi_flash_bank *info = bank->driver_priv; + uint32_t pagesize, currsize; int retval; - uint32_t n, pagesize; if (!(info->probed)) { - LOG_ERROR("Flash bank not yet probed."); + LOG_ERROR("Flash bank not probed."); return ERROR_FLASH_BANK_NOT_PROBED; } /* if no write pagesize, use reasonable default */ - pagesize = info->dev->pagesize ? info->dev->pagesize : SPIFLASH_DEF_PAGESIZE; + pagesize = info->dev.pagesize ? info->dev.pagesize : SPIFLASH_DEF_PAGESIZE; - for (n = 0; n < count; n += pagesize) { - retval = jtagspi_page_write(bank, buffer + n, offset + n, - MIN(count - n, pagesize)); + while (count > 0) { + /* length up to end of current page */ + currsize = ((offset + pagesize) & ~(pagesize - 1)) - offset; + /* but no more than remaining size */ + currsize = (count < currsize) ? count : currsize; + + retval = jtagspi_page_write(bank, buffer, offset, currsize); if (retval != ERROR_OK) { LOG_ERROR("page write error"); return retval; } - LOG_DEBUG("wrote page at 0x%08" PRIx32, offset + n); + LOG_DEBUG("wrote page at 0x%08" PRIx32, offset); + offset += currsize; + buffer += currsize; + count -= currsize; } return ERROR_OK; } @@ -430,22 +733,72 @@ static int jtagspi_info(struct flash_bank *bank, struct command_invocation *cmd) return ERROR_OK; } - command_print_sameline(cmd, "\nSPIFI flash information:\n" - " Device \'%s\' (ID 0x%08" PRIx32 ")\n", - info->dev->name, info->dev->device_id); + command_print_sameline(cmd, "flash \'%s\', device id = 0x%06" PRIx32 + ", flash size = %" PRIu32 " %sbytes\n(page size = %" PRIu32 + ", read = 0x%02" PRIx8 ", qread = 0x%02" PRIx8 + ", pprog = 0x%02" PRIx8 ", mass_erase = 0x%02" PRIx8 + ", sector size = %" PRIu32 " %sbytes, sector_erase = 0x%02" PRIx8 ")", + info->dev.name, info->dev.device_id & 0xFFFFFF, + bank->size / 4096 ? bank->size / 1024 : bank->size, + bank->size / 4096 ? "k" : "", info->dev.pagesize, + info->dev.read_cmd, info->dev.qread_cmd, + info->dev.pprog_cmd, info->dev.chip_erase_cmd, + info->dev.sectorsize / 4096 ? + info->dev.sectorsize / 1024 : info->dev.sectorsize, + info->dev.sectorsize / 4096 ? "k" : "", + info->dev.erase_cmd); return ERROR_OK; } +static const struct command_registration jtagspi_exec_command_handlers[] = { + { + .name = "set", + .handler = jtagspi_handle_set, + .mode = COMMAND_EXEC, + .usage = "bank_id name chip_size page_size read_cmd unused pprg_cmd " + "[ mass_erase_cmd ] [ sector_size sector_erase_cmd ]", + .help = "Set device parameters if not autodetected.", + }, + { + .name = "cmd", + .handler = jtagspi_handle_cmd, + .mode = COMMAND_EXEC, + .usage = "bank_id num_resp cmd_byte ...", + .help = "Send low-level command cmd_byte and following bytes, read num_bytes.", + }, + { + .name = "always_4byte", + .handler = jtagspi_handle_always_4byte, + .mode = COMMAND_EXEC, + .usage = "bank_id [ on | off ]", + .help = "Use always 4-byte address except for basic 0x03.", + }, + + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration jtagspi_command_handlers[] = { + { + .name = "jtagspi", + .mode = COMMAND_ANY, + .help = "jtagspi command group", + .usage = "", + .chain = jtagspi_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + const struct flash_driver jtagspi_flash = { .name = "jtagspi", + .commands = jtagspi_command_handlers, .flash_bank_command = jtagspi_flash_bank_command, .erase = jtagspi_erase, .protect = jtagspi_protect, .write = jtagspi_write, .read = jtagspi_read, .probe = jtagspi_probe, - .auto_probe = jtagspi_probe, + .auto_probe = jtagspi_auto_probe, .erase_check = default_flash_blank_check, .info = jtagspi_info, .free_driver_priv = default_flash_free_driver_priv, From a9d0386411d1e372bf4d2187ff7b843bb5e9bfc6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 10:37:06 +0200 Subject: [PATCH 18/82] jtag/core: get rid of variable 'jtag' The variable 'jtag' is set to 'adapter_driver' during adapter initialization and is used: - to check if adapter has been initialized; - as local copy of adapter_driver. Introduce a static flag to check if the adapter has been already initialized and a convenience test function. Use the test function and the original value of adapter_driver in the code and drop the variable 'jtag'. Change-Id: I1b1c54d3b36d7b60390985d787c8449432788141 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6639 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/core.c | 68 ++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 2de5fda47..f0c000a24 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -129,11 +129,15 @@ static int speed_khz; static int rclk_fallback_speed_khz; static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; -/* FIXME: change name to this variable, it is not anymore JTAG only */ -static struct adapter_driver *jtag; - extern struct adapter_driver *adapter_driver; +static bool adapter_initialized; + +static bool is_adapter_initialized(void) +{ + return adapter_initialized; +} + void jtag_set_flush_queue_sleep(int ms) { jtag_flush_queue_sleep = ms; @@ -505,7 +509,7 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state) { int retval; - if (!(jtag->jtag_ops->supported & DEBUG_CAP_TMS_SEQ)) + if (!(adapter_driver->jtag_ops->supported & DEBUG_CAP_TMS_SEQ)) return ERROR_JTAG_NOT_IMPLEMENTED; jtag_checks(); @@ -627,7 +631,7 @@ static int adapter_system_reset(int req_srst) /* Maybe change SRST signal state */ if (jtag_srst != req_srst) { - retval = jtag->reset(0, req_srst); + retval = adapter_driver->reset(0, req_srst); if (retval != ERROR_OK) { LOG_ERROR("SRST error"); return ERROR_FAIL; @@ -764,7 +768,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) int new_srst = 0; int new_trst = 0; - if (!jtag->reset) { + if (!adapter_driver->reset) { legacy_jtag_add_reset(req_tlr_or_trst, req_srst); return; } @@ -813,7 +817,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) /* guarantee jtag queue empty before changing reset status */ jtag_execute_queue(); - retval = jtag->reset(new_trst, new_srst); + retval = adapter_driver->reset(new_trst, new_srst); if (retval != ERROR_OK) { jtag_set_error(retval); LOG_ERROR("TRST/SRST error"); @@ -933,7 +937,7 @@ void jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *ma int default_interface_jtag_execute_queue(void) { - if (!jtag) { + if (!is_adapter_initialized()) { LOG_ERROR("No JTAG interface configured yet. " "Issue 'init' command in startup scripts " "before communicating with targets."); @@ -949,11 +953,11 @@ int default_interface_jtag_execute_queue(void) * The fix can be applied immediately after next release (v0.11.0 ?) */ LOG_ERROR("JTAG API jtag_execute_queue() called on non JTAG interface"); - if (!jtag->jtag_ops || !jtag->jtag_ops->execute_queue) + if (!adapter_driver->jtag_ops || !adapter_driver->jtag_ops->execute_queue) return ERROR_OK; } - int result = jtag->jtag_ops->execute_queue(); + int result = adapter_driver->jtag_ops->execute_queue(); struct jtag_command *cmd = jtag_command_queue; while (debug_level >= LOG_LVL_DEBUG_IO && cmd) { @@ -1508,7 +1512,7 @@ void jtag_tap_free(struct jtag_tap *tap) */ int adapter_init(struct command_context *cmd_ctx) { - if (jtag) + if (is_adapter_initialized()) return ERROR_OK; if (!adapter_driver) { @@ -1522,9 +1526,9 @@ int adapter_init(struct command_context *cmd_ctx) retval = adapter_driver->init(); if (retval != ERROR_OK) return retval; - jtag = adapter_driver; + adapter_initialized = true; - if (!jtag->speed) { + if (!adapter_driver->speed) { LOG_INFO("This adapter doesn't support configurable speed"); return ERROR_OK; } @@ -1541,7 +1545,7 @@ int adapter_init(struct command_context *cmd_ctx) retval = jtag_get_speed(&jtag_speed_var); if (retval != ERROR_OK) return retval; - retval = jtag->speed(jtag_speed_var); + retval = adapter_driver->speed(jtag_speed_var); if (retval != ERROR_OK) return retval; retval = jtag_get_speed_readable(&actual_khz); @@ -1643,9 +1647,9 @@ int jtag_init_inner(struct command_context *cmd_ctx) int adapter_quit(void) { - if (jtag && jtag->quit) { + if (is_adapter_initialized() && adapter_driver->quit) { /* close the JTAG interface */ - int result = jtag->quit(); + int result = adapter_driver->quit(); if (result != ERROR_OK) LOG_ERROR("failed: %d", result); } @@ -1776,15 +1780,15 @@ static int adapter_khz_to_speed(unsigned khz, int *speed) { LOG_DEBUG("convert khz to interface specific speed value"); speed_khz = khz; - if (!jtag) + if (!is_adapter_initialized()) return ERROR_OK; LOG_DEBUG("have interface set up"); - if (!jtag->khz) { + if (!adapter_driver->khz) { LOG_ERROR("Translation from khz to jtag_speed not implemented"); return ERROR_FAIL; } int speed_div1; - int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1); + int retval = adapter_driver->khz(jtag_get_speed_khz(), &speed_div1); if (retval != ERROR_OK) return retval; *speed = speed_div1; @@ -1805,7 +1809,7 @@ static int jtag_set_speed(int speed) { /* this command can be called during CONFIG, * in which case jtag isn't initialized */ - return jtag ? jtag->speed(speed) : ERROR_OK; + return is_adapter_initialized() ? adapter_driver->speed(speed) : ERROR_OK; } int jtag_config_khz(unsigned khz) @@ -1849,13 +1853,13 @@ int jtag_get_speed_readable(int *khz) int retval = jtag_get_speed(&jtag_speed_var); if (retval != ERROR_OK) return retval; - if (!jtag) + if (!is_adapter_initialized()) return ERROR_OK; - if (!jtag->speed_div) { + if (!adapter_driver->speed_div) { LOG_ERROR("Translation from jtag_speed to khz not implemented"); return ERROR_FAIL; } - return jtag->speed_div(jtag_speed_var, khz); + return adapter_driver->speed_div(jtag_speed_var, khz); } void jtag_set_verify(bool enable) @@ -1880,14 +1884,14 @@ bool jtag_will_verify_capture_ir(void) int jtag_power_dropout(int *dropout) { - if (!jtag) { + if (!is_adapter_initialized()) { /* TODO: as the jtag interface is not valid all * we can do at the moment is exit OpenOCD */ LOG_ERROR("No Valid JTAG Interface Configured."); exit(-1); } - if (jtag->power_dropout) - return jtag->power_dropout(dropout); + if (adapter_driver->power_dropout) + return adapter_driver->power_dropout(dropout); *dropout = 0; /* by default we can't detect power dropout */ return ERROR_OK; @@ -1895,8 +1899,8 @@ int jtag_power_dropout(int *dropout) int jtag_srst_asserted(int *srst_asserted) { - if (jtag->srst_asserted) - return jtag->srst_asserted(srst_asserted); + if (adapter_driver->srst_asserted) + return adapter_driver->srst_asserted(srst_asserted); *srst_asserted = 0; /* by default we can't detect srst asserted */ return ERROR_OK; @@ -2089,8 +2093,8 @@ int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler) { - if (jtag->config_trace) { - return jtag->config_trace(enabled, pin_protocol, port_size, trace_freq, + if (adapter_driver->config_trace) { + return adapter_driver->config_trace(enabled, pin_protocol, port_size, trace_freq, traceclkin_freq, prescaler); } else if (enabled) { LOG_ERROR("The selected interface does not support tracing"); @@ -2102,8 +2106,8 @@ int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, int adapter_poll_trace(uint8_t *buf, size_t *size) { - if (jtag->poll_trace) - return jtag->poll_trace(buf, size); + if (adapter_driver->poll_trace) + return adapter_driver->poll_trace(buf, size); return ERROR_FAIL; } From 4cb3c9fae2a6a6cb5cf2c664179edace22abf5f6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 6 Oct 2021 23:17:30 +0200 Subject: [PATCH 19/82] jtag/adapter: move 'usb location' code in adapter.c The configuration code for adapter parameters is spread around. Add a struct in adapter.c aimed at containing all the adapter's configuration data. Move in adapter.c the code related to configuring 'usb location' and the copyright tag. Add adapter.h to export the functions. While there: - rework the copyright and the SPDX tag; - rename the 'usb location' functions; - remove the JTAG_SRC variable in Makefile.am. Change-Id: I4fe0d32991a8a30e315807180688035ae9ee01ce Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6640 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/Makefile.am | 6 +- src/jtag/adapter.c | 123 ++++++++++++++++++++++------- src/jtag/adapter.h | 19 +++++ src/jtag/drivers/Makefile.am | 2 - src/jtag/drivers/ftdi.c | 4 +- src/jtag/drivers/jlink.c | 6 +- src/jtag/drivers/jtag_usb_common.c | 82 ------------------- src/jtag/drivers/jtag_usb_common.h | 17 ---- src/jtag/drivers/libusb_helper.c | 9 ++- 9 files changed, 126 insertions(+), 142 deletions(-) create mode 100644 src/jtag/adapter.h delete mode 100644 src/jtag/drivers/jtag_usb_common.c delete mode 100644 src/jtag/drivers/jtag_usb_common.h diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am index 4ed5e7aa0..cbdfb2054 100644 --- a/src/jtag/Makefile.am +++ b/src/jtag/Makefile.am @@ -1,6 +1,5 @@ noinst_LTLIBRARIES += %D%/libjtag.la -JTAG_SRCS = %D%/commands.c %C%_libjtag_la_LIBADD = if HLADAPTER @@ -18,6 +17,8 @@ include %D%/drivers/Makefile.am %C%_libjtag_la_SOURCES = \ %D%/adapter.c \ + %D%/adapter.h \ + %D%/commands.c \ %D%/core.c \ %D%/interface.c \ %D%/interfaces.c \ @@ -31,7 +32,6 @@ include %D%/drivers/Makefile.am %D%/jtag.h \ %D%/swd.h \ %D%/swim.h \ - %D%/tcl.h \ - $(JTAG_SRCS) + %D%/tcl.h STARTUP_TCL_SRCS += %D%/startup.tcl diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 80d5ab048..47a1d794b 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -1,41 +1,22 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2005 by Dominic Rath + * Copyright (C) 2007-2010 Øyvind Harboe + * Copyright (C) 2009 SoftPLC Corporation, http://softplc.com, Dick Hollenbeck + * Copyright (C) 2009 Zachary T Welch + * Copyright (C) 2018 Pengutronix, Oleksij Rempel + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include "adapter.h" #include "jtag.h" #include "minidriver.h" #include "interface.h" #include "interfaces.h" #include -#include #ifdef HAVE_STRINGS_H #include @@ -49,6 +30,88 @@ struct adapter_driver *adapter_driver; const char * const jtag_only[] = { "jtag", NULL }; +/** + * Adapter configuration + */ +static struct { + char *usb_location; +} adapter_config; + +/* + * 1 char: bus + * 2 * 7 chars: max 7 ports + * 1 char: test for overflow + * ------ + * 16 chars + */ +#define USB_MAX_LOCATION_LENGTH 16 + +#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS +static void adapter_usb_set_location(const char *location) +{ + if (strnlen(location, USB_MAX_LOCATION_LENGTH) == USB_MAX_LOCATION_LENGTH) + LOG_WARNING("usb location string is too long!!"); + + free(adapter_config.usb_location); + + adapter_config.usb_location = strndup(location, USB_MAX_LOCATION_LENGTH); +} +#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */ + +const char *adapter_usb_get_location(void) +{ + return adapter_config.usb_location; +} + +bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len) +{ + size_t path_step, string_length; + char *ptr, *loc; + bool equal = false; + + if (!adapter_usb_get_location()) + return equal; + + /* strtok need non const char */ + loc = strndup(adapter_usb_get_location(), USB_MAX_LOCATION_LENGTH); + string_length = strnlen(loc, USB_MAX_LOCATION_LENGTH); + + ptr = strtok(loc, "-"); + if (!ptr) { + LOG_WARNING("no '-' in usb path\n"); + goto done; + } + + string_length -= strnlen(ptr, string_length); + /* check bus mismatch */ + if (atoi(ptr) != dev_bus) + goto done; + + path_step = 0; + while (path_step < path_len) { + ptr = strtok(NULL, "."); + + /* no more tokens in path */ + if (!ptr) + break; + + /* path mismatch at some step */ + if (path_step < path_len && atoi(ptr) != port_path[path_step]) + break; + + path_step++; + string_length -= strnlen(ptr, string_length) + 1; + }; + + /* walked the full path, all elements match */ + if (path_step == path_len && !string_length) + equal = true; + +done: + free(loc); + return equal; +} + static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { struct jim_getopt_info goi; @@ -501,9 +564,9 @@ COMMAND_HANDLER(handle_adapter_reset_de_assert) COMMAND_HANDLER(handle_usb_location_command) { if (CMD_ARGC == 1) - jtag_usb_set_location(CMD_ARGV[0]); + adapter_usb_set_location(CMD_ARGV[0]); - command_print(CMD, "adapter usb location: %s", jtag_usb_get_location()); + command_print(CMD, "adapter usb location: %s", adapter_usb_get_location()); return ERROR_OK; } diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h new file mode 100644 index 000000000..854ee9ce6 --- /dev/null +++ b/src/jtag/adapter.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2018 Pengutronix, Oleksij Rempel + */ + +#ifndef OPENOCD_JTAG_ADAPTER_H +#define OPENOCD_JTAG_ADAPTER_H + +#include +#include +#include + +/** @returns USB location string set with command 'adapter usb location' */ +const char *adapter_usb_get_location(void); + +/** @returns true if USB location string is "-[.[...]]" */ +bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len); + +#endif /* OPENOCD_JTAG_ADAPTER_H */ diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index da60f366e..c2161523d 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -19,7 +19,6 @@ DRIVERFILES = # Standard Driver: common files DRIVERFILES += %D%/driver.c -DRIVERFILES += %D%/jtag_usb_common.c if USE_LIBUSB1 DRIVERFILES += %D%/libusb_helper.c @@ -187,7 +186,6 @@ endif DRIVERHEADERS = \ %D%/bitbang.h \ %D%/bitq.h \ - %D%/jtag_usb_common.h \ %D%/libftdi_helper.h \ %D%/libusb_helper.h \ %D%/cmsis_dap.h \ diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 82298c23d..5e7eae073 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -69,7 +69,7 @@ #endif /* project specific includes */ -#include +#include #include #include #include @@ -672,7 +672,7 @@ static int ftdi_initialize(void) for (int i = 0; ftdi_vid[i] || ftdi_pid[i]; i++) { mpsse_ctx = mpsse_open(&ftdi_vid[i], &ftdi_pid[i], ftdi_device_desc, - ftdi_serial, jtag_usb_get_location(), ftdi_channel); + ftdi_serial, adapter_usb_get_location(), ftdi_channel); if (mpsse_ctx) break; } diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 53ae1dfae..12ac05fa6 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include @@ -547,7 +547,7 @@ static bool jlink_usb_location_equal(struct jaylink_device *dev) return false; } - equal = jtag_usb_location_equal(bus, ports, num_ports); + equal = adapter_usb_location_equal(bus, ports, num_ports); free(ports); return equal; @@ -573,7 +573,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device) return ERROR_JTAG_INIT_FAILED; } - use_usb_location = !!jtag_usb_get_location(); + use_usb_location = !!adapter_usb_get_location(); if (!use_serial_number && !use_usb_address && !use_usb_location && num_devices > 1) { LOG_ERROR("Multiple devices found, specify the desired device"); diff --git a/src/jtag/drivers/jtag_usb_common.c b/src/jtag/drivers/jtag_usb_common.c deleted file mode 100644 index 94cd7e74d..000000000 --- a/src/jtag/drivers/jtag_usb_common.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0+ - * Copyright (c) 2018 Pengutronix, Oleksij Rempel - */ - -#include -#include - -#include "jtag_usb_common.h" - -static char *jtag_usb_location; -/* - * 1 char: bus - * 2 * 7 chars: max 7 ports - * 1 char: test for overflow - * ------ - * 16 chars - */ -#define JTAG_USB_MAX_LOCATION_LENGTH 16 - -void jtag_usb_set_location(const char *location) -{ - if (strnlen(location, JTAG_USB_MAX_LOCATION_LENGTH) == - JTAG_USB_MAX_LOCATION_LENGTH) - LOG_WARNING("usb location string is too long!!\n"); - - free(jtag_usb_location); - - jtag_usb_location = strndup(location, JTAG_USB_MAX_LOCATION_LENGTH); -} - -const char *jtag_usb_get_location(void) -{ - return jtag_usb_location; -} - -bool jtag_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, - size_t path_len) -{ - size_t path_step, string_length; - char *ptr, *loc; - bool equal = false; - - /* strtok need non const char */ - loc = strndup(jtag_usb_get_location(), JTAG_USB_MAX_LOCATION_LENGTH); - string_length = strnlen(loc, JTAG_USB_MAX_LOCATION_LENGTH); - - ptr = strtok(loc, "-"); - if (!ptr) { - LOG_WARNING("no '-' in usb path\n"); - goto done; - } - - string_length -= strnlen(ptr, string_length); - /* check bus mismatch */ - if (atoi(ptr) != dev_bus) - goto done; - - path_step = 0; - while (path_step < path_len) { - ptr = strtok(NULL, "."); - - /* no more tokens in path */ - if (!ptr) - break; - - /* path mismatch at some step */ - if (path_step < path_len && atoi(ptr) != port_path[path_step]) - break; - - path_step++; - string_length -= strnlen(ptr, string_length) + 1; - }; - - /* walked the full path, all elements match */ - if (path_step == path_len && !string_length) - equal = true; - -done: - free(loc); - return equal; -} diff --git a/src/jtag/drivers/jtag_usb_common.h b/src/jtag/drivers/jtag_usb_common.h deleted file mode 100644 index c4c28cc91..000000000 --- a/src/jtag/drivers/jtag_usb_common.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0+ - * Copyright (c) 2018 Pengutronix, Oleksij Rempel - */ - -#ifndef OPENOCD_JTAG_USB_COMMON_H -#define OPENOCD_JTAG_USB_COMMON_H - -#include -#include - -void jtag_usb_set_location(const char *location); -const char *jtag_usb_get_location(void); -bool jtag_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, - size_t path_len); - -#endif /* OPENOCD_JTAG_USB_COMMON_H */ diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index 3308d8742..b8f1124e3 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -20,8 +20,11 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif + +#include + #include -#include +#include #include "libusb_helper.h" /* @@ -85,7 +88,7 @@ static bool jtag_libusb_location_equal(struct libusb_device *device) } dev_bus = libusb_get_bus_number(device); - return jtag_usb_location_equal(dev_bus, port_path, path_len); + return adapter_usb_location_equal(dev_bus, port_path, path_len); } #else /* HAVE_LIBUSB_GET_PORT_NUMBERS */ static bool jtag_libusb_location_equal(struct libusb_device *device) @@ -177,7 +180,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], if (!jtag_libusb_match_ids(&dev_desc, vids, pids)) continue; - if (jtag_usb_get_location() && !jtag_libusb_location_equal(devs[idx])) + if (adapter_usb_get_location() && !jtag_libusb_location_equal(devs[idx])) continue; err_code = libusb_open(devs[idx], &libusb_handle); From b8ec1d4e7ddcb4cc3993a2d31225fd17527f267d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 12:13:28 +0200 Subject: [PATCH 20/82] jtag: move adapter init/quit and speed to adapter.c The configuration code for adapter parameters is spread around. Move in adapter.c the code that handles the configuration of adapter speed. For convenience, move also the functions adapter_init() and adapter_quit(), that anyway have no reason to be in file core.c To simplify the review, the code moved is not modified. It will be cleaned and adapted in the following changes. Change-Id: I2b38975a0cd2e74d3d2de6c56ea17818ff225fd8 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6641 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/adapter.c | 182 ++++++++++++++++++++++++++++++++++++++++++++ src/jtag/adapter.h | 3 + src/jtag/core.c | 183 +-------------------------------------------- 3 files changed, 186 insertions(+), 182 deletions(-) diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 47a1d794b..bdb131cf0 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -37,6 +37,188 @@ static struct { char *usb_location; } adapter_config; +/* speed in kHz*/ +static int speed_khz; +/* speed to fallback to when RCLK is requested but not supported */ +static int rclk_fallback_speed_khz; +static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; + +static bool adapter_initialized; + +bool is_adapter_initialized(void) +{ + return adapter_initialized; +} + +/** + * Do low-level setup like initializing registers, output signals, + * and clocking. + */ +int adapter_init(struct command_context *cmd_ctx) +{ + if (is_adapter_initialized()) + return ERROR_OK; + + if (!adapter_driver) { + /* nothing was previously specified by "adapter driver" command */ + LOG_ERROR("Debug Adapter has to be specified, " + "see \"adapter driver\" command"); + return ERROR_JTAG_INVALID_INTERFACE; + } + + int retval; + retval = adapter_driver->init(); + if (retval != ERROR_OK) + return retval; + adapter_initialized = true; + + if (!adapter_driver->speed) { + LOG_INFO("This adapter doesn't support configurable speed"); + return ERROR_OK; + } + + if (clock_mode == CLOCK_MODE_UNSELECTED) { + LOG_ERROR("An adapter speed is not selected in the init script." + " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed."); + return ERROR_JTAG_INIT_FAILED; + } + + int requested_khz = jtag_get_speed_khz(); + int actual_khz = requested_khz; + int jtag_speed_var = 0; + retval = jtag_get_speed(&jtag_speed_var); + if (retval != ERROR_OK) + return retval; + retval = adapter_driver->speed(jtag_speed_var); + if (retval != ERROR_OK) + return retval; + retval = jtag_get_speed_readable(&actual_khz); + if (retval != ERROR_OK) + LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var); + else if (actual_khz) { + /* Adaptive clocking -- JTAG-specific */ + if ((clock_mode == CLOCK_MODE_RCLK) + || ((clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) { + LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz" + , actual_khz); + } else + LOG_INFO("clock speed %d kHz", actual_khz); + } else + LOG_INFO("RCLK (adaptive clock speed)"); + + return ERROR_OK; +} + +int adapter_quit(void) +{ + if (is_adapter_initialized() && adapter_driver->quit) { + /* close the JTAG interface */ + int result = adapter_driver->quit(); + if (result != ERROR_OK) + LOG_ERROR("failed: %d", result); + } + + struct jtag_tap *t = jtag_all_taps(); + while (t) { + struct jtag_tap *n = t->next_tap; + jtag_tap_free(t); + t = n; + } + + return ERROR_OK; +} + +unsigned jtag_get_speed_khz(void) +{ + return speed_khz; +} + +static int adapter_khz_to_speed(unsigned khz, int *speed) +{ + LOG_DEBUG("convert khz to interface specific speed value"); + speed_khz = khz; + if (!is_adapter_initialized()) + return ERROR_OK; + LOG_DEBUG("have interface set up"); + if (!adapter_driver->khz) { + LOG_ERROR("Translation from khz to jtag_speed not implemented"); + return ERROR_FAIL; + } + int speed_div1; + int retval = adapter_driver->khz(jtag_get_speed_khz(), &speed_div1); + if (retval != ERROR_OK) + return retval; + *speed = speed_div1; + return ERROR_OK; +} + +static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int *speed) +{ + int retval = adapter_khz_to_speed(0, speed); + if ((retval != ERROR_OK) && fallback_speed_khz) { + LOG_DEBUG("trying fallback speed..."); + retval = adapter_khz_to_speed(fallback_speed_khz, speed); + } + return retval; +} + +static int jtag_set_speed(int speed) +{ + /* this command can be called during CONFIG, + * in which case jtag isn't initialized */ + return is_adapter_initialized() ? adapter_driver->speed(speed) : ERROR_OK; +} + +int jtag_config_khz(unsigned khz) +{ + LOG_DEBUG("handle jtag khz"); + clock_mode = CLOCK_MODE_KHZ; + int speed = 0; + int retval = adapter_khz_to_speed(khz, &speed); + return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); +} + +int jtag_config_rclk(unsigned fallback_speed_khz) +{ + LOG_DEBUG("handle jtag rclk"); + clock_mode = CLOCK_MODE_RCLK; + rclk_fallback_speed_khz = fallback_speed_khz; + int speed = 0; + int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed); + return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); +} + +int jtag_get_speed(int *speed) +{ + switch (clock_mode) { + case CLOCK_MODE_KHZ: + adapter_khz_to_speed(jtag_get_speed_khz(), speed); + break; + case CLOCK_MODE_RCLK: + jtag_rclk_to_speed(rclk_fallback_speed_khz, speed); + break; + default: + LOG_ERROR("BUG: unknown jtag clock mode"); + return ERROR_FAIL; + } + return ERROR_OK; +} + +int jtag_get_speed_readable(int *khz) +{ + int jtag_speed_var = 0; + int retval = jtag_get_speed(&jtag_speed_var); + if (retval != ERROR_OK) + return retval; + if (!is_adapter_initialized()) + return ERROR_OK; + if (!adapter_driver->speed_div) { + LOG_ERROR("Translation from jtag_speed to khz not implemented"); + return ERROR_FAIL; + } + return adapter_driver->speed_div(jtag_speed_var, khz); +} + /* * 1 char: bus * 2 * 7 chars: max 7 ports diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index 854ee9ce6..fe9a6318c 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -10,6 +10,9 @@ #include #include +/** @returns true if adapter has been initialized */ +bool is_adapter_initialized(void); + /** @returns USB location string set with command 'adapter usb location' */ const char *adapter_usb_get_location(void); diff --git a/src/jtag/core.c b/src/jtag/core.c index f0c000a24..29ab6cc1c 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -30,6 +30,7 @@ #include "config.h" #endif +#include "adapter.h" #include "jtag.h" #include "swd.h" #include "interface.h" @@ -123,21 +124,8 @@ struct jtag_event_callback { /* callbacks to inform high-level handlers about JTAG state changes */ static struct jtag_event_callback *jtag_event_callbacks; -/* speed in kHz*/ -static int speed_khz; -/* speed to fallback to when RCLK is requested but not supported */ -static int rclk_fallback_speed_khz; -static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; - extern struct adapter_driver *adapter_driver; -static bool adapter_initialized; - -static bool is_adapter_initialized(void) -{ - return adapter_initialized; -} - void jtag_set_flush_queue_sleep(int ms) { jtag_flush_queue_sleep = ms; @@ -1506,65 +1494,6 @@ void jtag_tap_free(struct jtag_tap *tap) free(tap); } -/** - * Do low-level setup like initializing registers, output signals, - * and clocking. - */ -int adapter_init(struct command_context *cmd_ctx) -{ - if (is_adapter_initialized()) - return ERROR_OK; - - if (!adapter_driver) { - /* nothing was previously specified by "adapter driver" command */ - LOG_ERROR("Debug Adapter has to be specified, " - "see \"adapter driver\" command"); - return ERROR_JTAG_INVALID_INTERFACE; - } - - int retval; - retval = adapter_driver->init(); - if (retval != ERROR_OK) - return retval; - adapter_initialized = true; - - if (!adapter_driver->speed) { - LOG_INFO("This adapter doesn't support configurable speed"); - return ERROR_OK; - } - - if (clock_mode == CLOCK_MODE_UNSELECTED) { - LOG_ERROR("An adapter speed is not selected in the init script." - " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed."); - return ERROR_JTAG_INIT_FAILED; - } - - int requested_khz = jtag_get_speed_khz(); - int actual_khz = requested_khz; - int jtag_speed_var = 0; - retval = jtag_get_speed(&jtag_speed_var); - if (retval != ERROR_OK) - return retval; - retval = adapter_driver->speed(jtag_speed_var); - if (retval != ERROR_OK) - return retval; - retval = jtag_get_speed_readable(&actual_khz); - if (retval != ERROR_OK) - LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var); - else if (actual_khz) { - /* Adaptive clocking -- JTAG-specific */ - if ((clock_mode == CLOCK_MODE_RCLK) - || ((clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) { - LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz" - , actual_khz); - } else - LOG_INFO("clock speed %d kHz", actual_khz); - } else - LOG_INFO("RCLK (adaptive clock speed)"); - - return ERROR_OK; -} - int jtag_init_inner(struct command_context *cmd_ctx) { struct jtag_tap *tap; @@ -1645,25 +1574,6 @@ int jtag_init_inner(struct command_context *cmd_ctx) return ERROR_OK; } -int adapter_quit(void) -{ - if (is_adapter_initialized() && adapter_driver->quit) { - /* close the JTAG interface */ - int result = adapter_driver->quit(); - if (result != ERROR_OK) - LOG_ERROR("failed: %d", result); - } - - struct jtag_tap *t = jtag_all_taps(); - while (t) { - struct jtag_tap *n = t->next_tap; - jtag_tap_free(t); - t = n; - } - - return ERROR_OK; -} - int swd_init_reset(struct command_context *cmd_ctx) { int retval, retval1; @@ -1771,97 +1681,6 @@ int jtag_init(struct command_context *cmd_ctx) return ERROR_OK; } -unsigned jtag_get_speed_khz(void) -{ - return speed_khz; -} - -static int adapter_khz_to_speed(unsigned khz, int *speed) -{ - LOG_DEBUG("convert khz to interface specific speed value"); - speed_khz = khz; - if (!is_adapter_initialized()) - return ERROR_OK; - LOG_DEBUG("have interface set up"); - if (!adapter_driver->khz) { - LOG_ERROR("Translation from khz to jtag_speed not implemented"); - return ERROR_FAIL; - } - int speed_div1; - int retval = adapter_driver->khz(jtag_get_speed_khz(), &speed_div1); - if (retval != ERROR_OK) - return retval; - *speed = speed_div1; - return ERROR_OK; -} - -static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int *speed) -{ - int retval = adapter_khz_to_speed(0, speed); - if ((retval != ERROR_OK) && fallback_speed_khz) { - LOG_DEBUG("trying fallback speed..."); - retval = adapter_khz_to_speed(fallback_speed_khz, speed); - } - return retval; -} - -static int jtag_set_speed(int speed) -{ - /* this command can be called during CONFIG, - * in which case jtag isn't initialized */ - return is_adapter_initialized() ? adapter_driver->speed(speed) : ERROR_OK; -} - -int jtag_config_khz(unsigned khz) -{ - LOG_DEBUG("handle jtag khz"); - clock_mode = CLOCK_MODE_KHZ; - int speed = 0; - int retval = adapter_khz_to_speed(khz, &speed); - return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); -} - -int jtag_config_rclk(unsigned fallback_speed_khz) -{ - LOG_DEBUG("handle jtag rclk"); - clock_mode = CLOCK_MODE_RCLK; - rclk_fallback_speed_khz = fallback_speed_khz; - int speed = 0; - int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed); - return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); -} - -int jtag_get_speed(int *speed) -{ - switch (clock_mode) { - case CLOCK_MODE_KHZ: - adapter_khz_to_speed(jtag_get_speed_khz(), speed); - break; - case CLOCK_MODE_RCLK: - jtag_rclk_to_speed(rclk_fallback_speed_khz, speed); - break; - default: - LOG_ERROR("BUG: unknown jtag clock mode"); - return ERROR_FAIL; - } - return ERROR_OK; -} - -int jtag_get_speed_readable(int *khz) -{ - int jtag_speed_var = 0; - int retval = jtag_get_speed(&jtag_speed_var); - if (retval != ERROR_OK) - return retval; - if (!is_adapter_initialized()) - return ERROR_OK; - if (!adapter_driver->speed_div) { - LOG_ERROR("Translation from jtag_speed to khz not implemented"); - return ERROR_FAIL; - } - return adapter_driver->speed_div(jtag_speed_var, khz); -} - void jtag_set_verify(bool enable) { jtag_verify = enable; From ba7d0bc49148d89c27b8208120de9783a89058a7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 12:21:18 +0200 Subject: [PATCH 21/82] jtag/adapter: move config vars in struct adapter_config Move the static variables used to configure the adapter in the struct adapter_config. Change-Id: I1639e2bd39d0cbb12c71dfa347025558879d8b1d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6642 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/adapter.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index bdb131cf0..991338be8 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -30,24 +30,26 @@ struct adapter_driver *adapter_driver; const char * const jtag_only[] = { "jtag", NULL }; +enum adapter_clk_mode { + CLOCK_MODE_UNSELECTED = 0, + CLOCK_MODE_KHZ, + CLOCK_MODE_RCLK +}; + /** * Adapter configuration */ static struct { + bool adapter_initialized; char *usb_location; + enum adapter_clk_mode clock_mode; + int speed_khz; + int rclk_fallback_speed_khz; } adapter_config; -/* speed in kHz*/ -static int speed_khz; -/* speed to fallback to when RCLK is requested but not supported */ -static int rclk_fallback_speed_khz; -static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; - -static bool adapter_initialized; - bool is_adapter_initialized(void) { - return adapter_initialized; + return adapter_config.adapter_initialized; } /** @@ -70,14 +72,14 @@ int adapter_init(struct command_context *cmd_ctx) retval = adapter_driver->init(); if (retval != ERROR_OK) return retval; - adapter_initialized = true; + adapter_config.adapter_initialized = true; if (!adapter_driver->speed) { LOG_INFO("This adapter doesn't support configurable speed"); return ERROR_OK; } - if (clock_mode == CLOCK_MODE_UNSELECTED) { + if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) { LOG_ERROR("An adapter speed is not selected in the init script." " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed."); return ERROR_JTAG_INIT_FAILED; @@ -97,8 +99,8 @@ int adapter_init(struct command_context *cmd_ctx) LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var); else if (actual_khz) { /* Adaptive clocking -- JTAG-specific */ - if ((clock_mode == CLOCK_MODE_RCLK) - || ((clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) { + if ((adapter_config.clock_mode == CLOCK_MODE_RCLK) + || ((adapter_config.clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) { LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz" , actual_khz); } else @@ -130,13 +132,13 @@ int adapter_quit(void) unsigned jtag_get_speed_khz(void) { - return speed_khz; + return adapter_config.speed_khz; } static int adapter_khz_to_speed(unsigned khz, int *speed) { LOG_DEBUG("convert khz to interface specific speed value"); - speed_khz = khz; + adapter_config.speed_khz = khz; if (!is_adapter_initialized()) return ERROR_OK; LOG_DEBUG("have interface set up"); @@ -172,7 +174,7 @@ static int jtag_set_speed(int speed) int jtag_config_khz(unsigned khz) { LOG_DEBUG("handle jtag khz"); - clock_mode = CLOCK_MODE_KHZ; + adapter_config.clock_mode = CLOCK_MODE_KHZ; int speed = 0; int retval = adapter_khz_to_speed(khz, &speed); return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); @@ -181,8 +183,8 @@ int jtag_config_khz(unsigned khz) int jtag_config_rclk(unsigned fallback_speed_khz) { LOG_DEBUG("handle jtag rclk"); - clock_mode = CLOCK_MODE_RCLK; - rclk_fallback_speed_khz = fallback_speed_khz; + adapter_config.clock_mode = CLOCK_MODE_RCLK; + adapter_config.rclk_fallback_speed_khz = fallback_speed_khz; int speed = 0; int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed); return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); @@ -190,12 +192,12 @@ int jtag_config_rclk(unsigned fallback_speed_khz) int jtag_get_speed(int *speed) { - switch (clock_mode) { + switch (adapter_config.clock_mode) { case CLOCK_MODE_KHZ: adapter_khz_to_speed(jtag_get_speed_khz(), speed); break; case CLOCK_MODE_RCLK: - jtag_rclk_to_speed(rclk_fallback_speed_khz, speed); + jtag_rclk_to_speed(adapter_config.rclk_fallback_speed_khz, speed); break; default: LOG_ERROR("BUG: unknown jtag clock mode"); From 679dcd0b52f6bafe848eb48e714764d37a101bb5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 14:30:43 +0200 Subject: [PATCH 22/82] jtag: move prototype of adapter init/quit and speed to adapter.h After moved the code, align the include files. Change-Id: I514a3020648816810d69f76c2ec4f6e52a1c57ab Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6643 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/adapter.h | 32 ++++++++++++++++++++++++++++++++ src/jtag/drivers/amt_jtagaccel.c | 1 + src/jtag/drivers/cmsis_dap.c | 1 + src/jtag/drivers/parport.c | 1 + src/jtag/drivers/vsllink.c | 1 + src/jtag/jtag.h | 31 ------------------------------- src/jtag/tcl.c | 1 + src/openocd.c | 1 + src/target/mips32_pracc.c | 1 + src/target/mips64_pracc.c | 1 + 10 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index fe9a6318c..b2405e984 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -10,6 +10,14 @@ #include #include +struct command_context; + +/** Initialize debug adapter upon startup. */ +int adapter_init(struct command_context *cmd_ctx); + +/** Shutdown the debug adapter upon program exit. */ +int adapter_quit(void); + /** @returns true if adapter has been initialized */ bool is_adapter_initialized(void); @@ -19,4 +27,28 @@ const char *adapter_usb_get_location(void); /** @returns true if USB location string is "-[.[...]]" */ bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len); +/** @returns The current JTAG speed setting. */ +int jtag_get_speed(int *speed); + +/** + * Given a @a speed setting, use the interface @c speed_div callback to + * adjust the setting. + * @param speed The speed setting to convert back to readable KHz. + * @returns ERROR_OK if the interface has not been initialized or on success; + * otherwise, the error code produced by the @c speed_div callback. + */ +int jtag_get_speed_readable(int *speed); + +/** Attempt to configure the interface for the specified KHz. */ +int jtag_config_khz(unsigned khz); + +/** + * Attempt to enable RTCK/RCLK. If that fails, fallback to the + * specified frequency. + */ +int jtag_config_rclk(unsigned fallback_speed_khz); + +/** Retrieves the clock speed of the JTAG interface in KHz. */ +unsigned jtag_get_speed_khz(void); + #endif /* OPENOCD_JTAG_ADAPTER_H */ diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c index e9ff8dfa1..b73c66161 100644 --- a/src/jtag/drivers/amt_jtagaccel.c +++ b/src/jtag/drivers/amt_jtagaccel.c @@ -20,6 +20,7 @@ #include "config.h" #endif +#include #include #if PARPORT_USE_PPDEV == 1 diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index 9bd4cb73a..289ffcd92 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -40,6 +40,7 @@ #include #include "helper/replacements.h" +#include #include #include #include diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index d50d306d3..714cb1daa 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -23,6 +23,7 @@ #include "config.h" #endif +#include #include #include "bitbang.h" diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index 7325f6abc..5d771443c 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -24,6 +24,7 @@ #include "config.h" #endif +#include #include #include #include diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index feb4614fa..d7d7d977c 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -217,31 +217,6 @@ int jtag_unregister_event_callback(jtag_event_handler_t f, void *x); int jtag_call_event_callbacks(enum jtag_event event); - -/** @returns The current JTAG speed setting. */ -int jtag_get_speed(int *speed); - -/** - * Given a @a speed setting, use the interface @c speed_div callback to - * adjust the setting. - * @param speed The speed setting to convert back to readable KHz. - * @returns ERROR_OK if the interface has not been initialized or on success; - * otherwise, the error code produced by the @c speed_div callback. - */ -int jtag_get_speed_readable(int *speed); - -/** Attempt to configure the interface for the specified KHz. */ -int jtag_config_khz(unsigned khz); - -/** - * Attempt to enable RTCK/RCLK. If that fails, fallback to the - * specified frequency. - */ -int jtag_config_rclk(unsigned fallback_speed_khz); - -/** Retrieves the clock speed of the JTAG interface in KHz. */ -unsigned jtag_get_speed_khz(void); - enum reset_types { RESET_NONE = 0x0, RESET_HAS_TRST = 0x1, @@ -285,12 +260,6 @@ void jtag_set_verify_capture_ir(bool enable); /** @returns True if IR scan verification will be performed. */ bool jtag_will_verify_capture_ir(void); -/** Initialize debug adapter upon startup. */ -int adapter_init(struct command_context *cmd_ctx); - -/** Shutdown the debug adapter upon program exit. */ -int adapter_quit(void); - /** Set ms to sleep after jtag_execute_queue() flushes queue. Debug purposes. */ void jtag_set_flush_queue_sleep(int ms); diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 6d3fee43c..8bf4ea9c1 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -30,6 +30,7 @@ #include "config.h" #endif +#include "adapter.h" #include "jtag.h" #include "swd.h" #include "minidriver.h" diff --git a/src/openocd.c b/src/openocd.c index 12bd52c58..e8c526bfd 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -27,6 +27,7 @@ #endif #include "openocd.h" +#include #include #include #include diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 923cdf877..ebe02e66d 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -70,6 +70,7 @@ #include #include +#include #include "mips32.h" #include "mips32_pracc.h" diff --git a/src/target/mips64_pracc.c b/src/target/mips64_pracc.c index bb2af228d..d68521d63 100644 --- a/src/target/mips64_pracc.c +++ b/src/target/mips64_pracc.c @@ -21,6 +21,7 @@ #include "mips64_pracc.h" #include +#include #define STACK_DEPTH 32 From 3c50288612cde9ce5d8f3004f5ad287abd80753e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 14:59:29 +0200 Subject: [PATCH 23/82] jtag: align adapter speed code to new structure Rename the jtag_XXX functions as adapter_XXX. Rename internal variables. Adapt log messages and comments text. Change-Id: I67f209c67074899cd58bad495055def03f0d1bcf Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6644 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/adapter.c | 68 ++++++++++++++++---------------- src/jtag/adapter.h | 18 ++++----- src/jtag/drivers/amt_jtagaccel.c | 4 +- src/jtag/drivers/cmsis_dap.c | 4 +- src/jtag/drivers/ftdi.c | 2 +- src/jtag/drivers/jlink.c | 2 +- src/jtag/drivers/parport.c | 4 +- src/jtag/drivers/vsllink.c | 4 +- src/jtag/tcl.c | 6 +-- src/target/mips32_pracc.c | 4 +- src/target/mips64_pracc.c | 2 +- 11 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 991338be8..0320d295d 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -85,18 +85,18 @@ int adapter_init(struct command_context *cmd_ctx) return ERROR_JTAG_INIT_FAILED; } - int requested_khz = jtag_get_speed_khz(); + int requested_khz = adapter_get_speed_khz(); int actual_khz = requested_khz; - int jtag_speed_var = 0; - retval = jtag_get_speed(&jtag_speed_var); + int speed_var = 0; + retval = adapter_get_speed(&speed_var); if (retval != ERROR_OK) return retval; - retval = adapter_driver->speed(jtag_speed_var); + retval = adapter_driver->speed(speed_var); if (retval != ERROR_OK) return retval; - retval = jtag_get_speed_readable(&actual_khz); + retval = adapter_get_speed_readable(&actual_khz); if (retval != ERROR_OK) - LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var); + LOG_INFO("adapter-specific clock speed value %d", speed_var); else if (actual_khz) { /* Adaptive clocking -- JTAG-specific */ if ((adapter_config.clock_mode == CLOCK_MODE_RCLK) @@ -130,31 +130,31 @@ int adapter_quit(void) return ERROR_OK; } -unsigned jtag_get_speed_khz(void) +unsigned int adapter_get_speed_khz(void) { return adapter_config.speed_khz; } -static int adapter_khz_to_speed(unsigned khz, int *speed) +static int adapter_khz_to_speed(unsigned int khz, int *speed) { - LOG_DEBUG("convert khz to interface specific speed value"); + LOG_DEBUG("convert khz to adapter specific speed value"); adapter_config.speed_khz = khz; if (!is_adapter_initialized()) return ERROR_OK; - LOG_DEBUG("have interface set up"); + LOG_DEBUG("have adapter set up"); if (!adapter_driver->khz) { - LOG_ERROR("Translation from khz to jtag_speed not implemented"); + LOG_ERROR("Translation from khz to adapter speed not implemented"); return ERROR_FAIL; } int speed_div1; - int retval = adapter_driver->khz(jtag_get_speed_khz(), &speed_div1); + int retval = adapter_driver->khz(adapter_get_speed_khz(), &speed_div1); if (retval != ERROR_OK) return retval; *speed = speed_div1; return ERROR_OK; } -static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int *speed) +static int adapter_rclk_to_speed(unsigned int fallback_speed_khz, int *speed) { int retval = adapter_khz_to_speed(0, speed); if ((retval != ERROR_OK) && fallback_speed_khz) { @@ -164,61 +164,61 @@ static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int *speed) return retval; } -static int jtag_set_speed(int speed) +static int adapter_set_speed(int speed) { /* this command can be called during CONFIG, - * in which case jtag isn't initialized */ + * in which case adapter isn't initialized */ return is_adapter_initialized() ? adapter_driver->speed(speed) : ERROR_OK; } -int jtag_config_khz(unsigned khz) +int adapter_config_khz(unsigned int khz) { - LOG_DEBUG("handle jtag khz"); + LOG_DEBUG("handle adapter khz"); adapter_config.clock_mode = CLOCK_MODE_KHZ; int speed = 0; int retval = adapter_khz_to_speed(khz, &speed); - return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); + return (retval != ERROR_OK) ? retval : adapter_set_speed(speed); } -int jtag_config_rclk(unsigned fallback_speed_khz) +int adapter_config_rclk(unsigned int fallback_speed_khz) { - LOG_DEBUG("handle jtag rclk"); + LOG_DEBUG("handle adapter rclk"); adapter_config.clock_mode = CLOCK_MODE_RCLK; adapter_config.rclk_fallback_speed_khz = fallback_speed_khz; int speed = 0; - int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed); - return (retval != ERROR_OK) ? retval : jtag_set_speed(speed); + int retval = adapter_rclk_to_speed(fallback_speed_khz, &speed); + return (retval != ERROR_OK) ? retval : adapter_set_speed(speed); } -int jtag_get_speed(int *speed) +int adapter_get_speed(int *speed) { switch (adapter_config.clock_mode) { case CLOCK_MODE_KHZ: - adapter_khz_to_speed(jtag_get_speed_khz(), speed); + adapter_khz_to_speed(adapter_get_speed_khz(), speed); break; case CLOCK_MODE_RCLK: - jtag_rclk_to_speed(adapter_config.rclk_fallback_speed_khz, speed); + adapter_rclk_to_speed(adapter_config.rclk_fallback_speed_khz, speed); break; default: - LOG_ERROR("BUG: unknown jtag clock mode"); + LOG_ERROR("BUG: unknown adapter clock mode"); return ERROR_FAIL; } return ERROR_OK; } -int jtag_get_speed_readable(int *khz) +int adapter_get_speed_readable(int *khz) { - int jtag_speed_var = 0; - int retval = jtag_get_speed(&jtag_speed_var); + int speed_var = 0; + int retval = adapter_get_speed(&speed_var); if (retval != ERROR_OK) return retval; if (!is_adapter_initialized()) return ERROR_OK; if (!adapter_driver->speed_div) { - LOG_ERROR("Translation from jtag_speed to khz not implemented"); + LOG_ERROR("Translation from adapter speed to khz not implemented"); return ERROR_FAIL; } - return adapter_driver->speed_div(jtag_speed_var, khz); + return adapter_driver->speed_div(speed_var, khz); } /* @@ -640,13 +640,13 @@ COMMAND_HANDLER(handle_adapter_speed_command) unsigned khz = 0; COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz); - retval = jtag_config_khz(khz); + retval = adapter_config_khz(khz); if (retval != ERROR_OK) return retval; } - int cur_speed = jtag_get_speed_khz(); - retval = jtag_get_speed_readable(&cur_speed); + int cur_speed = adapter_get_speed_khz(); + retval = adapter_get_speed_readable(&cur_speed); if (retval != ERROR_OK) return retval; diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index b2405e984..a66fef1a7 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -27,28 +27,28 @@ const char *adapter_usb_get_location(void); /** @returns true if USB location string is "-[.[...]]" */ bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len); -/** @returns The current JTAG speed setting. */ -int jtag_get_speed(int *speed); +/** @returns The current adapter speed setting. */ +int adapter_get_speed(int *speed); /** * Given a @a speed setting, use the interface @c speed_div callback to * adjust the setting. - * @param speed The speed setting to convert back to readable KHz. + * @param speed The speed setting to convert back to readable kHz. * @returns ERROR_OK if the interface has not been initialized or on success; * otherwise, the error code produced by the @c speed_div callback. */ -int jtag_get_speed_readable(int *speed); +int adapter_get_speed_readable(int *speed); -/** Attempt to configure the interface for the specified KHz. */ -int jtag_config_khz(unsigned khz); +/** Attempt to configure the adapter for the specified kHz. */ +int adapter_config_khz(unsigned int khz); /** * Attempt to enable RTCK/RCLK. If that fails, fallback to the * specified frequency. */ -int jtag_config_rclk(unsigned fallback_speed_khz); +int adapter_config_rclk(unsigned int fallback_speed_khz); -/** Retrieves the clock speed of the JTAG interface in KHz. */ -unsigned jtag_get_speed_khz(void); +/** Retrieves the clock speed of the adapter in kHz. */ +unsigned int adapter_get_speed_khz(void); #endif /* OPENOCD_JTAG_ADAPTER_H */ diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c index b73c66161..c204f237a 100644 --- a/src/jtag/drivers/amt_jtagaccel.c +++ b/src/jtag/drivers/amt_jtagaccel.c @@ -199,7 +199,7 @@ static void amt_jtagaccel_state_move(void) aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f); AMT_AW(aw_scan_tms_5); int jtag_speed = 0; - int retval = jtag_get_speed(&jtag_speed); + int retval = adapter_get_speed(&jtag_speed); assert(retval == ERROR_OK); if (jtag_speed > 3 || rtck_enabled) amt_wait_scan_busy(); @@ -255,7 +255,7 @@ static void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, uint8_t *buffe uint8_t aw_tms_scan; uint8_t tms_scan[2]; int jtag_speed_var; - int retval = jtag_get_speed(&jtag_speed_var); + int retval = adapter_get_speed(&jtag_speed_var); assert(retval == ERROR_OK); if (ir_scan) diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index 289ffcd92..19649b71c 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -1145,7 +1145,7 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq) /* Atmel EDBG needs renew clock setting after SWJ_Sequence * otherwise default frequency is used */ - return cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz()); + return cmsis_dap_cmd_dap_swj_clock(adapter_get_speed_khz()); } static int cmsis_dap_swd_open(void) @@ -1262,7 +1262,7 @@ static int cmsis_dap_init(void) /* Now try to connect to the target * TODO: This is all SWD only @ present */ - retval = cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz()); + retval = cmsis_dap_cmd_dap_swj_clock(adapter_get_speed_khz()); if (retval != ERROR_OK) goto init_err; diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 5e7eae073..6e2e18450 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -699,7 +699,7 @@ static int ftdi_initialize(void) mpsse_loopback_config(mpsse_ctx, false); - freq = mpsse_set_frequency(mpsse_ctx, jtag_get_speed_khz() * 1000); + freq = mpsse_set_frequency(mpsse_ctx, adapter_get_speed_khz() * 1000); return mpsse_flush(mpsse_ctx); } diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 12ac05fa6..ce1e9bfb7 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -811,7 +811,7 @@ static int jlink_init(void) jtag_sleep(3000); jlink_tap_init(); - jlink_speed(jtag_get_speed_khz()); + jlink_speed(adapter_get_speed_khz()); if (iface == JAYLINK_TIF_JTAG) { /* diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index 714cb1daa..9273e3ec2 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -458,9 +458,9 @@ COMMAND_HANDLER(parport_handle_parport_toggling_time_command) } parport_toggling_time_ns = ns; - retval = jtag_get_speed(&wait_states); + retval = adapter_get_speed(&wait_states); if (retval != ERROR_OK) { - /* if jtag_get_speed fails then the clock_mode + /* if adapter_get_speed fails then the clock_mode * has not been configured, this happens if parport_toggling_time is * called before the adapter speed is set */ LOG_INFO("no parport speed set - defaulting to zero wait states"); diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index 5d771443c..9cec2bea7 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -324,7 +324,7 @@ static int vsllink_init(void) versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0, GPIO_TRST, GPIO_TRST); versaloon_interface.adaptors.swd.init(0); - vsllink_swd_frequency(jtag_get_speed_khz() * 1000); + vsllink_swd_frequency(adapter_get_speed_khz() * 1000); vsllink_swd_switch_seq(JTAG_TO_SWD); } else { @@ -340,7 +340,7 @@ static int vsllink_init(void) } versaloon_interface.adaptors.jtag_raw.init(0); - versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz()); + versaloon_interface.adaptors.jtag_raw.config(0, adapter_get_speed_khz()); versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST, GPIO_TRST, GPIO_SRST, GPIO_SRST); } diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 8bf4ea9c1..566c406b9 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -1041,13 +1041,13 @@ COMMAND_HANDLER(handle_jtag_rclk_command) unsigned khz = 0; COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz); - retval = jtag_config_rclk(khz); + retval = adapter_config_rclk(khz); if (retval != ERROR_OK) return retval; } - int cur_khz = jtag_get_speed_khz(); - retval = jtag_get_speed_readable(&cur_khz); + int cur_khz = adapter_get_speed_khz(); + retval = adapter_get_speed_readable(&cur_khz); if (retval != ERROR_OK) return retval; diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index ebe02e66d..9f8762e34 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -381,7 +381,7 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in } unsigned num_clocks = - ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; + ((uint64_t)(ejtag_info->scan_delay) * adapter_get_speed_khz() + 500000) / 1000000; uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL); @@ -1011,7 +1011,7 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are unsigned num_clocks = 0; /* like in legacy code */ if (ejtag_info->mode != 0) - num_clocks = ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; + num_clocks = ((uint64_t)(ejtag_info->scan_delay) * adapter_get_speed_khz() + 500000) / 1000000; for (int i = 0; i < count; i++) { jtag_add_clocks(num_clocks); diff --git a/src/target/mips64_pracc.c b/src/target/mips64_pracc.c index d68521d63..81a4cfbfa 100644 --- a/src/target/mips64_pracc.c +++ b/src/target/mips64_pracc.c @@ -1387,7 +1387,7 @@ int mips64_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, /* like in legacy code */ unsigned num_clocks = 0; if (ejtag_info->mode != 0) - num_clocks = ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; + num_clocks = ((uint64_t)(ejtag_info->scan_delay) * adapter_get_speed_khz() + 500000) / 1000000; LOG_DEBUG("num_clocks=%d", num_clocks); for (i = 0; i < count; i++) { jtag_add_clocks(num_clocks); From ac1a632ba13efa77393cecf29bd29410db60cada Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 15:07:57 +0200 Subject: [PATCH 24/82] jtag: remove file driver.h The only purpose of include file driver.h was to expose the API to register the adapter's commands. Move the prototype in adapter.h, already used by openocd.c. Change-Id: Ie1090c60ef9e5bac5ea187c87bed6e7b08d9671c Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6645 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/Makefile.am | 1 - src/jtag/adapter.c | 2 +- src/jtag/adapter.h | 4 ++++ src/jtag/driver.h | 26 -------------------------- src/openocd.c | 3 +-- 5 files changed, 6 insertions(+), 30 deletions(-) delete mode 100644 src/jtag/driver.h diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am index cbdfb2054..23424f5a2 100644 --- a/src/jtag/Makefile.am +++ b/src/jtag/Makefile.am @@ -25,7 +25,6 @@ include %D%/drivers/Makefile.am %D%/tcl.c \ %D%/swim.c \ %D%/commands.h \ - %D%/driver.h \ %D%/interface.h \ %D%/interfaces.h \ %D%/minidriver.h \ diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 0320d295d..a5a6222a9 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -886,7 +886,7 @@ static const struct command_registration interface_command_handlers[] = { * @todo Remove internal assumptions that all debug adapters use JTAG for * transport. Various types and data structures are not named generically. */ -int interface_register_commands(struct command_context *ctx) +int adapter_register_commands(struct command_context *ctx) { return register_commands(ctx, NULL, interface_command_handlers); } diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index a66fef1a7..8b73c0c9e 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* + * Copyright (C) 2005 by Dominic Rath * Copyright (c) 2018 Pengutronix, Oleksij Rempel */ @@ -12,6 +13,9 @@ struct command_context; +/** Register the adapter's commands */ +int adapter_register_commands(struct command_context *ctx); + /** Initialize debug adapter upon startup. */ int adapter_init(struct command_context *cmd_ctx); diff --git a/src/jtag/driver.h b/src/jtag/driver.h deleted file mode 100644 index ae00414c4..000000000 --- a/src/jtag/driver.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVER_H -#define OPENOCD_JTAG_DRIVER_H - -struct command_context; - -int interface_register_commands(struct command_context *ctx); - -#endif /* OPENOCD_JTAG_DRIVER_H */ diff --git a/src/openocd.c b/src/openocd.c index e8c526bfd..0292ba445 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -28,7 +28,6 @@ #include "openocd.h" #include -#include #include #include #include @@ -313,7 +312,7 @@ static struct command_context *setup_command_handler(Jim_Interp *interp) &log_register_commands, &rtt_server_register_commands, &transport_register_commands, - &interface_register_commands, + &adapter_register_commands, &target_register_commands, &flash_register_commands, &nand_register_commands, From e9a569aa18230766ae0bb6dd1a6dc843eb8c087b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 18:13:21 +0200 Subject: [PATCH 25/82] jtag/adapter: fix memory leak on usb location At exit, free the memory allocated to hold the USB location. Change-Id: I050701f4dc8be14fd40e8add9d0b047461fa0d1c Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6646 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/adapter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index a5a6222a9..c30019c17 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -120,6 +120,8 @@ int adapter_quit(void) LOG_ERROR("failed: %d", result); } + free(adapter_config.usb_location); + struct jtag_tap *t = jtag_all_taps(); while (t) { struct jtag_tap *n = t->next_tap; From a4f8bf7a9041eb37cf5b8df441935664809f13ac Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Mon, 1 Nov 2021 15:28:28 +0100 Subject: [PATCH 26/82] helper/log: Add macros for target-related errors/warnings/... This commit introduces macros for target related log entries (error, warning, ...) which is a very common operation in OpenOCD: * LOG_TARGET_ERROR * LOG_TARGET_WARNING * LOG_TARGET_INFO * LOG_TARGET_DEBUG * LOG_TARGET_DEBUG_IO The goal is to have one macro for this common operation and to make such log entries look the same way - to make it more readable for humans as well easier for parsing via scripts. Change-Id: I6166565fc9040b03d3fca5c3aa44a1ccbcf96ad2 Signed-off-by: Jan Matyas Reviewed-on: https://review.openocd.org/c/openocd/+/6667 Tested-by: jenkins Reviewed-by: Tim Newsome Reviewed-by: Tomas Vanek Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/helper/log.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/helper/log.h b/src/helper/log.h index 34ff835b8..621d467b4 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -143,6 +143,23 @@ extern int debug_level; #define LOG_OUTPUT(expr ...) \ log_printf(LOG_LVL_OUTPUT, __FILE__, __LINE__, __func__, expr) +/* Output a log entry that is related to a given target */ + +#define LOG_TARGET_DEBUG_IO(target, fmt_str, ...) \ + LOG_DEBUG_IO("[%s] " fmt_str, target_name(target), ##__VA_ARGS__) + +#define LOG_TARGET_DEBUG(target, fmt_str, ...) \ + LOG_DEBUG("[%s] " fmt_str, target_name(target), ##__VA_ARGS__) + +#define LOG_TARGET_INFO(target, fmt_str, ...) \ + LOG_INFO("[%s] " fmt_str, target_name(target), ##__VA_ARGS__) + +#define LOG_TARGET_WARNING(target, fmt_str, ...) \ + LOG_WARNING("[%s] " fmt_str, target_name(target), ##__VA_ARGS__) + +#define LOG_TARGET_ERROR(target, fmt_str, ...) \ + LOG_ERROR("[%s] " fmt_str, target_name(target), ##__VA_ARGS__) + /* general failures * error codes < 100 */ From 3f778c7c63cbd293c30144a88c041f845f1eb46d Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 3 Nov 2021 16:22:22 +0100 Subject: [PATCH 27/82] stlink (tcp): manage scattered stlink-server responses detected in ubuntu 20.04 sometimes, the stlink-server response could be segmented on multiple packets. this causes stlink_tcp_send_cmd to fail with the following msg: Error: failed to receive USB CMD response because the received_size < expected size to fix the issue, do recv in a loop till all data is received or timeout is reached. Change-Id: I46cc60c231b4cc52f150ead268f843bc60c41149 Signed-off-by: Tarek BOCHKATI Reviewed-on: https://review.openocd.org/c/openocd/+/6671 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 37 ++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index b51a0c2ba..87e6ddc20 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -926,17 +927,35 @@ static int stlink_tcp_send_cmd(void *handle, int send_size, int recv_size, bool return ERROR_FAIL; } - keep_alive(); - /* read the TCP response */ - int received_size = recv(h->tcp_backend_priv.fd, (void *)h->tcp_backend_priv.recv_buf, recv_size, 0); - if (received_size != recv_size) { - LOG_ERROR("failed to receive USB CMD response"); - if (received_size == -1) + int retval = ERROR_OK; + int remaining_bytes = recv_size; + uint8_t *recv_buf = h->tcp_backend_priv.recv_buf; + const int64_t timeout = timeval_ms() + 1000; /* 1 second */ + + while (remaining_bytes > 0) { + if (timeval_ms() > timeout) { + LOG_DEBUG("received size %d (expected %d)", recv_size - remaining_bytes, recv_size); + retval = ERROR_TIMEOUT_REACHED; + break; + } + + keep_alive(); + int received = recv(h->tcp_backend_priv.fd, (void *)recv_buf, remaining_bytes, 0); + + if (received == -1) { LOG_DEBUG("socket recv error: %s (errno %d)", strerror(errno), errno); - else - LOG_DEBUG("received size %d (expected %d)", received_size, recv_size); - return ERROR_FAIL; + retval = ERROR_FAIL; + break; + } + + recv_buf += received; + remaining_bytes -= received; + } + + if (retval != ERROR_OK) { + LOG_ERROR("failed to receive USB CMD response"); + return retval; } if (check_tcp_status) { From 50f977b0581408891ef8dbeeda3fc64e3ef0619a Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 20 Oct 2021 12:10:44 +0100 Subject: [PATCH 28/82] flash/stm32h7x: avoid using magic numbers for device ids Change-Id: I4d682ee828404974abd9a42f98b840d77835cfe0 Signed-off-by: Tarek BOCHKATI Reviewed-on: https://review.openocd.org/c/openocd/+/6669 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/flash/nor/stm32h7x.c | 45 ++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 89ba75dad..e6a4efc19 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -100,6 +100,11 @@ #define FLASH_REG_BASE_B0 0x52002000 #define FLASH_REG_BASE_B1 0x52002100 +/* Supported device IDs */ +#define DEVID_STM32H74_H75XX 0x450 +#define DEVID_STM32H7A_H7BXX 0x480 +#define DEVID_STM32H72_H73XX 0x483 + struct stm32h7x_rev { uint16_t rev; const char *str; @@ -139,24 +144,24 @@ enum stm32h7x_opt_rdp { OPT_RDP_L2 = 0xcc }; -static const struct stm32h7x_rev stm32_450_revs[] = { +static const struct stm32h7x_rev stm32h74_h75xx_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, { 0x2003, "V" }, }; -static const struct stm32h7x_rev stm32_480_revs[] = { +static const struct stm32h7x_rev stm32h7a_h7bxx_revs[] = { { 0x1000, "A"}, }; -static const struct stm32h7x_rev stm32_483_revs[] = { +static const struct stm32h7x_rev stm32h72_h73xx_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, }; -static uint32_t stm32x_compute_flash_cr_450_483(uint32_t cmd, int snb) +static uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb) { return cmd | (snb << 8); } -static uint32_t stm32x_compute_flash_cr_480(uint32_t cmd, int snb) +static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb) { /* save FW and START bits, to be right shifted by 2 bits later */ const uint32_t tmp = cmd & (FLASH_FW | FLASH_START); @@ -169,9 +174,9 @@ static uint32_t stm32x_compute_flash_cr_480(uint32_t cmd, int snb) static const struct stm32h7x_part_info stm32h7x_parts[] = { { - .id = 0x450, - .revs = stm32_450_revs, - .num_revs = ARRAY_SIZE(stm32_450_revs), + .id = DEVID_STM32H74_H75XX, + .revs = stm32h74_h75xx_revs, + .num_revs = ARRAY_SIZE(stm32h74_h75xx_revs), .device_str = "STM32H74x/75x", .page_size_kb = 128, .block_size = 32, @@ -181,12 +186,12 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .fsize_addr = 0x1FF1E880, .wps_group_size = 1, .wps_mask = 0xFF, - .compute_flash_cr = stm32x_compute_flash_cr_450_483, + .compute_flash_cr = stm32h74_h75xx_compute_flash_cr, }, { - .id = 0x480, - .revs = stm32_480_revs, - .num_revs = ARRAY_SIZE(stm32_480_revs), + .id = DEVID_STM32H7A_H7BXX, + .revs = stm32h7a_h7bxx_revs, + .num_revs = ARRAY_SIZE(stm32h7a_h7bxx_revs), .device_str = "STM32H7Ax/7Bx", .page_size_kb = 8, .block_size = 16, @@ -196,12 +201,12 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .fsize_addr = 0x08FFF80C, .wps_group_size = 4, .wps_mask = 0xFFFFFFFF, - .compute_flash_cr = stm32x_compute_flash_cr_480, + .compute_flash_cr = stm32h7a_h7bxx_compute_flash_cr, }, { - .id = 0x483, - .revs = stm32_483_revs, - .num_revs = ARRAY_SIZE(stm32_483_revs), + .id = DEVID_STM32H72_H73XX, + .revs = stm32h72_h73xx_revs, + .num_revs = ARRAY_SIZE(stm32h72_h73xx_revs), .device_str = "STM32H72x/73x", .page_size_kb = 128, .block_size = 32, @@ -211,7 +216,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .fsize_addr = 0x1FF1E880, .wps_group_size = 1, .wps_mask = 0xFF, - .compute_flash_cr = stm32x_compute_flash_cr_450_483, + .compute_flash_cr = stm32h74_h75xx_compute_flash_cr, }, }; @@ -808,8 +813,8 @@ static int stm32x_probe(struct flash_bank *bank) bool has_dual_bank = stm32x_info->part_info->has_dual_bank; switch (device_id) { - case 0x450: - case 0x480: + case DEVID_STM32H74_H75XX: + case DEVID_STM32H7A_H7BXX: /* For STM32H74x/75x and STM32H7Ax/Bx * - STM32H7xxxI devices contains dual bank, 1 Mbyte each * - STM32H7xxxG devices contains dual bank, 512 Kbyte each @@ -822,7 +827,7 @@ static int stm32x_probe(struct flash_bank *bank) /* flash size is 2M or 1M */ flash_size_in_kb /= 2; break; - case 0x483: + case DEVID_STM32H72_H73XX: break; default: LOG_ERROR("unsupported device"); From 9d574aa3fab6e6d802fab4ededb24b73542ef2b9 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 20 Oct 2021 12:13:01 +0100 Subject: [PATCH 29/82] flash/stm32h7x: don't read flash size using the H74/H75x CPU2 CPU2 (Cortex-M4) cannot read flash size register. assume the maximum flash size without triggering an error message Change-Id: I5c3328b7cc42e3aa57165075021227d7936f3d26 Signed-off-by: Tarek BOCHKATI Reviewed-on: https://review.openocd.org/c/openocd/+/6670 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/stm32h7x.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index e6a4efc19..a3e304351 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -21,7 +21,7 @@ #include "imp.h" #include #include -#include +#include /* Erase time can be as high as 1000ms, 10x this and it's toast... */ @@ -759,6 +759,7 @@ static int stm32x_read_id_code(struct flash_bank *bank, uint32_t *id) static int stm32x_probe(struct flash_bank *bank) { struct target *target = bank->target; + struct cortex_m_common *cortex_m = target_to_cm(target); struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; uint16_t flash_size_in_kb; uint32_t device_id; @@ -797,15 +798,19 @@ static int stm32x_probe(struct flash_bank *bank) LOG_DEBUG("flash_regs_base: 0x%" PRIx32, stm32x_info->flash_regs_base); /* get flash size from target */ - retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb); + /* STM32H74x/H75x, the second core (Cortex-M4) cannot read the flash size */ + retval = ERROR_FAIL; + if (device_id == DEVID_STM32H74_H75XX && cortex_m->core_info->partno == CORTEX_M4_PARTNO) + LOG_WARNING("%s cannot read the flash size register", target_name(target)); + else + retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb); + if (retval != ERROR_OK) { /* read error when device has invalid value, set max flash size */ flash_size_in_kb = stm32x_info->part_info->max_flash_size_kb; + LOG_INFO("assuming %" PRIu16 "k flash", flash_size_in_kb); } else - LOG_INFO("flash size probed value %" PRIu16, flash_size_in_kb); - - - + LOG_INFO("flash size probed value %" PRIu16 "k", flash_size_in_kb); /* setup bank size */ const uint32_t bank1_base = FLASH_BANK0_ADDRESS; From a498a3deaaec7ee87d73cf753bdddefaf4779666 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 13 Nov 2021 14:38:21 +0100 Subject: [PATCH 30/82] jtagspi: fix build on MacOS Commit be57b0ab847e ("Update jtagspi driver for 1-, 2- and 4-byte addresses") introduces two incorrect format string for uint32_t data types. This cause build failure on MacOS: src/flash/nor/jtagspi.c:474:35: error: format specifies type 'unsigned char' but the argument has type 'uint32_t' (aka 'unsigned int') [-Werror,-Wformat] LOG_DEBUG("status=0x%02" PRIx8, *status); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~ src/flash/nor/jtagspi.c:513:65: error: format specifies type 'unsigned char' but the argument has type 'uint32_t' (aka 'unsigned int') [-Werror,-Wformat] LOG_ERROR("Cannot enable write to flash. Status=0x%02" PRIx8, status); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~ Fix the format string. Change-Id: I209053317c8b26c35c6f11be0553ccccc698c551 Signed-off-by: Antonio Borneo Fixes: be57b0ab847e ("Update jtagspi driver for 1-, 2- and 4-byte addresses") Reviewed-on: https://review.openocd.org/c/openocd/+/6701 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/flash/nor/jtagspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index 9d377ce70..a5672c63e 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -471,7 +471,7 @@ static int jtagspi_read_status(struct flash_bank *bank, uint32_t *status) int err = jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, 0, &buf, -1); if (err == ERROR_OK) { *status = buf; - LOG_DEBUG("status=0x%02" PRIx8, *status); + LOG_DEBUG("status=0x%02" PRIx32, *status); } return err; } @@ -510,7 +510,7 @@ static int jtagspi_write_enable(struct flash_bank *bank) return retval; if ((status & SPIFLASH_WE_BIT) == 0) { - LOG_ERROR("Cannot enable write to flash. Status=0x%02" PRIx8, status); + LOG_ERROR("Cannot enable write to flash. Status=0x%02" PRIx32, status); return ERROR_FAIL; } return ERROR_OK; From 5a0b4889d0d46639b38effd24102f0d5fca1ca31 Mon Sep 17 00:00:00 2001 From: asier70 Date: Wed, 1 Sep 2021 22:00:51 +0200 Subject: [PATCH 31/82] flash/nor/stm32f1x: Add support for GD32E23x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GD32E23x from GigaDevice is cortex-M23 microcontroller and it can work with the stm32f1x driver. Modifications are similar to this done for GD32F1x0 in #6164 (https://review.openocd.org/c/openocd/+/6164). Configuration file is added because its cortex-M23 CPU ID is different. I think that GigaDevice microcontrollers should be handled in an independent unit to separate them from STM32, but nowadays quick solution is welcome. Signed-off-by: asier70Andrzej Sierżęga Change-Id: I91f31f5f66808bc50a8f607ac2c107e6b7c5e2b8 Reviewed-on: https://review.openocd.org/c/openocd/+/6527 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 4 +-- src/flash/nor/stm32f1x.c | 19 +++++++++-- src/flash/startup.tcl | 3 ++ tcl/target/gd32e23x.cfg | 74 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 tcl/target/gd32e23x.cfg diff --git a/doc/openocd.texi b/doc/openocd.texi index c7ffc4f42..a6da1675e 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7120,8 +7120,8 @@ applied to all of them. @deffn {Flash Driver} {stm32f1x} All members of the STM32F0, STM32F1 and STM32F3 microcontroller families -from STMicroelectronics and all members of the GD32F1x0 and GD32F3x0 microcontroller -families from GigaDevice include internal flash and use ARM Cortex-M0/M3/M4 cores. +from STMicroelectronics and all members of the GD32F1x0, GD32F3x0 and GD32E23x microcontroller +families from GigaDevice include internal flash and use ARM Cortex-M0/M3/M4/M23 cores. The driver automatically recognizes a number of these chips using the chip identification register, and autoconfigures itself. diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 3bda9bc20..6744779e9 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -640,6 +640,9 @@ static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id) case CORTEX_M4_PARTNO: /* STM32F3x devices */ device_id_register = 0xE0042000; break; + case CORTEX_M23_PARTNO: /* GD32E23x devices */ + device_id_register = 0x40015800; + break; default: LOG_ERROR("Cannot identify target as a stm32x"); return ERROR_FAIL; @@ -674,6 +677,9 @@ static int stm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_size_i case CORTEX_M4_PARTNO: /* STM32F3x devices */ flash_size_reg = 0x1FFFF7CC; break; + case CORTEX_M23_PARTNO: /* GD32E23x devices */ + flash_size_reg = 0x1FFFF7E0; + break; default: LOG_ERROR("Cannot identify target as a stm32x"); return ERROR_FAIL; @@ -756,8 +762,8 @@ static int stm32x_probe(struct flash_bank *bank) page_size = 1024; stm32x_info->ppage_size = 4; max_flash_size_in_kb = 128; - /* GigaDevice GD32F1x0 & GD32F3x0 series devices share DEV_ID - with STM32F101/2/3 medium-density line, + /* GigaDevice GD32F1x0 & GD32F3x0 & GD32E23x series devices + share DEV_ID with STM32F101/2/3 medium-density line, however they use a REV_ID different from any STM32 device. The main difference is another offset of user option bits (like WDG_SW, nRST_STOP, nRST_STDBY) in option byte register @@ -774,6 +780,11 @@ static int stm32x_probe(struct flash_bank *bank) stm32x_info->user_data_offset = 16; stm32x_info->option_offset = 6; break; + case 0x1909: /* gd32e23x */ + stm32x_info->user_data_offset = 16; + stm32x_info->option_offset = 6; + max_flash_size_in_kb = 64; + break; } break; case 0x412: /* stm32f1x low-density */ @@ -984,6 +995,10 @@ static int get_stm32x_info(struct flash_bank *bank, struct command_invocation *c device_str = "GD32F3x0"; break; + case 0x1909: /* gd32e23x */ + device_str = "GD32E23x"; + break; + case 0x2000: rev_str = "B"; break; diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index 93ef82ce6..16cbe1950 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -121,3 +121,6 @@ proc stm32l5x args { eval stm32l4x $args } proc stm32u5x args { eval stm32l4x $args } proc stm32wbx args { eval stm32l4x $args } proc stm32wlx args { eval stm32l4x $args } + +# gd32e23x uses the same flash driver as the stm32f1x +proc gd32e23x args { eval stm32f1x $args } diff --git a/tcl/target/gd32e23x.cfg b/tcl/target/gd32e23x.cfg new file mode 100644 index 000000000..250427413 --- /dev/null +++ b/tcl/target/gd32e23x.cfg @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# script for GigaDevice gd32e23x Cortex-M23 Series + +# https://www.gigadevice.com/microcontroller/gd32e230c8t6/ + +# +# gd32e23x devices support SWD transports only. +# +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME gd32e23x +} + +# Work-area is a space in RAM used for flash programming +# By default use 4kB (as found on some GD32E230s) +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x1000 +} + +# Allow overriding the Flash bank size +if { [info exists FLASH_SIZE] } { + set _FLASH_SIZE $FLASH_SIZE +} else { + # autodetect size + set _FLASH_SIZE 0 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # this is the SW-DP tap id not the jtag tap id + set _CPUTAPID 0x0bf11477 +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +# flash size will be probed +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME + +# SWD speed (may be updated to higher value in board config file) +adapter speed 1000 + +reset_config srst_nogate + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +$_TARGETNAME configure -event examine-end { + # Debug clock enable + # RCU_APB2EN |= DBGMCUEN + mmw 0x40021018 0x00400000 0 + + # Stop watchdog counters during halt + # DBG_CTL0 |= WWDGT_HOLD | FWDGT_HOLD | STB_HOLD | DSLP_HOLD | SLP_HOLD + mmw 0x40015804 0x00000307 0 +} From aa8a79809ef9e6b97d45da60508d902da0e3270e Mon Sep 17 00:00:00 2001 From: Janco Kock Date: Fri, 22 Oct 2021 16:06:22 +0200 Subject: [PATCH 32/82] flash/nor/at91samd: Add SAMR35J18B support Add support for the mcu SAMR35J18B Signed-off-by: Janco Change-Id: I45d801485ad1c16d1b3086516a2b6d71d13f3fc7 Reviewed-on: https://review.openocd.org/c/openocd/+/6664 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/flash/nor/at91samd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c index 5cefd1766..a8fab486c 100644 --- a/src/flash/nor/at91samd.c +++ b/src/flash/nor/at91samd.c @@ -251,6 +251,7 @@ static const struct samd_part saml21_parts[] = { /* SAMR34/R35 parts have integrated SAML21 with a lora radio */ { 0x28, "SAMR34J18", 256, 32 }, + { 0x2B, "SAMR35J18", 256, 32 }, }; /* Known SAML22 parts. */ From b502947a1427aabe9c4e9ab0b3dd9e45f51e5b62 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 8 Nov 2021 14:24:33 +0100 Subject: [PATCH 33/82] cortex_m: use cortex_m_write_debug_halt_mask() in cortex_m_single_step_core() cortex_m_single_step_core() used mem_ap_write_atomic_u32() to manipulate dhcsr bits unlike the rest of code, where a specialized function cortex_m_write_debug_halt_mask() takes place. Unify setting of dhcsr bits and use cortex_m_write_debug_halt_mask() here as well. Extracted from [1]. [1] Antonio Borneo: 6207: cortex_m: rework handling of dcb_dhcsr Link: https://review.openocd.org/c/openocd/+/6207 Change-Id: I9ef05ce88a9dce42e1d3d5404a4fe87ec86b5fe8 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6676 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tarek BOCHKATI --- src/target/cortex_m.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 3412c5677..f68260603 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -301,7 +301,6 @@ static int cortex_m_clear_halt(struct target *target) static int cortex_m_single_step_core(struct target *target) { struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; int retval; /* Mask interrupts before clearing halt, if not done already. This avoids @@ -309,13 +308,11 @@ static int cortex_m_single_step_core(struct target *target) * HALT can put the core into an unknown state. */ if (!(cortex_m->dcb_dhcsr & C_MASKINTS)) { - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, - DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN); + retval = cortex_m_write_debug_halt_mask(target, C_MASKINTS, 0); if (retval != ERROR_OK) return retval; } - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, - DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN); + retval = cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT); if (retval != ERROR_OK) return retval; LOG_DEBUG(" "); From 111dcbeb1a54f629866449efe0c3b17ec1ab8957 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 8 Nov 2021 15:40:24 +0100 Subject: [PATCH 34/82] target/cortex_m: use cortex_m->dcb_dhcsr in cortex_m_soft_reset_halt() cortex_m->dcb_dhcsr caches status of DHCSR register. Use it instead of local variable in cortex_m_soft_reset_halt() like in other code. Extracted from [1]. [1] Antonio Borneo: 6207: cortex_m: rework handling of dcb_dhcsr Link: https://review.openocd.org/c/openocd/+/6207 Change-Id: I9a0aeba0b6b0b4969f05f4a32fc2fc8d244f56ca Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6677 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tarek BOCHKATI --- src/target/cortex_m.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index f68260603..d4affa683 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -776,7 +776,6 @@ static int cortex_m_soft_reset_halt(struct target *target) { struct cortex_m_common *cortex_m = target_to_cm(target); struct armv7m_common *armv7m = &cortex_m->armv7m; - uint32_t dcb_dhcsr = 0; int retval, timeout = 0; /* on single cortex_m MCU soft_reset_halt should be avoided as same functionality @@ -812,25 +811,23 @@ static int cortex_m_soft_reset_halt(struct target *target) register_cache_invalidate(cortex_m->armv7m.arm.core_cache); while (timeout < 100) { - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &dcb_dhcsr); + retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); if (retval == ERROR_OK) { retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR, &cortex_m->nvic_dfsr); if (retval != ERROR_OK) return retval; - if ((dcb_dhcsr & S_HALT) + if ((cortex_m->dcb_dhcsr & S_HALT) && (cortex_m->nvic_dfsr & DFSR_VCATCH)) { - LOG_DEBUG("system reset-halted, DHCSR 0x%08x, " - "DFSR 0x%08x", - (unsigned) dcb_dhcsr, - (unsigned) cortex_m->nvic_dfsr); + LOG_DEBUG("system reset-halted, DHCSR 0x%08" PRIx32 ", DFSR 0x%08" PRIx32, + cortex_m->dcb_dhcsr, cortex_m->nvic_dfsr); cortex_m_poll(target); /* FIXME restore user's vector catch config */ return ERROR_OK; } else LOG_DEBUG("waiting for system reset-halt, " - "DHCSR 0x%08x, %d ms", - (unsigned) dcb_dhcsr, timeout); + "DHCSR 0x%08" PRIx32 ", %d ms", + cortex_m->dcb_dhcsr, timeout); } timeout++; alive_sleep(1); From 0dcf95c7171b702d70ec326f8c1a63cbc9255b6f Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Thu, 22 Apr 2021 10:41:50 +0200 Subject: [PATCH 35/82] target/cortex_m: cumulate DHCSR sticky bits DCB DHCSR register contains S_RETIRE_ST and S_RESET_ST bits cleared on a read. The change introduces a helper function cortex_m_cumulate_dhcsr_sticky(). Call this function each time DHCSR is read to preserve S_RESET_ST state in the case of a reset event was detected. Introduce cortex_m_read_dhcsr_atomic_sticky() convenience helper to read DHCSR, store it to cortex_m->dcb_dhcsr and cumulate sticky bits. The cumulated state of S_RESET_ST is read and cleared in cortex_m_poll() Change-Id: Ib679599f850fd219fb9418c6ff32eed7cf5740da Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6180 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tarek BOCHKATI --- src/target/cortex_m.c | 69 +++++++++++++++++++++++++++++++++---------- src/target/cortex_m.h | 1 + 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index d4affa683..655825227 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -118,6 +118,33 @@ static int cortex_m_store_core_reg_u32(struct target *target, uint32_t num, uint32_t value); static void cortex_m_dwt_free(struct target *target); +/** DCB DHCSR register contains S_RETIRE_ST and S_RESET_ST bits cleared + * on a read. Call this helper function each time DHCSR is read + * to preserve S_RESET_ST state in case of a reset event was detected. + */ +static inline void cortex_m_cumulate_dhcsr_sticky(struct cortex_m_common *cortex_m, + uint32_t dhcsr) +{ + cortex_m->dcb_dhcsr_cumulated_sticky |= dhcsr; +} + +/** Read DCB DHCSR register to cortex_m->dcb_dhcsr and cumulate + * sticky bits in cortex_m->dcb_dhcsr_cumulated_sticky + */ +static int cortex_m_read_dhcsr_atomic_sticky(struct target *target) +{ + struct cortex_m_common *cortex_m = target_to_cm(target); + struct armv7m_common *armv7m = target_to_armv7m(target); + + int retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, + &cortex_m->dcb_dhcsr); + if (retval != ERROR_OK) + return retval; + + cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); + return ERROR_OK; +} + static int cortex_m_load_core_reg_u32(struct target *target, uint32_t regsel, uint32_t *value) { @@ -362,11 +389,12 @@ static int cortex_m_endreset_event(struct target *target) if (retval != ERROR_OK) return retval; - /* Enable debug requests */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) return retval; + if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { + /* Enable debug requests */ retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS); if (retval != ERROR_OK) return retval; @@ -428,7 +456,9 @@ static int cortex_m_endreset_event(struct target *target) register_cache_invalidate(armv7m->arm.core_cache); /* make sure we have latest dhcsr flags */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); + if (retval != ERROR_OK) + return retval; return retval; } @@ -552,7 +582,8 @@ static int cortex_m_debug_entry(struct target *target) cortex_m_set_maskints_for_halt(target); cortex_m_clear_halt(target); - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) return retval; @@ -636,7 +667,7 @@ static int cortex_m_poll(struct target *target) struct armv7m_common *armv7m = &cortex_m->armv7m; /* Read from Debug Halting Control and Status Register */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) { target->state = TARGET_UNKNOWN; return retval; @@ -657,12 +688,13 @@ static int cortex_m_poll(struct target *target) detected_failure = ERROR_FAIL; /* refresh status bits */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) return retval; } - if (cortex_m->dcb_dhcsr & S_RESET_ST) { + if (cortex_m->dcb_dhcsr_cumulated_sticky & S_RESET_ST) { + cortex_m->dcb_dhcsr_cumulated_sticky &= ~S_RESET_ST; if (target->state != TARGET_RESET) { target->state = TARGET_RESET; LOG_INFO("%s: external reset detected", target_name(target)); @@ -709,7 +741,12 @@ static int cortex_m_poll(struct target *target) } if (target->state == TARGET_UNKNOWN) { - /* check if processor is retiring instructions or sleeping */ + /* Check if processor is retiring instructions or sleeping. + * Unlike S_RESET_ST here we test if the target *is* running now, + * not if it has been running (possibly in the past). Instructions are + * typically processed much faster than OpenOCD polls DHCSR so S_RETIRE_ST + * is read always 1. That's the reason not to use dcb_dhcsr_cumulated_sticky. + */ if (cortex_m->dcb_dhcsr & S_RETIRE_ST || cortex_m->dcb_dhcsr & S_SLEEP) { target->state = TARGET_RUNNING; retval = ERROR_OK; @@ -811,7 +848,7 @@ static int cortex_m_soft_reset_halt(struct target *target) register_cache_invalidate(cortex_m->armv7m.arm.core_cache); while (timeout < 100) { - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval == ERROR_OK) { retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR, &cortex_m->nvic_dfsr); @@ -1076,9 +1113,7 @@ static int cortex_m_step(struct target *target, int current, /* Wait for pending handlers to complete or timeout */ do { - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, - DCB_DHCSR, - &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) { target->state = TARGET_UNKNOWN; return retval; @@ -1113,7 +1148,7 @@ static int cortex_m_step(struct target *target, int current, } } - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) return retval; @@ -1191,8 +1226,8 @@ static int cortex_m_assert_reset(struct target *target) } /* Enable debug requests */ - int retval; - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); + int retval = cortex_m_read_dhcsr_atomic_sticky(target); + /* Store important errors instead of failing and proceed to reset assert */ if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN)) @@ -2136,11 +2171,13 @@ int cortex_m_examine(struct target *target) armv7m->debug_ap->tar_autoincr_block = (1 << 12); } - /* Enable debug requests */ retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr); if (retval != ERROR_OK) return retval; + cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); + if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { + /* Enable debug requests */ uint32_t dhcsr = (cortex_m->dcb_dhcsr | C_DEBUGEN) & ~(C_HALT | C_STEP | C_MASKINTS); retval = target_write_u32(target, DCB_DHCSR, DBGKEY | (dhcsr & 0x0000FFFFUL)); diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 16fc8ab70..a5dfbf856 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -213,6 +213,7 @@ struct cortex_m_common { /* Context information */ uint32_t dcb_dhcsr; + uint32_t dcb_dhcsr_cumulated_sticky; uint32_t nvic_dfsr; /* Debug Fault Status Register - shows reason for debug halt */ uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */ From 65d7629183288595177301ce262dac4ba716618b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 14 Oct 2019 19:03:48 +0200 Subject: [PATCH 36/82] cortex_m: poll S_REGRDY on register r/w Accordingly to arm documentation [1], chapter C1.6.4, the operation to read/write from/to core registers can require time, and the specific flag DHCSR.S_REGRDY has to be polled to verify that the operation has been completed. The lack of check on S_REGRDY causes OpenOCD to fail handling correctly the core registers on a Cortex-M4 emulated in a slow FPGA, and it could also fail on devices clocked at very low speed while using a fast adapter. Poll S_REGRDY as specified in [1] while either reading or writing the core registers. A timeout of 0.5s is added. This could still be too small in some extremely slow cases, but at least now we log the timeout event, which can help tracking down such odd issue. During register read include in the polling loop the read of DCRSR and to flush the JTAG queue only once. During register write, relax the write in DCRSR by removing the atomicity that is now useless since followed by the atomic read to S_REGRDY. During register read include the read of DCRSR inside the polling loop to relax the read of S_REGRDY since followed by the atomic read to DCRSR. This change has the drawback of adding other transfers to the adapter while reading/writing the registers, so it is expected to introduce some speed degradation during step-by-step. [1] DDI0403E - "ARMv7-M Architecture Reference Manual" Change-Id: I61f454248f11a3bec6dcf4c58a50c5c996d7ef81 Signed-off-by: Antonio Borneo Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/5319 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/target/cortex_m.c | 53 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 655825227..ba7bc17b5 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -53,6 +53,9 @@ * any longer. */ +/* Timeout for register r/w */ +#define DHCSR_S_REGRDY_TIMEOUT (500) + /* Supported Cortex-M Cores */ static const struct cortex_m_part_info cortex_m_parts[] = { { @@ -148,9 +151,11 @@ static int cortex_m_read_dhcsr_atomic_sticky(struct target *target) static int cortex_m_load_core_reg_u32(struct target *target, uint32_t regsel, uint32_t *value) { + struct cortex_m_common *cortex_m = target_to_cm(target); struct armv7m_common *armv7m = target_to_armv7m(target); int retval; - uint32_t dcrdr; + uint32_t dcrdr, tmp_value; + int64_t then; /* because the DCB_DCRDR is used for the emulated dcc channel * we have to save/restore the DCB_DCRDR when used */ @@ -164,9 +169,28 @@ static int cortex_m_load_core_reg_u32(struct target *target, if (retval != ERROR_OK) return retval; - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; + /* check if value from register is ready and pre-read it */ + then = timeval_ms(); + while (1) { + retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DHCSR, + &cortex_m->dcb_dhcsr); + if (retval != ERROR_OK) + return retval; + retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DCRDR, + &tmp_value); + if (retval != ERROR_OK) + return retval; + cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); + if (cortex_m->dcb_dhcsr & S_REGRDY) + break; + if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) { + LOG_ERROR("Timeout waiting for DCRDR transfer ready"); + return ERROR_TIMEOUT_REACHED; + } + keep_alive(); + } + + *value = tmp_value; if (target->dbg_msg_enabled) { /* restore DCB_DCRDR - this needs to be in a separate @@ -181,9 +205,11 @@ static int cortex_m_load_core_reg_u32(struct target *target, static int cortex_m_store_core_reg_u32(struct target *target, uint32_t regsel, uint32_t value) { + struct cortex_m_common *cortex_m = target_to_cm(target); struct armv7m_common *armv7m = target_to_armv7m(target); int retval; uint32_t dcrdr; + int64_t then; /* because the DCB_DCRDR is used for the emulated dcc channel * we have to save/restore the DCB_DCRDR when used */ @@ -197,10 +223,27 @@ static int cortex_m_store_core_reg_u32(struct target *target, if (retval != ERROR_OK) return retval; - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regsel | DCRSR_WNR); + retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel | DCRSR_WNR); if (retval != ERROR_OK) return retval; + /* check if value is written into register */ + then = timeval_ms(); + while (1) { + retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, + &cortex_m->dcb_dhcsr); + if (retval != ERROR_OK) + return retval; + cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); + if (cortex_m->dcb_dhcsr & S_REGRDY) + break; + if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) { + LOG_ERROR("Timeout waiting for DCRDR transfer ready"); + return ERROR_TIMEOUT_REACHED; + } + keep_alive(); + } + if (target->dbg_msg_enabled) { /* restore DCB_DCRDR - this needs to be in a separate * transaction otherwise the emulated DCC channel breaks */ From 88f429ead019fd6df96ec15f0d897385f3cef0d0 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 5 Feb 2019 09:39:11 +0100 Subject: [PATCH 37/82] target/cortex_m: faster reading of all CPU registers Without the change cortex_m_debug_entry() reads all registers calling cortex_m_load_core_reg_u32() for each register with a poor usage of JTAG/SWD queue. It is time consuming, especially on an USB FS based adapter. Moreover if target_request debugmsgs are enabled, DCB_DCRDR is saved and restored on each register read. This change introduces cortex_m_fast_read_all_regs() which queues all register reads and a single dap_run() transaction does all work. cortex_m_fast_read_all_regs() reads all registers unconditionally regardless register cache is valid or not. This is a difference from the original cortex_m_debug_entry() code. cortex_m_debug_entry times from -d3 log, Cortex-M4F and CMSIS-DAP (Kinetis K28F-FRDM kit) target_request | time [ms] debugmsgs | without the change | with the change ---------------+--------------------+----------------- disable | 186 | 27 enable | 232 | 29 Added checking of DHCSR.S_REGRDY flag. If "not ready" is seen, cortex_m->slow_register_read is set and fallback to the old register read method cortex_m_slow_read_all_regs() is used instead of cortex_m_fast_read_all_regs(). Change-Id: I0665d94b97ede217394640871dc451ec93410254 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/5321 Tested-by: jenkins Reviewed-by: Andreas Fritiofson Reviewed-by: Antonio Borneo --- src/target/armv7m.c | 4 +- src/target/armv7m.h | 5 ++ src/target/cortex_m.c | 179 +++++++++++++++++++++++++++++++++++++++--- src/target/cortex_m.h | 2 + 4 files changed, 179 insertions(+), 11 deletions(-) diff --git a/src/target/armv7m.c b/src/target/armv7m.c index ffc8ca875..0a51ad4d6 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -251,7 +251,7 @@ static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf) return ERROR_OK; } -static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) +uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) { switch (arm_reg_id) { case ARMV7M_R0 ... ARMV7M_R14: @@ -289,7 +289,7 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) } } -static bool armv7m_map_reg_packing(unsigned int arm_reg_id, +bool armv7m_map_reg_packing(unsigned int arm_reg_id, unsigned int *reg32_id, uint32_t *offset) { diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 2816a9145..d33e57492 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -309,6 +309,11 @@ int armv7m_invalidate_core_regs(struct target *target); int armv7m_restore_context(struct target *target); +uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id); + +bool armv7m_map_reg_packing(unsigned int arm_reg_id, + unsigned int *reg32_id, uint32_t *offset); + int armv7m_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum); int armv7m_blank_check_memory(struct target *target, diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index ba7bc17b5..82d5eff80 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -202,6 +202,163 @@ static int cortex_m_load_core_reg_u32(struct target *target, return retval; } +static int cortex_m_slow_read_all_regs(struct target *target) +{ + struct armv7m_common *armv7m = target_to_armv7m(target); + const unsigned int num_regs = armv7m->arm.core_cache->num_regs; + + for (unsigned int reg_id = 0; reg_id < num_regs; reg_id++) { + struct reg *r = &armv7m->arm.core_cache->reg_list[reg_id]; + if (r->exist) { + int retval = armv7m->arm.read_core_reg(target, r, reg_id, ARM_MODE_ANY); + if (retval != ERROR_OK) + return retval; + } + } + return ERROR_OK; +} + +static int cortex_m_queue_reg_read(struct target *target, uint32_t regsel, + uint32_t *reg_value, uint32_t *dhcsr) +{ + struct armv7m_common *armv7m = target_to_armv7m(target); + int retval; + + retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel); + if (retval != ERROR_OK) + return retval; + + retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DHCSR, dhcsr); + if (retval != ERROR_OK) + return retval; + + return mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, reg_value); +} + +static int cortex_m_fast_read_all_regs(struct target *target) +{ + struct cortex_m_common *cortex_m = target_to_cm(target); + struct armv7m_common *armv7m = target_to_armv7m(target); + int retval; + uint32_t dcrdr; + + /* 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) { + retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr); + if (retval != ERROR_OK) + return retval; + } + + const unsigned int num_regs = armv7m->arm.core_cache->num_regs; + const unsigned int n_r32 = ARMV7M_LAST_REG - ARMV7M_CORE_FIRST_REG + 1 + + ARMV7M_FPU_LAST_REG - ARMV7M_FPU_FIRST_REG + 1; + /* we need one 32-bit word for each register except FP D0..D15, which + * need two words */ + uint32_t r_vals[n_r32]; + uint32_t dhcsr[n_r32]; + + unsigned int wi = 0; /* write index to r_vals and dhcsr arrays */ + unsigned int reg_id; /* register index in the reg_list, ARMV7M_R0... */ + for (reg_id = 0; reg_id < num_regs; reg_id++) { + struct reg *r = &armv7m->arm.core_cache->reg_list[reg_id]; + if (!r->exist) + continue; /* skip non existent registers */ + + if (r->size <= 8) { + /* Any 8-bit or shorter register is unpacked from a 32-bit + * container register. Skip it now. */ + continue; + } + + uint32_t regsel = armv7m_map_id_to_regsel(reg_id); + retval = cortex_m_queue_reg_read(target, regsel, &r_vals[wi], + &dhcsr[wi]); + if (retval != ERROR_OK) + return retval; + wi++; + + assert(r->size == 32 || r->size == 64); + if (r->size == 32) + continue; /* done with 32-bit register */ + + assert(reg_id >= ARMV7M_FPU_FIRST_REG && reg_id <= ARMV7M_FPU_LAST_REG); + /* the odd part of FP register (S1, S3...) */ + retval = cortex_m_queue_reg_read(target, regsel + 1, &r_vals[wi], + &dhcsr[wi]); + if (retval != ERROR_OK) + return retval; + wi++; + } + + assert(wi <= n_r32); + + retval = dap_run(armv7m->debug_ap->dap); + if (retval != ERROR_OK) + return retval; + + if (target->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); + if (retval != ERROR_OK) + return retval; + } + + bool not_ready = false; + for (unsigned int i = 0; i < wi; i++) { + if ((dhcsr[i] & S_REGRDY) == 0) { + not_ready = true; + LOG_DEBUG("Register %u was not ready during fast read", i); + } + cortex_m_cumulate_dhcsr_sticky(cortex_m, dhcsr[i]); + } + + if (not_ready) { + /* Any register was not ready, + * fall back to slow read with S_REGRDY polling */ + return ERROR_TIMEOUT_REACHED; + } + + LOG_DEBUG("read %u 32-bit registers", wi); + + unsigned int ri = 0; /* read index from r_vals array */ + for (reg_id = 0; reg_id < num_regs; reg_id++) { + struct reg *r = &armv7m->arm.core_cache->reg_list[reg_id]; + if (!r->exist) + continue; /* skip non existent registers */ + + r->dirty = false; + + unsigned int reg32_id; + uint32_t offset; + if (armv7m_map_reg_packing(reg_id, ®32_id, &offset)) { + /* Unpack a partial register from 32-bit container register */ + struct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id]; + + /* The container register ought to precede all regs unpacked + * from it in the reg_list. So the value should be ready + * to unpack */ + assert(r32->valid); + buf_cpy(r32->value + offset, r->value, r->size); + + } else { + assert(r->size == 32 || r->size == 64); + buf_set_u32(r->value, 0, 32, r_vals[ri++]); + + if (r->size == 64) { + assert(reg_id >= ARMV7M_FPU_FIRST_REG && reg_id <= ARMV7M_FPU_LAST_REG); + /* the odd part of FP register (S1, S3...) */ + buf_set_u32(r->value + 4, 0, 32, r_vals[ri++]); + } + } + r->valid = true; + } + assert(ri == wi); + + return retval; +} + static int cortex_m_store_core_reg_u32(struct target *target, uint32_t regsel, uint32_t value) { @@ -610,7 +767,6 @@ static int cortex_m_examine_exception_reason(struct target *target) static int cortex_m_debug_entry(struct target *target) { - int i; uint32_t xPSR; int retval; struct cortex_m_common *cortex_m = target_to_cm(target); @@ -646,16 +802,21 @@ static int cortex_m_debug_entry(struct target *target) secure_state = (dscsr & DSCSR_CDS) == DSCSR_CDS; } - /* Examine target state and mode - * First load register accessible through core debug port */ - int num_regs = arm->core_cache->num_regs; - - for (i = 0; i < num_regs; i++) { - r = &armv7m->arm.core_cache->reg_list[i]; - if (r->exist && !r->valid) - arm->read_core_reg(target, r, i, ARM_MODE_ANY); + /* Load all registers to arm.core_cache */ + if (!cortex_m->slow_register_read) { + retval = cortex_m_fast_read_all_regs(target); + if (retval == ERROR_TIMEOUT_REACHED) { + cortex_m->slow_register_read = true; + LOG_DEBUG("Switched to slow register read"); + } } + if (cortex_m->slow_register_read) + retval = cortex_m_slow_read_all_regs(target); + + if (retval != ERROR_OK) + return retval; + r = arm->cpsr; xPSR = buf_get_u32(r->value, 0, 32); diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index a5dfbf856..57ef1e7e8 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -238,6 +238,8 @@ struct cortex_m_common { const struct cortex_m_part_info *core_info; struct armv7m_common armv7m; + bool slow_register_read; /* A register has not been ready, poll S_REGRDY */ + int apsel; /* Whether this target has the erratum that makes C_MASKINTS not apply to From caa16981364d747c1c71edaf156e8a4faa83b02b Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Mon, 8 Nov 2021 18:09:56 +0100 Subject: [PATCH 38/82] cortex_m: Restore fast register reads if no polling is needed If the target is in a state where S_REGRDY polling is necessary (slow clock, low power state...?), OpenOCD will continue to use the slow path even if the condition is temporary and the target at a later point would be capable of fast reads again. Revert to fast reads if a full register dump can be made without need for polling any of the registers; presumably it will succeed the next time too. Change-Id: I557f0d90b7ce6f9d81aa409b6400fc9c83d16008 Signed-off-by: Andreas Fritiofson Reviewed-on: https://review.openocd.org/c/openocd/+/6678 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- src/target/cortex_m.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 82d5eff80..721cf0a24 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -183,6 +183,7 @@ static int cortex_m_load_core_reg_u32(struct target *target, cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); if (cortex_m->dcb_dhcsr & S_REGRDY) break; + cortex_m->slow_register_read = true; /* Polling (still) needed. */ if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) { LOG_ERROR("Timeout waiting for DCRDR transfer ready"); return ERROR_TIMEOUT_REACHED; @@ -204,9 +205,14 @@ static int cortex_m_load_core_reg_u32(struct target *target, static int cortex_m_slow_read_all_regs(struct target *target) { + struct cortex_m_common *cortex_m = target_to_cm(target); struct armv7m_common *armv7m = target_to_armv7m(target); const unsigned int num_regs = armv7m->arm.core_cache->num_regs; + /* Opportunistically restore fast read, it'll revert to slow + * if any register needed polling in cortex_m_load_core_reg_u32(). */ + cortex_m->slow_register_read = false; + for (unsigned int reg_id = 0; reg_id < num_regs; reg_id++) { struct reg *r = &armv7m->arm.core_cache->reg_list[reg_id]; if (r->exist) { @@ -215,6 +221,10 @@ static int cortex_m_slow_read_all_regs(struct target *target) return retval; } } + + if (!cortex_m->slow_register_read) + LOG_DEBUG("Switching back to fast register reads"); + return ERROR_OK; } From 0432ac83997c2e3aef18ab545be35a28ec6d8c11 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 11 Nov 2021 16:39:39 +0100 Subject: [PATCH 39/82] arm_adi_v5: add missing enum DORMANT_TO_JTAG Add the value DORMANT_TO_JTAG in the enum listing the SWJ-DP switching sequences. The corresponding bit-sequence is already available. Change-Id: I6f1ffd29a8f5729ec70ce0303248bc251409d37d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6689 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/target/arm_adi_v5.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 0e1b95f50..fa0a78a7e 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -191,6 +191,7 @@ enum swd_special_seq { SWD_TO_JTAG, SWD_TO_DORMANT, DORMANT_TO_SWD, + DORMANT_TO_JTAG, }; /** From ed44acce26edf259f5b238b972a6a4fe2597ca48 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 11 Nov 2021 16:42:51 +0100 Subject: [PATCH 40/82] cmsis_dap: add support for dormant-to-jtag Change-Id: I4a51f3772cd94d7dda5a66a1d13acd24d0d0c63c Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6690 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/cmsis_dap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index 19649b71c..c0898fc30 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -1134,6 +1134,11 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq) s = swd_seq_dormant_to_swd; s_len = swd_seq_dormant_to_swd_len; break; + case DORMANT_TO_JTAG: + LOG_DEBUG("DORMANT-to-JTAG"); + s = swd_seq_dormant_to_jtag; + s_len = swd_seq_dormant_to_jtag_len; + break; default: LOG_ERROR("Sequence %d not supported", seq); return ERROR_FAIL; From b4aa144c326e2f86f52ac48d4cb560f88a1f2b97 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 11 Nov 2021 16:44:27 +0100 Subject: [PATCH 41/82] drivers/bitbang: add support to switch to/from dormant state While there, replace the SWD_CMD_PARK macro to the magic number. Change-Id: Id9094dcb2b010b9e894a5ed9e4a99d2287e5969c Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6691 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/bitbang.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c index 5c4febb20..d202a0596 100644 --- a/src/jtag/drivers/bitbang.c +++ b/src/jtag/drivers/bitbang.c @@ -434,10 +434,26 @@ static int bitbang_swd_switch_seq(enum swd_special_seq seq) LOG_DEBUG("JTAG-to-SWD"); bitbang_swd_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len); break; + case JTAG_TO_DORMANT: + LOG_DEBUG("JTAG-to-DORMANT"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_jtag_to_dormant, 0, swd_seq_jtag_to_dormant_len); + break; case SWD_TO_JTAG: LOG_DEBUG("SWD-to-JTAG"); bitbang_swd_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len); break; + case SWD_TO_DORMANT: + LOG_DEBUG("SWD-to-DORMANT"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_swd_to_dormant, 0, swd_seq_swd_to_dormant_len); + break; + case DORMANT_TO_SWD: + LOG_DEBUG("DORMANT-to-SWD"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_dormant_to_swd, 0, swd_seq_dormant_to_swd_len); + break; + case DORMANT_TO_JTAG: + LOG_DEBUG("DORMANT-to-JTAG"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_dormant_to_jtag, 0, swd_seq_dormant_to_jtag_len); + break; default: LOG_ERROR("Sequence %d not supported", seq); return ERROR_FAIL; @@ -465,7 +481,7 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay for (;;) { uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; - cmd |= SWD_CMD_START | (1 << 7); + cmd |= SWD_CMD_START | SWD_CMD_PARK; bitbang_swd_exchange(false, &cmd, 0, 8); bitbang_interface->swdio_drive(false); @@ -526,7 +542,7 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32, value); buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(value)); - cmd |= SWD_CMD_START | (1 << 7); + cmd |= SWD_CMD_START | SWD_CMD_PARK; bitbang_swd_exchange(false, &cmd, 0, 8); bitbang_interface->swdio_drive(false); From 560f0d83392bafc03d674e13880940d52d3f7f94 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 11 Nov 2021 22:13:55 +0100 Subject: [PATCH 42/82] jlink: add support to switch to/from dormant state Change-Id: Ifeda21ab7a40926166045f211b9e772aedff715d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6692 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/jlink.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index ce1e9bfb7..0414ec710 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -2148,11 +2148,31 @@ static int jlink_swd_switch_seq(enum swd_special_seq seq) s = swd_seq_jtag_to_swd; s_len = swd_seq_jtag_to_swd_len; break; + case JTAG_TO_DORMANT: + LOG_DEBUG("JTAG-to-DORMANT"); + s = swd_seq_jtag_to_dormant; + s_len = swd_seq_jtag_to_dormant_len; + break; case SWD_TO_JTAG: LOG_DEBUG("SWD-to-JTAG"); s = swd_seq_swd_to_jtag; s_len = swd_seq_swd_to_jtag_len; break; + case SWD_TO_DORMANT: + LOG_DEBUG("SWD-to-DORMANT"); + s = swd_seq_swd_to_dormant; + s_len = swd_seq_swd_to_dormant_len; + break; + case DORMANT_TO_SWD: + LOG_DEBUG("DORMANT-to-SWD"); + s = swd_seq_dormant_to_swd; + s_len = swd_seq_dormant_to_swd_len; + break; + case DORMANT_TO_JTAG: + LOG_DEBUG("DORMANT-to-JTAG"); + s = swd_seq_dormant_to_jtag; + s_len = swd_seq_dormant_to_jtag_len; + break; default: LOG_ERROR("Sequence %d not supported", seq); return ERROR_FAIL; From fdaa16506d121f4d4616a2bcafe7dee017d55d81 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 11 Nov 2021 22:29:32 +0100 Subject: [PATCH 43/82] ftdi: add support to switch to/from dormant state Partially extracted from https://review.openocd.org/4935 Change-Id: Ia3f197b257434a1a7979fdbc08936c7c541db1e2 Signed-off-by: Antonio Borneo Signed-off-by: graham sanderson Reviewed-on: https://review.openocd.org/c/openocd/+/6693 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Andreas Fritiofson --- src/jtag/drivers/ftdi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 6e2e18450..d03a4ca23 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -1238,11 +1238,31 @@ static int ftdi_swd_switch_seq(enum swd_special_seq seq) ftdi_swd_swdio_en(true); mpsse_clock_data_out(mpsse_ctx, swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len, SWD_MODE); break; + case JTAG_TO_DORMANT: + LOG_DEBUG("JTAG-to-DORMANT"); + ftdi_swd_swdio_en(true); + mpsse_clock_data_out(mpsse_ctx, swd_seq_jtag_to_dormant, 0, swd_seq_jtag_to_dormant_len, SWD_MODE); + break; case SWD_TO_JTAG: LOG_DEBUG("SWD-to-JTAG"); ftdi_swd_swdio_en(true); mpsse_clock_data_out(mpsse_ctx, swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len, SWD_MODE); break; + case SWD_TO_DORMANT: + LOG_DEBUG("SWD-to-DORMANT"); + ftdi_swd_swdio_en(true); + mpsse_clock_data_out(mpsse_ctx, swd_seq_swd_to_dormant, 0, swd_seq_swd_to_dormant_len, SWD_MODE); + break; + case DORMANT_TO_SWD: + LOG_DEBUG("DORMANT-to-SWD"); + ftdi_swd_swdio_en(true); + mpsse_clock_data_out(mpsse_ctx, swd_seq_dormant_to_swd, 0, swd_seq_dormant_to_swd_len, SWD_MODE); + break; + case DORMANT_TO_JTAG: + LOG_DEBUG("DORMANT-to-JTAG"); + ftdi_swd_swdio_en(true); + mpsse_clock_data_out(mpsse_ctx, swd_seq_dormant_to_jtag, 0, swd_seq_dormant_to_jtag_len, SWD_MODE); + break; default: LOG_ERROR("Sequence %d not supported", seq); return ERROR_FAIL; From d385dfbab44dc669c037b87c2e5b5c52accfcbe3 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 11 Nov 2021 23:48:10 +0100 Subject: [PATCH 44/82] adi_v5_swd: add comment to describe debug flag 'do_sync' Change-Id: I1f7f0eed7a6e3626f5fde841ec7fa1d29906db29 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6696 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/adi_v5_swd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index a21bf25b9..5e4fd2222 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -53,6 +53,7 @@ #include +/* for debug, set do_sync to true to force synchronous transfers */ static bool do_sync; static void swd_finish_read(struct adiv5_dap *dap) From ee670f9dcee606141112a7552d8409788f3caf7f Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 8 Nov 2021 09:42:41 +0100 Subject: [PATCH 45/82] jimtcl: update to master branch 20211108 Today's version of jimtcl includes a fix for autoconf >= 2.70 and a minor fix for warnings with GCC 11. To prepare for next jimtcl 0.81, let's merge and test the updated master branch. Change-Id: I455cc708f7d4786461978e38b6ac71816e2c9825 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6674 Tested-by: jenkins --- jimtcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jimtcl b/jimtcl index 2d66360c6..70b007b63 160000 --- a/jimtcl +++ b/jimtcl @@ -1 +1 @@ -Subproject commit 2d66360c61d2a89d4008e8bad12ae3aa5f0331e2 +Subproject commit 70b007b63669a709b0e8aef34a22658047815cc2 From f8bd2566a936c7909f2b602bba3c83cc833afaea Mon Sep 17 00:00:00 2001 From: Jan Matyas <50193733+JanMatCodasip@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:48:23 +0100 Subject: [PATCH 46/82] riscv: Regenerated debug_defines.h and encoding.h The main intention is to get access to some of the CSRs that were so far unknown to OpenOCD (tinfo, mcountinhibit, ...). https://github.com/riscv/riscv-openocd/pull/659 Signed-off-by: Tim Newsome Change-Id: I824fdb558d5c1f73432b0f56f3b0b4d865eceeba Reviewed-on: https://review.openocd.org/c/openocd/+/6682 Tested-by: jenkins Reviewed-by: Jan Matyas Reviewed-by: Antonio Borneo --- src/target/riscv/debug_defines.h | 25 +- src/target/riscv/encoding.h | 1845 +++++++++++++++++++++++++++--- 2 files changed, 1705 insertions(+), 165 deletions(-) diff --git a/src/target/riscv/debug_defines.h b/src/target/riscv/debug_defines.h index b5104d530..5c9eef4ea 100644 --- a/src/target/riscv/debug_defines.h +++ b/src/target/riscv/debug_defines.h @@ -1,6 +1,6 @@ /* * This file is auto-generated by running 'make debug_defines.h' in - * https://github.com/riscv/riscv-debug-spec/ (63c985f) + * https://github.com/riscv/riscv-debug-spec/ (3dfe4f7) * License: Creative Commons Attribution 4.0 International Public License (CC BY 4.0) */ @@ -266,7 +266,7 @@ * * 1: An {\tt ebreak} instruction was executed. (priority 3) * - * 2: The Trigger Module caused a breakpoint exception. (priority 4) + * 2: A Trigger Module trigger fired with action=0. (priority 4) * * 3: The debugger requested entry to Debug Mode using \FdmDmcontrolHaltreq. * (priority 1) @@ -461,7 +461,7 @@ * * \FcsrTcontrolMpte and \FcsrTcontrolMte provide one solution to a problem * regarding triggers with action=0 firing in M-mode trap handlers. See - * Section~\ref{sec:mmtrigger} for more details. + * Section~\ref{sec:nativetrigger} for more details. * * When a trap into M-mode is taken, \FcsrTcontrolMpte is set to the value of * \FcsrTcontrolMte. @@ -811,8 +811,9 @@ #define CSR_MCONTROL6_VU_LENGTH 1 #define CSR_MCONTROL6_VU (0x1ULL << CSR_MCONTROL6_VU_OFFSET) /* - * If this bit is implemented, the hardware sets it when this - * trigger matches. The trigger's user can set or clear it at any + * If this bit is implemented then it must become set when this + * trigger fires and may become set when this trigger matches. + * The trigger's user can set or clear it at any * time. It is used to determine which * trigger(s) matched. If the bit is not implemented, it is always 0 * and writing it has no effect. @@ -1237,7 +1238,8 @@ #define CSR_ETRIGGER_VU (0x1ULL << CSR_ETRIGGER_VU_OFFSET) /* * When set, non-maskable interrupts cause this - * trigger to fire, regardless of the values of \FcsrEtriggerM, \FcsrEtriggerS, and \FcsrEtriggerU. + * trigger to fire, regardless of the values of \FcsrEtriggerM, + * \FcsrEtriggerS, \FcsrEtriggerU, \FcsrEtriggerVs, and \FcsrEtriggerVu. */ #define CSR_ETRIGGER_NMI_OFFSET 10 #define CSR_ETRIGGER_NMI_LENGTH 1 @@ -1361,10 +1363,15 @@ * 1: This trigger will only match if the low bits of * \RcsrScontext equal \FcsrTextraThirtytwoSvalue. * - * 2: This trigger will only match if the currently active ASID - * value, from either \Rsatp or \Rvsatp, - * equals the lower ASIDMAX (defined in the Privileged Spec) bits of + * 2: This trigger will only match if: + * \begin{itemize}[noitemsep,nolistsep] + * \item the mode is VS-mode or VU-mode and ASID in \Rvsatp + * equals the lower ASIDMAX (defined in the Privileged Spec) bits + * of \FcsrTextraThirtytwoSvalue. + * \item in all other modes, ASID in \Rsatp equals the lower + * ASIDMAX (defined in the Privileged Spec) bits of * \FcsrTextraThirtytwoSvalue. + * \end{itemize} * * This field should be tied to 0 when S-mode is not supported. */ diff --git a/src/target/riscv/encoding.h b/src/target/riscv/encoding.h index 4a035e288..4445f0bd2 100644 --- a/src/target/riscv/encoding.h +++ b/src/target/riscv/encoding.h @@ -1,6 +1,6 @@ /* * This file is auto-generated by running 'make ../riscv-openocd/src/target/riscv/encoding.h' in - * https://github.com/riscv/riscv-opcodes (876ee63) + * https://github.com/riscv/riscv-opcodes (6c34f60) */ /* See LICENSE for license details. */ @@ -14,7 +14,7 @@ #define MSTATUS_MIE 0x00000008 #define MSTATUS_UPIE 0x00000010 #define MSTATUS_SPIE 0x00000020 -#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_UBE 0x00000040 #define MSTATUS_MPIE 0x00000080 #define MSTATUS_SPP 0x00000100 #define MSTATUS_VS 0x00000600 @@ -30,14 +30,22 @@ #define MSTATUS32_SD 0x80000000 #define MSTATUS_UXL 0x0000000300000000 #define MSTATUS_SXL 0x0000000C00000000 +#define MSTATUS_SBE 0x0000001000000000 +#define MSTATUS_MBE 0x0000002000000000 #define MSTATUS_GVA 0x0000004000000000 #define MSTATUS_MPV 0x0000008000000000 #define MSTATUS64_SD 0x8000000000000000 +#define MSTATUSH_SBE 0x00000010 +#define MSTATUSH_MBE 0x00000020 +#define MSTATUSH_GVA 0x00000040 +#define MSTATUSH_MPV 0x00000080 + #define SSTATUS_UIE 0x00000001 #define SSTATUS_SIE 0x00000002 #define SSTATUS_UPIE 0x00000010 #define SSTATUS_SPIE 0x00000020 +#define SSTATUS_UBE 0x00000040 #define SSTATUS_SPP 0x00000100 #define SSTATUS_VS 0x00000600 #define SSTATUS_FS 0x00006000 @@ -48,10 +56,6 @@ #define SSTATUS_UXL 0x0000000300000000 #define SSTATUS64_SD 0x8000000000000000 -#define SSTATUS_VS_MASK (SSTATUS_SIE | SSTATUS_SPIE | \ - SSTATUS_SPP | SSTATUS_SUM | \ - SSTATUS_MXR | SSTATUS_UXL) - #define HSTATUS_VSXL 0x300000000 #define HSTATUS_VTSR 0x00400000 #define HSTATUS_VTW 0x00200000 @@ -205,12 +209,6 @@ #define IRQ_COP 12 #define IRQ_HOST 13 -#define DEFAULT_RSTVEC 0x00001000 -#define CLINT_BASE 0x02000000 -#define CLINT_SIZE 0x000c0000 -#define EXT_IO_BASE 0x40000000 -#define DRAM_BASE 0x80000000 - /* page table entry (PTE) fields */ #define PTE_V 0x001 /* Valid */ #define PTE_R 0x002 /* Read */ @@ -221,6 +219,10 @@ #define PTE_A 0x040 /* Accessed */ #define PTE_D 0x080 /* Dirty */ #define PTE_SOFT 0x300 /* Reserved for Software */ +#define PTE_RSVD 0x1FC0000000000000 /* Reserved for future standard use */ +#define PTE_PBMT 0x6000000000000000 /* Svpbmt: Page-based memory types */ +#define PTE_N 0x8000000000000000 /* Svnapot: NAPOT translation contiguity */ +#define PTE_ATTR 0xFFC0000000000000 /* All attributes and reserved bits */ #define PTE_PPN_SHIFT 10 @@ -347,18 +349,12 @@ #define MASK_AUIPC 0x7f #define MATCH_ADDI 0x13 #define MASK_ADDI 0x707f -#define MATCH_SLLI 0x1013 -#define MASK_SLLI 0xfc00707f #define MATCH_SLTI 0x2013 #define MASK_SLTI 0x707f #define MATCH_SLTIU 0x3013 #define MASK_SLTIU 0x707f #define MATCH_XORI 0x4013 #define MASK_XORI 0x707f -#define MATCH_SRLI 0x5013 -#define MASK_SRLI 0xfc00707f -#define MATCH_SRAI 0x40005013 -#define MASK_SRAI 0xfc00707f #define MATCH_ORI 0x6013 #define MASK_ORI 0x707f #define MATCH_ANDI 0x7013 @@ -427,6 +423,12 @@ #define MASK_LWU 0x707f #define MATCH_SD 0x3023 #define MASK_SD 0x707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f #define MATCH_MUL 0x2000033 #define MASK_MUL 0xfe00707f #define MATCH_MULH 0x2001033 @@ -715,12 +717,216 @@ #define MASK_FCVT_Q_L 0xfff0007f #define MATCH_FCVT_Q_LU 0xd6300053 #define MASK_FCVT_Q_LU 0xfff0007f +#define MATCH_ANDN 0x40007033 +#define MASK_ANDN 0xfe00707f +#define MATCH_ORN 0x40006033 +#define MASK_ORN 0xfe00707f +#define MATCH_XNOR 0x40004033 +#define MASK_XNOR 0xfe00707f +#define MATCH_SLO 0x20001033 +#define MASK_SLO 0xfe00707f +#define MATCH_SRO 0x20005033 +#define MASK_SRO 0xfe00707f +#define MATCH_ROL 0x60001033 +#define MASK_ROL 0xfe00707f +#define MATCH_ROR 0x60005033 +#define MASK_ROR 0xfe00707f +#define MATCH_BCLR 0x48001033 +#define MASK_BCLR 0xfe00707f +#define MATCH_BSET 0x28001033 +#define MASK_BSET 0xfe00707f +#define MATCH_BINV 0x68001033 +#define MASK_BINV 0xfe00707f +#define MATCH_BEXT 0x48005033 +#define MASK_BEXT 0xfe00707f +#define MATCH_GORC 0x28005033 +#define MASK_GORC 0xfe00707f +#define MATCH_GREV 0x68005033 +#define MASK_GREV 0xfe00707f +#define MATCH_SLOI 0x20001013 +#define MASK_SLOI 0xfc00707f +#define MATCH_SROI 0x20005013 +#define MASK_SROI 0xfc00707f +#define MATCH_RORI 0x60005013 +#define MASK_RORI 0xfc00707f +#define MATCH_BCLRI 0x48001013 +#define MASK_BCLRI 0xfc00707f +#define MATCH_BSETI 0x28001013 +#define MASK_BSETI 0xfc00707f +#define MATCH_BINVI 0x68001013 +#define MASK_BINVI 0xfc00707f +#define MATCH_BEXTI 0x48005013 +#define MASK_BEXTI 0xfc00707f +#define MATCH_GORCI 0x28005013 +#define MASK_GORCI 0xfc00707f +#define MATCH_GREVI 0x68005013 +#define MASK_GREVI 0xfc00707f +#define MATCH_CMIX 0x6001033 +#define MASK_CMIX 0x600707f +#define MATCH_CMOV 0x6005033 +#define MASK_CMOV 0x600707f +#define MATCH_FSL 0x4001033 +#define MASK_FSL 0x600707f +#define MATCH_FSR 0x4005033 +#define MASK_FSR 0x600707f +#define MATCH_FSRI 0x4005013 +#define MASK_FSRI 0x400707f +#define MATCH_CLZ 0x60001013 +#define MASK_CLZ 0xfff0707f +#define MATCH_CTZ 0x60101013 +#define MASK_CTZ 0xfff0707f +#define MATCH_CPOP 0x60201013 +#define MASK_CPOP 0xfff0707f +#define MATCH_SEXT_B 0x60401013 +#define MASK_SEXT_B 0xfff0707f +#define MATCH_SEXT_H 0x60501013 +#define MASK_SEXT_H 0xfff0707f +#define MATCH_CRC32_B 0x61001013 +#define MASK_CRC32_B 0xfff0707f +#define MATCH_CRC32_H 0x61101013 +#define MASK_CRC32_H 0xfff0707f +#define MATCH_CRC32_W 0x61201013 +#define MASK_CRC32_W 0xfff0707f +#define MATCH_CRC32C_B 0x61801013 +#define MASK_CRC32C_B 0xfff0707f +#define MATCH_CRC32C_H 0x61901013 +#define MASK_CRC32C_H 0xfff0707f +#define MATCH_CRC32C_W 0x61a01013 +#define MASK_CRC32C_W 0xfff0707f +#define MATCH_SH1ADD 0x20002033 +#define MASK_SH1ADD 0xfe00707f +#define MATCH_SH2ADD 0x20004033 +#define MASK_SH2ADD 0xfe00707f +#define MATCH_SH3ADD 0x20006033 +#define MASK_SH3ADD 0xfe00707f +#define MATCH_CLMUL 0xa001033 +#define MASK_CLMUL 0xfe00707f +#define MATCH_CLMULR 0xa002033 +#define MASK_CLMULR 0xfe00707f +#define MATCH_CLMULH 0xa003033 +#define MASK_CLMULH 0xfe00707f +#define MATCH_MIN 0xa004033 +#define MASK_MIN 0xfe00707f +#define MATCH_MINU 0xa005033 +#define MASK_MINU 0xfe00707f +#define MATCH_MAX 0xa006033 +#define MASK_MAX 0xfe00707f +#define MATCH_MAXU 0xa007033 +#define MASK_MAXU 0xfe00707f +#define MATCH_SHFL 0x8001033 +#define MASK_SHFL 0xfe00707f +#define MATCH_UNSHFL 0x8005033 +#define MASK_UNSHFL 0xfe00707f +#define MATCH_BCOMPRESS 0x8006033 +#define MASK_BCOMPRESS 0xfe00707f +#define MATCH_BDECOMPRESS 0x48006033 +#define MASK_BDECOMPRESS 0xfe00707f +#define MATCH_PACK 0x8004033 +#define MASK_PACK 0xfe00707f +#define MATCH_PACKU 0x48004033 +#define MASK_PACKU 0xfe00707f +#define MATCH_PACKH 0x8007033 +#define MASK_PACKH 0xfe00707f +#define MATCH_BFP 0x48007033 +#define MASK_BFP 0xfe00707f +#define MATCH_SHFLI 0x8001013 +#define MASK_SHFLI 0xfe00707f +#define MATCH_UNSHFLI 0x8005013 +#define MASK_UNSHFLI 0xfe00707f +#define MATCH_XPERM4 0x28002033 +#define MASK_XPERM4 0xfe00707f +#define MATCH_XPERM8 0x28004033 +#define MASK_XPERM8 0xfe00707f +#define MATCH_XPERM16 0x28006033 +#define MASK_XPERM16 0xfe00707f +#define MATCH_BMATFLIP 0x60301013 +#define MASK_BMATFLIP 0xfff0707f +#define MATCH_CRC32_D 0x61301013 +#define MASK_CRC32_D 0xfff0707f +#define MATCH_CRC32C_D 0x61b01013 +#define MASK_CRC32C_D 0xfff0707f +#define MATCH_BMATOR 0x8003033 +#define MASK_BMATOR 0xfe00707f +#define MATCH_BMATXOR 0x48003033 +#define MASK_BMATXOR 0xfe00707f +#define MATCH_SLLI_UW 0x800101b +#define MASK_SLLI_UW 0xfc00707f +#define MATCH_ADD_UW 0x800003b +#define MASK_ADD_UW 0xfe00707f +#define MATCH_SLOW 0x2000103b +#define MASK_SLOW 0xfe00707f +#define MATCH_SROW 0x2000503b +#define MASK_SROW 0xfe00707f +#define MATCH_ROLW 0x6000103b +#define MASK_ROLW 0xfe00707f +#define MATCH_RORW 0x6000503b +#define MASK_RORW 0xfe00707f +#define MATCH_SBCLRW 0x4800103b +#define MASK_SBCLRW 0xfe00707f +#define MATCH_SBSETW 0x2800103b +#define MASK_SBSETW 0xfe00707f +#define MATCH_SBINVW 0x6800103b +#define MASK_SBINVW 0xfe00707f +#define MATCH_SBEXTW 0x4800503b +#define MASK_SBEXTW 0xfe00707f +#define MATCH_GORCW 0x2800503b +#define MASK_GORCW 0xfe00707f +#define MATCH_GREVW 0x6800503b +#define MASK_GREVW 0xfe00707f +#define MATCH_SLOIW 0x2000101b +#define MASK_SLOIW 0xfe00707f +#define MATCH_SROIW 0x2000501b +#define MASK_SROIW 0xfe00707f +#define MATCH_RORIW 0x6000501b +#define MASK_RORIW 0xfe00707f +#define MATCH_SBCLRIW 0x4800101b +#define MASK_SBCLRIW 0xfe00707f +#define MATCH_SBSETIW 0x2800101b +#define MASK_SBSETIW 0xfe00707f +#define MATCH_SBINVIW 0x6800101b +#define MASK_SBINVIW 0xfe00707f +#define MATCH_GORCIW 0x2800501b +#define MASK_GORCIW 0xfe00707f +#define MATCH_GREVIW 0x6800501b +#define MASK_GREVIW 0xfe00707f +#define MATCH_FSLW 0x400103b +#define MASK_FSLW 0x600707f +#define MATCH_FSRW 0x400503b +#define MASK_FSRW 0x600707f +#define MATCH_FSRIW 0x400501b +#define MASK_FSRIW 0x600707f +#define MATCH_CLZW 0x6000101b +#define MASK_CLZW 0xfff0707f +#define MATCH_CTZW 0x6010101b +#define MASK_CTZW 0xfff0707f +#define MATCH_CPOPW 0x6020101b +#define MASK_CPOPW 0xfff0707f +#define MATCH_SH1ADD_UW 0x2000203b +#define MASK_SH1ADD_UW 0xfe00707f +#define MATCH_SH2ADD_UW 0x2000403b +#define MASK_SH2ADD_UW 0xfe00707f +#define MATCH_SH3ADD_UW 0x2000603b +#define MASK_SH3ADD_UW 0xfe00707f +#define MATCH_SHFLW 0x800103b +#define MASK_SHFLW 0xfe00707f +#define MATCH_UNSHFLW 0x800503b +#define MASK_UNSHFLW 0xfe00707f +#define MATCH_BCOMPRESSW 0x800603b +#define MASK_BCOMPRESSW 0xfe00707f +#define MATCH_BDECOMPRESSW 0x4800603b +#define MASK_BDECOMPRESSW 0xfe00707f +#define MATCH_PACKW 0x800403b +#define MASK_PACKW 0xfe00707f +#define MATCH_PACKUW 0x4800403b +#define MASK_PACKUW 0xfe00707f +#define MATCH_BFPW 0x4800703b +#define MASK_BFPW 0xfe00707f +#define MATCH_XPERM32 0x28000033 +#define MASK_XPERM32 0xfe00707f #define MATCH_ECALL 0x73 #define MASK_ECALL 0xffffffff #define MATCH_EBREAK 0x100073 #define MASK_EBREAK 0xffffffff -#define MATCH_URET 0x200073 -#define MASK_URET 0xffffffff #define MATCH_SRET 0x10200073 #define MASK_SRET 0xffffffff #define MATCH_MRET 0x30200073 @@ -743,6 +949,146 @@ #define MASK_CSRRSI 0x707f #define MATCH_CSRRCI 0x7073 #define MASK_CSRRCI 0x707f +#define MATCH_SINVAL_VMA 0x16000073 +#define MASK_SINVAL_VMA 0xfe007fff +#define MATCH_SFENCE_W_INVAL 0x18000073 +#define MASK_SFENCE_W_INVAL 0xffffffff +#define MATCH_SFENCE_INVAL_IR 0x18100073 +#define MASK_SFENCE_INVAL_IR 0xffffffff +#define MATCH_HINVAL_VVMA 0x36000073 +#define MASK_HINVAL_VVMA 0xfe007fff +#define MATCH_HINVAL_GVMA 0x76000073 +#define MASK_HINVAL_GVMA 0xfe007fff +#define MATCH_FADD_H 0x4000053 +#define MASK_FADD_H 0xfe00007f +#define MATCH_FSUB_H 0xc000053 +#define MASK_FSUB_H 0xfe00007f +#define MATCH_FMUL_H 0x14000053 +#define MASK_FMUL_H 0xfe00007f +#define MATCH_FDIV_H 0x1c000053 +#define MASK_FDIV_H 0xfe00007f +#define MATCH_FSGNJ_H 0x24000053 +#define MASK_FSGNJ_H 0xfe00707f +#define MATCH_FSGNJN_H 0x24001053 +#define MASK_FSGNJN_H 0xfe00707f +#define MATCH_FSGNJX_H 0x24002053 +#define MASK_FSGNJX_H 0xfe00707f +#define MATCH_FMIN_H 0x2c000053 +#define MASK_FMIN_H 0xfe00707f +#define MATCH_FMAX_H 0x2c001053 +#define MASK_FMAX_H 0xfe00707f +#define MATCH_FCVT_H_S 0x44000053 +#define MASK_FCVT_H_S 0xfff0007f +#define MATCH_FCVT_S_H 0x40200053 +#define MASK_FCVT_S_H 0xfff0007f +#define MATCH_FSQRT_H 0x5c000053 +#define MASK_FSQRT_H 0xfff0007f +#define MATCH_FLE_H 0xa4000053 +#define MASK_FLE_H 0xfe00707f +#define MATCH_FLT_H 0xa4001053 +#define MASK_FLT_H 0xfe00707f +#define MATCH_FEQ_H 0xa4002053 +#define MASK_FEQ_H 0xfe00707f +#define MATCH_FCVT_W_H 0xc4000053 +#define MASK_FCVT_W_H 0xfff0007f +#define MATCH_FCVT_WU_H 0xc4100053 +#define MASK_FCVT_WU_H 0xfff0007f +#define MATCH_FMV_X_H 0xe4000053 +#define MASK_FMV_X_H 0xfff0707f +#define MATCH_FCLASS_H 0xe4001053 +#define MASK_FCLASS_H 0xfff0707f +#define MATCH_FCVT_H_W 0xd4000053 +#define MASK_FCVT_H_W 0xfff0007f +#define MATCH_FCVT_H_WU 0xd4100053 +#define MASK_FCVT_H_WU 0xfff0007f +#define MATCH_FMV_H_X 0xf4000053 +#define MASK_FMV_H_X 0xfff0707f +#define MATCH_FLH 0x1007 +#define MASK_FLH 0x707f +#define MATCH_FSH 0x1027 +#define MASK_FSH 0x707f +#define MATCH_FMADD_H 0x4000043 +#define MASK_FMADD_H 0x600007f +#define MATCH_FMSUB_H 0x4000047 +#define MASK_FMSUB_H 0x600007f +#define MATCH_FNMSUB_H 0x400004b +#define MASK_FNMSUB_H 0x600007f +#define MATCH_FNMADD_H 0x400004f +#define MASK_FNMADD_H 0x600007f +#define MATCH_FCVT_H_D 0x44100053 +#define MASK_FCVT_H_D 0xfff0007f +#define MATCH_FCVT_D_H 0x42200053 +#define MASK_FCVT_D_H 0xfff0007f +#define MATCH_FCVT_H_Q 0x44300053 +#define MASK_FCVT_H_Q 0xfff0007f +#define MATCH_FCVT_Q_H 0x46200053 +#define MASK_FCVT_Q_H 0xfff0007f +#define MATCH_FCVT_L_H 0xc4200053 +#define MASK_FCVT_L_H 0xfff0007f +#define MATCH_FCVT_LU_H 0xc4300053 +#define MASK_FCVT_LU_H 0xfff0007f +#define MATCH_FCVT_H_L 0xd4200053 +#define MASK_FCVT_H_L 0xfff0007f +#define MATCH_FCVT_H_LU 0xd4300053 +#define MASK_FCVT_H_LU 0xfff0007f +#define MATCH_SM4ED 0x30000033 +#define MASK_SM4ED 0x3e00707f +#define MATCH_SM4KS 0x34000033 +#define MASK_SM4KS 0x3e00707f +#define MATCH_SM3P0 0x10801013 +#define MASK_SM3P0 0xfff0707f +#define MATCH_SM3P1 0x10901013 +#define MASK_SM3P1 0xfff0707f +#define MATCH_SHA256SUM0 0x10001013 +#define MASK_SHA256SUM0 0xfff0707f +#define MATCH_SHA256SUM1 0x10101013 +#define MASK_SHA256SUM1 0xfff0707f +#define MATCH_SHA256SIG0 0x10201013 +#define MASK_SHA256SIG0 0xfff0707f +#define MATCH_SHA256SIG1 0x10301013 +#define MASK_SHA256SIG1 0xfff0707f +#define MATCH_AES32ESMI 0x26000033 +#define MASK_AES32ESMI 0x3e00707f +#define MATCH_AES32ESI 0x22000033 +#define MASK_AES32ESI 0x3e00707f +#define MATCH_AES32DSMI 0x2e000033 +#define MASK_AES32DSMI 0x3e00707f +#define MATCH_AES32DSI 0x2a000033 +#define MASK_AES32DSI 0x3e00707f +#define MATCH_SHA512SUM0R 0x50000033 +#define MASK_SHA512SUM0R 0xfe00707f +#define MATCH_SHA512SUM1R 0x52000033 +#define MASK_SHA512SUM1R 0xfe00707f +#define MATCH_SHA512SIG0L 0x54000033 +#define MASK_SHA512SIG0L 0xfe00707f +#define MATCH_SHA512SIG0H 0x5c000033 +#define MASK_SHA512SIG0H 0xfe00707f +#define MATCH_SHA512SIG1L 0x56000033 +#define MASK_SHA512SIG1L 0xfe00707f +#define MATCH_SHA512SIG1H 0x5e000033 +#define MASK_SHA512SIG1H 0xfe00707f +#define MATCH_AES64KS1I 0x31001013 +#define MASK_AES64KS1I 0xff00707f +#define MATCH_AES64IM 0x30001013 +#define MASK_AES64IM 0xfff0707f +#define MATCH_AES64KS2 0x7e000033 +#define MASK_AES64KS2 0xfe00707f +#define MATCH_AES64ESM 0x36000033 +#define MASK_AES64ESM 0xfe00707f +#define MATCH_AES64ES 0x32000033 +#define MASK_AES64ES 0xfe00707f +#define MATCH_AES64DSM 0x3e000033 +#define MASK_AES64DSM 0xfe00707f +#define MATCH_AES64DS 0x3a000033 +#define MASK_AES64DS 0xfe00707f +#define MATCH_SHA512SUM0 0x10401013 +#define MASK_SHA512SUM0 0xfff0707f +#define MATCH_SHA512SUM1 0x10501013 +#define MASK_SHA512SUM1 0xfff0707f +#define MATCH_SHA512SIG0 0x10601013 +#define MASK_SHA512SIG0 0xfff0707f +#define MATCH_SHA512SIG1 0x10701013 +#define MASK_SHA512SIG1 0xfff0707f #define MATCH_C_NOP 0x1 #define MASK_C_NOP 0xffff #define MATCH_C_ADDI16SP 0x6101 @@ -881,10 +1227,16 @@ #define MASK_CUSTOM3_RD_RS1 0x707f #define MATCH_CUSTOM3_RD_RS1_RS2 0x707b #define MASK_CUSTOM3_RD_RS1_RS2 0x707f +#define MATCH_VSETIVLI 0xc0007057 +#define MASK_VSETIVLI 0xc000707f #define MATCH_VSETVLI 0x7057 #define MASK_VSETVLI 0x8000707f #define MATCH_VSETVL 0x80007057 #define MASK_VSETVL 0xfe00707f +#define MATCH_VLM_V 0x2b00007 +#define MASK_VLM_V 0xfff0707f +#define MATCH_VSM_V 0x2b00027 +#define MASK_VSM_V 0xfff0707f #define MATCH_VLE8_V 0x7 #define MASK_VLE8_V 0x1df0707f #define MATCH_VLE16_V 0x5007 @@ -917,6 +1269,38 @@ #define MASK_VSE512_V 0x1df0707f #define MATCH_VSE1024_V 0x10007027 #define MASK_VSE1024_V 0x1df0707f +#define MATCH_VLUXEI8_V 0x4000007 +#define MASK_VLUXEI8_V 0x1c00707f +#define MATCH_VLUXEI16_V 0x4005007 +#define MASK_VLUXEI16_V 0x1c00707f +#define MATCH_VLUXEI32_V 0x4006007 +#define MASK_VLUXEI32_V 0x1c00707f +#define MATCH_VLUXEI64_V 0x4007007 +#define MASK_VLUXEI64_V 0x1c00707f +#define MATCH_VLUXEI128_V 0x14000007 +#define MASK_VLUXEI128_V 0x1c00707f +#define MATCH_VLUXEI256_V 0x14005007 +#define MASK_VLUXEI256_V 0x1c00707f +#define MATCH_VLUXEI512_V 0x14006007 +#define MASK_VLUXEI512_V 0x1c00707f +#define MATCH_VLUXEI1024_V 0x14007007 +#define MASK_VLUXEI1024_V 0x1c00707f +#define MATCH_VSUXEI8_V 0x4000027 +#define MASK_VSUXEI8_V 0x1c00707f +#define MATCH_VSUXEI16_V 0x4005027 +#define MASK_VSUXEI16_V 0x1c00707f +#define MATCH_VSUXEI32_V 0x4006027 +#define MASK_VSUXEI32_V 0x1c00707f +#define MATCH_VSUXEI64_V 0x4007027 +#define MASK_VSUXEI64_V 0x1c00707f +#define MATCH_VSUXEI128_V 0x14000027 +#define MASK_VSUXEI128_V 0x1c00707f +#define MATCH_VSUXEI256_V 0x14005027 +#define MASK_VSUXEI256_V 0x1c00707f +#define MATCH_VSUXEI512_V 0x14006027 +#define MASK_VSUXEI512_V 0x1c00707f +#define MATCH_VSUXEI1024_V 0x14007027 +#define MASK_VSUXEI1024_V 0x1c00707f #define MATCH_VLSE8_V 0x8000007 #define MASK_VLSE8_V 0x1c00707f #define MATCH_VLSE16_V 0x8005007 @@ -949,54 +1333,38 @@ #define MASK_VSSE512_V 0x1c00707f #define MATCH_VSSE1024_V 0x18007027 #define MASK_VSSE1024_V 0x1c00707f -#define MATCH_VLXEI8_V 0xc000007 -#define MASK_VLXEI8_V 0x1c00707f -#define MATCH_VLXEI16_V 0xc005007 -#define MASK_VLXEI16_V 0x1c00707f -#define MATCH_VLXEI32_V 0xc006007 -#define MASK_VLXEI32_V 0x1c00707f -#define MATCH_VLXEI64_V 0xc007007 -#define MASK_VLXEI64_V 0x1c00707f -#define MATCH_VLXEI128_V 0x1c000007 -#define MASK_VLXEI128_V 0x1c00707f -#define MATCH_VLXEI256_V 0x1c005007 -#define MASK_VLXEI256_V 0x1c00707f -#define MATCH_VLXEI512_V 0x1c006007 -#define MASK_VLXEI512_V 0x1c00707f -#define MATCH_VLXEI1024_V 0x1c007007 -#define MASK_VLXEI1024_V 0x1c00707f -#define MATCH_VSXEI8_V 0xc000027 -#define MASK_VSXEI8_V 0x1c00707f -#define MATCH_VSXEI16_V 0xc005027 -#define MASK_VSXEI16_V 0x1c00707f -#define MATCH_VSXEI32_V 0xc006027 -#define MASK_VSXEI32_V 0x1c00707f -#define MATCH_VSXEI64_V 0xc007027 -#define MASK_VSXEI64_V 0x1c00707f -#define MATCH_VSXEI128_V 0x1c000027 -#define MASK_VSXEI128_V 0x1c00707f -#define MATCH_VSXEI256_V 0x1c005027 -#define MASK_VSXEI256_V 0x1c00707f -#define MATCH_VSXEI512_V 0x1c006027 -#define MASK_VSXEI512_V 0x1c00707f -#define MATCH_VSXEI1024_V 0x1c007027 -#define MASK_VSXEI1024_V 0x1c00707f -#define MATCH_VSUXEI8_V 0x4000027 -#define MASK_VSUXEI8_V 0x1c00707f -#define MATCH_VSUXEI16_V 0x4005027 -#define MASK_VSUXEI16_V 0x1c00707f -#define MATCH_VSUXEI32_V 0x4006027 -#define MASK_VSUXEI32_V 0x1c00707f -#define MATCH_VSUXEI64_V 0x4007027 -#define MASK_VSUXEI64_V 0x1c00707f -#define MATCH_VSUXEI128_V 0x14000027 -#define MASK_VSUXEI128_V 0x1c00707f -#define MATCH_VSUXEI256_V 0x14005027 -#define MASK_VSUXEI256_V 0x1c00707f -#define MATCH_VSUXEI512_V 0x14006027 -#define MASK_VSUXEI512_V 0x1c00707f -#define MATCH_VSUXEI1024_V 0x14007027 -#define MASK_VSUXEI1024_V 0x1c00707f +#define MATCH_VLOXEI8_V 0xc000007 +#define MASK_VLOXEI8_V 0x1c00707f +#define MATCH_VLOXEI16_V 0xc005007 +#define MASK_VLOXEI16_V 0x1c00707f +#define MATCH_VLOXEI32_V 0xc006007 +#define MASK_VLOXEI32_V 0x1c00707f +#define MATCH_VLOXEI64_V 0xc007007 +#define MASK_VLOXEI64_V 0x1c00707f +#define MATCH_VLOXEI128_V 0x1c000007 +#define MASK_VLOXEI128_V 0x1c00707f +#define MATCH_VLOXEI256_V 0x1c005007 +#define MASK_VLOXEI256_V 0x1c00707f +#define MATCH_VLOXEI512_V 0x1c006007 +#define MASK_VLOXEI512_V 0x1c00707f +#define MATCH_VLOXEI1024_V 0x1c007007 +#define MASK_VLOXEI1024_V 0x1c00707f +#define MATCH_VSOXEI8_V 0xc000027 +#define MASK_VSOXEI8_V 0x1c00707f +#define MATCH_VSOXEI16_V 0xc005027 +#define MASK_VSOXEI16_V 0x1c00707f +#define MATCH_VSOXEI32_V 0xc006027 +#define MASK_VSOXEI32_V 0x1c00707f +#define MATCH_VSOXEI64_V 0xc007027 +#define MASK_VSOXEI64_V 0x1c00707f +#define MATCH_VSOXEI128_V 0x1c000027 +#define MASK_VSOXEI128_V 0x1c00707f +#define MATCH_VSOXEI256_V 0x1c005027 +#define MASK_VSOXEI256_V 0x1c00707f +#define MATCH_VSOXEI512_V 0x1c006027 +#define MASK_VSOXEI512_V 0x1c00707f +#define MATCH_VSOXEI1024_V 0x1c007027 +#define MASK_VSOXEI1024_V 0x1c00707f #define MATCH_VLE8FF_V 0x1000007 #define MASK_VLE8FF_V 0x1df0707f #define MATCH_VLE16FF_V 0x1005007 @@ -1133,8 +1501,8 @@ #define MASK_VFWNMSAC_VF 0xfc00707f #define MATCH_VFADD_VV 0x1057 #define MASK_VFADD_VV 0xfc00707f -#define MATCH_VFREDSUM_VS 0x4001057 -#define MASK_VFREDSUM_VS 0xfc00707f +#define MATCH_VFREDUSUM_VS 0x4001057 +#define MASK_VFREDUSUM_VS 0xfc00707f #define MATCH_VFSUB_VV 0x8001057 #define MASK_VFSUB_VV 0xfc00707f #define MATCH_VFREDOSUM_VS 0xc001057 @@ -1227,12 +1595,16 @@ #define MASK_VFNCVT_RTZ_X_F_W 0xfc0ff07f #define MATCH_VFSQRT_V 0x4c001057 #define MASK_VFSQRT_V 0xfc0ff07f +#define MATCH_VFRSQRT7_V 0x4c021057 +#define MASK_VFRSQRT7_V 0xfc0ff07f +#define MATCH_VFREC7_V 0x4c029057 +#define MASK_VFREC7_V 0xfc0ff07f #define MATCH_VFCLASS_V 0x4c081057 #define MASK_VFCLASS_V 0xfc0ff07f #define MATCH_VFWADD_VV 0xc0001057 #define MASK_VFWADD_VV 0xfc00707f -#define MATCH_VFWREDSUM_VS 0xc4001057 -#define MASK_VFWREDSUM_VS 0xfc00707f +#define MATCH_VFWREDUSUM_VS 0xc4001057 +#define MASK_VFWREDUSUM_VS 0xfc00707f #define MATCH_VFWSUB_VV 0xc8001057 #define MASK_VFWSUB_VV 0xfc00707f #define MATCH_VFWREDOSUM_VS 0xcc001057 @@ -1243,8 +1615,6 @@ #define MASK_VFWSUB_WV 0xfc00707f #define MATCH_VFWMUL_VV 0xe0001057 #define MASK_VFWMUL_VV 0xfc00707f -#define MATCH_VFDOT_VV 0xe4001057 -#define MASK_VFDOT_VV 0xfc00707f #define MATCH_VFWMACC_VV 0xf0001057 #define MASK_VFWMACC_VV 0xfc00707f #define MATCH_VFWNMACC_VV 0xf4001057 @@ -1282,11 +1652,15 @@ #define MATCH_VADC_VXM 0x40004057 #define MASK_VADC_VXM 0xfe00707f #define MATCH_VMADC_VXM 0x44004057 -#define MASK_VMADC_VXM 0xfc00707f +#define MASK_VMADC_VXM 0xfe00707f +#define MATCH_VMADC_VX 0x46004057 +#define MASK_VMADC_VX 0xfe00707f #define MATCH_VSBC_VXM 0x48004057 #define MASK_VSBC_VXM 0xfe00707f #define MATCH_VMSBC_VXM 0x4c004057 -#define MASK_VMSBC_VXM 0xfc00707f +#define MASK_VMSBC_VXM 0xfe00707f +#define MATCH_VMSBC_VX 0x4e004057 +#define MASK_VMSBC_VX 0xfe00707f #define MATCH_VMERGE_VXM 0x5c004057 #define MASK_VMERGE_VXM 0xfe00707f #define MATCH_VMV_V_X 0x5e004057 @@ -1335,14 +1709,6 @@ #define MASK_VNCLIPU_WX 0xfc00707f #define MATCH_VNCLIP_WX 0xbc004057 #define MASK_VNCLIP_WX 0xfc00707f -#define MATCH_VQMACCU_VX 0xf0004057 -#define MASK_VQMACCU_VX 0xfc00707f -#define MATCH_VQMACC_VX 0xf4004057 -#define MASK_VQMACC_VX 0xfc00707f -#define MATCH_VQMACCUS_VX 0xf8004057 -#define MASK_VQMACCUS_VX 0xfc00707f -#define MATCH_VQMACCSU_VX 0xfc004057 -#define MASK_VQMACCSU_VX 0xfc00707f #define MATCH_VADD_VV 0x57 #define MASK_VADD_VV 0xfc00707f #define MATCH_VSUB_VV 0x8000057 @@ -1368,11 +1734,15 @@ #define MATCH_VADC_VVM 0x40000057 #define MASK_VADC_VVM 0xfe00707f #define MATCH_VMADC_VVM 0x44000057 -#define MASK_VMADC_VVM 0xfc00707f +#define MASK_VMADC_VVM 0xfe00707f +#define MATCH_VMADC_VV 0x46000057 +#define MASK_VMADC_VV 0xfe00707f #define MATCH_VSBC_VVM 0x48000057 #define MASK_VSBC_VVM 0xfe00707f #define MATCH_VMSBC_VVM 0x4c000057 -#define MASK_VMSBC_VVM 0xfc00707f +#define MASK_VMSBC_VVM 0xfe00707f +#define MATCH_VMSBC_VV 0x4e000057 +#define MASK_VMSBC_VV 0xfe00707f #define MATCH_VMERGE_VVM 0x5c000057 #define MASK_VMERGE_VVM 0xfe00707f #define MATCH_VMV_V_V 0x5e000057 @@ -1421,16 +1791,6 @@ #define MASK_VWREDSUMU_VS 0xfc00707f #define MATCH_VWREDSUM_VS 0xc4000057 #define MASK_VWREDSUM_VS 0xfc00707f -#define MATCH_VDOTU_VV 0xe0000057 -#define MASK_VDOTU_VV 0xfc00707f -#define MATCH_VDOT_VV 0xe4000057 -#define MASK_VDOT_VV 0xfc00707f -#define MATCH_VQMACCU_VV 0xf0000057 -#define MASK_VQMACCU_VV 0xfc00707f -#define MATCH_VQMACC_VV 0xf4000057 -#define MASK_VQMACC_VV 0xfc00707f -#define MATCH_VQMACCSU_VV 0xfc000057 -#define MASK_VQMACCSU_VV 0xfc00707f #define MATCH_VADD_VI 0x3057 #define MASK_VADD_VI 0xfc00707f #define MATCH_VRSUB_VI 0xc003057 @@ -1450,7 +1810,9 @@ #define MATCH_VADC_VIM 0x40003057 #define MASK_VADC_VIM 0xfe00707f #define MATCH_VMADC_VIM 0x44003057 -#define MASK_VMADC_VIM 0xfc00707f +#define MASK_VMADC_VIM 0xfe00707f +#define MATCH_VMADC_VI 0x46003057 +#define MASK_VMADC_VI 0xfe00707f #define MATCH_VMERGE_VIM 0x5c003057 #define MASK_VMERGE_VIM 0xfe00707f #define MATCH_VMV_V_I 0x5e003057 @@ -1563,8 +1925,8 @@ #define MASK_VIOTA_M 0xfc0ff07f #define MATCH_VID_V 0x5008a057 #define MASK_VID_V 0xfdfff07f -#define MATCH_VPOPC_M 0x40082057 -#define MASK_VPOPC_M 0xfc0ff07f +#define MATCH_VCPOP_M 0x40082057 +#define MASK_VCPOP_M 0xfc0ff07f #define MATCH_VFIRST_M 0x4008a057 #define MASK_VFIRST_M 0xfc0ff07f #define MATCH_VDIVU_VV 0x80002057 @@ -1759,6 +2121,658 @@ #define MASK_VAMOMINUEI64_V 0xf800707f #define MATCH_VAMOMAXUEI64_V 0xe000702f #define MASK_VAMOMAXUEI64_V 0xf800707f +#define MATCH_ADD8 0x48000077 +#define MASK_ADD8 0xfe00707f +#define MATCH_ADD16 0x40000077 +#define MASK_ADD16 0xfe00707f +#define MATCH_ADD64 0xc0001077 +#define MASK_ADD64 0xfe00707f +#define MATCH_AVE 0xe0000077 +#define MASK_AVE 0xfe00707f +#define MATCH_BITREV 0xe6000077 +#define MASK_BITREV 0xfe00707f +#define MATCH_BITREVI 0xe8000077 +#define MASK_BITREVI 0xfc00707f +#define MATCH_BPICK 0x3077 +#define MASK_BPICK 0x600707f +#define MATCH_CLRS8 0xae000077 +#define MASK_CLRS8 0xfff0707f +#define MATCH_CLRS16 0xae800077 +#define MASK_CLRS16 0xfff0707f +#define MATCH_CLRS32 0xaf800077 +#define MASK_CLRS32 0xfff0707f +#define MATCH_CLO8 0xae300077 +#define MASK_CLO8 0xfff0707f +#define MATCH_CLO16 0xaeb00077 +#define MASK_CLO16 0xfff0707f +#define MATCH_CLO32 0xafb00077 +#define MASK_CLO32 0xfff0707f +#define MATCH_CLZ8 0xae100077 +#define MASK_CLZ8 0xfff0707f +#define MATCH_CLZ16 0xae900077 +#define MASK_CLZ16 0xfff0707f +#define MATCH_CLZ32 0xaf900077 +#define MASK_CLZ32 0xfff0707f +#define MATCH_CMPEQ8 0x4e000077 +#define MASK_CMPEQ8 0xfe00707f +#define MATCH_CMPEQ16 0x4c000077 +#define MASK_CMPEQ16 0xfe00707f +#define MATCH_CRAS16 0x44000077 +#define MASK_CRAS16 0xfe00707f +#define MATCH_CRSA16 0x46000077 +#define MASK_CRSA16 0xfe00707f +#define MATCH_INSB 0xac000077 +#define MASK_INSB 0xff80707f +#define MATCH_KABS8 0xad000077 +#define MASK_KABS8 0xfff0707f +#define MATCH_KABS16 0xad100077 +#define MASK_KABS16 0xfff0707f +#define MATCH_KABSW 0xad400077 +#define MASK_KABSW 0xfff0707f +#define MATCH_KADD8 0x18000077 +#define MASK_KADD8 0xfe00707f +#define MATCH_KADD16 0x10000077 +#define MASK_KADD16 0xfe00707f +#define MATCH_KADD64 0x90001077 +#define MASK_KADD64 0xfe00707f +#define MATCH_KADDH 0x4001077 +#define MASK_KADDH 0xfe00707f +#define MATCH_KADDW 0x1077 +#define MASK_KADDW 0xfe00707f +#define MATCH_KCRAS16 0x14000077 +#define MASK_KCRAS16 0xfe00707f +#define MATCH_KCRSA16 0x16000077 +#define MASK_KCRSA16 0xfe00707f +#define MATCH_KDMBB 0xa001077 +#define MASK_KDMBB 0xfe00707f +#define MATCH_KDMBT 0x1a001077 +#define MASK_KDMBT 0xfe00707f +#define MATCH_KDMTT 0x2a001077 +#define MASK_KDMTT 0xfe00707f +#define MATCH_KDMABB 0xd2001077 +#define MASK_KDMABB 0xfe00707f +#define MATCH_KDMABT 0xe2001077 +#define MASK_KDMABT 0xfe00707f +#define MATCH_KDMATT 0xf2001077 +#define MASK_KDMATT 0xfe00707f +#define MATCH_KHM8 0x8e000077 +#define MASK_KHM8 0xfe00707f +#define MATCH_KHMX8 0x9e000077 +#define MASK_KHMX8 0xfe00707f +#define MATCH_KHM16 0x86000077 +#define MASK_KHM16 0xfe00707f +#define MATCH_KHMX16 0x96000077 +#define MASK_KHMX16 0xfe00707f +#define MATCH_KHMBB 0xc001077 +#define MASK_KHMBB 0xfe00707f +#define MATCH_KHMBT 0x1c001077 +#define MASK_KHMBT 0xfe00707f +#define MATCH_KHMTT 0x2c001077 +#define MASK_KHMTT 0xfe00707f +#define MATCH_KMABB 0x5a001077 +#define MASK_KMABB 0xfe00707f +#define MATCH_KMABT 0x6a001077 +#define MASK_KMABT 0xfe00707f +#define MATCH_KMATT 0x7a001077 +#define MASK_KMATT 0xfe00707f +#define MATCH_KMADA 0x48001077 +#define MASK_KMADA 0xfe00707f +#define MATCH_KMAXDA 0x4a001077 +#define MASK_KMAXDA 0xfe00707f +#define MATCH_KMADS 0x5c001077 +#define MASK_KMADS 0xfe00707f +#define MATCH_KMADRS 0x6c001077 +#define MASK_KMADRS 0xfe00707f +#define MATCH_KMAXDS 0x7c001077 +#define MASK_KMAXDS 0xfe00707f +#define MATCH_KMAR64 0x94001077 +#define MASK_KMAR64 0xfe00707f +#define MATCH_KMDA 0x38001077 +#define MASK_KMDA 0xfe00707f +#define MATCH_KMXDA 0x3a001077 +#define MASK_KMXDA 0xfe00707f +#define MATCH_KMMAC 0x60001077 +#define MASK_KMMAC 0xfe00707f +#define MATCH_KMMAC_U 0x70001077 +#define MASK_KMMAC_U 0xfe00707f +#define MATCH_KMMAWB 0x46001077 +#define MASK_KMMAWB 0xfe00707f +#define MATCH_KMMAWB_U 0x56001077 +#define MASK_KMMAWB_U 0xfe00707f +#define MATCH_KMMAWB2 0xce001077 +#define MASK_KMMAWB2 0xfe00707f +#define MATCH_KMMAWB2_U 0xde001077 +#define MASK_KMMAWB2_U 0xfe00707f +#define MATCH_KMMAWT 0x66001077 +#define MASK_KMMAWT 0xfe00707f +#define MATCH_KMMAWT_U 0x76001077 +#define MASK_KMMAWT_U 0xfe00707f +#define MATCH_KMMAWT2 0xee001077 +#define MASK_KMMAWT2 0xfe00707f +#define MATCH_KMMAWT2_U 0xfe001077 +#define MASK_KMMAWT2_U 0xfe00707f +#define MATCH_KMMSB 0x42001077 +#define MASK_KMMSB 0xfe00707f +#define MATCH_KMMSB_U 0x52001077 +#define MASK_KMMSB_U 0xfe00707f +#define MATCH_KMMWB2 0x8e001077 +#define MASK_KMMWB2 0xfe00707f +#define MATCH_KMMWB2_U 0x9e001077 +#define MASK_KMMWB2_U 0xfe00707f +#define MATCH_KMMWT2 0xae001077 +#define MASK_KMMWT2 0xfe00707f +#define MATCH_KMMWT2_U 0xbe001077 +#define MASK_KMMWT2_U 0xfe00707f +#define MATCH_KMSDA 0x4c001077 +#define MASK_KMSDA 0xfe00707f +#define MATCH_KMSXDA 0x4e001077 +#define MASK_KMSXDA 0xfe00707f +#define MATCH_KMSR64 0x96001077 +#define MASK_KMSR64 0xfe00707f +#define MATCH_KSLLW 0x26001077 +#define MASK_KSLLW 0xfe00707f +#define MATCH_KSLLIW 0x36001077 +#define MASK_KSLLIW 0xfe00707f +#define MATCH_KSLL8 0x6c000077 +#define MASK_KSLL8 0xfe00707f +#define MATCH_KSLLI8 0x7c800077 +#define MASK_KSLLI8 0xff80707f +#define MATCH_KSLL16 0x64000077 +#define MASK_KSLL16 0xfe00707f +#define MATCH_KSLLI16 0x75000077 +#define MASK_KSLLI16 0xff00707f +#define MATCH_KSLRA8 0x5e000077 +#define MASK_KSLRA8 0xfe00707f +#define MATCH_KSLRA8_U 0x6e000077 +#define MASK_KSLRA8_U 0xfe00707f +#define MATCH_KSLRA16 0x56000077 +#define MASK_KSLRA16 0xfe00707f +#define MATCH_KSLRA16_U 0x66000077 +#define MASK_KSLRA16_U 0xfe00707f +#define MATCH_KSLRAW 0x6e001077 +#define MASK_KSLRAW 0xfe00707f +#define MATCH_KSLRAW_U 0x7e001077 +#define MASK_KSLRAW_U 0xfe00707f +#define MATCH_KSTAS16 0xc4002077 +#define MASK_KSTAS16 0xfe00707f +#define MATCH_KSTSA16 0xc6002077 +#define MASK_KSTSA16 0xfe00707f +#define MATCH_KSUB8 0x1a000077 +#define MASK_KSUB8 0xfe00707f +#define MATCH_KSUB16 0x12000077 +#define MASK_KSUB16 0xfe00707f +#define MATCH_KSUB64 0x92001077 +#define MASK_KSUB64 0xfe00707f +#define MATCH_KSUBH 0x6001077 +#define MASK_KSUBH 0xfe00707f +#define MATCH_KSUBW 0x2001077 +#define MASK_KSUBW 0xfe00707f +#define MATCH_KWMMUL 0x62001077 +#define MASK_KWMMUL 0xfe00707f +#define MATCH_KWMMUL_U 0x72001077 +#define MASK_KWMMUL_U 0xfe00707f +#define MATCH_MADDR32 0xc4001077 +#define MASK_MADDR32 0xfe00707f +#define MATCH_MAXW 0xf2000077 +#define MASK_MAXW 0xfe00707f +#define MATCH_MINW 0xf0000077 +#define MASK_MINW 0xfe00707f +#define MATCH_MSUBR32 0xc6001077 +#define MASK_MSUBR32 0xfe00707f +#define MATCH_MULR64 0xf0001077 +#define MASK_MULR64 0xfe00707f +#define MATCH_MULSR64 0xe0001077 +#define MASK_MULSR64 0xfe00707f +#define MATCH_PBSAD 0xfc000077 +#define MASK_PBSAD 0xfe00707f +#define MATCH_PBSADA 0xfe000077 +#define MASK_PBSADA 0xfe00707f +#define MATCH_PKBB16 0xe001077 +#define MASK_PKBB16 0xfe00707f +#define MATCH_PKBT16 0x1e001077 +#define MASK_PKBT16 0xfe00707f +#define MATCH_PKTT16 0x2e001077 +#define MASK_PKTT16 0xfe00707f +#define MATCH_PKTB16 0x3e001077 +#define MASK_PKTB16 0xfe00707f +#define MATCH_RADD8 0x8000077 +#define MASK_RADD8 0xfe00707f +#define MATCH_RADD16 0x77 +#define MASK_RADD16 0xfe00707f +#define MATCH_RADD64 0x80001077 +#define MASK_RADD64 0xfe00707f +#define MATCH_RADDW 0x20001077 +#define MASK_RADDW 0xfe00707f +#define MATCH_RCRAS16 0x4000077 +#define MASK_RCRAS16 0xfe00707f +#define MATCH_RCRSA16 0x6000077 +#define MASK_RCRSA16 0xfe00707f +#define MATCH_RSTAS16 0xb4002077 +#define MASK_RSTAS16 0xfe00707f +#define MATCH_RSTSA16 0xb6002077 +#define MASK_RSTSA16 0xfe00707f +#define MATCH_RSUB8 0xa000077 +#define MASK_RSUB8 0xfe00707f +#define MATCH_RSUB16 0x2000077 +#define MASK_RSUB16 0xfe00707f +#define MATCH_RSUB64 0x82001077 +#define MASK_RSUB64 0xfe00707f +#define MATCH_RSUBW 0x22001077 +#define MASK_RSUBW 0xfe00707f +#define MATCH_SCLIP8 0x8c000077 +#define MASK_SCLIP8 0xff80707f +#define MATCH_SCLIP16 0x84000077 +#define MASK_SCLIP16 0xff00707f +#define MATCH_SCLIP32 0xe4000077 +#define MASK_SCLIP32 0xfe00707f +#define MATCH_SCMPLE8 0x1e000077 +#define MASK_SCMPLE8 0xfe00707f +#define MATCH_SCMPLE16 0x1c000077 +#define MASK_SCMPLE16 0xfe00707f +#define MATCH_SCMPLT8 0xe000077 +#define MASK_SCMPLT8 0xfe00707f +#define MATCH_SCMPLT16 0xc000077 +#define MASK_SCMPLT16 0xfe00707f +#define MATCH_SLL8 0x5c000077 +#define MASK_SLL8 0xfe00707f +#define MATCH_SLLI8 0x7c000077 +#define MASK_SLLI8 0xff80707f +#define MATCH_SLL16 0x54000077 +#define MASK_SLL16 0xfe00707f +#define MATCH_SLLI16 0x74000077 +#define MASK_SLLI16 0xff00707f +#define MATCH_SMAL 0x5e001077 +#define MASK_SMAL 0xfe00707f +#define MATCH_SMALBB 0x88001077 +#define MASK_SMALBB 0xfe00707f +#define MATCH_SMALBT 0x98001077 +#define MASK_SMALBT 0xfe00707f +#define MATCH_SMALTT 0xa8001077 +#define MASK_SMALTT 0xfe00707f +#define MATCH_SMALDA 0x8c001077 +#define MASK_SMALDA 0xfe00707f +#define MATCH_SMALXDA 0x9c001077 +#define MASK_SMALXDA 0xfe00707f +#define MATCH_SMALDS 0x8a001077 +#define MASK_SMALDS 0xfe00707f +#define MATCH_SMALDRS 0x9a001077 +#define MASK_SMALDRS 0xfe00707f +#define MATCH_SMALXDS 0xaa001077 +#define MASK_SMALXDS 0xfe00707f +#define MATCH_SMAR64 0x84001077 +#define MASK_SMAR64 0xfe00707f +#define MATCH_SMAQA 0xc8000077 +#define MASK_SMAQA 0xfe00707f +#define MATCH_SMAQA_SU 0xca000077 +#define MASK_SMAQA_SU 0xfe00707f +#define MATCH_SMAX8 0x8a000077 +#define MASK_SMAX8 0xfe00707f +#define MATCH_SMAX16 0x82000077 +#define MASK_SMAX16 0xfe00707f +#define MATCH_SMBB16 0x8001077 +#define MASK_SMBB16 0xfe00707f +#define MATCH_SMBT16 0x18001077 +#define MASK_SMBT16 0xfe00707f +#define MATCH_SMTT16 0x28001077 +#define MASK_SMTT16 0xfe00707f +#define MATCH_SMDS 0x58001077 +#define MASK_SMDS 0xfe00707f +#define MATCH_SMDRS 0x68001077 +#define MASK_SMDRS 0xfe00707f +#define MATCH_SMXDS 0x78001077 +#define MASK_SMXDS 0xfe00707f +#define MATCH_SMIN8 0x88000077 +#define MASK_SMIN8 0xfe00707f +#define MATCH_SMIN16 0x80000077 +#define MASK_SMIN16 0xfe00707f +#define MATCH_SMMUL 0x40001077 +#define MASK_SMMUL 0xfe00707f +#define MATCH_SMMUL_U 0x50001077 +#define MASK_SMMUL_U 0xfe00707f +#define MATCH_SMMWB 0x44001077 +#define MASK_SMMWB 0xfe00707f +#define MATCH_SMMWB_U 0x54001077 +#define MASK_SMMWB_U 0xfe00707f +#define MATCH_SMMWT 0x64001077 +#define MASK_SMMWT 0xfe00707f +#define MATCH_SMMWT_U 0x74001077 +#define MASK_SMMWT_U 0xfe00707f +#define MATCH_SMSLDA 0xac001077 +#define MASK_SMSLDA 0xfe00707f +#define MATCH_SMSLXDA 0xbc001077 +#define MASK_SMSLXDA 0xfe00707f +#define MATCH_SMSR64 0x86001077 +#define MASK_SMSR64 0xfe00707f +#define MATCH_SMUL8 0xa8000077 +#define MASK_SMUL8 0xfe00707f +#define MATCH_SMULX8 0xaa000077 +#define MASK_SMULX8 0xfe00707f +#define MATCH_SMUL16 0xa0000077 +#define MASK_SMUL16 0xfe00707f +#define MATCH_SMULX16 0xa2000077 +#define MASK_SMULX16 0xfe00707f +#define MATCH_SRA_U 0x24001077 +#define MASK_SRA_U 0xfe00707f +#define MATCH_SRAI_U 0xd4001077 +#define MASK_SRAI_U 0xfc00707f +#define MATCH_SRA8 0x58000077 +#define MASK_SRA8 0xfe00707f +#define MATCH_SRA8_U 0x68000077 +#define MASK_SRA8_U 0xfe00707f +#define MATCH_SRAI8 0x78000077 +#define MASK_SRAI8 0xff80707f +#define MATCH_SRAI8_U 0x78800077 +#define MASK_SRAI8_U 0xff80707f +#define MATCH_SRA16 0x50000077 +#define MASK_SRA16 0xfe00707f +#define MATCH_SRA16_U 0x60000077 +#define MASK_SRA16_U 0xfe00707f +#define MATCH_SRAI16 0x70000077 +#define MASK_SRAI16 0xff00707f +#define MATCH_SRAI16_U 0x71000077 +#define MASK_SRAI16_U 0xff00707f +#define MATCH_SRL8 0x5a000077 +#define MASK_SRL8 0xfe00707f +#define MATCH_SRL8_U 0x6a000077 +#define MASK_SRL8_U 0xfe00707f +#define MATCH_SRLI8 0x7a000077 +#define MASK_SRLI8 0xff80707f +#define MATCH_SRLI8_U 0x7a800077 +#define MASK_SRLI8_U 0xff80707f +#define MATCH_SRL16 0x52000077 +#define MASK_SRL16 0xfe00707f +#define MATCH_SRL16_U 0x62000077 +#define MASK_SRL16_U 0xfe00707f +#define MATCH_SRLI16 0x72000077 +#define MASK_SRLI16 0xff00707f +#define MATCH_SRLI16_U 0x73000077 +#define MASK_SRLI16_U 0xff00707f +#define MATCH_STAS16 0xf4002077 +#define MASK_STAS16 0xfe00707f +#define MATCH_STSA16 0xf6002077 +#define MASK_STSA16 0xfe00707f +#define MATCH_SUB8 0x4a000077 +#define MASK_SUB8 0xfe00707f +#define MATCH_SUB16 0x42000077 +#define MASK_SUB16 0xfe00707f +#define MATCH_SUB64 0xc2001077 +#define MASK_SUB64 0xfe00707f +#define MATCH_SUNPKD810 0xac800077 +#define MASK_SUNPKD810 0xfff0707f +#define MATCH_SUNPKD820 0xac900077 +#define MASK_SUNPKD820 0xfff0707f +#define MATCH_SUNPKD830 0xaca00077 +#define MASK_SUNPKD830 0xfff0707f +#define MATCH_SUNPKD831 0xacb00077 +#define MASK_SUNPKD831 0xfff0707f +#define MATCH_SUNPKD832 0xad300077 +#define MASK_SUNPKD832 0xfff0707f +#define MATCH_SWAP8 0xad800077 +#define MASK_SWAP8 0xfff0707f +#define MATCH_UCLIP8 0x8d000077 +#define MASK_UCLIP8 0xff80707f +#define MATCH_UCLIP16 0x85000077 +#define MASK_UCLIP16 0xff00707f +#define MATCH_UCLIP32 0xf4000077 +#define MASK_UCLIP32 0xfe00707f +#define MATCH_UCMPLE8 0x3e000077 +#define MASK_UCMPLE8 0xfe00707f +#define MATCH_UCMPLE16 0x3c000077 +#define MASK_UCMPLE16 0xfe00707f +#define MATCH_UCMPLT8 0x2e000077 +#define MASK_UCMPLT8 0xfe00707f +#define MATCH_UCMPLT16 0x2c000077 +#define MASK_UCMPLT16 0xfe00707f +#define MATCH_UKADD8 0x38000077 +#define MASK_UKADD8 0xfe00707f +#define MATCH_UKADD16 0x30000077 +#define MASK_UKADD16 0xfe00707f +#define MATCH_UKADD64 0xb0001077 +#define MASK_UKADD64 0xfe00707f +#define MATCH_UKADDH 0x14001077 +#define MASK_UKADDH 0xfe00707f +#define MATCH_UKADDW 0x10001077 +#define MASK_UKADDW 0xfe00707f +#define MATCH_UKCRAS16 0x34000077 +#define MASK_UKCRAS16 0xfe00707f +#define MATCH_UKCRSA16 0x36000077 +#define MASK_UKCRSA16 0xfe00707f +#define MATCH_UKMAR64 0xb4001077 +#define MASK_UKMAR64 0xfe00707f +#define MATCH_UKMSR64 0xb6001077 +#define MASK_UKMSR64 0xfe00707f +#define MATCH_UKSTAS16 0xe4002077 +#define MASK_UKSTAS16 0xfe00707f +#define MATCH_UKSTSA16 0xe6002077 +#define MASK_UKSTSA16 0xfe00707f +#define MATCH_UKSUB8 0x3a000077 +#define MASK_UKSUB8 0xfe00707f +#define MATCH_UKSUB16 0x32000077 +#define MASK_UKSUB16 0xfe00707f +#define MATCH_UKSUB64 0xb2001077 +#define MASK_UKSUB64 0xfe00707f +#define MATCH_UKSUBH 0x16001077 +#define MASK_UKSUBH 0xfe00707f +#define MATCH_UKSUBW 0x12001077 +#define MASK_UKSUBW 0xfe00707f +#define MATCH_UMAR64 0xa4001077 +#define MASK_UMAR64 0xfe00707f +#define MATCH_UMAQA 0xcc000077 +#define MASK_UMAQA 0xfe00707f +#define MATCH_UMAX8 0x9a000077 +#define MASK_UMAX8 0xfe00707f +#define MATCH_UMAX16 0x92000077 +#define MASK_UMAX16 0xfe00707f +#define MATCH_UMIN8 0x98000077 +#define MASK_UMIN8 0xfe00707f +#define MATCH_UMIN16 0x90000077 +#define MASK_UMIN16 0xfe00707f +#define MATCH_UMSR64 0xa6001077 +#define MASK_UMSR64 0xfe00707f +#define MATCH_UMUL8 0xb8000077 +#define MASK_UMUL8 0xfe00707f +#define MATCH_UMULX8 0xba000077 +#define MASK_UMULX8 0xfe00707f +#define MATCH_UMUL16 0xb0000077 +#define MASK_UMUL16 0xfe00707f +#define MATCH_UMULX16 0xb2000077 +#define MASK_UMULX16 0xfe00707f +#define MATCH_URADD8 0x28000077 +#define MASK_URADD8 0xfe00707f +#define MATCH_URADD16 0x20000077 +#define MASK_URADD16 0xfe00707f +#define MATCH_URADD64 0xa0001077 +#define MASK_URADD64 0xfe00707f +#define MATCH_URADDW 0x30001077 +#define MASK_URADDW 0xfe00707f +#define MATCH_URCRAS16 0x24000077 +#define MASK_URCRAS16 0xfe00707f +#define MATCH_URCRSA16 0x26000077 +#define MASK_URCRSA16 0xfe00707f +#define MATCH_URSTAS16 0xd4002077 +#define MASK_URSTAS16 0xfe00707f +#define MATCH_URSTSA16 0xd6002077 +#define MASK_URSTSA16 0xfe00707f +#define MATCH_URSUB8 0x2a000077 +#define MASK_URSUB8 0xfe00707f +#define MATCH_URSUB16 0x22000077 +#define MASK_URSUB16 0xfe00707f +#define MATCH_URSUB64 0xa2001077 +#define MASK_URSUB64 0xfe00707f +#define MATCH_URSUBW 0x32001077 +#define MASK_URSUBW 0xfe00707f +#define MATCH_WEXTI 0xde000077 +#define MASK_WEXTI 0xfe00707f +#define MATCH_WEXT 0xce000077 +#define MASK_WEXT 0xfe00707f +#define MATCH_ZUNPKD810 0xacc00077 +#define MASK_ZUNPKD810 0xfff0707f +#define MATCH_ZUNPKD820 0xacd00077 +#define MASK_ZUNPKD820 0xfff0707f +#define MATCH_ZUNPKD830 0xace00077 +#define MASK_ZUNPKD830 0xfff0707f +#define MATCH_ZUNPKD831 0xacf00077 +#define MASK_ZUNPKD831 0xfff0707f +#define MATCH_ZUNPKD832 0xad700077 +#define MASK_ZUNPKD832 0xfff0707f +#define MATCH_ADD32 0x40002077 +#define MASK_ADD32 0xfe00707f +#define MATCH_CRAS32 0x44002077 +#define MASK_CRAS32 0xfe00707f +#define MATCH_CRSA32 0x46002077 +#define MASK_CRSA32 0xfe00707f +#define MATCH_KABS32 0xad200077 +#define MASK_KABS32 0xfff0707f +#define MATCH_KADD32 0x10002077 +#define MASK_KADD32 0xfe00707f +#define MATCH_KCRAS32 0x14002077 +#define MASK_KCRAS32 0xfe00707f +#define MATCH_KCRSA32 0x16002077 +#define MASK_KCRSA32 0xfe00707f +#define MATCH_KDMBB16 0xda001077 +#define MASK_KDMBB16 0xfe00707f +#define MATCH_KDMBT16 0xea001077 +#define MASK_KDMBT16 0xfe00707f +#define MATCH_KDMTT16 0xfa001077 +#define MASK_KDMTT16 0xfe00707f +#define MATCH_KDMABB16 0xd8001077 +#define MASK_KDMABB16 0xfe00707f +#define MATCH_KDMABT16 0xe8001077 +#define MASK_KDMABT16 0xfe00707f +#define MATCH_KDMATT16 0xf8001077 +#define MASK_KDMATT16 0xfe00707f +#define MATCH_KHMBB16 0xdc001077 +#define MASK_KHMBB16 0xfe00707f +#define MATCH_KHMBT16 0xec001077 +#define MASK_KHMBT16 0xfe00707f +#define MATCH_KHMTT16 0xfc001077 +#define MASK_KHMTT16 0xfe00707f +#define MATCH_KMABB32 0x5a002077 +#define MASK_KMABB32 0xfe00707f +#define MATCH_KMABT32 0x6a002077 +#define MASK_KMABT32 0xfe00707f +#define MATCH_KMATT32 0x7a002077 +#define MASK_KMATT32 0xfe00707f +#define MATCH_KMAXDA32 0x4a002077 +#define MASK_KMAXDA32 0xfe00707f +#define MATCH_KMDA32 0x38002077 +#define MASK_KMDA32 0xfe00707f +#define MATCH_KMXDA32 0x3a002077 +#define MASK_KMXDA32 0xfe00707f +#define MATCH_KMADS32 0x5c002077 +#define MASK_KMADS32 0xfe00707f +#define MATCH_KMADRS32 0x6c002077 +#define MASK_KMADRS32 0xfe00707f +#define MATCH_KMAXDS32 0x7c002077 +#define MASK_KMAXDS32 0xfe00707f +#define MATCH_KMSDA32 0x4c002077 +#define MASK_KMSDA32 0xfe00707f +#define MATCH_KMSXDA32 0x4e002077 +#define MASK_KMSXDA32 0xfe00707f +#define MATCH_KSLL32 0x64002077 +#define MASK_KSLL32 0xfe00707f +#define MATCH_KSLLI32 0x84002077 +#define MASK_KSLLI32 0xfe00707f +#define MATCH_KSLRA32 0x56002077 +#define MASK_KSLRA32 0xfe00707f +#define MATCH_KSLRA32_U 0x66002077 +#define MASK_KSLRA32_U 0xfe00707f +#define MATCH_KSTAS32 0xc0002077 +#define MASK_KSTAS32 0xfe00707f +#define MATCH_KSTSA32 0xc2002077 +#define MASK_KSTSA32 0xfe00707f +#define MATCH_KSUB32 0x12002077 +#define MASK_KSUB32 0xfe00707f +#define MATCH_PKBB32 0xe002077 +#define MASK_PKBB32 0xfe00707f +#define MATCH_PKBT32 0x1e002077 +#define MASK_PKBT32 0xfe00707f +#define MATCH_PKTT32 0x2e002077 +#define MASK_PKTT32 0xfe00707f +#define MATCH_PKTB32 0x3e002077 +#define MASK_PKTB32 0xfe00707f +#define MATCH_RADD32 0x2077 +#define MASK_RADD32 0xfe00707f +#define MATCH_RCRAS32 0x4002077 +#define MASK_RCRAS32 0xfe00707f +#define MATCH_RCRSA32 0x6002077 +#define MASK_RCRSA32 0xfe00707f +#define MATCH_RSTAS32 0xb0002077 +#define MASK_RSTAS32 0xfe00707f +#define MATCH_RSTSA32 0xb2002077 +#define MASK_RSTSA32 0xfe00707f +#define MATCH_RSUB32 0x2002077 +#define MASK_RSUB32 0xfe00707f +#define MATCH_SLL32 0x54002077 +#define MASK_SLL32 0xfe00707f +#define MATCH_SLLI32 0x74002077 +#define MASK_SLLI32 0xfe00707f +#define MATCH_SMAX32 0x92002077 +#define MASK_SMAX32 0xfe00707f +#define MATCH_SMBT32 0x18002077 +#define MASK_SMBT32 0xfe00707f +#define MATCH_SMTT32 0x28002077 +#define MASK_SMTT32 0xfe00707f +#define MATCH_SMDS32 0x58002077 +#define MASK_SMDS32 0xfe00707f +#define MATCH_SMDRS32 0x68002077 +#define MASK_SMDRS32 0xfe00707f +#define MATCH_SMXDS32 0x78002077 +#define MASK_SMXDS32 0xfe00707f +#define MATCH_SMIN32 0x90002077 +#define MASK_SMIN32 0xfe00707f +#define MATCH_SRA32 0x50002077 +#define MASK_SRA32 0xfe00707f +#define MATCH_SRA32_U 0x60002077 +#define MASK_SRA32_U 0xfe00707f +#define MATCH_SRAI32 0x70002077 +#define MASK_SRAI32 0xfe00707f +#define MATCH_SRAI32_U 0x80002077 +#define MASK_SRAI32_U 0xfe00707f +#define MATCH_SRAIW_U 0x34001077 +#define MASK_SRAIW_U 0xfe00707f +#define MATCH_SRL32 0x52002077 +#define MASK_SRL32 0xfe00707f +#define MATCH_SRL32_U 0x62002077 +#define MASK_SRL32_U 0xfe00707f +#define MATCH_SRLI32 0x72002077 +#define MASK_SRLI32 0xfe00707f +#define MATCH_SRLI32_U 0x82002077 +#define MASK_SRLI32_U 0xfe00707f +#define MATCH_STAS32 0xf0002077 +#define MASK_STAS32 0xfe00707f +#define MATCH_STSA32 0xf2002077 +#define MASK_STSA32 0xfe00707f +#define MATCH_SUB32 0x42002077 +#define MASK_SUB32 0xfe00707f +#define MATCH_UKADD32 0x30002077 +#define MASK_UKADD32 0xfe00707f +#define MATCH_UKCRAS32 0x34002077 +#define MASK_UKCRAS32 0xfe00707f +#define MATCH_UKCRSA32 0x36002077 +#define MASK_UKCRSA32 0xfe00707f +#define MATCH_UKSTAS32 0xe0002077 +#define MASK_UKSTAS32 0xfe00707f +#define MATCH_UKSTSA32 0xe2002077 +#define MASK_UKSTSA32 0xfe00707f +#define MATCH_UKSUB32 0x32002077 +#define MASK_UKSUB32 0xfe00707f +#define MATCH_UMAX32 0xa2002077 +#define MASK_UMAX32 0xfe00707f +#define MATCH_UMIN32 0xa0002077 +#define MASK_UMIN32 0xfe00707f +#define MATCH_URADD32 0x20002077 +#define MASK_URADD32 0xfe00707f +#define MATCH_URCRAS32 0x24002077 +#define MASK_URCRAS32 0xfe00707f +#define MATCH_URCRSA32 0x26002077 +#define MASK_URCRSA32 0xfe00707f +#define MATCH_URSTAS32 0xd0002077 +#define MASK_URSTAS32 0xfe00707f +#define MATCH_URSTSA32 0xd2002077 +#define MASK_URSTSA32 0xfe00707f +#define MATCH_URSUB32 0x22002077 +#define MASK_URSUB32 0xfe00707f #define MATCH_VMVNFR_V 0x9e003057 #define MASK_VMVNFR_V 0xfe00707f #define MATCH_VL1R_V 0x2800007 @@ -1769,21 +2783,24 @@ #define MASK_VL4R_V 0xfff0707f #define MATCH_VL8R_V 0x1e807007 #define MASK_VL8R_V 0xfff0707f +#define MATCH_VLE1_V 0x2b00007 +#define MASK_VLE1_V 0xfff0707f +#define MATCH_VSE1_V 0x2b00027 +#define MASK_VSE1_V 0xfff0707f +#define MATCH_VFREDSUM_VS 0x4001057 +#define MASK_VFREDSUM_VS 0xfc00707f +#define MATCH_VFWREDSUM_VS 0xc4001057 +#define MASK_VFWREDSUM_VS 0xfc00707f +#define MATCH_VPOPC_M 0x40082057 +#define MASK_VPOPC_M 0xfc0ff07f #define CSR_FFLAGS 0x1 #define CSR_FRM 0x2 #define CSR_FCSR 0x3 -#define CSR_USTATUS 0x0 -#define CSR_UIE 0x4 -#define CSR_UTVEC 0x5 #define CSR_VSTART 0x8 #define CSR_VXSAT 0x9 #define CSR_VXRM 0xa #define CSR_VCSR 0xf -#define CSR_USCRATCH 0x40 -#define CSR_UEPC 0x41 -#define CSR_UCAUSE 0x42 -#define CSR_UTVAL 0x43 -#define CSR_UIP 0x44 +#define CSR_SEED 0x15 #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 #define CSR_INSTRET 0xc02 @@ -1831,6 +2848,7 @@ #define CSR_STVAL 0x143 #define CSR_SIP 0x144 #define CSR_SATP 0x180 +#define CSR_SCONTEXT 0x5a8 #define CSR_VSSTATUS 0x200 #define CSR_VSIE 0x204 #define CSR_VSTVEC 0x205 @@ -1852,6 +2870,7 @@ #define CSR_HVIP 0x645 #define CSR_HTINST 0x64a #define CSR_HGATP 0x680 +#define CSR_HCONTEXT 0x6a8 #define CSR_HGEIP 0xe12 #define CSR_UTVT 0x7 #define CSR_UNXTI 0x45 @@ -1907,6 +2926,10 @@ #define CSR_TDATA1 0x7a1 #define CSR_TDATA2 0x7a2 #define CSR_TDATA3 0x7a3 +#define CSR_TINFO 0x7a4 +#define CSR_TCONTROL 0x7a5 +#define CSR_MCONTEXT 0x7a8 +#define CSR_MSCONTEXT 0x7aa #define CSR_DCSR 0x7b0 #define CSR_DPC 0x7b1 #define CSR_DSCRATCH0 0x7b2 @@ -2095,12 +3118,9 @@ DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) -DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) -DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) -DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) DECLARE_INSN(add, MATCH_ADD, MASK_ADD) @@ -2135,6 +3155,9 @@ DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) DECLARE_INSN(ld, MATCH_LD, MASK_LD) DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) @@ -2279,9 +3302,111 @@ DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q) DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q) DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L) DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU) +DECLARE_INSN(andn, MATCH_ANDN, MASK_ANDN) +DECLARE_INSN(orn, MATCH_ORN, MASK_ORN) +DECLARE_INSN(xnor, MATCH_XNOR, MASK_XNOR) +DECLARE_INSN(slo, MATCH_SLO, MASK_SLO) +DECLARE_INSN(sro, MATCH_SRO, MASK_SRO) +DECLARE_INSN(rol, MATCH_ROL, MASK_ROL) +DECLARE_INSN(ror, MATCH_ROR, MASK_ROR) +DECLARE_INSN(bclr, MATCH_BCLR, MASK_BCLR) +DECLARE_INSN(bset, MATCH_BSET, MASK_BSET) +DECLARE_INSN(binv, MATCH_BINV, MASK_BINV) +DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT) +DECLARE_INSN(gorc, MATCH_GORC, MASK_GORC) +DECLARE_INSN(grev, MATCH_GREV, MASK_GREV) +DECLARE_INSN(sloi, MATCH_SLOI, MASK_SLOI) +DECLARE_INSN(sroi, MATCH_SROI, MASK_SROI) +DECLARE_INSN(rori, MATCH_RORI, MASK_RORI) +DECLARE_INSN(bclri, MATCH_BCLRI, MASK_BCLRI) +DECLARE_INSN(bseti, MATCH_BSETI, MASK_BSETI) +DECLARE_INSN(binvi, MATCH_BINVI, MASK_BINVI) +DECLARE_INSN(bexti, MATCH_BEXTI, MASK_BEXTI) +DECLARE_INSN(gorci, MATCH_GORCI, MASK_GORCI) +DECLARE_INSN(grevi, MATCH_GREVI, MASK_GREVI) +DECLARE_INSN(cmix, MATCH_CMIX, MASK_CMIX) +DECLARE_INSN(cmov, MATCH_CMOV, MASK_CMOV) +DECLARE_INSN(fsl, MATCH_FSL, MASK_FSL) +DECLARE_INSN(fsr, MATCH_FSR, MASK_FSR) +DECLARE_INSN(fsri, MATCH_FSRI, MASK_FSRI) +DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ) +DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ) +DECLARE_INSN(cpop, MATCH_CPOP, MASK_CPOP) +DECLARE_INSN(sext_b, MATCH_SEXT_B, MASK_SEXT_B) +DECLARE_INSN(sext_h, MATCH_SEXT_H, MASK_SEXT_H) +DECLARE_INSN(crc32_b, MATCH_CRC32_B, MASK_CRC32_B) +DECLARE_INSN(crc32_h, MATCH_CRC32_H, MASK_CRC32_H) +DECLARE_INSN(crc32_w, MATCH_CRC32_W, MASK_CRC32_W) +DECLARE_INSN(crc32c_b, MATCH_CRC32C_B, MASK_CRC32C_B) +DECLARE_INSN(crc32c_h, MATCH_CRC32C_H, MASK_CRC32C_H) +DECLARE_INSN(crc32c_w, MATCH_CRC32C_W, MASK_CRC32C_W) +DECLARE_INSN(sh1add, MATCH_SH1ADD, MASK_SH1ADD) +DECLARE_INSN(sh2add, MATCH_SH2ADD, MASK_SH2ADD) +DECLARE_INSN(sh3add, MATCH_SH3ADD, MASK_SH3ADD) +DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL) +DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR) +DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH) +DECLARE_INSN(min, MATCH_MIN, MASK_MIN) +DECLARE_INSN(minu, MATCH_MINU, MASK_MINU) +DECLARE_INSN(max, MATCH_MAX, MASK_MAX) +DECLARE_INSN(maxu, MATCH_MAXU, MASK_MAXU) +DECLARE_INSN(shfl, MATCH_SHFL, MASK_SHFL) +DECLARE_INSN(unshfl, MATCH_UNSHFL, MASK_UNSHFL) +DECLARE_INSN(bcompress, MATCH_BCOMPRESS, MASK_BCOMPRESS) +DECLARE_INSN(bdecompress, MATCH_BDECOMPRESS, MASK_BDECOMPRESS) +DECLARE_INSN(pack, MATCH_PACK, MASK_PACK) +DECLARE_INSN(packu, MATCH_PACKU, MASK_PACKU) +DECLARE_INSN(packh, MATCH_PACKH, MASK_PACKH) +DECLARE_INSN(bfp, MATCH_BFP, MASK_BFP) +DECLARE_INSN(shfli, MATCH_SHFLI, MASK_SHFLI) +DECLARE_INSN(unshfli, MATCH_UNSHFLI, MASK_UNSHFLI) +DECLARE_INSN(xperm4, MATCH_XPERM4, MASK_XPERM4) +DECLARE_INSN(xperm8, MATCH_XPERM8, MASK_XPERM8) +DECLARE_INSN(xperm16, MATCH_XPERM16, MASK_XPERM16) +DECLARE_INSN(bmatflip, MATCH_BMATFLIP, MASK_BMATFLIP) +DECLARE_INSN(crc32_d, MATCH_CRC32_D, MASK_CRC32_D) +DECLARE_INSN(crc32c_d, MATCH_CRC32C_D, MASK_CRC32C_D) +DECLARE_INSN(bmator, MATCH_BMATOR, MASK_BMATOR) +DECLARE_INSN(bmatxor, MATCH_BMATXOR, MASK_BMATXOR) +DECLARE_INSN(slli_uw, MATCH_SLLI_UW, MASK_SLLI_UW) +DECLARE_INSN(add_uw, MATCH_ADD_UW, MASK_ADD_UW) +DECLARE_INSN(slow, MATCH_SLOW, MASK_SLOW) +DECLARE_INSN(srow, MATCH_SROW, MASK_SROW) +DECLARE_INSN(rolw, MATCH_ROLW, MASK_ROLW) +DECLARE_INSN(rorw, MATCH_RORW, MASK_RORW) +DECLARE_INSN(sbclrw, MATCH_SBCLRW, MASK_SBCLRW) +DECLARE_INSN(sbsetw, MATCH_SBSETW, MASK_SBSETW) +DECLARE_INSN(sbinvw, MATCH_SBINVW, MASK_SBINVW) +DECLARE_INSN(sbextw, MATCH_SBEXTW, MASK_SBEXTW) +DECLARE_INSN(gorcw, MATCH_GORCW, MASK_GORCW) +DECLARE_INSN(grevw, MATCH_GREVW, MASK_GREVW) +DECLARE_INSN(sloiw, MATCH_SLOIW, MASK_SLOIW) +DECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW) +DECLARE_INSN(roriw, MATCH_RORIW, MASK_RORIW) +DECLARE_INSN(sbclriw, MATCH_SBCLRIW, MASK_SBCLRIW) +DECLARE_INSN(sbsetiw, MATCH_SBSETIW, MASK_SBSETIW) +DECLARE_INSN(sbinviw, MATCH_SBINVIW, MASK_SBINVIW) +DECLARE_INSN(gorciw, MATCH_GORCIW, MASK_GORCIW) +DECLARE_INSN(greviw, MATCH_GREVIW, MASK_GREVIW) +DECLARE_INSN(fslw, MATCH_FSLW, MASK_FSLW) +DECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW) +DECLARE_INSN(fsriw, MATCH_FSRIW, MASK_FSRIW) +DECLARE_INSN(clzw, MATCH_CLZW, MASK_CLZW) +DECLARE_INSN(ctzw, MATCH_CTZW, MASK_CTZW) +DECLARE_INSN(cpopw, MATCH_CPOPW, MASK_CPOPW) +DECLARE_INSN(sh1add_uw, MATCH_SH1ADD_UW, MASK_SH1ADD_UW) +DECLARE_INSN(sh2add_uw, MATCH_SH2ADD_UW, MASK_SH2ADD_UW) +DECLARE_INSN(sh3add_uw, MATCH_SH3ADD_UW, MASK_SH3ADD_UW) +DECLARE_INSN(shflw, MATCH_SHFLW, MASK_SHFLW) +DECLARE_INSN(unshflw, MATCH_UNSHFLW, MASK_UNSHFLW) +DECLARE_INSN(bcompressw, MATCH_BCOMPRESSW, MASK_BCOMPRESSW) +DECLARE_INSN(bdecompressw, MATCH_BDECOMPRESSW, MASK_BDECOMPRESSW) +DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW) +DECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW) +DECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW) +DECLARE_INSN(xperm32, MATCH_XPERM32, MASK_XPERM32) DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) -DECLARE_INSN(uret, MATCH_URET, MASK_URET) DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) @@ -2293,6 +3418,76 @@ DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA) +DECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL) +DECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR) +DECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA) +DECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA) +DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H) +DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H) +DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H) +DECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H) +DECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H) +DECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H) +DECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H) +DECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H) +DECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H) +DECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S) +DECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H) +DECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H) +DECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H) +DECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H) +DECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H) +DECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H) +DECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H) +DECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H) +DECLARE_INSN(fclass_h, MATCH_FCLASS_H, MASK_FCLASS_H) +DECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W) +DECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU) +DECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X) +DECLARE_INSN(flh, MATCH_FLH, MASK_FLH) +DECLARE_INSN(fsh, MATCH_FSH, MASK_FSH) +DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H) +DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H) +DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H) +DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H) +DECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D) +DECLARE_INSN(fcvt_d_h, MATCH_FCVT_D_H, MASK_FCVT_D_H) +DECLARE_INSN(fcvt_h_q, MATCH_FCVT_H_Q, MASK_FCVT_H_Q) +DECLARE_INSN(fcvt_q_h, MATCH_FCVT_Q_H, MASK_FCVT_Q_H) +DECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H) +DECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H) +DECLARE_INSN(fcvt_h_l, MATCH_FCVT_H_L, MASK_FCVT_H_L) +DECLARE_INSN(fcvt_h_lu, MATCH_FCVT_H_LU, MASK_FCVT_H_LU) +DECLARE_INSN(sm4ed, MATCH_SM4ED, MASK_SM4ED) +DECLARE_INSN(sm4ks, MATCH_SM4KS, MASK_SM4KS) +DECLARE_INSN(sm3p0, MATCH_SM3P0, MASK_SM3P0) +DECLARE_INSN(sm3p1, MATCH_SM3P1, MASK_SM3P1) +DECLARE_INSN(sha256sum0, MATCH_SHA256SUM0, MASK_SHA256SUM0) +DECLARE_INSN(sha256sum1, MATCH_SHA256SUM1, MASK_SHA256SUM1) +DECLARE_INSN(sha256sig0, MATCH_SHA256SIG0, MASK_SHA256SIG0) +DECLARE_INSN(sha256sig1, MATCH_SHA256SIG1, MASK_SHA256SIG1) +DECLARE_INSN(aes32esmi, MATCH_AES32ESMI, MASK_AES32ESMI) +DECLARE_INSN(aes32esi, MATCH_AES32ESI, MASK_AES32ESI) +DECLARE_INSN(aes32dsmi, MATCH_AES32DSMI, MASK_AES32DSMI) +DECLARE_INSN(aes32dsi, MATCH_AES32DSI, MASK_AES32DSI) +DECLARE_INSN(sha512sum0r, MATCH_SHA512SUM0R, MASK_SHA512SUM0R) +DECLARE_INSN(sha512sum1r, MATCH_SHA512SUM1R, MASK_SHA512SUM1R) +DECLARE_INSN(sha512sig0l, MATCH_SHA512SIG0L, MASK_SHA512SIG0L) +DECLARE_INSN(sha512sig0h, MATCH_SHA512SIG0H, MASK_SHA512SIG0H) +DECLARE_INSN(sha512sig1l, MATCH_SHA512SIG1L, MASK_SHA512SIG1L) +DECLARE_INSN(sha512sig1h, MATCH_SHA512SIG1H, MASK_SHA512SIG1H) +DECLARE_INSN(aes64ks1i, MATCH_AES64KS1I, MASK_AES64KS1I) +DECLARE_INSN(aes64im, MATCH_AES64IM, MASK_AES64IM) +DECLARE_INSN(aes64ks2, MATCH_AES64KS2, MASK_AES64KS2) +DECLARE_INSN(aes64esm, MATCH_AES64ESM, MASK_AES64ESM) +DECLARE_INSN(aes64es, MATCH_AES64ES, MASK_AES64ES) +DECLARE_INSN(aes64dsm, MATCH_AES64DSM, MASK_AES64DSM) +DECLARE_INSN(aes64ds, MATCH_AES64DS, MASK_AES64DS) +DECLARE_INSN(sha512sum0, MATCH_SHA512SUM0, MASK_SHA512SUM0) +DECLARE_INSN(sha512sum1, MATCH_SHA512SUM1, MASK_SHA512SUM1) +DECLARE_INSN(sha512sig0, MATCH_SHA512SIG0, MASK_SHA512SIG0) +DECLARE_INSN(sha512sig1, MATCH_SHA512SIG1, MASK_SHA512SIG1) DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) @@ -2362,8 +3557,11 @@ DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) +DECLARE_INSN(vsetivli, MATCH_VSETIVLI, MASK_VSETIVLI) DECLARE_INSN(vsetvli, MATCH_VSETVLI, MASK_VSETVLI) DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL) +DECLARE_INSN(vlm_v, MATCH_VLM_V, MASK_VLM_V) +DECLARE_INSN(vsm_v, MATCH_VSM_V, MASK_VSM_V) DECLARE_INSN(vle8_v, MATCH_VLE8_V, MASK_VLE8_V) DECLARE_INSN(vle16_v, MATCH_VLE16_V, MASK_VLE16_V) DECLARE_INSN(vle32_v, MATCH_VLE32_V, MASK_VLE32_V) @@ -2380,6 +3578,22 @@ DECLARE_INSN(vse128_v, MATCH_VSE128_V, MASK_VSE128_V) DECLARE_INSN(vse256_v, MATCH_VSE256_V, MASK_VSE256_V) DECLARE_INSN(vse512_v, MATCH_VSE512_V, MASK_VSE512_V) DECLARE_INSN(vse1024_v, MATCH_VSE1024_V, MASK_VSE1024_V) +DECLARE_INSN(vluxei8_v, MATCH_VLUXEI8_V, MASK_VLUXEI8_V) +DECLARE_INSN(vluxei16_v, MATCH_VLUXEI16_V, MASK_VLUXEI16_V) +DECLARE_INSN(vluxei32_v, MATCH_VLUXEI32_V, MASK_VLUXEI32_V) +DECLARE_INSN(vluxei64_v, MATCH_VLUXEI64_V, MASK_VLUXEI64_V) +DECLARE_INSN(vluxei128_v, MATCH_VLUXEI128_V, MASK_VLUXEI128_V) +DECLARE_INSN(vluxei256_v, MATCH_VLUXEI256_V, MASK_VLUXEI256_V) +DECLARE_INSN(vluxei512_v, MATCH_VLUXEI512_V, MASK_VLUXEI512_V) +DECLARE_INSN(vluxei1024_v, MATCH_VLUXEI1024_V, MASK_VLUXEI1024_V) +DECLARE_INSN(vsuxei8_v, MATCH_VSUXEI8_V, MASK_VSUXEI8_V) +DECLARE_INSN(vsuxei16_v, MATCH_VSUXEI16_V, MASK_VSUXEI16_V) +DECLARE_INSN(vsuxei32_v, MATCH_VSUXEI32_V, MASK_VSUXEI32_V) +DECLARE_INSN(vsuxei64_v, MATCH_VSUXEI64_V, MASK_VSUXEI64_V) +DECLARE_INSN(vsuxei128_v, MATCH_VSUXEI128_V, MASK_VSUXEI128_V) +DECLARE_INSN(vsuxei256_v, MATCH_VSUXEI256_V, MASK_VSUXEI256_V) +DECLARE_INSN(vsuxei512_v, MATCH_VSUXEI512_V, MASK_VSUXEI512_V) +DECLARE_INSN(vsuxei1024_v, MATCH_VSUXEI1024_V, MASK_VSUXEI1024_V) DECLARE_INSN(vlse8_v, MATCH_VLSE8_V, MASK_VLSE8_V) DECLARE_INSN(vlse16_v, MATCH_VLSE16_V, MASK_VLSE16_V) DECLARE_INSN(vlse32_v, MATCH_VLSE32_V, MASK_VLSE32_V) @@ -2396,30 +3610,22 @@ DECLARE_INSN(vsse128_v, MATCH_VSSE128_V, MASK_VSSE128_V) DECLARE_INSN(vsse256_v, MATCH_VSSE256_V, MASK_VSSE256_V) DECLARE_INSN(vsse512_v, MATCH_VSSE512_V, MASK_VSSE512_V) DECLARE_INSN(vsse1024_v, MATCH_VSSE1024_V, MASK_VSSE1024_V) -DECLARE_INSN(vlxei8_v, MATCH_VLXEI8_V, MASK_VLXEI8_V) -DECLARE_INSN(vlxei16_v, MATCH_VLXEI16_V, MASK_VLXEI16_V) -DECLARE_INSN(vlxei32_v, MATCH_VLXEI32_V, MASK_VLXEI32_V) -DECLARE_INSN(vlxei64_v, MATCH_VLXEI64_V, MASK_VLXEI64_V) -DECLARE_INSN(vlxei128_v, MATCH_VLXEI128_V, MASK_VLXEI128_V) -DECLARE_INSN(vlxei256_v, MATCH_VLXEI256_V, MASK_VLXEI256_V) -DECLARE_INSN(vlxei512_v, MATCH_VLXEI512_V, MASK_VLXEI512_V) -DECLARE_INSN(vlxei1024_v, MATCH_VLXEI1024_V, MASK_VLXEI1024_V) -DECLARE_INSN(vsxei8_v, MATCH_VSXEI8_V, MASK_VSXEI8_V) -DECLARE_INSN(vsxei16_v, MATCH_VSXEI16_V, MASK_VSXEI16_V) -DECLARE_INSN(vsxei32_v, MATCH_VSXEI32_V, MASK_VSXEI32_V) -DECLARE_INSN(vsxei64_v, MATCH_VSXEI64_V, MASK_VSXEI64_V) -DECLARE_INSN(vsxei128_v, MATCH_VSXEI128_V, MASK_VSXEI128_V) -DECLARE_INSN(vsxei256_v, MATCH_VSXEI256_V, MASK_VSXEI256_V) -DECLARE_INSN(vsxei512_v, MATCH_VSXEI512_V, MASK_VSXEI512_V) -DECLARE_INSN(vsxei1024_v, MATCH_VSXEI1024_V, MASK_VSXEI1024_V) -DECLARE_INSN(vsuxei8_v, MATCH_VSUXEI8_V, MASK_VSUXEI8_V) -DECLARE_INSN(vsuxei16_v, MATCH_VSUXEI16_V, MASK_VSUXEI16_V) -DECLARE_INSN(vsuxei32_v, MATCH_VSUXEI32_V, MASK_VSUXEI32_V) -DECLARE_INSN(vsuxei64_v, MATCH_VSUXEI64_V, MASK_VSUXEI64_V) -DECLARE_INSN(vsuxei128_v, MATCH_VSUXEI128_V, MASK_VSUXEI128_V) -DECLARE_INSN(vsuxei256_v, MATCH_VSUXEI256_V, MASK_VSUXEI256_V) -DECLARE_INSN(vsuxei512_v, MATCH_VSUXEI512_V, MASK_VSUXEI512_V) -DECLARE_INSN(vsuxei1024_v, MATCH_VSUXEI1024_V, MASK_VSUXEI1024_V) +DECLARE_INSN(vloxei8_v, MATCH_VLOXEI8_V, MASK_VLOXEI8_V) +DECLARE_INSN(vloxei16_v, MATCH_VLOXEI16_V, MASK_VLOXEI16_V) +DECLARE_INSN(vloxei32_v, MATCH_VLOXEI32_V, MASK_VLOXEI32_V) +DECLARE_INSN(vloxei64_v, MATCH_VLOXEI64_V, MASK_VLOXEI64_V) +DECLARE_INSN(vloxei128_v, MATCH_VLOXEI128_V, MASK_VLOXEI128_V) +DECLARE_INSN(vloxei256_v, MATCH_VLOXEI256_V, MASK_VLOXEI256_V) +DECLARE_INSN(vloxei512_v, MATCH_VLOXEI512_V, MASK_VLOXEI512_V) +DECLARE_INSN(vloxei1024_v, MATCH_VLOXEI1024_V, MASK_VLOXEI1024_V) +DECLARE_INSN(vsoxei8_v, MATCH_VSOXEI8_V, MASK_VSOXEI8_V) +DECLARE_INSN(vsoxei16_v, MATCH_VSOXEI16_V, MASK_VSOXEI16_V) +DECLARE_INSN(vsoxei32_v, MATCH_VSOXEI32_V, MASK_VSOXEI32_V) +DECLARE_INSN(vsoxei64_v, MATCH_VSOXEI64_V, MASK_VSOXEI64_V) +DECLARE_INSN(vsoxei128_v, MATCH_VSOXEI128_V, MASK_VSOXEI128_V) +DECLARE_INSN(vsoxei256_v, MATCH_VSOXEI256_V, MASK_VSOXEI256_V) +DECLARE_INSN(vsoxei512_v, MATCH_VSOXEI512_V, MASK_VSOXEI512_V) +DECLARE_INSN(vsoxei1024_v, MATCH_VSOXEI1024_V, MASK_VSOXEI1024_V) DECLARE_INSN(vle8ff_v, MATCH_VLE8FF_V, MASK_VLE8FF_V) DECLARE_INSN(vle16ff_v, MATCH_VLE16FF_V, MASK_VLE16FF_V) DECLARE_INSN(vle32ff_v, MATCH_VLE32FF_V, MASK_VLE32FF_V) @@ -2488,7 +3694,7 @@ DECLARE_INSN(vfwnmacc_vf, MATCH_VFWNMACC_VF, MASK_VFWNMACC_VF) DECLARE_INSN(vfwmsac_vf, MATCH_VFWMSAC_VF, MASK_VFWMSAC_VF) DECLARE_INSN(vfwnmsac_vf, MATCH_VFWNMSAC_VF, MASK_VFWNMSAC_VF) DECLARE_INSN(vfadd_vv, MATCH_VFADD_VV, MASK_VFADD_VV) -DECLARE_INSN(vfredsum_vs, MATCH_VFREDSUM_VS, MASK_VFREDSUM_VS) +DECLARE_INSN(vfredusum_vs, MATCH_VFREDUSUM_VS, MASK_VFREDUSUM_VS) DECLARE_INSN(vfsub_vv, MATCH_VFSUB_VV, MASK_VFSUB_VV) DECLARE_INSN(vfredosum_vs, MATCH_VFREDOSUM_VS, MASK_VFREDOSUM_VS) DECLARE_INSN(vfmin_vv, MATCH_VFMIN_VV, MASK_VFMIN_VV) @@ -2535,15 +3741,16 @@ DECLARE_INSN(vfncvt_rod_f_f_w, MATCH_VFNCVT_ROD_F_F_W, MASK_VFNCVT_ROD_F_F_W) DECLARE_INSN(vfncvt_rtz_xu_f_w, MATCH_VFNCVT_RTZ_XU_F_W, MASK_VFNCVT_RTZ_XU_F_W) DECLARE_INSN(vfncvt_rtz_x_f_w, MATCH_VFNCVT_RTZ_X_F_W, MASK_VFNCVT_RTZ_X_F_W) DECLARE_INSN(vfsqrt_v, MATCH_VFSQRT_V, MASK_VFSQRT_V) +DECLARE_INSN(vfrsqrt7_v, MATCH_VFRSQRT7_V, MASK_VFRSQRT7_V) +DECLARE_INSN(vfrec7_v, MATCH_VFREC7_V, MASK_VFREC7_V) DECLARE_INSN(vfclass_v, MATCH_VFCLASS_V, MASK_VFCLASS_V) DECLARE_INSN(vfwadd_vv, MATCH_VFWADD_VV, MASK_VFWADD_VV) -DECLARE_INSN(vfwredsum_vs, MATCH_VFWREDSUM_VS, MASK_VFWREDSUM_VS) +DECLARE_INSN(vfwredusum_vs, MATCH_VFWREDUSUM_VS, MASK_VFWREDUSUM_VS) DECLARE_INSN(vfwsub_vv, MATCH_VFWSUB_VV, MASK_VFWSUB_VV) DECLARE_INSN(vfwredosum_vs, MATCH_VFWREDOSUM_VS, MASK_VFWREDOSUM_VS) DECLARE_INSN(vfwadd_wv, MATCH_VFWADD_WV, MASK_VFWADD_WV) DECLARE_INSN(vfwsub_wv, MATCH_VFWSUB_WV, MASK_VFWSUB_WV) DECLARE_INSN(vfwmul_vv, MATCH_VFWMUL_VV, MASK_VFWMUL_VV) -DECLARE_INSN(vfdot_vv, MATCH_VFDOT_VV, MASK_VFDOT_VV) DECLARE_INSN(vfwmacc_vv, MATCH_VFWMACC_VV, MASK_VFWMACC_VV) DECLARE_INSN(vfwnmacc_vv, MATCH_VFWNMACC_VV, MASK_VFWNMACC_VV) DECLARE_INSN(vfwmsac_vv, MATCH_VFWMSAC_VV, MASK_VFWMSAC_VV) @@ -2563,8 +3770,10 @@ DECLARE_INSN(vslideup_vx, MATCH_VSLIDEUP_VX, MASK_VSLIDEUP_VX) DECLARE_INSN(vslidedown_vx, MATCH_VSLIDEDOWN_VX, MASK_VSLIDEDOWN_VX) DECLARE_INSN(vadc_vxm, MATCH_VADC_VXM, MASK_VADC_VXM) DECLARE_INSN(vmadc_vxm, MATCH_VMADC_VXM, MASK_VMADC_VXM) +DECLARE_INSN(vmadc_vx, MATCH_VMADC_VX, MASK_VMADC_VX) DECLARE_INSN(vsbc_vxm, MATCH_VSBC_VXM, MASK_VSBC_VXM) DECLARE_INSN(vmsbc_vxm, MATCH_VMSBC_VXM, MASK_VMSBC_VXM) +DECLARE_INSN(vmsbc_vx, MATCH_VMSBC_VX, MASK_VMSBC_VX) DECLARE_INSN(vmerge_vxm, MATCH_VMERGE_VXM, MASK_VMERGE_VXM) DECLARE_INSN(vmv_v_x, MATCH_VMV_V_X, MASK_VMV_V_X) DECLARE_INSN(vmseq_vx, MATCH_VMSEQ_VX, MASK_VMSEQ_VX) @@ -2589,10 +3798,6 @@ DECLARE_INSN(vnsrl_wx, MATCH_VNSRL_WX, MASK_VNSRL_WX) DECLARE_INSN(vnsra_wx, MATCH_VNSRA_WX, MASK_VNSRA_WX) DECLARE_INSN(vnclipu_wx, MATCH_VNCLIPU_WX, MASK_VNCLIPU_WX) DECLARE_INSN(vnclip_wx, MATCH_VNCLIP_WX, MASK_VNCLIP_WX) -DECLARE_INSN(vqmaccu_vx, MATCH_VQMACCU_VX, MASK_VQMACCU_VX) -DECLARE_INSN(vqmacc_vx, MATCH_VQMACC_VX, MASK_VQMACC_VX) -DECLARE_INSN(vqmaccus_vx, MATCH_VQMACCUS_VX, MASK_VQMACCUS_VX) -DECLARE_INSN(vqmaccsu_vx, MATCH_VQMACCSU_VX, MASK_VQMACCSU_VX) DECLARE_INSN(vadd_vv, MATCH_VADD_VV, MASK_VADD_VV) DECLARE_INSN(vsub_vv, MATCH_VSUB_VV, MASK_VSUB_VV) DECLARE_INSN(vminu_vv, MATCH_VMINU_VV, MASK_VMINU_VV) @@ -2606,8 +3811,10 @@ DECLARE_INSN(vrgather_vv, MATCH_VRGATHER_VV, MASK_VRGATHER_VV) DECLARE_INSN(vrgatherei16_vv, MATCH_VRGATHEREI16_VV, MASK_VRGATHEREI16_VV) DECLARE_INSN(vadc_vvm, MATCH_VADC_VVM, MASK_VADC_VVM) DECLARE_INSN(vmadc_vvm, MATCH_VMADC_VVM, MASK_VMADC_VVM) +DECLARE_INSN(vmadc_vv, MATCH_VMADC_VV, MASK_VMADC_VV) DECLARE_INSN(vsbc_vvm, MATCH_VSBC_VVM, MASK_VSBC_VVM) DECLARE_INSN(vmsbc_vvm, MATCH_VMSBC_VVM, MASK_VMSBC_VVM) +DECLARE_INSN(vmsbc_vv, MATCH_VMSBC_VV, MASK_VMSBC_VV) DECLARE_INSN(vmerge_vvm, MATCH_VMERGE_VVM, MASK_VMERGE_VVM) DECLARE_INSN(vmv_v_v, MATCH_VMV_V_V, MASK_VMV_V_V) DECLARE_INSN(vmseq_vv, MATCH_VMSEQ_VV, MASK_VMSEQ_VV) @@ -2632,11 +3839,6 @@ DECLARE_INSN(vnclipu_wv, MATCH_VNCLIPU_WV, MASK_VNCLIPU_WV) DECLARE_INSN(vnclip_wv, MATCH_VNCLIP_WV, MASK_VNCLIP_WV) DECLARE_INSN(vwredsumu_vs, MATCH_VWREDSUMU_VS, MASK_VWREDSUMU_VS) DECLARE_INSN(vwredsum_vs, MATCH_VWREDSUM_VS, MASK_VWREDSUM_VS) -DECLARE_INSN(vdotu_vv, MATCH_VDOTU_VV, MASK_VDOTU_VV) -DECLARE_INSN(vdot_vv, MATCH_VDOT_VV, MASK_VDOT_VV) -DECLARE_INSN(vqmaccu_vv, MATCH_VQMACCU_VV, MASK_VQMACCU_VV) -DECLARE_INSN(vqmacc_vv, MATCH_VQMACC_VV, MASK_VQMACC_VV) -DECLARE_INSN(vqmaccsu_vv, MATCH_VQMACCSU_VV, MASK_VQMACCSU_VV) DECLARE_INSN(vadd_vi, MATCH_VADD_VI, MASK_VADD_VI) DECLARE_INSN(vrsub_vi, MATCH_VRSUB_VI, MASK_VRSUB_VI) DECLARE_INSN(vand_vi, MATCH_VAND_VI, MASK_VAND_VI) @@ -2647,6 +3849,7 @@ DECLARE_INSN(vslideup_vi, MATCH_VSLIDEUP_VI, MASK_VSLIDEUP_VI) DECLARE_INSN(vslidedown_vi, MATCH_VSLIDEDOWN_VI, MASK_VSLIDEDOWN_VI) DECLARE_INSN(vadc_vim, MATCH_VADC_VIM, MASK_VADC_VIM) DECLARE_INSN(vmadc_vim, MATCH_VMADC_VIM, MASK_VMADC_VIM) +DECLARE_INSN(vmadc_vi, MATCH_VMADC_VI, MASK_VMADC_VI) DECLARE_INSN(vmerge_vim, MATCH_VMERGE_VIM, MASK_VMERGE_VIM) DECLARE_INSN(vmv_v_i, MATCH_VMV_V_I, MASK_VMV_V_I) DECLARE_INSN(vmseq_vi, MATCH_VMSEQ_VI, MASK_VMSEQ_VI) @@ -2703,7 +3906,7 @@ DECLARE_INSN(vmsof_m, MATCH_VMSOF_M, MASK_VMSOF_M) DECLARE_INSN(vmsif_m, MATCH_VMSIF_M, MASK_VMSIF_M) DECLARE_INSN(viota_m, MATCH_VIOTA_M, MASK_VIOTA_M) DECLARE_INSN(vid_v, MATCH_VID_V, MASK_VID_V) -DECLARE_INSN(vpopc_m, MATCH_VPOPC_M, MASK_VPOPC_M) +DECLARE_INSN(vcpop_m, MATCH_VCPOP_M, MASK_VCPOP_M) DECLARE_INSN(vfirst_m, MATCH_VFIRST_M, MASK_VFIRST_M) DECLARE_INSN(vdivu_vv, MATCH_VDIVU_VV, MASK_VDIVU_VV) DECLARE_INSN(vdiv_vv, MATCH_VDIV_VV, MASK_VDIV_VV) @@ -2801,28 +4004,352 @@ DECLARE_INSN(vamominei64_v, MATCH_VAMOMINEI64_V, MASK_VAMOMINEI64_V) DECLARE_INSN(vamomaxei64_v, MATCH_VAMOMAXEI64_V, MASK_VAMOMAXEI64_V) DECLARE_INSN(vamominuei64_v, MATCH_VAMOMINUEI64_V, MASK_VAMOMINUEI64_V) DECLARE_INSN(vamomaxuei64_v, MATCH_VAMOMAXUEI64_V, MASK_VAMOMAXUEI64_V) +DECLARE_INSN(add8, MATCH_ADD8, MASK_ADD8) +DECLARE_INSN(add16, MATCH_ADD16, MASK_ADD16) +DECLARE_INSN(add64, MATCH_ADD64, MASK_ADD64) +DECLARE_INSN(ave, MATCH_AVE, MASK_AVE) +DECLARE_INSN(bitrev, MATCH_BITREV, MASK_BITREV) +DECLARE_INSN(bitrevi, MATCH_BITREVI, MASK_BITREVI) +DECLARE_INSN(bpick, MATCH_BPICK, MASK_BPICK) +DECLARE_INSN(clrs8, MATCH_CLRS8, MASK_CLRS8) +DECLARE_INSN(clrs16, MATCH_CLRS16, MASK_CLRS16) +DECLARE_INSN(clrs32, MATCH_CLRS32, MASK_CLRS32) +DECLARE_INSN(clo8, MATCH_CLO8, MASK_CLO8) +DECLARE_INSN(clo16, MATCH_CLO16, MASK_CLO16) +DECLARE_INSN(clo32, MATCH_CLO32, MASK_CLO32) +DECLARE_INSN(clz8, MATCH_CLZ8, MASK_CLZ8) +DECLARE_INSN(clz16, MATCH_CLZ16, MASK_CLZ16) +DECLARE_INSN(clz32, MATCH_CLZ32, MASK_CLZ32) +DECLARE_INSN(cmpeq8, MATCH_CMPEQ8, MASK_CMPEQ8) +DECLARE_INSN(cmpeq16, MATCH_CMPEQ16, MASK_CMPEQ16) +DECLARE_INSN(cras16, MATCH_CRAS16, MASK_CRAS16) +DECLARE_INSN(crsa16, MATCH_CRSA16, MASK_CRSA16) +DECLARE_INSN(insb, MATCH_INSB, MASK_INSB) +DECLARE_INSN(kabs8, MATCH_KABS8, MASK_KABS8) +DECLARE_INSN(kabs16, MATCH_KABS16, MASK_KABS16) +DECLARE_INSN(kabsw, MATCH_KABSW, MASK_KABSW) +DECLARE_INSN(kadd8, MATCH_KADD8, MASK_KADD8) +DECLARE_INSN(kadd16, MATCH_KADD16, MASK_KADD16) +DECLARE_INSN(kadd64, MATCH_KADD64, MASK_KADD64) +DECLARE_INSN(kaddh, MATCH_KADDH, MASK_KADDH) +DECLARE_INSN(kaddw, MATCH_KADDW, MASK_KADDW) +DECLARE_INSN(kcras16, MATCH_KCRAS16, MASK_KCRAS16) +DECLARE_INSN(kcrsa16, MATCH_KCRSA16, MASK_KCRSA16) +DECLARE_INSN(kdmbb, MATCH_KDMBB, MASK_KDMBB) +DECLARE_INSN(kdmbt, MATCH_KDMBT, MASK_KDMBT) +DECLARE_INSN(kdmtt, MATCH_KDMTT, MASK_KDMTT) +DECLARE_INSN(kdmabb, MATCH_KDMABB, MASK_KDMABB) +DECLARE_INSN(kdmabt, MATCH_KDMABT, MASK_KDMABT) +DECLARE_INSN(kdmatt, MATCH_KDMATT, MASK_KDMATT) +DECLARE_INSN(khm8, MATCH_KHM8, MASK_KHM8) +DECLARE_INSN(khmx8, MATCH_KHMX8, MASK_KHMX8) +DECLARE_INSN(khm16, MATCH_KHM16, MASK_KHM16) +DECLARE_INSN(khmx16, MATCH_KHMX16, MASK_KHMX16) +DECLARE_INSN(khmbb, MATCH_KHMBB, MASK_KHMBB) +DECLARE_INSN(khmbt, MATCH_KHMBT, MASK_KHMBT) +DECLARE_INSN(khmtt, MATCH_KHMTT, MASK_KHMTT) +DECLARE_INSN(kmabb, MATCH_KMABB, MASK_KMABB) +DECLARE_INSN(kmabt, MATCH_KMABT, MASK_KMABT) +DECLARE_INSN(kmatt, MATCH_KMATT, MASK_KMATT) +DECLARE_INSN(kmada, MATCH_KMADA, MASK_KMADA) +DECLARE_INSN(kmaxda, MATCH_KMAXDA, MASK_KMAXDA) +DECLARE_INSN(kmads, MATCH_KMADS, MASK_KMADS) +DECLARE_INSN(kmadrs, MATCH_KMADRS, MASK_KMADRS) +DECLARE_INSN(kmaxds, MATCH_KMAXDS, MASK_KMAXDS) +DECLARE_INSN(kmar64, MATCH_KMAR64, MASK_KMAR64) +DECLARE_INSN(kmda, MATCH_KMDA, MASK_KMDA) +DECLARE_INSN(kmxda, MATCH_KMXDA, MASK_KMXDA) +DECLARE_INSN(kmmac, MATCH_KMMAC, MASK_KMMAC) +DECLARE_INSN(kmmac_u, MATCH_KMMAC_U, MASK_KMMAC_U) +DECLARE_INSN(kmmawb, MATCH_KMMAWB, MASK_KMMAWB) +DECLARE_INSN(kmmawb_u, MATCH_KMMAWB_U, MASK_KMMAWB_U) +DECLARE_INSN(kmmawb2, MATCH_KMMAWB2, MASK_KMMAWB2) +DECLARE_INSN(kmmawb2_u, MATCH_KMMAWB2_U, MASK_KMMAWB2_U) +DECLARE_INSN(kmmawt, MATCH_KMMAWT, MASK_KMMAWT) +DECLARE_INSN(kmmawt_u, MATCH_KMMAWT_U, MASK_KMMAWT_U) +DECLARE_INSN(kmmawt2, MATCH_KMMAWT2, MASK_KMMAWT2) +DECLARE_INSN(kmmawt2_u, MATCH_KMMAWT2_U, MASK_KMMAWT2_U) +DECLARE_INSN(kmmsb, MATCH_KMMSB, MASK_KMMSB) +DECLARE_INSN(kmmsb_u, MATCH_KMMSB_U, MASK_KMMSB_U) +DECLARE_INSN(kmmwb2, MATCH_KMMWB2, MASK_KMMWB2) +DECLARE_INSN(kmmwb2_u, MATCH_KMMWB2_U, MASK_KMMWB2_U) +DECLARE_INSN(kmmwt2, MATCH_KMMWT2, MASK_KMMWT2) +DECLARE_INSN(kmmwt2_u, MATCH_KMMWT2_U, MASK_KMMWT2_U) +DECLARE_INSN(kmsda, MATCH_KMSDA, MASK_KMSDA) +DECLARE_INSN(kmsxda, MATCH_KMSXDA, MASK_KMSXDA) +DECLARE_INSN(kmsr64, MATCH_KMSR64, MASK_KMSR64) +DECLARE_INSN(ksllw, MATCH_KSLLW, MASK_KSLLW) +DECLARE_INSN(kslliw, MATCH_KSLLIW, MASK_KSLLIW) +DECLARE_INSN(ksll8, MATCH_KSLL8, MASK_KSLL8) +DECLARE_INSN(kslli8, MATCH_KSLLI8, MASK_KSLLI8) +DECLARE_INSN(ksll16, MATCH_KSLL16, MASK_KSLL16) +DECLARE_INSN(kslli16, MATCH_KSLLI16, MASK_KSLLI16) +DECLARE_INSN(kslra8, MATCH_KSLRA8, MASK_KSLRA8) +DECLARE_INSN(kslra8_u, MATCH_KSLRA8_U, MASK_KSLRA8_U) +DECLARE_INSN(kslra16, MATCH_KSLRA16, MASK_KSLRA16) +DECLARE_INSN(kslra16_u, MATCH_KSLRA16_U, MASK_KSLRA16_U) +DECLARE_INSN(kslraw, MATCH_KSLRAW, MASK_KSLRAW) +DECLARE_INSN(kslraw_u, MATCH_KSLRAW_U, MASK_KSLRAW_U) +DECLARE_INSN(kstas16, MATCH_KSTAS16, MASK_KSTAS16) +DECLARE_INSN(kstsa16, MATCH_KSTSA16, MASK_KSTSA16) +DECLARE_INSN(ksub8, MATCH_KSUB8, MASK_KSUB8) +DECLARE_INSN(ksub16, MATCH_KSUB16, MASK_KSUB16) +DECLARE_INSN(ksub64, MATCH_KSUB64, MASK_KSUB64) +DECLARE_INSN(ksubh, MATCH_KSUBH, MASK_KSUBH) +DECLARE_INSN(ksubw, MATCH_KSUBW, MASK_KSUBW) +DECLARE_INSN(kwmmul, MATCH_KWMMUL, MASK_KWMMUL) +DECLARE_INSN(kwmmul_u, MATCH_KWMMUL_U, MASK_KWMMUL_U) +DECLARE_INSN(maddr32, MATCH_MADDR32, MASK_MADDR32) +DECLARE_INSN(maxw, MATCH_MAXW, MASK_MAXW) +DECLARE_INSN(minw, MATCH_MINW, MASK_MINW) +DECLARE_INSN(msubr32, MATCH_MSUBR32, MASK_MSUBR32) +DECLARE_INSN(mulr64, MATCH_MULR64, MASK_MULR64) +DECLARE_INSN(mulsr64, MATCH_MULSR64, MASK_MULSR64) +DECLARE_INSN(pbsad, MATCH_PBSAD, MASK_PBSAD) +DECLARE_INSN(pbsada, MATCH_PBSADA, MASK_PBSADA) +DECLARE_INSN(pkbb16, MATCH_PKBB16, MASK_PKBB16) +DECLARE_INSN(pkbt16, MATCH_PKBT16, MASK_PKBT16) +DECLARE_INSN(pktt16, MATCH_PKTT16, MASK_PKTT16) +DECLARE_INSN(pktb16, MATCH_PKTB16, MASK_PKTB16) +DECLARE_INSN(radd8, MATCH_RADD8, MASK_RADD8) +DECLARE_INSN(radd16, MATCH_RADD16, MASK_RADD16) +DECLARE_INSN(radd64, MATCH_RADD64, MASK_RADD64) +DECLARE_INSN(raddw, MATCH_RADDW, MASK_RADDW) +DECLARE_INSN(rcras16, MATCH_RCRAS16, MASK_RCRAS16) +DECLARE_INSN(rcrsa16, MATCH_RCRSA16, MASK_RCRSA16) +DECLARE_INSN(rstas16, MATCH_RSTAS16, MASK_RSTAS16) +DECLARE_INSN(rstsa16, MATCH_RSTSA16, MASK_RSTSA16) +DECLARE_INSN(rsub8, MATCH_RSUB8, MASK_RSUB8) +DECLARE_INSN(rsub16, MATCH_RSUB16, MASK_RSUB16) +DECLARE_INSN(rsub64, MATCH_RSUB64, MASK_RSUB64) +DECLARE_INSN(rsubw, MATCH_RSUBW, MASK_RSUBW) +DECLARE_INSN(sclip8, MATCH_SCLIP8, MASK_SCLIP8) +DECLARE_INSN(sclip16, MATCH_SCLIP16, MASK_SCLIP16) +DECLARE_INSN(sclip32, MATCH_SCLIP32, MASK_SCLIP32) +DECLARE_INSN(scmple8, MATCH_SCMPLE8, MASK_SCMPLE8) +DECLARE_INSN(scmple16, MATCH_SCMPLE16, MASK_SCMPLE16) +DECLARE_INSN(scmplt8, MATCH_SCMPLT8, MASK_SCMPLT8) +DECLARE_INSN(scmplt16, MATCH_SCMPLT16, MASK_SCMPLT16) +DECLARE_INSN(sll8, MATCH_SLL8, MASK_SLL8) +DECLARE_INSN(slli8, MATCH_SLLI8, MASK_SLLI8) +DECLARE_INSN(sll16, MATCH_SLL16, MASK_SLL16) +DECLARE_INSN(slli16, MATCH_SLLI16, MASK_SLLI16) +DECLARE_INSN(smal, MATCH_SMAL, MASK_SMAL) +DECLARE_INSN(smalbb, MATCH_SMALBB, MASK_SMALBB) +DECLARE_INSN(smalbt, MATCH_SMALBT, MASK_SMALBT) +DECLARE_INSN(smaltt, MATCH_SMALTT, MASK_SMALTT) +DECLARE_INSN(smalda, MATCH_SMALDA, MASK_SMALDA) +DECLARE_INSN(smalxda, MATCH_SMALXDA, MASK_SMALXDA) +DECLARE_INSN(smalds, MATCH_SMALDS, MASK_SMALDS) +DECLARE_INSN(smaldrs, MATCH_SMALDRS, MASK_SMALDRS) +DECLARE_INSN(smalxds, MATCH_SMALXDS, MASK_SMALXDS) +DECLARE_INSN(smar64, MATCH_SMAR64, MASK_SMAR64) +DECLARE_INSN(smaqa, MATCH_SMAQA, MASK_SMAQA) +DECLARE_INSN(smaqa_su, MATCH_SMAQA_SU, MASK_SMAQA_SU) +DECLARE_INSN(smax8, MATCH_SMAX8, MASK_SMAX8) +DECLARE_INSN(smax16, MATCH_SMAX16, MASK_SMAX16) +DECLARE_INSN(smbb16, MATCH_SMBB16, MASK_SMBB16) +DECLARE_INSN(smbt16, MATCH_SMBT16, MASK_SMBT16) +DECLARE_INSN(smtt16, MATCH_SMTT16, MASK_SMTT16) +DECLARE_INSN(smds, MATCH_SMDS, MASK_SMDS) +DECLARE_INSN(smdrs, MATCH_SMDRS, MASK_SMDRS) +DECLARE_INSN(smxds, MATCH_SMXDS, MASK_SMXDS) +DECLARE_INSN(smin8, MATCH_SMIN8, MASK_SMIN8) +DECLARE_INSN(smin16, MATCH_SMIN16, MASK_SMIN16) +DECLARE_INSN(smmul, MATCH_SMMUL, MASK_SMMUL) +DECLARE_INSN(smmul_u, MATCH_SMMUL_U, MASK_SMMUL_U) +DECLARE_INSN(smmwb, MATCH_SMMWB, MASK_SMMWB) +DECLARE_INSN(smmwb_u, MATCH_SMMWB_U, MASK_SMMWB_U) +DECLARE_INSN(smmwt, MATCH_SMMWT, MASK_SMMWT) +DECLARE_INSN(smmwt_u, MATCH_SMMWT_U, MASK_SMMWT_U) +DECLARE_INSN(smslda, MATCH_SMSLDA, MASK_SMSLDA) +DECLARE_INSN(smslxda, MATCH_SMSLXDA, MASK_SMSLXDA) +DECLARE_INSN(smsr64, MATCH_SMSR64, MASK_SMSR64) +DECLARE_INSN(smul8, MATCH_SMUL8, MASK_SMUL8) +DECLARE_INSN(smulx8, MATCH_SMULX8, MASK_SMULX8) +DECLARE_INSN(smul16, MATCH_SMUL16, MASK_SMUL16) +DECLARE_INSN(smulx16, MATCH_SMULX16, MASK_SMULX16) +DECLARE_INSN(sra_u, MATCH_SRA_U, MASK_SRA_U) +DECLARE_INSN(srai_u, MATCH_SRAI_U, MASK_SRAI_U) +DECLARE_INSN(sra8, MATCH_SRA8, MASK_SRA8) +DECLARE_INSN(sra8_u, MATCH_SRA8_U, MASK_SRA8_U) +DECLARE_INSN(srai8, MATCH_SRAI8, MASK_SRAI8) +DECLARE_INSN(srai8_u, MATCH_SRAI8_U, MASK_SRAI8_U) +DECLARE_INSN(sra16, MATCH_SRA16, MASK_SRA16) +DECLARE_INSN(sra16_u, MATCH_SRA16_U, MASK_SRA16_U) +DECLARE_INSN(srai16, MATCH_SRAI16, MASK_SRAI16) +DECLARE_INSN(srai16_u, MATCH_SRAI16_U, MASK_SRAI16_U) +DECLARE_INSN(srl8, MATCH_SRL8, MASK_SRL8) +DECLARE_INSN(srl8_u, MATCH_SRL8_U, MASK_SRL8_U) +DECLARE_INSN(srli8, MATCH_SRLI8, MASK_SRLI8) +DECLARE_INSN(srli8_u, MATCH_SRLI8_U, MASK_SRLI8_U) +DECLARE_INSN(srl16, MATCH_SRL16, MASK_SRL16) +DECLARE_INSN(srl16_u, MATCH_SRL16_U, MASK_SRL16_U) +DECLARE_INSN(srli16, MATCH_SRLI16, MASK_SRLI16) +DECLARE_INSN(srli16_u, MATCH_SRLI16_U, MASK_SRLI16_U) +DECLARE_INSN(stas16, MATCH_STAS16, MASK_STAS16) +DECLARE_INSN(stsa16, MATCH_STSA16, MASK_STSA16) +DECLARE_INSN(sub8, MATCH_SUB8, MASK_SUB8) +DECLARE_INSN(sub16, MATCH_SUB16, MASK_SUB16) +DECLARE_INSN(sub64, MATCH_SUB64, MASK_SUB64) +DECLARE_INSN(sunpkd810, MATCH_SUNPKD810, MASK_SUNPKD810) +DECLARE_INSN(sunpkd820, MATCH_SUNPKD820, MASK_SUNPKD820) +DECLARE_INSN(sunpkd830, MATCH_SUNPKD830, MASK_SUNPKD830) +DECLARE_INSN(sunpkd831, MATCH_SUNPKD831, MASK_SUNPKD831) +DECLARE_INSN(sunpkd832, MATCH_SUNPKD832, MASK_SUNPKD832) +DECLARE_INSN(swap8, MATCH_SWAP8, MASK_SWAP8) +DECLARE_INSN(uclip8, MATCH_UCLIP8, MASK_UCLIP8) +DECLARE_INSN(uclip16, MATCH_UCLIP16, MASK_UCLIP16) +DECLARE_INSN(uclip32, MATCH_UCLIP32, MASK_UCLIP32) +DECLARE_INSN(ucmple8, MATCH_UCMPLE8, MASK_UCMPLE8) +DECLARE_INSN(ucmple16, MATCH_UCMPLE16, MASK_UCMPLE16) +DECLARE_INSN(ucmplt8, MATCH_UCMPLT8, MASK_UCMPLT8) +DECLARE_INSN(ucmplt16, MATCH_UCMPLT16, MASK_UCMPLT16) +DECLARE_INSN(ukadd8, MATCH_UKADD8, MASK_UKADD8) +DECLARE_INSN(ukadd16, MATCH_UKADD16, MASK_UKADD16) +DECLARE_INSN(ukadd64, MATCH_UKADD64, MASK_UKADD64) +DECLARE_INSN(ukaddh, MATCH_UKADDH, MASK_UKADDH) +DECLARE_INSN(ukaddw, MATCH_UKADDW, MASK_UKADDW) +DECLARE_INSN(ukcras16, MATCH_UKCRAS16, MASK_UKCRAS16) +DECLARE_INSN(ukcrsa16, MATCH_UKCRSA16, MASK_UKCRSA16) +DECLARE_INSN(ukmar64, MATCH_UKMAR64, MASK_UKMAR64) +DECLARE_INSN(ukmsr64, MATCH_UKMSR64, MASK_UKMSR64) +DECLARE_INSN(ukstas16, MATCH_UKSTAS16, MASK_UKSTAS16) +DECLARE_INSN(ukstsa16, MATCH_UKSTSA16, MASK_UKSTSA16) +DECLARE_INSN(uksub8, MATCH_UKSUB8, MASK_UKSUB8) +DECLARE_INSN(uksub16, MATCH_UKSUB16, MASK_UKSUB16) +DECLARE_INSN(uksub64, MATCH_UKSUB64, MASK_UKSUB64) +DECLARE_INSN(uksubh, MATCH_UKSUBH, MASK_UKSUBH) +DECLARE_INSN(uksubw, MATCH_UKSUBW, MASK_UKSUBW) +DECLARE_INSN(umar64, MATCH_UMAR64, MASK_UMAR64) +DECLARE_INSN(umaqa, MATCH_UMAQA, MASK_UMAQA) +DECLARE_INSN(umax8, MATCH_UMAX8, MASK_UMAX8) +DECLARE_INSN(umax16, MATCH_UMAX16, MASK_UMAX16) +DECLARE_INSN(umin8, MATCH_UMIN8, MASK_UMIN8) +DECLARE_INSN(umin16, MATCH_UMIN16, MASK_UMIN16) +DECLARE_INSN(umsr64, MATCH_UMSR64, MASK_UMSR64) +DECLARE_INSN(umul8, MATCH_UMUL8, MASK_UMUL8) +DECLARE_INSN(umulx8, MATCH_UMULX8, MASK_UMULX8) +DECLARE_INSN(umul16, MATCH_UMUL16, MASK_UMUL16) +DECLARE_INSN(umulx16, MATCH_UMULX16, MASK_UMULX16) +DECLARE_INSN(uradd8, MATCH_URADD8, MASK_URADD8) +DECLARE_INSN(uradd16, MATCH_URADD16, MASK_URADD16) +DECLARE_INSN(uradd64, MATCH_URADD64, MASK_URADD64) +DECLARE_INSN(uraddw, MATCH_URADDW, MASK_URADDW) +DECLARE_INSN(urcras16, MATCH_URCRAS16, MASK_URCRAS16) +DECLARE_INSN(urcrsa16, MATCH_URCRSA16, MASK_URCRSA16) +DECLARE_INSN(urstas16, MATCH_URSTAS16, MASK_URSTAS16) +DECLARE_INSN(urstsa16, MATCH_URSTSA16, MASK_URSTSA16) +DECLARE_INSN(ursub8, MATCH_URSUB8, MASK_URSUB8) +DECLARE_INSN(ursub16, MATCH_URSUB16, MASK_URSUB16) +DECLARE_INSN(ursub64, MATCH_URSUB64, MASK_URSUB64) +DECLARE_INSN(ursubw, MATCH_URSUBW, MASK_URSUBW) +DECLARE_INSN(wexti, MATCH_WEXTI, MASK_WEXTI) +DECLARE_INSN(wext, MATCH_WEXT, MASK_WEXT) +DECLARE_INSN(zunpkd810, MATCH_ZUNPKD810, MASK_ZUNPKD810) +DECLARE_INSN(zunpkd820, MATCH_ZUNPKD820, MASK_ZUNPKD820) +DECLARE_INSN(zunpkd830, MATCH_ZUNPKD830, MASK_ZUNPKD830) +DECLARE_INSN(zunpkd831, MATCH_ZUNPKD831, MASK_ZUNPKD831) +DECLARE_INSN(zunpkd832, MATCH_ZUNPKD832, MASK_ZUNPKD832) +DECLARE_INSN(add32, MATCH_ADD32, MASK_ADD32) +DECLARE_INSN(cras32, MATCH_CRAS32, MASK_CRAS32) +DECLARE_INSN(crsa32, MATCH_CRSA32, MASK_CRSA32) +DECLARE_INSN(kabs32, MATCH_KABS32, MASK_KABS32) +DECLARE_INSN(kadd32, MATCH_KADD32, MASK_KADD32) +DECLARE_INSN(kcras32, MATCH_KCRAS32, MASK_KCRAS32) +DECLARE_INSN(kcrsa32, MATCH_KCRSA32, MASK_KCRSA32) +DECLARE_INSN(kdmbb16, MATCH_KDMBB16, MASK_KDMBB16) +DECLARE_INSN(kdmbt16, MATCH_KDMBT16, MASK_KDMBT16) +DECLARE_INSN(kdmtt16, MATCH_KDMTT16, MASK_KDMTT16) +DECLARE_INSN(kdmabb16, MATCH_KDMABB16, MASK_KDMABB16) +DECLARE_INSN(kdmabt16, MATCH_KDMABT16, MASK_KDMABT16) +DECLARE_INSN(kdmatt16, MATCH_KDMATT16, MASK_KDMATT16) +DECLARE_INSN(khmbb16, MATCH_KHMBB16, MASK_KHMBB16) +DECLARE_INSN(khmbt16, MATCH_KHMBT16, MASK_KHMBT16) +DECLARE_INSN(khmtt16, MATCH_KHMTT16, MASK_KHMTT16) +DECLARE_INSN(kmabb32, MATCH_KMABB32, MASK_KMABB32) +DECLARE_INSN(kmabt32, MATCH_KMABT32, MASK_KMABT32) +DECLARE_INSN(kmatt32, MATCH_KMATT32, MASK_KMATT32) +DECLARE_INSN(kmaxda32, MATCH_KMAXDA32, MASK_KMAXDA32) +DECLARE_INSN(kmda32, MATCH_KMDA32, MASK_KMDA32) +DECLARE_INSN(kmxda32, MATCH_KMXDA32, MASK_KMXDA32) +DECLARE_INSN(kmads32, MATCH_KMADS32, MASK_KMADS32) +DECLARE_INSN(kmadrs32, MATCH_KMADRS32, MASK_KMADRS32) +DECLARE_INSN(kmaxds32, MATCH_KMAXDS32, MASK_KMAXDS32) +DECLARE_INSN(kmsda32, MATCH_KMSDA32, MASK_KMSDA32) +DECLARE_INSN(kmsxda32, MATCH_KMSXDA32, MASK_KMSXDA32) +DECLARE_INSN(ksll32, MATCH_KSLL32, MASK_KSLL32) +DECLARE_INSN(kslli32, MATCH_KSLLI32, MASK_KSLLI32) +DECLARE_INSN(kslra32, MATCH_KSLRA32, MASK_KSLRA32) +DECLARE_INSN(kslra32_u, MATCH_KSLRA32_U, MASK_KSLRA32_U) +DECLARE_INSN(kstas32, MATCH_KSTAS32, MASK_KSTAS32) +DECLARE_INSN(kstsa32, MATCH_KSTSA32, MASK_KSTSA32) +DECLARE_INSN(ksub32, MATCH_KSUB32, MASK_KSUB32) +DECLARE_INSN(pkbb32, MATCH_PKBB32, MASK_PKBB32) +DECLARE_INSN(pkbt32, MATCH_PKBT32, MASK_PKBT32) +DECLARE_INSN(pktt32, MATCH_PKTT32, MASK_PKTT32) +DECLARE_INSN(pktb32, MATCH_PKTB32, MASK_PKTB32) +DECLARE_INSN(radd32, MATCH_RADD32, MASK_RADD32) +DECLARE_INSN(rcras32, MATCH_RCRAS32, MASK_RCRAS32) +DECLARE_INSN(rcrsa32, MATCH_RCRSA32, MASK_RCRSA32) +DECLARE_INSN(rstas32, MATCH_RSTAS32, MASK_RSTAS32) +DECLARE_INSN(rstsa32, MATCH_RSTSA32, MASK_RSTSA32) +DECLARE_INSN(rsub32, MATCH_RSUB32, MASK_RSUB32) +DECLARE_INSN(sll32, MATCH_SLL32, MASK_SLL32) +DECLARE_INSN(slli32, MATCH_SLLI32, MASK_SLLI32) +DECLARE_INSN(smax32, MATCH_SMAX32, MASK_SMAX32) +DECLARE_INSN(smbt32, MATCH_SMBT32, MASK_SMBT32) +DECLARE_INSN(smtt32, MATCH_SMTT32, MASK_SMTT32) +DECLARE_INSN(smds32, MATCH_SMDS32, MASK_SMDS32) +DECLARE_INSN(smdrs32, MATCH_SMDRS32, MASK_SMDRS32) +DECLARE_INSN(smxds32, MATCH_SMXDS32, MASK_SMXDS32) +DECLARE_INSN(smin32, MATCH_SMIN32, MASK_SMIN32) +DECLARE_INSN(sra32, MATCH_SRA32, MASK_SRA32) +DECLARE_INSN(sra32_u, MATCH_SRA32_U, MASK_SRA32_U) +DECLARE_INSN(srai32, MATCH_SRAI32, MASK_SRAI32) +DECLARE_INSN(srai32_u, MATCH_SRAI32_U, MASK_SRAI32_U) +DECLARE_INSN(sraiw_u, MATCH_SRAIW_U, MASK_SRAIW_U) +DECLARE_INSN(srl32, MATCH_SRL32, MASK_SRL32) +DECLARE_INSN(srl32_u, MATCH_SRL32_U, MASK_SRL32_U) +DECLARE_INSN(srli32, MATCH_SRLI32, MASK_SRLI32) +DECLARE_INSN(srli32_u, MATCH_SRLI32_U, MASK_SRLI32_U) +DECLARE_INSN(stas32, MATCH_STAS32, MASK_STAS32) +DECLARE_INSN(stsa32, MATCH_STSA32, MASK_STSA32) +DECLARE_INSN(sub32, MATCH_SUB32, MASK_SUB32) +DECLARE_INSN(ukadd32, MATCH_UKADD32, MASK_UKADD32) +DECLARE_INSN(ukcras32, MATCH_UKCRAS32, MASK_UKCRAS32) +DECLARE_INSN(ukcrsa32, MATCH_UKCRSA32, MASK_UKCRSA32) +DECLARE_INSN(ukstas32, MATCH_UKSTAS32, MASK_UKSTAS32) +DECLARE_INSN(ukstsa32, MATCH_UKSTSA32, MASK_UKSTSA32) +DECLARE_INSN(uksub32, MATCH_UKSUB32, MASK_UKSUB32) +DECLARE_INSN(umax32, MATCH_UMAX32, MASK_UMAX32) +DECLARE_INSN(umin32, MATCH_UMIN32, MASK_UMIN32) +DECLARE_INSN(uradd32, MATCH_URADD32, MASK_URADD32) +DECLARE_INSN(urcras32, MATCH_URCRAS32, MASK_URCRAS32) +DECLARE_INSN(urcrsa32, MATCH_URCRSA32, MASK_URCRSA32) +DECLARE_INSN(urstas32, MATCH_URSTAS32, MASK_URSTAS32) +DECLARE_INSN(urstsa32, MATCH_URSTSA32, MASK_URSTSA32) +DECLARE_INSN(ursub32, MATCH_URSUB32, MASK_URSUB32) DECLARE_INSN(vmvnfr_v, MATCH_VMVNFR_V, MASK_VMVNFR_V) DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V) DECLARE_INSN(vl2r_v, MATCH_VL2R_V, MASK_VL2R_V) DECLARE_INSN(vl4r_v, MATCH_VL4R_V, MASK_VL4R_V) DECLARE_INSN(vl8r_v, MATCH_VL8R_V, MASK_VL8R_V) +DECLARE_INSN(vle1_v, MATCH_VLE1_V, MASK_VLE1_V) +DECLARE_INSN(vse1_v, MATCH_VSE1_V, MASK_VSE1_V) +DECLARE_INSN(vfredsum_vs, MATCH_VFREDSUM_VS, MASK_VFREDSUM_VS) +DECLARE_INSN(vfwredsum_vs, MATCH_VFWREDSUM_VS, MASK_VFWREDSUM_VS) +DECLARE_INSN(vpopc_m, MATCH_VPOPC_M, MASK_VPOPC_M) #endif #ifdef DECLARE_CSR DECLARE_CSR(fflags, CSR_FFLAGS) DECLARE_CSR(frm, CSR_FRM) DECLARE_CSR(fcsr, CSR_FCSR) -DECLARE_CSR(ustatus, CSR_USTATUS) -DECLARE_CSR(uie, CSR_UIE) -DECLARE_CSR(utvec, CSR_UTVEC) DECLARE_CSR(vstart, CSR_VSTART) DECLARE_CSR(vxsat, CSR_VXSAT) DECLARE_CSR(vxrm, CSR_VXRM) DECLARE_CSR(vcsr, CSR_VCSR) -DECLARE_CSR(uscratch, CSR_USCRATCH) -DECLARE_CSR(uepc, CSR_UEPC) -DECLARE_CSR(ucause, CSR_UCAUSE) -DECLARE_CSR(utval, CSR_UTVAL) -DECLARE_CSR(uip, CSR_UIP) +DECLARE_CSR(seed, CSR_SEED) DECLARE_CSR(cycle, CSR_CYCLE) DECLARE_CSR(time, CSR_TIME) DECLARE_CSR(instret, CSR_INSTRET) @@ -2870,6 +4397,7 @@ DECLARE_CSR(scause, CSR_SCAUSE) DECLARE_CSR(stval, CSR_STVAL) DECLARE_CSR(sip, CSR_SIP) DECLARE_CSR(satp, CSR_SATP) +DECLARE_CSR(scontext, CSR_SCONTEXT) DECLARE_CSR(vsstatus, CSR_VSSTATUS) DECLARE_CSR(vsie, CSR_VSIE) DECLARE_CSR(vstvec, CSR_VSTVEC) @@ -2891,6 +4419,7 @@ DECLARE_CSR(hip, CSR_HIP) DECLARE_CSR(hvip, CSR_HVIP) DECLARE_CSR(htinst, CSR_HTINST) DECLARE_CSR(hgatp, CSR_HGATP) +DECLARE_CSR(hcontext, CSR_HCONTEXT) DECLARE_CSR(hgeip, CSR_HGEIP) DECLARE_CSR(utvt, CSR_UTVT) DECLARE_CSR(unxti, CSR_UNXTI) @@ -2946,6 +4475,10 @@ DECLARE_CSR(tselect, CSR_TSELECT) DECLARE_CSR(tdata1, CSR_TDATA1) DECLARE_CSR(tdata2, CSR_TDATA2) DECLARE_CSR(tdata3, CSR_TDATA3) +DECLARE_CSR(tinfo, CSR_TINFO) +DECLARE_CSR(tcontrol, CSR_TCONTROL) +DECLARE_CSR(mcontext, CSR_MCONTEXT) +DECLARE_CSR(mscontext, CSR_MSCONTEXT) DECLARE_CSR(dcsr, CSR_DCSR) DECLARE_CSR(dpc, CSR_DPC) DECLARE_CSR(dscratch0, CSR_DSCRATCH0) From 6441fe8d9d29d7720e1272e1a5b166535116d172 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Tue, 5 Oct 2021 10:03:19 -0700 Subject: [PATCH 47/82] riscv: Clear type 6 triggers on connecting. I missed this when I first add mcontrol6 support. https://github.com/riscv/riscv-openocd/pull/648 Change-Id: I1a2706c7ea3a6757ed5083091cd2c764a8b0267c Signed-off-by: Tim Newsome Reviewed-on: https://review.openocd.org/c/openocd/+/6684 Tested-by: jenkins Reviewed-by: Jan Matyas Reviewed-by: Antonio Borneo --- src/target/riscv/riscv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 084939e11..407b7e279 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -3569,6 +3569,10 @@ int riscv_enumerate_triggers(struct target *target) if (tdata1 & MCONTROL_DMODE(riscv_xlen(target))) riscv_set_register(target, GDB_REGNO_TDATA1, 0); break; + case 6: + if (tdata1 & MCONTROL_DMODE(riscv_xlen(target))) + riscv_set_register(target, GDB_REGNO_TDATA1, 0); + break; } } From 8457a1be10d1463b40c020867ad4dc2513c93a4b Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Tue, 12 Oct 2021 11:06:44 -0700 Subject: [PATCH 48/82] target: Use target_addr_t for algorithm addresses. Otherwise 64-bit addresses can't work. Signed-off-by: Tim Newsome Change-Id: Id9f92ff8a1602153cc06810bcf515a9d0a89c81b Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6662 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/target.c | 6 +++--- src/target/target.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 35e9b5332..ed6f655ea 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -839,7 +839,7 @@ static int target_soft_reset_halt(struct target *target) int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, - uint32_t entry_point, uint32_t exit_point, + target_addr_t entry_point, target_addr_t exit_point, int timeout_ms, void *arch_info) { int retval = ERROR_FAIL; @@ -880,7 +880,7 @@ done: int target_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - uint32_t entry_point, uint32_t exit_point, + target_addr_t entry_point, target_addr_t exit_point, void *arch_info) { int retval = ERROR_FAIL; @@ -924,7 +924,7 @@ done: int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - uint32_t exit_point, int timeout_ms, + target_addr_t exit_point, int timeout_ms, void *arch_info) { int retval = ERROR_FAIL; diff --git a/src/target/target.h b/src/target/target.h index 1e19434e4..99ec2be10 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -547,7 +547,7 @@ int target_step(struct target *target, int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, - uint32_t entry_point, uint32_t exit_point, + target_addr_t entry_point, target_addr_t exit_point, int timeout_ms, void *arch_info); /** @@ -558,7 +558,7 @@ int target_run_algorithm(struct target *target, int target_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - uint32_t entry_point, uint32_t exit_point, + target_addr_t entry_point, target_addr_t exit_point, void *arch_info); /** @@ -569,7 +569,7 @@ int target_start_algorithm(struct target *target, int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - uint32_t exit_point, int timeout_ms, + target_addr_t exit_point, int timeout_ms, void *arch_info); /** From 46e39108400ef717d05c2cff66088f1b499a02a5 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Thu, 11 Nov 2021 16:35:18 +0100 Subject: [PATCH 49/82] drivers/jtag_vpi: Added "jtag_vpi:" prefixes to log messages Added "jtag_vpi:" prefixes to log messages from the jtag_vpi driver. The intention is to make it clear what the messages relate to. Without the prefix, many of the log messages won't make much sense to the user. This change does not alter any functionality, just the printed text. Example: Before: Error: Can't connect to 127.0.0.1 : 5555 After: Error: jtag_vpi: Can't connect to 127.0.0.1 : 5555 Change-Id: I779c379f52722b094b200d08b25ab0f7280d2845 Signed-off-by: Jan Matyas Reviewed-on: https://review.openocd.org/c/openocd/+/6686 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/jtag_vpi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index a0138f840..0fc688edf 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -159,7 +159,7 @@ retry_write: /* This means we could not send all data, which is most likely fatal for the jtag_vpi connection (the underlying TCP connection likely not usable anymore) */ - LOG_ERROR("Could not send all data through jtag_vpi connection."); + LOG_ERROR("jtag_vpi: Could not send all data through jtag_vpi connection."); exit(-1); } @@ -541,7 +541,7 @@ static int jtag_vpi_init(void) sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { - LOG_ERROR("Could not create socket"); + LOG_ERROR("jtag_vpi: Could not create client socket"); return ERROR_FAIL; } @@ -556,13 +556,13 @@ static int jtag_vpi_init(void) serv_addr.sin_addr.s_addr = inet_addr(server_address); if (serv_addr.sin_addr.s_addr == INADDR_NONE) { - LOG_ERROR("inet_addr error occurred"); + LOG_ERROR("jtag_vpi: inet_addr error occurred"); return ERROR_FAIL; } if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { close(sockfd); - LOG_ERROR("Can't connect to %s : %u", server_address, server_port); + LOG_ERROR("jtag_vpi: Can't connect to %s : %u", server_address, server_port); return ERROR_COMMAND_CLOSE_CONNECTION; } @@ -573,7 +573,7 @@ static int jtag_vpi_init(void) setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)); } - LOG_INFO("Connection to %s : %u succeed", server_address, server_port); + LOG_INFO("jtag_vpi: Connection to %s : %u successful", server_address, server_port); return ERROR_OK; } From 08dac883a14aab398922a4e61d55204d7cef644f Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Thu, 11 Nov 2021 23:55:39 +0100 Subject: [PATCH 50/82] jtag/hla_layout: add #include hla_layout.h uses explicitly tpiu_pin_protocol enum defined in arm_tpiu_swo.h. To make this header file consistent, add the missing include. Change-Id: Ibecc279da8d6859ced2b8377e812554c747d81bb Signed-off-by: Tarek BOCHKATI Reviewed-on: https://review.openocd.org/c/openocd/+/6687 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/hla/hla_layout.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h index a8088fe95..732fe1e6a 100644 --- a/src/jtag/hla/hla_layout.h +++ b/src/jtag/hla/hla_layout.h @@ -23,6 +23,7 @@ #define OPENOCD_JTAG_HLA_HLA_LAYOUT_H #include +#include /** */ struct hl_interface_s; From 3eef83e4bd2b112b98d73f8b0947af93c193e0ef Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Wed, 10 Nov 2021 12:46:42 +0100 Subject: [PATCH 51/82] target/arm_dap: fix memory leak in error path of dap_create() Change-Id: I91fa5910670161b62a76fc834b6394c5a6c05395 Suggested-by: Antonio Borneo Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6685 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/arm_dap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 94edfc09d..18e77b50f 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -267,8 +267,11 @@ static int dap_create(struct jim_getopt_info *goi) dap_commands[0].chain = NULL; e = register_commands_with_data(cmd_ctx, NULL, dap_commands, dap); - if (e != ERROR_OK) + if (e != ERROR_OK) { + free(dap->name); + free(dap); return JIM_ERR; + } list_add_tail(&dap->lh, &all_dap); From 872682345af6e26af145c76d5a4373b16d815b7e Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 12 Nov 2021 09:49:01 +0100 Subject: [PATCH 52/82] drivers/swd: add support for SWD multidrop According to ARM IHI0031C+ chapter 2.3.11 "TARGETSEL, Target Selection register" multidrop capable DPv2 must not drive SWDIO line during the response phase of a write to TARGETSEL register. Introduce helper functions swd_cmd_returns_ack() and swd_ack_to_error_code() to centralize these tests from all drivers to one place. Introduce distinct error codes for SWD protocol. Partly inspired by Graham Sanderson's http://review.openocd.org/4935 Change-Id: Ie5f9edb22e066a933a534bf2b29e7e1d3087dad1 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6699 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/jtag/swd.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/jtag/swd.h b/src/jtag/swd.h index fe28667c6..8a436d0c6 100644 --- a/src/jtag/swd.h +++ b/src/jtag/swd.h @@ -18,6 +18,7 @@ #ifndef OPENOCD_JTAG_SWD_H #define OPENOCD_JTAG_SWD_H +#include #include /* Bits in SWD command packets, written from host to target @@ -32,6 +33,12 @@ #define SWD_CMD_PARK (1 << 7) /* driven high by host */ /* followed by TRN, 3-bits of ACK, TRN */ +/* + * The SWD subsystem error codes + */ +#define ERROR_SWD_FAIL (-400) /** protocol or parity error */ +#define ERROR_SWD_FAULT (-401) /** device returned FAULT in ACK field */ + /** * Construct a "cmd" byte, in lSB bit order, which swd_driver.read_reg() * and swd_driver.write_reg() methods will use directly. @@ -53,6 +60,40 @@ static inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum) /* SWD_ACK_* bits are defined in */ +/** + * Test if we can rely on ACK returned by SWD command + * + * @param cmd Byte constructed by swd_cmd(), START, STOP and TRN are filtered off + * @returns true if ACK should be checked, false if should be ignored + */ +static inline bool swd_cmd_returns_ack(uint8_t cmd) +{ + uint8_t base_cmd = cmd & (SWD_CMD_APNDP | SWD_CMD_RNW | SWD_CMD_A32); + + /* DPv2 does not reply to DP_TARGETSEL write cmd */ + return base_cmd != swd_cmd(false, false, DP_TARGETSEL); +} + +/** + * Convert SWD ACK value returned from DP to OpenOCD error code + * + * @param ack + * @returns error code + */ +static inline int swd_ack_to_error_code(uint8_t ack) +{ + switch (ack) { + case SWD_ACK_OK: + return ERROR_OK; + case SWD_ACK_WAIT: + return ERROR_WAIT; + case SWD_ACK_FAULT: + return ERROR_SWD_FAULT; + default: + return ERROR_SWD_FAIL; + } +} + /* * The following sequences are updated to * ARM(tm) Debug Interface v5 Architecture Specification ARM IHI 0031E From d569b9bd68c9ffb4ee464eb5a40cf2839663965b Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 12 Nov 2021 14:14:32 +0100 Subject: [PATCH 53/82] drivers/ftdi: add support for SWD multidrop Ignore ack received after DP_TARGETSEL write to prevent false error. Inspired by Graham Sanderson's http://review.openocd.org/4935 Change-Id: I04fd77cde3244de250743d8c8bfb93ed26379385 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6698 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/ftdi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index d03a4ca23..8366774bc 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -1121,7 +1121,11 @@ static int ftdi_swd_run_queue(void) for (size_t i = 0; i < swd_cmd_queue_length; i++) { int ack = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1, 3); - LOG_DEBUG_IO("%s %s %s reg %X = %08"PRIx32, + /* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */ + bool check_ack = swd_cmd_returns_ack(swd_cmd_queue[i].cmd); + + LOG_DEBUG_IO("%s%s %s %s reg %X = %08"PRIx32, + check_ack ? "" : "ack ignored ", ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", swd_cmd_queue[i].cmd & SWD_CMD_APNDP ? "AP" : "DP", swd_cmd_queue[i].cmd & SWD_CMD_RNW ? "read" : "write", @@ -1129,8 +1133,8 @@ static int ftdi_swd_run_queue(void) buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3 + (swd_cmd_queue[i].cmd & SWD_CMD_RNW ? 0 : 1), 32)); - if (ack != SWD_ACK_OK) { - queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL; + if (ack != SWD_ACK_OK && check_ack) { + queued_retval = swd_ack_to_error_code(ack); goto skip; } else if (swd_cmd_queue[i].cmd & SWD_CMD_RNW) { From 9dd39a33e6dbd9d95b5bcfde4b41c498841a27a1 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 12 Nov 2021 15:28:30 +0100 Subject: [PATCH 54/82] drivers/bitbang: add support for SWD multidrop Ignore ack received after DP_TARGETSEL write to prevent false error. This change also fixes a bug: Received ACK FAULT or JUNK value were incorrectly stored to queued_retval and later used as bitbang_swd_run_queue() error return. Use LOG_ERROR for parity mismatch. Change-Id: I5ff1f658f221af78d8bbec8416a7a0fc64ba2550 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6700 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/bitbang.c | 77 +++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c index d202a0596..898d6d3df 100644 --- a/src/jtag/drivers/bitbang.c +++ b/src/jtag/drivers/bitbang.c @@ -492,38 +492,30 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay uint32_t data = buf_get_u32(trn_ack_data_parity_trn, 1 + 3, 32); int parity = buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 32, 1); - LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, + LOG_DEBUG("%s %s read reg %X = %08"PRIx32, ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", cmd & SWD_CMD_APNDP ? "AP" : "DP", - cmd & SWD_CMD_RNW ? "read" : "write", (cmd & SWD_CMD_A32) >> 1, data); - switch (ack) { - case SWD_ACK_OK: - if (parity != parity_u32(data)) { - LOG_DEBUG("Wrong parity detected"); - queued_retval = ERROR_FAIL; - return; - } - if (value) - *value = data; - if (cmd & SWD_CMD_APNDP) - bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); - return; - case SWD_ACK_WAIT: - LOG_DEBUG("SWD_ACK_WAIT"); + if (ack == SWD_ACK_WAIT) { swd_clear_sticky_errors(); - break; - case SWD_ACK_FAULT: - LOG_DEBUG("SWD_ACK_FAULT"); - queued_retval = ack; - return; - default: - LOG_DEBUG("No valid acknowledge: ack=%d", ack); - queued_retval = ack; + continue; + } else if (ack != SWD_ACK_OK) { + queued_retval = swd_ack_to_error_code(ack); return; } + + if (parity != parity_u32(data)) { + LOG_ERROR("Wrong parity detected"); + queued_retval = ERROR_FAIL; + return; + } + if (value) + *value = data; + if (cmd & SWD_CMD_APNDP) + bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); + return; } } @@ -537,6 +529,9 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay return; } + /* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */ + bool check_ack = swd_cmd_returns_ack(cmd); + for (;;) { uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32, value); @@ -551,31 +546,27 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1); int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3); - LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, + + LOG_DEBUG("%s%s %s write reg %X = %08"PRIx32, + check_ack ? "" : "ack ignored ", ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", cmd & SWD_CMD_APNDP ? "AP" : "DP", - cmd & SWD_CMD_RNW ? "read" : "write", (cmd & SWD_CMD_A32) >> 1, buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32)); - switch (ack) { - case SWD_ACK_OK: - if (cmd & SWD_CMD_APNDP) - bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); - return; - case SWD_ACK_WAIT: - LOG_DEBUG("SWD_ACK_WAIT"); - swd_clear_sticky_errors(); - break; - case SWD_ACK_FAULT: - LOG_DEBUG("SWD_ACK_FAULT"); - queued_retval = ack; - return; - default: - LOG_DEBUG("No valid acknowledge: ack=%d", ack); - queued_retval = ack; - return; + if (check_ack) { + if (ack == SWD_ACK_WAIT) { + swd_clear_sticky_errors(); + continue; + } else if (ack != SWD_ACK_OK) { + queued_retval = swd_ack_to_error_code(ack); + return; + } } + + if (cmd & SWD_CMD_APNDP) + bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); + return; } } From 81afe6e3fdb1253659d7d5a1be9f4f444c2c18d5 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 5 Apr 2021 05:57:46 +0200 Subject: [PATCH 55/82] target/adi_v5_swd: introduce swd_queue_dp_read/write_inner() This is a preparatory change for swd multidrop, mostly refactoring. Split swd_queue_dp_read/write() to inner and outer parts. Use the inner parts in swd_queue_dp_bankselect(), swd_connect() they do not need to check reconnect. Use the outer parts exclusively in swd_dap_ops. Rearrange the code to reduce forward declarations. Change-Id: I47b7f0cb037e0032a267463f06ba02123ba96fe7 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6139 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/target/adi_v5_swd.c | 166 ++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 74 deletions(-) diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 5e4fd2222..6e403e8b2 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -56,6 +56,20 @@ /* for debug, set do_sync to true to force synchronous transfers */ static bool do_sync; + +static int swd_run(struct adiv5_dap *dap); +static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg, + uint32_t data); + + +static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq) +{ + const struct swd_driver *swd = adiv5_dap_swd_driver(dap); + assert(swd); + + return swd->switch_seq(seq); +} + static void swd_finish_read(struct adiv5_dap *dap) { const struct swd_driver *swd = adiv5_dap_swd_driver(dap); @@ -65,11 +79,6 @@ static void swd_finish_read(struct adiv5_dap *dap) } } -static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, - uint32_t data); -static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, - uint32_t *data); - static void swd_clear_sticky_errors(struct adiv5_dap *dap) { const struct swd_driver *swd = adiv5_dap_swd_driver(dap); @@ -94,6 +103,79 @@ static int swd_run_inner(struct adiv5_dap *dap) return retval; } +static inline int check_sync(struct adiv5_dap *dap) +{ + return do_sync ? swd_run_inner(dap) : ERROR_OK; +} + +/** Select the DP register bank matching bits 7:4 of reg. */ +static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg) +{ + /* Only register address 4 is banked. */ + if ((reg & 0xf) != 4) + return ERROR_OK; + + uint32_t select_dp_bank = (reg & 0x000000F0) >> 4; + uint32_t sel = select_dp_bank + | (dap->select & (DP_SELECT_APSEL | DP_SELECT_APBANK)); + + if (sel == dap->select) + return ERROR_OK; + + dap->select = sel; + + int retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel); + if (retval != ERROR_OK) + dap->select = DP_SELECT_INVALID; + + return retval; +} + +static int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg, + uint32_t *data) +{ + const struct swd_driver *swd = adiv5_dap_swd_driver(dap); + assert(swd); + + int retval = swd_queue_dp_bankselect(dap, reg); + if (retval != ERROR_OK) + return retval; + + swd->read_reg(swd_cmd(true, false, reg), data, 0); + + return check_sync(dap); +} + +static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg, + uint32_t data) +{ + int retval; + const struct swd_driver *swd = adiv5_dap_swd_driver(dap); + assert(swd); + + swd_finish_read(dap); + + if (reg == DP_SELECT) { + dap->select = data & (DP_SELECT_APSEL | DP_SELECT_APBANK | DP_SELECT_DPBANK); + + swd->write_reg(swd_cmd(false, false, reg), data, 0); + + retval = check_sync(dap); + if (retval != ERROR_OK) + dap->select = DP_SELECT_INVALID; + + return retval; + } + + retval = swd_queue_dp_bankselect(dap, reg); + if (retval != ERROR_OK) + return retval; + + swd->write_reg(swd_cmd(false, false, reg), data, 0); + + return check_sync(dap); +} + static int swd_connect(struct adiv5_dap *dap) { const struct swd_driver *swd = adiv5_dap_swd_driver(dap); @@ -130,7 +212,7 @@ static int swd_connect(struct adiv5_dap *dap) dap->do_reconnect = false; dap_invalidate_cache(dap); - status = swd_queue_dp_read(dap, DP_DPIDR, &dpidr); + status = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr); if (status == ERROR_OK) { status = swd_run_inner(dap); if (status == ERROR_OK) @@ -186,19 +268,6 @@ static int swd_connect(struct adiv5_dap *dap) return status; } -static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq) -{ - const struct swd_driver *swd = adiv5_dap_swd_driver(dap); - assert(swd); - - return swd->switch_seq(seq); -} - -static inline int check_sync(struct adiv5_dap *dap) -{ - return do_sync ? swd_run_inner(dap) : ERROR_OK; -} - static int swd_check_reconnect(struct adiv5_dap *dap) { if (dap->do_reconnect) @@ -212,51 +281,19 @@ static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) const struct swd_driver *swd = adiv5_dap_swd_driver(dap); assert(swd); - swd->write_reg(swd_cmd(false, false, DP_ABORT), + swd->write_reg(swd_cmd(false, false, DP_ABORT), DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0); return check_sync(dap); } -/** Select the DP register bank matching bits 7:4 of reg. */ -static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned reg) -{ - /* Only register address 4 is banked. */ - if ((reg & 0xf) != 4) - return ERROR_OK; - - uint32_t select_dp_bank = (reg & 0x000000F0) >> 4; - uint32_t sel = select_dp_bank - | (dap->select & (DP_SELECT_APSEL | DP_SELECT_APBANK)); - - if (sel == dap->select) - return ERROR_OK; - - dap->select = sel; - - int retval = swd_queue_dp_write(dap, DP_SELECT, sel); - if (retval != ERROR_OK) - dap->select = DP_SELECT_INVALID; - - return retval; -} - static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data) { - const struct swd_driver *swd = adiv5_dap_swd_driver(dap); - assert(swd); - int retval = swd_check_reconnect(dap); if (retval != ERROR_OK) return retval; - retval = swd_queue_dp_bankselect(dap, reg); - if (retval != ERROR_OK) - return retval; - - swd->read_reg(swd_cmd(true, false, reg), data, 0); - - return check_sync(dap); + return swd_queue_dp_read_inner(dap, reg, data); } static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, @@ -269,26 +306,7 @@ static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) return retval; - swd_finish_read(dap); - if (reg == DP_SELECT) { - dap->select = data & (DP_SELECT_APSEL | DP_SELECT_APBANK | DP_SELECT_DPBANK); - - swd->write_reg(swd_cmd(false, false, reg), data, 0); - - retval = check_sync(dap); - if (retval != ERROR_OK) - dap->select = DP_SELECT_INVALID; - - return retval; - } - - retval = swd_queue_dp_bankselect(dap, reg); - if (retval != ERROR_OK) - return retval; - - swd->write_reg(swd_cmd(false, false, reg), data, 0); - - return check_sync(dap); + return swd_queue_dp_write_inner(dap, reg, data); } /** Select the AP register bank matching bits 7:4 of reg. */ @@ -304,7 +322,7 @@ static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg) dap->select = sel; - int retval = swd_queue_dp_write(dap, DP_SELECT, sel); + int retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel); if (retval != ERROR_OK) dap->select = DP_SELECT_INVALID; From bb78fa10c77411bbdf665c17eac954b7741f2040 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 15 Nov 2021 15:32:39 +0100 Subject: [PATCH 56/82] target/arm_dap: clean up dap_configure code dap_configure() contained first time init related tasks, as the call to dap_init_instance() and the check for configured tap. Move all first time init related stuff to dap_create() to make dap_configure() usable in eventual stand-alone 'dap configure' command. Change-Id: Ia86eadb4e960ce54e8581630d01af75720d2318d Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6702 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Matthias Welwarsky --- src/target/arm_dap.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 18e77b50f..0eb55a9cb 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -165,11 +165,10 @@ static const struct jim_nvp nvp_config_opts[] = { static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap) { - struct jtag_tap *tap = NULL; struct jim_nvp *n; int e; - /* parse config or cget options ... */ + /* parse config ... */ while (goi->argc > 0) { Jim_SetEmptyResult(goi->interp); @@ -184,11 +183,14 @@ static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap e = jim_getopt_obj(goi, &o_t); if (e != JIM_OK) return e; + + struct jtag_tap *tap; tap = jtag_tap_by_jim_obj(goi->interp, o_t); if (!tap) { Jim_SetResultString(goi->interp, "-chain-position is invalid", -1); return JIM_ERR; } + dap->dap.tap = tap; /* loop for more */ break; } @@ -200,14 +202,6 @@ static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap } } - if (!tap) { - Jim_SetResultString(goi->interp, "-chain-position required when creating DAP", -1); - return JIM_ERR; - } - - dap_instance_init(&dap->dap); - dap->dap.tap = tap; - return JIM_OK; } @@ -242,15 +236,21 @@ static int dap_create(struct jim_getopt_info *goi) if (!dap) return JIM_ERR; - e = dap_configure(goi, dap); - if (e != JIM_OK) { - free(dap); - return e; - } + dap_instance_init(&dap->dap); cp = Jim_GetString(new_cmd, NULL); dap->name = strdup(cp); + e = dap_configure(goi, dap); + if (e != JIM_OK) + goto err; + + if (!dap->dap.tap) { + Jim_SetResultString(goi->interp, "-chain-position required when creating DAP", -1); + e = JIM_ERR; + goto err; + } + struct command_registration dap_commands[] = { { .name = cp, @@ -268,14 +268,18 @@ static int dap_create(struct jim_getopt_info *goi) e = register_commands_with_data(cmd_ctx, NULL, dap_commands, dap); if (e != ERROR_OK) { - free(dap->name); - free(dap); - return JIM_ERR; + e = JIM_ERR; + goto err; } list_add_tail(&dap->lh, &all_dap); return JIM_OK; + +err: + free(dap->name); + free(dap); + return e; } static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) From b973a76d8663dec254084d0d86d93762a2873805 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 6 Apr 2021 13:59:14 +0200 Subject: [PATCH 57/82] target/arm_adi_v5,arm_dap: introduce multidrop_targetsel and its configuration Add multidrop_targetsel to struct adiv5_dap. Add option -dp-id and -instance-id to dap create command. Add convenience function dap_is_multidrop() Change-Id: Ibb93abb5f50b3665c320a10c1497421035762134 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6140 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 14 ++++++++++++ src/target/arm_adi_v5.h | 18 ++++++++++++++++ src/target/arm_dap.c | 48 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index a6da1675e..85dc432da 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4404,6 +4404,20 @@ A DAP may also provide optional @var{configparams}: register during initial examination and when checking the sticky error bit. This bit is normally checked after setting the CSYSPWRUPREQ bit, but some devices do not set the ack bit until sometime later. + +@item @code{-dp-id} @var{number} +@*Debug port identification number for SWD DPv2 multidrop. +The @var{number} is written to bits 0..27 of DP TARGETSEL during DP selection. +To find the id number of a single connected device read DP TARGETID: +@code{device.dap dpreg 0x24} +Use bits 0..27 of TARGETID. + +@item @code{-instance-id} @var{number} +@*Instance identification number for SWD DPv2 multidrop. +The @var{number} is written to bits 28..31 of DP TARGETSEL during DP selection. +To find the instance number of a single connected device read DP DLPIDR: +@code{device.dap dpreg 0x34} +The instance number is in bits 28..31 of DLPIDR value. @end itemize @end deffn diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index fa0a78a7e..1c96dc87a 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -97,6 +97,11 @@ #define DP_APSEL_MAX (255) #define DP_APSEL_INVALID (-1) +#define DP_TARGETSEL_INVALID 0xFFFFFFFFU +#define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU +#define DP_TARGETSEL_INSTANCEID_MASK 0xF0000000U +#define DP_TARGETSEL_INSTANCEID_SHIFT 28 + /* MEM-AP register addresses */ #define MEM_AP_REG_CSW 0x00 @@ -324,6 +329,13 @@ struct adiv5_dap { /** Flag saying whether to ignore the syspwrupack flag in DAP. Some devices * do not set this bit until later in the bringup sequence */ bool ignore_syspwrupack; + + /** Value to select DP in SWD multidrop mode or DP_TARGETSEL_INVALID */ + uint32_t multidrop_targetsel; + /** TPARTNO and TDESIGNER fields of multidrop_targetsel have been configured */ + bool multidrop_dp_id_valid; + /** TINSTANCE field of multidrop_targetsel has been configured */ + bool multidrop_instance_id_valid; }; /** @@ -610,6 +622,12 @@ static inline struct adiv5_ap *dap_ap(struct adiv5_dap *dap, uint8_t ap_num) return &dap->ap[ap_num]; } +/** Check if SWD multidrop configuration is valid */ +static inline bool dap_is_multidrop(struct adiv5_dap *dap) +{ + return dap->multidrop_dp_id_valid && dap->multidrop_instance_id_valid; +} + /* Lookup CoreSight component */ int dap_lookup_cs_component(struct adiv5_ap *ap, target_addr_t dbgbase, uint8_t type, target_addr_t *addr, int32_t *idx); diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 0eb55a9cb..bde1dfb5e 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -155,11 +155,15 @@ int dap_cleanup_all(void) enum dap_cfg_param { CFG_CHAIN_POSITION, CFG_IGNORE_SYSPWRUPACK, + CFG_DP_ID, + CFG_INSTANCE_ID, }; static const struct jim_nvp nvp_config_opts[] = { - { .name = "-chain-position", .value = CFG_CHAIN_POSITION }, + { .name = "-chain-position", .value = CFG_CHAIN_POSITION }, { .name = "-ignore-syspwrupack", .value = CFG_IGNORE_SYSPWRUPACK }, + { .name = "-dp-id", .value = CFG_DP_ID }, + { .name = "-instance-id", .value = CFG_INSTANCE_ID }, { .name = NULL, .value = -1 } }; @@ -197,6 +201,48 @@ static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap case CFG_IGNORE_SYSPWRUPACK: dap->dap.ignore_syspwrupack = true; break; + case CFG_DP_ID: { + jim_wide w; + e = jim_getopt_wide(goi, &w); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi->interp, + "create %s: bad parameter %s", + dap->name, n->name); + return JIM_ERR; + } + if (w < 0 || w > DP_TARGETSEL_DPID_MASK) { + Jim_SetResultFormatted(goi->interp, + "create %s: %s out of range", + dap->name, n->name); + return JIM_ERR; + } + dap->dap.multidrop_targetsel = + (dap->dap.multidrop_targetsel & DP_TARGETSEL_INSTANCEID_MASK) + | (w & DP_TARGETSEL_DPID_MASK); + dap->dap.multidrop_dp_id_valid = true; + break; + } + case CFG_INSTANCE_ID: { + jim_wide w; + e = jim_getopt_wide(goi, &w); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi->interp, + "create %s: bad parameter %s", + dap->name, n->name); + return JIM_ERR; + } + if (w < 0 || w > 15) { + Jim_SetResultFormatted(goi->interp, + "create %s: %s out of range", + dap->name, n->name); + return JIM_ERR; + } + dap->dap.multidrop_targetsel = + (dap->dap.multidrop_targetsel & DP_TARGETSEL_DPID_MASK) + | ((w << DP_TARGETSEL_INSTANCEID_SHIFT) & DP_TARGETSEL_INSTANCEID_MASK); + dap->dap.multidrop_instance_id_valid = true; + break; + } default: break; } From d2033997871f8561d1406550c12508461f63de48 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 6 Apr 2021 15:04:31 +0200 Subject: [PATCH 58/82] target/adi_v5_swd: add support for SWD multidrop Based on Graham Sanderson's http://review.openocd.org/4935 Unlike Graham Sanderson's version this patch does not add any multidrop specific queuing. Multidrop SWD is handled mostly by the same code as single SWD, just a selection sequence is prepended to a SWD operation as needed. This is a minimal working implementation without checking for configuration errors (mixing multidrop and non multidrop DPs, multiple use of the same selection id etc...). Multidrop switching likely demands changes in the adapter code. Change-Id: I99a5742c209b49c0483e800f6105cb5e59a897d9 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6141 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/adi_v5_swd.c | 293 ++++++++++++++++++++++++++++++++-------- src/target/arm_adi_v5.h | 6 + 2 files changed, 246 insertions(+), 53 deletions(-) diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 6e403e8b2..c23cee157 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -56,8 +56,9 @@ /* for debug, set do_sync to true to force synchronous transfers */ static bool do_sync; +static struct adiv5_dap *swd_multidrop_selected_dap; + -static int swd_run(struct adiv5_dap *dap); static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg, uint32_t data); @@ -176,17 +177,191 @@ static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg, return check_sync(dap); } + +static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr, + uint32_t *dlpidr_ptr, bool clear_sticky) +{ + int retval; + uint32_t dpidr, dlpidr; + + assert(dap_is_multidrop(dap)); + + swd_send_sequence(dap, LINE_RESET); + + retval = swd_queue_dp_write_inner(dap, DP_TARGETSEL, dap->multidrop_targetsel); + if (retval != ERROR_OK) + return retval; + + retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr); + if (retval != ERROR_OK) + return retval; + + if (clear_sticky) { + /* Clear all sticky errors (including ORUN) */ + swd_clear_sticky_errors(dap); + } else { + /* Ideally just clear ORUN flag which is set by reset */ + retval = swd_queue_dp_write_inner(dap, DP_ABORT, ORUNERRCLR); + if (retval != ERROR_OK) + return retval; + } + + retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr); + if (retval != ERROR_OK) + return retval; + + retval = swd_run_inner(dap); + if (retval != ERROR_OK) + return retval; + + if ((dpidr & DP_DPIDR_VERSION_MASK) < (2UL << DP_DPIDR_VERSION_SHIFT)) { + LOG_INFO("Read DPIDR 0x%08" PRIx32 + " has version < 2. A non multidrop capable device connected?", + dpidr); + return ERROR_FAIL; + } + + /* TODO: check TARGETID if DLIPDR is same for more than one DP */ + uint32_t expected_dlpidr = DP_DLPIDR_PROTVSN | + (dap->multidrop_targetsel & DP_TARGETSEL_INSTANCEID_MASK); + if (dlpidr != expected_dlpidr) { + LOG_INFO("Read incorrect DLPIDR 0x%08" PRIx32 + " (possibly CTRL/STAT value)", + dlpidr); + return ERROR_FAIL; + } + + LOG_DEBUG_IO("Selected DP_TARGETSEL 0x%08" PRIx32, dap->multidrop_targetsel); + swd_multidrop_selected_dap = dap; + + if (dpidr_ptr) + *dpidr_ptr = dpidr; + + if (dlpidr_ptr) + *dlpidr_ptr = dlpidr; + + return retval; +} + +static int swd_multidrop_select(struct adiv5_dap *dap) +{ + if (!dap_is_multidrop(dap)) + return ERROR_OK; + + if (swd_multidrop_selected_dap == dap) + return ERROR_OK; + + int retval = ERROR_OK; + for (unsigned int retry = 0; ; retry++) { + bool clear_sticky = retry > 0; + + retval = swd_multidrop_select_inner(dap, NULL, NULL, clear_sticky); + if (retval == ERROR_OK) + break; + + swd_multidrop_selected_dap = NULL; + if (retry > 3) { + LOG_ERROR("Failed to select multidrop %s", adiv5_dap_name(dap)); + return retval; + } + + LOG_DEBUG("Failed to select multidrop %s, retrying...", + adiv5_dap_name(dap)); + } + + return retval; +} + +static int swd_connect_multidrop(struct adiv5_dap *dap) +{ + int retval; + uint32_t dpidr = 0xdeadbeef; + uint32_t dlpidr = 0xdeadbeef; + int64_t timeout = timeval_ms() + 500; + + do { + swd_send_sequence(dap, JTAG_TO_DORMANT); + swd_send_sequence(dap, DORMANT_TO_SWD); + + /* Clear link state, including the SELECT cache. */ + dap->do_reconnect = false; + dap_invalidate_cache(dap); + swd_multidrop_selected_dap = NULL; + + retval = swd_multidrop_select_inner(dap, &dpidr, &dlpidr, true); + if (retval == ERROR_OK) + break; + + alive_sleep(1); + + } while (timeval_ms() < timeout); + + if (retval != ERROR_OK) { + swd_multidrop_selected_dap = NULL; + LOG_ERROR("Failed to connect multidrop %s", adiv5_dap_name(dap)); + return retval; + } + + LOG_INFO("SWD DPIDR 0x%08" PRIx32 ", DLPIDR 0x%08" PRIx32, + dpidr, dlpidr); + + return retval; +} + +static int swd_connect_single(struct adiv5_dap *dap) +{ + int retval; + uint32_t dpidr = 0xdeadbeef; + int64_t timeout = timeval_ms() + 500; + + do { + swd_send_sequence(dap, JTAG_TO_SWD); + + /* Clear link state, including the SELECT cache. */ + dap->do_reconnect = false; + dap_invalidate_cache(dap); + + retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr); + if (retval == ERROR_OK) { + retval = swd_run_inner(dap); + if (retval == ERROR_OK) + break; + } + + alive_sleep(1); + + } while (timeval_ms() < timeout); + + if (retval != ERROR_OK) { + LOG_ERROR("Error connecting DP: cannot read IDR"); + return retval; + } + + LOG_INFO("SWD DPIDR 0x%08" PRIx32, dpidr); + + do { + dap->do_reconnect = false; + + /* force clear all sticky faults */ + swd_clear_sticky_errors(dap); + + retval = swd_run_inner(dap); + if (retval != ERROR_WAIT) + break; + + alive_sleep(10); + + } while (timeval_ms() < timeout); + + return retval; +} + static int swd_connect(struct adiv5_dap *dap) { - const struct swd_driver *swd = adiv5_dap_swd_driver(dap); - uint32_t dpidr = 0xdeadbeef; int status; /* FIXME validate transport config ... is the * configured DAP present (check IDCODE)? - * Is *only* one DAP configured? - * - * MUST READ DPIDR */ /* Check if we should reset srst already when connecting, but not if reconnecting. */ @@ -201,48 +376,10 @@ static int swd_connect(struct adiv5_dap *dap) } } - - int64_t timeout = timeval_ms() + 500; - - do { - /* Note, debugport_init() does setup too */ - swd->switch_seq(JTAG_TO_SWD); - - /* Clear link state, including the SELECT cache. */ - dap->do_reconnect = false; - dap_invalidate_cache(dap); - - status = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr); - if (status == ERROR_OK) { - status = swd_run_inner(dap); - if (status == ERROR_OK) - break; - } - - alive_sleep(1); - - } while (timeval_ms() < timeout); - - if (status != ERROR_OK) { - LOG_ERROR("Error connecting DP: cannot read IDR"); - return status; - } - - LOG_INFO("SWD DPIDR %#8.8" PRIx32, dpidr); - - do { - dap->do_reconnect = false; - - /* force clear all sticky faults */ - swd_clear_sticky_errors(dap); - - status = swd_run_inner(dap); - if (status != ERROR_WAIT) - break; - - alive_sleep(10); - - } while (timeval_ms() < timeout); + if (dap_is_multidrop(dap)) + status = swd_connect_multidrop(dap); + else + status = swd_connect_single(dap); /* IHI 0031E B4.3.2: * "A WAIT response must not be issued to the ... @@ -257,9 +394,11 @@ static int swd_connect(struct adiv5_dap *dap) dap->do_reconnect = false; - swd->write_reg(swd_cmd(false, false, DP_ABORT), - DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0); - status = swd_run_inner(dap); + status = swd_queue_dp_write_inner(dap, DP_ABORT, + DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR); + + if (status == ERROR_OK) + status = swd_run_inner(dap); } if (status == ERROR_OK) @@ -281,6 +420,14 @@ static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) const struct swd_driver *swd = adiv5_dap_swd_driver(dap); assert(swd); + /* TODO: Send DAPABORT in swd_multidrop_select_inner() + * in the case the multidrop dap is not selected? + * swd_queue_ap_abort() is not currently used anyway... + */ + int retval = swd_multidrop_select(dap); + if (retval != ERROR_OK) + return retval; + swd->write_reg(swd_cmd(false, false, DP_ABORT), DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0); return check_sync(dap); @@ -293,6 +440,10 @@ static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) return retval; + retval = swd_multidrop_select(dap); + if (retval != ERROR_OK) + return retval; + return swd_queue_dp_read_inner(dap, reg, data); } @@ -306,6 +457,10 @@ static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) return retval; + retval = swd_multidrop_select(dap); + if (retval != ERROR_OK) + return retval; + return swd_queue_dp_write_inner(dap, reg, data); } @@ -340,6 +495,10 @@ static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg, if (retval != ERROR_OK) return retval; + retval = swd_multidrop_select(dap); + if (retval != ERROR_OK) + return retval; + retval = swd_queue_ap_bankselect(ap, reg); if (retval != ERROR_OK) return retval; @@ -361,7 +520,12 @@ static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg, if (retval != ERROR_OK) return retval; + retval = swd_multidrop_select(dap); + if (retval != ERROR_OK) + return retval; + swd_finish_read(dap); + retval = swd_queue_ap_bankselect(ap, reg); if (retval != ERROR_OK) return retval; @@ -374,7 +538,12 @@ static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg, /** Executes all queued DAP operations. */ static int swd_run(struct adiv5_dap *dap) { + int retval = swd_multidrop_select(dap); + if (retval != ERROR_OK) + return retval; + swd_finish_read(dap); + return swd_run_inner(dap); } @@ -382,9 +551,27 @@ static int swd_run(struct adiv5_dap *dap) static void swd_quit(struct adiv5_dap *dap) { const struct swd_driver *swd = adiv5_dap_swd_driver(dap); + static bool done; - swd->switch_seq(SWD_TO_JTAG); - /* flush the queue before exit */ + /* There is no difference if the sequence is sent at the last + * or the first swd_quit() call, send it just once */ + if (done) + return; + + done = true; + if (dap_is_multidrop(dap)) { + swd->switch_seq(SWD_TO_DORMANT); + /* Revisit! + * Leaving DPs in dormant state was tested and offers some safety + * against DPs mismatch in case of unintentional use of non-multidrop SWD. + * To put SWJ-DPs to power-on state issue + * swd->switch_seq(DORMANT_TO_JTAG); + */ + } else { + swd->switch_seq(SWD_TO_JTAG); + } + + /* flush the queue to shift out the sequence before exit */ swd->run(); } diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 1c96dc87a..758cfa096 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -65,6 +65,10 @@ #define DLCR_TO_TRN(dlcr) ((uint32_t)(1 + ((3 & (dlcr)) >> 8))) /* 1..4 clocks */ +/* Fields of DP_DPIDR register */ +#define DP_DPIDR_VERSION_SHIFT 12 +#define DP_DPIDR_VERSION_MASK (0xFUL << DP_DPIDR_VERSION_SHIFT) + /* Fields of the DP's AP ABORT register */ #define DAPABORT (1UL << 0) #define STKCMPCLR (1UL << 1) /* SWD-only */ @@ -89,6 +93,8 @@ #define CSYSPWRUPREQ (1UL << 30) #define CSYSPWRUPACK (1UL << 31) +#define DP_DLPIDR_PROTVSN 1u + #define DP_SELECT_APSEL 0xFF000000 #define DP_SELECT_APBANK 0x000000F0 #define DP_SELECT_DPBANK 0x0000000F From 8d9379c9bab8defe1ddb875352b432567d94f65b Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 6 Apr 2021 22:30:52 +0200 Subject: [PATCH 59/82] target/arm_dap: check SWD DAP configuration Raise error if * more than one plain SWD DAPs are defined * plain and multidrop DAPs are mixed * two multidrop DAPs have the same TARGETSEL value Inspired by Graham Sanderson's http://review.openocd.org/4935 Change-Id: I7279744464f5cc6477e50695c596be9c5e5507bf Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6142 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/arm_dap.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index bde1dfb5e..4728ce3bf 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -251,6 +251,52 @@ static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap return JIM_OK; } +static int dap_check_config(struct adiv5_dap *dap) +{ + if (transport_is_jtag() || transport_is_dapdirect_jtag() || transport_is_hla()) + return ERROR_OK; + + struct arm_dap_object *obj; + bool new_multidrop = dap_is_multidrop(dap); + bool had_multidrop = new_multidrop; + uint32_t targetsel = dap->multidrop_targetsel; + unsigned int non_multidrop_count = had_multidrop ? 0 : 1; + + list_for_each_entry(obj, &all_dap, lh) { + struct adiv5_dap *dap_it = &obj->dap; + + if (transport_is_swd()) { + if (dap_is_multidrop(dap_it)) { + had_multidrop = true; + if (new_multidrop && dap_it->multidrop_targetsel == targetsel) { + uint32_t dp_id = targetsel & DP_TARGETSEL_DPID_MASK; + uint32_t instance_id = targetsel >> DP_TARGETSEL_INSTANCEID_SHIFT; + LOG_ERROR("%s and %s have the same multidrop selectors -dp-id 0x%08" + PRIx32 " and -instance-id 0x%" PRIx32, + obj->name, adiv5_dap_name(dap), + dp_id, instance_id); + return ERROR_FAIL; + } + } else { + non_multidrop_count++; + } + } else if (transport_is_dapdirect_swd()) { + non_multidrop_count++; + } + } + + if (non_multidrop_count > 1) { + LOG_ERROR("Two or more SWD non multidrop DAPs are not supported"); + return ERROR_FAIL; + } + if (had_multidrop && non_multidrop_count) { + LOG_ERROR("Mixing of SWD multidrop DAPs and non multidrop DAPs is not supported"); + return ERROR_FAIL; + } + + return ERROR_OK; +} + static int dap_create(struct jim_getopt_info *goi) { struct command_context *cmd_ctx; @@ -297,6 +343,12 @@ static int dap_create(struct jim_getopt_info *goi) goto err; } + e = dap_check_config(&dap->dap); + if (e != ERROR_OK) { + e = JIM_ERR; + goto err; + } + struct command_registration dap_commands[] = { { .name = cp, From b5d1b719e5a4a248d99921ebfd1298dcb473d1c1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 9 Nov 2021 00:04:52 +0100 Subject: [PATCH 60/82] openocd: use single line for register_commands*() Do not split in multiple lines the calls to register_commands*(). No change in code behaviour, just make it easy to grep in the code and identify the commands that can be registered. This would help detecting undocumented commands. Change-Id: Id654e107cdabf7ee31fc3d227c1d2a59acc5669e Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6716 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nand/tcl.c | 3 +-- src/flash/nor/tcl.c | 3 +-- src/jtag/adapter.c | 3 +-- src/jtag/aice/aice_transport.c | 3 +-- src/jtag/hla/hla_transport.c | 6 ++---- src/pld/pld.c | 3 +-- src/target/etm.c | 3 +-- 7 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c index 6707314cc..b796fb7ce 100644 --- a/src/flash/nand/tcl.c +++ b/src/flash/nand/tcl.c @@ -528,8 +528,7 @@ static COMMAND_HELPER(create_nand_device, const char *bank_name, } if (controller->commands) { - retval = register_commands(CMD_CTX, NULL, - controller->commands); + retval = register_commands(CMD_CTX, NULL, controller->commands); if (retval != ERROR_OK) return retval; } diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 228e76fd0..b24191348 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -1284,8 +1284,7 @@ COMMAND_HANDLER(handle_flash_bank_command) /* register flash specific commands */ if (driver->commands) { - int retval = register_commands(CMD_CTX, NULL, - driver->commands); + int retval = register_commands(CMD_CTX, NULL, driver->commands); if (retval != ERROR_OK) { LOG_ERROR("couldn't register '%s' commands", driver_name); diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index c30019c17..65874590d 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -367,8 +367,7 @@ COMMAND_HANDLER(handle_adapter_driver_command) continue; if (adapter_drivers[i]->commands) { - retval = register_commands(CMD_CTX, NULL, - adapter_drivers[i]->commands); + retval = register_commands(CMD_CTX, NULL, adapter_drivers[i]->commands); if (retval != ERROR_OK) return retval; } diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c index 3e9d94219..c0088f5a4 100644 --- a/src/jtag/aice/aice_transport.c +++ b/src/jtag/aice/aice_transport.c @@ -387,8 +387,7 @@ static const struct command_registration aice_transport_command_handlers[] = { /* */ static int aice_transport_register_commands(struct command_context *cmd_ctx) { - return register_commands(cmd_ctx, NULL, - aice_transport_command_handlers); + return register_commands(cmd_ctx, NULL, aice_transport_command_handlers); } /* */ diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index d925b174a..684a52cb9 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -196,15 +196,13 @@ static int hl_jtag_transport_select(struct command_context *cmd_ctx) * That works with only C code ... no Tcl glue required. */ - return register_commands(cmd_ctx, NULL, - hl_jtag_transport_command_handlers); + return register_commands(cmd_ctx, NULL, hl_jtag_transport_command_handlers); } static int hl_swd_transport_select(struct command_context *cmd_ctx) { LOG_DEBUG("hl_swd_transport_select"); - return register_commands(cmd_ctx, NULL, - hl_swd_transport_command_handlers); + return register_commands(cmd_ctx, NULL, hl_swd_transport_command_handlers); } static struct transport hl_swd_transport = { diff --git a/src/pld/pld.c b/src/pld/pld.c index d0f85d74b..fe21f6c85 100644 --- a/src/pld/pld.c +++ b/src/pld/pld.c @@ -67,8 +67,7 @@ COMMAND_HANDLER(handle_pld_device_command) /* register pld specific commands */ int retval; if (pld_drivers[i]->commands) { - retval = register_commands(CMD_CTX, NULL, - pld_drivers[i]->commands); + retval = register_commands(CMD_CTX, NULL, pld_drivers[i]->commands); if (retval != ERROR_OK) { LOG_ERROR("couldn't register '%s' commands", CMD_ARGV[0]); return ERROR_FAIL; diff --git a/src/target/etm.c b/src/target/etm.c index e8bd20fef..119c0df5d 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -1416,8 +1416,7 @@ COMMAND_HANDLER(handle_etm_config_command) for (i = 0; etm_capture_drivers[i]; i++) { if (strcmp(CMD_ARGV[4], etm_capture_drivers[i]->name) == 0) { - int retval = register_commands(CMD_CTX, NULL, - etm_capture_drivers[i]->commands); + int retval = register_commands(CMD_CTX, NULL, etm_capture_drivers[i]->commands); if (retval != ERROR_OK) { free(etm_ctx); return retval; From b46cb18c91372bf32c0a946ce739884e4e42497c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 17 Nov 2021 22:15:20 +0100 Subject: [PATCH 61/82] openocd: use unique name for struct command_registration Just to avoid name clash when comparing documentation with registered commands through scripts. Change-Id: I8832545d8d9236ea5dabe6e73732f51e5246caff Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6717 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/flash/nor/stm32f1x.c | 8 ++++---- src/flash/nor/stm32f2x.c | 8 ++++---- src/flash/nor/stm32h7x.c | 8 ++++---- src/target/arm_dap.c | 6 +++--- src/target/hla_target.c | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 6744779e9..90cee6412 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -1545,7 +1545,7 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command) return retval; } -static const struct command_registration stm32x_exec_command_handlers[] = { +static const struct command_registration stm32f1x_exec_command_handlers[] = { { .name = "lock", .handler = stm32x_handle_lock_command, @@ -1593,20 +1593,20 @@ static const struct command_registration stm32x_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static const struct command_registration stm32x_command_handlers[] = { +static const struct command_registration stm32f1x_command_handlers[] = { { .name = "stm32f1x", .mode = COMMAND_ANY, .help = "stm32f1x flash command group", .usage = "", - .chain = stm32x_exec_command_handlers, + .chain = stm32f1x_exec_command_handlers, }, COMMAND_REGISTRATION_DONE }; const struct flash_driver stm32f1x_flash = { .name = "stm32f1x", - .commands = stm32x_command_handlers, + .commands = stm32f1x_command_handlers, .flash_bank_command = stm32x_flash_bank_command, .erase = stm32x_erase, .protect = stm32x_protect, diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index e80928ddf..d3e7d709c 100644 --- a/src/flash/nor/stm32f2x.c +++ b/src/flash/nor/stm32f2x.c @@ -1747,7 +1747,7 @@ COMMAND_HANDLER(stm32x_handle_otp_command) return retval; } -static const struct command_registration stm32x_exec_command_handlers[] = { +static const struct command_registration stm32f2x_exec_command_handlers[] = { { .name = "lock", .handler = stm32x_handle_lock_command, @@ -1800,20 +1800,20 @@ static const struct command_registration stm32x_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static const struct command_registration stm32x_command_handlers[] = { +static const struct command_registration stm32f2x_command_handlers[] = { { .name = "stm32f2x", .mode = COMMAND_ANY, .help = "stm32f2x flash command group", .usage = "", - .chain = stm32x_exec_command_handlers, + .chain = stm32f2x_exec_command_handlers, }, COMMAND_REGISTRATION_DONE }; const struct flash_driver stm32f2x_flash = { .name = "stm32f2x", - .commands = stm32x_command_handlers, + .commands = stm32f2x_command_handlers, .flash_bank_command = stm32x_flash_bank_command, .erase = stm32x_erase, .protect = stm32x_protect, diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index a3e304351..d3f17b2b1 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -1151,7 +1151,7 @@ COMMAND_HANDLER(stm32x_handle_option_write_command) return stm32x_modify_option(bank, reg_offset, value, mask); } -static const struct command_registration stm32x_exec_command_handlers[] = { +static const struct command_registration stm32h7x_exec_command_handlers[] = { { .name = "lock", .handler = stm32x_handle_lock_command, @@ -1190,20 +1190,20 @@ static const struct command_registration stm32x_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static const struct command_registration stm32x_command_handlers[] = { +static const struct command_registration stm32h7x_command_handlers[] = { { .name = "stm32h7x", .mode = COMMAND_ANY, .help = "stm32h7x flash command group", .usage = "", - .chain = stm32x_exec_command_handlers, + .chain = stm32h7x_exec_command_handlers, }, COMMAND_REGISTRATION_DONE }; const struct flash_driver stm32h7x_flash = { .name = "stm32h7x", - .commands = stm32x_command_handlers, + .commands = stm32h7x_command_handlers, .flash_bank_command = stm32x_flash_bank_command, .erase = stm32x_erase, .protect = stm32x_protect, diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 4728ce3bf..2dba45d0b 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -349,7 +349,7 @@ static int dap_create(struct jim_getopt_info *goi) goto err; } - struct command_registration dap_commands[] = { + struct command_registration dap_create_commands[] = { { .name = cp, .mode = COMMAND_ANY, @@ -362,9 +362,9 @@ static int dap_create(struct jim_getopt_info *goi) /* don't expose the instance commands when using hla */ if (transport_is_hla()) - dap_commands[0].chain = NULL; + dap_create_commands[0].chain = NULL; - e = register_commands_with_data(cmd_ctx, NULL, dap_commands, dap); + e = register_commands_with_data(cmd_ctx, NULL, dap_create_commands, dap); if (e != ERROR_OK) { e = JIM_ERR; goto err; diff --git a/src/target/hla_target.c b/src/target/hla_target.c index c67c9cc89..a0f2d7608 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -621,7 +621,7 @@ static int adapter_write_memory(struct target *target, target_addr_t address, return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer); } -static const struct command_registration adapter_command_handlers[] = { +static const struct command_registration hla_command_handlers[] = { { .chain = arm_command_handlers, }, @@ -647,7 +647,7 @@ struct target_type hla_target = { .target_create = adapter_target_create, .target_jim_configure = adiv5_jim_configure, .examine = cortex_m_examine, - .commands = adapter_command_handlers, + .commands = hla_command_handlers, .poll = adapter_poll, .arch_state = armv7m_arch_state, From 43ea974555de9a5bd9870a18f9f8423f1c476ea5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 17 Nov 2021 22:44:21 +0100 Subject: [PATCH 62/82] openocd: declare struct command_registration in a single line To simplify scripts to compare documentation and registered commands. Change-Id: I3bed5ba80ea8be1fd615697e80d66b42d7b45fd1 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6718 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/aice/aice_transport.c | 3 +-- src/jtag/hla/hla_transport.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c index c0088f5a4..2f2542e53 100644 --- a/src/jtag/aice/aice_transport.c +++ b/src/jtag/aice/aice_transport.c @@ -284,8 +284,7 @@ static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } /* */ -static const struct command_registration -aice_transport_jtag_subcommand_handlers[] = { +static const struct command_registration aice_transport_jtag_subcommand_handlers[] = { { .name = "init", .mode = COMMAND_ANY, diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index 684a52cb9..58dfe4b63 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -45,8 +45,7 @@ COMMAND_HANDLER(hl_transport_reset_command) return hl_interface_init_reset(); } -static const struct command_registration -hl_swd_transport_subcommand_handlers[] = { +static const struct command_registration hl_swd_transport_subcommand_handlers[] = { { .name = "newdap", .mode = COMMAND_CONFIG, @@ -67,8 +66,7 @@ static const struct command_registration hl_swd_transport_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static const struct command_registration -hl_transport_jtag_subcommand_handlers[] = { +static const struct command_registration hl_transport_jtag_subcommand_handlers[] = { { .name = "newtap", .mode = COMMAND_CONFIG, From facbb481b806275208baca30debfd66d54bc4f9b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 18 Nov 2021 00:25:37 +0100 Subject: [PATCH 63/82] flash/rp2040: don't initialize to NULL fields in struct When a struct is initialized, missing fields are already filled with zero or NULL. This change simplifies scripts to compare documentation and registered commands. Change-Id: I96fbdfa98bbb1f2b5e2a9532faf5a15cb5bc28dd Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6719 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/rp2040.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 5b4c16bb9..fb34172d2 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -441,7 +441,6 @@ FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command) struct flash_driver rp2040_flash = { .name = "rp2040_flash", - .commands = NULL, .flash_bank_command = rp2040_flash_bank_command, .erase = rp2040_flash_erase, .write = rp2040_flash_write, From cbfd0b9aad5e7693fffb5c88098712070b0efc71 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 18 Nov 2021 00:27:47 +0100 Subject: [PATCH 64/82] flash/psoc6: initialize usage field The missing initialization triggers a run-time error message: Error: BUG: command 'psoc6 reset_halt' does not have the '.usage' field filled out Change-Id: I975e4ba99bd939aa924a9d62b1ab76b2ab5bf193 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6720 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/psoc6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c index d3a4b3702..198dff5c8 100644 --- a/src/flash/nor/psoc6.c +++ b/src/flash/nor/psoc6.c @@ -1015,7 +1015,7 @@ static const struct command_registration psoc6_exec_command_handlers[] = { .name = "reset_halt", .handler = psoc6_handle_reset_halt, .mode = COMMAND_EXEC, - .usage = NULL, + .usage = "", .help = "Tries to simulate broken Vector Catch", }, COMMAND_REGISTRATION_DONE From cb97a4e82171dcf81fce8d012554b99344787836 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 18 Nov 2021 11:15:42 +0100 Subject: [PATCH 65/82] doc: remove non-existing command riscv set_scratch_ram The command was proposed in http://review.openocd.org/#/c/4578/2 and dropped in favor on existing work area commands. Nevertheless the command landed in documentation. Remove it! Change-Id: I6e18124256f29be15d8593c07d96f61d19e983f8 Signed-off-by: Antonio Borneo Fixes: a51ab8ddf63a ("Add RISC-V support.") Reviewed-on: https://review.openocd.org/c/openocd/+/6721 Tested-by: jenkins Reviewed-by: Jan Matyas --- doc/openocd.texi | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 85dc432da..40a3f2791 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -10199,11 +10199,6 @@ Set the maximum time to wait for a hart to come out of reset after reset is deasserted. @end deffn -@deffn {Command} {riscv set_scratch_ram} none|[address] -Set the address of 16 bytes of scratch RAM the debugger can use, or 'none'. -This is used to access 64-bit floating point registers on 32-bit targets. -@end deffn - @deffn {Command} {riscv set_prefer_sba} on|off When on, prefer to use System Bus Access to access memory. When off (default), prefer to use the Program Buffer to access memory. From 563a5f5d7837ebfa9421885f56380d34e11822c4 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 18 Nov 2021 11:30:08 +0100 Subject: [PATCH 66/82] doc: remove non-existing command swd wcr The commands has been dropped in commit 150b7d26f213 ("arm_adi_v5: Update DP (Debug Port) registers defined in ADIv5.2.") but the documentation still keeps it. Remove it! Change-Id: I4e88f481d943f064d919f8065562052244122bf0 Signed-off-by: Antonio Borneo Fixes: 150b7d26f213 ("arm_adi_v5: Update DP (Debug Port) registers defined in ADIv5.2.") Reviewed-on: https://review.openocd.org/c/openocd/+/6722 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 40a3f2791..33e1c0d99 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3471,11 +3471,6 @@ Declares a single DAP which uses SWD transport. Parameters are currently the same as "jtag newtap" but this is expected to change. @end deffn -@deffn {Command} {swd wcr trn prescale} -Updates TRN (turnaround delay) and prescaling.fields of the -Wire Control Register (WCR). -No parameters: displays current settings. -@end deffn @subsection SPI Transport @cindex SPI From 55159ea2e523989a8edcc930a4f01192131bb9d4 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 18 Nov 2021 11:45:15 +0100 Subject: [PATCH 67/82] doc: remove non-existing command readgroup The documentation included it in commit 4e79b48e2c7e ("Add new target type: OpenRISC"), but the command was never added. Remove it! Change-Id: Ice5fa1ee4086b5f5ceb942c3ce68bc9bbd75d19b Signed-off-by: Antonio Borneo Fixes: 4e79b48e2c7e ("Add new target type: OpenRISC") Reviewed-on: https://review.openocd.org/c/openocd/+/6723 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 8 -------- 1 file changed, 8 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 33e1c0d99..9ff2e2e52 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -10139,14 +10139,6 @@ included in the generated target descriptor file. addreg rtest 0x1234 org.gnu.gdb.or1k.group0 system @end example - -@end deffn -@deffn {Command} {readgroup} (@option{group}) -Display all registers in @emph{group}. - -@emph{group} can be "system", - "dmmu", "immu", "dcache", "icache", "mac", "debug", "perf", "power", "pic", - "timer" or any new group created with addreg command. @end deffn @section RISC-V Architecture From 4626af440122272a6c18ad293edc81d3051d83ec Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 18 Nov 2021 12:29:49 +0100 Subject: [PATCH 68/82] doc: fix typos in commands definition Change-Id: Ie07260f229c6bd227bae0bf3dd97d29bf84c72ec Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6725 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 9ff2e2e52..0ab4b36ac 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2833,7 +2833,7 @@ Reset the current configuration. @deffn {Command} {jlink config write} Write the current configuration to the internal persistent storage. @end deffn -@deffn {Command} {jlink emucom write } +@deffn {Command} {jlink emucom write} Write data to an EMUCOM channel. The data needs to be encoded as hexadecimal pairs. @@ -2843,7 +2843,7 @@ the EMUCOM channel 0x10: > jlink emucom write 0x10 aa0b23 @end example @end deffn -@deffn {Command} {jlink emucom read } +@deffn {Command} {jlink emucom read} Read data from an EMUCOM channel. The read data is encoded as hexadecimal pairs. @@ -7206,7 +7206,7 @@ as per the following example. flash bank $_FLASHNAME stm32f2x 0x1FFF7800 0 0 0 $_TARGETNAME @end example -@deffn {Command} {stm32f2x otp } num (@option{enable}|@option{disable}|@option{show}) +@deffn {Command} {stm32f2x otp} num (@option{enable}|@option{disable}|@option{show}) Enables or disables OTP write commands for bank @var{num}. The @var{num} parameter is a value shown by @command{flash banks}. @end deffn @@ -7643,7 +7643,7 @@ Some tms470-specific commands are defined: Saves programming keys in a register, to enable flash erase and write commands. @end deffn -@deffn {Command} {tms470 osc_mhz} clock_mhz +@deffn {Command} {tms470 osc_megahertz} clock_mhz Reports the clock speed, which is used to calculate timings. @end deffn @@ -8678,7 +8678,7 @@ If the control block location is not known, OpenOCD starts searching for it. Stop RTT. @end deffn -@deffn {Command} {rtt polling_interval [interval]} +@deffn {Command} {rtt polling_interval} [interval] Display the polling interval. If @var{interval} is provided, set the polling interval. The polling interval determines (in milliseconds) how often the up-channels are @@ -9026,7 +9026,7 @@ Enable (@option{on}) or disable (@option{off}) the CTI. Displays a register dump of the CTI. @end deffn -@deffn {Command} {$cti_name write } @var{reg_name} @var{value} +@deffn {Command} {$cti_name write} @var{reg_name} @var{value} Write @var{value} to the CTI register with the symbolic name @var{reg_name}. @end deffn @@ -9533,7 +9533,7 @@ cores @emph{except the ARM1176} use the same six bits. display information about target caches @end deffn -@deffn {Command} {cortex_a dacrfixup [@option{on}|@option{off}]} +@deffn {Command} {cortex_a dacrfixup} [@option{on}|@option{off}] Work around issues with software breakpoints when the program text is mapped read-only by the operating system. This option sets the CP15 DACR to "all-manager" to bypass MMU permission checks on memory access. @@ -9571,12 +9571,12 @@ possible (4096) entries are printed. @subsection ARMv7-R specific commands @cindex Cortex-R -@deffn {Command} {cortex_r dbginit} +@deffn {Command} {cortex_r4 dbginit} Initialize core debug Enables debug by unlocking the Software Lock and clearing sticky powerdown indications @end deffn -@deffn {Command} {cortex_r maskisr} [@option{on}|@option{off}] +@deffn {Command} {cortex_r4 maskisr} [@option{on}|@option{off}] Selects whether interrupts will be processed when single stepping @end deffn From f66a16c4a06fde23ae25f39c92990aa049c3c970 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 22 Nov 2021 13:50:01 +0100 Subject: [PATCH 69/82] target/hla_target: set cortex_m->common_magic hla_target uses the same struct cortex_m_common as the standard cortex_m target. Unlike the cortex_m target hla missed setting of common_magic. Set commont_magic to help pointer verification. Add convenience tests is_cortex_m_or_hla() and is_cortex_m_with_dap_access() Use proper test in cortex_m_verify_pointer() - this code relied on unset common_magic on hla target before the change. Change-Id: I4dae79f056c3d73adf524e26aa8ef2d3a57b471e Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/6741 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/cortex_m.c | 2 +- src/target/cortex_m.h | 13 +++++++++++++ src/target/hla_target.c | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 721cf0a24..649ee32f2 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2589,7 +2589,7 @@ static int cortex_m_target_create(struct target *target, Jim_Interp *interp) static int cortex_m_verify_pointer(struct command_invocation *cmd, struct cortex_m_common *cm) { - if (cm->common_magic != CORTEX_M_COMMON_MAGIC) { + if (!is_cortex_m_with_dap_access(cm)) { command_print(cmd, "target is not a Cortex-M"); return ERROR_TARGET_INVALID; } diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 57ef1e7e8..c2f836a35 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -254,6 +254,19 @@ target_to_cm(struct target *target) struct cortex_m_common, armv7m); } +static inline bool is_cortex_m_or_hla(const struct cortex_m_common *cortex_m) +{ + return cortex_m->common_magic == CORTEX_M_COMMON_MAGIC; +} + +static inline bool is_cortex_m_with_dap_access(const struct cortex_m_common *cortex_m) +{ + if (!is_cortex_m_or_hla(cortex_m)) + return false; + + return !cortex_m->armv7m.is_hla_target; +} + int cortex_m_examine(struct target *target); int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint); int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint); diff --git a/src/target/hla_target.c b/src/target/hla_target.c index a0f2d7608..3e359b950 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -214,6 +214,8 @@ static int adapter_target_create(struct target *target, return ERROR_FAIL; } + cortex_m->common_magic = CORTEX_M_COMMON_MAGIC; + adapter_init_arch_info(target, cortex_m, target->tap); return ERROR_OK; From 0343ae7cc734d8dfae17ff1ae9dbe834962f6da3 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 19:27:31 +0200 Subject: [PATCH 70/82] jtag/adapter: add command 'adapter serial' Several adapter define their own command to specify the USB serial number or serial string to be used during USB search. Define a general command 'adapter serial' to be proposed as replacement of the driver specific ones. No driver is changed so far to use it. Change-Id: I7631687a4163ccc63a9bdf3ad1fcb300fc483d3a Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6647 Reviewed-by: Tomas Vanek Tested-by: jenkins --- doc/openocd.texi | 8 ++++++++ src/jtag/adapter.c | 24 ++++++++++++++++++++++++ src/jtag/adapter.h | 3 +++ 3 files changed, 35 insertions(+) diff --git a/doc/openocd.texi b/doc/openocd.texi index 0ab4b36ac..286943643 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2367,6 +2367,14 @@ The USB bus topology can be queried with the command @emph{lsusb -t} or @emph{dm This command is only available if your libusb1 is at least version 1.0.16. @end deffn +@deffn {Config Command} {adapter serial} serial_string +Specifies the @var{serial_string} of the adapter to use. +If this command is not specified, serial strings are not checked. +No adapter uses this command, so far. +The following adapters have their own command to specify the serial string: +cmsis_dap, ft232r, ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. +@end deffn + @section Interface Drivers Each of the interface drivers listed here must be explicitly diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 65874590d..14452d42f 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -42,6 +42,7 @@ enum adapter_clk_mode { static struct { bool adapter_initialized; char *usb_location; + char *serial; enum adapter_clk_mode clock_mode; int speed_khz; int rclk_fallback_speed_khz; @@ -120,6 +121,7 @@ int adapter_quit(void) LOG_ERROR("failed: %d", result); } + free(adapter_config.serial); free(adapter_config.usb_location); struct jtag_tap *t = jtag_all_taps(); @@ -223,6 +225,11 @@ int adapter_get_speed_readable(int *khz) return adapter_driver->speed_div(speed_var, khz); } +const char *adapter_get_required_serial(void) +{ + return adapter_config.serial; +} + /* * 1 char: bus * 2 * 7 chars: max 7 ports @@ -659,6 +666,16 @@ COMMAND_HANDLER(handle_adapter_speed_command) return retval; } +COMMAND_HANDLER(handle_adapter_serial_command) +{ + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + free(adapter_config.serial); + adapter_config.serial = strdup(CMD_ARGV[0]); + return ERROR_OK; +} + COMMAND_HANDLER(handle_adapter_reset_de_assert) { enum values { @@ -806,6 +823,13 @@ static const struct command_registration adapter_command_handlers[] = { "With or without argument, display current setting.", .usage = "[khz]", }, + { + .name = "serial", + .handler = handle_adapter_serial_command, + .mode = COMMAND_CONFIG, + .help = "Set the serial number of the adapter", + .usage = "serial_string", + }, { .name = "list", .handler = handle_adapter_list_command, diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index 8b73c0c9e..300769c22 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -55,4 +55,7 @@ int adapter_config_rclk(unsigned int fallback_speed_khz); /** Retrieves the clock speed of the adapter in kHz. */ unsigned int adapter_get_speed_khz(void); +/** Retrieves the serial number set with command 'adapter serial' */ +const char *adapter_get_required_serial(void); + #endif /* OPENOCD_JTAG_ADAPTER_H */ From a3b69dee622066d3a2b70c32775818d82b5ffb54 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 19:34:27 +0200 Subject: [PATCH 71/82] jtag/aice: switch to command 'adapter serial' The driver aice defines the command 'aice serial' to specify the serial string of the adapter, but actually does not use this value in the code. Remove and deprecate the driver command, and use 'adapter serial'. Change-Id: I892e0a4e1b41a7a87adf54a5736abf7419f32979 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6648 Tested-by: jenkins --- src/jtag/aice/aice_interface.c | 22 ++-------------------- src/jtag/aice/aice_port.h | 2 -- src/jtag/startup.tcl | 6 ++++++ tcl/interface/nds32-aice.cfg | 2 +- 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c index c7556c018..cb126c6b1 100644 --- a/src/jtag/aice/aice_interface.c +++ b/src/jtag/aice/aice_interface.c @@ -20,6 +20,7 @@ #include "config.h" #endif +#include #include #include #include @@ -269,7 +270,7 @@ COMMAND_HANDLER(aice_handle_aice_info_command) LOG_DEBUG("aice_handle_aice_info_command"); command_print(CMD, "Description: %s", param.device_desc); - command_print(CMD, "Serial number: %s", param.serial); + command_print(CMD, "Serial number: %s", adapter_get_required_serial()); if (strncmp(aice_port->name, "aice_pipe", 9) == 0) command_print(CMD, "Adapter: %s", param.adapter_name); @@ -308,18 +309,6 @@ COMMAND_HANDLER(aice_handle_aice_desc_command) return ERROR_OK; } -COMMAND_HANDLER(aice_handle_aice_serial_command) -{ - LOG_DEBUG("aice_handle_aice_serial_command"); - - if (CMD_ARGC == 1) - param.serial = strdup(CMD_ARGV[0]); - else - LOG_ERROR("expected exactly one argument to aice serial "); - - return ERROR_OK; -} - COMMAND_HANDLER(aice_handle_aice_vid_pid_command) { LOG_DEBUG("aice_handle_aice_vid_pid_command"); @@ -438,13 +427,6 @@ static const struct command_registration aice_subcommand_handlers[] = { .help = "set the aice device description", .usage = "[description string]", }, - { - .name = "serial", - .handler = &aice_handle_aice_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the AICE device", - .usage = "[serial string]", - }, { .name = "vid_pid", .handler = &aice_handle_aice_vid_pid_command, diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h index d3d6a1a2c..159368888 100644 --- a/src/jtag/aice/aice_port.h +++ b/src/jtag/aice/aice_port.h @@ -107,8 +107,6 @@ struct aice_port_param_s { /** */ const char *device_desc; /** */ - const char *serial; - /** */ uint16_t vid; /** */ uint16_t pid; diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index d5b2ae221..b6c185ef2 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -735,4 +735,10 @@ proc ft232r_restore_serial args { eval ft232r restore_serial $args } +lappend _telnet_autocomplete_skip "aice serial" +proc "aice serial" {args} { + echo "DEPRECATED! use 'adapter serial' not 'aice serial'" + eval adapter serial $args +} + # END MIGRATION AIDS diff --git a/tcl/interface/nds32-aice.cfg b/tcl/interface/nds32-aice.cfg index 3b21025b5..fcc33ec28 100644 --- a/tcl/interface/nds32-aice.cfg +++ b/tcl/interface/nds32-aice.cfg @@ -6,7 +6,7 @@ adapter driver aice aice desc "Andes AICE adapter" -aice serial "C001-42163" +# adapter serial "C001-42163" aice vid_pid 0x1CFC 0x0000 aice port aice_usb reset_config trst_and_srst From 248161cbf47af9f7fc8c00b5efa79a1ff8e65848 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 19:42:54 +0200 Subject: [PATCH 72/82] jtag/cmsis_dap: switch to command 'adapter serial' The driver cmsis_dap defines the command 'cmsis_dap_serial' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Change-Id: I88e2d4de360a6c6f23529bb18494962a267250df Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6649 Tested-by: jenkins --- doc/openocd.texi | 10 +++------- src/jtag/drivers/cmsis_dap.c | 24 ++---------------------- src/jtag/drivers/cmsis_dap.h | 2 +- src/jtag/drivers/cmsis_dap_usb_bulk.c | 2 +- src/jtag/drivers/cmsis_dap_usb_hid.c | 2 +- src/jtag/startup.tcl | 6 ++++++ tcl/interface/cmsis-dap.cfg | 2 +- 7 files changed, 15 insertions(+), 33 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 286943643..4ce6e0426 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2370,9 +2370,10 @@ This command is only available if your libusb1 is at least version 1.0.16. @deffn {Config Command} {adapter serial} serial_string Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. -No adapter uses this command, so far. +Only the following adapter drivers use the serial string from this command: +cmsis_dap. The following adapters have their own command to specify the serial string: -cmsis_dap, ft232r, ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. +ft232r, ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. @end deffn @section Interface Drivers @@ -2427,11 +2428,6 @@ cmsis_dap_vid_pid 0xc251 0xf001 0x0d28 0x0204 @end example @end deffn -@deffn {Config Command} {cmsis_dap_serial} [serial] -Specifies the @var{serial} of the CMSIS-DAP device to use. -If not specified, serial numbers are not considered. -@end deffn - @deffn {Config Command} {cmsis_dap_backend} [@option{auto}|@option{usb_bulk}|@option{hid}] Specifies how to communicate with the adapter: diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index c0898fc30..e7562d087 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -76,7 +76,6 @@ static const struct cmsis_dap_backend *const cmsis_dap_backends[] = { /* vid = pid = 0 marks the end of the list */ static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 }; static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 }; -static char *cmsis_dap_serial; static int cmsis_dap_backend = -1; static bool swd_mode; @@ -289,13 +288,13 @@ static int cmsis_dap_open(void) if (cmsis_dap_backend >= 0) { /* Use forced backend */ backend = cmsis_dap_backends[cmsis_dap_backend]; - if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, cmsis_dap_serial) != ERROR_OK) + if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()) != ERROR_OK) backend = NULL; } else { /* Try all backends */ for (unsigned int i = 0; i < ARRAY_SIZE(cmsis_dap_backends); i++) { backend = cmsis_dap_backends[i]; - if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, cmsis_dap_serial) == ERROR_OK) + if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()) == ERROR_OK) break; else backend = NULL; @@ -325,8 +324,6 @@ static void cmsis_dap_close(struct cmsis_dap *dap) free(cmsis_dap_handle->packet_buffer); free(cmsis_dap_handle); cmsis_dap_handle = NULL; - free(cmsis_dap_serial); - cmsis_dap_serial = NULL; for (int i = 0; i < MAX_PENDING_REQUESTS; i++) { free(pending_fifo[i].transfers); @@ -2056,16 +2053,6 @@ COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command) return ERROR_OK; } -COMMAND_HANDLER(cmsis_dap_handle_serial_command) -{ - if (CMD_ARGC == 1) - cmsis_dap_serial = strdup(CMD_ARGV[0]); - else - LOG_ERROR("expected exactly one argument to cmsis_dap_serial "); - - return ERROR_OK; -} - COMMAND_HANDLER(cmsis_dap_handle_backend_command) { if (CMD_ARGC == 1) { @@ -2122,13 +2109,6 @@ static const struct command_registration cmsis_dap_command_handlers[] = { .help = "the vendor ID and product ID of the CMSIS-DAP device", .usage = "(vid pid)*", }, - { - .name = "cmsis_dap_serial", - .handler = &cmsis_dap_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the adapter", - .usage = "serial_string", - }, { .name = "cmsis_dap_backend", .handler = &cmsis_dap_handle_backend_command, diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h index f6d9df21b..7c64d492c 100644 --- a/src/jtag/drivers/cmsis_dap.h +++ b/src/jtag/drivers/cmsis_dap.h @@ -24,7 +24,7 @@ struct cmsis_dap { struct cmsis_dap_backend { const char *name; - int (*open)(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial); + int (*open)(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial); void (*close)(struct cmsis_dap *dap); int (*read)(struct cmsis_dap *dap, int timeout_ms); int (*write)(struct cmsis_dap *dap, int len, int timeout_ms); diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c index 26c6784f9..819596b21 100644 --- a/src/jtag/drivers/cmsis_dap_usb_bulk.c +++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c @@ -55,7 +55,7 @@ static int cmsis_dap_usb_interface = -1; static void cmsis_dap_usb_close(struct cmsis_dap *dap); static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz); -static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial) +static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial) { int err; struct libusb_context *ctx; diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c b/src/jtag/drivers/cmsis_dap_usb_hid.c index 5bb8ee8b1..912ba3972 100644 --- a/src/jtag/drivers/cmsis_dap_usb_hid.c +++ b/src/jtag/drivers/cmsis_dap_usb_hid.c @@ -48,7 +48,7 @@ struct cmsis_dap_backend_data { static void cmsis_dap_hid_close(struct cmsis_dap *dap); static int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz); -static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial) +static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial) { hid_device *dev = NULL; int i; diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index b6c185ef2..94030dbc5 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -741,4 +741,10 @@ proc "aice serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip cmsis_dap_serial +proc cmsis_dap_serial args { + echo "DEPRECATED! use 'adapter serial' not 'cmsis_dap_serial'" + eval adapter serial $args +} + # END MIGRATION AIDS diff --git a/tcl/interface/cmsis-dap.cfg b/tcl/interface/cmsis-dap.cfg index 887d2d713..1bc91a527 100644 --- a/tcl/interface/cmsis-dap.cfg +++ b/tcl/interface/cmsis-dap.cfg @@ -7,4 +7,4 @@ adapter driver cmsis-dap # Optionally specify the serial number of CMSIS-DAP usb device. -#cmsis_dap_serial 02200201E6661E601B98E3B9 +# adapter serial 02200201E6661E601B98E3B9 From 52b94977243b500b2f6c051710dc8d88fdab78a0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 22:25:27 +0200 Subject: [PATCH 73/82] jtag/ft232r: switch to command 'adapter serial' The driver ft232r defines the command 'ft232r serial_desc' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Change-Id: I0bd909923a668420604fed3c9f6a260716b044c7 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6650 Tested-by: jenkins --- doc/openocd.texi | 10 ++-------- src/jtag/drivers/ft232r.c | 20 ++------------------ src/jtag/startup.tcl | 10 ++++++++-- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 4ce6e0426..2891f3519 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,9 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap. +cmsis_dap, ft232r. The following adapters have their own command to specify the serial string: -ft232r, ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. +ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. @end deffn @section Interface Drivers @@ -2641,12 +2641,6 @@ The vendor ID and product ID of the adapter. If not specified, default 0x0403:0x6001 is used. @end deffn -@deffn {Config Command} {ft232r serial_desc} @var{serial} -Specifies the @var{serial} of the adapter to use, in case the -vendor provides unique IDs and more than one adapter is connected to -the host. If not specified, serial numbers are not considered. -@end deffn - @deffn {Config Command} {ft232r jtag_nums} @var{tck} @var{tms} @var{tdi} @var{tdo} Set four JTAG GPIO numbers at once. If not specified, default 0 3 1 2 or TXD CTS RXD RTS is used. diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 22c0fe5dd..fc3cdbae2 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -26,6 +26,7 @@ #endif /* project specific includes */ +#include #include #include #include @@ -68,7 +69,6 @@ #define FT232R_BUF_SIZE_EXTRA 4096 -static char *ft232r_serial_desc; static uint16_t ft232r_vid = 0x0403; /* FTDI */ static uint16_t ft232r_pid = 0x6001; /* FT232R */ static struct libusb_device_handle *adapter; @@ -257,6 +257,7 @@ static int ft232r_init(void) { uint16_t avids[] = {ft232r_vid, 0}; uint16_t apids[] = {ft232r_pid, 0}; + const char *ft232r_serial_desc = adapter_get_required_serial(); if (jtag_libusb_open(avids, apids, ft232r_serial_desc, &adapter, NULL)) { LOG_ERROR("ft232r not found: vid=%04x, pid=%04x, serial=%s\n", ft232r_vid, ft232r_pid, (!ft232r_serial_desc) ? "[any]" : ft232r_serial_desc); @@ -395,16 +396,6 @@ static int ft232r_bit_name_to_number(const char *name) return -1; } -COMMAND_HANDLER(ft232r_handle_serial_desc_command) -{ - if (CMD_ARGC == 1) - ft232r_serial_desc = strdup(CMD_ARGV[0]); - else - LOG_ERROR("require exactly one argument to " - "ft232r_serial_desc "); - return ERROR_OK; -} - COMMAND_HANDLER(ft232r_handle_vid_pid_command) { if (CMD_ARGC > 2) { @@ -561,13 +552,6 @@ COMMAND_HANDLER(ft232r_handle_restore_serial_command) } static const struct command_registration ft232r_subcommand_handlers[] = { - { - .name = "serial_desc", - .handler = ft232r_handle_serial_desc_command, - .mode = COMMAND_CONFIG, - .help = "USB serial descriptor of the adapter", - .usage = "serial string", - }, { .name = "vid_pid", .handler = ft232r_handle_vid_pid_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 94030dbc5..b5f4a0298 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -677,8 +677,8 @@ proc usb_blaster_firmware args { lappend _telnet_autocomplete_skip ft232r_serial_desc proc ft232r_serial_desc args { - echo "DEPRECATED! use 'ft232r serial_desc' not 'ft232r_serial_desc'" - eval ft232r serial_desc $args + echo "DEPRECATED! use 'adapter serial_desc' not 'ft232r_serial_desc'" + eval adapter serial_desc $args } lappend _telnet_autocomplete_skip ft232r_vid_pid @@ -747,4 +747,10 @@ proc cmsis_dap_serial args { eval adapter serial $args } +lappend _telnet_autocomplete_skip "ft232r serial_desc" +proc "ft232r serial_desc" {args} { + echo "DEPRECATED! use 'adapter serial' not 'ft232r serial_desc'" + eval adapter serial $args +} + # END MIGRATION AIDS From b1afd3dba4f046843d0c7c583c0b4ed56122d757 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 22:28:30 +0200 Subject: [PATCH 74/82] jtag/ftdi: switch to command 'adapter serial' The driver ftdi defines the command 'ftdi serial' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Change-Id: Ia5b1f325b9fab8f58b5ea70f8b807e50b148b939 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6651 Tested-by: jenkins --- doc/openocd.texi | 13 ++----------- src/jtag/drivers/ftdi.c | 23 +---------------------- src/jtag/startup.tcl | 10 ++++++++-- tcl/interface/ftdi/flossjtag.cfg | 2 +- 4 files changed, 12 insertions(+), 36 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 2891f3519..5b9d65047 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,9 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r. +cmsis_dap, ft232r, ftdi. The following adapters have their own command to specify the serial string: -ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. +hla, jlink, kitprog, presto, st-link, vsllink, xds110. @end deffn @section Interface Drivers @@ -2512,15 +2512,6 @@ of the adapter. If not specified, the device description is ignored during device selection. @end deffn -@deffn {Config Command} {ftdi serial} serial-number -Specifies the @var{serial-number} of the adapter to use, -in case the vendor provides unique IDs and more than one adapter -is connected to the host. -If not specified, serial numbers are not considered. -(Note that USB serial numbers can be arbitrary Unicode strings, -and are not restricted to containing only decimal digits.) -@end deffn - @deffn {Config Command} {ftdi channel} channel Selects the channel of the FTDI device to use for MPSSE operations. Most adapters use the default, channel 0, but there are exceptions. diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 8366774bc..7671cee5d 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -90,7 +90,6 @@ #define SWD_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT) static char *ftdi_device_desc; -static char *ftdi_serial; static uint8_t ftdi_channel; static uint8_t ftdi_jtag_mode = JTAG_MODE; @@ -672,7 +671,7 @@ static int ftdi_initialize(void) for (int i = 0; ftdi_vid[i] || ftdi_pid[i]; i++) { mpsse_ctx = mpsse_open(&ftdi_vid[i], &ftdi_pid[i], ftdi_device_desc, - ftdi_serial, adapter_usb_get_location(), ftdi_channel); + adapter_get_required_serial(), adapter_usb_get_location(), ftdi_channel); if (mpsse_ctx) break; } @@ -717,7 +716,6 @@ static int ftdi_quit(void) } free(ftdi_device_desc); - free(ftdi_serial); free(swd_cmd_queue); @@ -736,18 +734,6 @@ COMMAND_HANDLER(ftdi_handle_device_desc_command) return ERROR_OK; } -COMMAND_HANDLER(ftdi_handle_serial_command) -{ - if (CMD_ARGC == 1) { - free(ftdi_serial); - ftdi_serial = strdup(CMD_ARGV[0]); - } else { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - COMMAND_HANDLER(ftdi_handle_channel_command) { if (CMD_ARGC == 1) @@ -955,13 +941,6 @@ static const struct command_registration ftdi_subcommand_handlers[] = { .help = "set the USB device description of the FTDI device", .usage = "description_string", }, - { - .name = "serial", - .handler = &ftdi_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the FTDI device", - .usage = "serial_string", - }, { .name = "channel", .handler = &ftdi_handle_channel_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index b5f4a0298..b21ddc646 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -215,8 +215,8 @@ proc ftdi_device_desc args { lappend _telnet_autocomplete_skip ftdi_serial proc ftdi_serial args { - echo "DEPRECATED! use 'ftdi serial' not 'ftdi_serial'" - eval ftdi serial $args + echo "DEPRECATED! use 'adapter serial' not 'ftdi_serial'" + eval adapter serial $args } lappend _telnet_autocomplete_skip ftdi_channel @@ -753,4 +753,10 @@ proc "ft232r serial_desc" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip "ftdi serial" +proc "ftdi serial" {args} { + echo "DEPRECATED! use 'adapter serial' not 'ftdi serial'" + eval adapter serial $args +} + # END MIGRATION AIDS diff --git a/tcl/interface/ftdi/flossjtag.cfg b/tcl/interface/ftdi/flossjtag.cfg index 2e3cfca48..c1506a2e9 100644 --- a/tcl/interface/ftdi/flossjtag.cfg +++ b/tcl/interface/ftdi/flossjtag.cfg @@ -20,7 +20,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi vid_pid 0x0403 0x6010 ftdi device_desc "FLOSS-JTAG" -#ftdi serial "FJ000001" +# adapter serial "FJ000001" ftdi layout_init 0x0008 0x180b ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 From d7b2313b5aec47e6a4a450fdf625644ca60d633d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 22:31:27 +0200 Subject: [PATCH 75/82] jtag/kitprog: switch to command 'adapter serial' The driver kitprog defines the command 'kitprog_serial' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Change-Id: I844cb815af01137392b6d12e1b5972fc77ac092d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6652 Reviewed-by: Tomas Vanek Tested-by: jenkins --- doc/openocd.texi | 9 ++------- src/jtag/drivers/kitprog.c | 28 ++-------------------------- src/jtag/startup.tcl | 6 ++++++ tcl/interface/kitprog.cfg | 2 +- 4 files changed, 11 insertions(+), 34 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 5b9d65047..c36047f07 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,9 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r, ftdi. +cmsis_dap, ft232r, ftdi, kitprog. The following adapters have their own command to specify the serial string: -hla, jlink, kitprog, presto, st-link, vsllink, xds110. +hla, jlink, presto, st-link, vsllink, xds110. @end deffn @section Interface Drivers @@ -2896,11 +2896,6 @@ Indicate that a PSoC acquisition sequence needs to be run during adapter init. Please be aware that the acquisition sequence hard-resets the target. @end deffn -@deffn {Config Command} {kitprog_serial} serial -Select a KitProg device by its @var{serial}. If left unspecified, the first -device detected by OpenOCD will be used. -@end deffn - @deffn {Command} {kitprog acquire_psoc} Run a PSoC acquisition sequence immediately. Typically, this should not be used outside of the target-specific configuration scripts since it hard-resets the diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 327bb572d..0c5ccc6a7 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -114,7 +115,6 @@ struct pending_transfer_result { void *buffer; }; -static char *kitprog_serial; static bool kitprog_init_acquire_psoc; static int pending_transfer_count, pending_queue_len; @@ -230,7 +230,6 @@ static int kitprog_quit(void) free(kitprog_handle->packet_buffer); free(kitprog_handle->serial); free(kitprog_handle); - free(kitprog_serial); free(pending_transfers); return ERROR_OK; @@ -272,7 +271,7 @@ static int kitprog_usb_open(void) const uint16_t vids[] = { VID, 0 }; const uint16_t pids[] = { PID, 0 }; - if (jtag_libusb_open(vids, pids, kitprog_serial, + if (jtag_libusb_open(vids, pids, adapter_get_required_serial(), &kitprog_handle->usb_handle, NULL) != ERROR_OK) { LOG_ERROR("Failed to open or find the device"); return ERROR_FAIL; @@ -851,22 +850,6 @@ COMMAND_HANDLER(kitprog_handle_acquire_psoc_command) return retval; } -COMMAND_HANDLER(kitprog_handle_serial_command) -{ - if (CMD_ARGC == 1) { - kitprog_serial = strdup(CMD_ARGV[0]); - if (!kitprog_serial) { - LOG_ERROR("Failed to allocate memory for the serial number"); - return ERROR_FAIL; - } - } else { - LOG_ERROR("expected exactly one argument to kitprog_serial "); - return ERROR_FAIL; - } - - return ERROR_OK; -} - COMMAND_HANDLER(kitprog_handle_init_acquire_psoc_command) { kitprog_init_acquire_psoc = true; @@ -900,13 +883,6 @@ static const struct command_registration kitprog_command_handlers[] = { .usage = "", .chain = kitprog_subcommand_handlers, }, - { - .name = "kitprog_serial", - .handler = &kitprog_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the adapter", - .usage = "serial_string", - }, { .name = "kitprog_init_acquire_psoc", .handler = &kitprog_handle_init_acquire_psoc_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index b21ddc646..75b1bfbdf 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -759,4 +759,10 @@ proc "ftdi serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip kitprog_serial +proc kitprog_serial args { + echo "DEPRECATED! use 'adapter serial' not 'kitprog_serial'" + eval adapter serial $args +} + # END MIGRATION AIDS diff --git a/tcl/interface/kitprog.cfg b/tcl/interface/kitprog.cfg index 29fce489b..933a05408 100644 --- a/tcl/interface/kitprog.cfg +++ b/tcl/interface/kitprog.cfg @@ -9,4 +9,4 @@ adapter driver kitprog # Optionally specify the serial number of the KitProg you want to use. -#kitprog_serial 1926402735485200 +# adapter serial 1926402735485200 From c41d9f61907464add62bf9d6647a1dcd6a77cc0e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 22:35:12 +0200 Subject: [PATCH 76/82] jtag/presto: switch to command 'adapter serial' The driver presto defines the command 'presto serial' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Change-Id: I1a69acce7d4910082d2029d5941ae84f9424314c Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6653 Tested-by: jenkins --- doc/openocd.texi | 7 ++---- src/jtag/drivers/presto.c | 47 +++++---------------------------------- src/jtag/startup.tcl | 6 +++++ 3 files changed, 13 insertions(+), 47 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index c36047f07..1e2524c7e 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,9 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r, ftdi, kitprog. +cmsis_dap, ft232r, ftdi, kitprog, presto. The following adapters have their own command to specify the serial string: -hla, jlink, presto, st-link, vsllink, xds110. +hla, jlink, st-link, vsllink, xds110. @end deffn @section Interface Drivers @@ -3010,9 +3010,6 @@ parport cable wiggler @deffn {Interface Driver} {presto} ASIX PRESTO USB JTAG programmer. -@deffn {Config Command} {presto serial} serial_string -Configures the USB serial number of the Presto device to use. -@end deffn @end deffn @deffn {Interface Driver} {rlink} diff --git a/src/jtag/drivers/presto.c b/src/jtag/drivers/presto.c index 61de42630..e938a3be3 100644 --- a/src/jtag/drivers/presto.c +++ b/src/jtag/drivers/presto.c @@ -29,6 +29,7 @@ #include "windows.h" #endif +#include #include #include #include "bitq.h" @@ -132,7 +133,7 @@ static int presto_read(uint8_t *buf, uint32_t size) return ERROR_OK; } -static int presto_open_libftdi(char *req_serial) +static int presto_open_libftdi(const char *req_serial) { uint8_t presto_data; @@ -195,7 +196,7 @@ static int presto_open_libftdi(char *req_serial) return ERROR_OK; } -static int presto_open(char *req_serial) +static int presto_open(const char *req_serial) { presto->buff_out_pos = 0; presto->buff_in_pos = 0; @@ -506,43 +507,10 @@ static int presto_jtag_speed(int speed) return 0; } -static char *presto_serial; - -COMMAND_HANDLER(presto_handle_serial_command) -{ - if (CMD_ARGC == 1) { - free(presto_serial); - presto_serial = strdup(CMD_ARGV[0]); - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - -static const struct command_registration presto_subcommand_handlers[] = { - { - .name = "serial", - .handler = presto_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "Configure USB serial number of Presto device.", - .usage = "serial_string", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration presto_command_handlers[] = { - { - .name = "presto", - .mode = COMMAND_ANY, - .help = "perform presto management", - .chain = presto_subcommand_handlers, - .usage = "", - }, - COMMAND_REGISTRATION_DONE -}; - static int presto_jtag_init(void) { + const char *presto_serial = adapter_get_required_serial(); + if (presto_open(presto_serial) != ERROR_OK) { presto_close(); if (presto_serial) @@ -562,10 +530,6 @@ static int presto_jtag_quit(void) bitq_cleanup(); presto_close(); LOG_INFO("PRESTO closed"); - - free(presto_serial); - presto_serial = NULL; - return ERROR_OK; } @@ -576,7 +540,6 @@ static struct jtag_interface presto_interface = { struct adapter_driver presto_adapter_driver = { .name = "presto", .transports = jtag_only, - .commands = presto_command_handlers, .init = presto_jtag_init, .quit = presto_jtag_quit, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 75b1bfbdf..b8b866fbe 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -765,4 +765,10 @@ proc kitprog_serial args { eval adapter serial $args } +lappend _telnet_autocomplete_skip "presto serial" +proc "presto serial" {args} { + echo "DEPRECATED! use 'adapter serial' not 'presto serial'" + eval adapter serial $args +} + # END MIGRATION AIDS From 271e5416af975b52d4cd0e2ced65a4cbda9d041f Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 22:39:45 +0200 Subject: [PATCH 77/82] jtag/vsllink: switch to command 'adapter serial' The driver vsllink defines the command 'vsllink usb_serial' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Change-Id: Iadcc018b8aa8974ccd7156915b84e58270fad29d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6654 Reviewed-by: Tomas Vanek Tested-by: jenkins --- doc/openocd.texi | 4 ++-- src/jtag/drivers/versaloon/versaloon.c | 1 - src/jtag/drivers/versaloon/versaloon.h | 2 -- src/jtag/drivers/vsllink.c | 26 ++------------------------ src/jtag/startup.tcl | 10 ++++++++-- 5 files changed, 12 insertions(+), 31 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 1e2524c7e..c76fc076c 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,9 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r, ftdi, kitprog, presto. +cmsis_dap, ft232r, ftdi, kitprog, presto, vsllink. The following adapters have their own command to specify the serial string: -hla, jlink, st-link, vsllink, xds110. +hla, jlink, st-link, xds110. @end deffn @section Interface Drivers diff --git a/src/jtag/drivers/versaloon/versaloon.c b/src/jtag/drivers/versaloon/versaloon.c index b17c1d49b..7c2efefaa 100644 --- a/src/jtag/drivers/versaloon/versaloon.c +++ b/src/jtag/drivers/versaloon/versaloon.c @@ -87,7 +87,6 @@ struct versaloon_interface_t versaloon_interface = { .ep_out = VERSALOON_OUTP, .ep_in = VERSALOON_INP, .interface = VERSALOON_IFACE, - .serialstring = NULL, .buf_size = 256, } }; diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h index 22e73fb35..e4aafb250 100644 --- a/src/jtag/drivers/versaloon/versaloon.h +++ b/src/jtag/drivers/versaloon/versaloon.h @@ -94,8 +94,6 @@ struct versaloon_usb_setting_t { uint8_t ep_out; uint8_t ep_in; uint8_t interface; - char *serialstring; - uint16_t buf_size; }; diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index 9cec2bea7..f59a7033e 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -499,21 +499,6 @@ COMMAND_HANDLER(vsllink_handle_usb_pid_command) return ERROR_OK; } -COMMAND_HANDLER(vsllink_handle_usb_serial_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - free(versaloon_interface.usb_setting.serialstring); - - if (CMD_ARGC == 1) - versaloon_interface.usb_setting.serialstring = strdup(CMD_ARGV[0]); - else - versaloon_interface.usb_setting.serialstring = NULL; - - return ERROR_OK; -} - COMMAND_HANDLER(vsllink_handle_usb_bulkin_command) { if (CMD_ARGC != 1) @@ -786,14 +771,14 @@ static int vsllink_check_usb_strings( char desc_string[256]; int retval; - if (versaloon_interface.usb_setting.serialstring) { + if (adapter_get_required_serial()) { retval = libusb_get_string_descriptor_ascii(usb_device_handle, usb_desc->iSerialNumber, (unsigned char *)desc_string, sizeof(desc_string)); if (retval < 0) return ERROR_FAIL; - if (strncmp(desc_string, versaloon_interface.usb_setting.serialstring, + if (strncmp(desc_string, adapter_get_required_serial(), sizeof(desc_string))) return ERROR_FAIL; } @@ -903,13 +888,6 @@ static const struct command_registration vsllink_subcommand_handlers[] = { .help = "Set USB PID", .usage = "", }, - { - .name = "usb_serial", - .handler = &vsllink_handle_usb_serial_command, - .mode = COMMAND_CONFIG, - .help = "Set or disable check for USB serial", - .usage = "[]", - }, { .name = "usb_bulkin", .handler = &vsllink_handle_usb_bulkin_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index b8b866fbe..95fe55ca7 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -371,8 +371,8 @@ proc vsllink_usb_pid args { lappend _telnet_autocomplete_skip vsllink_usb_serial proc vsllink_usb_serial args { - echo "DEPRECATED! use 'vsllink usb_serial' not 'vsllink_usb_serial'" - eval vsllink usb_serial $args + echo "DEPRECATED! use 'adapter serial' not 'vsllink_usb_serial'" + eval adapter serial $args } lappend _telnet_autocomplete_skip vsllink_usb_bulkin @@ -771,4 +771,10 @@ proc "presto serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip "vsllink usb_serial" +proc "vsllink usb_serial" {args} { + echo "DEPRECATED! use 'adapter serial' not 'vsllink usb_serial'" + eval adapter serial $args +} + # END MIGRATION AIDS From 61a2f3284b984abee0ffd1166ecd79a0ea82976e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 7 Oct 2021 23:03:23 +0200 Subject: [PATCH 78/82] jtag/xds110: switch to command 'adapter serial' The driver xds110 defines the command 'xds110 serial' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Note: the original command 'xds110 serial' used a complex and undocumented conversion of the serial number through multibyte string, wide-character string and C cast. The XDS110 I can access and the lsusb dumps available through Google don't show any exotic USB serial that require such conversion. The original developer doesn't remember any constraint that mandates such conversion (see comments in https://review.openocd.org/4322/). The conversion is removed by this patch. Change-Id: I38909918079b2c1797ad85ebec2fea1b33743606 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6655 Reviewed-by: Tomas Vanek Tested-by: jenkins --- doc/openocd.texi | 9 ++----- src/jtag/drivers/xds110.c | 50 ++++----------------------------------- src/jtag/startup.tcl | 10 ++++++-- tcl/interface/xds110.cfg | 2 +- 4 files changed, 16 insertions(+), 55 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index c76fc076c..78451c71c 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,9 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r, ftdi, kitprog, presto, vsllink. +cmsis_dap, ft232r, ftdi, kitprog, presto, vsllink, xds110. The following adapters have their own command to specify the serial string: -hla, jlink, st-link, xds110. +hla, jlink, st-link. @end deffn @section Interface Drivers @@ -3141,11 +3141,6 @@ LaunchPad evaluation boards. The XDS110 is also available as a stand-alone USB debug probe with the added capability to supply power to the target board. The following commands are supported by the XDS110 driver: -@deffn {Config Command} {xds110 serial} serial_string -Specifies the serial number of which XDS110 probe to use. Otherwise, the first -XDS110 found will be used. -@end deffn - @deffn {Config Command} {xds110 supply} voltage_in_millivolts Available only on the XDS110 stand-alone probe. Sets the voltage level of the XDS110 power supply. A value of 0 leaves the supply off. Otherwise, the supply diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 243577d7c..c5249b296 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -20,15 +20,13 @@ #endif #include +#include #include #include #include #include #include -/* XDS110 USB serial number length */ -#define XDS110_SERIAL_LEN 8 - /* XDS110 stand-alone probe voltage supply limits */ #define XDS110_MIN_VOLTAGE 1800 #define XDS110_MAX_VOLTAGE 3600 @@ -238,8 +236,6 @@ struct xds110_info { /* TCK speed and delay count*/ uint32_t speed; uint32_t delay_count; - /* XDS110 serial number */ - char serial[XDS110_SERIAL_LEN + 1]; /* XDS110 voltage supply setting */ uint32_t voltage; /* XDS110 firmware and hardware version */ @@ -269,7 +265,6 @@ static struct xds110_info xds110 = { .is_ap_dirty = false, .speed = XDS110_DEFAULT_TCK_SPEED, .delay_count = 0, - .serial = {0}, .voltage = 0, .firmware = 0, .hardware = 0, @@ -371,7 +366,7 @@ static bool usb_connect(void) *data = '\0'; /* May be the requested device if serial number matches */ - if (xds110.serial[0] == 0) { + if (!adapter_get_required_serial()) { /* No serial number given; match first XDS110 found */ found = true; break; @@ -380,7 +375,7 @@ static bool usb_connect(void) result = libusb_get_string_descriptor_ascii(dev, desc.iSerialNumber, data, max_data); if (result > 0 && - strcmp((char *)data, (char *)xds110.serial) == 0) { + strcmp((char *)data, adapter_get_required_serial()) == 0) { found = true; break; } @@ -1395,8 +1390,8 @@ static void xds110_show_info(void) (((firmware >> 12) & 0xf) * 10) + ((firmware >> 8) & 0xf), (((firmware >> 4) & 0xf) * 10) + ((firmware >> 0) & 0xf)); LOG_INFO("XDS110: hardware version = 0x%04x", xds110.hardware); - if (xds110.serial[0] != 0) - LOG_INFO("XDS110: serial number = %s", xds110.serial); + if (adapter_get_required_serial()) + LOG_INFO("XDS110: serial number = %s", adapter_get_required_serial()); if (xds110.is_swd_mode) { LOG_INFO("XDS110: connected to target via SWD"); LOG_INFO("XDS110: SWCLK set to %" PRIu32 " kHz", xds110.speed); @@ -2024,34 +2019,6 @@ COMMAND_HANDLER(xds110_handle_info_command) return ERROR_OK; } -COMMAND_HANDLER(xds110_handle_serial_command) -{ - wchar_t serial[XDS110_SERIAL_LEN + 1]; - - xds110.serial[0] = 0; - - if (CMD_ARGC == 1) { - size_t len = mbstowcs(0, CMD_ARGV[0], 0); - if (len > XDS110_SERIAL_LEN) { - LOG_ERROR("XDS110: serial number is limited to %d characters", - XDS110_SERIAL_LEN); - return ERROR_FAIL; - } - if ((size_t)-1 == mbstowcs(serial, CMD_ARGV[0], len + 1)) { - LOG_ERROR("XDS110: unable to convert serial number"); - return ERROR_FAIL; - } - - for (uint32_t i = 0; i < len; i++) - xds110.serial[i] = (char)serial[i]; - - xds110.serial[len] = 0; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - COMMAND_HANDLER(xds110_handle_supply_voltage_command) { uint32_t voltage = 0; @@ -2082,13 +2049,6 @@ static const struct command_registration xds110_subcommand_handlers[] = { .help = "show XDS110 info", .usage = "", }, - { - .name = "serial", - .handler = &xds110_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the XDS110 probe serial number", - .usage = "serial_string", - }, { .name = "supply", .handler = &xds110_handle_supply_voltage_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 95fe55ca7..d6c3b85b4 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -187,8 +187,8 @@ proc ftdi_location args { lappend _telnet_autocomplete_skip xds110_serial proc xds110_serial args { - echo "DEPRECATED! use 'xds110 serial' not 'xds110_serial'" - eval xds110 serial $args + echo "DEPRECATED! use 'adapter serial' not 'xds110_serial'" + eval adapter serial $args } lappend _telnet_autocomplete_skip xds110_supply_voltage @@ -777,4 +777,10 @@ proc "vsllink usb_serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip "xds110 serial" +proc "xds110 serial" {args} { + echo "DEPRECATED! use 'adapter serial' not 'xds110 serial'" + eval adapter serial $args +} + # END MIGRATION AIDS diff --git a/tcl/interface/xds110.cfg b/tcl/interface/xds110.cfg index 51f4e28d3..74122c3e6 100644 --- a/tcl/interface/xds110.cfg +++ b/tcl/interface/xds110.cfg @@ -9,4 +9,4 @@ adapter driver xds110 # Use serial number option to use a specific XDS110 # when more than one are connected to the host. -#xds110 serial 00000000 +# adapter serial 00000000 From ad18c1a47fb8f3eaae66a7314700a1f186391359 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 8 Oct 2021 11:53:56 +0200 Subject: [PATCH 79/82] jtag/jlink: switch to command 'adapter serial' The driver jlink defines the command 'jlink serial' to specify the serial string of the adapter. Remove and deprecate the driver command, and use 'adapter serial'. Note: in former code the commands 'jlink serial' and 'jlink usb' were mutually exclusive; running one of them would invalidate the effect of a previous execution of the other. The new code gives priority to 'adapter serial', even if executed before 'jlink usb'. Change-Id: I920b0c136716f459b6fd6f7da8a01a7fa1ed389f Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6656 Reviewed-by: zapb Tested-by: jenkins --- doc/openocd.texi | 10 ++------ src/jtag/drivers/jlink.c | 51 ++++++++++++++-------------------------- src/jtag/startup.tcl | 6 +++++ tcl/interface/jlink.cfg | 2 +- 4 files changed, 26 insertions(+), 43 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 78451c71c..58e533f62 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,9 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r, ftdi, kitprog, presto, vsllink, xds110. +cmsis_dap, ft232r, ftdi, jlink, kitprog, presto, vsllink, xds110. The following adapters have their own command to specify the serial string: -hla, jlink, st-link. +hla, st-link. @end deffn @section Interface Drivers @@ -2848,12 +2848,6 @@ to the host. If not specified, USB addresses are not considered. Device selection via USB address is not always unambiguous. It is recommended to use the serial number instead, if possible. -As a configuration command, it can be used only before 'init'. -@end deffn -@deffn {Config Command} {jlink serial} -Set the serial number of the interface, in case more than one adapter is -connected to the host. If not specified, serial numbers are not considered. - As a configuration command, it can be used only before 'init'. @end deffn @end deffn diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 0414ec710..fdf4ae778 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -669,6 +669,23 @@ static int jlink_init(void) return ERROR_JTAG_INIT_FAILED; } + const char *serial = adapter_get_required_serial(); + if (serial) { + ret = jaylink_parse_serial_number(serial, &serial_number); + if (ret == JAYLINK_ERR) { + LOG_ERROR("Invalid serial number: %s", serial); + jaylink_exit(jayctx); + return ERROR_JTAG_INIT_FAILED; + } + if (ret != JAYLINK_OK) { + LOG_ERROR("jaylink_parse_serial_number() failed: %s", jaylink_strerror(ret)); + jaylink_exit(jayctx); + return ERROR_JTAG_INIT_FAILED; + } + use_serial_number = true; + use_usb_address = false; + } + bool found_device; ret = jlink_open_device(JAYLINK_HIF_USB, &found_device); if (ret != ERROR_OK) @@ -979,38 +996,11 @@ COMMAND_HANDLER(jlink_usb_command) usb_address = tmp; - use_serial_number = false; use_usb_address = true; return ERROR_OK; } -COMMAND_HANDLER(jlink_serial_command) -{ - int ret; - - if (CMD_ARGC != 1) { - command_print(CMD, "Need exactly one argument for jlink serial"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - ret = jaylink_parse_serial_number(CMD_ARGV[0], &serial_number); - - if (ret == JAYLINK_ERR) { - command_print(CMD, "Invalid serial number: %s", CMD_ARGV[0]); - return ERROR_FAIL; - } else if (ret != JAYLINK_OK) { - command_print(CMD, "jaylink_parse_serial_number() failed: %s", - jaylink_strerror(ret)); - return ERROR_FAIL; - } - - use_serial_number = true; - use_usb_address = false; - - return ERROR_OK; -} - COMMAND_HANDLER(jlink_handle_hwstatus_command) { int ret; @@ -1932,13 +1922,6 @@ static const struct command_registration jlink_subcommand_handlers[] = { .help = "set the USB address of the device that should be used", .usage = "<0-3>" }, - { - .name = "serial", - .handler = &jlink_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the device that should be used", - .usage = "" - }, { .name = "config", .handler = &jlink_handle_config_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index d6c3b85b4..199ca04d6 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -759,6 +759,12 @@ proc "ftdi serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip "jlink serial" +proc "jlink serial" {args} { + echo "DEPRECATED! use 'adapter serial' not 'jlink serial'" + eval adapter serial $args +} + lappend _telnet_autocomplete_skip kitprog_serial proc kitprog_serial args { echo "DEPRECATED! use 'adapter serial' not 'kitprog_serial'" diff --git a/tcl/interface/jlink.cfg b/tcl/interface/jlink.cfg index 51f420b7f..f9a18b05f 100644 --- a/tcl/interface/jlink.cfg +++ b/tcl/interface/jlink.cfg @@ -11,4 +11,4 @@ adapter driver jlink # # Example: Select J-Link with serial number 123456789 # -# jlink serial 123456789 +# adapter serial 123456789 From c6460ea36d7eeaf4a0fe4fb1a4c65bb21547afbe Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 8 Oct 2021 12:37:19 +0200 Subject: [PATCH 80/82] jtag/hla, jtag/stlink: switch to command 'adapter serial' The driver hla defines the command 'hla_serial' to specify the serial string of the adapter. The driver st-link defines the command 'st-link serial' to specify the serial string of the adapter. Remove and deprecate the driver commands and use 'adapter serial'. Change-Id: I9505c398a77125b1ebf4ba71da7baf4d663b75be Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6657 Tested-by: jenkins --- doc/openocd.texi | 12 +------- src/jtag/drivers/nulink_usb.c | 8 ++++-- src/jtag/drivers/stlink_usb.c | 50 ++++++++-------------------------- src/jtag/drivers/ti_icdi_usb.c | 5 ++-- src/jtag/hla/hla_interface.c | 22 --------------- src/jtag/hla/hla_interface.h | 2 -- src/jtag/startup.tcl | 12 ++++++++ tcl/interface/stlink-dap.cfg | 2 +- tcl/interface/stlink.cfg | 2 +- tcl/interface/ti-icdi.cfg | 2 +- 10 files changed, 36 insertions(+), 81 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 58e533f62..19ec31b34 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,9 +2371,7 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r, ftdi, jlink, kitprog, presto, vsllink, xds110. -The following adapters have their own command to specify the serial string: -hla, st-link. +cmsis_dap, ft232r, ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. @end deffn @section Interface Drivers @@ -3040,10 +3038,6 @@ version reported is V2.J21.S4. Currently Not Supported. @end deffn -@deffn {Config Command} {hla_serial} serial -Specifies the serial number of the adapter. -@end deffn - @deffn {Config Command} {hla_layout} (@option{stlink}|@option{icdi}|@option{nulink}) Specifies the adapter layout to use. @end deffn @@ -3092,10 +3086,6 @@ ST-LINK server software module}. @emph{Note:} ST-Link TCP server does not support the SWIM transport. @end deffn -@deffn {Config Command} {st-link serial} serial -Specifies the serial number of the adapter. -@end deffn - @deffn {Config Command} {st-link vid_pid} [vid pid]+ Pairs of vendor IDs and product IDs of the device. @end deffn diff --git a/src/jtag/drivers/nulink_usb.c b/src/jtag/drivers/nulink_usb.c index 3eea9de58..d4b8b53bc 100644 --- a/src/jtag/drivers/nulink_usb.c +++ b/src/jtag/drivers/nulink_usb.c @@ -22,6 +22,7 @@ /* project specific includes */ #include +#include #include #include #include @@ -1054,8 +1055,9 @@ static int nulink_usb_open(struct hl_interface_param_s *param, void **fd) goto error_open; } - if (param->serial) { - size_t len = mbstowcs(NULL, param->serial, 0); + const char *serial = adapter_get_required_serial(); + if (serial) { + size_t len = mbstowcs(NULL, serial, 0); target_serial = calloc(len + 1, sizeof(wchar_t)); if (!target_serial) { @@ -1063,7 +1065,7 @@ static int nulink_usb_open(struct hl_interface_param_s *param, void **fd) goto error_open; } - if (mbstowcs(target_serial, param->serial, len + 1) == (size_t)(-1)) { + if (mbstowcs(target_serial, serial, len + 1) == (size_t)(-1)) { LOG_WARNING("unable to convert serial"); free(target_serial); target_serial = NULL; diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 87e6ddc20..4c0e025fc 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -3363,7 +3364,7 @@ static int stlink_usb_usb_open(void *handle, struct hl_interface_param_s *param) in order to become operational. */ do { - if (jtag_libusb_open(param->vid, param->pid, param->serial, + if (jtag_libusb_open(param->vid, param->pid, adapter_get_required_serial(), &h->usb_backend_priv.fd, stlink_usb_get_alternate_serial) != ERROR_OK) { LOG_ERROR("open failed"); return ERROR_FAIL; @@ -3574,7 +3575,8 @@ static int stlink_tcp_open(void *handle, struct hl_interface_param_s *param) char serial[STLINK_TCP_SERIAL_SIZE + 1] = {0}; uint8_t stlink_used; bool stlink_id_matched = false; - bool stlink_serial_matched = (!param->serial); + const char *adapter_serial = adapter_get_required_serial(); + bool stlink_serial_matched = !adapter_serial; for (uint32_t stlink_id = 0; stlink_id < connected_stlinks; stlink_id++) { /* get the stlink info */ @@ -3604,27 +3606,28 @@ static int stlink_tcp_open(void *handle, struct hl_interface_param_s *param) continue; /* check the serial if specified */ - if (param->serial) { + if (adapter_serial) { /* ST-Link server fixes the buggy serial returned by old ST-Link DFU * for further details refer to stlink_usb_get_alternate_serial * so if the user passes the buggy serial, we need to fix it before * comparing with the serial returned by ST-Link server */ - if (strlen(param->serial) == STLINK_SERIAL_LEN / 2) { + if (strlen(adapter_serial) == STLINK_SERIAL_LEN / 2) { char fixed_serial[STLINK_SERIAL_LEN + 1]; for (unsigned int i = 0; i < STLINK_SERIAL_LEN; i += 2) - sprintf(fixed_serial + i, "%02X", param->serial[i / 2]); + sprintf(fixed_serial + i, "%02X", adapter_serial[i / 2]); fixed_serial[STLINK_SERIAL_LEN] = '\0'; stlink_serial_matched = strcmp(fixed_serial, serial) == 0; - } else - stlink_serial_matched = strcmp(param->serial, serial) == 0; + } else { + stlink_serial_matched = strcmp(adapter_serial, serial) == 0; + } } if (!stlink_serial_matched) LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'", - serial, param->serial); + serial, adapter_serial); else /* exit the search loop if there is match */ break; } @@ -3693,7 +3696,7 @@ static int stlink_open(struct hl_interface_param_s *param, enum stlink_mode mode for (unsigned i = 0; param->vid[i]; i++) { LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", h->st_mode, param->vid[i], param->pid[i], - param->serial ? param->serial : ""); + adapter_get_required_serial() ? adapter_get_required_serial() : ""); } if (param->use_stlink_tcp) @@ -4916,25 +4919,6 @@ static int stlink_dap_trace_read(uint8_t *buf, size_t *size) return stlink_usb_trace_read(stlink_dap_handle, buf, size); } -/** */ -COMMAND_HANDLER(stlink_dap_serial_command) -{ - LOG_DEBUG("stlink_dap_serial_command"); - - if (CMD_ARGC != 1) { - LOG_ERROR("Expected exactly one argument for \"st-link serial \"."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (stlink_dap_param.serial) { - LOG_WARNING("Command \"st-link serial\" already used. Replacing previous value"); - free((void *)stlink_dap_param.serial); - } - - stlink_dap_param.serial = strdup(CMD_ARGV[0]); - return ERROR_OK; -} - /** */ COMMAND_HANDLER(stlink_dap_vid_pid) { @@ -5025,13 +5009,6 @@ COMMAND_HANDLER(stlink_dap_cmd_command) /** */ static const struct command_registration stlink_dap_subcommand_handlers[] = { - { - .name = "serial", - .handler = stlink_dap_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the adapter", - .usage = "", - }, { .name = "vid_pid", .handler = stlink_dap_vid_pid, @@ -5112,9 +5089,6 @@ static int stlink_dap_quit(void) { LOG_DEBUG("stlink_dap_quit()"); - free((void *)stlink_dap_param.serial); - stlink_dap_param.serial = NULL; - return stlink_close(stlink_dap_handle); } diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c index d911fdacb..a359dd17d 100644 --- a/src/jtag/drivers/ti_icdi_usb.c +++ b/src/jtag/drivers/ti_icdi_usb.c @@ -23,6 +23,7 @@ /* project specific includes */ #include +#include #include #include #include @@ -681,11 +682,11 @@ static int icdi_usb_open(struct hl_interface_param_s *param, void **fd) for (uint8_t i = 0; param->vid[i] && param->pid[i]; ++i) LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", param->transport, - param->vid[i], param->pid[i], param->serial ? param->serial : ""); + param->vid[i], param->pid[i], adapter_get_required_serial() ? adapter_get_required_serial() : ""); /* TI (Stellaris) ICDI provides its serial number in the USB descriptor; no need to provide a callback here. */ - jtag_libusb_open(param->vid, param->pid, param->serial, &h->usb_dev, NULL); + jtag_libusb_open(param->vid, param->pid, adapter_get_required_serial(), &h->usb_dev, NULL); if (!h->usb_dev) { LOG_ERROR("open failed"); diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index fc362c040..074e3c2fb 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -38,7 +38,6 @@ static struct hl_interface_s hl_if = { .param = { .device_desc = NULL, - .serial = NULL, .vid = { 0 }, .pid = { 0 }, .transport = HL_TRANSPORT_UNKNOWN, @@ -136,7 +135,6 @@ static int hl_interface_quit(void) jtag_command_queue_reset(); free((void *)hl_if.param.device_desc); - free((void *)hl_if.param.serial); return ERROR_OK; } @@ -238,19 +236,6 @@ COMMAND_HANDLER(hl_interface_handle_device_desc_command) return ERROR_OK; } -COMMAND_HANDLER(hl_interface_handle_serial_command) -{ - LOG_DEBUG("hl_interface_handle_serial_command"); - - if (CMD_ARGC == 1) { - hl_if.param.serial = strdup(CMD_ARGV[0]); - } else { - LOG_ERROR("expected exactly one argument to hl_serial "); - } - - return ERROR_OK; -} - COMMAND_HANDLER(hl_interface_handle_layout_command) { LOG_DEBUG("hl_interface_handle_layout_command"); @@ -354,13 +339,6 @@ static const struct command_registration hl_interface_command_handlers[] = { .help = "set the device description of the adapter", .usage = "description_string", }, - { - .name = "hla_serial", - .handler = &hl_interface_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the adapter", - .usage = "serial_string", - }, { .name = "hla_layout", .handler = &hl_interface_handle_layout_command, diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h index c882acf48..31d055a3c 100644 --- a/src/jtag/hla/hla_interface.h +++ b/src/jtag/hla/hla_interface.h @@ -34,8 +34,6 @@ extern const char *hl_transports[]; struct hl_interface_param_s { /** */ const char *device_desc; - /** */ - const char *serial; /** List of recognised VIDs */ uint16_t vid[HLA_MAX_USB_IDS + 1]; /** List of recognised PIDs */ diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 199ca04d6..ee116269e 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -759,6 +759,12 @@ proc "ftdi serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip hla_serial +proc hla_serial args { + echo "DEPRECATED! use 'adapter serial' not 'hla_serial'" + eval adapter serial $args +} + lappend _telnet_autocomplete_skip "jlink serial" proc "jlink serial" {args} { echo "DEPRECATED! use 'adapter serial' not 'jlink serial'" @@ -777,6 +783,12 @@ proc "presto serial" {args} { eval adapter serial $args } +lappend _telnet_autocomplete_skip "st-link serial" +proc "st-link serial" {args} { + echo "DEPRECATED! use 'adapter serial' not 'st-link serial'" + eval adapter serial $args +} + lappend _telnet_autocomplete_skip "vsllink usb_serial" proc "vsllink usb_serial" {args} { echo "DEPRECATED! use 'adapter serial' not 'vsllink usb_serial'" diff --git a/tcl/interface/stlink-dap.cfg b/tcl/interface/stlink-dap.cfg index d912a5560..5a7d2e9ae 100644 --- a/tcl/interface/stlink-dap.cfg +++ b/tcl/interface/stlink-dap.cfg @@ -17,4 +17,4 @@ st-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0 # Optionally specify the serial number of usb device # e.g. -# st-link serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" +# adapter serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" diff --git a/tcl/interface/stlink.cfg b/tcl/interface/stlink.cfg index cb8e00494..8ac9b579f 100644 --- a/tcl/interface/stlink.cfg +++ b/tcl/interface/stlink.cfg @@ -13,4 +13,4 @@ hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374 # firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial # number reset issues. # eg. -#hla_serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" +# adapter serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" diff --git a/tcl/interface/ti-icdi.cfg b/tcl/interface/ti-icdi.cfg index 8561a3182..5cf6e37be 100644 --- a/tcl/interface/ti-icdi.cfg +++ b/tcl/interface/ti-icdi.cfg @@ -14,4 +14,4 @@ hla_vid_pid 0x1cbe 0x00fd # Optionally specify the serial number of TI-ICDI devices, for when using # multiple devices. Serial numbers can be obtained using lsusb -v # Ex. -#hla_serial "0F003065" +# adapter serial "0F003065" From 1d1386e31ed47dcdd9b433b810b27a0f28928bc7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 19 Oct 2021 13:09:25 +0200 Subject: [PATCH 81/82] drivers: call adapter_get_required_serial() in jtag_libusb_open() Now that adapter serial is handled independently from the adapter drivers, move inside jtag_libusb_open() the call to adapter_get_required_serial(), so every adapter that uses libusb will automagically get USB serial support. Extend the documentation to list the adapters involved. Change-Id: I75b3482d38f8ed3418329f3106c5e8b689fd460b Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6663 Tested-by: jenkins --- doc/openocd.texi | 3 ++- src/jtag/aice/aice_usb.c | 4 ++-- src/jtag/drivers/arm-jtag-ew.c | 2 +- src/jtag/drivers/ft232r.c | 4 ++-- src/jtag/drivers/kitprog.c | 4 +--- src/jtag/drivers/libusb_helper.c | 2 +- src/jtag/drivers/libusb_helper.h | 1 - src/jtag/drivers/opendous.c | 2 +- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/osbdm.c | 2 +- src/jtag/drivers/rlink.c | 2 +- src/jtag/drivers/stlink_usb.c | 2 +- src/jtag/drivers/ti_icdi_usb.c | 2 +- src/jtag/drivers/usb_blaster/ublast2_access_libusb.c | 8 +++----- src/jtag/drivers/usbprog.c | 2 +- 15 files changed, 19 insertions(+), 23 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 19ec31b34..337328187 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2371,7 +2371,8 @@ This command is only available if your libusb1 is at least version 1.0.16. Specifies the @var{serial_string} of the adapter to use. If this command is not specified, serial strings are not checked. Only the following adapter drivers use the serial string from this command: -cmsis_dap, ft232r, ftdi, hla, jlink, kitprog, presto, st-link, vsllink, xds110. +aice (aice_usb), arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus, +openjtag, osbdm, presto, rlink, st-link, usb_blaster (ublast2), usbprog, vsllink, xds110. @end deffn @section Interface Drivers diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index a943bb8b0..5d586763c 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -2085,7 +2085,7 @@ static int aice_usb_open(struct aice_port_param_s *param) const uint16_t pids[] = { param->pid, 0 }; struct libusb_device_handle *devh; - if (jtag_libusb_open(vids, pids, NULL, &devh, NULL) != ERROR_OK) + if (jtag_libusb_open(vids, pids, &devh, NULL) != ERROR_OK) return ERROR_FAIL; /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS @@ -2109,7 +2109,7 @@ static int aice_usb_open(struct aice_port_param_s *param) /* reopen jlink after usb_reset * on win32 this may take a second or two to re-enumerate */ int retval; - while ((retval = jtag_libusb_open(vids, pids, NULL, &devh, NULL)) != ERROR_OK) { + while ((retval = jtag_libusb_open(vids, pids, &devh, NULL)) != ERROR_OK) { usleep(1000); timeout--; if (!timeout) diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c index 5b5a9669e..703378940 100644 --- a/src/jtag/drivers/arm-jtag-ew.c +++ b/src/jtag/drivers/arm-jtag-ew.c @@ -688,7 +688,7 @@ static struct armjtagew *armjtagew_usb_open(void) const uint16_t pids[] = { USB_PID, 0 }; struct libusb_device_handle *dev; - if (jtag_libusb_open(vids, pids, NULL, &dev, NULL) != ERROR_OK) + if (jtag_libusb_open(vids, pids, &dev, NULL) != ERROR_OK) return NULL; struct armjtagew *result = malloc(sizeof(struct armjtagew)); diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index fc3cdbae2..c930d8c4c 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -257,8 +257,8 @@ static int ft232r_init(void) { uint16_t avids[] = {ft232r_vid, 0}; uint16_t apids[] = {ft232r_pid, 0}; - const char *ft232r_serial_desc = adapter_get_required_serial(); - if (jtag_libusb_open(avids, apids, ft232r_serial_desc, &adapter, NULL)) { + if (jtag_libusb_open(avids, apids, &adapter, NULL)) { + const char *ft232r_serial_desc = adapter_get_required_serial(); LOG_ERROR("ft232r not found: vid=%04x, pid=%04x, serial=%s\n", ft232r_vid, ft232r_pid, (!ft232r_serial_desc) ? "[any]" : ft232r_serial_desc); return ERROR_JTAG_INIT_FAILED; diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 0c5ccc6a7..5e2168eea 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -271,8 +270,7 @@ static int kitprog_usb_open(void) const uint16_t vids[] = { VID, 0 }; const uint16_t pids[] = { PID, 0 }; - if (jtag_libusb_open(vids, pids, adapter_get_required_serial(), - &kitprog_handle->usb_handle, NULL) != ERROR_OK) { + if (jtag_libusb_open(vids, pids, &kitprog_handle->usb_handle, NULL) != ERROR_OK) { LOG_ERROR("Failed to open or find the device"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index b8f1124e3..fc961cb91 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -157,7 +157,6 @@ static bool jtag_libusb_match_serial(struct libusb_device_handle *device, } int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, struct libusb_device_handle **out, adapter_get_alternate_serial_fn adapter_get_alternate_serial) { @@ -165,6 +164,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], int retval = ERROR_FAIL; bool serial_mismatch = false; struct libusb_device_handle *libusb_handle = NULL; + const char *serial = adapter_get_required_serial(); if (libusb_init(&jtag_libusb_context) < 0) return ERROR_FAIL; diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h index 6087128d2..2ddb246b3 100644 --- a/src/jtag/drivers/libusb_helper.h +++ b/src/jtag/drivers/libusb_helper.h @@ -28,7 +28,6 @@ typedef char * (*adapter_get_alternate_serial_fn)(struct libusb_device_handle *d struct libusb_device_descriptor *dev_desc); int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, struct libusb_device_handle **out, adapter_get_alternate_serial_fn adapter_get_alternate_serial); void jtag_libusb_close(struct libusb_device_handle *dev); diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 6881959c3..ae21cf2b9 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -706,7 +706,7 @@ struct opendous_jtag *opendous_usb_open(void) struct opendous_jtag *result; struct libusb_device_handle *devh; - if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh, NULL) != ERROR_OK) + if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, &devh, NULL) != ERROR_OK) return NULL; jtag_libusb_set_configuration(devh, 0); diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 7340119a1..771b6e6f3 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -449,7 +449,7 @@ static int openjtag_init_cy7c65215(void) int ret; usbh = NULL; - ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh, NULL); + ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, &usbh, NULL); if (ret != ERROR_OK) { LOG_ERROR("unable to open cy7c65215 device"); goto err; diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index 5c43d3244..f7665eb12 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -374,7 +374,7 @@ static int osbdm_flush(struct osbdm *osbdm, struct queue *queue) static int osbdm_open(struct osbdm *osbdm) { (void)memset(osbdm, 0, sizeof(*osbdm)); - if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh, NULL) != ERROR_OK) + if (jtag_libusb_open(osbdm_vid, osbdm_pid, &osbdm->devh, NULL) != ERROR_OK) return ERROR_FAIL; if (libusb_claim_interface(osbdm->devh, 0) != ERROR_OK) diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c index f75a38b5d..73be3c57e 100644 --- a/src/jtag/drivers/rlink.c +++ b/src/jtag/drivers/rlink.c @@ -1461,7 +1461,7 @@ static int rlink_init(void) const uint16_t vids[] = { USB_IDVENDOR, 0 }; const uint16_t pids[] = { USB_IDPRODUCT, 0 }; - if (jtag_libusb_open(vids, pids, NULL, &hdev, NULL) != ERROR_OK) + if (jtag_libusb_open(vids, pids, &hdev, NULL) != ERROR_OK) return ERROR_FAIL; struct libusb_device_descriptor descriptor; diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 4c0e025fc..2f61bf946 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3364,7 +3364,7 @@ static int stlink_usb_usb_open(void *handle, struct hl_interface_param_s *param) in order to become operational. */ do { - if (jtag_libusb_open(param->vid, param->pid, adapter_get_required_serial(), + if (jtag_libusb_open(param->vid, param->pid, &h->usb_backend_priv.fd, stlink_usb_get_alternate_serial) != ERROR_OK) { LOG_ERROR("open failed"); return ERROR_FAIL; diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c index a359dd17d..c94a1102f 100644 --- a/src/jtag/drivers/ti_icdi_usb.c +++ b/src/jtag/drivers/ti_icdi_usb.c @@ -686,7 +686,7 @@ static int icdi_usb_open(struct hl_interface_param_s *param, void **fd) /* TI (Stellaris) ICDI provides its serial number in the USB descriptor; no need to provide a callback here. */ - jtag_libusb_open(param->vid, param->pid, adapter_get_required_serial(), &h->usb_dev, NULL); + jtag_libusb_open(param->vid, param->pid, &h->usb_dev, NULL); if (!h->usb_dev) { LOG_ERROR("open failed"); diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index d55bf85cd..21f9ae72b 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -210,7 +210,7 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) bool renumeration = false; int ret; - if (jtag_libusb_open(vids, pids, NULL, &temp, NULL) == ERROR_OK) { + if (jtag_libusb_open(vids, pids, &temp, NULL) == ERROR_OK) { LOG_INFO("Altera USB-Blaster II (uninitialized) found"); LOG_INFO("Loading firmware..."); ret = load_usb_blaster_firmware(temp, low); @@ -224,15 +224,13 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) const uint16_t pids_renum[] = { low->ublast_pid, 0 }; if (renumeration == false) { - if (jtag_libusb_open(vids_renum, pids_renum, NULL, - &low->libusb_dev, NULL) != ERROR_OK) { + if (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK) { LOG_ERROR("Altera USB-Blaster II not found"); return ERROR_FAIL; } } else { int retry = 10; - while (jtag_libusb_open(vids_renum, pids_renum, NULL, - &low->libusb_dev, NULL) != ERROR_OK && retry--) { + while (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK && retry--) { usleep(1000000); LOG_INFO("Waiting for reenumerate..."); } diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c index 44db61ec0..a2ebdbc86 100644 --- a/src/jtag/drivers/usbprog.c +++ b/src/jtag/drivers/usbprog.c @@ -354,7 +354,7 @@ struct usbprog_jtag *usbprog_jtag_open(void) const uint16_t pids[] = { PID, 0 }; struct libusb_device_handle *dev; - if (jtag_libusb_open(vids, pids, NULL, &dev, NULL) != ERROR_OK) + if (jtag_libusb_open(vids, pids, &dev, NULL) != ERROR_OK) return NULL; struct usbprog_jtag *tmp = malloc(sizeof(struct usbprog_jtag)); From 1ad6ed38b6da09b1d5d9e56d1344fced2dce12bc Mon Sep 17 00:00:00 2001 From: Doug Brunner Date: Mon, 25 Oct 2021 12:21:34 -0700 Subject: [PATCH 82/82] flash/nor/efm32: fixed BG1x identification The EFM32 flash driver misidentifies the EFR32BG1B on my board as EFR32MG1B. Looks like this was caused by a copy-paste error, fixed. Signed-off-by: Doug Brunner Change-Id: I3067f7ba132c2562487da8c2371f63a4843230c1 Reviewed-on: https://review.openocd.org/c/openocd/+/6666 Tested-by: jenkins Reviewed-by: Fredrik Hederstierna Reviewed-by: Tomas Vanek --- src/flash/nor/efm32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index ab0186d7d..fb4b09624 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -119,9 +119,9 @@ static const struct efm32_family_data efm32_families[] = { { 16, "EFR32MG1P Mighty", .series = 1 }, { 17, "EFR32MG1B Mighty", .series = 1 }, { 18, "EFR32MG1V Mighty", .series = 1 }, - { 19, "EFR32MG1P Blue", .series = 1 }, - { 20, "EFR32MG1B Blue", .series = 1 }, - { 21, "EFR32MG1V Blue", .series = 1 }, + { 19, "EFR32BG1P Blue", .series = 1 }, + { 20, "EFR32BG1B Blue", .series = 1 }, + { 21, "EFR32BG1V Blue", .series = 1 }, { 25, "EFR32FG1P Flex", .series = 1 }, { 26, "EFR32FG1B Flex", .series = 1 }, { 27, "EFR32FG1V Flex", .series = 1 },