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.
 
 
 
 
 
 

508 lines
11 KiB

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