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.
 
 
 
 
 
 

562 lines
15 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "interface.h"
  24. #include "commands.h"
  25. #if PARPORT_USE_PPDEV == 1
  26. #include <linux/parport.h>
  27. #include <linux/ppdev.h>
  28. #include <sys/ioctl.h>
  29. #else /* not PARPORT_USE_PPDEV */
  30. #ifndef _WIN32
  31. #include <sys/io.h>
  32. #endif
  33. #endif
  34. #if PARPORT_USE_GIVEIO == 1
  35. #if IS_CYGWIN == 1
  36. #include <windows.h>
  37. #endif
  38. #endif
  39. /* configuration */
  40. static u16 amt_jtagaccel_port;
  41. /* interface variables
  42. */
  43. static u8 aw_control_rst = 0x00;
  44. static u8 aw_control_fsm = 0x10;
  45. static u8 aw_control_baudrate = 0x20;
  46. static int rtck_enabled = 0;
  47. #if PARPORT_USE_PPDEV == 1
  48. static int device_handle;
  49. static int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR ;
  50. #define AMT_AW(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); write(device_handle, &val, 1); } while (0)
  51. #define AMT_AR(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); read(device_handle, &val, 1); } while (0)
  52. static int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA ;
  53. #define AMT_DW(val) do { ioctl(device_handle, PPSETMODE, &data_mode); write(device_handle, &val, 1); } while (0)
  54. #define AMT_DR(val) do { ioctl(device_handle, PPSETMODE, &data_mode); read(device_handle, &val, 1); } while (0)
  55. #else
  56. #define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0)
  57. #define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0)
  58. #define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0)
  59. #define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0)
  60. #endif // PARPORT_USE_PPDEV
  61. static int amt_jtagaccel_execute_queue(void);
  62. static int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx);
  63. static int amt_jtagaccel_speed(int speed);
  64. static int amt_jtagaccel_init(void);
  65. static int amt_jtagaccel_quit(void);
  66. static int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  67. static int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  68. /* tap_move[i][j]: tap movement command to go from state i to state j
  69. * 0: Test-Logic-Reset
  70. * 1: Run-Test/Idle
  71. * 2: Shift-DR
  72. * 3: Pause-DR
  73. * 4: Shift-IR
  74. * 5: Pause-IR
  75. */
  76. static u8 amt_jtagaccel_tap_move[6][6][2] =
  77. {
  78. /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
  79. {{0x1f, 0x00}, {0x0f, 0x00}, {0x8a, 0x04}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* RESET */
  80. {{0x1f, 0x00}, {0x00, 0x00}, {0x85, 0x08}, {0x05, 0x00}, {0x8b, 0x08}, {0x0b, 0x00}}, /* IDLE */
  81. {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRSHIFT */
  82. {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRPAUSE */
  83. {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* IRSHIFT */
  84. {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* IRPAUSE */
  85. };
  86. jtag_interface_t amt_jtagaccel_interface =
  87. {
  88. .name = "amt_jtagaccel",
  89. .execute_queue = amt_jtagaccel_execute_queue,
  90. .speed = amt_jtagaccel_speed,
  91. .register_commands = amt_jtagaccel_register_commands,
  92. .init = amt_jtagaccel_init,
  93. .quit = amt_jtagaccel_quit,
  94. };
  95. static int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx)
  96. {
  97. register_command(cmd_ctx, NULL, "parport_port", amt_jtagaccel_handle_parport_port_command,
  98. COMMAND_CONFIG, NULL);
  99. register_command(cmd_ctx, NULL, "rtck", amt_jtagaccel_handle_rtck_command,
  100. COMMAND_CONFIG, NULL);
  101. return ERROR_OK;
  102. }
  103. static void amt_jtagaccel_reset(int trst, int srst)
  104. {
  105. if (trst == 1)
  106. aw_control_rst |= 0x4;
  107. else if (trst == 0)
  108. aw_control_rst &= ~0x4;
  109. if (srst == 1)
  110. aw_control_rst |= 0x1;
  111. else if (srst == 0)
  112. aw_control_rst &= ~0x1;
  113. AMT_AW(aw_control_rst);
  114. }
  115. static int amt_jtagaccel_speed(int speed)
  116. {
  117. aw_control_baudrate &= 0xf0;
  118. aw_control_baudrate |= speed & 0x0f;
  119. AMT_AW(aw_control_baudrate);
  120. return ERROR_OK;
  121. }
  122. static void amt_jtagaccel_end_state(tap_state_t state)
  123. {
  124. if (tap_is_state_stable(state))
  125. tap_set_end_state(state);
  126. else
  127. {
  128. LOG_ERROR("BUG: %i is not a valid end state", state);
  129. exit(-1);
  130. }
  131. }
  132. static void amt_wait_scan_busy(void)
  133. {
  134. int timeout = 4096;
  135. u8 ar_status;
  136. AMT_AR(ar_status);
  137. while (((ar_status) & 0x80) && (timeout-- > 0))
  138. AMT_AR(ar_status);
  139. if (ar_status & 0x80)
  140. {
  141. LOG_ERROR("amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x", (rtck_enabled) ? "enabled" : "disabled", ar_status);
  142. exit(-1);
  143. }
  144. }
  145. static void amt_jtagaccel_state_move(void)
  146. {
  147. u8 aw_scan_tms_5;
  148. u8 tms_scan[2];
  149. tap_state_t cur_state = tap_get_state();
  150. tap_state_t end_state = tap_get_end_state();
  151. tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0];
  152. tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1];
  153. aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f);
  154. AMT_AW(aw_scan_tms_5);
  155. int jtag_speed = jtag_get_speed();
  156. if (jtag_speed > 3 || rtck_enabled)
  157. amt_wait_scan_busy();
  158. if (tms_scan[0] & 0x80)
  159. {
  160. aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f);
  161. AMT_AW(aw_scan_tms_5);
  162. if (jtag_speed > 3 || rtck_enabled)
  163. amt_wait_scan_busy();
  164. }
  165. tap_set_state(end_state);
  166. }
  167. static void amt_jtagaccel_runtest(int num_cycles)
  168. {
  169. int i = 0;
  170. u8 aw_scan_tms_5;
  171. u8 aw_scan_tms_1to4;
  172. tap_state_t saved_end_state = tap_get_end_state();
  173. /* only do a state_move when we're not already in IDLE */
  174. if (tap_get_state() != TAP_IDLE)
  175. {
  176. amt_jtagaccel_end_state(TAP_IDLE);
  177. amt_jtagaccel_state_move();
  178. }
  179. while (num_cycles - i >= 5)
  180. {
  181. aw_scan_tms_5 = 0x40;
  182. AMT_AW(aw_scan_tms_5);
  183. i += 5;
  184. }
  185. if (num_cycles - i > 0)
  186. {
  187. aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4;
  188. AMT_AW(aw_scan_tms_1to4);
  189. }
  190. amt_jtagaccel_end_state(saved_end_state);
  191. if (tap_get_state() != tap_get_end_state())
  192. amt_jtagaccel_state_move();
  193. }
  194. static void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, u8 *buffer, int scan_size)
  195. {
  196. int bits_left = scan_size;
  197. int bit_count = 0;
  198. tap_state_t saved_end_state = tap_get_end_state();
  199. u8 aw_tdi_option;
  200. u8 dw_tdi_scan;
  201. u8 dr_tdo;
  202. u8 aw_tms_scan;
  203. u8 tms_scan[2];
  204. int jtag_speed = jtag_get_speed();
  205. if (ir_scan)
  206. amt_jtagaccel_end_state(TAP_IRSHIFT);
  207. else
  208. amt_jtagaccel_end_state(TAP_DRSHIFT);
  209. amt_jtagaccel_state_move();
  210. amt_jtagaccel_end_state(saved_end_state);
  211. /* handle unaligned bits at the beginning */
  212. if ((scan_size - 1) % 8)
  213. {
  214. aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1);
  215. AMT_AW(aw_tdi_option);
  216. dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff;
  217. AMT_DW(dw_tdi_scan);
  218. if (jtag_speed > 3 || rtck_enabled)
  219. amt_wait_scan_busy();
  220. if ((type == SCAN_IN) || (type == SCAN_IO))
  221. {
  222. AMT_DR(dr_tdo);
  223. dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8));
  224. buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo);
  225. }
  226. bit_count += (scan_size - 1) % 8;
  227. bits_left -= (scan_size - 1) % 8;
  228. }
  229. while (bits_left - 1 >= 8)
  230. {
  231. dw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff;
  232. AMT_DW(dw_tdi_scan);
  233. if (jtag_speed > 3 || rtck_enabled)
  234. amt_wait_scan_busy();
  235. if ((type == SCAN_IN) || (type == SCAN_IO))
  236. {
  237. AMT_DR(dr_tdo);
  238. buf_set_u32(buffer, bit_count, 8, dr_tdo);
  239. }
  240. bit_count += 8;
  241. bits_left -= 8;
  242. }
  243. tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
  244. tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
  245. aw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5);
  246. AMT_AW(aw_tms_scan);
  247. if (jtag_speed > 3 || rtck_enabled)
  248. amt_wait_scan_busy();
  249. if ((type == SCAN_IN) || (type == SCAN_IO))
  250. {
  251. AMT_DR(dr_tdo);
  252. dr_tdo = dr_tdo >> 7;
  253. buf_set_u32(buffer, bit_count, 1, dr_tdo);
  254. }
  255. if (tms_scan[0] & 0x80)
  256. {
  257. aw_tms_scan = 0x40 | (tms_scan[1] & 0x1f);
  258. AMT_AW(aw_tms_scan);
  259. if (jtag_speed > 3 || rtck_enabled)
  260. amt_wait_scan_busy();
  261. }
  262. tap_set_state(tap_get_end_state());
  263. }
  264. static int amt_jtagaccel_execute_queue(void)
  265. {
  266. jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
  267. int scan_size;
  268. enum scan_type type;
  269. u8 *buffer;
  270. int retval;
  271. /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
  272. * that wasn't handled by a caller-provided error handler
  273. */
  274. retval = ERROR_OK;
  275. while (cmd)
  276. {
  277. switch (cmd->type)
  278. {
  279. case JTAG_RESET:
  280. #ifdef _DEBUG_JTAG_IO_
  281. LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
  282. #endif
  283. if (cmd->cmd.reset->trst == 1)
  284. {
  285. tap_set_state(TAP_RESET);
  286. }
  287. amt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
  288. break;
  289. case JTAG_RUNTEST:
  290. #ifdef _DEBUG_JTAG_IO_
  291. LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
  292. #endif
  293. amt_jtagaccel_end_state(cmd->cmd.runtest->end_state);
  294. amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles);
  295. break;
  296. case JTAG_STATEMOVE:
  297. #ifdef _DEBUG_JTAG_IO_
  298. LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
  299. #endif
  300. amt_jtagaccel_end_state(cmd->cmd.statemove->end_state);
  301. amt_jtagaccel_state_move();
  302. break;
  303. case JTAG_SCAN:
  304. #ifdef _DEBUG_JTAG_IO_
  305. LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
  306. #endif
  307. amt_jtagaccel_end_state(cmd->cmd.scan->end_state);
  308. scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
  309. type = jtag_scan_type(cmd->cmd.scan);
  310. amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
  311. if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
  312. retval = ERROR_JTAG_QUEUE_FAILED;
  313. if (buffer)
  314. free(buffer);
  315. break;
  316. case JTAG_SLEEP:
  317. #ifdef _DEBUG_JTAG_IO_
  318. LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
  319. #endif
  320. jtag_sleep(cmd->cmd.sleep->us);
  321. break;
  322. default:
  323. LOG_ERROR("BUG: unknown JTAG command type encountered");
  324. exit(-1);
  325. }
  326. cmd = cmd->next;
  327. }
  328. return retval;
  329. }
  330. #if PARPORT_USE_GIVEIO == 1
  331. int amt_jtagaccel_get_giveio_access(void)
  332. {
  333. HANDLE h;
  334. OSVERSIONINFO version;
  335. version.dwOSVersionInfoSize = sizeof version;
  336. if (!GetVersionEx( &version )) {
  337. errno = EINVAL;
  338. return -1;
  339. }
  340. if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
  341. return 0;
  342. h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  343. if (h == INVALID_HANDLE_VALUE) {
  344. errno = ENODEV;
  345. return -1;
  346. }
  347. CloseHandle( h );
  348. return 0;
  349. }
  350. #endif
  351. static int amt_jtagaccel_init(void)
  352. {
  353. #if PARPORT_USE_PPDEV == 1
  354. char buffer[256];
  355. int i = 0;
  356. u8 control_port;
  357. #else
  358. u8 status_port;
  359. #endif
  360. u8 ar_status;
  361. #if PARPORT_USE_PPDEV == 1
  362. if (device_handle > 0)
  363. {
  364. LOG_ERROR("device is already opened");
  365. return ERROR_JTAG_INIT_FAILED;
  366. }
  367. snprintf(buffer, 256, "/dev/parport%d", amt_jtagaccel_port);
  368. device_handle = open(buffer, O_RDWR);
  369. if (device_handle < 0)
  370. {
  371. LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
  372. return ERROR_JTAG_INIT_FAILED;
  373. }
  374. i = ioctl(device_handle, PPCLAIM);
  375. if (i < 0)
  376. {
  377. LOG_ERROR("cannot claim device");
  378. return ERROR_JTAG_INIT_FAILED;
  379. }
  380. i = IEEE1284_MODE_EPP;
  381. i = ioctl(device_handle, PPSETMODE, & i);
  382. if (i < 0)
  383. {
  384. LOG_ERROR(" cannot set compatible mode to device");
  385. return ERROR_JTAG_INIT_FAILED;
  386. }
  387. control_port = 0x00;
  388. i = ioctl(device_handle, PPWCONTROL, &control_port);
  389. control_port = 0x04;
  390. i = ioctl(device_handle, PPWCONTROL, &control_port);
  391. #else
  392. if (amt_jtagaccel_port == 0)
  393. {
  394. amt_jtagaccel_port = 0x378;
  395. LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
  396. }
  397. #if PARPORT_USE_GIVEIO == 1
  398. if (amt_jtagaccel_get_giveio_access() != 0) {
  399. #else /* PARPORT_USE_GIVEIO */
  400. if (ioperm(amt_jtagaccel_port, 5, 1) != 0) {
  401. #endif /* PARPORT_USE_GIVEIO */
  402. LOG_ERROR("missing privileges for direct i/o");
  403. return ERROR_JTAG_INIT_FAILED;
  404. }
  405. /* prepare epp port */
  406. /* clear timeout */
  407. status_port = inb(amt_jtagaccel_port + 1);
  408. outb(status_port | 0x1, amt_jtagaccel_port + 1);
  409. /* reset epp port */
  410. outb(0x00, amt_jtagaccel_port + 2);
  411. outb(0x04, amt_jtagaccel_port + 2);
  412. #endif
  413. if (rtck_enabled)
  414. {
  415. /* set RTCK enable bit */
  416. aw_control_fsm |= 0x02;
  417. }
  418. /* enable JTAG port */
  419. aw_control_fsm |= 0x04;
  420. AMT_AW(aw_control_fsm);
  421. amt_jtagaccel_speed(jtag_get_speed());
  422. enum reset_types jtag_reset_config = jtag_get_reset_config();
  423. if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
  424. aw_control_rst &= ~0x8;
  425. else
  426. aw_control_rst |= 0x8;
  427. if (jtag_reset_config & RESET_SRST_PUSH_PULL)
  428. aw_control_rst &= ~0x2;
  429. else
  430. aw_control_rst |= 0x2;
  431. amt_jtagaccel_reset(0, 0);
  432. /* read status register */
  433. AMT_AR(ar_status);
  434. LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status);
  435. return ERROR_OK;
  436. }
  437. static int amt_jtagaccel_quit(void)
  438. {
  439. return ERROR_OK;
  440. }
  441. static int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  442. {
  443. if (argc == 0)
  444. return ERROR_OK;
  445. /* only if the port wasn't overwritten by cmdline */
  446. if (amt_jtagaccel_port == 0)
  447. amt_jtagaccel_port = strtoul(args[0], NULL, 0);
  448. return ERROR_OK;
  449. }
  450. static int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  451. {
  452. if (argc == 0)
  453. {
  454. command_print(cmd_ctx, "amt_jtagaccel RTCK feature %s", (rtck_enabled) ? "enabled" : "disabled");
  455. return ERROR_OK;
  456. }
  457. else
  458. {
  459. if (strcmp(args[0], "enabled") == 0)
  460. {
  461. rtck_enabled = 1;
  462. }
  463. else
  464. {
  465. rtck_enabled = 0;
  466. }
  467. }
  468. return ERROR_OK;
  469. }