zy1000: embedded ice dcc tweak
[fw/openocd] / src / jtag / zy1000 / zy1000.c
index 6465aaa7b25db1ffbe16c705a941e2f62019ee9c..005a4e02e4393dac7fd7310a89eb07e1f892f259 100644 (file)
@@ -574,49 +574,31 @@ static __inline void scanFields(int num_fields, const struct scan_field *fields,
        }
 }
 
-int interface_jtag_add_ir_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
+int interface_jtag_add_ir_scan(struct jtag_tap *active, const struct scan_field *fields, tap_state_t state)
 {
-
-       int j;
        int scan_size = 0;
        struct jtag_tap *tap, *nextTap;
+
        for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap)
        {
                nextTap = jtag_tap_next_enabled(tap);
-               int pause = (nextTap==NULL);
-
-               int found = 0;
-
+               bool pause = (nextTap==NULL);
                scan_size = tap->ir_length;
 
                /* search the list */
-               for (j = 0; j < num_fields; j++)
+               if (tap == active)
                {
-                       if (tap == fields[j].tap)
-                       {
-                               found = 1;
-
-                               scanFields(1, fields + j, TAP_IRSHIFT, pause);
-                               /* update device information */
-                               buf_cpy(fields[j].out_value, tap->cur_instr, scan_size);
-
-                               tap->bypass = 0;
-                               break;
-                       }
-               }
+                       scanFields(1, fields, TAP_IRSHIFT, pause);
+                       /* update device information */
+                       buf_cpy(fields[0].out_value, tap->cur_instr, scan_size);
 
-               if (!found)
+                       tap->bypass = 0;
+               } else
                {
                        /* if a device isn't listed, set it to BYPASS */
-                       uint8_t ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+                       assert(scan_size <= 32);
+                       shiftValueInner(TAP_IRSHIFT, pause?TAP_IRPAUSE:TAP_IRSHIFT, scan_size, 0xffffffff);
 
-                       struct scan_field tmp;
-                       memset(&tmp, 0, sizeof(tmp));
-                       tmp.out_value = ones;
-                       tmp.num_bits = scan_size;
-                       scanFields(1, &tmp, TAP_IRSHIFT, pause);
-                       /* update device information */
-                       buf_cpy(tmp.out_value, tap->cur_instr, scan_size);
                        tap->bypass = 1;
                }
        }
@@ -629,67 +611,56 @@ int interface_jtag_add_ir_scan(int num_fields, const struct scan_field *fields,
 
 
 
-int interface_jtag_add_plain_ir_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
+int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
 {
-       scanFields(num_fields, fields, TAP_IRSHIFT, 1);
+       struct scan_field field;
+       field.num_bits  = num_bits;
+       field.out_value = out_bits;
+       field.in_value  = in_bits;
+
+       scanFields(1, &field, TAP_IRSHIFT, 1);
        gotoEndState(state);
 
        return ERROR_OK;
 }
 
-int interface_jtag_add_dr_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
+int interface_jtag_add_dr_scan(struct jtag_tap *active, int num_fields, const struct scan_field *fields, tap_state_t state)
 {
-
-       int j;
        struct jtag_tap *tap, *nextTap;
        for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap)
        {
                nextTap = jtag_tap_next_enabled(tap);
-               int found = 0;
-               int pause = (nextTap==NULL);
+               bool pause = (nextTap==NULL);
 
-               for (j = 0; j < num_fields; j++)
+               /* Find a range of fields to write to this tap */
+               if (tap == active)
                {
-                       /* Find a range of fields to write to this tap */
-                       if (tap == fields[j].tap)
-                       {
-                               found = 1;
-                               int i;
-                               for (i = j + 1; i < num_fields; i++)
-                               {
-                                       if (tap != fields[j].tap)
-                                       {
-                                               break;
-                                       }
-                               }
+                       assert(!tap->bypass);
 
-                               scanFields(i - j, fields + j, TAP_DRSHIFT, pause);
-
-                               j = i;
-                       }
-               }
-
-               if (!found)
+                       scanFields(num_fields, fields, TAP_DRSHIFT, pause);
+               } else
                {
                        /* Shift out a 0 for disabled tap's */
+                       assert(tap->bypass);
                        shiftValueInner(TAP_DRSHIFT, pause?TAP_DRPAUSE:TAP_DRSHIFT, 1, 0);
                }
-               else
-               {
-               }
        }
        gotoEndState(state);
        return ERROR_OK;
 }
 
-int interface_jtag_add_plain_dr_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
+int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
 {
-       scanFields(num_fields, fields, TAP_DRSHIFT, 1);
+       struct scan_field field;
+       field.num_bits  = num_bits;
+       field.out_value = out_bits;
+       field.in_value  = in_bits;
+
+       scanFields(1, &field, TAP_DRSHIFT, 1);
        gotoEndState(state);
        return ERROR_OK;
 }
 
-
 int interface_jtag_add_tlr()
 {
        setCurrentState(TAP_RESET);
@@ -697,8 +668,6 @@ int interface_jtag_add_tlr()
 }
 
 
-
-
 int interface_jtag_add_reset(int req_trst, int req_srst)
 {
        zy1000_reset(req_trst, req_srst);
@@ -743,7 +712,6 @@ static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t
        ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state);
 #endif
 
-
        return ERROR_OK;
 }
 
@@ -835,34 +803,43 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
        return interface_add_tms_seq(state_count, seq, cur_state);
 }
 
-void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count)
+static void jtag_pre_post_bits(struct jtag_tap *tap, int *pre, int *post)
 {
-//     static int const reg_addr = 0x5;
-       tap_state_t end_state = jtag_get_end_state();
-       if (jtag_tap_next_enabled(jtag_tap_next_enabled(NULL)) == NULL)
+       /* bypass bits before and after */
+       int pre_bits = 0;
+       int post_bits = 0;
+
+       bool found = false;
+       struct jtag_tap *cur_tap, *nextTap;
+       for (cur_tap = jtag_tap_next_enabled(NULL); cur_tap!= NULL; cur_tap = nextTap)
        {
-               /* better performance via code duplication */
-               if (little)
+               nextTap = jtag_tap_next_enabled(cur_tap);
+               if (cur_tap == tap)
                {
-                       int i;
-                       for (i = 0; i < count; i++)
-                       {
-                               shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 1));
-                               shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr | (1 << 5));
-                               buffer += 4;
-                       }
+                       found = true;
                } else
                {
-                       int i;
-                       for (i = 0; i < count; i++)
+                       if (found)
                        {
-                               shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 0));
-                               shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr | (1 << 5));
-                               buffer += 4;
+                               post_bits++;
+                       } else
+                       {
+                               pre_bits++;
                        }
                }
        }
-       else
+       *pre = pre_bits;
+       *post = post_bits;
+}
+
+void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count)
+{
+
+       int pre_bits;
+       int post_bits;
+       jtag_pre_post_bits(tap, &pre_bits, &post_bits);
+
+       if ((pre_bits > 32) || (post_bits > 32))
        {
                int i;
                for (i = 0; i < count; i++)
@@ -870,6 +847,22 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer,
                        embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, little));
                        buffer += 4;
                }
+       } else
+       {
+               tap_state_t end_state = jtag_get_end_state();
+               tap_state_t shift_end_state;
+               if (post_bits == 0)
+                       shift_end_state = end_state;
+
+               int i;
+               for (i = 0; i < count; i++)
+               {
+                       shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0);
+                       shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, little));
+                       shiftValueInner(TAP_DRSHIFT, shift_end_state, 6, reg_addr | (1 << 5));
+                       shiftValueInner(shift_end_state, end_state, post_bits, 0);
+                       buffer += 4;
+               }
        }
 }
 
@@ -890,8 +883,9 @@ int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opc
 
 
        /* bypass bits before and after */
-       int pre_bits = 0;
-       int post_bits = 0;
+       int pre_bits;
+       int post_bits;
+       jtag_pre_post_bits(tap, &pre_bits, &post_bits);
 
        bool found = false;
        struct jtag_tap *cur_tap, *nextTap;
@@ -927,6 +921,7 @@ int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opc
                value |= (*t++<<24);
 
                shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, value);
+               /* minimum 2 bits */
                shiftValueInner(TAP_DRSHIFT, TAP_DRPAUSE, post_bits, 0);
 
 #if 1