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 uint16_t amt_jtagaccel_port
;
47 /* interface variables
49 static uint8_t aw_control_rst
= 0x00;
50 static uint8_t aw_control_fsm
= 0x10;
51 static uint8_t 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 uint8_t 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)
179 uint8_t aw_scan_tms_5
;
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 int jtag_speed
= jtag_get_speed();
191 if (jtag_speed
> 3 || rtck_enabled
)
192 amt_wait_scan_busy();
194 if (tms_scan
[0] & 0x80)
196 aw_scan_tms_5
= 0x40 | (tms_scan
[1] & 0x1f);
197 AMT_AW(aw_scan_tms_5
);
198 if (jtag_speed
> 3 || rtck_enabled
)
199 amt_wait_scan_busy();
202 tap_set_state(end_state
);
205 static void amt_jtagaccel_runtest(int num_cycles
)
208 uint8_t aw_scan_tms_5
;
209 uint8_t aw_scan_tms_1to4
;
211 tap_state_t saved_end_state
= tap_get_end_state();
213 /* only do a state_move when we're not already in IDLE */
214 if (tap_get_state() != TAP_IDLE
)
216 amt_jtagaccel_end_state(TAP_IDLE
);
217 amt_jtagaccel_state_move();
220 while (num_cycles
- i
>= 5)
222 aw_scan_tms_5
= 0x40;
223 AMT_AW(aw_scan_tms_5
);
227 if (num_cycles
- i
> 0)
229 aw_scan_tms_1to4
= 0x80 | ((num_cycles
- i
- 1) & 0x3) << 4;
230 AMT_AW(aw_scan_tms_1to4
);
233 amt_jtagaccel_end_state(saved_end_state
);
234 if (tap_get_state() != tap_get_end_state())
235 amt_jtagaccel_state_move();
238 static void amt_jtagaccel_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
)
240 int bits_left
= scan_size
;
242 tap_state_t saved_end_state
= tap_get_end_state();
243 uint8_t aw_tdi_option
;
248 int jtag_speed
= jtag_get_speed();
251 amt_jtagaccel_end_state(TAP_IRSHIFT
);
253 amt_jtagaccel_end_state(TAP_DRSHIFT
);
255 amt_jtagaccel_state_move();
256 amt_jtagaccel_end_state(saved_end_state
);
258 /* handle unaligned bits at the beginning */
259 if ((scan_size
- 1) % 8)
261 aw_tdi_option
= 0x30 | (((scan_size
- 1) % 8) - 1);
262 AMT_AW(aw_tdi_option
);
264 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, (scan_size
- 1) % 8) & 0xff;
266 if (jtag_speed
> 3 || rtck_enabled
)
267 amt_wait_scan_busy();
269 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
272 dr_tdo
= dr_tdo
>> (8 - ((scan_size
- 1) % 8));
273 buf_set_u32(buffer
, bit_count
, (scan_size
- 1) % 8, dr_tdo
);
276 bit_count
+= (scan_size
- 1) % 8;
277 bits_left
-= (scan_size
- 1) % 8;
280 while (bits_left
- 1 >= 8)
282 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, 8) & 0xff;
284 if (jtag_speed
> 3 || rtck_enabled
)
285 amt_wait_scan_busy();
287 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
290 buf_set_u32(buffer
, bit_count
, 8, dr_tdo
);
297 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
298 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
299 aw_tms_scan
= 0x40 | (tms_scan
[0] & 0x1f) | (buf_get_u32(buffer
, bit_count
, 1) << 5);
301 if (jtag_speed
> 3 || rtck_enabled
)
302 amt_wait_scan_busy();
304 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
307 dr_tdo
= dr_tdo
>> 7;
308 buf_set_u32(buffer
, bit_count
, 1, dr_tdo
);
311 if (tms_scan
[0] & 0x80)
313 aw_tms_scan
= 0x40 | (tms_scan
[1] & 0x1f);
315 if (jtag_speed
> 3 || rtck_enabled
)
316 amt_wait_scan_busy();
318 tap_set_state(tap_get_end_state());
321 static int amt_jtagaccel_execute_queue(void)
323 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
329 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
330 * that wasn't handled by a caller-provided error handler
339 #ifdef _DEBUG_JTAG_IO_
340 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
342 if (cmd
->cmd
.reset
->trst
== 1)
344 tap_set_state(TAP_RESET
);
346 amt_jtagaccel_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
349 #ifdef _DEBUG_JTAG_IO_
350 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
352 amt_jtagaccel_end_state(cmd
->cmd
.runtest
->end_state
);
353 amt_jtagaccel_runtest(cmd
->cmd
.runtest
->num_cycles
);
356 #ifdef _DEBUG_JTAG_IO_
357 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
359 amt_jtagaccel_end_state(cmd
->cmd
.statemove
->end_state
);
360 amt_jtagaccel_state_move();
363 #ifdef _DEBUG_JTAG_IO_
364 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
366 amt_jtagaccel_end_state(cmd
->cmd
.scan
->end_state
);
367 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
368 type
= jtag_scan_type(cmd
->cmd
.scan
);
369 amt_jtagaccel_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
370 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
371 retval
= ERROR_JTAG_QUEUE_FAILED
;
376 #ifdef _DEBUG_JTAG_IO_
377 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
379 jtag_sleep(cmd
->cmd
.sleep
->us
);
382 LOG_ERROR("BUG: unknown JTAG command type encountered");
391 #if PARPORT_USE_GIVEIO == 1
392 int amt_jtagaccel_get_giveio_access(void)
395 OSVERSIONINFO version
;
397 version
.dwOSVersionInfoSize
= sizeof version
;
398 if (!GetVersionEx( &version
)) {
402 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
405 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
406 if (h
== INVALID_HANDLE_VALUE
) {
417 static int amt_jtagaccel_init(void)
419 #if PARPORT_USE_PPDEV == 1
422 uint8_t control_port
;
428 #if PARPORT_USE_PPDEV == 1
429 if (device_handle
> 0)
431 LOG_ERROR("device is already opened");
432 return ERROR_JTAG_INIT_FAILED
;
435 snprintf(buffer
, 256, "/dev/parport%d", amt_jtagaccel_port
);
436 device_handle
= open(buffer
, O_RDWR
);
438 if (device_handle
< 0)
440 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
441 return ERROR_JTAG_INIT_FAILED
;
444 i
= ioctl(device_handle
, PPCLAIM
);
447 LOG_ERROR("cannot claim device");
448 return ERROR_JTAG_INIT_FAILED
;
451 i
= IEEE1284_MODE_EPP
;
452 i
= ioctl(device_handle
, PPSETMODE
, & i
);
455 LOG_ERROR(" cannot set compatible mode to device");
456 return ERROR_JTAG_INIT_FAILED
;
460 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
463 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
466 if (amt_jtagaccel_port
== 0)
468 amt_jtagaccel_port
= 0x378;
469 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
472 #if PARPORT_USE_GIVEIO == 1
473 if (amt_jtagaccel_get_giveio_access() != 0) {
474 #else /* PARPORT_USE_GIVEIO */
475 if (ioperm(amt_jtagaccel_port
, 5, 1) != 0) {
476 #endif /* PARPORT_USE_GIVEIO */
477 LOG_ERROR("missing privileges for direct i/o");
478 return ERROR_JTAG_INIT_FAILED
;
481 /* prepare epp port */
483 status_port
= inb(amt_jtagaccel_port
+ 1);
484 outb(status_port
| 0x1, amt_jtagaccel_port
+ 1);
487 outb(0x00, amt_jtagaccel_port
+ 2);
488 outb(0x04, amt_jtagaccel_port
+ 2);
493 /* set RTCK enable bit */
494 aw_control_fsm
|= 0x02;
497 /* enable JTAG port */
498 aw_control_fsm
|= 0x04;
499 AMT_AW(aw_control_fsm
);
501 amt_jtagaccel_speed(jtag_get_speed());
503 enum reset_types jtag_reset_config
= jtag_get_reset_config();
504 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
505 aw_control_rst
&= ~0x8;
507 aw_control_rst
|= 0x8;
509 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
510 aw_control_rst
&= ~0x2;
512 aw_control_rst
|= 0x2;
514 amt_jtagaccel_reset(0, 0);
516 /* read status register */
518 LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status
);
523 static int amt_jtagaccel_quit(void)
529 static int amt_jtagaccel_handle_parport_port_command(
530 struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
534 /* only if the port wasn't overwritten by cmdline */
535 if (amt_jtagaccel_port
== 0)
537 int retval
= parse_u16(args
[0], &amt_jtagaccel_port
);
538 if (ERROR_OK
!= retval
)
543 LOG_ERROR("The parport port was already configured!");
548 command_print(cmd_ctx
, "parport port = %u", amt_jtagaccel_port
);
553 static int amt_jtagaccel_handle_rtck_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
557 command_print(cmd_ctx
, "amt_jtagaccel RTCK feature %s", (rtck_enabled
) ? "enabled" : "disabled");
562 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)