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>
25 #include <jtag/commands.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 /* tap_move[i][j]: tap movement command to go from state i to state j
83 static uint8_t amt_jtagaccel_tap_move
[6][6][2] =
85 /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
86 {{0x1f, 0x00}, {0x0f, 0x00}, {0x05, 0x00}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* RESET */
87 {{0x1f, 0x00}, {0x00, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x0b, 0x00}}, /* IDLE */
88 {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRSHIFT */
89 {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* DRPAUSE */
90 {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* IRSHIFT */
91 {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* IRPAUSE */
95 static void amt_jtagaccel_reset(int trst
, int srst
)
98 aw_control_rst
|= 0x4;
100 aw_control_rst
&= ~0x4;
103 aw_control_rst
|= 0x1;
105 aw_control_rst
&= ~0x1;
107 AMT_AW(aw_control_rst
);
110 static int amt_jtagaccel_speed(int speed
)
112 aw_control_baudrate
&= 0xf0;
113 aw_control_baudrate
|= speed
& 0x0f;
114 AMT_AW(aw_control_baudrate
);
119 static void amt_jtagaccel_end_state(tap_state_t state
)
121 if (tap_is_state_stable(state
))
122 tap_set_end_state(state
);
125 LOG_ERROR("BUG: %i is not a valid end state", state
);
130 static void amt_wait_scan_busy(void)
136 while (((ar_status
) & 0x80) && (timeout
-- > 0))
139 if (ar_status
& 0x80)
141 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
);
146 static void amt_jtagaccel_state_move(void)
148 uint8_t aw_scan_tms_5
;
151 tap_state_t cur_state
= tap_get_state();
152 tap_state_t end_state
= tap_get_end_state();
154 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][0];
155 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(cur_state
)][tap_move_ndx(end_state
)][1];
157 aw_scan_tms_5
= 0x40 | (tms_scan
[0] & 0x1f);
158 AMT_AW(aw_scan_tms_5
);
159 int jtag_speed
= jtag_get_speed();
160 if (jtag_speed
> 3 || rtck_enabled
)
161 amt_wait_scan_busy();
163 if (tms_scan
[0] & 0x80)
165 aw_scan_tms_5
= 0x40 | (tms_scan
[1] & 0x1f);
166 AMT_AW(aw_scan_tms_5
);
167 if (jtag_speed
> 3 || rtck_enabled
)
168 amt_wait_scan_busy();
171 tap_set_state(end_state
);
174 static void amt_jtagaccel_runtest(int num_cycles
)
177 uint8_t aw_scan_tms_5
;
178 uint8_t aw_scan_tms_1to4
;
180 tap_state_t saved_end_state
= tap_get_end_state();
182 /* only do a state_move when we're not already in IDLE */
183 if (tap_get_state() != TAP_IDLE
)
185 amt_jtagaccel_end_state(TAP_IDLE
);
186 amt_jtagaccel_state_move();
189 while (num_cycles
- i
>= 5)
191 aw_scan_tms_5
= 0x40;
192 AMT_AW(aw_scan_tms_5
);
196 if (num_cycles
- i
> 0)
198 aw_scan_tms_1to4
= 0x80 | ((num_cycles
- i
- 1) & 0x3) << 4;
199 AMT_AW(aw_scan_tms_1to4
);
202 amt_jtagaccel_end_state(saved_end_state
);
203 if (tap_get_state() != tap_get_end_state())
204 amt_jtagaccel_state_move();
207 static void amt_jtagaccel_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
)
209 int bits_left
= scan_size
;
211 tap_state_t saved_end_state
= tap_get_end_state();
212 uint8_t aw_tdi_option
;
217 int jtag_speed
= jtag_get_speed();
220 amt_jtagaccel_end_state(TAP_IRSHIFT
);
222 amt_jtagaccel_end_state(TAP_DRSHIFT
);
224 amt_jtagaccel_state_move();
225 amt_jtagaccel_end_state(saved_end_state
);
227 /* handle unaligned bits at the beginning */
228 if ((scan_size
- 1) % 8)
230 aw_tdi_option
= 0x30 | (((scan_size
- 1) % 8) - 1);
231 AMT_AW(aw_tdi_option
);
233 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, (scan_size
- 1) % 8) & 0xff;
235 if (jtag_speed
> 3 || rtck_enabled
)
236 amt_wait_scan_busy();
238 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
241 dr_tdo
= dr_tdo
>> (8 - ((scan_size
- 1) % 8));
242 buf_set_u32(buffer
, bit_count
, (scan_size
- 1) % 8, dr_tdo
);
245 bit_count
+= (scan_size
- 1) % 8;
246 bits_left
-= (scan_size
- 1) % 8;
249 while (bits_left
- 1 >= 8)
251 dw_tdi_scan
= buf_get_u32(buffer
, bit_count
, 8) & 0xff;
253 if (jtag_speed
> 3 || rtck_enabled
)
254 amt_wait_scan_busy();
256 if ((type
== SCAN_IN
) || (type
== SCAN_IO
))
259 buf_set_u32(buffer
, bit_count
, 8, dr_tdo
);
266 tms_scan
[0] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
267 tms_scan
[1] = amt_jtagaccel_tap_move
[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
268 aw_tms_scan
= 0x40 | (tms_scan
[0] & 0x1f) | (buf_get_u32(buffer
, bit_count
, 1) << 5);
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
>> 7;
277 buf_set_u32(buffer
, bit_count
, 1, dr_tdo
);
280 if (tms_scan
[0] & 0x80)
282 aw_tms_scan
= 0x40 | (tms_scan
[1] & 0x1f);
284 if (jtag_speed
> 3 || rtck_enabled
)
285 amt_wait_scan_busy();
287 tap_set_state(tap_get_end_state());
290 static int amt_jtagaccel_execute_queue(void)
292 struct jtag_command
*cmd
= jtag_command_queue
; /* currently processed command */
298 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
299 * that wasn't handled by a caller-provided error handler
308 #ifdef _DEBUG_JTAG_IO_
309 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
311 if (cmd
->cmd
.reset
->trst
== 1)
313 tap_set_state(TAP_RESET
);
315 amt_jtagaccel_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
318 #ifdef _DEBUG_JTAG_IO_
319 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
321 amt_jtagaccel_end_state(cmd
->cmd
.runtest
->end_state
);
322 amt_jtagaccel_runtest(cmd
->cmd
.runtest
->num_cycles
);
325 #ifdef _DEBUG_JTAG_IO_
326 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
328 amt_jtagaccel_end_state(cmd
->cmd
.statemove
->end_state
);
329 amt_jtagaccel_state_move();
332 #ifdef _DEBUG_JTAG_IO_
333 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
335 amt_jtagaccel_end_state(cmd
->cmd
.scan
->end_state
);
336 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
337 type
= jtag_scan_type(cmd
->cmd
.scan
);
338 amt_jtagaccel_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
339 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
340 retval
= ERROR_JTAG_QUEUE_FAILED
;
345 #ifdef _DEBUG_JTAG_IO_
346 LOG_DEBUG("sleep %" PRIi32
, cmd
->cmd
.sleep
->us
);
348 jtag_sleep(cmd
->cmd
.sleep
->us
);
351 LOG_ERROR("BUG: unknown JTAG command type encountered");
360 #if PARPORT_USE_GIVEIO == 1
361 int amt_jtagaccel_get_giveio_access(void)
364 OSVERSIONINFO version
;
366 version
.dwOSVersionInfoSize
= sizeof version
;
367 if (!GetVersionEx(&version
)) {
371 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
374 h
= CreateFile("\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
375 if (h
== INVALID_HANDLE_VALUE
) {
386 static int amt_jtagaccel_init(void)
388 #if PARPORT_USE_PPDEV == 1
391 uint8_t control_port
;
397 #if PARPORT_USE_PPDEV == 1
398 if (device_handle
> 0)
400 LOG_ERROR("device is already opened");
401 return ERROR_JTAG_INIT_FAILED
;
404 snprintf(buffer
, 256, "/dev/parport%d", amt_jtagaccel_port
);
405 device_handle
= open(buffer
, O_RDWR
);
407 if (device_handle
< 0)
409 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
410 return ERROR_JTAG_INIT_FAILED
;
413 i
= ioctl(device_handle
, PPCLAIM
);
416 LOG_ERROR("cannot claim device");
417 return ERROR_JTAG_INIT_FAILED
;
420 i
= IEEE1284_MODE_EPP
;
421 i
= ioctl(device_handle
, PPSETMODE
, & i
);
424 LOG_ERROR(" cannot set compatible mode to device");
425 return ERROR_JTAG_INIT_FAILED
;
429 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
432 i
= ioctl(device_handle
, PPWCONTROL
, &control_port
);
435 if (amt_jtagaccel_port
== 0)
437 amt_jtagaccel_port
= 0x378;
438 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
441 #if PARPORT_USE_GIVEIO == 1
442 if (amt_jtagaccel_get_giveio_access() != 0) {
443 #else /* PARPORT_USE_GIVEIO */
444 if (ioperm(amt_jtagaccel_port
, 5, 1) != 0) {
445 #endif /* PARPORT_USE_GIVEIO */
446 LOG_ERROR("missing privileges for direct i/o");
447 return ERROR_JTAG_INIT_FAILED
;
450 /* prepare epp port */
452 status_port
= inb(amt_jtagaccel_port
+ 1);
453 outb(status_port
| 0x1, amt_jtagaccel_port
+ 1);
456 outb(0x00, amt_jtagaccel_port
+ 2);
457 outb(0x04, amt_jtagaccel_port
+ 2);
462 /* set RTCK enable bit */
463 aw_control_fsm
|= 0x02;
466 /* enable JTAG port */
467 aw_control_fsm
|= 0x04;
468 AMT_AW(aw_control_fsm
);
470 amt_jtagaccel_speed(jtag_get_speed());
472 enum reset_types jtag_reset_config
= jtag_get_reset_config();
473 if (jtag_reset_config
& RESET_TRST_OPEN_DRAIN
)
474 aw_control_rst
&= ~0x8;
476 aw_control_rst
|= 0x8;
478 if (jtag_reset_config
& RESET_SRST_PUSH_PULL
)
479 aw_control_rst
&= ~0x2;
481 aw_control_rst
|= 0x2;
483 amt_jtagaccel_reset(0, 0);
485 /* read status register */
487 LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status
);
492 static int amt_jtagaccel_quit(void)
498 COMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command
)
502 /* only if the port wasn't overwritten by cmdline */
503 if (amt_jtagaccel_port
== 0)
506 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], port
);
507 amt_jtagaccel_port
= port
;
511 LOG_ERROR("The parport port was already configured!");
516 command_print(CMD_CTX
, "parport port = %u", amt_jtagaccel_port
);
521 COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command
)
525 command_print(CMD_CTX
, "amt_jtagaccel RTCK feature %s", (rtck_enabled
) ? "enabled" : "disabled");
530 if (strcmp(CMD_ARGV
[0], "enabled") == 0)
543 static const struct command_registration amtjtagaccel_command_handlers
[] = {
545 .name
= "parport_port",
546 .handler
= &amt_jtagaccel_handle_parport_port_command
,
547 .mode
= COMMAND_CONFIG
,
548 .help
= "configure the parallel port to use",
549 .usage
= "<port_num>",
552 .name
= "parport_port",
553 .handler
= &amt_jtagaccel_handle_rtck_command
,
554 .mode
= COMMAND_CONFIG
,
555 .help
= "enable RTCK",
556 .usage
= "<enable|disable>",
558 COMMAND_REGISTRATION_DONE
561 struct jtag_interface amt_jtagaccel_interface
= {
562 .name
= "amt_jtagaccel",
563 .commands
= amtjtagaccel_command_handlers
,
564 .init
= &amt_jtagaccel_init
,
565 .quit
= &amt_jtagaccel_quit
,
566 .speed
= &amt_jtagaccel_speed
,
567 .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)