1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
5 * Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *
6 ***************************************************************************/
8 /* The Freedom E SPI controller is a SPI bus controller
9 * specifically designed for SPI Flash Memories on Freedom E platforms.
11 * Two working modes are available:
12 * - SW mode: the SPI is controlled by SW. Any custom commands can be sent
13 * on the bus. Writes are only possible in this mode.
14 * - HW mode: Memory content is directly
15 * accessible in CPU memory space. CPU can read and execute memory content.
19 * To have flash memory mapped in CPU memory space, the controller
20 * must have "HW mode" enabled.
21 * 1) The command "reset init" has to initialize the controller and put
22 * it in HW mode (this is actually the default out of reset for Freedom E systems).
23 * 2) every command in this file have to return to prompt in HW mode. */
31 #include <jtag/jtag.h>
32 #include <helper/time_support.h>
33 #include <target/algorithm.h>
34 #include "target/riscv/riscv.h"
36 /* Register offsets */
38 #define FESPI_REG_SCKDIV 0x00
39 #define FESPI_REG_SCKMODE 0x04
40 #define FESPI_REG_CSID 0x10
41 #define FESPI_REG_CSDEF 0x14
42 #define FESPI_REG_CSMODE 0x18
44 #define FESPI_REG_DCSSCK 0x28
45 #define FESPI_REG_DSCKCS 0x2a
46 #define FESPI_REG_DINTERCS 0x2c
47 #define FESPI_REG_DINTERXFR 0x2e
49 #define FESPI_REG_FMT 0x40
50 #define FESPI_REG_TXFIFO 0x48
51 #define FESPI_REG_RXFIFO 0x4c
52 #define FESPI_REG_TXCTRL 0x50
53 #define FESPI_REG_RXCTRL 0x54
55 #define FESPI_REG_FCTRL 0x60
56 #define FESPI_REG_FFMT 0x64
58 #define FESPI_REG_IE 0x70
59 #define FESPI_REG_IP 0x74
63 #define FESPI_SCK_POL 0x1
64 #define FESPI_SCK_PHA 0x2
66 #define FESPI_FMT_PROTO(x) ((x) & 0x3)
67 #define FESPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
68 #define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
69 #define FESPI_FMT_LEN(x) (((x) & 0xf) << 16)
72 #define FESPI_TXWM(x) ((x) & 0xffff)
74 #define FESPI_RXWM(x) ((x) & 0xffff)
76 #define FESPI_IP_TXWM 0x1
77 #define FESPI_IP_RXWM 0x2
79 #define FESPI_FCTRL_EN 0x1
81 #define FESPI_INSN_CMD_EN 0x1
82 #define FESPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
83 #define FESPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
84 #define FESPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
85 #define FESPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
86 #define FESPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
87 #define FESPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
88 #define FESPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
92 #define FESPI_CSMODE_AUTO 0
93 #define FESPI_CSMODE_HOLD 2
94 #define FESPI_CSMODE_OFF 3
96 #define FESPI_DIR_RX 0
97 #define FESPI_DIR_TX 1
99 #define FESPI_PROTO_S 0
100 #define FESPI_PROTO_D 1
101 #define FESPI_PROTO_Q 2
103 #define FESPI_ENDIAN_MSB 0
104 #define FESPI_ENDIAN_LSB 1
108 #define FESPI_CMD_TIMEOUT (100)
109 #define FESPI_PROBE_TIMEOUT (100)
110 #define FESPI_MAX_TIMEOUT (3000)
113 struct fespi_flash_bank
{
115 target_addr_t ctrl_base
;
116 const struct flash_device
*dev
;
119 struct fespi_target
{
125 /* TODO !!! What is the right naming convention here? */
126 static const struct fespi_target target_devices
[] = {
127 /* name, tap_idcode, ctrl_base */
128 { "Freedom E310-G000 SPI Flash", 0x10e31913, 0x10014000 },
129 { "Freedom E310-G002 SPI Flash", 0x20000913, 0x10014000 },
133 FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command
)
135 struct fespi_flash_bank
*fespi_info
;
137 LOG_DEBUG("%s", __func__
);
140 return ERROR_COMMAND_SYNTAX_ERROR
;
142 fespi_info
= malloc(sizeof(struct fespi_flash_bank
));
144 LOG_ERROR("not enough memory");
148 bank
->driver_priv
= fespi_info
;
149 fespi_info
->probed
= false;
150 fespi_info
->ctrl_base
= 0;
152 COMMAND_PARSE_ADDRESS(CMD_ARGV
[6], fespi_info
->ctrl_base
);
153 LOG_DEBUG("ASSUMING FESPI device at ctrl_base = " TARGET_ADDR_FMT
,
154 fespi_info
->ctrl_base
);
160 static int fespi_read_reg(struct flash_bank
*bank
, uint32_t *value
, target_addr_t address
)
162 struct target
*target
= bank
->target
;
163 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
165 int result
= target_read_u32(target
, fespi_info
->ctrl_base
+ address
, value
);
166 if (result
!= ERROR_OK
) {
167 LOG_ERROR("fespi_read_reg() error at " TARGET_ADDR_FMT
,
168 fespi_info
->ctrl_base
+ address
);
174 static int fespi_write_reg(struct flash_bank
*bank
, target_addr_t address
, uint32_t value
)
176 struct target
*target
= bank
->target
;
177 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
179 int result
= target_write_u32(target
, fespi_info
->ctrl_base
+ address
, value
);
180 if (result
!= ERROR_OK
) {
181 LOG_ERROR("fespi_write_reg() error writing 0x%" PRIx32
" to " TARGET_ADDR_FMT
,
182 value
, fespi_info
->ctrl_base
+ address
);
188 static int fespi_disable_hw_mode(struct flash_bank
*bank
)
191 if (fespi_read_reg(bank
, &fctrl
, FESPI_REG_FCTRL
) != ERROR_OK
)
193 return fespi_write_reg(bank
, FESPI_REG_FCTRL
, fctrl
& ~FESPI_FCTRL_EN
);
196 static int fespi_enable_hw_mode(struct flash_bank
*bank
)
199 if (fespi_read_reg(bank
, &fctrl
, FESPI_REG_FCTRL
) != ERROR_OK
)
201 return fespi_write_reg(bank
, FESPI_REG_FCTRL
, fctrl
| FESPI_FCTRL_EN
);
204 static int fespi_set_dir(struct flash_bank
*bank
, bool dir
)
207 if (fespi_read_reg(bank
, &fmt
, FESPI_REG_FMT
) != ERROR_OK
)
210 return fespi_write_reg(bank
, FESPI_REG_FMT
,
211 (fmt
& ~(FESPI_FMT_DIR(0xFFFFFFFF))) | FESPI_FMT_DIR(dir
));
214 static int fespi_txwm_wait(struct flash_bank
*bank
)
216 int64_t start
= timeval_ms();
220 if (fespi_read_reg(bank
, &ip
, FESPI_REG_IP
) != ERROR_OK
)
222 if (ip
& FESPI_IP_TXWM
)
224 int64_t now
= timeval_ms();
225 if (now
- start
> 1000) {
226 LOG_ERROR("ip.txwm didn't get set.");
227 return ERROR_TARGET_TIMEOUT
;
234 static int fespi_tx(struct flash_bank
*bank
, uint8_t in
)
236 int64_t start
= timeval_ms();
240 if (fespi_read_reg(bank
, &txfifo
, FESPI_REG_TXFIFO
) != ERROR_OK
)
244 int64_t now
= timeval_ms();
245 if (now
- start
> 1000) {
246 LOG_ERROR("txfifo stayed negative.");
247 return ERROR_TARGET_TIMEOUT
;
251 return fespi_write_reg(bank
, FESPI_REG_TXFIFO
, in
);
254 static int fespi_rx(struct flash_bank
*bank
, uint8_t *out
)
256 int64_t start
= timeval_ms();
260 if (fespi_read_reg(bank
, &value
, FESPI_REG_RXFIFO
) != ERROR_OK
)
264 int64_t now
= timeval_ms();
265 if (now
- start
> 1000) {
266 LOG_ERROR("rxfifo didn't go positive (value=0x%" PRIx32
").", value
);
267 return ERROR_TARGET_TIMEOUT
;
277 /* TODO!!! Why don't we need to call this after writing? */
278 static int fespi_wip(struct flash_bank
*bank
, int timeout
)
282 fespi_set_dir(bank
, FESPI_DIR_RX
);
284 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
286 endtime
= timeval_ms() + timeout
;
288 fespi_tx(bank
, SPIFLASH_READ_STATUS
);
289 if (fespi_rx(bank
, NULL
) != ERROR_OK
)
297 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
299 if ((rx
& SPIFLASH_BSY_BIT
) == 0) {
300 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
302 fespi_set_dir(bank
, FESPI_DIR_TX
);
305 } while (timeval_ms() < endtime
);
307 LOG_ERROR("timeout");
311 static int fespi_erase_sector(struct flash_bank
*bank
, int sector
)
313 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
316 retval
= fespi_tx(bank
, SPIFLASH_WRITE_ENABLE
);
317 if (retval
!= ERROR_OK
)
319 retval
= fespi_txwm_wait(bank
);
320 if (retval
!= ERROR_OK
)
323 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
325 retval
= fespi_tx(bank
, fespi_info
->dev
->erase_cmd
);
326 if (retval
!= ERROR_OK
)
328 sector
= bank
->sectors
[sector
].offset
;
329 if (bank
->size
> 0x1000000) {
330 retval
= fespi_tx(bank
, sector
>> 24);
331 if (retval
!= ERROR_OK
)
334 retval
= fespi_tx(bank
, sector
>> 16);
335 if (retval
!= ERROR_OK
)
337 retval
= fespi_tx(bank
, sector
>> 8);
338 if (retval
!= ERROR_OK
)
340 retval
= fespi_tx(bank
, sector
);
341 if (retval
!= ERROR_OK
)
343 retval
= fespi_txwm_wait(bank
);
344 if (retval
!= ERROR_OK
)
346 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
349 retval
= fespi_wip(bank
, FESPI_MAX_TIMEOUT
);
350 if (retval
!= ERROR_OK
)
356 static int fespi_erase(struct flash_bank
*bank
, unsigned int first
,
359 struct target
*target
= bank
->target
;
360 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
361 int retval
= ERROR_OK
;
363 LOG_DEBUG("%s: from sector %u to sector %u", __func__
, first
, last
);
365 if (target
->state
!= TARGET_HALTED
) {
366 LOG_ERROR("Target not halted");
367 return ERROR_TARGET_NOT_HALTED
;
370 if ((last
< first
) || (last
>= bank
->num_sectors
)) {
371 LOG_ERROR("Flash sector invalid");
372 return ERROR_FLASH_SECTOR_INVALID
;
375 if (!(fespi_info
->probed
)) {
376 LOG_ERROR("Flash bank not probed");
377 return ERROR_FLASH_BANK_NOT_PROBED
;
380 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
381 if (bank
->sectors
[sector
].is_protected
) {
382 LOG_ERROR("Flash sector %u protected", sector
);
387 if (fespi_info
->dev
->erase_cmd
== 0x00)
388 return ERROR_FLASH_OPER_UNSUPPORTED
;
390 if (fespi_write_reg(bank
, FESPI_REG_TXCTRL
, FESPI_TXWM(1)) != ERROR_OK
)
392 retval
= fespi_txwm_wait(bank
);
393 if (retval
!= ERROR_OK
) {
394 LOG_ERROR("WM Didn't go high before attempting.");
398 /* Disable Hardware accesses*/
399 if (fespi_disable_hw_mode(bank
) != ERROR_OK
)
403 retval
= fespi_wip(bank
, FESPI_PROBE_TIMEOUT
);
404 if (retval
!= ERROR_OK
)
407 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
408 retval
= fespi_erase_sector(bank
, sector
);
409 if (retval
!= ERROR_OK
)
414 /* Switch to HW mode before return to prompt */
416 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
421 static int fespi_protect(struct flash_bank
*bank
, int set
,
422 unsigned int first
, unsigned int last
)
424 for (unsigned int sector
= first
; sector
<= last
; sector
++)
425 bank
->sectors
[sector
].is_protected
= set
;
429 static int slow_fespi_write_buffer(struct flash_bank
*bank
,
430 const uint8_t *buffer
, uint32_t offset
, uint32_t len
)
432 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
435 /* TODO!!! assert that len < page size */
437 if (fespi_tx(bank
, SPIFLASH_WRITE_ENABLE
) != ERROR_OK
)
439 if (fespi_txwm_wait(bank
) != ERROR_OK
)
442 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
445 if (fespi_tx(bank
, fespi_info
->dev
->pprog_cmd
) != ERROR_OK
)
448 if (bank
->size
> 0x1000000 && fespi_tx(bank
, offset
>> 24) != ERROR_OK
)
450 if (fespi_tx(bank
, offset
>> 16) != ERROR_OK
)
452 if (fespi_tx(bank
, offset
>> 8) != ERROR_OK
)
454 if (fespi_tx(bank
, offset
) != ERROR_OK
)
457 for (ii
= 0; ii
< len
; ii
++) {
458 if (fespi_tx(bank
, buffer
[ii
]) != ERROR_OK
)
462 if (fespi_txwm_wait(bank
) != ERROR_OK
)
465 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
473 static const uint8_t riscv32_bin
[] = {
474 #include "../../../contrib/loaders/flash/fespi/riscv32_fespi.inc"
477 static const uint8_t riscv64_bin
[] = {
478 #include "../../../contrib/loaders/flash/fespi/riscv64_fespi.inc"
481 static int fespi_write(struct flash_bank
*bank
, const uint8_t *buffer
,
482 uint32_t offset
, uint32_t count
)
484 struct target
*target
= bank
->target
;
485 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
486 uint32_t cur_count
, page_size
;
487 int retval
= ERROR_OK
;
489 LOG_DEBUG("bank->size=0x%x offset=0x%08" PRIx32
" count=0x%08" PRIx32
,
490 bank
->size
, offset
, count
);
492 if (target
->state
!= TARGET_HALTED
) {
493 LOG_ERROR("Target not halted");
494 return ERROR_TARGET_NOT_HALTED
;
497 if (offset
+ count
> fespi_info
->dev
->size_in_bytes
) {
498 LOG_WARNING("Write past end of flash. Extra data discarded.");
499 count
= fespi_info
->dev
->size_in_bytes
- offset
;
502 /* Check sector protection */
503 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
504 /* Start offset in or before this sector? */
505 /* End offset in or behind this sector? */
507 (bank
->sectors
[sector
].offset
+ bank
->sectors
[sector
].size
))
508 && ((offset
+ count
- 1) >= bank
->sectors
[sector
].offset
)
509 && bank
->sectors
[sector
].is_protected
) {
510 LOG_ERROR("Flash sector %u protected", sector
);
515 struct riscv_info
*riscv
= riscv_info(target
);
516 if (!is_riscv(riscv
)) {
517 LOG_ERROR("Unexpected target type");
521 unsigned int xlen
= riscv_xlen(target
);
522 struct working_area
*algorithm_wa
= NULL
;
523 struct working_area
*data_wa
= NULL
;
528 bin_size
= sizeof(riscv32_bin
);
531 bin_size
= sizeof(riscv64_bin
);
534 unsigned data_wa_size
= 0;
535 if (target_alloc_working_area(target
, bin_size
, &algorithm_wa
) == ERROR_OK
) {
536 retval
= target_write_buffer(target
, algorithm_wa
->address
,
538 if (retval
!= ERROR_OK
) {
539 LOG_ERROR("Failed to write code to " TARGET_ADDR_FMT
": %d",
540 algorithm_wa
->address
, retval
);
541 target_free_working_area(target
, algorithm_wa
);
545 data_wa_size
= MIN(target_get_working_area_avail(target
), count
);
546 if (data_wa_size
< 128) {
547 LOG_WARNING("Couldn't allocate data working area.");
548 target_free_working_area(target
, algorithm_wa
);
550 } else if (target_alloc_working_area(target
, data_wa_size
, &data_wa
) != ERROR_OK
) {
551 target_free_working_area(target
, algorithm_wa
);
556 LOG_WARNING("Couldn't allocate %zd-byte working area.", bin_size
);
560 /* If no valid page_size, use reasonable default. */
561 page_size
= fespi_info
->dev
->pagesize
?
562 fespi_info
->dev
->pagesize
: SPIFLASH_DEF_PAGESIZE
;
565 struct reg_param reg_params
[6];
566 init_reg_param(®_params
[0], "a0", xlen
, PARAM_IN_OUT
);
567 init_reg_param(®_params
[1], "a1", xlen
, PARAM_OUT
);
568 init_reg_param(®_params
[2], "a2", xlen
, PARAM_OUT
);
569 init_reg_param(®_params
[3], "a3", xlen
, PARAM_OUT
);
570 init_reg_param(®_params
[4], "a4", xlen
, PARAM_OUT
);
571 init_reg_param(®_params
[5], "a5", xlen
, PARAM_OUT
);
574 cur_count
= MIN(count
, data_wa_size
);
575 buf_set_u64(reg_params
[0].value
, 0, xlen
, fespi_info
->ctrl_base
);
576 buf_set_u64(reg_params
[1].value
, 0, xlen
, page_size
);
577 buf_set_u64(reg_params
[2].value
, 0, xlen
, data_wa
->address
);
578 buf_set_u64(reg_params
[3].value
, 0, xlen
, offset
);
579 buf_set_u64(reg_params
[4].value
, 0, xlen
, cur_count
);
580 buf_set_u64(reg_params
[5].value
, 0, xlen
,
581 fespi_info
->dev
->pprog_cmd
| (bank
->size
> 0x1000000 ? 0x100 : 0));
583 retval
= target_write_buffer(target
, data_wa
->address
, cur_count
,
585 if (retval
!= ERROR_OK
) {
586 LOG_DEBUG("Failed to write %d bytes to " TARGET_ADDR_FMT
": %d",
587 cur_count
, data_wa
->address
, retval
);
591 LOG_DEBUG("write(ctrl_base=0x%" TARGET_PRIxADDR
", page_size=0x%x, "
592 "address=0x%" TARGET_PRIxADDR
", offset=0x%" PRIx32
593 ", count=0x%" PRIx32
"), buffer=%02x %02x %02x %02x %02x %02x ..." PRIx32
,
594 fespi_info
->ctrl_base
, page_size
, data_wa
->address
, offset
, cur_count
,
595 buffer
[0], buffer
[1], buffer
[2], buffer
[3], buffer
[4], buffer
[5]);
596 retval
= target_run_algorithm(target
, 0, NULL
,
597 ARRAY_SIZE(reg_params
), reg_params
,
598 algorithm_wa
->address
, 0, cur_count
* 2, NULL
);
599 if (retval
!= ERROR_OK
) {
600 LOG_ERROR("Failed to execute algorithm at " TARGET_ADDR_FMT
": %d",
601 algorithm_wa
->address
, retval
);
605 uint64_t algorithm_result
= buf_get_u64(reg_params
[0].value
, 0, xlen
);
606 if (algorithm_result
!= 0) {
607 LOG_ERROR("Algorithm returned error %" PRId64
, algorithm_result
);
617 target_free_working_area(target
, data_wa
);
618 target_free_working_area(target
, algorithm_wa
);
621 fespi_txwm_wait(bank
);
623 /* Disable Hardware accesses*/
624 if (fespi_disable_hw_mode(bank
) != ERROR_OK
)
628 retval
= fespi_wip(bank
, FESPI_PROBE_TIMEOUT
);
629 if (retval
!= ERROR_OK
)
632 uint32_t page_offset
= offset
% page_size
;
633 /* central part, aligned words */
635 /* clip block at page boundary */
636 if (page_offset
+ count
> page_size
)
637 cur_count
= page_size
- page_offset
;
641 retval
= slow_fespi_write_buffer(bank
, buffer
, offset
, cur_count
);
642 if (retval
!= ERROR_OK
)
651 /* Switch to HW mode before return to prompt */
652 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
659 target_free_working_area(target
, data_wa
);
660 target_free_working_area(target
, algorithm_wa
);
662 /* Switch to HW mode before return to prompt */
663 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
669 /* Return ID of flash device */
670 /* On exit, SW mode is kept */
671 static int fespi_read_flash_id(struct flash_bank
*bank
, uint32_t *id
)
673 struct target
*target
= bank
->target
;
676 if (target
->state
!= TARGET_HALTED
) {
677 LOG_ERROR("Target not halted");
678 return ERROR_TARGET_NOT_HALTED
;
681 fespi_txwm_wait(bank
);
684 retval
= fespi_wip(bank
, FESPI_PROBE_TIMEOUT
);
685 if (retval
!= ERROR_OK
)
688 fespi_set_dir(bank
, FESPI_DIR_RX
);
690 /* Send SPI command "read ID" */
691 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
694 fespi_tx(bank
, SPIFLASH_READ_ID
);
695 /* Send dummy bytes to actually read the ID.*/
700 /* read ID from Receive Register */
702 if (fespi_rx(bank
, NULL
) != ERROR_OK
)
705 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
708 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
711 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
715 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
718 fespi_set_dir(bank
, FESPI_DIR_TX
);
723 static int fespi_probe(struct flash_bank
*bank
)
725 struct target
*target
= bank
->target
;
726 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
727 struct flash_sector
*sectors
;
728 uint32_t id
= 0; /* silence uninitialized warning */
729 const struct fespi_target
*target_device
;
733 if (fespi_info
->probed
)
735 fespi_info
->probed
= false;
737 if (fespi_info
->ctrl_base
== 0) {
738 for (target_device
= target_devices
; target_device
->name
; ++target_device
)
739 if (target_device
->tap_idcode
== target
->tap
->idcode
)
742 if (!target_device
->name
) {
743 LOG_ERROR("Device ID 0x%" PRIx32
" is not known as FESPI capable",
744 target
->tap
->idcode
);
748 fespi_info
->ctrl_base
= target_device
->ctrl_base
;
750 LOG_DEBUG("Valid FESPI on device %s at address " TARGET_ADDR_FMT
,
751 target_device
->name
, bank
->base
);
754 LOG_DEBUG("Assuming FESPI as specified at address " TARGET_ADDR_FMT
755 " with ctrl at " TARGET_ADDR_FMT
, fespi_info
->ctrl_base
,
759 /* read and decode flash ID; returns in SW mode */
760 if (fespi_write_reg(bank
, FESPI_REG_TXCTRL
, FESPI_TXWM(1)) != ERROR_OK
)
762 fespi_set_dir(bank
, FESPI_DIR_TX
);
764 /* Disable Hardware accesses*/
765 if (fespi_disable_hw_mode(bank
) != ERROR_OK
)
768 retval
= fespi_read_flash_id(bank
, &id
);
770 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
772 if (retval
!= ERROR_OK
)
775 fespi_info
->dev
= NULL
;
776 for (const struct flash_device
*p
= flash_devices
; p
->name
; p
++)
777 if (p
->device_id
== id
) {
782 if (!fespi_info
->dev
) {
783 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32
")", id
);
787 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")",
788 fespi_info
->dev
->name
, fespi_info
->dev
->device_id
);
790 /* Set correct size value */
791 bank
->size
= fespi_info
->dev
->size_in_bytes
;
793 if (bank
->size
<= (1UL << 16))
794 LOG_WARNING("device needs 2-byte addresses - not implemented");
796 /* if no sectors, treat whole bank as single sector */
797 sectorsize
= fespi_info
->dev
->sectorsize
?
798 fespi_info
->dev
->sectorsize
: fespi_info
->dev
->size_in_bytes
;
800 /* create and fill sectors array */
801 bank
->num_sectors
= fespi_info
->dev
->size_in_bytes
/ sectorsize
;
802 sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
804 LOG_ERROR("not enough memory");
808 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
809 sectors
[sector
].offset
= sector
* sectorsize
;
810 sectors
[sector
].size
= sectorsize
;
811 sectors
[sector
].is_erased
= -1;
812 sectors
[sector
].is_protected
= 0;
815 bank
->sectors
= sectors
;
816 fespi_info
->probed
= true;
820 static int fespi_auto_probe(struct flash_bank
*bank
)
822 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
823 if (fespi_info
->probed
)
825 return fespi_probe(bank
);
828 static int fespi_protect_check(struct flash_bank
*bank
)
830 /* Nothing to do. Protection is only handled in SW. */
834 static int get_fespi_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
836 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
838 if (!(fespi_info
->probed
)) {
839 command_print_sameline(cmd
, "\nFESPI flash bank not probed yet\n");
843 command_print_sameline(cmd
, "\nFESPI flash information:\n"
844 " Device \'%s\' (ID 0x%08" PRIx32
")\n",
845 fespi_info
->dev
->name
, fespi_info
->dev
->device_id
);
850 const struct flash_driver fespi_flash
= {
852 .flash_bank_command
= fespi_flash_bank_command
,
853 .erase
= fespi_erase
,
854 .protect
= fespi_protect
,
855 .write
= fespi_write
,
856 .read
= default_flash_read
,
857 .probe
= fespi_probe
,
858 .auto_probe
= fespi_auto_probe
,
859 .erase_check
= default_flash_blank_check
,
860 .protect_check
= fespi_protect_check
,
861 .info
= get_fespi_info
,
862 .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)