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(int num_cycles)
189 {
190  tap_state_t saved_end_state = tap_get_end_state();
191  int i;
192 
193  /* only do a state_move when we're not already in IDLE */
194  if (tap_get_state() != TAP_IDLE) {
197  }
198 
199  for (i = 0; i < num_cycles; i++) {
200  gw16012_control(0x0); /* single-bit mode */
201  gw16012_data(0x0); /* TMS cycle with TMS low */
202  }
203 
204  gw16012_end_state(saved_end_state);
205  if (tap_get_state() != tap_get_end_state())
207 }
208 
209 static void gw16012_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
210 {
211  int bits_left = scan_size;
212  int bit_count = 0;
213  tap_state_t saved_end_state = tap_get_end_state();
214  uint8_t scan_out, scan_in;
215 
216  /* only if we're not already in the correct Shift state */
217  if (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) ||
218  (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {
219  if (ir_scan)
221  else
223 
225  gw16012_end_state(saved_end_state);
226  }
227 
228  while (type == SCAN_OUT && ((bits_left - 1) > 7)) {
229  gw16012_control(0x2); /* seven-bit mode */
230  scan_out = buf_get_u32(buffer, bit_count, 7);
231  gw16012_data(scan_out);
232  bit_count += 7;
233  bits_left -= 7;
234  }
235 
236  gw16012_control(0x0); /* single-bit mode */
237  while (bits_left-- > 0) {
238  uint8_t tms = 0;
239 
240  scan_out = buf_get_u32(buffer, bit_count, 1);
241 
242  if (bits_left == 0) /* last bit */ {
243  if ((ir_scan && (tap_get_end_state() == TAP_IRSHIFT))
244  || (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT)))
245  tms = 0;
246  else
247  tms = 2;
248  }
249 
250  gw16012_data(scan_out | tms);
251 
252  if (type != SCAN_OUT) {
253  gw16012_input(&scan_in);
254  buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3));
255  }
256 
257  bit_count++;
258  }
259 
260  if (!((ir_scan && (tap_get_end_state() == TAP_IRSHIFT)) ||
261  (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT)))) {
262  gw16012_data(0x0);
263  if (ir_scan)
265  else
267 
268  if (tap_get_state() != tap_get_end_state())
270  }
271 }
272 
273 static int gw16012_execute_queue(void)
274 {
275  struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
276  int scan_size;
277  enum scan_type type;
278  uint8_t *buffer;
279  int retval;
280 
281  /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
282  * that wasn't handled by a caller-provided error handler
283  */
284  retval = ERROR_OK;
285 
286  while (cmd) {
287  switch (cmd->type) {
288  case JTAG_RESET:
289  LOG_DEBUG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
290  if (cmd->cmd.reset->trst == 1)
292  gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
293  break;
294  case JTAG_RUNTEST:
295  LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
296  cmd->cmd.runtest->end_state);
297  gw16012_end_state(cmd->cmd.runtest->end_state);
298  gw16012_runtest(cmd->cmd.runtest->num_cycles);
299  break;
300  case JTAG_TLR_RESET:
301  LOG_DEBUG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
302  gw16012_end_state(cmd->cmd.statemove->end_state);
304  break;
305  case JTAG_PATHMOVE:
306  LOG_DEBUG_IO("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
307  cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
308  gw16012_path_move(cmd->cmd.pathmove);
309  break;
310  case JTAG_SCAN:
311  gw16012_end_state(cmd->cmd.scan->end_state);
312  scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
313  type = jtag_scan_type(cmd->cmd.scan);
314  LOG_DEBUG_IO("%s scan (%i) %i bit end in %i", (cmd->cmd.scan->ir_scan) ? "ir" : "dr",
315  type, scan_size, cmd->cmd.scan->end_state);
316  gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
317  if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
318  retval = ERROR_JTAG_QUEUE_FAILED;
319  free(buffer);
320  break;
321  case JTAG_SLEEP:
322  LOG_DEBUG_IO("sleep %" PRIu32, cmd->cmd.sleep->us);
323  jtag_sleep(cmd->cmd.sleep->us);
324  break;
325  default:
326  LOG_ERROR("BUG: unknown JTAG command type encountered");
327  exit(-1);
328  }
329  cmd = cmd->next;
330  }
331 
332  return retval;
333 }
334 
335 #if PARPORT_USE_GIVEIO == 1
336 static int gw16012_get_giveio_access(void)
337 {
338  HANDLE h;
339  OSVERSIONINFO version;
340 
341  version.dwOSVersionInfoSize = sizeof(version);
342  if (!GetVersionEx(&version)) {
343  errno = EINVAL;
344  return -1;
345  }
346  if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
347  return 0;
348 
349  h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING,
350  FILE_ATTRIBUTE_NORMAL, NULL);
351  if (h == INVALID_HANDLE_VALUE) {
352  errno = ENODEV;
353  return -1;
354  }
355 
356  CloseHandle(h);
357 
358  return 0;
359 }
360 #endif
361 
362 #if PARPORT_USE_PPDEV == 1
363 
364 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
365 
366 #define GW16012_PPDEV_NAME "ppi"
367 
368 static int gw16012_init_ioctls(void)
369 {
370  int temp = 0;
371  temp = ioctl(device_handle, PPCLAIM);
372  if (temp < 0) {
373  LOG_ERROR("cannot claim device");
374  return ERROR_JTAG_INIT_FAILED;
375  }
376 
377  temp = PARPORT_MODE_COMPAT;
378  temp = ioctl(device_handle, PPSETMODE, &temp);
379  if (temp < 0) {
380  LOG_ERROR(" cannot set compatible mode to device");
381  return ERROR_JTAG_INIT_FAILED;
382  }
383 
384  temp = IEEE1284_MODE_COMPAT;
385  temp = ioctl(device_handle, PPNEGOT, &temp);
386  if (temp < 0) {
387  LOG_ERROR("cannot set compatible 1284 mode to device");
388  return ERROR_JTAG_INIT_FAILED;
389  }
390  return ERROR_OK;
391 }
392 #else
393 
394 #define GW16012_PPDEV_NAME "parport"
395 
396 static int gw16012_init_ioctls(void)
397 {
398  return ERROR_OK;
399 }
400 
401 #endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */
402 
403 static int gw16012_init_device(void)
404 {
405  const char *device_name = GW16012_PPDEV_NAME;
406  char buffer[256];
407 
408  if (device_handle > 0) {
409  LOG_ERROR("device is already opened");
410  return ERROR_JTAG_INIT_FAILED;
411  }
412 
413  snprintf(buffer, 256, "/dev/%s%d", device_name, gw16012_port);
414  LOG_DEBUG("opening %s...", buffer);
415 
416  device_handle = open(buffer, O_WRONLY);
417  if (device_handle < 0) {
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 
422  LOG_DEBUG("...open");
423 
424  if (gw16012_init_ioctls() != ERROR_OK)
425  return ERROR_JTAG_INIT_FAILED;
426 
427  return ERROR_OK;
428 }
429 
430 #else /* PARPORT_USE_PPDEV */
431 
432 static int gw16012_init_device(void)
433 {
434  if (gw16012_port == 0) {
435  gw16012_port = 0x378;
436  LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
437  }
438 
439  LOG_DEBUG("requesting privileges for parallel port 0x%" PRIx16 "...", gw16012_port);
440 #if PARPORT_USE_GIVEIO == 1
441  if (gw16012_get_giveio_access() != 0) {
442 #else /* PARPORT_USE_GIVEIO */
443  if (ioperm(gw16012_port, 3, 1) != 0) {
444 #endif /* PARPORT_USE_GIVEIO */
445  LOG_ERROR("missing privileges for direct i/o");
446  return ERROR_JTAG_INIT_FAILED;
447  }
448  LOG_DEBUG("...privileges granted");
449 
450  /* make sure parallel port is in right mode (clear tristate and interrupt */
451 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
452  outb(gw16012_port + 2, 0x0);
453 #else
454  outb(0x0, gw16012_port + 2);
455 #endif
456  return ERROR_OK;
457 }
458 
459 #endif /* PARPORT_USE_PPDEV */
460 
461 static int gw16012_init(void)
462 {
463  uint8_t status_port;
464 
465  if (gw16012_init_device() != ERROR_OK)
466  return ERROR_JTAG_INIT_FAILED;
467 
468  gw16012_input(&status_port);
469  gw16012_msb = (status_port & 0x80) ^ 0x80;
470 
471  gw16012_reset(0, 0);
472 
473  return ERROR_OK;
474 }
475 
476 static int gw16012_quit(void)
477 {
478 
479  return ERROR_OK;
480 }
481 
482 COMMAND_HANDLER(gw16012_handle_parport_port_command)
483 {
484  if (CMD_ARGC == 1) {
485  /* only if the port wasn't overwritten by cmdline */
486  if (gw16012_port == 0)
488  else {
489  LOG_ERROR("The parport port was already configured!");
490  return ERROR_FAIL;
491  }
492  }
493 
494  command_print(CMD, "parport port = %u", gw16012_port);
495 
496  return ERROR_OK;
497 }
498 
499 static const struct command_registration gw16012_command_handlers[] = {
500  {
501  .name = "parport_port",
502  .handler = gw16012_handle_parport_port_command,
503  .mode = COMMAND_CONFIG,
504  .help = "Display the address of the I/O port (e.g. 0x378) "
505  "or the number of the '/dev/parport' device used. "
506  "If a parameter is provided, first change that port.",
507  .usage = "[port_number]",
508  },
510 };
511 
512 static struct jtag_interface gw16012_interface = {
514 };
515 
517  .name = "gw16012",
518  .transports = jtag_only,
519  .commands = gw16012_command_handlers,
520 
521  .init = gw16012_init,
522  .quit = gw16012_quit,
523 
524  .jtag_ops = &gw16012_interface,
525 };
const char *const jtag_only[]
Definition: adapter.c:31
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:98
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:30
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:473
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:140
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:155
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
#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:425
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
@ COMMAND_CONFIG
Definition: command.h:41
struct jtag_command * jtag_command_queue
The current queue of jtag_command_s structures.
Definition: commands.c:36
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
Definition: commands.c:189
enum scan_type jtag_scan_type(const struct scan_command *cmd)
Definition: commands.c:162
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_s structure, indicating whether the command has the host scan in ...
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:461
static void gw16012_runtest(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:499
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:476
COMMAND_HANDLER(gw16012_handle_parport_port_command)
Definition: gw16012.c:482
static int gw16012_execute_queue(void)
Definition: gw16012.c:273
static uint16_t gw16012_port
Definition: gw16012.c:55
struct adapter_driver gw16012_adapter_driver
Definition: gw16012.c:516
static int gw16012_init_device(void)
Definition: gw16012.c:432
static struct jtag_interface gw16012_interface
Definition: gw16012.c:512
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:209
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:55
@ TAP_DRPAUSE
Definition: jtag.h:43
@ TAP_IRSHIFT
Definition: jtag.h:50
@ TAP_IDLE
Definition: jtag.h:52
@ TAP_DRSHIFT
Definition: jtag.h:42
@ TAP_IRPAUSE
Definition: jtag.h:51
#define ERROR_JTAG_QUEUE_FAILED
Definition: jtag.h:553
#define ERROR_JTAG_INIT_FAILED
Definition: jtag.h:549
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:120
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:155
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:229
Represents a driver for a debugging interface.
Definition: interface.h:184
int(* execute_queue)(void)
Execute queued commands.
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