digilent: heap-allocate shift buffers, drop the size cap
The TX/TXRX functions used fixed ~1-2 KB stack buffers and rejected anything larger, so any big shift failed: bscan_idle_cycles(10000) and above all the ~19 Mbit bitstream load for the BSCAN proxy. Size the pack/capture buffers to the shift on the heap instead. This is what unblocked the proxy load — see next commit.
This commit is contained in:
@@ -285,26 +285,26 @@ static int drv_Digilent_DeInit(jtag_core *jc)
|
|||||||
|
|
||||||
static int drv_Digilent_TMS_xfer(jtag_core *jc, unsigned char *str_out, int size)
|
static int drv_Digilent_TMS_xfer(jtag_core *jc, unsigned char *str_out, int size)
|
||||||
{
|
{
|
||||||
DJ_BYTE buf_snd[1024];
|
DJ_BYTE *buf_snd;
|
||||||
int nbytes = (size + 7) / 8;
|
int nbytes = (size + 7) / 8;
|
||||||
int i;
|
int i, ok;
|
||||||
|
|
||||||
if (!g_dj_open) return JTAG_CORE_BAD_PARAMETER;
|
if (!g_dj_open) return JTAG_CORE_BAD_PARAMETER;
|
||||||
if (size <= 0) return JTAG_CORE_NO_ERROR;
|
if (size <= 0) return JTAG_CORE_NO_ERROR;
|
||||||
if (nbytes > (int)sizeof(buf_snd)) {
|
|
||||||
jtagcore_logs_printf(jc, MSG_ERROR,
|
|
||||||
"drv_Digilent_TMS_xfer : size %d > %d bits\r\n",
|
|
||||||
size, (int)sizeof(buf_snd) * 8);
|
|
||||||
return JTAG_CORE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buf_snd, 0, nbytes);
|
/* Heap-allocated and sized to the shift: a bitstream load shifts
|
||||||
|
* millions of bits in one call, far past any fixed buffer. */
|
||||||
|
buf_snd = calloc(1, (size_t)nbytes);
|
||||||
|
if (!buf_snd) return JTAG_CORE_BAD_PARAMETER;
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if (str_out[i] & JTAG_STR_TMS)
|
if (str_out[i] & JTAG_STR_TMS)
|
||||||
buf_snd[i >> 3] |= (DJ_BYTE)(1u << (i & 7));
|
buf_snd[i >> 3] |= (DJ_BYTE)(1u << (i & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_dj.PutTmsBits(g_dj_hif, /*fTdi=*/0, buf_snd, NULL, (DJ_DWORD)size, /*fOverlap=*/0)) {
|
ok = g_dj.PutTmsBits(g_dj_hif, /*fTdi=*/0, buf_snd, NULL, (DJ_DWORD)size, /*fOverlap=*/0);
|
||||||
|
free(buf_snd);
|
||||||
|
if (!ok) {
|
||||||
jtagcore_logs_printf(jc, MSG_ERROR,
|
jtagcore_logs_printf(jc, MSG_ERROR,
|
||||||
"drv_Digilent_TMS_xfer : DjtgPutTmsBits failed\r\n");
|
"drv_Digilent_TMS_xfer : DjtgPutTmsBits failed\r\n");
|
||||||
return JTAG_CORE_BAD_PARAMETER;
|
return JTAG_CORE_BAD_PARAMETER;
|
||||||
@@ -317,10 +317,9 @@ static int drv_Digilent_TDOTDI_xfer(jtag_core *jc,
|
|||||||
unsigned char *str_in,
|
unsigned char *str_in,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
DJ_BYTE buf_snd[2048];
|
DJ_BYTE *buf_snd, *buf_rcv = NULL;
|
||||||
DJ_BYTE buf_rcv[1024];
|
|
||||||
int has_tms = 0;
|
int has_tms = 0;
|
||||||
int i;
|
int i, ok, snd_bytes;
|
||||||
|
|
||||||
if (!g_dj_open) return JTAG_CORE_BAD_PARAMETER;
|
if (!g_dj_open) return JTAG_CORE_BAD_PARAMETER;
|
||||||
if (size <= 0) return JTAG_CORE_NO_ERROR;
|
if (size <= 0) return JTAG_CORE_NO_ERROR;
|
||||||
@@ -329,54 +328,50 @@ static int drv_Digilent_TDOTDI_xfer(jtag_core *jc,
|
|||||||
if (str_out[i] & JTAG_STR_TMS) { has_tms = 1; break; }
|
if (str_out[i] & JTAG_STR_TMS) { has_tms = 1; break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (str_in) {
|
||||||
|
buf_rcv = calloc(1, (size_t)((size + 7) / 8));
|
||||||
|
if (!buf_rcv) return JTAG_CORE_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PutTmsTdiBits packs 2 bits/clock, PutTdiBits 1 bit/clock. Buffers
|
||||||
|
* are heap-sized to the shift (bitstream loads run into MB). */
|
||||||
|
snd_bytes = has_tms ? (2 * size + 7) / 8 : (size + 7) / 8;
|
||||||
|
buf_snd = calloc(1, (size_t)snd_bytes);
|
||||||
|
if (!buf_snd) { free(buf_rcv); return JTAG_CORE_BAD_PARAMETER; }
|
||||||
|
|
||||||
if (has_tms) {
|
if (has_tms) {
|
||||||
/* Mixed TMS+TDI shift: 2 bits per clock (TDI low, TMS high), LSB-first. */
|
/* 2 bits per clock: TDI low, TMS high, LSB-first. */
|
||||||
int nbytes_snd = (2 * size + 7) / 8;
|
|
||||||
if (nbytes_snd > (int)sizeof(buf_snd) || (size + 7) / 8 > (int)sizeof(buf_rcv)) {
|
|
||||||
jtagcore_logs_printf(jc, MSG_ERROR,
|
|
||||||
"drv_Digilent_TDOTDI_xfer : size %d too large\r\n", size);
|
|
||||||
return JTAG_CORE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
memset(buf_snd, 0, nbytes_snd);
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
int pos = 2 * i;
|
int pos = 2 * i;
|
||||||
if (str_out[i] & JTAG_STR_DOUT)
|
if (str_out[i] & JTAG_STR_DOUT)
|
||||||
buf_snd[pos >> 3] |= (DJ_BYTE)(1u << (pos & 7)); /* TDI = low bit */
|
buf_snd[pos >> 3] |= (DJ_BYTE)(1u << (pos & 7));
|
||||||
pos++;
|
pos++;
|
||||||
if (str_out[i] & JTAG_STR_TMS)
|
if (str_out[i] & JTAG_STR_TMS)
|
||||||
buf_snd[pos >> 3] |= (DJ_BYTE)(1u << (pos & 7)); /* TMS = high bit */
|
buf_snd[pos >> 3] |= (DJ_BYTE)(1u << (pos & 7));
|
||||||
}
|
|
||||||
if (!g_dj.PutTmsTdiBits(g_dj_hif, buf_snd, str_in ? buf_rcv : NULL,
|
|
||||||
(DJ_DWORD)size, /*fOverlap=*/0)) {
|
|
||||||
jtagcore_logs_printf(jc, MSG_ERROR,
|
|
||||||
"drv_Digilent_TDOTDI_xfer : DjtgPutTmsTdiBits failed\r\n");
|
|
||||||
return JTAG_CORE_BAD_PARAMETER;
|
|
||||||
}
|
}
|
||||||
|
ok = g_dj.PutTmsTdiBits(g_dj_hif, buf_snd, buf_rcv, (DJ_DWORD)size, /*fOverlap=*/0);
|
||||||
} else {
|
} else {
|
||||||
/* Pure data shift: TMS held to 0, 1 bit per clock. */
|
/* Pure data shift: TMS held to 0, 1 bit per clock. */
|
||||||
int nbytes_snd = (size + 7) / 8;
|
|
||||||
if (nbytes_snd > (int)sizeof(buf_rcv)) {
|
|
||||||
jtagcore_logs_printf(jc, MSG_ERROR,
|
|
||||||
"drv_Digilent_TDOTDI_xfer : size %d too large\r\n", size);
|
|
||||||
return JTAG_CORE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
memset(buf_snd, 0, nbytes_snd);
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if (str_out[i] & JTAG_STR_DOUT)
|
if (str_out[i] & JTAG_STR_DOUT)
|
||||||
buf_snd[i >> 3] |= (DJ_BYTE)(1u << (i & 7));
|
buf_snd[i >> 3] |= (DJ_BYTE)(1u << (i & 7));
|
||||||
}
|
}
|
||||||
if (!g_dj.PutTdiBits(g_dj_hif, /*fTms=*/0, buf_snd, str_in ? buf_rcv : NULL,
|
ok = g_dj.PutTdiBits(g_dj_hif, /*fTms=*/0, buf_snd, buf_rcv, (DJ_DWORD)size, /*fOverlap=*/0);
|
||||||
(DJ_DWORD)size, /*fOverlap=*/0)) {
|
}
|
||||||
jtagcore_logs_printf(jc, MSG_ERROR,
|
free(buf_snd);
|
||||||
"drv_Digilent_TDOTDI_xfer : DjtgPutTdiBits failed\r\n");
|
|
||||||
return JTAG_CORE_BAD_PARAMETER;
|
if (!ok) {
|
||||||
}
|
free(buf_rcv);
|
||||||
|
jtagcore_logs_printf(jc, MSG_ERROR,
|
||||||
|
"drv_Digilent_TDOTDI_xfer : Djtg shift failed (size %d)\r\n", size);
|
||||||
|
return JTAG_CORE_BAD_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str_in) {
|
if (str_in) {
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
str_in[i] = (buf_rcv[i >> 3] & (1u << (i & 7))) ? JTAG_STR_DOUT : 0;
|
str_in[i] = (buf_rcv[i >> 3] & (1u << (i & 7))) ? JTAG_STR_DOUT : 0;
|
||||||
}
|
}
|
||||||
|
free(buf_rcv);
|
||||||
}
|
}
|
||||||
return JTAG_CORE_NO_ERROR;
|
return JTAG_CORE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user