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 "interface.h"
28 #if PARPORT_USE_PPDEV == 1
29 #include <linux/parport.h>
30 #include <linux/ppdev.h>
31 #include <sys/ioctl.h>
32 #else /* not PARPORT_USE_PPDEV */
38 #if PARPORT_USE_GIVEIO == 1
45 static u16 amt_jtagaccel_port
;
47 /* interface variables
49 static u8 aw_control_rst
= 0x00;
50 static u8 aw_control_fsm
= 0x10;
51 static u8 aw_control_baudrate
= 0x20;
53 static int rtck_enabled
= 0;
55 #if PARPORT_USE_PPDEV == 1
56 static int device_handle
;
58 static int addr_mode
= IEEE1284_MODE_EPP
| IEEE1284_ADDR
;
59 #define AMT_AW(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); write(device_handle, &val, 1); } while (0)
60 #define AMT_AR(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); read(device_handle, &val, 1); } while (0)
62 static int data_mode
= IEEE1284_MODE_EPP
| IEEE1284_DATA
;
63 #define AMT_DW(val) do { ioctl(device_handle, PPSETMODE, &data_mode); write(device_handle, &val, 1); } while (0)
64 #define AMT_DR(val) do { ioctl(device_handle, PPSETMODE, &data_mode); read(device_handle, &val, 1); } while (0)
68 #define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0)
69 #define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0)
70 #define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0)
71 #define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0)
73 #endif // PARPORT_USE_PPDEV
75 static int amt_jtagaccel_execute_queue(void);
76 static int amt_jtagaccel_register_commands(struct command_context_s
*cmd_ctx
);
77 static int amt_jtagaccel_speed(int speed
);
78 static int amt_jtagaccel_init(void);
79 static int amt_jtagaccel_quit(void);
81 static int amt_jtagaccel_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
82 static int amt_jtagaccel_handle_rtck_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
84 /* tap_move[i][j]: tap movement command to go from state i to state j
92 static u8 amt_jtagaccel_tap_move
[6][6][2] =
94 /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
95 {{0x1f, 0x00}, {0x0f, 0x00}, {0x8a, 0x04}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* RESET */
96 {{0x1f, 0x00}, {0x00, 0x00}, {0x85, 0x08}, {0x05, 0x00}, {0x8b, 0x08}, {0x0b, 0x00}}, /* IDLE */
97 {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRSHIFT */
98 {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRPAUSE */
99 {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* IRSHIFT */
100 {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* IRPAUSE */
104 jtag_interface_t amt_jtagaccel_interface
=
106 .name
= "amt_jtagaccel",
108 .execute_queue
= amt_jtagaccel_execute_queue
,
110 .speed
= amt_jtagaccel_speed
,
111 .register_commands
= amt_jtagaccel_register_commands
,
112 .init
= amt_jtagaccel_init
,
113 .quit
= amt_jtagaccel_quit
,
116 static int amt_jtagaccel_register_commands(struct command_context_s
*cmd_ctx
)
118 register_command(cmd_ctx
, NULL
, "parport_port", amt_jtagaccel_handle_parport_port_command
,
119 COMMAND_CONFIG
, NULL
);
120 register_command(cmd_ctx
, NULL
, "rtck", amt_jtagaccel_handle_rtck_command
,
121 COMMAND_CONFIG
, NULL
);
126 static void amt_jtagaccel_reset(int trst
, int srst
)
129 aw_control_rst
|= 0x4;
131 aw_control_rst
&= ~0x4;
134 aw_control_rst
|= 0x1;
136 aw_control_rst
&= ~0x1;
138 AMT_AW(aw_control_rst
);
141 static int amt_jtagaccel_speed(int speed
)
143 aw_control_baudrate
&= 0xf0;
144 aw_control_baudrate
|= speed
& 0x0f;
145 AMT_AW(aw_control_baudrate
);
150 static void amt_jtagaccel_end_state(tap_state_t state
)
152 if (tap_is_state_stable(state
))
153 tap_set_end_state(state
);
156 LOG_ERROR("BUG: %i is not a valid end state", state
);
161 static void amt_wait_scan_busy(void)
167 while (((ar_status
) & 0x80) && (timeout
-- > 0))
170 if (ar_status
& 0x80)
172 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
);
177 static void amt_jtagaccel_state_move(void)
182 tap_state_t cur_state
= tap_get_state();
183 tap_state_t end_state
= tap_get_end_state();
185 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][0];
186 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][1];
188 aw_scan_tms_5
= 0x40 | (tms_scan
[0] & 0x1f);
189 AMT_AW(aw_scan_tms_5
);
190 if (jtag_speed
> 3 || rtck_enabled
)
191 amt_wait_scan_busy();
193 if (tms_scan
[0] & 0x80)
195 aw_scan_tms_5
= 0x40 | (tms_scan
[1] & 0x1f);
196 AMT_AW(aw_scan_tms_5
);
197 if (jtag_speed
> 3 || rtck_enabled
)
198 amt_wait_scan_busy();
201 tap_set_state(end_state
);
204 static void amt_jtagaccel_runtest(int num_cycles
)
210 tap_state_t saved_end_state
= tap_get_end_state();
212 /* only do a state_move when we're not already in IDLE */
213 if (tap_get_state() != TAP_IDLE
)
215 amt_jtagaccel_end_state(TAP_IDLE
);
216 amt_jtagaccel_state_move();
219 while (num_cycles
- i
>= 5)
221 aw_scan_tms_5
= 0x40;
222 AMT_AW(aw_scan_tms_5
);
226 if (num_cycles
- i
> 0)
228 aw_scan_tms_1to4
= 0x80 | ((num_cycles
- i
- 1) & 0x3) << 4;
229 AMT_AW(aw_scan_tms_1to4
);
232 amt_jtagaccel_end_state(saved_end_state
);
233 if (tap_get_state() != tap_get_end_state())
234 amt_jtagaccel_state_move();
237 static void amt_jtagaccel_scan(bool ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
239 int bits_left
= scan_size
;
241 tap_state_t saved_end_state
= tap_get_end_state();
249 amt_jtagaccel_end_state(TAP_IRSHIFT
);
251 amt_jtagaccel_end_state(TAP_DRSHIFT
);
253 amt_jtagaccel_state_move();
254 amt_jtagaccel_end_state(saved_end_state
);
256 /* handle unaligned bits at the beginning */
257 if ((scan_size
- 1) % 8)
259 aw_tdi_option
= 0x30 | (((scan_size
- 1) % 8) - 1);
260 AMT_AW(aw_tdi_option
);
262 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, (scan_size
- 1) % 8) & 0xff;
264 if (jtag_speed
> 3 || rtck_enabled
)
265 amt_wait_scan_busy();
267 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
270 dr_tdo
= dr_tdo
>> (8 - ((scan_size
- 1) % 8));
271 buf_set_u32(buffer
, bit_count
, (scan_size
- 1) % 8, dr_tdo
);
274 bit_count
+= (scan_size
- 1) % 8;
275 bits_left
-= (scan_size
- 1) % 8;
278 while (bits_left
- 1 >= 8)
280 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, 8) & 0xff;
282 if (jtag_speed
> 3 || rtck_enabled
)
283 amt_wait_scan_busy();
285 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
288 buf_set_u32(buffer
, bit_count
, 8, dr_tdo
);
295 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
296 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
297 aw_tms_scan
= 0x40 | (tms_scan
[0] & 0x1f) | (buf_get_u32(buffer
, bit_count
, 1) << 5);
299 if (jtag_speed
> 3 || rtck_enabled
)
300 amt_wait_scan_busy();
302 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
305 dr_tdo
= dr_tdo
>> 7;
306 buf_set_u32(buffer
, bit_count
, 1, dr_tdo
);
309 if (tms_scan
[0] & 0x80)
311 aw_tms_scan
= 0x40 | (tms_scan
[1] & 0x1f);
313 if (jtag_speed
> 3 || rtck_enabled
)
314 amt_wait_scan_busy();
316 tap_set_state(tap_get_end_state());
319 static int amt_jtagaccel_execute_queue(void)
321 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
327 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
328 * that wasn't handled by a caller-provided error handler
337 #ifdef _DEBUG_JTAG_IO_
338 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
340 if (cmd
->cmd
.reset
->trst
== 1)
342 tap_set_state(TAP_RESET
);
344 amt_jtagaccel_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
347 #ifdef _DEBUG_JTAG_IO_
348 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
350 amt_jtagaccel_end_state(cmd
->cmd
.runtest
->end_state
);
351 amt_jtagaccel_runtest(cmd
->cmd
.runtest
->num_cycles
);
354 #ifdef _DEBUG_JTAG_IO_
355 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
357 amt_jtagaccel_end_state(cmd
->cmd
.statemove
->end_state
);
358 amt_jtagaccel_state_move();
361 #ifdef _DEBUG_JTAG_IO_
362 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
364 amt_jtagaccel_end_state(cmd
->cmd
.scan
->end_state
);
365 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
366 type
= jtag_scan_type(cmd
->cmd
.scan
);
367 amt_jtagaccel_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
368 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
369 retval
= ERROR_JTAG_QUEUE_FAILED
;
374 #ifdef _DEBUG_JTAG_IO_
375 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
377 jtag_sleep(cmd
->cmd
.sleep
->us
);
380 LOG_ERROR("BUG: unknown JTAG command type encountered");
389 #if PARPORT_USE_GIVEIO == 1
390 int amt_jtagaccel_get_giveio_access(void)
393 OSVERSIONINFO version
;
395 version
.dwOSVersionInfoSize
= sizeof version
;
396 if (!GetVersionEx( &version
)) {
400 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
403 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
404 if (h
== INVALID_HANDLE_VALUE
) {
415 static int amt_jtagaccel_init(void)
417 #if PARPORT_USE_PPDEV == 1
426 #if PARPORT_USE_PPDEV == 1
427 if (device_handle
> 0)
429 LOG_ERROR("device is already opened");
430 return ERROR_JTAG_INIT_FAILED
;
433 snprintf(buffer
, 256, "/dev/parport%d", amt_jtagaccel_port
);
434 device_handle
= open(buffer
, O_RDWR
);
436 if (device_handle
< 0)
438 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
439 return ERROR_JTAG_INIT_FAILED
;
442 i
= ioctl(device_handle
, PPCLAIM
);
445 LOG_ERROR("cannot claim device");
446 return ERROR_JTAG_INIT_FAILED
;
449 i
= IEEE1284_MODE_EPP
;
450 i
= ioctl(device_handle
, PPSETMODE
, & i
);
453 LOG_ERROR(" cannot set compatible mode to device");
454 return ERROR_JTAG_INIT_FAILED
;
458 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
461 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
464 if (amt_jtagaccel_port
== 0)
466 amt_jtagaccel_port
= 0x378;
467 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
470 #if PARPORT_USE_GIVEIO == 1
471 if (amt_jtagaccel_get_giveio_access() != 0) {
472 #else /* PARPORT_USE_GIVEIO */
473 if (ioperm(amt_jtagaccel_port
, 5, 1) != 0) {
474 #endif /* PARPORT_USE_GIVEIO */
475 LOG_ERROR("missing privileges for direct i/o");
476 return ERROR_JTAG_INIT_FAILED
;
479 /* prepare epp port */
481 status_port
= inb(amt_jtagaccel_port
+ 1);
482 outb(status_port
| 0x1, amt_jtagaccel_port
+ 1);
485 outb(0x00, amt_jtagaccel_port
+ 2);
486 outb(0x04, amt_jtagaccel_port
+ 2);
491 /* set RTCK enable bit */
492 aw_control_fsm
|= 0x02;
495 /* enable JTAG port */
496 aw_control_fsm
|= 0x04;
497 AMT_AW(aw_control_fsm
);
499 amt_jtagaccel_speed(jtag_speed
);
501 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
502 aw_control_rst
&= ~0x8;
504 aw_control_rst
|= 0x8;
506 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
507 aw_control_rst
&= ~0x2;
509 aw_control_rst
|= 0x2;
511 amt_jtagaccel_reset(0, 0);
513 /* read status register */
515 LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status
);
520 static int amt_jtagaccel_quit(void)
526 static int amt_jtagaccel_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
531 /* only if the port wasn't overwritten by cmdline */
532 if (amt_jtagaccel_port
== 0)
533 amt_jtagaccel_port
= strtoul(args
[0], NULL
, 0);
538 static int amt_jtagaccel_handle_rtck_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
542 command_print(cmd_ctx
, "amt_jtagaccel RTCK feature %s", (rtck_enabled
) ? "enabled" : "disabled");
547 if (strcmp(args
[0], "enabled") == 0)
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)