1 /***************************************************************************
2 * Copyright (C) 2016 by Uladzimir Pylinski aka barthess *
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. *
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. *
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 ***************************************************************************/
26 #include <jtag/jtag.h>
27 #include <helper/time_support.h>
30 ******************************************************************************
32 ******************************************************************************
35 #define SECTOR_ERASE_TIMEOUT_MS (35 * 1000)
37 #define XCF_PAGE_SIZE 32
38 #define XCF_DATA_SECTOR_SIZE (1024 * 1024)
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
48 const char *xcf_name_list
[] = {
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 */
67 ******************************************************************************
69 ******************************************************************************
71 static const uint8_t CMD_BYPASS
[2] = {0xFF, 0xFF};
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};
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};
92 ******************************************************************************
94 ******************************************************************************
97 static const char *product_name(const struct flash_bank
*bank
)
100 switch (bank
->target
->tap
->idcode
& ID_MEANINGFUL_MASK
) {
102 return xcf_name_list
[0];
104 return xcf_name_list
[1];
106 return xcf_name_list
[2];
108 return xcf_name_list
[3];
112 static void fill_sector_table(struct flash_bank
*bank
)
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. */
119 for (i
= 0; i
< bank
->num_sectors
; i
++) {
120 bank
->sectors
[i
].is_erased
= -1;
121 bank
->sectors
[i
].is_protected
= -1;
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
;
128 bank
->size
= bank
->num_sectors
* XCF_DATA_SECTOR_SIZE
;
131 static struct xcf_status
read_status(struct flash_bank
*bank
)
133 struct xcf_status ret
;
135 struct scan_field scan
;
137 scan
.check_mask
= NULL
;
138 scan
.check_value
= NULL
;
140 scan
.out_value
= CMD_BYPASS
;
141 scan
.in_value
= irdata
;
143 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
144 jtag_execute_queue();
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;
154 static int isc_enter(struct flash_bank
*bank
)
157 struct xcf_status status
= read_status(bank
);
159 if (true == status
.isc_mode
)
162 struct scan_field scan
;
164 scan
.check_mask
= NULL
;
165 scan
.check_value
= NULL
;
167 scan
.out_value
= CMD_ISC_ENABLE
;
168 scan
.in_value
= NULL
;
170 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
171 jtag_execute_queue();
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
;
183 static int isc_leave(struct flash_bank
*bank
)
186 struct xcf_status status
= read_status(bank
);
188 if (false == status
.isc_mode
)
191 struct scan_field scan
;
193 scan
.check_mask
= NULL
;
194 scan
.check_value
= NULL
;
196 scan
.out_value
= CMD_ISC_DISABLE
;
197 scan
.in_value
= NULL
;
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 */
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
;
213 static int sector_state(uint8_t wrpt
, int sector
)
215 if (((wrpt
>> sector
) & 1) == 1)
221 static uint8_t fill_select_block(int first
, int last
)
224 for (int i
= first
; i
<= last
; i
++)
229 static int isc_read_register(struct flash_bank
*bank
, const uint8_t *cmd
,
230 uint8_t *data_buf
, int num_bits
)
232 struct scan_field scan
;
234 scan
.check_mask
= NULL
;
235 scan
.check_value
= NULL
;
236 scan
.out_value
= cmd
;
237 scan
.in_value
= NULL
;
239 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_DRSHIFT
);
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
);
246 return jtag_execute_queue();
249 static int isc_wait_erase_program(struct flash_bank
*bank
, int64_t timeout_ms
)
253 int64_t t0
= timeval_ms();
257 isc_read_register(bank
, CMD_XSC_OP_STATUS
, &isc_default
, 8);
258 if (((isc_default
>> 2) & 1) == 1)
260 dt
= timeval_ms() - t0
;
261 } while (dt
<= timeout_ms
);
262 return ERROR_FLASH_OPERATION_FAILED
;
266 * helper function for procedures without program jtag command at the end
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
)
271 struct scan_field scan
;
273 scan
.check_mask
= NULL
;
274 scan
.check_value
= NULL
;
276 scan
.out_value
= cmd
;
277 scan
.in_value
= NULL
;
278 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_DRSHIFT
);
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
);
286 return jtag_execute_queue();
288 return isc_wait_erase_program(bank
, timeout_ms
);
292 * helper function for procedures required program jtag command at the end
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
)
297 struct scan_field scan
;
299 scan
.check_mask
= NULL
;
300 scan
.check_value
= NULL
;
302 scan
.out_value
= cmd
;
303 scan
.in_value
= NULL
;
304 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_DRSHIFT
);
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
);
312 scan
.out_value
= CMD_ISC_PROGRAM
;
313 scan
.in_value
= NULL
;
314 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
317 return jtag_execute_queue();
319 return isc_wait_erase_program(bank
, timeout_ms
);
322 static int isc_clear_protect(struct flash_bank
*bank
, int first
, int last
)
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);
329 static int isc_set_protect(struct flash_bank
*bank
, int first
, int last
)
331 uint8_t wrpt
[2] = {0xFF, 0xFF};
332 for (int i
= first
; i
<= last
; i
++)
333 wrpt
[0] &= ~(1 << i
);
335 return isc_program_register(bank
, CMD_XSC_DATA_WRPT
, wrpt
, 16, 0);
338 static int isc_erase_sectors(struct flash_bank
*bank
, int first
, int last
)
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
);
346 static int isc_adr_shift(struct flash_bank
*bank
, int adr
)
349 h_u24_to_le(adr_buf
, adr
);
350 return isc_set_register(bank
, CMD_ISC_ADDRESS_SHIFT
, adr_buf
, 24, 0);
353 static int isc_program_data_page(struct flash_bank
*bank
, const uint8_t *page_buf
)
355 return isc_program_register(bank
, CMD_ISC_DATA_SHIFT
, page_buf
, 8 * XCF_PAGE_SIZE
, 100);
358 static void isc_data_read_out(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t count
)
361 struct scan_field scan
;
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
;
368 scan
.out_value
= CMD_XSC_READ
;
369 scan
.in_value
= NULL
;
370 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
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
);
377 jtag_execute_queue();
380 static int isc_set_data_done(struct flash_bank
*bank
, int sector
)
383 done
&= ~(1 << sector
);
384 return isc_program_register(bank
, CMD_XSC_DATA_DONE
, &done
, 8, 100);
387 static void flip_u8(uint8_t *out
, const uint8_t *in
, int len
)
389 for (int i
= 0; i
< len
; i
++)
390 out
[i
] = flip_u32(in
[i
], 8);
394 * Xilinx bin file contains simple fixed header for automatic bus width detection:
396 * 4 byte sync word 0xAA995566 or (bit reversed) 0x5599AA66 in MSC file
398 * Function presumes need of bit reversing if it can not exactly detects
401 bool need_bit_reverse(const uint8_t *buffer
)
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;
411 if (0 == memcmp(reference
, buffer
, L
))
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.
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
)
429 int dbg_count
= count
;
432 uint8_t *page_buf
= malloc(XCF_PAGE_SIZE
);
436 if (offset
% XCF_PAGE_SIZE
!= 0) {
437 ret
= ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
441 if ((offset
+ count
) > (uint32_t)(bank
->num_sectors
* XCF_DATA_SECTOR_SIZE
)) {
442 ret
= ERROR_FLASH_DST_OUT_OF_BANK
;
446 if ((write_flag
) && (0 == offset
) && (count
>= XCF_PAGE_SIZE
))
447 revbit
= need_bit_reverse(w_buffer
);
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
;
460 while (sector_bytes
> 0) {
463 if (sector_bytes
< XCF_PAGE_SIZE
) {
465 memset(page_buf
, 0xFF, XCF_PAGE_SIZE
);
470 flip_u8(page_buf
, w_buffer
, len
);
472 memcpy(page_buf
, w_buffer
, len
);
476 ret
= isc_program_data_page(bank
, page_buf
);
480 LOG_DEBUG("written %d bytes from %d", dbg_written
, dbg_count
);
485 isc_data_read_out(bank
, r_buffer
, sector_bytes
);
486 flip_u8(r_buffer
, r_buffer
, sector_bytes
);
487 r_buffer
+= sector_bytes
;
491 /* Set 'done' flags for all data sectors because driver supports
492 * only single revision. */
494 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
495 ret
= isc_set_data_done(bank
, i
);
507 static uint16_t isc_read_ccb(struct flash_bank
*bank
)
510 isc_read_register(bank
, CMD_XSC_DATA_CCB
, ccb
, 16);
511 return le_to_h_u16(ccb
);
514 static int gucr_num(const struct flash_bank
*bank
)
516 return bank
->num_sectors
;
519 static int sucr_num(const struct flash_bank
*bank
)
521 return bank
->num_sectors
+ 1;
524 static int isc_program_ccb(struct flash_bank
*bank
, uint16_t ccb
)
527 h_u16_to_le(buf
, ccb
);
528 return isc_program_register(bank
, CMD_XSC_DATA_CCB
, buf
, 16, 100);
531 static int isc_program_singe_revision_sucr(struct flash_bank
*bank
)
533 uint8_t sucr
[2] = {0xFC, 0xFF};
534 return isc_program_register(bank
, CMD_XSC_DATA_SUCR
, sucr
, 16, 100);
537 static int isc_program_single_revision_btc(struct flash_bank
*bank
)
540 uint32_t btc
= 0xFFFFFFFF;
542 btc
|= ((bank
->num_sectors
- 1) << 2);
544 h_u32_to_le(buf
, btc
);
545 return isc_program_register(bank
, CMD_XSC_DATA_BTC
, buf
, 32, 100);
548 static int fpga_configure(struct flash_bank
*bank
)
550 struct scan_field scan
;
552 scan
.check_mask
= NULL
;
553 scan
.check_value
= NULL
;
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();
564 ******************************************************************************
566 ******************************************************************************
569 FLASH_BANK_COMMAND_HANDLER(xcf_flash_bank_command
)
571 struct xcf_priv
*priv
;
573 priv
= malloc(sizeof(struct xcf_priv
));
575 LOG_ERROR("no memory for flash bank info");
578 bank
->driver_priv
= priv
;
579 priv
->probed
= false;
583 static int xcf_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
585 const struct xcf_priv
*priv
= bank
->driver_priv
;
587 if (false == priv
->probed
) {
588 snprintf(buf
, buf_size
, "\nXCF flash bank not probed yet\n");
591 snprintf(buf
, buf_size
, "%s", product_name(bank
));
595 static int xcf_probe(struct flash_bank
*bank
)
597 struct xcf_priv
*priv
= bank
->driver_priv
;
600 if (true == priv
->probed
)
602 priv
->probed
= false;
604 if (bank
->target
->tap
== NULL
) {
605 LOG_ERROR("Target has no JTAG tap");
609 /* check idcode and alloc memory for sector table */
610 if (!bank
->target
->tap
->hasidcode
)
611 return ERROR_FLASH_OPERATION_FAILED
;
613 /* guess number of blocks using chip ID */
614 id
= bank
->target
->tap
->idcode
;
615 switch (id
& ID_MEANINGFUL_MASK
) {
617 bank
->num_sectors
= 1;
620 bank
->num_sectors
= 2;
623 bank
->num_sectors
= 4;
626 LOG_ERROR("Unknown flash device ID 0x%X", id
);
631 bank
->sectors
= malloc(bank
->num_sectors
* sizeof(struct flash_sector
));
632 if (NULL
== bank
->sectors
) {
633 LOG_ERROR("No memory for sector table");
636 fill_sector_table(bank
);
639 /* REVISIT: Why is unchanged bank->driver_priv rewritten by same value? */
640 bank
->driver_priv
= priv
;
642 LOG_INFO("product name: %s", product_name(bank
));
643 LOG_INFO("device id = 0x%X ", bank
->target
->tap
->idcode
);
644 LOG_INFO("flash size = %d configuration bits",
645 bank
->num_sectors
* XCF_DATA_SECTOR_SIZE
* 8);
646 LOG_INFO("number of sectors = %d", bank
->num_sectors
);
651 static int xcf_auto_probe(struct flash_bank
*bank
)
653 struct xcf_priv
*priv
= bank
->driver_priv
;
655 if (true == priv
->probed
)
658 return xcf_probe(bank
);
661 static int xcf_protect_check(struct flash_bank
*bank
)
666 isc_read_register(bank
, CMD_XSC_DATA_WRPT
, wrpt
, 16);
669 for (int i
= 0; i
< bank
->num_sectors
; i
++)
670 bank
->sectors
[i
].is_protected
= sector_state(wrpt
[0], i
);
675 static int xcf_erase_check(struct flash_bank
*bank
)
678 struct scan_field scan
;
682 /* Do not change this code with isc_read_register() call because it needs
683 * transition to IDLE state and pause before data retrieving. */
684 scan
.check_mask
= NULL
;
685 scan
.check_value
= NULL
;
687 scan
.out_value
= CMD_XSC_BLANK_CHECK
;
688 scan
.in_value
= NULL
;
689 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
690 jtag_execute_queue();
691 alive_sleep(500); /* device needs at least 0.5s to self check */
694 scan
.in_value
= &blankreg
;
695 jtag_add_dr_scan(bank
->target
->tap
, 1, &scan
, TAP_IDLE
);
696 jtag_execute_queue();
700 for (int i
= 0; i
< bank
->num_sectors
; i
++)
701 bank
->sectors
[i
].is_erased
= sector_state(blankreg
, i
);
706 static int xcf_erase(struct flash_bank
*bank
, int first
, int last
)
708 if ((first
>= bank
->num_sectors
)
709 || (last
>= bank
->num_sectors
)
711 return ERROR_FLASH_SECTOR_INVALID
;
714 isc_clear_protect(bank
, first
, last
);
715 int ret
= isc_erase_sectors(bank
, first
, last
);
721 static int xcf_read(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
723 return read_write_data(bank
, NULL
, buffer
, false, offset
, count
);
726 static int xcf_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
,
729 return read_write_data(bank
, buffer
, NULL
, true, offset
, count
);
732 static int xcf_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
738 ret
= isc_set_protect(bank
, first
, last
);
740 /* write protection may be removed only with following erase */
741 isc_clear_protect(bank
, first
, last
);
742 ret
= isc_erase_sectors(bank
, first
, last
);
749 COMMAND_HANDLER(xcf_handle_ccb_command
) {
751 if (!((CMD_ARGC
== 1) || (CMD_ARGC
== 5)))
752 return ERROR_COMMAND_SYNTAX_ERROR
;
754 struct flash_bank
*bank
;
755 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
756 if (ERROR_OK
!= retval
)
759 uint16_t ccb
= 0xFFFF;
761 uint16_t old_ccb
= isc_read_ccb(bank
);
765 LOG_INFO("current CCB = 0x%X", old_ccb
);
768 /* skip over flash bank */
772 if (strcmp("external", CMD_ARGV
[0]) == 0)
774 else if (strcmp("internal", CMD_ARGV
[0]) == 0)
776 else if (strcmp("serial", CMD_ARGV
[0]) == 0)
778 else if (strcmp("parallel", CMD_ARGV
[0]) == 0)
780 else if (strcmp("slave", CMD_ARGV
[0]) == 0)
782 else if (strcmp("master", CMD_ARGV
[0]) == 0)
784 else if (strcmp("40", CMD_ARGV
[0]) == 0)
786 else if (strcmp("20", CMD_ARGV
[0]) == 0)
789 return ERROR_COMMAND_SYNTAX_ERROR
;
798 sector
= gucr_num(bank
);
799 isc_clear_protect(bank
, sector
, sector
);
800 int ret
= isc_erase_sectors(bank
, sector
, sector
);
803 ret
= isc_program_ccb(bank
, ccb
);
806 ret
= isc_program_single_revision_btc(bank
);
809 ret
= isc_set_data_done(bank
, sector
);
814 sector
= sucr_num(bank
);
815 isc_clear_protect(bank
, sector
, sector
);
816 ret
= isc_erase_sectors(bank
, sector
, sector
);
819 ret
= isc_program_singe_revision_sucr(bank
);
822 ret
= isc_set_data_done(bank
, sector
);
832 COMMAND_HANDLER(xcf_handle_configure_command
) {
835 return ERROR_COMMAND_SYNTAX_ERROR
;
837 struct flash_bank
*bank
;
838 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
839 if (ERROR_OK
!= retval
)
842 return fpga_configure(bank
);
845 static const struct command_registration xcf_exec_command_handlers
[] = {
848 .handler
= xcf_handle_configure_command
,
849 .mode
= COMMAND_EXEC
,
851 .help
= "Initiate FPGA loading procedure."
855 .handler
= xcf_handle_ccb_command
,
856 .mode
= COMMAND_EXEC
,
857 .usage
= "bank_id [('external'|'internal') "
858 "('serial'|'parallel') "
859 "('slave'|'master') "
861 .help
= "Write CCB register with supplied options and (silently) BTC "
862 "register with single revision options. Display current "
863 "CCB value when only bank_id supplied. "
864 "Following options available: "
865 "1) external or internal clock source; "
866 "2) serial or parallel bus mode; "
867 "3) slave or master mode; "
868 "4) clock frequency in MHz for internal clock in master mode;"
870 COMMAND_REGISTRATION_DONE
873 static const struct command_registration xcf_command_handlers
[] = {
877 .help
= "Xilinx platform flash command group",
879 .chain
= xcf_exec_command_handlers
881 COMMAND_REGISTRATION_DONE
884 const struct flash_driver xcf_flash
= {
887 .commands
= xcf_command_handlers
,
888 .flash_bank_command
= xcf_flash_bank_command
,
890 .protect
= xcf_protect
,
894 .auto_probe
= xcf_auto_probe
,
895 .erase_check
= xcf_erase_check
,
896 .protect_check
= xcf_protect_check
,
898 .free_driver_priv
= default_flash_free_driver_priv
,
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)