drivers/cmsis_dap: fix segfault in quirk mode setting

CMSIS-DAP quirk mode had to be set after init otherwise
openocd failed due to NULL cmsis_dap_handle

Move quirk_mode from struct cmsis_dap to
a standalone static variable to allow setting from Tcl config
before calling cmsis_dap_open()

Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Fixes: 7966: drivers/cmsis_dap: use quirk workarounds optionally | https://review.openocd.org/c/openocd/+/7966
Fixes: https://sourceforge.net/p/openocd/tickets/420/
Change-Id: I0b53ec09b35ccf66660e00490f41aaed1bd0f91f
Reviewed-on: https://review.openocd.org/c/openocd/+/8641
Reviewed-by: zapb <dev@zapb.de>
Tested-by: jenkins
This commit is contained in:
Tomas Vanek
2024-12-10 09:47:21 +01:00
parent 6bc2c58596
commit 66ea461846
2 changed files with 7 additions and 7 deletions

View File

@@ -76,6 +76,7 @@ static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 };
static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 }; static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 };
static int cmsis_dap_backend = -1; static int cmsis_dap_backend = -1;
static bool swd_mode; static bool swd_mode;
static bool cmsis_dap_quirk_mode; /* enable expensive workarounds */
/* CMSIS-DAP General Commands */ /* CMSIS-DAP General Commands */
#define CMD_DAP_INFO 0x00 #define CMD_DAP_INFO 0x00
@@ -870,7 +871,7 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
goto skip; goto skip;
} }
unsigned int packet_count = dap->quirk_mode ? 1 : dap->packet_count; unsigned int packet_count = cmsis_dap_quirk_mode ? 1 : dap->packet_count;
dap->pending_fifo_put_idx = (dap->pending_fifo_put_idx + 1) % packet_count; dap->pending_fifo_put_idx = (dap->pending_fifo_put_idx + 1) % packet_count;
dap->pending_fifo_block_count++; dap->pending_fifo_block_count++;
if (dap->pending_fifo_block_count > packet_count) if (dap->pending_fifo_block_count > packet_count)
@@ -990,7 +991,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
skip: skip:
block->transfer_count = 0; block->transfer_count = 0;
if (!dap->quirk_mode && dap->packet_count > 1) if (!cmsis_dap_quirk_mode && dap->packet_count > 1)
dap->pending_fifo_get_idx = (dap->pending_fifo_get_idx + 1) % dap->packet_count; dap->pending_fifo_get_idx = (dap->pending_fifo_get_idx + 1) % dap->packet_count;
dap->pending_fifo_block_count--; dap->pending_fifo_block_count--;
} }
@@ -1086,7 +1087,7 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
/* Not enough room in the queue. Run the queue. */ /* Not enough room in the queue. Run the queue. */
cmsis_dap_swd_write_from_queue(cmsis_dap_handle); cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
unsigned int packet_count = cmsis_dap_handle->quirk_mode ? 1 : cmsis_dap_handle->packet_count; unsigned int packet_count = cmsis_dap_quirk_mode ? 1 : cmsis_dap_handle->packet_count;
if (cmsis_dap_handle->pending_fifo_block_count >= packet_count) if (cmsis_dap_handle->pending_fifo_block_count >= packet_count)
cmsis_dap_swd_read_process(cmsis_dap_handle, CMSIS_DAP_BLOCKING); cmsis_dap_swd_read_process(cmsis_dap_handle, CMSIS_DAP_BLOCKING);
} }
@@ -1230,7 +1231,7 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
if (swd_mode) if (swd_mode)
queued_retval = cmsis_dap_swd_run_queue(); queued_retval = cmsis_dap_swd_run_queue();
if (cmsis_dap_handle->quirk_mode && seq != LINE_RESET && if (cmsis_dap_quirk_mode && seq != LINE_RESET &&
(output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST)) (output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST))
== (SWJ_PIN_SRST | SWJ_PIN_TRST)) { == (SWJ_PIN_SRST | SWJ_PIN_TRST)) {
/* Following workaround deasserts reset on most adapters. /* Following workaround deasserts reset on most adapters.
@@ -2239,10 +2240,10 @@ COMMAND_HANDLER(cmsis_dap_handle_quirk_command)
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
if (CMD_ARGC == 1) if (CMD_ARGC == 1)
COMMAND_PARSE_ENABLE(CMD_ARGV[0], cmsis_dap_handle->quirk_mode); COMMAND_PARSE_ENABLE(CMD_ARGV[0], cmsis_dap_quirk_mode);
command_print(CMD, "CMSIS-DAP quirk workarounds %s", command_print(CMD, "CMSIS-DAP quirk workarounds %s",
cmsis_dap_handle->quirk_mode ? "enabled" : "disabled"); cmsis_dap_quirk_mode ? "enabled" : "disabled");
return ERROR_OK; return ERROR_OK;
} }

View File

@@ -52,7 +52,6 @@ struct cmsis_dap {
unsigned int pending_fifo_block_count; unsigned int pending_fifo_block_count;
uint16_t caps; uint16_t caps;
bool quirk_mode; /* enable expensive workarounds */
uint32_t swo_buf_sz; uint32_t swo_buf_sz;
bool trace_enabled; bool trace_enabled;