1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2006 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 ***************************************************************************/
13 #include "xilinx_bit.h"
16 static const struct virtex2_command_set virtex2_default_commands
= {
24 .num_user
= 2, /* virtex II has only 2 user instructions */
27 static int virtex2_set_instr(struct jtag_tap
*tap
, uint64_t new_instr
)
32 if (buf_get_u64(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
) {
33 struct scan_field field
;
35 field
.num_bits
= tap
->ir_length
;
36 void *t
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
38 LOG_ERROR("Out of memory");
42 buf_set_u64(t
, 0, field
.num_bits
, new_instr
);
43 field
.in_value
= NULL
;
45 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
53 static int virtex2_send_32(struct pld_device
*pld_device
,
54 int num_words
, uint32_t *words
)
56 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
57 struct scan_field scan_field
;
61 values
= malloc(num_words
* 4);
63 LOG_ERROR("Out of memory");
67 scan_field
.num_bits
= num_words
* 32;
68 scan_field
.out_value
= values
;
69 scan_field
.in_value
= NULL
;
71 for (i
= 0; i
< num_words
; i
++)
72 buf_set_u32(values
+ 4 * i
, 0, 32, flip_u32(*words
++, 32));
74 int retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.cfg_in
);
75 if (retval
!= ERROR_OK
) {
80 jtag_add_dr_scan(virtex2_info
->tap
, 1, &scan_field
, TAP_DRPAUSE
);
87 static inline void virtexflip32(jtag_callback_data_t arg
)
89 uint8_t *in
= (uint8_t *)arg
;
90 *((uint32_t *)arg
) = flip_u32(le_to_h_u32(in
), 32);
93 static int virtex2_receive_32(struct pld_device
*pld_device
,
94 int num_words
, uint32_t *words
)
96 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
97 struct scan_field scan_field
;
99 scan_field
.num_bits
= 32;
100 scan_field
.out_value
= NULL
;
101 scan_field
.in_value
= NULL
;
103 int retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.cfg_out
);
104 if (retval
!= ERROR_OK
)
107 while (num_words
--) {
108 scan_field
.in_value
= (uint8_t *)words
;
110 jtag_add_dr_scan(virtex2_info
->tap
, 1, &scan_field
, TAP_DRPAUSE
);
112 jtag_add_callback(virtexflip32
, (jtag_callback_data_t
)words
);
120 static int virtex2_read_stat(struct pld_device
*pld_device
, uint32_t *status
)
126 data
[0] = 0xaa995566; /* synch word */
127 data
[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
128 data
[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
129 data
[3] = 0x20000000; /* NOOP */
130 data
[4] = 0x20000000; /* NOOP */
131 int retval
= virtex2_send_32(pld_device
, 5, data
);
132 if (retval
!= ERROR_OK
)
135 retval
= virtex2_receive_32(pld_device
, 1, status
);
136 if (retval
!= ERROR_OK
)
139 retval
= jtag_execute_queue();
140 if (retval
== ERROR_OK
)
141 LOG_DEBUG("status: 0x%8.8" PRIx32
, *status
);
146 static int virtex2_program(struct pld_device
*pld_device
)
148 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
152 int retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jshutdown
);
153 if (retval
!= ERROR_OK
)
156 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jprog_b
);
157 if (retval
!= ERROR_OK
)
160 jtag_add_runtest(62000, TAP_IDLE
);
161 if (!(virtex2_info
->no_jstart
)) {
162 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jstart
);
163 if (retval
!= ERROR_OK
)
167 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.bypass
);
168 if (retval
!= ERROR_OK
)
170 jtag_add_runtest(2000, TAP_IDLE
);
172 return jtag_execute_queue();
175 static int virtex2_load_prepare(struct pld_device
*pld_device
)
177 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
180 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jprog_b
);
181 if (retval
!= ERROR_OK
)
184 retval
= jtag_execute_queue();
185 if (retval
!= ERROR_OK
)
187 jtag_add_sleep(1000);
189 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.cfg_in
);
190 if (retval
!= ERROR_OK
)
193 return jtag_execute_queue();
196 static int virtex2_load_cleanup(struct pld_device
*pld_device
)
198 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
203 if (!(virtex2_info
->no_jstart
)) {
204 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jstart
);
205 if (retval
!= ERROR_OK
)
208 jtag_add_runtest(13, TAP_IDLE
);
209 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.bypass
);
210 if (retval
!= ERROR_OK
)
212 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.bypass
);
213 if (retval
!= ERROR_OK
)
215 if (!(virtex2_info
->no_jstart
)) {
216 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jstart
);
217 if (retval
!= ERROR_OK
)
220 jtag_add_runtest(13, TAP_IDLE
);
221 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.bypass
);
222 if (retval
!= ERROR_OK
)
225 return jtag_execute_queue();
228 static int virtex2_load(struct pld_device
*pld_device
, const char *filename
)
230 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
231 struct xilinx_bit_file bit_file
;
234 struct scan_field field
;
236 field
.in_value
= NULL
;
238 retval
= xilinx_read_bit_file(&bit_file
, filename
);
239 if (retval
!= ERROR_OK
)
242 retval
= virtex2_load_prepare(pld_device
);
243 if (retval
!= ERROR_OK
) {
244 xilinx_free_bit_file(&bit_file
);
248 for (i
= 0; i
< bit_file
.length
; i
++)
249 bit_file
.data
[i
] = flip_u32(bit_file
.data
[i
], 8);
251 field
.num_bits
= bit_file
.length
* 8;
252 field
.out_value
= bit_file
.data
;
254 jtag_add_dr_scan(virtex2_info
->tap
, 1, &field
, TAP_DRPAUSE
);
255 retval
= jtag_execute_queue();
256 if (retval
!= ERROR_OK
) {
257 xilinx_free_bit_file(&bit_file
);
261 retval
= virtex2_load_cleanup(pld_device
);
263 xilinx_free_bit_file(&bit_file
);
268 COMMAND_HANDLER(virtex2_handle_refresh_command
)
270 struct pld_device
*device
;
273 return ERROR_COMMAND_SYNTAX_ERROR
;
275 device
= get_pld_device_by_name_or_numstr(CMD_ARGV
[0]);
277 command_print(CMD
, "pld device '#%s' is out of bounds or unknown", CMD_ARGV
[0]);
281 return virtex2_program(device
);
284 COMMAND_HANDLER(virtex2_handle_read_stat_command
)
286 struct pld_device
*device
;
290 return ERROR_COMMAND_SYNTAX_ERROR
;
292 device
= get_pld_device_by_name_or_numstr(CMD_ARGV
[0]);
294 command_print(CMD
, "pld device '#%s' is out of bounds or unknown", CMD_ARGV
[0]);
298 int retval
= virtex2_read_stat(device
, &status
);
299 if (retval
!= ERROR_OK
) {
300 command_print(CMD
, "cannot read virtex2 status register");
304 command_print(CMD
, "virtex2 status register: 0x%8.8" PRIx32
, status
);
309 static int xilinx_get_ipdbg_hub(int user_num
, struct pld_device
*pld_device
, struct pld_ipdbg_hub
*hub
)
314 struct virtex2_pld_device
*pld_device_info
= pld_device
->driver_priv
;
316 if (!pld_device_info
|| !pld_device_info
->tap
)
319 hub
->tap
= pld_device_info
->tap
;
320 if (user_num
< 1 || (unsigned int)user_num
> pld_device_info
->command_set
.num_user
) {
321 LOG_ERROR("device has only user register 1 to %d", pld_device_info
->command_set
.num_user
);
325 hub
->user_ir_code
= pld_device_info
->command_set
.user
[user_num
- 1];
329 static int xilinx_get_jtagspi_userircode(struct pld_device
*pld_device
, unsigned int *ir
)
331 if (!pld_device
|| !pld_device
->driver_priv
)
333 struct virtex2_pld_device
*pld_device_info
= pld_device
->driver_priv
;
335 if (pld_device_info
->command_set
.num_user
< 1) {
336 LOG_ERROR("code for command 'select user1' is unknown");
340 *ir
= pld_device_info
->command_set
.user
[0];
344 COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command
)
346 if (CMD_ARGC
< 6 || CMD_ARGC
> (6 + VIRTEX2_MAX_USER_INSTRUCTIONS
))
347 return ERROR_COMMAND_SYNTAX_ERROR
;
349 struct pld_device
*device
= get_pld_device_by_name(CMD_ARGV
[0]);
351 command_print(CMD
, "pld device '#%s' is unknown", CMD_ARGV
[0]);
355 struct virtex2_pld_device
*virtex2_info
= device
->driver_priv
;
359 struct virtex2_command_set instr_codes
;
360 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[1], instr_codes
.cfg_out
);
361 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[2], instr_codes
.cfg_in
);
362 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[3], instr_codes
.jprog_b
);
363 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[4], instr_codes
.jstart
);
364 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[5], instr_codes
.jshutdown
);
365 instr_codes
.bypass
= 0xffffffffffffffffULL
;
367 unsigned int num_user
= CMD_ARGC
- 6;
368 for (unsigned int i
= 0; i
< num_user
; ++i
)
369 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[6 + i
], instr_codes
.user
[i
]);
370 instr_codes
.num_user
= num_user
;
372 virtex2_info
->command_set
= instr_codes
;
376 COMMAND_HANDLER(virtex2_handle_set_user_codes_command
)
378 if (CMD_ARGC
< 2 || CMD_ARGC
> (1 + VIRTEX2_MAX_USER_INSTRUCTIONS
))
379 return ERROR_COMMAND_SYNTAX_ERROR
;
381 struct pld_device
*device
= get_pld_device_by_name(CMD_ARGV
[0]);
383 command_print(CMD
, "pld device '#%s' is unknown", CMD_ARGV
[0]);
387 struct virtex2_pld_device
*virtex2_info
= device
->driver_priv
;
391 uint64_t user
[VIRTEX2_MAX_USER_INSTRUCTIONS
];
392 unsigned int num_user
= CMD_ARGC
- 1;
393 for (unsigned int i
= 0; i
< num_user
; ++i
)
394 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[1 + i
], user
[i
]);
395 virtex2_info
->command_set
.num_user
= num_user
;
396 memcpy(virtex2_info
->command_set
.user
, user
, num_user
* sizeof(uint64_t));
400 PLD_CREATE_COMMAND_HANDLER(virtex2_pld_create_command
)
403 return ERROR_COMMAND_SYNTAX_ERROR
;
405 if (strcmp(CMD_ARGV
[2], "-chain-position") != 0)
406 return ERROR_COMMAND_SYNTAX_ERROR
;
408 struct jtag_tap
*tap
= jtag_tap_by_string(CMD_ARGV
[3]);
410 command_print(CMD
, "Tap: %s does not exist", CMD_ARGV
[3]);
414 struct virtex2_pld_device
*virtex2_info
= malloc(sizeof(struct virtex2_pld_device
));
416 LOG_ERROR("Out of memory");
419 virtex2_info
->tap
= tap
;
420 virtex2_info
->command_set
= virtex2_default_commands
;
422 virtex2_info
->no_jstart
= 0;
423 if (CMD_ARGC
>= 5 && strcmp(CMD_ARGV
[4], "-no_jstart") == 0)
424 virtex2_info
->no_jstart
= 1;
426 pld
->driver_priv
= virtex2_info
;
431 static const struct command_registration virtex2_exec_command_handlers
[] = {
434 .mode
= COMMAND_EXEC
,
435 .handler
= virtex2_handle_read_stat_command
,
436 .help
= "read status register",
439 .name
= "set_instr_codes",
441 .handler
= virtex2_handle_set_instuction_codes_command
,
442 .help
= "set instructions codes used for loading the bitstream/refreshing/jtag-hub",
443 .usage
= "pld_name cfg_out cfg_in jprogb jstart jshutdown"
444 " [user1 [user2 [user3 [user4]]]]",
446 .name
= "set_user_codes",
448 .handler
= virtex2_handle_set_user_codes_command
,
449 .help
= "set instructions codes used for jtag-hub",
450 .usage
= "pld_name user1 [user2 [user3 [user4]]]",
453 .mode
= COMMAND_EXEC
,
454 .handler
= virtex2_handle_refresh_command
,
455 .help
= "start loading of configuration (program)",
458 COMMAND_REGISTRATION_DONE
461 static const struct command_registration virtex2_command_handler
[] = {
465 .help
= "Virtex-II specific commands",
467 .chain
= virtex2_exec_command_handlers
,
469 COMMAND_REGISTRATION_DONE
472 struct pld_driver virtex2_pld
= {
474 .commands
= virtex2_command_handler
,
475 .pld_create_command
= &virtex2_pld_create_command
,
476 .load
= &virtex2_load
,
477 .get_ipdbg_hub
= xilinx_get_ipdbg_hub
,
478 .get_jtagspi_userircode
= xilinx_get_jtagspi_userircode
,
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)