pld: add support for lattice certus devices
[openocd.git] / src / pld / lattice.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2022 by Daniel Anselmi *
5 * danselmi@gmx.ch *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "lattice.h"
13 #include <jtag/jtag.h>
14 #include "pld.h"
15 #include "lattice_bit.h"
16 #include "ecp2_3.h"
17 #include "ecp5.h"
18 #include "certus.h"
19
20 #define PRELOAD 0x1C
21
22 struct lattice_devices_elem {
23 uint32_t id;
24 size_t preload_length;
25 enum lattice_family_e family;
26 };
27
28 static const struct lattice_devices_elem lattice_devices[] = {
29 {0x01270043, 654, LATTICE_ECP2 /* ecp2-6e */},
30 {0x01271043, 643, LATTICE_ECP2 /* ecp2-12e */},
31 {0x01272043, 827, LATTICE_ECP2 /* ecp2-20e */},
32 {0x01274043, 1011, LATTICE_ECP2 /* ecp2-35e */},
33 {0x01273043, 1219, LATTICE_ECP2 /* ecp2-50e */},
34 {0x01275043, 654, LATTICE_ECP2 /* ecp2-70e */},
35 {0x01279043, 680, LATTICE_ECP2 /* ecp2m20e */},
36 {0x0127A043, 936, LATTICE_ECP2 /* ecp2m35e */},
37 {0x0127B043, 1056, LATTICE_ECP2 /* ecp2m50e */},
38 {0x0127C043, 1039, LATTICE_ECP2 /* ecp2m70e */},
39 {0x0127D043, 1311, LATTICE_ECP2 /* ecp2m100e */},
40 {0x01010043, 467, LATTICE_ECP3 /* ecp3 lae3-17ea & lfe3-17ea*/},
41 {0x01012043, 675, LATTICE_ECP3 /* ecp3 lae3-35ea & lfe3-35ea*/},
42 {0x01014043, 1077, LATTICE_ECP3 /* ecp3 lfe3-70ea & lfe3-70e & lfe3-95ea && lfe3-95e*/},
43 {0x01015043, 1326, LATTICE_ECP3 /* ecp3 lfe3-150e*/},
44 {0x21111043, 409, LATTICE_ECP5 /* "LAE5U-12F & LFE5U-12F" */},
45 {0x41111043, 409, LATTICE_ECP5 /* "LFE5U-25F" */},
46 {0x41112043, 510, LATTICE_ECP5 /* "LFE5U-45F" */},
47 {0x41113043, 750, LATTICE_ECP5 /* "LFE5U-85F" */},
48 {0x81111043, 409, LATTICE_ECP5 /* "LFE5UM5G-25F" */},
49 {0x81112043, 510, LATTICE_ECP5 /* "LFE5UM5G-45F" */},
50 {0x81113043, 750, LATTICE_ECP5 /* "LFE5UM5G-85F" */},
51 {0x01111043, 409, LATTICE_ECP5 /* "LAE5UM-25F" */},
52 {0x01112043, 510, LATTICE_ECP5 /* "LAE5UM-45F" */},
53 {0x01113043, 750, LATTICE_ECP5 /* "LAE5UM-85F" */},
54 {0x310f0043, 362, LATTICE_CERTUS /* LFD2NX-17 */},
55 {0x310f1043, 362, LATTICE_CERTUS /* LFD2NX-40 */},
56 {0x010f4043, 362, LATTICE_CERTUS /* LFCPNX-100 */},
57 };
58
59 int lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, tap_state_t endstate)
60 {
61 struct scan_field field;
62 field.num_bits = tap->ir_length;
63 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
64 if (!t) {
65 LOG_ERROR("Out of memory");
66 return ERROR_FAIL;
67 }
68 field.out_value = t;
69 buf_set_u32(t, 0, field.num_bits, new_instr);
70 field.in_value = NULL;
71 jtag_add_ir_scan(tap, &field, endstate);
72 free(t);
73 return ERROR_OK;
74 }
75
76 static int lattice_check_device_family(struct lattice_pld_device *lattice_device)
77 {
78 if (lattice_device->family != LATTICE_UNKNOWN && lattice_device->preload_length != 0)
79 return ERROR_OK;
80
81 if (!lattice_device->tap || !lattice_device->tap->hasidcode)
82 return ERROR_FAIL;
83
84 for (size_t i = 0; i < ARRAY_SIZE(lattice_devices); ++i) {
85 if (lattice_devices[i].id == lattice_device->tap->idcode) {
86 if (lattice_device->family == LATTICE_UNKNOWN)
87 lattice_device->family = lattice_devices[i].family;
88 if (lattice_device->preload_length == 0)
89 lattice_device->preload_length = lattice_devices[i].preload_length;
90 return ERROR_OK;
91 }
92 }
93 LOG_ERROR("Unknown id! Specify family and preload-length manually.");
94 return ERROR_FAIL;
95 }
96
97 int lattice_read_u32_register(struct jtag_tap *tap, uint8_t cmd, uint32_t *in_val,
98 uint32_t out_val, bool do_idle)
99 {
100 struct scan_field field;
101 uint8_t buffer[4];
102
103 int retval = lattice_set_instr(tap, cmd, TAP_IDLE);
104 if (retval != ERROR_OK)
105 return retval;
106 if (do_idle) {
107 jtag_add_runtest(2, TAP_IDLE);
108 jtag_add_sleep(1000);
109 }
110
111 h_u32_to_le(buffer, out_val);
112 field.num_bits = 32;
113 field.out_value = buffer;
114 field.in_value = buffer;
115 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
116 retval = jtag_execute_queue();
117 if (retval == ERROR_OK)
118 *in_val = le_to_h_u32(buffer);
119
120 return retval;
121 }
122
123 int lattice_read_u64_register(struct jtag_tap *tap, uint8_t cmd, uint64_t *in_val,
124 uint64_t out_val)
125 {
126 struct scan_field field;
127 uint8_t buffer[8];
128
129 int retval = lattice_set_instr(tap, cmd, TAP_IDLE);
130 if (retval != ERROR_OK)
131 return retval;
132 h_u64_to_le(buffer, out_val);
133 field.num_bits = 64;
134 field.out_value = buffer;
135 field.in_value = buffer;
136 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
137 retval = jtag_execute_queue();
138 if (retval == ERROR_OK)
139 *in_val = le_to_h_u64(buffer);
140
141 return retval;
142 }
143
144 int lattice_preload(struct lattice_pld_device *lattice_device)
145 {
146 struct scan_field field;
147 size_t sz_bytes = DIV_ROUND_UP(lattice_device->preload_length, 8);
148
149 int retval = lattice_set_instr(lattice_device->tap, PRELOAD, TAP_IDLE);
150 if (retval != ERROR_OK)
151 return retval;
152 uint8_t *buffer = malloc(sz_bytes);
153 if (!buffer) {
154 LOG_ERROR("Out of memory");
155 return ERROR_FAIL;
156 }
157 memset(buffer, 0xff, sz_bytes);
158
159 field.num_bits = lattice_device->preload_length;
160 field.out_value = buffer;
161 field.in_value = NULL;
162 jtag_add_dr_scan(lattice_device->tap, 1, &field, TAP_IDLE);
163 retval = jtag_execute_queue();
164 free(buffer);
165 return retval;
166 }
167
168 static int lattice_read_usercode(struct lattice_pld_device *lattice_device, uint32_t *usercode, uint32_t out)
169 {
170 struct jtag_tap *tap = lattice_device->tap;
171 if (!tap)
172 return ERROR_FAIL;
173
174 if (lattice_device->family == LATTICE_ECP2 || lattice_device->family == LATTICE_ECP3)
175 return lattice_ecp2_3_read_usercode(tap, usercode, out);
176 else if (lattice_device->family == LATTICE_ECP5)
177 return lattice_ecp5_read_usercode(tap, usercode, out);
178 else if (lattice_device->family == LATTICE_CERTUS)
179 return lattice_certus_read_usercode(tap, usercode, out);
180
181 return ERROR_FAIL;
182 }
183
184 int lattice_verify_usercode(struct lattice_pld_device *lattice_device, uint32_t out,
185 uint32_t expected, uint32_t mask)
186 {
187 uint32_t usercode;
188
189 int retval = lattice_read_usercode(lattice_device, &usercode, out);
190 if (retval != ERROR_OK)
191 return retval;
192
193 if ((usercode & mask) != expected) {
194 LOG_ERROR("verifying user code register failed got: 0x%08" PRIx32 " expected: 0x%08" PRIx32,
195 usercode & mask, expected);
196 return ERROR_FAIL;
197 }
198 return ERROR_OK;
199 }
200
201 static int lattice_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)
202 {
203 if (lattice_device->family == LATTICE_ECP2 || lattice_device->family == LATTICE_ECP3)
204 return lattice_ecp2_3_write_usercode(lattice_device, usercode);
205 else if (lattice_device->family == LATTICE_ECP5)
206 return lattice_ecp5_write_usercode(lattice_device, usercode);
207 else if (lattice_device->family == LATTICE_CERTUS)
208 return lattice_certus_write_usercode(lattice_device, usercode);
209
210 return ERROR_FAIL;
211 }
212
213 static int lattice_read_status_u32(struct lattice_pld_device *lattice_device, uint32_t *status,
214 uint32_t out, bool do_idle)
215 {
216 if (!lattice_device->tap)
217 return ERROR_FAIL;
218
219 if (lattice_device->family == LATTICE_ECP2 || lattice_device->family == LATTICE_ECP3)
220 return lattice_ecp2_3_read_status(lattice_device->tap, status, out, do_idle);
221 else if (lattice_device->family == LATTICE_ECP5)
222 return lattice_ecp5_read_status(lattice_device->tap, status, out, do_idle);
223
224 return ERROR_FAIL;
225 }
226 static int lattice_read_status_u64(struct lattice_pld_device *lattice_device, uint64_t *status,
227 uint64_t out)
228 {
229 if (!lattice_device->tap)
230 return ERROR_FAIL;
231
232 if (lattice_device->family == LATTICE_CERTUS)
233 return lattice_certus_read_status(lattice_device->tap, status, out);
234
235 return ERROR_FAIL;
236 }
237
238 int lattice_verify_status_register_u32(struct lattice_pld_device *lattice_device, uint32_t out,
239 uint32_t expected, uint32_t mask, bool do_idle)
240 {
241 uint32_t status;
242 int retval = lattice_read_status_u32(lattice_device, &status, out, do_idle);
243 if (retval != ERROR_OK)
244 return retval;
245
246 if ((status & mask) != expected) {
247 LOG_ERROR("verifying status register failed got: 0x%08" PRIx32 " expected: 0x%08" PRIx32,
248 status & mask, expected);
249 return ERROR_FAIL;
250 }
251 return ERROR_OK;
252 }
253
254 int lattice_verify_status_register_u64(struct lattice_pld_device *lattice_device, uint64_t out,
255 uint64_t expected, uint64_t mask)
256 {
257 uint64_t status;
258 int retval = lattice_read_status_u64(lattice_device, &status, out);
259 if (retval != ERROR_OK)
260 return retval;
261
262 if ((status & mask) != expected) {
263 LOG_ERROR("verifying status register failed got: 0x%08" PRIx64 " expected: 0x%08" PRIx64,
264 status & mask, expected);
265 return ERROR_FAIL;
266 }
267 return ERROR_OK;
268 }
269
270 static int lattice_load_command(struct pld_device *pld_device, const char *filename)
271 {
272 if (!pld_device)
273 return ERROR_FAIL;
274
275 struct lattice_pld_device *lattice_device = pld_device->driver_priv;
276 if (!lattice_device || !lattice_device->tap)
277 return ERROR_FAIL;
278 struct jtag_tap *tap = lattice_device->tap;
279
280 if (!tap || !tap->hasidcode)
281 return ERROR_FAIL;
282
283 int retval = lattice_check_device_family(lattice_device);
284 if (retval != ERROR_OK)
285 return retval;
286
287 struct lattice_bit_file bit_file;
288 retval = lattice_read_file(&bit_file, filename, lattice_device->family);
289 if (retval != ERROR_OK)
290 return retval;
291
292 uint32_t id = tap->idcode;
293 retval = ERROR_FAIL;
294 switch (lattice_device->family) {
295 case LATTICE_ECP2:
296 retval = lattice_ecp2_load(lattice_device, &bit_file);
297 break;
298 case LATTICE_ECP3:
299 retval = lattice_ecp3_load(lattice_device, &bit_file);
300 break;
301 case LATTICE_ECP5:
302 case LATTICE_CERTUS:
303 if (bit_file.has_id && id != bit_file.idcode)
304 LOG_WARNING("Id on device (0x%8.8" PRIx32 ") and id in bit-stream (0x%8.8" PRIx32 ") don't match.",
305 id, bit_file.idcode);
306 if (lattice_device->family == LATTICE_ECP5)
307 retval = lattice_ecp5_load(lattice_device, &bit_file);
308 else
309 retval = lattice_certus_load(lattice_device, &bit_file);
310 break;
311 default:
312 LOG_ERROR("loading unknown device family");
313 break;
314 }
315 free(bit_file.raw_bit.data);
316 return retval;
317 }
318
319 PLD_DEVICE_COMMAND_HANDLER(lattice_pld_device_command)
320 {
321 if (CMD_ARGC < 2 || CMD_ARGC > 3)
322 return ERROR_COMMAND_SYNTAX_ERROR;
323
324 struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[1]);
325 if (!tap) {
326 command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
327 return ERROR_FAIL;
328 }
329
330 struct lattice_pld_device *lattice_device = malloc(sizeof(struct lattice_pld_device));
331 if (!lattice_device) {
332 LOG_ERROR("Out of memory");
333 return ERROR_FAIL;
334 }
335 /* id is not known yet -> postpone lattice_check_device_family() */
336 enum lattice_family_e family = LATTICE_UNKNOWN;
337 if (CMD_ARGC == 3) {
338 if (strcasecmp(CMD_ARGV[2], "ecp2") == 0) {
339 family = LATTICE_ECP2;
340 } else if (strcasecmp(CMD_ARGV[2], "ecp3") == 0) {
341 family = LATTICE_ECP3;
342 } else if (strcasecmp(CMD_ARGV[2], "ecp5") == 0) {
343 family = LATTICE_ECP5;
344 } else if (strcasecmp(CMD_ARGV[2], "certus") == 0) {
345 family = LATTICE_CERTUS;
346 } else {
347 command_print(CMD, "unknown family");
348 free(lattice_device);
349 return ERROR_FAIL;
350 }
351 }
352 lattice_device->tap = tap;
353 lattice_device->family = family;
354 lattice_device->preload_length = 0;
355
356 pld->driver_priv = lattice_device;
357
358 return ERROR_OK;
359 }
360
361 COMMAND_HANDLER(lattice_read_usercode_register_command_handler)
362 {
363 int dev_id;
364 uint32_t usercode;
365
366 if (CMD_ARGC != 1)
367 return ERROR_COMMAND_SYNTAX_ERROR;
368
369 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
370 struct pld_device *device = get_pld_device_by_num(dev_id);
371 if (!device) {
372 command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
373 return ERROR_FAIL;
374 }
375
376 struct lattice_pld_device *lattice_device = device->driver_priv;
377 if (!lattice_device)
378 return ERROR_FAIL;
379
380 int retval = lattice_check_device_family(lattice_device);
381 if (retval != ERROR_OK)
382 return retval;
383
384 retval = lattice_read_usercode(lattice_device, &usercode, 0x0);
385 if (retval == ERROR_OK)
386 command_print(CMD, "0x%8.8" PRIx32, usercode);
387
388 return retval;
389 }
390
391 COMMAND_HANDLER(lattice_set_preload_command_handler)
392 {
393 int dev_id;
394 unsigned int preload_length;
395
396 if (CMD_ARGC != 2)
397 return ERROR_COMMAND_SYNTAX_ERROR;
398
399 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
400 struct pld_device *device = get_pld_device_by_num(dev_id);
401 if (!device) {
402 command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
403 return ERROR_FAIL;
404 }
405
406 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], preload_length);
407
408 struct lattice_pld_device *lattice_device = device->driver_priv;
409
410 if (!lattice_device)
411 return ERROR_FAIL;
412
413 lattice_device->preload_length = preload_length;
414
415 return ERROR_OK;
416 }
417
418 COMMAND_HANDLER(lattice_write_usercode_register_command_handler)
419 {
420 int dev_id;
421 uint32_t usercode;
422
423 if (CMD_ARGC != 2)
424 return ERROR_COMMAND_SYNTAX_ERROR;
425
426 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
427 struct pld_device *device = get_pld_device_by_num(dev_id);
428 if (!device) {
429 command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
430 return ERROR_FAIL;
431 }
432
433 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], usercode);
434
435 struct lattice_pld_device *lattice_device = device->driver_priv;
436 if (!lattice_device)
437 return ERROR_FAIL;
438
439 int retval = lattice_check_device_family(lattice_device);
440 if (retval != ERROR_OK)
441 return retval;
442
443 return lattice_write_usercode(lattice_device, usercode);
444 }
445
446 COMMAND_HANDLER(lattice_read_status_command_handler)
447 {
448 int dev_id;
449
450 if (CMD_ARGC != 1)
451 return ERROR_COMMAND_SYNTAX_ERROR;
452
453 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
454 struct pld_device *device = get_pld_device_by_num(dev_id);
455 if (!device) {
456 command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
457 return ERROR_FAIL;
458 }
459
460 struct lattice_pld_device *lattice_device = device->driver_priv;
461 if (!lattice_device)
462 return ERROR_FAIL;
463
464 int retval = lattice_check_device_family(lattice_device);
465 if (retval != ERROR_OK)
466 return retval;
467
468 if (lattice_device->family == LATTICE_CERTUS) {
469 uint64_t status;
470 retval = lattice_read_status_u64(lattice_device, &status, 0x0);
471 if (retval == ERROR_OK)
472 command_print(CMD, "0x%016" PRIx64, status);
473 } else {
474 uint32_t status;
475 const bool do_idle = lattice_device->family == LATTICE_ECP5;
476 retval = lattice_read_status_u32(lattice_device, &status, 0x0, do_idle);
477 if (retval == ERROR_OK)
478 command_print(CMD, "0x%8.8" PRIx32, status);
479 }
480
481 return retval;
482 }
483
484 static const struct command_registration lattice_exec_command_handlers[] = {
485 {
486 .name = "read_status",
487 .mode = COMMAND_EXEC,
488 .handler = lattice_read_status_command_handler,
489 .help = "reading status register from FPGA",
490 .usage = "num_pld",
491 }, {
492 .name = "read_user",
493 .mode = COMMAND_EXEC,
494 .handler = lattice_read_usercode_register_command_handler,
495 .help = "reading usercode register from FPGA",
496 .usage = "num_pld",
497 }, {
498 .name = "write_user",
499 .mode = COMMAND_EXEC,
500 .handler = lattice_write_usercode_register_command_handler,
501 .help = "writing usercode register to FPGA",
502 .usage = "num_pld value",
503 }, {
504 .name = "set_preload",
505 .mode = COMMAND_EXEC,
506 .handler = lattice_set_preload_command_handler,
507 .help = "set length for preload (device specific)",
508 .usage = "num_pld value",
509 },
510 COMMAND_REGISTRATION_DONE
511 };
512
513 static const struct command_registration lattice_command_handler[] = {
514 {
515 .name = "lattice",
516 .mode = COMMAND_ANY,
517 .help = "lattice specific commands",
518 .usage = "",
519 .chain = lattice_exec_command_handlers,
520 },
521 COMMAND_REGISTRATION_DONE
522 };
523
524 struct pld_driver lattice_pld = {
525 .name = "lattice",
526 .commands = lattice_command_handler,
527 .pld_device_command = &lattice_pld_device_command,
528 .load = &lattice_load_command,
529 };

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)