You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

231 lines
7.3 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007-2010 by √ėyvind Harboe *
  3. * *
  4. * This program is free software; you can redistribute it and/or modify *
  5. * it under the terms of the GNU General Public License as published by *
  6. * the Free Software Foundation; either version 2 of the License, or *
  7. * (at your option) any later version. *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. /* used to test manual mode */
  20. #define TEST_MANUAL() 0
  21. #define VERBOSE(a)
  22. #if BUILD_ZY1000_MASTER
  23. #define ZY1000_PEEK(a, b) do {b = *((volatile uint32_t *)(a)); } while (0)
  24. #define ZY1000_POKE(a, b) do {*((volatile uint32_t *)(a)) = b; } while (0)
  25. extern volatile void *zy1000_jtag_master;
  26. #define ZY1000_JTAG_BASE ((unsigned long)zy1000_jtag_master)
  27. #else
  28. /* redirect this to TCP/IP */
  29. #define ZY1000_JTAG_BASE 0
  30. extern void zy1000_tcpout(uint32_t address, uint32_t data);
  31. extern uint32_t zy1000_tcpin(uint32_t address);
  32. #define ZY1000_PEEK(a, b) b = zy1000_tcpin(a)
  33. #define ZY1000_POKE(a, b) zy1000_tcpout(a, b)
  34. #endif
  35. #if BUILD_ZY1000_MASTER
  36. /* FIFO empty? */
  37. static inline void waitIdle(void)
  38. {
  39. uint32_t empty;
  40. do {
  41. ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty);
  42. } while ((empty & 0x100) == 0);
  43. }
  44. static inline void zy1000_flush_readqueue(void)
  45. {
  46. /* Not used w/hardware fifo */
  47. }
  48. static inline void zy1000_flush_callbackqueue(void)
  49. {
  50. /* Not used w/hardware fifo */
  51. }
  52. #else
  53. extern void waitIdle(void);
  54. void zy1000_flush_readqueue(void);
  55. void zy1000_flush_callbackqueue(void);
  56. void zy1000_jtag_add_callback4(jtag_callback_t callback,
  57. jtag_callback_data_t data0,
  58. jtag_callback_data_t data1,
  59. jtag_callback_data_t data2,
  60. jtag_callback_data_t data3);
  61. void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0);
  62. #endif
  63. static inline void waitQueue(void)
  64. {
  65. /* waitIdle(); */
  66. }
  67. static inline void sampleShiftRegister(void)
  68. {
  69. #if 0
  70. uint32_t dummy;
  71. waitIdle();
  72. ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, dummy);
  73. #endif
  74. }
  75. static inline void setCurrentState(enum tap_state state)
  76. {
  77. uint32_t a;
  78. a = state;
  79. int repeat = 0;
  80. if (state == TAP_RESET) {
  81. /* The FPGA nor we know the current state of the CPU TAP */
  82. /* controller. This will move it to TAP for sure. */
  83. /* */
  84. /* 5 should be enough here, 7 is what OpenOCD uses */
  85. repeat = 7;
  86. }
  87. waitQueue();
  88. sampleShiftRegister();
  89. ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | a);
  90. }
  91. /*
  92. * Enter state and cause repeat transitions *out* of that state. So if the endState != state, then
  93. * the transition from state to endState counts as a transition out of state.
  94. */
  95. static inline void shiftValueInner(const enum tap_state state,
  96. const enum tap_state endState,
  97. int repeat,
  98. uint32_t value)
  99. {
  100. uint32_t a, b;
  101. a = state;
  102. b = endState;
  103. waitQueue();
  104. sampleShiftRegister();
  105. ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value);
  106. #if 1
  107. #if TEST_MANUAL()
  108. if ((state == TAP_DRSHIFT) && (endState != TAP_DRSHIFT)) {
  109. int i;
  110. setCurrentState(state);
  111. for (i = 0; i < repeat; i++) {
  112. int tms;
  113. tms = 0;
  114. if ((i == repeat-1) && (state != endState))
  115. tms = 1;
  116. /* shift out value */
  117. waitIdle();
  118. ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, (((value >> i)&1) << 1) | tms);
  119. }
  120. waitIdle();
  121. ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
  122. waitIdle();
  123. /* ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); // set this state and things
  124. * break => expected */
  125. ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRPAUSE); /* set this and things will
  126. * work => expected. Not
  127. * setting this is not
  128. * sufficient to make things
  129. * break. */
  130. setCurrentState(endState);
  131. } else
  132. ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
  133. #else
  134. /* fast version */
  135. ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
  136. #endif
  137. #else
  138. /* maximum debug version */
  139. if ((repeat > 0) && ((state == TAP_DRSHIFT) || (state == TAP_SI))) {
  140. int i;
  141. /* sample shift register for every bit. */
  142. for (i = 0; i < repeat-1; i++) {
  143. sampleShiftRegister();
  144. ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> i);
  145. ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | a);
  146. }
  147. sampleShiftRegister();
  148. ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> (repeat-1));
  149. ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | b);
  150. } else {
  151. sampleShiftRegister();
  152. ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
  153. }
  154. sampleShiftRegister();
  155. #endif
  156. }
  157. static inline void interface_jtag_add_dr_out_core(struct jtag_tap *target_tap,
  158. int num_fields,
  159. const int *num_bits,
  160. const uint32_t *value,
  161. enum tap_state end_state)
  162. {
  163. enum tap_state pause_state = TAP_DRSHIFT;
  164. struct jtag_tap *tap, *nextTap;
  165. for (tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = nextTap) {
  166. nextTap = jtag_tap_next_enabled(tap);
  167. if (nextTap == NULL)
  168. pause_state = end_state;
  169. if (tap == target_tap) {
  170. int j;
  171. for (j = 0; j < (num_fields-1); j++)
  172. shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[j], value[j]);
  173. shiftValueInner(TAP_DRSHIFT, pause_state, num_bits[j], value[j]);
  174. } else {
  175. /* program the scan field to 1 bit length, and ignore it's value */
  176. shiftValueInner(TAP_DRSHIFT, pause_state, 1, 0);
  177. }
  178. }
  179. }
  180. static inline void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
  181. int num_fields,
  182. const int *num_bits,
  183. const uint32_t *value,
  184. enum tap_state end_state)
  185. {
  186. int singletap = (jtag_tap_next_enabled(jtag_tap_next_enabled(NULL)) == NULL);
  187. if ((singletap) && (num_fields == 3)) {
  188. /* used by embeddedice_write_reg_inner() */
  189. shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[0], value[0]);
  190. shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[1], value[1]);
  191. shiftValueInner(TAP_DRSHIFT, end_state, num_bits[2], value[2]);
  192. } else if ((singletap) && (num_fields == 2)) {
  193. /* used by arm7 code */
  194. shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[0], value[0]);
  195. shiftValueInner(TAP_DRSHIFT, end_state, num_bits[1], value[1]);
  196. } else
  197. interface_jtag_add_dr_out_core(target_tap, num_fields, num_bits, value, end_state);
  198. }
  199. #if BUILD_ZY1000_MASTER
  200. #define interface_jtag_add_callback(callback, in) callback(in)
  201. #define interface_jtag_add_callback4(callback, in, data1, data2, \
  202. data3) jtag_set_error(callback(in, data1, data2, data3))
  203. #else
  204. #define interface_jtag_add_callback(callback, in) zy1000_jtag_add_callback(callback, in)
  205. #define interface_jtag_add_callback4(callback, in, data1, data2, data3) zy1000_jtag_add_callback4( \
  206. callback, \
  207. in, \
  208. data1, \
  209. data2, \
  210. data3)
  211. #endif