jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / pld / virtex2.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2006 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "virtex2.h"
13 #include "xilinx_bit.h"
14 #include "pld.h"
15
16 static const struct virtex2_command_set virtex2_default_commands = {
17 .cfg_out = 0x04,
18 .cfg_in = 0x05,
19 .jprog_b = 0x0b,
20 .jstart = 0x0c,
21 .jshutdown = 0x0d,
22 .bypass = 0x3f,
23 .user = {0x02, 0x03},
24 .num_user = 2, /* virtex II has only 2 user instructions */
25 };
26
27 static int virtex2_set_instr(struct jtag_tap *tap, uint64_t new_instr)
28 {
29 if (!tap)
30 return ERROR_FAIL;
31
32 if (buf_get_u64(tap->cur_instr, 0, tap->ir_length) != new_instr) {
33 struct scan_field field;
34
35 field.num_bits = tap->ir_length;
36 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
37 if (!t) {
38 LOG_ERROR("Out of memory");
39 return ERROR_FAIL;
40 }
41 field.out_value = t;
42 buf_set_u64(t, 0, field.num_bits, new_instr);
43 field.in_value = NULL;
44
45 jtag_add_ir_scan(tap, &field, TAP_IDLE);
46
47 free(t);
48 }
49
50 return ERROR_OK;
51 }
52
53 static int virtex2_send_32(struct pld_device *pld_device,
54 int num_words, uint32_t *words)
55 {
56 struct virtex2_pld_device *virtex2_info = pld_device->driver_priv;
57 struct scan_field scan_field;
58 uint8_t *values;
59 int i;
60
61 values = malloc(num_words * 4);
62 if (!values) {
63 LOG_ERROR("Out of memory");
64 return ERROR_FAIL;
65 }
66
67 scan_field.num_bits = num_words * 32;
68 scan_field.out_value = values;
69 scan_field.in_value = NULL;
70
71 for (i = 0; i < num_words; i++)
72 buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
73
74 int retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.cfg_in);
75 if (retval != ERROR_OK) {
76 free(values);
77 return retval;
78 }
79
80 jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE);
81
82 free(values);
83
84 return ERROR_OK;
85 }
86
87 static inline void virtexflip32(jtag_callback_data_t arg)
88 {
89 uint8_t *in = (uint8_t *)arg;
90 *((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32);
91 }
92
93 static int virtex2_receive_32(struct pld_device *pld_device,
94 int num_words, uint32_t *words)
95 {
96 struct virtex2_pld_device *virtex2_info = pld_device->driver_priv;
97 struct scan_field scan_field;
98
99 scan_field.num_bits = 32;
100 scan_field.out_value = NULL;
101 scan_field.in_value = NULL;
102
103 int retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.cfg_out);
104 if (retval != ERROR_OK)
105 return retval;
106
107 while (num_words--) {
108 scan_field.in_value = (uint8_t *)words;
109
110 jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE);
111
112 jtag_add_callback(virtexflip32, (jtag_callback_data_t)words);
113
114 words++;
115 }
116
117 return ERROR_OK;
118 }
119
120 static int virtex2_read_stat(struct pld_device *pld_device, uint32_t *status)
121 {
122 uint32_t data[5];
123
124 jtag_add_tlr();
125
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)
133 return retval;
134
135 retval = virtex2_receive_32(pld_device, 1, status);
136 if (retval != ERROR_OK)
137 return retval;
138
139 retval = jtag_execute_queue();
140 if (retval == ERROR_OK)
141 LOG_DEBUG("status: 0x%8.8" PRIx32, *status);
142
143 return retval;
144 }
145
146 static int virtex2_program(struct pld_device *pld_device)
147 {
148 struct virtex2_pld_device *virtex2_info = pld_device->driver_priv;
149 if (!virtex2_info)
150 return ERROR_FAIL;
151
152 int retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jshutdown);
153 if (retval != ERROR_OK)
154 return retval;
155
156 retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jprog_b);
157 if (retval != ERROR_OK)
158 return retval;
159
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)
164 return retval;
165 }
166
167 retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.bypass);
168 if (retval != ERROR_OK)
169 return retval;
170 jtag_add_runtest(2000, TAP_IDLE);
171
172 return jtag_execute_queue();
173 }
174
175 static int virtex2_load_prepare(struct pld_device *pld_device)
176 {
177 struct virtex2_pld_device *virtex2_info = pld_device->driver_priv;
178 int retval;
179
180 retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jprog_b);
181 if (retval != ERROR_OK)
182 return retval;
183
184 retval = jtag_execute_queue();
185 if (retval != ERROR_OK)
186 return retval;
187 jtag_add_sleep(1000);
188
189 retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.cfg_in);
190 if (retval != ERROR_OK)
191 return retval;
192
193 return jtag_execute_queue();
194 }
195
196 static int virtex2_load_cleanup(struct pld_device *pld_device)
197 {
198 struct virtex2_pld_device *virtex2_info = pld_device->driver_priv;
199 int retval;
200
201 jtag_add_tlr();
202
203 if (!(virtex2_info->no_jstart)) {
204 retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jstart);
205 if (retval != ERROR_OK)
206 return retval;
207 }
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)
211 return retval;
212 retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.bypass);
213 if (retval != ERROR_OK)
214 return retval;
215 if (!(virtex2_info->no_jstart)) {
216 retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jstart);
217 if (retval != ERROR_OK)
218 return retval;
219 }
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)
223 return retval;
224
225 return jtag_execute_queue();
226 }
227
228 static int virtex2_load(struct pld_device *pld_device, const char *filename)
229 {
230 struct virtex2_pld_device *virtex2_info = pld_device->driver_priv;
231 struct xilinx_bit_file bit_file;
232 int retval;
233 unsigned int i;
234 struct scan_field field;
235
236 field.in_value = NULL;
237
238 retval = xilinx_read_bit_file(&bit_file, filename);
239 if (retval != ERROR_OK)
240 return retval;
241
242 retval = virtex2_load_prepare(pld_device);
243 if (retval != ERROR_OK) {
244 xilinx_free_bit_file(&bit_file);
245 return retval;
246 }
247
248 for (i = 0; i < bit_file.length; i++)
249 bit_file.data[i] = flip_u32(bit_file.data[i], 8);
250
251 field.num_bits = bit_file.length * 8;
252 field.out_value = bit_file.data;
253
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);
258 return retval;
259 }
260
261 retval = virtex2_load_cleanup(pld_device);
262
263 xilinx_free_bit_file(&bit_file);
264
265 return retval;
266 }
267
268 COMMAND_HANDLER(virtex2_handle_refresh_command)
269 {
270 struct pld_device *device;
271
272 if (CMD_ARGC != 1)
273 return ERROR_COMMAND_SYNTAX_ERROR;
274
275 device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
276 if (!device) {
277 command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
278 return ERROR_FAIL;
279 }
280
281 return virtex2_program(device);
282 }
283
284 COMMAND_HANDLER(virtex2_handle_read_stat_command)
285 {
286 struct pld_device *device;
287 uint32_t status;
288
289 if (CMD_ARGC < 1)
290 return ERROR_COMMAND_SYNTAX_ERROR;
291
292 device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
293 if (!device) {
294 command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
295 return ERROR_FAIL;
296 }
297
298 int retval = virtex2_read_stat(device, &status);
299 if (retval != ERROR_OK) {
300 command_print(CMD, "cannot read virtex2 status register");
301 return retval;
302 }
303
304 command_print(CMD, "virtex2 status register: 0x%8.8" PRIx32, status);
305
306 return ERROR_OK;
307 }
308
309 static int xilinx_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)
310 {
311 if (!pld_device)
312 return ERROR_FAIL;
313
314 struct virtex2_pld_device *pld_device_info = pld_device->driver_priv;
315
316 if (!pld_device_info || !pld_device_info->tap)
317 return ERROR_FAIL;
318
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);
322 return ERROR_FAIL;
323 }
324
325 hub->user_ir_code = pld_device_info->command_set.user[user_num - 1];
326 return ERROR_OK;
327 }
328
329 static int xilinx_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
330 {
331 if (!pld_device || !pld_device->driver_priv)
332 return ERROR_FAIL;
333 struct virtex2_pld_device *pld_device_info = pld_device->driver_priv;
334
335 if (pld_device_info->command_set.num_user < 1) {
336 LOG_ERROR("code for command 'select user1' is unknown");
337 return ERROR_FAIL;
338 }
339
340 *ir = pld_device_info->command_set.user[0];
341 return ERROR_OK;
342 }
343
344 COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command)
345 {
346 if (CMD_ARGC < 6 || CMD_ARGC > (6 + VIRTEX2_MAX_USER_INSTRUCTIONS))
347 return ERROR_COMMAND_SYNTAX_ERROR;
348
349 struct pld_device *device = get_pld_device_by_name(CMD_ARGV[0]);
350 if (!device) {
351 command_print(CMD, "pld device '#%s' is unknown", CMD_ARGV[0]);
352 return ERROR_FAIL;
353 }
354
355 struct virtex2_pld_device *virtex2_info = device->driver_priv;
356 if (!virtex2_info)
357 return ERROR_FAIL;
358
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;
366
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;
371
372 virtex2_info->command_set = instr_codes;
373 return ERROR_OK;
374 }
375
376 COMMAND_HANDLER(virtex2_handle_set_user_codes_command)
377 {
378 if (CMD_ARGC < 2 || CMD_ARGC > (1 + VIRTEX2_MAX_USER_INSTRUCTIONS))
379 return ERROR_COMMAND_SYNTAX_ERROR;
380
381 struct pld_device *device = get_pld_device_by_name(CMD_ARGV[0]);
382 if (!device) {
383 command_print(CMD, "pld device '#%s' is unknown", CMD_ARGV[0]);
384 return ERROR_FAIL;
385 }
386
387 struct virtex2_pld_device *virtex2_info = device->driver_priv;
388 if (!virtex2_info)
389 return ERROR_FAIL;
390
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));
397 return ERROR_OK;
398 }
399
400 PLD_CREATE_COMMAND_HANDLER(virtex2_pld_create_command)
401 {
402 if (CMD_ARGC < 4)
403 return ERROR_COMMAND_SYNTAX_ERROR;
404
405 if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
406 return ERROR_COMMAND_SYNTAX_ERROR;
407
408 struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
409 if (!tap) {
410 command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
411 return ERROR_FAIL;
412 }
413
414 struct virtex2_pld_device *virtex2_info = malloc(sizeof(struct virtex2_pld_device));
415 if (!virtex2_info) {
416 LOG_ERROR("Out of memory");
417 return ERROR_FAIL;
418 }
419 virtex2_info->tap = tap;
420 virtex2_info->command_set = virtex2_default_commands;
421
422 virtex2_info->no_jstart = 0;
423 if (CMD_ARGC >= 5 && strcmp(CMD_ARGV[4], "-no_jstart") == 0)
424 virtex2_info->no_jstart = 1;
425
426 pld->driver_priv = virtex2_info;
427
428 return ERROR_OK;
429 }
430
431 static const struct command_registration virtex2_exec_command_handlers[] = {
432 {
433 .name = "read_stat",
434 .mode = COMMAND_EXEC,
435 .handler = virtex2_handle_read_stat_command,
436 .help = "read status register",
437 .usage = "pld_name",
438 }, {
439 .name = "set_instr_codes",
440 .mode = COMMAND_ANY,
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]]]]",
445 }, {
446 .name = "set_user_codes",
447 .mode = COMMAND_ANY,
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]]]",
451 }, {
452 .name = "refresh",
453 .mode = COMMAND_EXEC,
454 .handler = virtex2_handle_refresh_command,
455 .help = "start loading of configuration (program)",
456 .usage = "pld_name",
457 },
458 COMMAND_REGISTRATION_DONE
459 };
460
461 static const struct command_registration virtex2_command_handler[] = {
462 {
463 .name = "virtex2",
464 .mode = COMMAND_ANY,
465 .help = "Virtex-II specific commands",
466 .usage = "",
467 .chain = virtex2_exec_command_handlers,
468 },
469 COMMAND_REGISTRATION_DONE
470 };
471
472 struct pld_driver virtex2_pld = {
473 .name = "virtex2",
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,
479 };

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)