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

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)