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 retval
= jtag_get_speed(&jtag_speed
);
195 assert(retval
== ERROR_OK
);
196 if (jtag_speed
> 3 || rtck_enabled
)
197 amt_wait_scan_busy();
199 if (tms_scan
[0] & 0x80)
201 aw_scan_tms_5
= 0x40 | (tms_scan
[1] & 0x1f);
202 AMT_AW(aw_scan_tms_5
);
203 if (jtag_speed
> 3 || rtck_enabled
)
204 amt_wait_scan_busy();
207 tap_set_state(end_state
);
210 static void amt_jtagaccel_runtest(int num_cycles
)
213 uint8_t aw_scan_tms_5
;
214 uint8_t aw_scan_tms_1to4
;
216 tap_state_t saved_end_state
= tap_get_end_state();
218 /* only do a state_move when we're not already in IDLE */
219 if (tap_get_state() != TAP_IDLE
)
221 amt_jtagaccel_end_state(TAP_IDLE
);
222 amt_jtagaccel_state_move();
225 while (num_cycles
- i
>= 5)
227 aw_scan_tms_5
= 0x40;
228 AMT_AW(aw_scan_tms_5
);
232 if (num_cycles
- i
> 0)
234 aw_scan_tms_1to4
= 0x80 | ((num_cycles
- i
- 1) & 0x3) << 4;
235 AMT_AW(aw_scan_tms_1to4
);
238 amt_jtagaccel_end_state(saved_end_state
);
239 if (tap_get_state() != tap_get_end_state())
240 amt_jtagaccel_state_move();
243 static void amt_jtagaccel_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
)
245 int bits_left
= scan_size
;
247 tap_state_t saved_end_state
= tap_get_end_state();
248 uint8_t aw_tdi_option
;
254 int retval
= jtag_get_speed(&jtag_speed_var
);
255 assert(retval
== ERROR_OK
);
258 amt_jtagaccel_end_state(TAP_IRSHIFT
);
260 amt_jtagaccel_end_state(TAP_DRSHIFT
);
262 amt_jtagaccel_state_move();
263 amt_jtagaccel_end_state(saved_end_state
);
265 /* handle unaligned bits at the beginning */
266 if ((scan_size
- 1) % 8)
268 aw_tdi_option
= 0x30 | (((scan_size
- 1) % 8) - 1);
269 AMT_AW(aw_tdi_option
);
271 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, (scan_size
- 1) % 8) & 0xff;
273 if (jtag_speed_var
> 3 || rtck_enabled
)
274 amt_wait_scan_busy();
276 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
279 dr_tdo
= dr_tdo
>> (8 - ((scan_size
- 1) % 8));
280 buf_set_u32(buffer
, bit_count
, (scan_size
- 1) % 8, dr_tdo
);
283 bit_count
+= (scan_size
- 1) % 8;
284 bits_left
-= (scan_size
- 1) % 8;
287 while (bits_left
- 1 >= 8)
289 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, 8) & 0xff;
291 if (jtag_speed_var
> 3 || rtck_enabled
)
292 amt_wait_scan_busy();
294 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
297 buf_set_u32(buffer
, bit_count
, 8, dr_tdo
);
304 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
305 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
306 aw_tms_scan
= 0x40 | (tms_scan
[0] & 0x1f) | (buf_get_u32(buffer
, bit_count
, 1) << 5);
308 if (jtag_speed_var
> 3 || rtck_enabled
)
309 amt_wait_scan_busy();
311 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
314 dr_tdo
= dr_tdo
>> 7;
315 buf_set_u32(buffer
, bit_count
, 1, dr_tdo
);
318 if (tms_scan
[0] & 0x80)
320 aw_tms_scan
= 0x40 | (tms_scan
[1] & 0x1f);
322 if (jtag_speed_var
> 3 || rtck_enabled
)
323 amt_wait_scan_busy();
325 tap_set_state(tap_get_end_state());
328 static int amt_jtagaccel_execute_queue(void)
330 struct jtag_command
*cmd
= jtag_command_queue
; /* currently processed command */
336 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
337 * that wasn't handled by a caller-provided error handler
346 #ifdef _DEBUG_JTAG_IO_
347 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
349 if (cmd
->cmd
.reset
->trst
== 1)
351 tap_set_state(TAP_RESET
);
353 amt_jtagaccel_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
356 #ifdef _DEBUG_JTAG_IO_
357 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
359 amt_jtagaccel_end_state(cmd
->cmd
.runtest
->end_state
);
360 amt_jtagaccel_runtest(cmd
->cmd
.runtest
->num_cycles
);
363 #ifdef _DEBUG_JTAG_IO_
364 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
366 amt_jtagaccel_end_state(cmd
->cmd
.statemove
->end_state
);
367 amt_jtagaccel_state_move();
370 #ifdef _DEBUG_JTAG_IO_
371 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
373 amt_jtagaccel_end_state(cmd
->cmd
.scan
->end_state
);
374 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
375 type
= jtag_scan_type(cmd
->cmd
.scan
);
376 amt_jtagaccel_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
377 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
378 retval
= ERROR_JTAG_QUEUE_FAILED
;
383 #ifdef _DEBUG_JTAG_IO_
384 LOG_DEBUG("sleep %" PRIi32
, cmd
->cmd
.sleep
->us
);
386 jtag_sleep(cmd
->cmd
.sleep
->us
);
389 LOG_ERROR("BUG: unknown JTAG command type encountered");
398 #if PARPORT_USE_GIVEIO == 1
399 int amt_jtagaccel_get_giveio_access(void)
402 OSVERSIONINFO version
;
404 version
.dwOSVersionInfoSize
= sizeof version
;
405 if (!GetVersionEx(&version
)) {
409 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
412 h
= CreateFile("\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
413 if (h
== INVALID_HANDLE_VALUE
) {
424 static int amt_jtagaccel_init(void)
426 #if PARPORT_USE_PPDEV == 1
429 uint8_t control_port
;
435 #if PARPORT_USE_PPDEV == 1
436 if (device_handle
> 0)
438 LOG_ERROR("device is already opened");
439 return ERROR_JTAG_INIT_FAILED
;
442 snprintf(buffer
, 256, "/dev/parport%d", amt_jtagaccel_port
);
443 device_handle
= open(buffer
, O_RDWR
);
445 if (device_handle
< 0)
447 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
448 return ERROR_JTAG_INIT_FAILED
;
451 i
= ioctl(device_handle
, PPCLAIM
);
454 LOG_ERROR("cannot claim device");
455 return ERROR_JTAG_INIT_FAILED
;
458 i
= IEEE1284_MODE_EPP
;
459 i
= ioctl(device_handle
, PPSETMODE
, & i
);
462 LOG_ERROR(" cannot set compatible mode to device");
463 return ERROR_JTAG_INIT_FAILED
;
467 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
470 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
473 if (amt_jtagaccel_port
== 0)
475 amt_jtagaccel_port
= 0x378;
476 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
479 #if PARPORT_USE_GIVEIO == 1
480 if (amt_jtagaccel_get_giveio_access() != 0) {
481 #else /* PARPORT_USE_GIVEIO */
482 if (ioperm(amt_jtagaccel_port
, 5, 1) != 0) {
483 #endif /* PARPORT_USE_GIVEIO */
484 LOG_ERROR("missing privileges for direct i/o");
485 return ERROR_JTAG_INIT_FAILED
;
488 /* prepare epp port */
490 status_port
= inb(amt_jtagaccel_port
+ 1);
491 outb(status_port
| 0x1, amt_jtagaccel_port
+ 1);
494 outb(0x00, amt_jtagaccel_port
+ 2);
495 outb(0x04, amt_jtagaccel_port
+ 2);
500 /* set RTCK enable bit */
501 aw_control_fsm
|= 0x02;
504 /* enable JTAG port */
505 aw_control_fsm
|= 0x04;
506 AMT_AW(aw_control_fsm
);
509 int retval
= jtag_get_speed(&jtag_speed_var
);
510 amt_jtagaccel_speed(jtag_speed_var
);
512 enum reset_types jtag_reset_config
= jtag_get_reset_config();
513 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
514 aw_control_rst
&= ~0x8;
516 aw_control_rst
|= 0x8;
518 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
519 aw_control_rst
&= ~0x2;
521 aw_control_rst
|= 0x2;
523 amt_jtagaccel_reset(0, 0);
525 /* read status register */
527 LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status
);
532 static int amt_jtagaccel_quit(void)
538 COMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command
)
542 /* only if the port wasn't overwritten by cmdline */
543 if (amt_jtagaccel_port
== 0)
546 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], port
);
547 amt_jtagaccel_port
= port
;
551 LOG_ERROR("The parport port was already configured!");
556 command_print(CMD_CTX
, "parport port = %u", amt_jtagaccel_port
);
561 COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command
)
565 command_print(CMD_CTX
, "amt_jtagaccel RTCK feature %s", (rtck_enabled
) ? "enabled" : "disabled");
570 if (strcmp(CMD_ARGV
[0], "enabled") == 0)
583 static const struct command_registration amtjtagaccel_command_handlers
[] = {
585 .name
= "parport_port",
586 .handler
= &amt_jtagaccel_handle_parport_port_command
,
587 .mode
= COMMAND_CONFIG
,
588 .help
= "configure or display the parallel port to use",
589 .usage
= "[port_num]",
593 * @todo Remove this "rtck" command; just use the standard
594 * mechanism to enable/disable adaptive clocking. First
595 * implement the standard mechanism and deprecate "rtck";
596 * after a year or so, it'll be safe to remove this.
599 .handler
= &amt_jtagaccel_handle_rtck_command
,
600 .mode
= COMMAND_CONFIG
,
601 .help
= "configure or display RTCK support",
602 .usage
= "[enable|disable]",
604 COMMAND_REGISTRATION_DONE
607 struct jtag_interface amt_jtagaccel_interface
= {
608 .name
= "amt_jtagaccel",
609 .commands
= amtjtagaccel_command_handlers
,
611 .init
= amt_jtagaccel_init
,
612 .quit
= amt_jtagaccel_quit
,
613 .speed
= amt_jtagaccel_speed
,
614 .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)