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_load_prepare(struct pld_device
*pld_device
)
148 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
151 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jprog_b
);
152 if (retval
!= ERROR_OK
)
155 retval
= jtag_execute_queue();
156 if (retval
!= ERROR_OK
)
158 jtag_add_sleep(1000);
160 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.cfg_in
);
161 if (retval
!= ERROR_OK
)
164 return jtag_execute_queue();
167 static int virtex2_load_cleanup(struct pld_device
*pld_device
)
169 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
174 if (!(virtex2_info
->no_jstart
)) {
175 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jstart
);
176 if (retval
!= ERROR_OK
)
179 jtag_add_runtest(13, TAP_IDLE
);
180 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.bypass
);
181 if (retval
!= ERROR_OK
)
183 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.bypass
);
184 if (retval
!= ERROR_OK
)
186 if (!(virtex2_info
->no_jstart
)) {
187 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.jstart
);
188 if (retval
!= ERROR_OK
)
191 jtag_add_runtest(13, TAP_IDLE
);
192 retval
= virtex2_set_instr(virtex2_info
->tap
, virtex2_info
->command_set
.bypass
);
193 if (retval
!= ERROR_OK
)
196 return jtag_execute_queue();
199 static int virtex2_load(struct pld_device
*pld_device
, const char *filename
)
201 struct virtex2_pld_device
*virtex2_info
= pld_device
->driver_priv
;
202 struct xilinx_bit_file bit_file
;
205 struct scan_field field
;
207 field
.in_value
= NULL
;
209 retval
= xilinx_read_bit_file(&bit_file
, filename
);
210 if (retval
!= ERROR_OK
)
213 retval
= virtex2_load_prepare(pld_device
);
214 if (retval
!= ERROR_OK
) {
215 xilinx_free_bit_file(&bit_file
);
219 for (i
= 0; i
< bit_file
.length
; i
++)
220 bit_file
.data
[i
] = flip_u32(bit_file
.data
[i
], 8);
222 field
.num_bits
= bit_file
.length
* 8;
223 field
.out_value
= bit_file
.data
;
225 jtag_add_dr_scan(virtex2_info
->tap
, 1, &field
, TAP_DRPAUSE
);
226 retval
= jtag_execute_queue();
227 if (retval
!= ERROR_OK
) {
228 xilinx_free_bit_file(&bit_file
);
232 retval
= virtex2_load_cleanup(pld_device
);
234 xilinx_free_bit_file(&bit_file
);
239 COMMAND_HANDLER(virtex2_handle_read_stat_command
)
241 struct pld_device
*device
;
245 return ERROR_COMMAND_SYNTAX_ERROR
;
247 device
= get_pld_device_by_name_or_numstr(CMD_ARGV
[0]);
249 command_print(CMD
, "pld device '#%s' is out of bounds or unknown", CMD_ARGV
[0]);
253 int retval
= virtex2_read_stat(device
, &status
);
254 if (retval
!= ERROR_OK
) {
255 command_print(CMD
, "cannot read virtex2 status register");
259 command_print(CMD
, "virtex2 status register: 0x%8.8" PRIx32
, status
);
264 COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command
)
266 if (CMD_ARGC
< 6 || CMD_ARGC
> (6 + VIRTEX2_MAX_USER_INSTRUCTIONS
))
267 return ERROR_COMMAND_SYNTAX_ERROR
;
269 struct pld_device
*device
= get_pld_device_by_name(CMD_ARGV
[0]);
271 command_print(CMD
, "pld device '#%s' is unknown", CMD_ARGV
[0]);
275 struct virtex2_pld_device
*virtex2_info
= device
->driver_priv
;
279 struct virtex2_command_set instr_codes
;
280 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[1], instr_codes
.cfg_out
);
281 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[2], instr_codes
.cfg_in
);
282 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[3], instr_codes
.jprog_b
);
283 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[4], instr_codes
.jstart
);
284 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[5], instr_codes
.jshutdown
);
285 instr_codes
.bypass
= 0xffffffffffffffff;
287 unsigned int num_user
= CMD_ARGC
- 6;
288 for (unsigned int i
= 0; i
< num_user
; ++i
)
289 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[6 + i
], instr_codes
.user
[i
]);
290 instr_codes
.num_user
= num_user
;
292 virtex2_info
->command_set
= instr_codes
;
296 COMMAND_HANDLER(virtex2_handle_set_user_codes_command
)
298 if (CMD_ARGC
< 2 || CMD_ARGC
> (1 + VIRTEX2_MAX_USER_INSTRUCTIONS
))
299 return ERROR_COMMAND_SYNTAX_ERROR
;
301 struct pld_device
*device
= get_pld_device_by_name(CMD_ARGV
[0]);
303 command_print(CMD
, "pld device '#%s' is unknown", CMD_ARGV
[0]);
307 struct virtex2_pld_device
*virtex2_info
= device
->driver_priv
;
311 uint64_t user
[VIRTEX2_MAX_USER_INSTRUCTIONS
];
312 unsigned int num_user
= CMD_ARGC
- 1;
313 for (unsigned int i
= 0; i
< num_user
; ++i
)
314 COMMAND_PARSE_NUMBER(u64
, CMD_ARGV
[1 + i
], user
[i
]);
315 virtex2_info
->command_set
.num_user
= num_user
;
316 memcpy(virtex2_info
->command_set
.user
, user
, num_user
* sizeof(uint64_t));
320 PLD_CREATE_COMMAND_HANDLER(virtex2_pld_create_command
)
323 return ERROR_COMMAND_SYNTAX_ERROR
;
325 if (strcmp(CMD_ARGV
[2], "-chain-position") != 0)
326 return ERROR_COMMAND_SYNTAX_ERROR
;
328 struct jtag_tap
*tap
= jtag_tap_by_string(CMD_ARGV
[3]);
330 command_print(CMD
, "Tap: %s does not exist", CMD_ARGV
[3]);
334 struct virtex2_pld_device
*virtex2_info
= malloc(sizeof(struct virtex2_pld_device
));
336 LOG_ERROR("Out of memory");
339 virtex2_info
->tap
= tap
;
340 virtex2_info
->command_set
= virtex2_default_commands
;
342 virtex2_info
->no_jstart
= 0;
343 if (CMD_ARGC
>= 5 && strcmp(CMD_ARGV
[4], "-no_jstart") == 0)
344 virtex2_info
->no_jstart
= 1;
346 pld
->driver_priv
= virtex2_info
;
351 static const struct command_registration virtex2_exec_command_handlers
[] = {
354 .mode
= COMMAND_EXEC
,
355 .handler
= virtex2_handle_read_stat_command
,
356 .help
= "read status register",
359 .name
= "set_instr_codes",
360 .mode
= COMMAND_EXEC
,
361 .handler
= virtex2_handle_set_instuction_codes_command
,
362 .help
= "set instructions codes used for loading the bitstream/refreshing/jtag-hub",
363 .usage
= "pld_name cfg_out cfg_in jprogb jstart jshutdown"
364 " [user1 [user2 [user3 [user4]]]]",
366 .name
= "set_user_codes",
367 .mode
= COMMAND_EXEC
,
368 .handler
= virtex2_handle_set_user_codes_command
,
369 .help
= "set instructions codes used for jtag-hub",
370 .usage
= "pld_name user1 [user2 [user3 [user4]]]",
372 COMMAND_REGISTRATION_DONE
375 static const struct command_registration virtex2_command_handler
[] = {
379 .help
= "Virtex-II specific commands",
381 .chain
= virtex2_exec_command_handlers
,
383 COMMAND_REGISTRATION_DONE
386 struct pld_driver virtex2_pld
= {
388 .commands
= virtex2_command_handler
,
389 .pld_create_command
= &virtex2_pld_create_command
,
390 .load
= &virtex2_load
,
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)