1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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. *
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. *
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 ***************************************************************************/
24 #include <jtag/interface.h>
26 #if PARPORT_USE_PPDEV == 1
27 #include <linux/parport.h>
28 #include <linux/ppdev.h>
29 #include <sys/ioctl.h>
30 #else /* not PARPORT_USE_PPDEV */
36 #if PARPORT_USE_GIVEIO == 1
44 * Support the Amontec Chameleon POD with JTAG Accelerator support.
45 * This is a parallel port JTAG adapter with a CPLD between the
46 * parallel port and the JTAG connection. VHDL code running in the
47 * CPLD significantly accelerates JTAG operations compared to the
48 * bitbanging "Wiggler" style of most parallel port adapters.
52 static uint16_t amt_jtagaccel_port
;
54 /* interface variables
56 static uint8_t aw_control_rst
= 0x00;
57 static uint8_t aw_control_fsm
= 0x10;
58 static uint8_t aw_control_baudrate
= 0x20;
60 static int rtck_enabled
= 0;
62 #if PARPORT_USE_PPDEV == 1
63 static int device_handle
;
65 static const int addr_mode
= IEEE1284_MODE_EPP
| IEEE1284_ADDR
;
67 /* FIXME do something sane when these ioctl/read/write calls fail. */
73 __retval = ioctl(device_handle, PPSETMODE, &addr_mode); \
74 assert(__retval >= 0); \
75 __retval = write(device_handle, &val, 1); \
76 assert(__retval >= 0); \
82 __retval = ioctl(device_handle, PPSETMODE, &addr_mode); \
83 assert(__retval >= 0); \
84 __retval = read(device_handle, &val, 1); \
85 assert(__retval >= 0); \
88 static const int data_mode
= IEEE1284_MODE_EPP
| IEEE1284_DATA
;
94 __retval = ioctl(device_handle, PPSETMODE, &data_mode); \
95 assert(__retval >= 0); \
96 __retval = write(device_handle, &val, 1); \
97 assert(__retval >= 0); \
103 __retval = ioctl(device_handle, PPSETMODE, &data_mode); \
104 assert(__retval >= 0); \
105 __retval = read(device_handle, &val, 1); \
106 assert(__retval >= 0); \
111 #define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0)
112 #define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0)
113 #define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0)
114 #define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0)
116 #endif // PARPORT_USE_PPDEV
118 /* tap_move[i][j]: tap movement command to go from state i to state j
119 * 0: Test-Logic-Reset
126 static uint8_t amt_jtagaccel_tap_move
[6][6][2] =
128 /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
129 {{0x1f, 0x00}, {0x0f, 0x00}, {0x05, 0x00}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* RESET */
130 {{0x1f, 0x00}, {0x00, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x0b, 0x00}}, /* IDLE */
131 {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRSHIFT */
132 {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRPAUSE */
133 {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* IRSHIFT */
134 {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* IRPAUSE */
138 static void amt_jtagaccel_reset(int trst
, int srst
)
141 aw_control_rst
|= 0x4;
143 aw_control_rst
&= ~0x4;
146 aw_control_rst
|= 0x1;
148 aw_control_rst
&= ~0x1;
150 AMT_AW(aw_control_rst
);
153 static int amt_jtagaccel_speed(int speed
)
155 aw_control_baudrate
&= 0xf0;
156 aw_control_baudrate
|= speed
& 0x0f;
157 AMT_AW(aw_control_baudrate
);
162 static void amt_jtagaccel_end_state(tap_state_t state
)
164 if (tap_is_state_stable(state
))
165 tap_set_end_state(state
);
168 LOG_ERROR("BUG: %i is not a valid end state", state
);
173 static void amt_wait_scan_busy(void)
179 while (((ar_status
) & 0x80) && (timeout
-- > 0))
182 if (ar_status
& 0x80)
184 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
);
189 static void amt_jtagaccel_state_move(void)
191 uint8_t aw_scan_tms_5
;
194 tap_state_t cur_state
= tap_get_state();
195 tap_state_t end_state
= tap_get_end_state();
197 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][0];
198 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][1];
200 aw_scan_tms_5
= 0x40 | (tms_scan
[0] & 0x1f);
201 AMT_AW(aw_scan_tms_5
);
203 int retval
= jtag_get_speed(&jtag_speed
);
204 assert(retval
== ERROR_OK
);
205 if (jtag_speed
> 3 || rtck_enabled
)
206 amt_wait_scan_busy();
208 if (tms_scan
[0] & 0x80)
210 aw_scan_tms_5
= 0x40 | (tms_scan
[1] & 0x1f);
211 AMT_AW(aw_scan_tms_5
);
212 if (jtag_speed
> 3 || rtck_enabled
)
213 amt_wait_scan_busy();
216 tap_set_state(end_state
);
219 static void amt_jtagaccel_runtest(int num_cycles
)
222 uint8_t aw_scan_tms_5
;
223 uint8_t aw_scan_tms_1to4
;
225 tap_state_t saved_end_state
= tap_get_end_state();
227 /* only do a state_move when we're not already in IDLE */
228 if (tap_get_state() != TAP_IDLE
)
230 amt_jtagaccel_end_state(TAP_IDLE
);
231 amt_jtagaccel_state_move();
234 while (num_cycles
- i
>= 5)
236 aw_scan_tms_5
= 0x40;
237 AMT_AW(aw_scan_tms_5
);
241 if (num_cycles
- i
> 0)
243 aw_scan_tms_1to4
= 0x80 | ((num_cycles
- i
- 1) & 0x3) << 4;
244 AMT_AW(aw_scan_tms_1to4
);
247 amt_jtagaccel_end_state(saved_end_state
);
248 if (tap_get_state() != tap_get_end_state())
249 amt_jtagaccel_state_move();
252 static void amt_jtagaccel_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
)
254 int bits_left
= scan_size
;
256 tap_state_t saved_end_state
= tap_get_end_state();
257 uint8_t aw_tdi_option
;
263 int retval
= jtag_get_speed(&jtag_speed_var
);
264 assert(retval
== ERROR_OK
);
267 amt_jtagaccel_end_state(TAP_IRSHIFT
);
269 amt_jtagaccel_end_state(TAP_DRSHIFT
);
271 amt_jtagaccel_state_move();
272 amt_jtagaccel_end_state(saved_end_state
);
274 /* handle unaligned bits at the beginning */
275 if ((scan_size
- 1) % 8)
277 aw_tdi_option
= 0x30 | (((scan_size
- 1) % 8) - 1);
278 AMT_AW(aw_tdi_option
);
280 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, (scan_size
- 1) % 8) & 0xff;
282 if (jtag_speed_var
> 3 || rtck_enabled
)
283 amt_wait_scan_busy();
285 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
288 dr_tdo
= dr_tdo
>> (8 - ((scan_size
- 1) % 8));
289 buf_set_u32(buffer
, bit_count
, (scan_size
- 1) % 8, dr_tdo
);
292 bit_count
+= (scan_size
- 1) % 8;
293 bits_left
-= (scan_size
- 1) % 8;
296 while (bits_left
- 1 >= 8)
298 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, 8) & 0xff;
300 if (jtag_speed_var
> 3 || rtck_enabled
)
301 amt_wait_scan_busy();
303 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
306 buf_set_u32(buffer
, bit_count
, 8, dr_tdo
);
313 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
314 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
315 aw_tms_scan
= 0x40 | (tms_scan
[0] & 0x1f) | (buf_get_u32(buffer
, bit_count
, 1) << 5);
317 if (jtag_speed_var
> 3 || rtck_enabled
)
318 amt_wait_scan_busy();
320 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
323 dr_tdo
= dr_tdo
>> 7;
324 buf_set_u32(buffer
, bit_count
, 1, dr_tdo
);
327 if (tms_scan
[0] & 0x80)
329 aw_tms_scan
= 0x40 | (tms_scan
[1] & 0x1f);
331 if (jtag_speed_var
> 3 || rtck_enabled
)
332 amt_wait_scan_busy();
334 tap_set_state(tap_get_end_state());
337 static int amt_jtagaccel_execute_queue(void)
339 struct jtag_command
*cmd
= jtag_command_queue
; /* currently processed command */
345 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
346 * that wasn't handled by a caller-provided error handler
355 #ifdef _DEBUG_JTAG_IO_
356 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
358 if (cmd
->cmd
.reset
->trst
== 1)
360 tap_set_state(TAP_RESET
);
362 amt_jtagaccel_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
365 #ifdef _DEBUG_JTAG_IO_
366 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
368 amt_jtagaccel_end_state(cmd
->cmd
.runtest
->end_state
);
369 amt_jtagaccel_runtest(cmd
->cmd
.runtest
->num_cycles
);
372 #ifdef _DEBUG_JTAG_IO_
373 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
375 amt_jtagaccel_end_state(cmd
->cmd
.statemove
->end_state
);
376 amt_jtagaccel_state_move();
379 #ifdef _DEBUG_JTAG_IO_
380 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
382 amt_jtagaccel_end_state(cmd
->cmd
.scan
->end_state
);
383 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
384 type
= jtag_scan_type(cmd
->cmd
.scan
);
385 amt_jtagaccel_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
386 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
387 retval
= ERROR_JTAG_QUEUE_FAILED
;
392 #ifdef _DEBUG_JTAG_IO_
393 LOG_DEBUG("sleep %" PRIi32
, cmd
->cmd
.sleep
->us
);
395 jtag_sleep(cmd
->cmd
.sleep
->us
);
398 LOG_ERROR("BUG: unknown JTAG command type encountered");
407 #if PARPORT_USE_GIVEIO == 1
408 int amt_jtagaccel_get_giveio_access(void)
411 OSVERSIONINFO version
;
413 version
.dwOSVersionInfoSize
= sizeof version
;
414 if (!GetVersionEx(&version
)) {
418 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
421 h
= CreateFile("\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
422 if (h
== INVALID_HANDLE_VALUE
) {
433 static int amt_jtagaccel_init(void)
435 #if PARPORT_USE_PPDEV == 1
438 uint8_t control_port
;
444 #if PARPORT_USE_PPDEV == 1
445 if (device_handle
> 0)
447 LOG_ERROR("device is already opened");
448 return ERROR_JTAG_INIT_FAILED
;
451 snprintf(buffer
, 256, "/dev/parport%d", amt_jtagaccel_port
);
452 device_handle
= open(buffer
, O_RDWR
);
454 if (device_handle
< 0)
456 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
457 return ERROR_JTAG_INIT_FAILED
;
460 i
= ioctl(device_handle
, PPCLAIM
);
463 LOG_ERROR("cannot claim device");
464 return ERROR_JTAG_INIT_FAILED
;
467 i
= IEEE1284_MODE_EPP
;
468 i
= ioctl(device_handle
, PPSETMODE
, & i
);
471 LOG_ERROR(" cannot set compatible mode to device");
472 return ERROR_JTAG_INIT_FAILED
;
476 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
479 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
482 if (amt_jtagaccel_port
== 0)
484 amt_jtagaccel_port
= 0x378;
485 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
488 #if PARPORT_USE_GIVEIO == 1
489 if (amt_jtagaccel_get_giveio_access() != 0) {
490 #else /* PARPORT_USE_GIVEIO */
491 if (ioperm(amt_jtagaccel_port
, 5, 1) != 0) {
492 #endif /* PARPORT_USE_GIVEIO */
493 LOG_ERROR("missing privileges for direct i/o");
494 return ERROR_JTAG_INIT_FAILED
;
497 /* prepare epp port */
499 status_port
= inb(amt_jtagaccel_port
+ 1);
500 outb(status_port
| 0x1, amt_jtagaccel_port
+ 1);
503 outb(0x00, amt_jtagaccel_port
+ 2);
504 outb(0x04, amt_jtagaccel_port
+ 2);
509 /* set RTCK enable bit */
510 aw_control_fsm
|= 0x02;
513 /* enable JTAG port */
514 aw_control_fsm
|= 0x04;
515 AMT_AW(aw_control_fsm
);
517 enum reset_types jtag_reset_config
= jtag_get_reset_config();
518 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
519 aw_control_rst
&= ~0x8;
521 aw_control_rst
|= 0x8;
523 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
524 aw_control_rst
&= ~0x2;
526 aw_control_rst
|= 0x2;
528 amt_jtagaccel_reset(0, 0);
530 /* read status register */
532 LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status
);
537 static int amt_jtagaccel_quit(void)
543 COMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command
)
547 /* only if the port wasn't overwritten by cmdline */
548 if (amt_jtagaccel_port
== 0)
551 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], port
);
552 amt_jtagaccel_port
= port
;
556 LOG_ERROR("The parport port was already configured!");
561 command_print(CMD_CTX
, "parport port = %u", amt_jtagaccel_port
);
566 COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command
)
570 command_print(CMD_CTX
, "amt_jtagaccel RTCK feature %s", (rtck_enabled
) ? "enabled" : "disabled");
575 if (strcmp(CMD_ARGV
[0], "enabled") == 0)
588 static const struct command_registration amtjtagaccel_command_handlers
[] = {
590 .name
= "parport_port",
591 .handler
= &amt_jtagaccel_handle_parport_port_command
,
592 .mode
= COMMAND_CONFIG
,
593 .help
= "configure or display the parallel port to use",
594 .usage
= "[port_num]",
598 * @todo Remove this "rtck" command; just use the standard
599 * mechanism to enable/disable adaptive clocking. First
600 * implement the standard mechanism and deprecate "rtck";
601 * after a year or so, it'll be safe to remove this.
604 .handler
= &amt_jtagaccel_handle_rtck_command
,
605 .mode
= COMMAND_CONFIG
,
606 .help
= "configure or display RTCK support",
607 .usage
= "[enable|disable]",
609 COMMAND_REGISTRATION_DONE
612 struct jtag_interface amt_jtagaccel_interface
= {
613 .name
= "amt_jtagaccel",
614 .commands
= amtjtagaccel_command_handlers
,
616 .init
= amt_jtagaccel_init
,
617 .quit
= amt_jtagaccel_quit
,
618 .speed
= amt_jtagaccel_speed
,
619 .execute_queue
= amt_jtagaccel_execute_queue
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)