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 ***************************************************************************/
27 #if PARPORT_USE_PPDEV == 1
28 #include <linux/parport.h>
29 #include <linux/ppdev.h>
30 #include <sys/ioctl.h>
31 #else /* not PARPORT_USE_PPDEV */
37 #if PARPORT_USE_GIVEIO == 1
44 static u16 amt_jtagaccel_port
;
46 /* interface variables
48 static u8 aw_control_rst
= 0x00;
49 static u8 aw_control_fsm
= 0x10;
50 static u8 aw_control_baudrate
= 0x20;
52 static int rtck_enabled
= 0;
54 #if PARPORT_USE_PPDEV == 1
55 static int device_handle
;
57 static int addr_mode
= IEEE1284_MODE_EPP
| IEEE1284_ADDR
;
58 #define AMT_AW(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); write(device_handle, &val, 1); } while (0)
59 #define AMT_AR(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); read(device_handle, &val, 1); } while (0)
61 static int data_mode
= IEEE1284_MODE_EPP
| IEEE1284_DATA
;
62 #define AMT_DW(val) do { ioctl(device_handle, PPSETMODE, &data_mode); write(device_handle, &val, 1); } while (0)
63 #define AMT_DR(val) do { ioctl(device_handle, PPSETMODE, &data_mode); read(device_handle, &val, 1); } while (0)
67 #define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0)
68 #define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0)
69 #define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0)
70 #define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0)
72 #endif // PARPORT_USE_PPDEV
74 static int amt_jtagaccel_execute_queue(void);
75 static int amt_jtagaccel_register_commands(struct command_context_s
*cmd_ctx
);
76 static int amt_jtagaccel_speed(int speed
);
77 static int amt_jtagaccel_init(void);
78 static int amt_jtagaccel_quit(void);
80 static int amt_jtagaccel_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
81 static int amt_jtagaccel_handle_rtck_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
83 /* tap_move[i][j]: tap movement command to go from state i to state j
91 static u8 amt_jtagaccel_tap_move
[6][6][2] =
93 /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
94 {{0x1f, 0x00}, {0x0f, 0x00}, {0x8a, 0x04}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* RESET */
95 {{0x1f, 0x00}, {0x00, 0x00}, {0x85, 0x08}, {0x05, 0x00}, {0x8b, 0x08}, {0x0b, 0x00}}, /* IDLE */
96 {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRSHIFT */
97 {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRPAUSE */
98 {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* IRSHIFT */
99 {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* IRPAUSE */
103 jtag_interface_t amt_jtagaccel_interface
=
105 .name
= "amt_jtagaccel",
107 .execute_queue
= amt_jtagaccel_execute_queue
,
109 .speed
= amt_jtagaccel_speed
,
110 .register_commands
= amt_jtagaccel_register_commands
,
111 .init
= amt_jtagaccel_init
,
112 .quit
= amt_jtagaccel_quit
,
115 static int amt_jtagaccel_register_commands(struct command_context_s
*cmd_ctx
)
117 register_command(cmd_ctx
, NULL
, "parport_port", amt_jtagaccel_handle_parport_port_command
,
118 COMMAND_CONFIG
, NULL
);
119 register_command(cmd_ctx
, NULL
, "rtck", amt_jtagaccel_handle_rtck_command
,
120 COMMAND_CONFIG
, NULL
);
125 static void amt_jtagaccel_reset(int trst
, int srst
)
128 aw_control_rst
|= 0x4;
130 aw_control_rst
&= ~0x4;
133 aw_control_rst
|= 0x1;
135 aw_control_rst
&= ~0x1;
137 AMT_AW(aw_control_rst
);
140 static int amt_jtagaccel_speed(int speed
)
142 aw_control_baudrate
&= 0xf0;
143 aw_control_baudrate
|= speed
& 0x0f;
144 AMT_AW(aw_control_baudrate
);
149 static void amt_jtagaccel_end_state(tap_state_t state
)
151 if (tap_is_state_stable(state
))
152 tap_set_end_state(state
);
155 LOG_ERROR("BUG: %i is not a valid end state", state
);
160 static void amt_wait_scan_busy(void)
166 while (((ar_status
) & 0x80) && (timeout
-- > 0))
169 if (ar_status
& 0x80)
171 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
);
176 static void amt_jtagaccel_state_move(void)
181 tap_state_t cur_state
= tap_get_state();
182 tap_state_t end_state
= tap_get_end_state();
184 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][0];
185 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][1];
187 aw_scan_tms_5
= 0x40 | (tms_scan
[0] & 0x1f);
188 AMT_AW(aw_scan_tms_5
);
189 if (jtag_speed
> 3 || rtck_enabled
)
190 amt_wait_scan_busy();
192 if (tms_scan
[0] & 0x80)
194 aw_scan_tms_5
= 0x40 | (tms_scan
[1] & 0x1f);
195 AMT_AW(aw_scan_tms_5
);
196 if (jtag_speed
> 3 || rtck_enabled
)
197 amt_wait_scan_busy();
200 tap_set_state(end_state
);
203 static void amt_jtagaccel_runtest(int num_cycles
)
209 tap_state_t saved_end_state
= tap_get_end_state();
211 /* only do a state_move when we're not already in IDLE */
212 if (tap_get_state() != TAP_IDLE
)
214 amt_jtagaccel_end_state(TAP_IDLE
);
215 amt_jtagaccel_state_move();
218 while (num_cycles
- i
>= 5)
220 aw_scan_tms_5
= 0x40;
221 AMT_AW(aw_scan_tms_5
);
225 if (num_cycles
- i
> 0)
227 aw_scan_tms_1to4
= 0x80 | ((num_cycles
- i
- 1) & 0x3) << 4;
228 AMT_AW(aw_scan_tms_1to4
);
231 amt_jtagaccel_end_state(saved_end_state
);
232 if (tap_get_state() != tap_get_end_state())
233 amt_jtagaccel_state_move();
236 static void amt_jtagaccel_scan(bool ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
238 int bits_left
= scan_size
;
240 tap_state_t saved_end_state
= tap_get_end_state();
248 amt_jtagaccel_end_state(TAP_IRSHIFT
);
250 amt_jtagaccel_end_state(TAP_DRSHIFT
);
252 amt_jtagaccel_state_move();
253 amt_jtagaccel_end_state(saved_end_state
);
255 /* handle unaligned bits at the beginning */
256 if ((scan_size
- 1) % 8)
258 aw_tdi_option
= 0x30 | (((scan_size
- 1) % 8) - 1);
259 AMT_AW(aw_tdi_option
);
261 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, (scan_size
- 1) % 8) & 0xff;
263 if (jtag_speed
> 3 || rtck_enabled
)
264 amt_wait_scan_busy();
266 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
269 dr_tdo
= dr_tdo
>> (8 - ((scan_size
- 1) % 8));
270 buf_set_u32(buffer
, bit_count
, (scan_size
- 1) % 8, dr_tdo
);
273 bit_count
+= (scan_size
- 1) % 8;
274 bits_left
-= (scan_size
- 1) % 8;
277 while (bits_left
- 1 >= 8)
279 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, 8) & 0xff;
281 if (jtag_speed
> 3 || rtck_enabled
)
282 amt_wait_scan_busy();
284 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
287 buf_set_u32(buffer
, bit_count
, 8, dr_tdo
);
294 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
295 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
296 aw_tms_scan
= 0x40 | (tms_scan
[0] & 0x1f) | (buf_get_u32(buffer
, bit_count
, 1) << 5);
298 if (jtag_speed
> 3 || rtck_enabled
)
299 amt_wait_scan_busy();
301 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
304 dr_tdo
= dr_tdo
>> 7;
305 buf_set_u32(buffer
, bit_count
, 1, dr_tdo
);
308 if (tms_scan
[0] & 0x80)
310 aw_tms_scan
= 0x40 | (tms_scan
[1] & 0x1f);
312 if (jtag_speed
> 3 || rtck_enabled
)
313 amt_wait_scan_busy();
315 tap_set_state(tap_get_end_state());
318 static int amt_jtagaccel_execute_queue(void)
320 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
326 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
327 * that wasn't handled by a caller-provided error handler
336 #ifdef _DEBUG_JTAG_IO_
337 LOG_DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
339 if (cmd
->cmd
.end_state
->end_state
!= TAP_INVALID
)
340 amt_jtagaccel_end_state(cmd
->cmd
.end_state
->end_state
);
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 if (cmd
->cmd
.runtest
->end_state
!= TAP_INVALID
)
357 amt_jtagaccel_end_state(cmd
->cmd
.runtest
->end_state
);
358 amt_jtagaccel_runtest(cmd
->cmd
.runtest
->num_cycles
);
361 #ifdef _DEBUG_JTAG_IO_
362 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
364 if (cmd
->cmd
.statemove
->end_state
!= TAP_INVALID
)
365 amt_jtagaccel_end_state(cmd
->cmd
.statemove
->end_state
);
366 amt_jtagaccel_state_move();
369 #ifdef _DEBUG_JTAG_IO_
370 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
372 if (cmd
->cmd
.scan
->end_state
!= TAP_INVALID
)
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 %i", 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
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
);
508 amt_jtagaccel_speed(jtag_speed
);
510 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
511 aw_control_rst
&= ~0x8;
513 aw_control_rst
|= 0x8;
515 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
516 aw_control_rst
&= ~0x2;
518 aw_control_rst
|= 0x2;
520 amt_jtagaccel_reset(0, 0);
522 /* read status register */
524 LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status
);
529 static int amt_jtagaccel_quit(void)
535 static int amt_jtagaccel_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
540 /* only if the port wasn't overwritten by cmdline */
541 if (amt_jtagaccel_port
== 0)
542 amt_jtagaccel_port
= strtoul(args
[0], NULL
, 0);
547 static int amt_jtagaccel_handle_rtck_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
551 command_print(cmd_ctx
, "amt_jtagaccel RTCK feature %s", (rtck_enabled
) ? "enabled" : "disabled");
556 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)