jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / xcf.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2016 by Uladzimir Pylinski aka barthess *
5 * barthess@yandex.ru *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <string.h>
13
14 #include "imp.h"
15 #include <jtag/jtag.h>
16 #include <helper/time_support.h>
17
18 /*
19 ******************************************************************************
20 * DEFINES
21 ******************************************************************************
22 */
23
24 #define SECTOR_ERASE_TIMEOUT_MS (35 * 1000)
25
26 #define XCF_PAGE_SIZE 32
27 #define XCF_DATA_SECTOR_SIZE (1024 * 1024)
28
29 #define ID_XCF01S 0x05044093
30 #define ID_XCF02S 0x05045093
31 #define ID_XCF04S 0x05046093
32 #define ID_XCF08P 0x05057093
33 #define ID_XCF16P 0x05058093
34 #define ID_XCF32P 0x05059093
35 #define ID_MEANINGFUL_MASK 0x0FFFFFFF
36
37 static const char * const xcf_name_list[] = {
38 "XCF08P",
39 "XCF16P",
40 "XCF32P",
41 "unknown"
42 };
43
44 struct xcf_priv {
45 bool probed;
46 };
47
48 struct xcf_status {
49 bool isc_error; /* false == OK, true == error */
50 bool prog_error; /* false == OK, true == error */
51 bool prog_busy; /* false == idle, true == busy */
52 bool isc_mode; /* false == normal mode, true == ISC mode */
53 };
54
55 /*
56 ******************************************************************************
57 * GLOBAL VARIABLES
58 ******************************************************************************
59 */
60 static const uint8_t cmd_bypass[2] = {0xFF, 0xFF};
61
62 static const uint8_t cmd_isc_address_shift[2] = {0xEB, 0x00};
63 static const uint8_t cmd_isc_data_shift[2] = {0xED, 0x00};
64 static const uint8_t cmd_isc_disable[2] = {0xF0, 0x00};
65 static const uint8_t cmd_isc_enable[2] = {0xE8, 0x00};
66 static const uint8_t cmd_isc_erase[2] = {0xEC, 0x00};
67 static const uint8_t cmd_isc_program[2] = {0xEA, 0x00};
68
69 static const uint8_t cmd_xsc_blank_check[2] = {0x0D, 0x00};
70 static const uint8_t cmd_xsc_config[2] = {0xEE, 0x00};
71 static const uint8_t cmd_xsc_data_btc[2] = {0xF2, 0x00};
72 static const uint8_t cmd_xsc_data_ccb[2] = {0x0C, 0x00};
73 static const uint8_t cmd_xsc_data_done[2] = {0x09, 0x00};
74 static const uint8_t cmd_xsc_data_sucr[2] = {0x0E, 0x00};
75 static const uint8_t cmd_xsc_data_wrpt[2] = {0xF7, 0x00};
76 static const uint8_t cmd_xsc_op_status[2] = {0xE3, 0x00};
77 static const uint8_t cmd_xsc_read[2] = {0xEF, 0x00};
78 static const uint8_t cmd_xsc_unlock[2] = {0x55, 0xAA};
79
80 /*
81 ******************************************************************************
82 * LOCAL FUNCTIONS
83 ******************************************************************************
84 */
85
86 static const char *product_name(const struct flash_bank *bank)
87 {
88
89 switch (bank->target->tap->idcode & ID_MEANINGFUL_MASK) {
90 case ID_XCF08P:
91 return xcf_name_list[0];
92 case ID_XCF16P:
93 return xcf_name_list[1];
94 case ID_XCF32P:
95 return xcf_name_list[2];
96 default:
97 return xcf_name_list[3];
98 }
99 }
100
101 static void fill_sector_table(struct flash_bank *bank)
102 {
103 /* Note: is_erased and is_protected fields must be set here to an unknown
104 * state, they will be correctly filled from other API calls. */
105
106 for (unsigned int i = 0; i < bank->num_sectors; i++) {
107 bank->sectors[i].is_erased = -1;
108 bank->sectors[i].is_protected = -1;
109 }
110 for (unsigned int i = 0; i < bank->num_sectors; i++) {
111 bank->sectors[i].size = XCF_DATA_SECTOR_SIZE;
112 bank->sectors[i].offset = i * XCF_DATA_SECTOR_SIZE;
113 }
114
115 bank->size = bank->num_sectors * XCF_DATA_SECTOR_SIZE;
116 }
117
118 static struct xcf_status read_status(struct flash_bank *bank)
119 {
120 struct xcf_status ret;
121 uint8_t irdata[2];
122 struct scan_field scan;
123
124 scan.check_mask = NULL;
125 scan.check_value = NULL;
126 scan.num_bits = 16;
127 scan.out_value = cmd_bypass;
128 scan.in_value = irdata;
129
130 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
131 jtag_execute_queue();
132
133 ret.isc_error = ((irdata[0] >> 7) & 3) == 1;
134 ret.prog_error = ((irdata[0] >> 5) & 3) == 1;
135 ret.prog_busy = ((irdata[0] >> 4) & 1) == 0;
136 ret.isc_mode = ((irdata[0] >> 3) & 1) == 1;
137
138 return ret;
139 }
140
141 static int isc_enter(struct flash_bank *bank)
142 {
143
144 struct xcf_status status = read_status(bank);
145
146 if (true == status.isc_mode)
147 return ERROR_OK;
148 else {
149 struct scan_field scan;
150
151 scan.check_mask = NULL;
152 scan.check_value = NULL;
153 scan.num_bits = 16;
154 scan.out_value = cmd_isc_enable;
155 scan.in_value = NULL;
156
157 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
158 jtag_execute_queue();
159
160 status = read_status(bank);
161 if (!status.isc_mode) {
162 LOG_ERROR("*** XCF: FAILED to enter ISC mode");
163 return ERROR_FLASH_OPERATION_FAILED;
164 }
165
166 return ERROR_OK;
167 }
168 }
169
170 static int isc_leave(struct flash_bank *bank)
171 {
172
173 struct xcf_status status = read_status(bank);
174
175 if (!status.isc_mode)
176 return ERROR_OK;
177 else {
178 struct scan_field scan;
179
180 scan.check_mask = NULL;
181 scan.check_value = NULL;
182 scan.num_bits = 16;
183 scan.out_value = cmd_isc_disable;
184 scan.in_value = NULL;
185
186 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
187 jtag_execute_queue();
188 alive_sleep(1); /* device needs 50 uS to leave ISC mode */
189
190 status = read_status(bank);
191 if (status.isc_mode) {
192 LOG_ERROR("*** XCF: FAILED to leave ISC mode");
193 return ERROR_FLASH_OPERATION_FAILED;
194 }
195
196 return ERROR_OK;
197 }
198 }
199
200 static int sector_state(uint8_t wrpt, int sector)
201 {
202 if (((wrpt >> sector) & 1) == 1)
203 return 0;
204 else
205 return 1;
206 }
207
208 static uint8_t fill_select_block(unsigned int first, unsigned int last)
209 {
210 uint8_t ret = 0;
211 for (unsigned int i = first; i <= last; i++)
212 ret |= 1 << i;
213 return ret;
214 }
215
216 static int isc_read_register(struct flash_bank *bank, const uint8_t *cmd,
217 uint8_t *data_buf, int num_bits)
218 {
219 struct scan_field scan;
220
221 scan.check_mask = NULL;
222 scan.check_value = NULL;
223 scan.out_value = cmd;
224 scan.in_value = NULL;
225 scan.num_bits = 16;
226 jtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);
227
228 scan.out_value = NULL;
229 scan.in_value = data_buf;
230 scan.num_bits = num_bits;
231 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
232
233 return jtag_execute_queue();
234 }
235
236 static int isc_wait_erase_program(struct flash_bank *bank, int64_t timeout_ms)
237 {
238
239 uint8_t isc_default;
240 int64_t t0 = timeval_ms();
241 int64_t dt;
242
243 do {
244 isc_read_register(bank, cmd_xsc_op_status, &isc_default, 8);
245 if (((isc_default >> 2) & 1) == 1)
246 return ERROR_OK;
247 dt = timeval_ms() - t0;
248 } while (dt <= timeout_ms);
249 return ERROR_FLASH_OPERATION_FAILED;
250 }
251
252 /*
253 * helper function for procedures without program jtag command at the end
254 */
255 static int isc_set_register(struct flash_bank *bank, const uint8_t *cmd,
256 const uint8_t *data_buf, int num_bits, int64_t timeout_ms)
257 {
258 struct scan_field scan;
259
260 scan.check_mask = NULL;
261 scan.check_value = NULL;
262 scan.num_bits = 16;
263 scan.out_value = cmd;
264 scan.in_value = NULL;
265 jtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);
266
267 scan.num_bits = num_bits;
268 scan.out_value = data_buf;
269 scan.in_value = NULL;
270 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
271
272 if (timeout_ms == 0)
273 return jtag_execute_queue();
274 else
275 return isc_wait_erase_program(bank, timeout_ms);
276 }
277
278 /*
279 * helper function for procedures required program jtag command at the end
280 */
281 static int isc_program_register(struct flash_bank *bank, const uint8_t *cmd,
282 const uint8_t *data_buf, int num_bits, int64_t timeout_ms)
283 {
284 struct scan_field scan;
285
286 scan.check_mask = NULL;
287 scan.check_value = NULL;
288 scan.num_bits = 16;
289 scan.out_value = cmd;
290 scan.in_value = NULL;
291 jtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);
292
293 scan.num_bits = num_bits;
294 scan.out_value = data_buf;
295 scan.in_value = NULL;
296 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IRSHIFT);
297
298 scan.num_bits = 16;
299 scan.out_value = cmd_isc_program;
300 scan.in_value = NULL;
301 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
302
303 if (timeout_ms == 0)
304 return jtag_execute_queue();
305 else
306 return isc_wait_erase_program(bank, timeout_ms);
307 }
308
309 static int isc_clear_protect(struct flash_bank *bank, unsigned int first,
310 unsigned int last)
311 {
312 uint8_t select_block[3] = {0x0, 0x0, 0x0};
313 select_block[0] = fill_select_block(first, last);
314 return isc_set_register(bank, cmd_xsc_unlock, select_block, 24, 0);
315 }
316
317 static int isc_set_protect(struct flash_bank *bank, unsigned int first,
318 unsigned int last)
319 {
320 uint8_t wrpt[2] = {0xFF, 0xFF};
321 for (unsigned int i = first; i <= last; i++)
322 wrpt[0] &= ~(1 << i);
323
324 return isc_program_register(bank, cmd_xsc_data_wrpt, wrpt, 16, 0);
325 }
326
327 static int isc_erase_sectors(struct flash_bank *bank, unsigned int first,
328 unsigned int last)
329 {
330 uint8_t select_block[3] = {0, 0, 0};
331 select_block[0] = fill_select_block(first, last);
332 int64_t timeout = SECTOR_ERASE_TIMEOUT_MS * (last - first + 1);
333 return isc_set_register(bank, cmd_isc_erase, select_block, 24, timeout);
334 }
335
336 static int isc_adr_shift(struct flash_bank *bank, int adr)
337 {
338 uint8_t adr_buf[3];
339 h_u24_to_le(adr_buf, adr);
340 return isc_set_register(bank, cmd_isc_address_shift, adr_buf, 24, 0);
341 }
342
343 static int isc_program_data_page(struct flash_bank *bank, const uint8_t *page_buf)
344 {
345 return isc_program_register(bank, cmd_isc_data_shift, page_buf, 8 * XCF_PAGE_SIZE, 100);
346 }
347
348 static void isc_data_read_out(struct flash_bank *bank, uint8_t *buffer, uint32_t count)
349 {
350
351 struct scan_field scan;
352
353 /* Do not change this code with isc_read_register() call because it needs
354 * transition to IDLE state before data retrieving. */
355 scan.check_mask = NULL;
356 scan.check_value = NULL;
357 scan.num_bits = 16;
358 scan.out_value = cmd_xsc_read;
359 scan.in_value = NULL;
360 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
361
362 scan.num_bits = 8 * count;
363 scan.out_value = NULL;
364 scan.in_value = buffer;
365 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
366
367 jtag_execute_queue();
368 }
369
370 static int isc_set_data_done(struct flash_bank *bank, int sector)
371 {
372 uint8_t done = 0xFF;
373 done &= ~(1 << sector);
374 return isc_program_register(bank, cmd_xsc_data_done, &done, 8, 100);
375 }
376
377 static void flip_u8(uint8_t *out, const uint8_t *in, int len)
378 {
379 for (int i = 0; i < len; i++)
380 out[i] = flip_u32(in[i], 8);
381 }
382
383 /*
384 * Xilinx bin file contains simple fixed header for automatic bus width detection:
385 * 16 bytes of 0xFF
386 * 4 byte sync word 0xAA995566 or (bit reversed) 0x5599AA66 in MSC file
387 *
388 * Function presumes need of bit reversing if it can not exactly detects
389 * the opposite.
390 */
391 static bool need_bit_reverse(const uint8_t *buffer)
392 {
393 const size_t L = 20;
394 uint8_t reference[L];
395 memset(reference, 0xFF, 16);
396 reference[16] = 0x55;
397 reference[17] = 0x99;
398 reference[18] = 0xAA;
399 reference[19] = 0x66;
400
401 if (memcmp(reference, buffer, L) == 0)
402 return false;
403 else
404 return true;
405 }
406
407 /*
408 * The page address to be programmed is determined by loading the
409 * internal ADDRESS Register using an ISC_ADDRESS_SHIFT instruction sequence.
410 * The page address automatically increments to the next 256-bit
411 * page address after each programming sequence until the last address
412 * in the 8 Mb block is reached. To continue programming the next block,
413 * the next 8 Mb block's starting address must be loaded into the
414 * internal ADDRESS register.
415 */
416 static int read_write_data(struct flash_bank *bank, const uint8_t *w_buffer,
417 uint8_t *r_buffer, bool write_flag, uint32_t offset, uint32_t count)
418 {
419 int dbg_count = count;
420 int dbg_written = 0;
421 int ret = ERROR_OK;
422 uint8_t *page_buf = malloc(XCF_PAGE_SIZE);
423 bool revbit = true;
424 isc_enter(bank);
425
426 if (offset % XCF_PAGE_SIZE != 0) {
427 ret = ERROR_FLASH_DST_BREAKS_ALIGNMENT;
428 goto EXIT;
429 }
430
431 if ((offset + count) > (bank->num_sectors * XCF_DATA_SECTOR_SIZE)) {
432 ret = ERROR_FLASH_DST_OUT_OF_BANK;
433 goto EXIT;
434 }
435
436 if ((write_flag) && (offset == 0) && (count >= XCF_PAGE_SIZE))
437 revbit = need_bit_reverse(w_buffer);
438
439 while (count > 0) {
440 uint32_t sector_num = offset / XCF_DATA_SECTOR_SIZE;
441 uint32_t sector_offset = offset - sector_num * XCF_DATA_SECTOR_SIZE;
442 uint32_t sector_bytes = XCF_DATA_SECTOR_SIZE - sector_offset;
443 if (count < sector_bytes)
444 sector_bytes = count;
445 isc_adr_shift(bank, offset);
446 offset += sector_bytes;
447 count -= sector_bytes;
448
449 if (write_flag) {
450 while (sector_bytes > 0) {
451 int len;
452
453 if (sector_bytes < XCF_PAGE_SIZE) {
454 len = sector_bytes;
455 memset(page_buf, 0xFF, XCF_PAGE_SIZE);
456 } else
457 len = XCF_PAGE_SIZE;
458
459 if (revbit)
460 flip_u8(page_buf, w_buffer, len);
461 else
462 memcpy(page_buf, w_buffer, len);
463
464 w_buffer += len;
465 sector_bytes -= len;
466 ret = isc_program_data_page(bank, page_buf);
467 if (ret != ERROR_OK)
468 goto EXIT;
469 else {
470 LOG_DEBUG("written %d bytes from %d", dbg_written, dbg_count);
471 dbg_written += len;
472 }
473 }
474 } else {
475 isc_data_read_out(bank, r_buffer, sector_bytes);
476 flip_u8(r_buffer, r_buffer, sector_bytes);
477 r_buffer += sector_bytes;
478 }
479 }
480
481 /* Set 'done' flags for all data sectors because driver supports
482 * only single revision. */
483 if (write_flag) {
484 for (unsigned int i = 0; i < bank->num_sectors; i++) {
485 ret = isc_set_data_done(bank, i);
486 if (ret != ERROR_OK)
487 goto EXIT;
488 }
489 }
490
491 EXIT:
492 free(page_buf);
493 isc_leave(bank);
494 return ret;
495 }
496
497 static uint16_t isc_read_ccb(struct flash_bank *bank)
498 {
499 uint8_t ccb[2];
500 isc_read_register(bank, cmd_xsc_data_ccb, ccb, 16);
501 return le_to_h_u16(ccb);
502 }
503
504 static unsigned int gucr_num(const struct flash_bank *bank)
505 {
506 return bank->num_sectors;
507 }
508
509 static unsigned int sucr_num(const struct flash_bank *bank)
510 {
511 return bank->num_sectors + 1;
512 }
513
514 static int isc_program_ccb(struct flash_bank *bank, uint16_t ccb)
515 {
516 uint8_t buf[2];
517 h_u16_to_le(buf, ccb);
518 return isc_program_register(bank, cmd_xsc_data_ccb, buf, 16, 100);
519 }
520
521 static int isc_program_singe_revision_sucr(struct flash_bank *bank)
522 {
523 uint8_t sucr[2] = {0xFC, 0xFF};
524 return isc_program_register(bank, cmd_xsc_data_sucr, sucr, 16, 100);
525 }
526
527 static int isc_program_single_revision_btc(struct flash_bank *bank)
528 {
529 uint8_t buf[4];
530 uint32_t btc = 0xFFFFFFFF;
531 btc &= ~0xF;
532 btc |= ((bank->num_sectors - 1) << 2);
533 btc &= ~(1 << 4);
534 h_u32_to_le(buf, btc);
535 return isc_program_register(bank, cmd_xsc_data_btc, buf, 32, 100);
536 }
537
538 static int fpga_configure(struct flash_bank *bank)
539 {
540 struct scan_field scan;
541
542 scan.check_mask = NULL;
543 scan.check_value = NULL;
544 scan.num_bits = 16;
545 scan.out_value = cmd_xsc_config;
546 scan.in_value = NULL;
547 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
548 jtag_execute_queue();
549
550 return ERROR_OK;
551 }
552
553 /*
554 ******************************************************************************
555 * EXPORTED FUNCTIONS
556 ******************************************************************************
557 */
558
559 FLASH_BANK_COMMAND_HANDLER(xcf_flash_bank_command)
560 {
561 struct xcf_priv *priv;
562
563 priv = malloc(sizeof(struct xcf_priv));
564 if (!priv) {
565 LOG_ERROR("no memory for flash bank info");
566 return ERROR_FAIL;
567 }
568 bank->driver_priv = priv;
569 priv->probed = false;
570 return ERROR_OK;
571 }
572
573 static int xcf_info(struct flash_bank *bank, struct command_invocation *cmd)
574 {
575 const struct xcf_priv *priv = bank->driver_priv;
576
577 if (!priv->probed) {
578 command_print_sameline(cmd, "\nXCF flash bank not probed yet\n");
579 return ERROR_OK;
580 }
581 command_print_sameline(cmd, "%s", product_name(bank));
582 return ERROR_OK;
583 }
584
585 static int xcf_probe(struct flash_bank *bank)
586 {
587 struct xcf_priv *priv = bank->driver_priv;
588 uint32_t id;
589
590 if (priv->probed)
591 free(bank->sectors);
592 priv->probed = false;
593
594 if (!bank->target->tap) {
595 LOG_ERROR("Target has no JTAG tap");
596 return ERROR_FAIL;
597 }
598
599 /* check idcode and alloc memory for sector table */
600 if (!bank->target->tap->has_idcode)
601 return ERROR_FLASH_OPERATION_FAILED;
602
603 /* guess number of blocks using chip ID */
604 id = bank->target->tap->idcode;
605 switch (id & ID_MEANINGFUL_MASK) {
606 case ID_XCF08P:
607 bank->num_sectors = 1;
608 break;
609 case ID_XCF16P:
610 bank->num_sectors = 2;
611 break;
612 case ID_XCF32P:
613 bank->num_sectors = 4;
614 break;
615 default:
616 LOG_ERROR("Unknown flash device ID 0x%" PRIX32, id);
617 return ERROR_FAIL;
618 }
619
620 bank->sectors = malloc(bank->num_sectors * sizeof(struct flash_sector));
621 if (!bank->sectors) {
622 LOG_ERROR("No memory for sector table");
623 return ERROR_FAIL;
624 }
625 fill_sector_table(bank);
626
627 priv->probed = true;
628 /* REVISIT: Why is unchanged bank->driver_priv rewritten by same value? */
629 bank->driver_priv = priv;
630
631 LOG_INFO("product name: %s", product_name(bank));
632 LOG_INFO("device id = 0x%" PRIX32, bank->target->tap->idcode);
633 LOG_INFO("flash size = %d configuration bits",
634 bank->num_sectors * XCF_DATA_SECTOR_SIZE * 8);
635 LOG_INFO("number of sectors = %u", bank->num_sectors);
636
637 return ERROR_OK;
638 }
639
640 static int xcf_auto_probe(struct flash_bank *bank)
641 {
642 struct xcf_priv *priv = bank->driver_priv;
643
644 if (priv->probed)
645 return ERROR_OK;
646 else
647 return xcf_probe(bank);
648 }
649
650 static int xcf_protect_check(struct flash_bank *bank)
651 {
652 uint8_t wrpt[2];
653
654 isc_enter(bank);
655 isc_read_register(bank, cmd_xsc_data_wrpt, wrpt, 16);
656 isc_leave(bank);
657
658 for (unsigned int i = 0; i < bank->num_sectors; i++)
659 bank->sectors[i].is_protected = sector_state(wrpt[0], i);
660
661 return ERROR_OK;
662 }
663
664 static int xcf_erase_check(struct flash_bank *bank)
665 {
666 uint8_t blankreg;
667 struct scan_field scan;
668
669 isc_enter(bank);
670
671 /* Do not change this code with isc_read_register() call because it needs
672 * transition to IDLE state and pause before data retrieving. */
673 scan.check_mask = NULL;
674 scan.check_value = NULL;
675 scan.num_bits = 16;
676 scan.out_value = cmd_xsc_blank_check;
677 scan.in_value = NULL;
678 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
679 jtag_execute_queue();
680 alive_sleep(500); /* device needs at least 0.5s to self check */
681
682 scan.num_bits = 8;
683 scan.in_value = &blankreg;
684 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
685 jtag_execute_queue();
686
687 isc_leave(bank);
688
689 for (unsigned int i = 0; i < bank->num_sectors; i++)
690 bank->sectors[i].is_erased = sector_state(blankreg, i);
691
692 return ERROR_OK;
693 }
694
695 static int xcf_erase(struct flash_bank *bank, unsigned int first,
696 unsigned int last)
697 {
698 if ((first >= bank->num_sectors)
699 || (last >= bank->num_sectors)
700 || (last < first))
701 return ERROR_FLASH_SECTOR_INVALID;
702 else {
703 isc_enter(bank);
704 isc_clear_protect(bank, first, last);
705 int ret = isc_erase_sectors(bank, first, last);
706 isc_leave(bank);
707 return ret;
708 }
709 }
710
711 static int xcf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
712 {
713 return read_write_data(bank, NULL, buffer, false, offset, count);
714 }
715
716 static int xcf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,
717 uint32_t count)
718 {
719 return read_write_data(bank, buffer, NULL, true, offset, count);
720 }
721
722 static int xcf_protect(struct flash_bank *bank, int set, unsigned int first,
723 unsigned int last)
724 {
725 int ret;
726
727 isc_enter(bank);
728 if (set)
729 ret = isc_set_protect(bank, first, last);
730 else {
731 /* write protection may be removed only with following erase */
732 isc_clear_protect(bank, first, last);
733 ret = isc_erase_sectors(bank, first, last);
734 }
735 isc_leave(bank);
736
737 return ret;
738 }
739
740 COMMAND_HANDLER(xcf_handle_ccb_command) {
741
742 if (!((CMD_ARGC == 1) || (CMD_ARGC == 5)))
743 return ERROR_COMMAND_SYNTAX_ERROR;
744
745 struct flash_bank *bank;
746 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
747 if (retval != ERROR_OK)
748 return retval;
749
750 uint16_t ccb = 0xFFFF;
751 isc_enter(bank);
752 uint16_t old_ccb = isc_read_ccb(bank);
753 isc_leave(bank);
754
755 if (CMD_ARGC == 1) {
756 LOG_INFO("current CCB = 0x%X", old_ccb);
757 return ERROR_OK;
758 } else {
759 /* skip over flash bank */
760 CMD_ARGC--;
761 CMD_ARGV++;
762 while (CMD_ARGC) {
763 if (strcmp("external", CMD_ARGV[0]) == 0)
764 ccb |= (1 << 0);
765 else if (strcmp("internal", CMD_ARGV[0]) == 0)
766 ccb &= ~(1 << 0);
767 else if (strcmp("serial", CMD_ARGV[0]) == 0)
768 ccb |= (3 << 1);
769 else if (strcmp("parallel", CMD_ARGV[0]) == 0)
770 ccb &= ~(3 << 1);
771 else if (strcmp("slave", CMD_ARGV[0]) == 0)
772 ccb |= (1 << 3);
773 else if (strcmp("master", CMD_ARGV[0]) == 0)
774 ccb &= ~(1 << 3);
775 else if (strcmp("40", CMD_ARGV[0]) == 0)
776 ccb |= (3 << 4);
777 else if (strcmp("20", CMD_ARGV[0]) == 0)
778 ccb &= ~(1 << 5);
779 else
780 return ERROR_COMMAND_SYNTAX_ERROR;
781 CMD_ARGC--;
782 CMD_ARGV++;
783 }
784
785 isc_enter(bank);
786 int sector;
787
788 /* GUCR sector */
789 sector = gucr_num(bank);
790 isc_clear_protect(bank, sector, sector);
791 int ret = isc_erase_sectors(bank, sector, sector);
792 if (ret != ERROR_OK)
793 goto EXIT;
794 ret = isc_program_ccb(bank, ccb);
795 if (ret != ERROR_OK)
796 goto EXIT;
797 ret = isc_program_single_revision_btc(bank);
798 if (ret != ERROR_OK)
799 goto EXIT;
800 ret = isc_set_data_done(bank, sector);
801 if (ret != ERROR_OK)
802 goto EXIT;
803
804 /* SUCR sector */
805 sector = sucr_num(bank);
806 isc_clear_protect(bank, sector, sector);
807 ret = isc_erase_sectors(bank, sector, sector);
808 if (ret != ERROR_OK)
809 goto EXIT;
810 ret = isc_program_singe_revision_sucr(bank);
811 if (ret != ERROR_OK)
812 goto EXIT;
813 ret = isc_set_data_done(bank, sector);
814 if (ret != ERROR_OK)
815 goto EXIT;
816
817 EXIT:
818 isc_leave(bank);
819 return ret;
820 }
821 }
822
823 COMMAND_HANDLER(xcf_handle_configure_command) {
824
825 if (CMD_ARGC != 1)
826 return ERROR_COMMAND_SYNTAX_ERROR;
827
828 struct flash_bank *bank;
829 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
830 if (retval != ERROR_OK)
831 return retval;
832
833 return fpga_configure(bank);
834 }
835
836 static const struct command_registration xcf_exec_command_handlers[] = {
837 {
838 .name = "configure",
839 .handler = xcf_handle_configure_command,
840 .mode = COMMAND_EXEC,
841 .usage = "bank_id",
842 .help = "Initiate FPGA loading procedure."
843 },
844 {
845 .name = "ccb",
846 .handler = xcf_handle_ccb_command,
847 .mode = COMMAND_EXEC,
848 .usage = "bank_id [('external'|'internal') "
849 "('serial'|'parallel') "
850 "('slave'|'master') "
851 "('40'|'20')]",
852 .help = "Write CCB register with supplied options and (silently) BTC "
853 "register with single revision options. Display current "
854 "CCB value when only bank_id supplied. "
855 "Following options available: "
856 "1) external or internal clock source; "
857 "2) serial or parallel bus mode; "
858 "3) slave or master mode; "
859 "4) clock frequency in MHz for internal clock in master mode;"
860 },
861 COMMAND_REGISTRATION_DONE
862 };
863
864 static const struct command_registration xcf_command_handlers[] = {
865 {
866 .name = "xcf",
867 .mode = COMMAND_ANY,
868 .help = "Xilinx platform flash command group",
869 .usage = "",
870 .chain = xcf_exec_command_handlers
871 },
872 COMMAND_REGISTRATION_DONE
873 };
874
875 const struct flash_driver xcf_flash = {
876 .name = "xcf",
877 .usage = NULL,
878 .commands = xcf_command_handlers,
879 .flash_bank_command = xcf_flash_bank_command,
880 .erase = xcf_erase,
881 .protect = xcf_protect,
882 .write = xcf_write,
883 .read = xcf_read,
884 .probe = xcf_probe,
885 .auto_probe = xcf_auto_probe,
886 .erase_check = xcf_erase_check,
887 .protect_check = xcf_protect_check,
888 .info = xcf_info,
889 .free_driver_priv = default_flash_free_driver_priv,
890 };

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)