summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-06-12 21:43:53 +0000
committerzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-06-12 21:43:53 +0000
commit8551803eb52db94ae3c1c9d4a7871d3e0986185a (patch)
treeedd4051ef09356ed07c8b6eeb61cd31336124ec5 /src
parenta92cc405ac5775ad97c0d0e72ca9233dcfdc8228 (diff)
downloadopenocd_libswd-8551803eb52db94ae3c1c9d4a7871d3e0986185a.tar.gz
openocd_libswd-8551803eb52db94ae3c1c9d4a7871d3e0986185a.tar.bz2
openocd_libswd-8551803eb52db94ae3c1c9d4a7871d3e0986185a.tar.xz
openocd_libswd-8551803eb52db94ae3c1c9d4a7871d3e0986185a.zip
David Brownell <david-b@pacbell.net>:
Partial fix to the "long IR length" problems. - Current code could handle up to 32 bit IR lengths with full functionality, if it didn't just reject may of them out of hand. So only reject clear errors, where the IR mask (or capture instruction) needs more than IrLen bits. - Longer IR lengths can only be handled in BYPASS mode for now. Example: TI's DSPs use 38-bit IR lengths. So we can't issue their IDCODE instructions... A more complete fix would be able to issue longer instructions; or minimally, would fail cleanly for the non-BYPASS case. Note that this *could* make some currently broken scripts fail, since the previous code accepted garbage values so long as they didn't use more than 16 bits. git-svn-id: svn://svn.berlios.de/openocd/trunk@2222 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src')
-rw-r--r--src/jtag/core.c1
-rw-r--r--src/jtag/tcl.c27
2 files changed, 22 insertions, 6 deletions
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 4c91abee..7ed5976c 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -1073,6 +1073,7 @@ void jtag_tap_init(jtag_tap_t *tap)
tap->expected_mask = malloc(tap->ir_length);
tap->cur_instr = malloc(tap->ir_length);
+ /// @todo cope sanely with ir_length bigger than 32 bits
buf_set_u32(tap->expected, 0, tap->ir_length, tap->ir_capture_value);
buf_set_u32(tap->expected_mask, 0, tap->ir_length, tap->ir_capture_mask);
buf_set_ones(tap->cur_instr, tap->ir_length);
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 152dd762..abc10062 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -296,6 +296,15 @@ static int jtag_tap_configure_cmd( Jim_GetOptInfo *goi, jtag_tap_t * tap)
return JIM_OK;
}
+static int is_bad_irval(int ir_length, jim_wide w)
+{
+ jim_wide v = 1;
+
+ v <<= ir_length;
+ v -= 1;
+ v = ~v;
+ return (w & v) != 0;
+}
extern void jtag_tap_init(jtag_tap_t *tap);
extern void jtag_tap_free(jtag_tap_t *tap);
@@ -411,22 +420,28 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi )
Jim_SetResult_sprintf( goi->interp, "option: %s bad parameter", n->name );
return e;
}
- if( (w < 0) || (w > 0xffff) ){
- /* wacky value */
- Jim_SetResult_sprintf( goi->interp, "option: %s - wacky value: %d (0x%x)",
- n->name, (int)(w), (int)(w));
- return JIM_ERR;
- }
switch(n->value){
case NTAP_OPT_IRLEN:
+ if (w < (jim_wide) sizeof(pTap->ir_capture_value))
+ LOG_WARNING("huge IR length %d", (int) w);
pTap->ir_length = w;
reqbits &= (~(NTREQ_IRLEN));
break;
case NTAP_OPT_IRMASK:
+ if (is_bad_irval(pTap->ir_length, w)) {
+ LOG_ERROR("IR mask %x too big",
+ (int) w);
+ return ERROR_FAIL;
+ }
pTap->ir_capture_mask = w;
reqbits &= (~(NTREQ_IRMASK));
break;
case NTAP_OPT_IRCAPTURE:
+ if (is_bad_irval(pTap->ir_length, w)) {
+ LOG_ERROR("IR capture %x too big",
+ (int) w);
+ return ERROR_FAIL;
+ }
pTap->ir_capture_value = w;
reqbits &= (~(NTREQ_IRCAPTURE));
break;