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 __retval = write(device_handle, &val, 1); \
80 __retval = ioctl(device_handle, PPSETMODE, &addr_mode); \
81 __retval = read(device_handle, &val, 1); \
84 static const int data_mode
= IEEE1284_MODE_EPP
| IEEE1284_DATA
;
90 __retval = ioctl(device_handle, PPSETMODE, &data_mode); \
91 __retval = write(device_handle, &val, 1); \
97 __retval = ioctl(device_handle, PPSETMODE, &data_mode); \
98 __retval = read(device_handle, &val, 1); \
103 #define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0)
104 #define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0)
105 #define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0)
106 #define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0)
108 #endif // PARPORT_USE_PPDEV
110 /* tap_move[i][j]: tap movement command to go from state i to state j
111 * 0: Test-Logic-Reset
118 static uint8_t amt_jtagaccel_tap_move
[6][6][2] =
120 /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
121 {{0x1f, 0x00}, {0x0f, 0x00}, {0x05, 0x00}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* RESET */
122 {{0x1f, 0x00}, {0x00, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x0b, 0x00}}, /* IDLE */
123 {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRSHIFT */
124 {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRPAUSE */
125 {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* IRSHIFT */
126 {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* IRPAUSE */
130 static void amt_jtagaccel_reset(int trst
, int srst
)
133 aw_control_rst
|= 0x4;
135 aw_control_rst
&= ~0x4;
138 aw_control_rst
|= 0x1;
140 aw_control_rst
&= ~0x1;
142 AMT_AW(aw_control_rst
);
145 static int amt_jtagaccel_speed(int speed
)
147 aw_control_baudrate
&= 0xf0;
148 aw_control_baudrate
|= speed
& 0x0f;
149 AMT_AW(aw_control_baudrate
);
154 static void amt_jtagaccel_end_state(tap_state_t state
)
156 if (tap_is_state_stable(state
))
157 tap_set_end_state(state
);
160 LOG_ERROR("BUG: %i is not a valid end state", state
);
165 static void amt_wait_scan_busy(void)
171 while (((ar_status
) & 0x80) && (timeout
-- > 0))
174 if (ar_status
& 0x80)
176 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
);
181 static void amt_jtagaccel_state_move(void)
183 uint8_t aw_scan_tms_5
;
186 tap_state_t cur_state
= tap_get_state();
187 tap_state_t end_state
= tap_get_end_state();
189 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][0];
190 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][1];
192 aw_scan_tms_5
= 0x40 | (tms_scan
[0] & 0x1f);
193 AMT_AW(aw_scan_tms_5
);
194 int jtag_speed
= jtag_get_speed();
195 if (jtag_speed
> 3 || rtck_enabled
)
196 amt_wait_scan_busy();
198 if (tms_scan
[0] & 0x80)
200 aw_scan_tms_5
= 0x40 | (tms_scan
[1] & 0x1f);
201 AMT_AW(aw_scan_tms_5
);
202 if (jtag_speed
> 3 || rtck_enabled
)
203 amt_wait_scan_busy();
206 tap_set_state(end_state
);
209 static void amt_jtagaccel_runtest(int num_cycles
)
212 uint8_t aw_scan_tms_5
;
213 uint8_t aw_scan_tms_1to4
;
215 tap_state_t saved_end_state
= tap_get_end_state();
217 /* only do a state_move when we're not already in IDLE */
218 if (tap_get_state() != TAP_IDLE
)
220 amt_jtagaccel_end_state(TAP_IDLE
);
221 amt_jtagaccel_state_move();
224 while (num_cycles
- i
>= 5)
226 aw_scan_tms_5
= 0x40;
227 AMT_AW(aw_scan_tms_5
);
231 if (num_cycles
- i
> 0)
233 aw_scan_tms_1to4
= 0x80 | ((num_cycles
- i
- 1) & 0x3) << 4;
234 AMT_AW(aw_scan_tms_1to4
);
237 amt_jtagaccel_end_state(saved_end_state
);
238 if (tap_get_state() != tap_get_end_state())
239 amt_jtagaccel_state_move();
242 static void amt_jtagaccel_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
)
244 int bits_left
= scan_size
;
246 tap_state_t saved_end_state
= tap_get_end_state();
247 uint8_t aw_tdi_option
;
252 int jtag_speed
= jtag_get_speed();
255 amt_jtagaccel_end_state(TAP_IRSHIFT
);
257 amt_jtagaccel_end_state(TAP_DRSHIFT
);
259 amt_jtagaccel_state_move();
260 amt_jtagaccel_end_state(saved_end_state
);
262 /* handle unaligned bits at the beginning */
263 if ((scan_size
- 1) % 8)
265 aw_tdi_option
= 0x30 | (((scan_size
- 1) % 8) - 1);
266 AMT_AW(aw_tdi_option
);
268 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, (scan_size
- 1) % 8) & 0xff;
270 if (jtag_speed
> 3 || rtck_enabled
)
271 amt_wait_scan_busy();
273 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
276 dr_tdo
= dr_tdo
>> (8 - ((scan_size
- 1) % 8));
277 buf_set_u32(buffer
, bit_count
, (scan_size
- 1) % 8, dr_tdo
);
280 bit_count
+= (scan_size
- 1) % 8;
281 bits_left
-= (scan_size
- 1) % 8;
284 while (bits_left
- 1 >= 8)
286 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, 8) & 0xff;
288 if (jtag_speed
> 3 || rtck_enabled
)
289 amt_wait_scan_busy();
291 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
294 buf_set_u32(buffer
, bit_count
, 8, dr_tdo
);
301 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
302 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
303 aw_tms_scan
= 0x40 | (tms_scan
[0] & 0x1f) | (buf_get_u32(buffer
, bit_count
, 1) << 5);
305 if (jtag_speed
> 3 || rtck_enabled
)
306 amt_wait_scan_busy();
308 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
311 dr_tdo
= dr_tdo
>> 7;
312 buf_set_u32(buffer
, bit_count
, 1, dr_tdo
);
315 if (tms_scan
[0] & 0x80)
317 aw_tms_scan
= 0x40 | (tms_scan
[1] & 0x1f);
319 if (jtag_speed
> 3 || rtck_enabled
)
320 amt_wait_scan_busy();
322 tap_set_state(tap_get_end_state());
325 static int amt_jtagaccel_execute_queue(void)
327 struct jtag_command
*cmd
= jtag_command_queue
; /* currently processed command */
333 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
334 * that wasn't handled by a caller-provided error handler
343 #ifdef _DEBUG_JTAG_IO_
344 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
346 if (cmd
->cmd
.reset
->trst
== 1)
348 tap_set_state(TAP_RESET
);
350 amt_jtagaccel_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
353 #ifdef _DEBUG_JTAG_IO_
354 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
356 amt_jtagaccel_end_state(cmd
->cmd
.runtest
->end_state
);
357 amt_jtagaccel_runtest(cmd
->cmd
.runtest
->num_cycles
);
360 #ifdef _DEBUG_JTAG_IO_
361 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
363 amt_jtagaccel_end_state(cmd
->cmd
.statemove
->end_state
);
364 amt_jtagaccel_state_move();
367 #ifdef _DEBUG_JTAG_IO_
368 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
370 amt_jtagaccel_end_state(cmd
->cmd
.scan
->end_state
);
371 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
372 type
= jtag_scan_type(cmd
->cmd
.scan
);
373 amt_jtagaccel_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
374 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
375 retval
= ERROR_JTAG_QUEUE_FAILED
;
380 #ifdef _DEBUG_JTAG_IO_
381 LOG_DEBUG("sleep %" PRIi32
, cmd
->cmd
.sleep
->us
);
383 jtag_sleep(cmd
->cmd
.sleep
->us
);
386 LOG_ERROR("BUG: unknown JTAG command type encountered");
395 #if PARPORT_USE_GIVEIO == 1
396 int amt_jtagaccel_get_giveio_access(void)
399 OSVERSIONINFO version
;
401 version
.dwOSVersionInfoSize
= sizeof version
;
402 if (!GetVersionEx(&version
)) {
406 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
409 h
= CreateFile("\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
410 if (h
== INVALID_HANDLE_VALUE
) {
421 static int amt_jtagaccel_init(void)
423 #if PARPORT_USE_PPDEV == 1
426 uint8_t control_port
;
432 #if PARPORT_USE_PPDEV == 1
433 if (device_handle
> 0)
435 LOG_ERROR("device is already opened");
436 return ERROR_JTAG_INIT_FAILED
;
439 snprintf(buffer
, 256, "/dev/parport%d", amt_jtagaccel_port
);
440 device_handle
= open(buffer
, O_RDWR
);
442 if (device_handle
< 0)
444 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
445 return ERROR_JTAG_INIT_FAILED
;
448 i
= ioctl(device_handle
, PPCLAIM
);
451 LOG_ERROR("cannot claim device");
452 return ERROR_JTAG_INIT_FAILED
;
455 i
= IEEE1284_MODE_EPP
;
456 i
= ioctl(device_handle
, PPSETMODE
, & i
);
459 LOG_ERROR(" cannot set compatible mode to device");
460 return ERROR_JTAG_INIT_FAILED
;
464 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
467 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
470 if (amt_jtagaccel_port
== 0)
472 amt_jtagaccel_port
= 0x378;
473 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
476 #if PARPORT_USE_GIVEIO == 1
477 if (amt_jtagaccel_get_giveio_access() != 0) {
478 #else /* PARPORT_USE_GIVEIO */
479 if (ioperm(amt_jtagaccel_port
, 5, 1) != 0) {
480 #endif /* PARPORT_USE_GIVEIO */
481 LOG_ERROR("missing privileges for direct i/o");
482 return ERROR_JTAG_INIT_FAILED
;
485 /* prepare epp port */
487 status_port
= inb(amt_jtagaccel_port
+ 1);
488 outb(status_port
| 0x1, amt_jtagaccel_port
+ 1);
491 outb(0x00, amt_jtagaccel_port
+ 2);
492 outb(0x04, amt_jtagaccel_port
+ 2);
497 /* set RTCK enable bit */
498 aw_control_fsm
|= 0x02;
501 /* enable JTAG port */
502 aw_control_fsm
|= 0x04;
503 AMT_AW(aw_control_fsm
);
505 amt_jtagaccel_speed(jtag_get_speed());
507 enum reset_types jtag_reset_config
= jtag_get_reset_config();
508 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
509 aw_control_rst
&= ~0x8;
511 aw_control_rst
|= 0x8;
513 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
514 aw_control_rst
&= ~0x2;
516 aw_control_rst
|= 0x2;
518 amt_jtagaccel_reset(0, 0);
520 /* read status register */
522 LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status
);
527 static int amt_jtagaccel_quit(void)
533 COMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command
)
537 /* only if the port wasn't overwritten by cmdline */
538 if (amt_jtagaccel_port
== 0)
541 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], port
);
542 amt_jtagaccel_port
= port
;
546 LOG_ERROR("The parport port was already configured!");
551 command_print(CMD_CTX
, "parport port = %u", amt_jtagaccel_port
);
556 COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command
)
560 command_print(CMD_CTX
, "amt_jtagaccel RTCK feature %s", (rtck_enabled
) ? "enabled" : "disabled");
565 if (strcmp(CMD_ARGV
[0], "enabled") == 0)
578 static const struct command_registration amtjtagaccel_command_handlers
[] = {
580 .name
= "parport_port",
581 .handler
= &amt_jtagaccel_handle_parport_port_command
,
582 .mode
= COMMAND_CONFIG
,
583 .help
= "configure or display the parallel port to use",
584 .usage
= "[port_num]",
588 * @todo Remove this "rtck" command; just use the standard
589 * mechanism to enable/disable adaptive clocking. First
590 * implement the standard mechanism and deprecate "rtck";
591 * after a year or so, it'll be safe to remove this.
594 .handler
= &amt_jtagaccel_handle_rtck_command
,
595 .mode
= COMMAND_CONFIG
,
596 .help
= "configure or display RTCK support",
597 .usage
= "[enable|disable]",
599 COMMAND_REGISTRATION_DONE
602 struct jtag_interface amt_jtagaccel_interface
= {
603 .name
= "amt_jtagaccel",
604 .commands
= amtjtagaccel_command_handlers
,
606 .init
= amt_jtagaccel_init
,
607 .quit
= amt_jtagaccel_quit
,
608 .speed
= amt_jtagaccel_speed
,
609 .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)