OpenOCD
gw16012.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2006 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include <jtag/interface.h>
13 #include <jtag/commands.h>
14 
15 #if 1
16 #define _DEBUG_GW16012_IO_
17 #endif
18 
19 /* system includes */
20 /* -ino: 060521-1036 */
21 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
22 
23 #include <machine/sysarch.h>
24 #include <machine/cpufunc.h>
25 #define ioperm(startport, length, enable) \
26  386_set_ioperm((startport), (length), (enable))
27 
28 #else
29 
30 #endif /* __FreeBSD__, __FreeBSD_kernel__ */
31 
32 #if PARPORT_USE_PPDEV == 1
33 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
34 #include <dev/ppbus/ppi.h>
35 #include <dev/ppbus/ppbconf.h>
36 #define PPRSTATUS PPIGSTATUS
37 #define PPWDATA PPISDATA
38 #else
39 #include <linux/parport.h>
40 #include <linux/ppdev.h>
41 #endif
42 #include <fcntl.h>
43 #include <sys/ioctl.h>
44 #else /* not PARPORT_USE_PPDEV */
45 #ifndef _WIN32
46 #include <sys/io.h>
47 #endif
48 #endif
49 
50 #if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1
51 #include <windows.h>
52 #endif
53 
54 /* configuration */
55 static uint16_t gw16012_port;
56 
57 /* interface variables
58  */
59 static uint8_t gw16012_msb;
60 static uint8_t gw16012_control_value;
61 
62 #if PARPORT_USE_PPDEV == 1
63 static int device_handle;
64 #endif
65 
66 static void gw16012_data(uint8_t value)
67 {
68  value = (value & 0x7f) | gw16012_msb;
69  gw16012_msb ^= 0x80; /* toggle MSB */
70 
71 #ifdef _DEBUG_GW16012_IO_
72  LOG_DEBUG("%2.2x", value);
73 #endif
74 
75  #if PARPORT_USE_PPDEV == 1
76  ioctl(device_handle, PPWDATA, &value);
77  #else
78  #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
79  outb(gw16012_port, value);
80  #else
81  outb(value, gw16012_port);
82  #endif
83  #endif
84 }
85 
86 static void gw16012_control(uint8_t value)
87 {
88  if (value != gw16012_control_value) {
89  gw16012_control_value = value;
90 
91 #ifdef _DEBUG_GW16012_IO_
93 #endif
94 
95  #if PARPORT_USE_PPDEV == 1
96  ioctl(device_handle, PPWCONTROL, &gw16012_control_value);
97  #else
98  #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
100  #else
102  #endif
103  #endif
104  }
105 }
106 
107 static void gw16012_input(uint8_t *value)
108 {
109  #if PARPORT_USE_PPDEV == 1
110  ioctl(device_handle, PPRSTATUS, value);
111  #else
112  *value = inb(gw16012_port + 1);
113  #endif
114 
115 #ifdef _DEBUG_GW16012_IO_
116  LOG_DEBUG("%2.2x", *value);
117 #endif
118 }
119 
120 /* (1) assert or (0) deassert reset lines */
121 static void gw16012_reset(int trst, int srst)
122 {
123  LOG_DEBUG("trst: %i, srst: %i", trst, srst);
124 
125  if (trst == 0)
126  gw16012_control(0x0d);
127  else if (trst == 1)
128  gw16012_control(0x0c);
129 
130  if (srst == 0)
131  gw16012_control(0x0a);
132  else if (srst == 1)
133  gw16012_control(0x0b);
134 }
135 
137 {
140  else {
141  LOG_ERROR("BUG: %i is not a valid end state", state);
142  exit(-1);
143  }
144 }
145 
146 static void gw16012_state_move(void)
147 {
148  int i = 0, tms = 0;
149  uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
151 
152  gw16012_control(0x0); /* single-bit mode */
153 
154  for (i = 0; i < tms_count; i++) {
155  tms = (tms_scan >> i) & 1;
156  gw16012_data(tms << 1); /* output next TMS bit */
157  }
158 
160 }
161 
163 {
164  int num_states = cmd->num_states;
165  int state_count;
166 
167  state_count = 0;
168  while (num_states) {
169  gw16012_control(0x0); /* single-bit mode */
170  if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])
171  gw16012_data(0x0); /* TCK cycle with TMS low */
172  else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])
173  gw16012_data(0x2); /* TCK cycle with TMS high */
174  else {
175  LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
176  tap_state_name(tap_get_state()), tap_state_name(cmd->path[state_count]));
177  exit(-1);
178  }
179 
180  tap_set_state(cmd->path[state_count]);
181  state_count++;
182  num_states--;
183  }
184 
186 }
187 
188 static void gw16012_runtest(unsigned int num_cycles)
189 {
190  tap_state_t saved_end_state = tap_get_end_state();
191 
192  /* only do a state_move when we're not already in IDLE */
193  if (tap_get_state() != TAP_IDLE) {
196  }
197 
198  for (unsigned int i = 0; i < num_cycles; i++) {
199  gw16012_control(0x0); /* single-bit mode */
200  gw16012_data(0x0); /* TMS cycle with TMS low */
201  }
202 
203  gw16012_end_state(saved_end_state);
204  if (tap_get_state() != tap_get_end_state())
206 }
207 
208 static void gw16012_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
209 {
210  int bits_left = scan_size;
211  int bit_count = 0;
212  tap_state_t saved_end_state = tap_get_end_state();
213  uint8_t scan_out, scan_in;
214 
215  /* only if we're not already in the correct Shift state */
216  if (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) ||
217  (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {
218  if (ir_scan)
220  else
222 
224  gw16012_end_state(saved_end_state);
225  }
226 
227  while (type == SCAN_OUT && ((bits_left - 1) > 7)) {
228  gw16012_control(0x2); /* seven-bit mode */
229  scan_out = buf_get_u32(buffer, bit_count, 7);
230  gw16012_data(scan_out);
231  bit_count += 7;
232  bits_left -= 7;
233  }
234 
235  gw16012_control(0x0); /* single-bit mode */
236  while (bits_left-- > 0) {
237  uint8_t tms = 0;
238 
239  scan_out = buf_get_u32(buffer, bit_count, 1);
240 
241  if (bits_left == 0) /* last bit */ {
242  if ((ir_scan && (tap_get_end_state() == TAP_IRSHIFT))
243  || (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT)))
244  tms = 0;
245  else
246  tms = 2;
247  }
248 
249  gw16012_data(scan_out | tms);
250 
251  if (type != SCAN_OUT) {
252  gw16012_input(&scan_in);
253  buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3));
254  }
255 
256  bit_count++;
257  }
258 
259  if (!((ir_scan && (tap_get_end_state() == TAP_IRSHIFT)) ||
260  (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT)))) {
261  gw16012_data(0x0);
262  if (ir_scan)
264  else
266 
267  if (tap_get_state() != tap_get_end_state())
269  }
270 }
271 
272 static int gw16012_execute_queue(struct jtag_command *cmd_queue)
273 {
274  struct jtag_command *cmd = cmd_queue; /* currently processed command */
275  int scan_size;
276  enum scan_type type;
277  uint8_t *buffer;
278  int retval;
279 
280  /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
281  * that wasn't handled by a caller-provided error handler
282  */
283  retval = ERROR_OK;
284 
285  while (cmd) {
286  switch (cmd->type) {
287  case JTAG_RESET:
288  LOG_DEBUG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
289  if (cmd->cmd.reset->trst == 1)
291  gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
292  break;
293  case JTAG_RUNTEST:
294  LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles,
295  cmd->cmd.runtest->end_state);
296  gw16012_end_state(cmd->cmd.runtest->end_state);
297  gw16012_runtest(cmd->cmd.runtest->num_cycles);
298  break;
299  case JTAG_TLR_RESET:
300  LOG_DEBUG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
301  gw16012_end_state(cmd->cmd.statemove->end_state);
303  break;
304  case JTAG_PATHMOVE:
305  LOG_DEBUG_IO("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
306  cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
307  gw16012_path_move(cmd->cmd.pathmove);
308  break;
309  case JTAG_SCAN:
310  gw16012_end_state(cmd->cmd.scan->end_state);
311  scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
312  type = jtag_scan_type(cmd->cmd.scan);
313  LOG_DEBUG_IO("%s scan (%i) %i bit end in %i", (cmd->cmd.scan->ir_scan) ? "ir" : "dr",
314  type, scan_size, cmd->cmd.scan->end_state);
315  gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
316  if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
317  retval = ERROR_JTAG_QUEUE_FAILED;
318  free(buffer);
319  break;
320  case JTAG_SLEEP:
321  LOG_DEBUG_IO("sleep %" PRIu32, cmd->cmd.sleep->us);
322  jtag_sleep(cmd->cmd.sleep->us);
323  break;
324  default:
325  LOG_ERROR("BUG: unknown JTAG command type encountered");
326  exit(-1);
327  }
328  cmd = cmd->next;
329  }
330 
331  return retval;
332 }
333 
334 #if PARPORT_USE_GIVEIO == 1
335 static int gw16012_get_giveio_access(void)
336 {
337  HANDLE h;
338  OSVERSIONINFO version;
339 
340  version.dwOSVersionInfoSize = sizeof(version);
341  if (!GetVersionEx(&version)) {
342  errno = EINVAL;
343  return -1;
344  }
345  if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
346  return 0;
347 
348  h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING,
349  FILE_ATTRIBUTE_NORMAL, NULL);
350  if (h == INVALID_HANDLE_VALUE) {
351  errno = ENODEV;
352  return -1;
353  }
354 
355  CloseHandle(h);
356 
357  return 0;
358 }
359 #endif
360 
361 #if PARPORT_USE_PPDEV == 1
362 
363 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
364 
365 #define GW16012_PPDEV_NAME "ppi"
366 
367 static int gw16012_init_ioctls(void)
368 {
369  int temp = 0;
370  temp = ioctl(device_handle, PPCLAIM);
371  if (temp < 0) {
372  LOG_ERROR("cannot claim device");
373  return ERROR_JTAG_INIT_FAILED;
374  }
375 
376  temp = PARPORT_MODE_COMPAT;
377  temp = ioctl(device_handle, PPSETMODE, &temp);
378  if (temp < 0) {
379  LOG_ERROR(" cannot set compatible mode to device");
380  return ERROR_JTAG_INIT_FAILED;
381  }
382 
383  temp = IEEE1284_MODE_COMPAT;
384  temp = ioctl(device_handle, PPNEGOT, &temp);
385  if (temp < 0) {
386  LOG_ERROR("cannot set compatible 1284 mode to device");
387  return ERROR_JTAG_INIT_FAILED;
388  }
389  return ERROR_OK;
390 }
391 #else
392 
393 #define GW16012_PPDEV_NAME "parport"
394 
395 static int gw16012_init_ioctls(void)
396 {
397  return ERROR_OK;
398 }
399 
400 #endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */
401 
402 static int gw16012_init_device(void)
403 {
404  const char *device_name = GW16012_PPDEV_NAME;
405  char buffer[256];
406 
407  if (device_handle > 0) {
408  LOG_ERROR("device is already opened");
409  return ERROR_JTAG_INIT_FAILED;
410  }
411 
412  snprintf(buffer, 256, "/dev/%s%d", device_name, gw16012_port);
413  LOG_DEBUG("opening %s...", buffer);
414 
415  device_handle = open(buffer, O_WRONLY);
416  if (device_handle < 0) {
417  LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
418  return ERROR_JTAG_INIT_FAILED;
419  }
420 
421  LOG_DEBUG("...open");
422 
423  if (gw16012_init_ioctls() != ERROR_OK)
424  return ERROR_JTAG_INIT_FAILED;
425 
426  return ERROR_OK;
427 }
428 
429 #else /* PARPORT_USE_PPDEV */
430 
431 static int gw16012_init_device(void)
432 {
433  if (gw16012_port == 0) {
434  gw16012_port = 0x378;
435  LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
436  }
437 
438  LOG_DEBUG("requesting privileges for parallel port 0x%" PRIx16 "...", gw16012_port);
439 #if PARPORT_USE_GIVEIO == 1
440  if (gw16012_get_giveio_access() != 0) {
441 #else /* PARPORT_USE_GIVEIO */
442  if (ioperm(gw16012_port, 3, 1) != 0) {
443 #endif /* PARPORT_USE_GIVEIO */
444  LOG_ERROR("missing privileges for direct i/o");
445  return ERROR_JTAG_INIT_FAILED;
446  }
447  LOG_DEBUG("...privileges granted");
448 
449  /* make sure parallel port is in right mode (clear tristate and interrupt */
450 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
451  outb(gw16012_port + 2, 0x0);
452 #else
453  outb(0x0, gw16012_port + 2);
454 #endif
455  return ERROR_OK;
456 }
457 
458 #endif /* PARPORT_USE_PPDEV */
459 
460 static int gw16012_init(void)
461 {
462  uint8_t status_port;
463 
464  if (gw16012_init_device() != ERROR_OK)
465  return ERROR_JTAG_INIT_FAILED;
466 
467  gw16012_input(&status_port);
468  gw16012_msb = (status_port & 0x80) ^ 0x80;
469 
470  gw16012_reset(0, 0);
471 
472  return ERROR_OK;
473 }
474 
475 static int gw16012_quit(void)
476 {
477 
478  return ERROR_OK;
479 }
480 
481 COMMAND_HANDLER(gw16012_handle_parport_port_command)
482 {
483  if (CMD_ARGC == 1) {
484  /* only if the port wasn't overwritten by cmdline */
485  if (gw16012_port == 0)
487  else {
488  LOG_ERROR("The parport port was already configured!");
489  return ERROR_FAIL;
490  }
491  }
492 
493  command_print(CMD, "parport port = %u", gw16012_port);
494 
495  return ERROR_OK;
496 }
497 
498 static const struct command_registration gw16012_command_handlers[] = {
499  {
500  .name = "parport_port",
501  .handler = gw16012_handle_parport_port_command,
502  .mode = COMMAND_CONFIG,
503  .help = "Display the address of the I/O port (e.g. 0x378) "
504  "or the number of the '/dev/parport' device used. "
505  "If a parameter is provided, first change that port.",
506  .usage = "[port_number]",
507  },
509 };
510 
511 static struct jtag_interface gw16012_interface = {
513 };
514 
516  .name = "gw16012",
517  .transports = jtag_only,
518  .commands = gw16012_command_handlers,
519 
520  .init = gw16012_init,
521  .quit = gw16012_quit,
522 
523  .jtag_ops = &gw16012_interface,
524 };
const char *const jtag_only[]
Definition: adapter.c:27
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:442
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ COMMAND_CONFIG
Definition: command.h:41
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
Definition: commands.c:192
enum scan_type jtag_scan_type(const struct scan_command *cmd)
Definition: commands.c:167
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)
Definition: commands.c:230
scan_type
The inferred type of a scan_command structure, indicating whether the command has the host scan in fr...
Definition: commands.h:22
@ SCAN_OUT
From host to device,.
Definition: commands.h:26
@ JTAG_TLR_RESET
Definition: commands.h:137
@ JTAG_SCAN
Definition: commands.h:129
@ JTAG_PATHMOVE
Definition: commands.h:140
@ JTAG_RUNTEST
Definition: commands.h:138
@ JTAG_SLEEP
Definition: commands.h:141
@ JTAG_RESET
Definition: commands.h:139
uint8_t type
Definition: esp_usb_jtag.c:0
static int gw16012_init(void)
Definition: gw16012.c:460
static void gw16012_runtest(unsigned int num_cycles)
Definition: gw16012.c:188
static void gw16012_data(uint8_t value)
Definition: gw16012.c:66
static void gw16012_control(uint8_t value)
Definition: gw16012.c:86
static uint8_t gw16012_msb
Definition: gw16012.c:59
static const struct command_registration gw16012_command_handlers[]
Definition: gw16012.c:498
static void gw16012_reset(int trst, int srst)
Definition: gw16012.c:121
static void gw16012_end_state(tap_state_t state)
Definition: gw16012.c:136
static void gw16012_input(uint8_t *value)
Definition: gw16012.c:107
static int gw16012_quit(void)
Definition: gw16012.c:475
COMMAND_HANDLER(gw16012_handle_parport_port_command)
Definition: gw16012.c:481
static int gw16012_execute_queue(struct jtag_command *cmd_queue)
Definition: gw16012.c:272
static uint16_t gw16012_port
Definition: gw16012.c:55
struct adapter_driver gw16012_adapter_driver
Definition: gw16012.c:515
static int gw16012_init_device(void)
Definition: gw16012.c:431
static struct jtag_interface gw16012_interface
Definition: gw16012.c:511
static void gw16012_path_move(struct pathmove_command *cmd)
Definition: gw16012.c:162
static void gw16012_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
Definition: gw16012.c:208
static void gw16012_state_move(void)
Definition: gw16012.c:146
static uint8_t gw16012_control_value
Definition: gw16012.c:60
bool tap_is_state_stable(tap_state_t astate)
Function tap_is_state_stable returns true if the astate is stable.
Definition: interface.c:200
tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
Function tap_state_transition takes a current TAP state and returns the next state according to the t...
Definition: interface.c:223
const char * tap_state_name(tap_state_t state)
Function tap_state_name Returns a string suitable for display representing the JTAG tap_state.
Definition: interface.c:344
void tap_set_end_state(tap_state_t new_end_state)
This function sets the state of an "end state follower" which tracks the state that any cable driver ...
Definition: interface.c:48
tap_state_t tap_get_end_state(void)
For more information,.
Definition: interface.c:56
int tap_get_tms_path(tap_state_t from, tap_state_t to)
This function provides a "bit sequence" indicating what has to be done with TMS during a sequence of ...
Definition: interface.c:190
int tap_get_tms_path_len(tap_state_t from, tap_state_t to)
Function int tap_get_tms_path_len returns the total number of bits that represents a TMS path transit...
Definition: interface.c:195
tap_state_t tap_get_state(void)
This function gets the state of the "state follower" which tracks the state of the TAPs connected to ...
Definition: interface.c:37
#define tap_set_state(new_state)
This function sets the state of a "state follower" which tracks the state of the TAPs connected to th...
Definition: interface.h:49
void jtag_sleep(uint32_t us)
Definition: jtag/core.c:1062
@ TAP_RESET
Definition: jtag.h:56
@ TAP_DRPAUSE
Definition: jtag.h:44
@ TAP_IRSHIFT
Definition: jtag.h:51
@ TAP_IDLE
Definition: jtag.h:53
@ TAP_DRSHIFT
Definition: jtag.h:43
@ TAP_IRPAUSE
Definition: jtag.h:52
#define ERROR_JTAG_QUEUE_FAILED
Definition: jtag.h:557
#define ERROR_JTAG_INIT_FAILED
Definition: jtag.h:553
enum tap_state tap_state_t
Defines JTAG Test Access Port states.
#define LOG_DEBUG_IO(expr ...)
Definition: log.h:101
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
Represents a driver for a debugging interface.
Definition: interface.h:207
const char *const name
The name of the interface driver.
Definition: interface.h:209
const char * name
Definition: command.h:235
Represents a driver for a debugging interface.
Definition: interface.h:182
int(* execute_queue)(struct jtag_command *cmd_queue)
Execute commands in the supplied queue.
Definition: interface.h:195
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t state[4]
Definition: vdebug.c:21