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

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)