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.

gw16012.c 13 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /***************************************************************************
  2. * Copyright (C) 2006 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 "replacements.h"
  24. #include "jtag.h"
  25. #if 1
  26. #define _DEBUG_GW16012_IO_
  27. #endif
  28. /* system includes */
  29. /* -ino: 060521-1036 */
  30. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  31. #include <sys/types.h>
  32. #include <machine/sysarch.h>
  33. #include <machine/cpufunc.h>
  34. #define ioperm(startport,length,enable)\
  35. i386_set_ioperm((startport), (length), (enable))
  36. #else
  37. #ifdef _WIN32
  38. #include "errno.h"
  39. #endif /* _WIN32 */
  40. #endif /* __FreeBSD__, __FreeBSD_kernel__ */
  41. #include <string.h>
  42. #include <stdlib.h>
  43. #if PARPORT_USE_PPDEV == 1
  44. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  45. #include <dev/ppbus/ppi.h>
  46. #include <dev/ppbus/ppbconf.h>
  47. #define PPRSTATUS PPIGSTATUS
  48. #define PPWDATA PPISDATA
  49. #else
  50. #include <linux/parport.h>
  51. #include <linux/ppdev.h>
  52. #endif
  53. #include <fcntl.h>
  54. #include <sys/ioctl.h>
  55. #else /* not PARPORT_USE_PPDEV */
  56. #ifndef _WIN32
  57. #include <sys/io.h>
  58. #endif
  59. #endif
  60. #if PARPORT_USE_GIVEIO == 1
  61. #if IS_CYGWIN == 1
  62. #include <windows.h>
  63. #include <errno.h>
  64. #endif
  65. #endif
  66. #include "log.h"
  67. /* configuration */
  68. u16 gw16012_port;
  69. /* interface variables
  70. */
  71. static u8 gw16012_msb = 0x0;
  72. static u8 gw16012_control_value = 0x0;
  73. #if PARPORT_USE_PPDEV == 1
  74. static int device_handle;
  75. #endif
  76. int gw16012_execute_queue(void);
  77. int gw16012_register_commands(struct command_context_s *cmd_ctx);
  78. int gw16012_speed(int speed);
  79. int gw16012_init(void);
  80. int gw16012_quit(void);
  81. int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  82. jtag_interface_t gw16012_interface =
  83. {
  84. .name = "gw16012",
  85. .execute_queue = gw16012_execute_queue,
  86. .speed = gw16012_speed,
  87. .register_commands = gw16012_register_commands,
  88. .init = gw16012_init,
  89. .quit = gw16012_quit,
  90. };
  91. int gw16012_register_commands(struct command_context_s *cmd_ctx)
  92. {
  93. register_command(cmd_ctx, NULL, "parport_port", gw16012_handle_parport_port_command,
  94. COMMAND_CONFIG, NULL);
  95. return ERROR_OK;
  96. }
  97. void gw16012_data(u8 value)
  98. {
  99. value = (value & 0x7f) | gw16012_msb;
  100. gw16012_msb ^= 0x80; /* toggle MSB */
  101. #ifdef _DEBUG_GW16012_IO_
  102. LOG_DEBUG("%2.2x", value);
  103. #endif
  104. #if PARPORT_USE_PPDEV == 1
  105. ioctl(device_handle, PPWDATA, &value);
  106. #else
  107. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  108. outb(gw16012_port, value);
  109. #else
  110. outb(value, gw16012_port);
  111. #endif
  112. #endif
  113. }
  114. void gw16012_control(u8 value)
  115. {
  116. if (value != gw16012_control_value)
  117. {
  118. gw16012_control_value = value;
  119. #ifdef _DEBUG_GW16012_IO_
  120. LOG_DEBUG("%2.2x", gw16012_control_value);
  121. #endif
  122. #if PARPORT_USE_PPDEV == 1
  123. ioctl(device_handle, PPWCONTROL, &gw16012_control_value);
  124. #else
  125. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  126. outb(gw16012_port + 2, gw16012_control_value);
  127. #else
  128. outb(gw16012_control_value, gw16012_port + 2);
  129. #endif
  130. #endif
  131. }
  132. }
  133. void gw16012_input(u8 *value)
  134. {
  135. #if PARPORT_USE_PPDEV == 1
  136. ioctl(device_handle, PPRSTATUS, value);
  137. #else
  138. *value = inb(gw16012_port + 1);
  139. #endif
  140. #ifdef _DEBUG_GW16012_IO_
  141. LOG_DEBUG("%2.2x", *value);
  142. #endif
  143. }
  144. /* (1) assert or (0) deassert reset lines */
  145. void gw16012_reset(int trst, int srst)
  146. {
  147. LOG_DEBUG("trst: %i, srst: %i", trst, srst);
  148. if (trst == 0)
  149. gw16012_control(0x0d);
  150. else if (trst == 1)
  151. gw16012_control(0x0c);
  152. if (srst == 0)
  153. gw16012_control(0x0a);
  154. else if (srst == 1)
  155. gw16012_control(0x0b);
  156. }
  157. int gw16012_speed(int speed)
  158. {
  159. return ERROR_OK;
  160. }
  161. void gw16012_end_state(int state)
  162. {
  163. if (tap_move_map[state] != -1)
  164. end_state = state;
  165. else
  166. {
  167. LOG_ERROR("BUG: %i is not a valid end state", state);
  168. exit(-1);
  169. }
  170. }
  171. void gw16012_state_move(void)
  172. {
  173. int i=0, tms=0;
  174. u8 tms_scan = TAP_MOVE(cur_state, end_state);
  175. gw16012_control(0x0); /* single-bit mode */
  176. for (i = 0; i < 7; i++)
  177. {
  178. tms = (tms_scan >> i) & 1;
  179. gw16012_data(tms << 1); /* output next TMS bit */
  180. }
  181. cur_state = end_state;
  182. }
  183. void gw16012_path_move(pathmove_command_t *cmd)
  184. {
  185. int num_states = cmd->num_states;
  186. int state_count;
  187. state_count = 0;
  188. while (num_states)
  189. {
  190. gw16012_control(0x0); /* single-bit mode */
  191. if (tap_transitions[cur_state].low == cmd->path[state_count])
  192. {
  193. gw16012_data(0x0); /* TCK cycle with TMS low */
  194. }
  195. else if (tap_transitions[cur_state].high == cmd->path[state_count])
  196. {
  197. gw16012_data(0x2); /* TCK cycle with TMS high */
  198. }
  199. else
  200. {
  201. LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
  202. exit(-1);
  203. }
  204. cur_state = cmd->path[state_count];
  205. state_count++;
  206. num_states--;
  207. }
  208. end_state = cur_state;
  209. }
  210. void gw16012_runtest(int num_cycles)
  211. {
  212. enum tap_state saved_end_state = end_state;
  213. int i;
  214. /* only do a state_move when we're not already in IDLE */
  215. if (cur_state != TAP_IDLE)
  216. {
  217. gw16012_end_state(TAP_IDLE);
  218. gw16012_state_move();
  219. }
  220. for (i = 0; i < num_cycles; i++)
  221. {
  222. gw16012_control(0x0); /* single-bit mode */
  223. gw16012_data(0x0); /* TMS cycle with TMS low */
  224. }
  225. gw16012_end_state(saved_end_state);
  226. if (cur_state != end_state)
  227. gw16012_state_move();
  228. }
  229. void gw16012_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
  230. {
  231. int bits_left = scan_size;
  232. int bit_count = 0;
  233. enum tap_state saved_end_state = end_state;
  234. u8 scan_out, scan_in;
  235. /* only if we're not already in the correct Shift state */
  236. if (!((!ir_scan && (cur_state == TAP_DRSHIFT)) || (ir_scan && (cur_state == TAP_IRSHIFT))))
  237. {
  238. if (ir_scan)
  239. gw16012_end_state(TAP_IRSHIFT);
  240. else
  241. gw16012_end_state(TAP_DRSHIFT);
  242. gw16012_state_move();
  243. gw16012_end_state(saved_end_state);
  244. }
  245. while (type == SCAN_OUT && ((bits_left - 1) > 7))
  246. {
  247. gw16012_control(0x2); /* seven-bit mode */
  248. scan_out = buf_get_u32(buffer, bit_count, 7);
  249. gw16012_data(scan_out);
  250. bit_count += 7;
  251. bits_left -= 7;
  252. }
  253. gw16012_control(0x0); /* single-bit mode */
  254. while (bits_left-- > 0)
  255. {
  256. u8 tms = 0;
  257. scan_out = buf_get_u32(buffer, bit_count, 1);
  258. if (bits_left == 0) /* last bit */
  259. {
  260. if ((ir_scan && (end_state == TAP_IRSHIFT))
  261. || (!ir_scan && (end_state == TAP_DRSHIFT)))
  262. {
  263. tms = 0;
  264. }
  265. else
  266. {
  267. tms = 2;
  268. }
  269. }
  270. gw16012_data(scan_out | tms);
  271. if (type != SCAN_OUT)
  272. {
  273. gw16012_input(&scan_in);
  274. buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3));
  275. }
  276. bit_count++;
  277. }
  278. if (!((ir_scan && (end_state == TAP_IRSHIFT)) ||
  279. (!ir_scan && (end_state == TAP_DRSHIFT))))
  280. {
  281. gw16012_data(0x0);
  282. if (ir_scan)
  283. cur_state = TAP_IRPAUSE;
  284. else
  285. cur_state = TAP_DRPAUSE;
  286. if (cur_state != end_state)
  287. gw16012_state_move();
  288. }
  289. }
  290. int gw16012_execute_queue(void)
  291. {
  292. jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
  293. int scan_size;
  294. enum scan_type type;
  295. u8 *buffer;
  296. int retval;
  297. /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
  298. * that wasn't handled by a caller-provided error handler
  299. */
  300. retval = ERROR_OK;
  301. while (cmd)
  302. {
  303. switch (cmd->type)
  304. {
  305. case JTAG_END_STATE:
  306. #ifdef _DEBUG_JTAG_IO_
  307. LOG_DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
  308. #endif
  309. if (cmd->cmd.end_state->end_state != -1)
  310. gw16012_end_state(cmd->cmd.end_state->end_state);
  311. break;
  312. case JTAG_RESET:
  313. #ifdef _DEBUG_JTAG_IO_
  314. LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
  315. #endif
  316. if (cmd->cmd.reset->trst == 1)
  317. {
  318. cur_state = TAP_RESET;
  319. }
  320. gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
  321. break;
  322. case JTAG_RUNTEST:
  323. #ifdef _DEBUG_JTAG_IO_
  324. LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
  325. #endif
  326. if (cmd->cmd.runtest->end_state != -1)
  327. gw16012_end_state(cmd->cmd.runtest->end_state);
  328. gw16012_runtest(cmd->cmd.runtest->num_cycles);
  329. break;
  330. case JTAG_STATEMOVE:
  331. #ifdef _DEBUG_JTAG_IO_
  332. LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
  333. #endif
  334. if (cmd->cmd.statemove->end_state != -1)
  335. gw16012_end_state(cmd->cmd.statemove->end_state);
  336. gw16012_state_move();
  337. break;
  338. case JTAG_PATHMOVE:
  339. #ifdef _DEBUG_JTAG_IO_
  340. LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
  341. #endif
  342. gw16012_path_move(cmd->cmd.pathmove);
  343. break;
  344. case JTAG_SCAN:
  345. if (cmd->cmd.scan->end_state != -1)
  346. gw16012_end_state(cmd->cmd.scan->end_state);
  347. scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
  348. type = jtag_scan_type(cmd->cmd.scan);
  349. #ifdef _DEBUG_JTAG_IO_
  350. LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd->cmd.scan->ir_scan) ? "ir" : "dr",
  351. type, scan_size, cmd->cmd.scan->end_state);
  352. #endif
  353. gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
  354. if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
  355. retval = ERROR_JTAG_QUEUE_FAILED;
  356. if (buffer)
  357. free(buffer);
  358. break;
  359. case JTAG_SLEEP:
  360. #ifdef _DEBUG_JTAG_IO_
  361. LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
  362. #endif
  363. jtag_sleep(cmd->cmd.sleep->us);
  364. break;
  365. default:
  366. LOG_ERROR("BUG: unknown JTAG command type encountered");
  367. exit(-1);
  368. }
  369. cmd = cmd->next;
  370. }
  371. return retval;
  372. }
  373. #if PARPORT_USE_GIVEIO == 1
  374. int gw16012_get_giveio_access()
  375. {
  376. HANDLE h;
  377. OSVERSIONINFO version;
  378. version.dwOSVersionInfoSize = sizeof version;
  379. if (!GetVersionEx( &version )) {
  380. errno = EINVAL;
  381. return -1;
  382. }
  383. if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
  384. return 0;
  385. h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  386. if (h == INVALID_HANDLE_VALUE) {
  387. errno = ENODEV;
  388. return -1;
  389. }
  390. CloseHandle( h );
  391. return 0;
  392. }
  393. #endif
  394. int gw16012_init(void)
  395. {
  396. #if PARPORT_USE_PPDEV == 1
  397. char buffer[256];
  398. int i = 0;
  399. #endif
  400. u8 status_port;
  401. #if PARPORT_USE_PPDEV == 1
  402. if (device_handle>0)
  403. {
  404. LOG_ERROR("device is already opened");
  405. return ERROR_JTAG_INIT_FAILED;
  406. }
  407. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  408. LOG_DEBUG("opening /dev/ppi%d...", gw16012_port);
  409. snprintf(buffer, 256, "/dev/ppi%d", gw16012_port);
  410. device_handle = open(buffer, O_WRONLY);
  411. #else
  412. LOG_DEBUG("opening /dev/parport%d...", gw16012_port);
  413. snprintf(buffer, 256, "/dev/parport%d", gw16012_port);
  414. device_handle = open(buffer, O_WRONLY);
  415. #endif
  416. if (device_handle<0)
  417. {
  418. LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
  419. return ERROR_JTAG_INIT_FAILED;
  420. }
  421. LOG_DEBUG("...open");
  422. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  423. i=ioctl(device_handle, PPCLAIM);
  424. if (i<0)
  425. {
  426. LOG_ERROR("cannot claim device");
  427. return ERROR_JTAG_INIT_FAILED;
  428. }
  429. i = PARPORT_MODE_COMPAT;
  430. i= ioctl(device_handle, PPSETMODE, & i);
  431. if (i<0)
  432. {
  433. LOG_ERROR(" cannot set compatible mode to device");
  434. return ERROR_JTAG_INIT_FAILED;
  435. }
  436. i = IEEE1284_MODE_COMPAT;
  437. i = ioctl(device_handle, PPNEGOT, & i);
  438. if (i<0)
  439. {
  440. LOG_ERROR("cannot set compatible 1284 mode to device");
  441. return ERROR_JTAG_INIT_FAILED;
  442. }
  443. #endif
  444. #else
  445. if (gw16012_port == 0)
  446. {
  447. gw16012_port = 0x378;
  448. LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
  449. }
  450. LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port) );
  451. #if PARPORT_USE_GIVEIO == 1
  452. if (gw16012_get_giveio_access() != 0)
  453. #else /* PARPORT_USE_GIVEIO */
  454. if (ioperm(gw16012_port, 3, 1) != 0)
  455. #endif /* PARPORT_USE_GIVEIO */
  456. {
  457. LOG_ERROR("missing privileges for direct i/o");
  458. return ERROR_JTAG_INIT_FAILED;
  459. }
  460. LOG_DEBUG("...privileges granted");
  461. /* make sure parallel port is in right mode (clear tristate and interrupt */
  462. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  463. outb(gw16012_port + 2, 0x0);
  464. #else
  465. outb(0x0, gw16012_port + 2);
  466. #endif
  467. #endif /* PARPORT_USE_PPDEV */
  468. gw16012_input(&status_port);
  469. gw16012_msb = (status_port & 0x80) ^ 0x80;
  470. gw16012_speed(jtag_speed);
  471. gw16012_reset(0, 0);
  472. return ERROR_OK;
  473. }
  474. int gw16012_quit(void)
  475. {
  476. return ERROR_OK;
  477. }
  478. int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  479. {
  480. if (argc == 0)
  481. return ERROR_OK;
  482. /* only if the port wasn't overwritten by cmdline */
  483. if (gw16012_port == 0)
  484. gw16012_port = strtoul(args[0], NULL, 0);
  485. return ERROR_OK;
  486. }