1 /***************************************************************************
2 * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
3 * Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *
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 ***************************************************************************/
19 /* The Freedom E SPI controller is a SPI bus controller
20 * specifically designed for SPI Flash Memories on Freedom E platforms.
22 * Two working modes are available:
23 * - SW mode: the SPI is controlled by SW. Any custom commands can be sent
24 * on the bus. Writes are only possible in this mode.
25 * - HW mode: Memory content is directly
26 * accessible in CPU memory space. CPU can read and execute memory content.
30 * To have flash memory mapped in CPU memory space, the controller
31 * must have "HW mode" enabled.
32 * 1) The command "reset init" has to initialize the controller and put
33 * it in HW mode (this is actually the default out of reset for Freedom E systems).
34 * 2) every command in this file have to return to prompt in HW mode. */
42 #include <jtag/jtag.h>
43 #include <helper/time_support.h>
44 #include <target/algorithm.h>
45 #include "target/riscv/riscv.h"
47 /* Register offsets */
49 #define FESPI_REG_SCKDIV 0x00
50 #define FESPI_REG_SCKMODE 0x04
51 #define FESPI_REG_CSID 0x10
52 #define FESPI_REG_CSDEF 0x14
53 #define FESPI_REG_CSMODE 0x18
55 #define FESPI_REG_DCSSCK 0x28
56 #define FESPI_REG_DSCKCS 0x2a
57 #define FESPI_REG_DINTERCS 0x2c
58 #define FESPI_REG_DINTERXFR 0x2e
60 #define FESPI_REG_FMT 0x40
61 #define FESPI_REG_TXFIFO 0x48
62 #define FESPI_REG_RXFIFO 0x4c
63 #define FESPI_REG_TXCTRL 0x50
64 #define FESPI_REG_RXCTRL 0x54
66 #define FESPI_REG_FCTRL 0x60
67 #define FESPI_REG_FFMT 0x64
69 #define FESPI_REG_IE 0x70
70 #define FESPI_REG_IP 0x74
74 #define FESPI_SCK_POL 0x1
75 #define FESPI_SCK_PHA 0x2
77 #define FESPI_FMT_PROTO(x) ((x) & 0x3)
78 #define FESPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
79 #define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
80 #define FESPI_FMT_LEN(x) (((x) & 0xf) << 16)
83 #define FESPI_TXWM(x) ((x) & 0xffff)
85 #define FESPI_RXWM(x) ((x) & 0xffff)
87 #define FESPI_IP_TXWM 0x1
88 #define FESPI_IP_RXWM 0x2
90 #define FESPI_FCTRL_EN 0x1
92 #define FESPI_INSN_CMD_EN 0x1
93 #define FESPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
94 #define FESPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
95 #define FESPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
96 #define FESPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
97 #define FESPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
98 #define FESPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
99 #define FESPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
103 #define FESPI_CSMODE_AUTO 0
104 #define FESPI_CSMODE_HOLD 2
105 #define FESPI_CSMODE_OFF 3
107 #define FESPI_DIR_RX 0
108 #define FESPI_DIR_TX 1
110 #define FESPI_PROTO_S 0
111 #define FESPI_PROTO_D 1
112 #define FESPI_PROTO_Q 2
114 #define FESPI_ENDIAN_MSB 0
115 #define FESPI_ENDIAN_LSB 1
119 #define FESPI_CMD_TIMEOUT (100)
120 #define FESPI_PROBE_TIMEOUT (100)
121 #define FESPI_MAX_TIMEOUT (3000)
124 struct fespi_flash_bank
{
126 target_addr_t ctrl_base
;
127 const struct flash_device
*dev
;
130 struct fespi_target
{
136 /* TODO !!! What is the right naming convention here? */
137 static const struct fespi_target target_devices
[] = {
138 /* name, tap_idcode, ctrl_base */
139 { "Freedom E300 SPI Flash", 0x10e31913 , 0x10014000 },
143 FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command
)
145 struct fespi_flash_bank
*fespi_info
;
147 LOG_DEBUG("%s", __func__
);
150 return ERROR_COMMAND_SYNTAX_ERROR
;
152 fespi_info
= malloc(sizeof(struct fespi_flash_bank
));
153 if (fespi_info
== NULL
) {
154 LOG_ERROR("not enough memory");
158 bank
->driver_priv
= fespi_info
;
159 fespi_info
->probed
= 0;
160 fespi_info
->ctrl_base
= 0;
163 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[6], temp
);
164 fespi_info
->ctrl_base
= (uint32_t) temp
;
165 LOG_DEBUG("ASSUMING FESPI device at ctrl_base = 0x%" TARGET_PRIxADDR
,
166 fespi_info
->ctrl_base
);
172 static int fespi_read_reg(struct flash_bank
*bank
, uint32_t *value
, target_addr_t address
)
174 struct target
*target
= bank
->target
;
175 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
177 int result
= target_read_u32(target
, fespi_info
->ctrl_base
+ address
, value
);
178 if (result
!= ERROR_OK
) {
179 LOG_ERROR("fespi_read_reg() error at 0x%" TARGET_PRIxADDR
,
180 fespi_info
->ctrl_base
+ address
);
186 static int fespi_write_reg(struct flash_bank
*bank
, target_addr_t address
, uint32_t value
)
188 struct target
*target
= bank
->target
;
189 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
191 int result
= target_write_u32(target
, fespi_info
->ctrl_base
+ address
, value
);
192 if (result
!= ERROR_OK
) {
193 LOG_ERROR("fespi_write_reg() error writing 0x%x to 0x%" TARGET_PRIxADDR
,
194 value
, fespi_info
->ctrl_base
+ address
);
200 static int fespi_disable_hw_mode(struct flash_bank
*bank
)
203 if (fespi_read_reg(bank
, &fctrl
, FESPI_REG_FCTRL
) != ERROR_OK
)
205 return fespi_write_reg(bank
, FESPI_REG_FCTRL
, fctrl
& ~FESPI_FCTRL_EN
);
208 static int fespi_enable_hw_mode(struct flash_bank
*bank
)
211 if (fespi_read_reg(bank
, &fctrl
, FESPI_REG_FCTRL
) != ERROR_OK
)
213 return fespi_write_reg(bank
, FESPI_REG_FCTRL
, fctrl
| FESPI_FCTRL_EN
);
216 static int fespi_set_dir(struct flash_bank
*bank
, bool dir
)
219 if (fespi_read_reg(bank
, &fmt
, FESPI_REG_FMT
) != ERROR_OK
)
222 return fespi_write_reg(bank
, FESPI_REG_FMT
,
223 (fmt
& ~(FESPI_FMT_DIR(0xFFFFFFFF))) | FESPI_FMT_DIR(dir
));
226 static int fespi_txwm_wait(struct flash_bank
*bank
)
228 int64_t start
= timeval_ms();
232 if (fespi_read_reg(bank
, &ip
, FESPI_REG_IP
) != ERROR_OK
)
234 if (ip
& FESPI_IP_TXWM
)
236 int64_t now
= timeval_ms();
237 if (now
- start
> 1000) {
238 LOG_ERROR("ip.txwm didn't get set.");
239 return ERROR_TARGET_TIMEOUT
;
246 static int fespi_tx(struct flash_bank
*bank
, uint8_t in
)
248 int64_t start
= timeval_ms();
252 if (fespi_read_reg(bank
, &txfifo
, FESPI_REG_TXFIFO
) != ERROR_OK
)
256 int64_t now
= timeval_ms();
257 if (now
- start
> 1000) {
258 LOG_ERROR("txfifo stayed negative.");
259 return ERROR_TARGET_TIMEOUT
;
263 return fespi_write_reg(bank
, FESPI_REG_TXFIFO
, in
);
266 static int fespi_rx(struct flash_bank
*bank
, uint8_t *out
)
268 int64_t start
= timeval_ms();
272 if (fespi_read_reg(bank
, &value
, FESPI_REG_RXFIFO
) != ERROR_OK
)
276 int64_t now
= timeval_ms();
277 if (now
- start
> 1000) {
278 LOG_ERROR("rxfifo didn't go positive (value=0x%x).", value
);
279 return ERROR_TARGET_TIMEOUT
;
289 /* TODO!!! Why don't we need to call this after writing? */
290 static int fespi_wip(struct flash_bank
*bank
, int timeout
)
294 fespi_set_dir(bank
, FESPI_DIR_RX
);
296 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
298 endtime
= timeval_ms() + timeout
;
300 fespi_tx(bank
, SPIFLASH_READ_STATUS
);
301 if (fespi_rx(bank
, NULL
) != ERROR_OK
)
309 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
311 if ((rx
& SPIFLASH_BSY_BIT
) == 0) {
312 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
314 fespi_set_dir(bank
, FESPI_DIR_TX
);
317 } while (timeval_ms() < endtime
);
319 LOG_ERROR("timeout");
323 static int fespi_erase_sector(struct flash_bank
*bank
, int sector
)
325 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
328 retval
= fespi_tx(bank
, SPIFLASH_WRITE_ENABLE
);
329 if (retval
!= ERROR_OK
)
331 retval
= fespi_txwm_wait(bank
);
332 if (retval
!= ERROR_OK
)
335 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
337 retval
= fespi_tx(bank
, fespi_info
->dev
->erase_cmd
);
338 if (retval
!= ERROR_OK
)
340 sector
= bank
->sectors
[sector
].offset
;
341 retval
= fespi_tx(bank
, sector
>> 16);
342 if (retval
!= ERROR_OK
)
344 retval
= fespi_tx(bank
, sector
>> 8);
345 if (retval
!= ERROR_OK
)
347 retval
= fespi_tx(bank
, sector
);
348 if (retval
!= ERROR_OK
)
350 retval
= fespi_txwm_wait(bank
);
351 if (retval
!= ERROR_OK
)
353 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
356 retval
= fespi_wip(bank
, FESPI_MAX_TIMEOUT
);
357 if (retval
!= ERROR_OK
)
363 static int fespi_erase(struct flash_bank
*bank
, int first
, int last
)
365 struct target
*target
= bank
->target
;
366 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
367 int retval
= ERROR_OK
;
370 LOG_DEBUG("%s: from sector %d to sector %d", __func__
, first
, last
);
372 if (target
->state
!= TARGET_HALTED
) {
373 LOG_ERROR("Target not halted");
374 return ERROR_TARGET_NOT_HALTED
;
377 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
378 LOG_ERROR("Flash sector invalid");
379 return ERROR_FLASH_SECTOR_INVALID
;
382 if (!(fespi_info
->probed
)) {
383 LOG_ERROR("Flash bank not probed");
384 return ERROR_FLASH_BANK_NOT_PROBED
;
387 for (sector
= first
; sector
<= last
; sector
++) {
388 if (bank
->sectors
[sector
].is_protected
) {
389 LOG_ERROR("Flash sector %d protected", sector
);
394 if (fespi_info
->dev
->erase_cmd
== 0x00)
395 return ERROR_FLASH_OPER_UNSUPPORTED
;
397 if (fespi_write_reg(bank
, FESPI_REG_TXCTRL
, FESPI_TXWM(1)) != ERROR_OK
)
399 retval
= fespi_txwm_wait(bank
);
400 if (retval
!= ERROR_OK
) {
401 LOG_ERROR("WM Didn't go high before attempting.");
405 /* Disable Hardware accesses*/
406 if (fespi_disable_hw_mode(bank
) != ERROR_OK
)
410 retval
= fespi_wip(bank
, FESPI_PROBE_TIMEOUT
);
411 if (retval
!= ERROR_OK
)
414 for (sector
= first
; sector
<= last
; sector
++) {
415 retval
= fespi_erase_sector(bank
, sector
);
416 if (retval
!= ERROR_OK
)
421 /* Switch to HW mode before return to prompt */
423 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
428 static int fespi_protect(struct flash_bank
*bank
, int set
,
433 for (sector
= first
; sector
<= last
; sector
++)
434 bank
->sectors
[sector
].is_protected
= set
;
438 static int slow_fespi_write_buffer(struct flash_bank
*bank
,
439 const uint8_t *buffer
, uint32_t offset
, uint32_t len
)
443 if (offset
& 0xFF000000) {
444 LOG_ERROR("FESPI interface does not support greater than 3B addressing, can't write to offset 0x%x",
449 /* TODO!!! assert that len < page size */
451 fespi_tx(bank
, SPIFLASH_WRITE_ENABLE
);
452 fespi_txwm_wait(bank
);
454 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
457 fespi_tx(bank
, SPIFLASH_PAGE_PROGRAM
);
459 fespi_tx(bank
, offset
>> 16);
460 fespi_tx(bank
, offset
>> 8);
461 fespi_tx(bank
, offset
);
463 for (ii
= 0; ii
< len
; ii
++)
464 fespi_tx(bank
, buffer
[ii
]);
466 fespi_txwm_wait(bank
);
468 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
476 static const uint8_t algorithm_bin
[] = {
477 #include "../../../contrib/loaders/flash/fespi/fespi.inc"
481 #define STEP_TXWM_WAIT 12
482 #define STEP_WRITE_REG 16
483 #define STEP_WIP_WAIT 20
484 #define STEP_SET_DIR 24
485 #define STEP_NOP 0xff
487 struct algorithm_steps
{
493 static struct algorithm_steps
*as_new(void)
495 struct algorithm_steps
*as
= calloc(1, sizeof(struct algorithm_steps
));
497 as
->steps
= malloc(as
->size
* sizeof(as
->steps
[0]));
501 static struct algorithm_steps
*as_delete(struct algorithm_steps
*as
)
503 for (unsigned step
= 0; step
< as
->used
; step
++) {
504 free(as
->steps
[step
]);
505 as
->steps
[step
] = NULL
;
512 static int as_empty(struct algorithm_steps
*as
)
514 for (unsigned s
= 0; s
< as
->used
; s
++) {
515 if (as
->steps
[s
][0] != STEP_NOP
)
521 /* Return size of compiled program. */
522 static unsigned as_compile(struct algorithm_steps
*as
, uint8_t *target
,
523 unsigned target_size
)
526 bool finish_early
= false;
527 for (unsigned s
= 0; s
< as
->used
&& !finish_early
; s
++) {
528 unsigned bytes_left
= target_size
- offset
;
529 switch (as
->steps
[s
][0]) {
534 unsigned size
= as
->steps
[s
][1];
535 if (size
+ 3 > bytes_left
) {
539 memcpy(target
+ offset
, as
->steps
[s
], size
+ 2);
544 if (4 > bytes_left
) {
548 memcpy(target
+ offset
, as
->steps
[s
], 3);
552 if (3 > bytes_left
) {
556 memcpy(target
+ offset
, as
->steps
[s
], 2);
561 if (2 > bytes_left
) {
565 memcpy(target
+ offset
, as
->steps
[s
], 1);
572 as
->steps
[s
][0] = STEP_NOP
;
574 assert(offset
+ 1 <= target_size
);
575 target
[offset
++] = STEP_EXIT
;
577 LOG_DEBUG("%d-byte program:", offset
);
578 for (unsigned i
= 0; i
< offset
;) {
580 for (unsigned x
= 0; i
< offset
&& x
< 16; x
++, i
++)
581 sprintf(buf
+ x
*3, "%02x ", target
[i
]);
582 LOG_DEBUG("%s", buf
);
588 static void as_add_step(struct algorithm_steps
*as
, uint8_t *step
)
590 if (as
->used
== as
->size
) {
592 as
->steps
= realloc(as
->steps
, sizeof(as
->steps
[0]) * as
->size
);
593 LOG_DEBUG("Increased size to 0x%x", as
->size
);
595 as
->steps
[as
->used
] = step
;
599 static void as_add_tx(struct algorithm_steps
*as
, unsigned count
, const uint8_t *data
)
601 LOG_DEBUG("count=%d", count
);
603 unsigned step_count
= MIN(count
, 255);
604 uint8_t *step
= malloc(step_count
+ 2);
606 step
[1] = step_count
;
607 memcpy(step
+ 2, data
, step_count
);
608 as_add_step(as
, step
);
614 static void as_add_tx1(struct algorithm_steps
*as
, uint8_t byte
)
618 as_add_tx(as
, 1, data
);
621 static void as_add_write_reg(struct algorithm_steps
*as
, uint8_t offset
, uint8_t data
)
623 uint8_t *step
= malloc(3);
624 step
[0] = STEP_WRITE_REG
;
627 as_add_step(as
, step
);
630 static void as_add_txwm_wait(struct algorithm_steps
*as
)
632 uint8_t *step
= malloc(1);
633 step
[0] = STEP_TXWM_WAIT
;
634 as_add_step(as
, step
);
637 static void as_add_wip_wait(struct algorithm_steps
*as
)
639 uint8_t *step
= malloc(1);
640 step
[0] = STEP_WIP_WAIT
;
641 as_add_step(as
, step
);
644 static void as_add_set_dir(struct algorithm_steps
*as
, bool dir
)
646 uint8_t *step
= malloc(2);
647 step
[0] = STEP_SET_DIR
;
648 step
[1] = FESPI_FMT_DIR(dir
);
649 as_add_step(as
, step
);
652 /* This should write something less than or equal to a page.*/
653 static int steps_add_buffer_write(struct algorithm_steps
*as
,
654 const uint8_t *buffer
, uint32_t chip_offset
, uint32_t len
)
656 if (chip_offset
& 0xFF000000) {
657 LOG_ERROR("FESPI interface does not support greater than 3B addressing, can't write to offset 0x%x",
662 as_add_tx1(as
, SPIFLASH_WRITE_ENABLE
);
663 as_add_txwm_wait(as
);
664 as_add_write_reg(as
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
);
667 SPIFLASH_PAGE_PROGRAM
,
672 as_add_tx(as
, sizeof(setup
), setup
);
674 as_add_tx(as
, len
, buffer
);
675 as_add_txwm_wait(as
);
676 as_add_write_reg(as
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
);
679 as_add_set_dir(as
, FESPI_DIR_RX
);
680 as_add_write_reg(as
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
);
682 as_add_write_reg(as
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
);
683 as_add_set_dir(as
, FESPI_DIR_TX
);
688 static int steps_execute(struct algorithm_steps
*as
,
689 struct flash_bank
*bank
, struct working_area
*algorithm_wa
,
690 struct working_area
*data_wa
)
692 struct target
*target
= bank
->target
;
693 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
694 uint32_t ctrl_base
= fespi_info
->ctrl_base
;
695 int xlen
= riscv_xlen(target
);
697 struct reg_param reg_params
[2];
698 init_reg_param(®_params
[0], "a0", xlen
, PARAM_OUT
);
699 init_reg_param(®_params
[1], "a1", xlen
, PARAM_OUT
);
700 buf_set_u64(reg_params
[0].value
, 0, xlen
, ctrl_base
);
701 buf_set_u64(reg_params
[1].value
, 0, xlen
, data_wa
->address
);
703 int retval
= ERROR_OK
;
704 while (!as_empty(as
)) {
706 uint8_t *data_buf
= malloc(data_wa
->size
);
707 unsigned bytes
= as_compile(as
, data_buf
, data_wa
->size
);
708 retval
= target_write_buffer(target
, data_wa
->address
, bytes
,
711 if (retval
!= ERROR_OK
) {
712 LOG_ERROR("Failed to write data to 0x%" TARGET_PRIxADDR
": %d",
713 data_wa
->address
, retval
);
717 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
718 algorithm_wa
->address
, algorithm_wa
->address
+ 4,
720 if (retval
!= ERROR_OK
) {
721 LOG_ERROR("Failed to execute algorithm at 0x%" TARGET_PRIxADDR
": %d",
722 algorithm_wa
->address
, retval
);
728 destroy_reg_param(®_params
[1]);
729 destroy_reg_param(®_params
[0]);
733 static int fespi_write(struct flash_bank
*bank
, const uint8_t *buffer
,
734 uint32_t offset
, uint32_t count
)
736 struct target
*target
= bank
->target
;
737 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
738 uint32_t cur_count
, page_size
, page_offset
;
740 int retval
= ERROR_OK
;
742 LOG_DEBUG("%s: offset=0x%08" PRIx32
" count=0x%08" PRIx32
,
743 __func__
, offset
, count
);
745 if (target
->state
!= TARGET_HALTED
) {
746 LOG_ERROR("Target not halted");
747 return ERROR_TARGET_NOT_HALTED
;
750 if (offset
+ count
> fespi_info
->dev
->size_in_bytes
) {
751 LOG_WARNING("Write past end of flash. Extra data discarded.");
752 count
= fespi_info
->dev
->size_in_bytes
- offset
;
755 /* Check sector protection */
756 for (sector
= 0; sector
< bank
->num_sectors
; sector
++) {
757 /* Start offset in or before this sector? */
758 /* End offset in or behind this sector? */
760 (bank
->sectors
[sector
].offset
+ bank
->sectors
[sector
].size
))
761 && ((offset
+ count
- 1) >= bank
->sectors
[sector
].offset
)
762 && bank
->sectors
[sector
].is_protected
) {
763 LOG_ERROR("Flash sector %d protected", sector
);
768 struct working_area
*algorithm_wa
;
769 if (target_alloc_working_area(target
, sizeof(algorithm_bin
),
770 &algorithm_wa
) != ERROR_OK
) {
771 LOG_WARNING("Couldn't allocate %zd-byte working area.",
772 sizeof(algorithm_bin
));
775 retval
= target_write_buffer(target
, algorithm_wa
->address
,
776 sizeof(algorithm_bin
), algorithm_bin
);
777 if (retval
!= ERROR_OK
) {
778 LOG_ERROR("Failed to write code to 0x%" TARGET_PRIxADDR
": %d",
779 algorithm_wa
->address
, retval
);
780 target_free_working_area(target
, algorithm_wa
);
785 struct working_area
*data_wa
= NULL
;
786 unsigned data_wa_size
= 2 * count
;
788 if (data_wa_size
< 128) {
789 LOG_WARNING("Couldn't allocate data working area.");
790 target_free_working_area(target
, algorithm_wa
);
793 if (target_alloc_working_area_try(target
, data_wa_size
, &data_wa
) ==
801 /* If no valid page_size, use reasonable default. */
802 page_size
= fespi_info
->dev
->pagesize
?
803 fespi_info
->dev
->pagesize
: SPIFLASH_DEF_PAGESIZE
;
805 fespi_txwm_wait(bank
);
807 /* Disable Hardware accesses*/
808 if (fespi_disable_hw_mode(bank
) != ERROR_OK
)
811 struct algorithm_steps
*as
= as_new();
814 retval
= fespi_wip(bank
, FESPI_PROBE_TIMEOUT
);
815 if (retval
!= ERROR_OK
)
818 page_offset
= offset
% page_size
;
819 /* central part, aligned words */
821 /* clip block at page boundary */
822 if (page_offset
+ count
> page_size
)
823 cur_count
= page_size
- page_offset
;
828 retval
= steps_add_buffer_write(as
, buffer
, offset
, cur_count
);
830 retval
= slow_fespi_write_buffer(bank
, buffer
, offset
, cur_count
);
831 if (retval
!= ERROR_OK
)
841 retval
= steps_execute(as
, bank
, algorithm_wa
, data_wa
);
845 target_free_working_area(target
, data_wa
);
846 target_free_working_area(target
, algorithm_wa
);
851 /* Switch to HW mode before return to prompt */
852 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
857 /* Return ID of flash device */
858 /* On exit, SW mode is kept */
859 static int fespi_read_flash_id(struct flash_bank
*bank
, uint32_t *id
)
861 struct target
*target
= bank
->target
;
864 if (target
->state
!= TARGET_HALTED
) {
865 LOG_ERROR("Target not halted");
866 return ERROR_TARGET_NOT_HALTED
;
869 fespi_txwm_wait(bank
);
872 retval
= fespi_wip(bank
, FESPI_PROBE_TIMEOUT
);
873 if (retval
!= ERROR_OK
)
876 fespi_set_dir(bank
, FESPI_DIR_RX
);
878 /* Send SPI command "read ID" */
879 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_HOLD
) != ERROR_OK
)
882 fespi_tx(bank
, SPIFLASH_READ_ID
);
883 /* Send dummy bytes to actually read the ID.*/
888 /* read ID from Receive Register */
890 if (fespi_rx(bank
, NULL
) != ERROR_OK
)
893 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
896 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
899 if (fespi_rx(bank
, &rx
) != ERROR_OK
)
903 if (fespi_write_reg(bank
, FESPI_REG_CSMODE
, FESPI_CSMODE_AUTO
) != ERROR_OK
)
906 fespi_set_dir(bank
, FESPI_DIR_TX
);
911 static int fespi_probe(struct flash_bank
*bank
)
913 struct target
*target
= bank
->target
;
914 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
915 struct flash_sector
*sectors
;
916 uint32_t id
= 0; /* silence uninitialized warning */
917 const struct fespi_target
*target_device
;
921 if (fespi_info
->probed
)
923 fespi_info
->probed
= 0;
925 if (fespi_info
->ctrl_base
== 0) {
926 for (target_device
= target_devices
; target_device
->name
; ++target_device
)
927 if (target_device
->tap_idcode
== target
->tap
->idcode
)
930 if (!target_device
->name
) {
931 LOG_ERROR("Device ID 0x%" PRIx32
" is not known as FESPI capable",
932 target
->tap
->idcode
);
936 fespi_info
->ctrl_base
= target_device
->ctrl_base
;
938 LOG_DEBUG("Valid FESPI on device %s at address 0x%" PRIx32
,
939 target_device
->name
, bank
->base
);
942 LOG_DEBUG("Assuming FESPI as specified at address 0x%" TARGET_PRIxADDR
943 " with ctrl at 0x%x", fespi_info
->ctrl_base
, bank
->base
);
946 /* read and decode flash ID; returns in SW mode */
947 if (fespi_write_reg(bank
, FESPI_REG_TXCTRL
, FESPI_TXWM(1)) != ERROR_OK
)
949 fespi_set_dir(bank
, FESPI_DIR_TX
);
951 /* Disable Hardware accesses*/
952 if (fespi_disable_hw_mode(bank
) != ERROR_OK
)
955 retval
= fespi_read_flash_id(bank
, &id
);
957 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
959 if (retval
!= ERROR_OK
)
962 fespi_info
->dev
= NULL
;
963 for (const struct flash_device
*p
= flash_devices
; p
->name
; p
++)
964 if (p
->device_id
== id
) {
969 if (!fespi_info
->dev
) {
970 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32
")", id
);
974 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")",
975 fespi_info
->dev
->name
, fespi_info
->dev
->device_id
);
977 /* Set correct size value */
978 bank
->size
= fespi_info
->dev
->size_in_bytes
;
980 if (bank
->size
<= (1UL << 16))
981 LOG_WARNING("device needs 2-byte addresses - not implemented");
982 if (bank
->size
> (1UL << 24))
983 LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
985 /* if no sectors, treat whole bank as single sector */
986 sectorsize
= fespi_info
->dev
->sectorsize
?
987 fespi_info
->dev
->sectorsize
: fespi_info
->dev
->size_in_bytes
;
989 /* create and fill sectors array */
990 bank
->num_sectors
= fespi_info
->dev
->size_in_bytes
/ sectorsize
;
991 sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
992 if (sectors
== NULL
) {
993 LOG_ERROR("not enough memory");
997 for (int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
998 sectors
[sector
].offset
= sector
* sectorsize
;
999 sectors
[sector
].size
= sectorsize
;
1000 sectors
[sector
].is_erased
= -1;
1001 sectors
[sector
].is_protected
= 0;
1004 bank
->sectors
= sectors
;
1005 fespi_info
->probed
= 1;
1009 static int fespi_auto_probe(struct flash_bank
*bank
)
1011 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
1012 if (fespi_info
->probed
)
1014 return fespi_probe(bank
);
1017 static int fespi_protect_check(struct flash_bank
*bank
)
1019 /* Nothing to do. Protection is only handled in SW. */
1023 static int get_fespi_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
1025 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
1027 if (!(fespi_info
->probed
)) {
1028 snprintf(buf
, buf_size
,
1029 "\nFESPI flash bank not probed yet\n");
1033 snprintf(buf
, buf_size
, "\nFESPI flash information:\n"
1034 " Device \'%s\' (ID 0x%08" PRIx32
")\n",
1035 fespi_info
->dev
->name
, fespi_info
->dev
->device_id
);
1040 struct flash_driver fespi_flash
= {
1042 .flash_bank_command
= fespi_flash_bank_command
,
1043 .erase
= fespi_erase
,
1044 .protect
= fespi_protect
,
1045 .write
= fespi_write
,
1046 .read
= default_flash_read
,
1047 .probe
= fespi_probe
,
1048 .auto_probe
= fespi_auto_probe
,
1049 .erase_check
= default_flash_blank_check
,
1050 .protect_check
= fespi_protect_check
,
1051 .info
= get_fespi_info
,
1052 .free_driver_priv
= default_flash_free_driver_priv