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 = " TARGET_ADDR_FMT
,
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 " TARGET_ADDR_FMT
,
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 " TARGET_ADDR_FMT
,
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 " TARGET_ADDR_FMT
": %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 " TARGET_ADDR_FMT
": %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 " TARGET_ADDR_FMT
": %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 " TARGET_ADDR_FMT
,
939 target_device
->name
, bank
->base
);
942 LOG_DEBUG("Assuming FESPI as specified at address " TARGET_ADDR_FMT
943 " with ctrl at " TARGET_ADDR_FMT
, fespi_info
->ctrl_base
,
947 /* read and decode flash ID; returns in SW mode */
948 if (fespi_write_reg(bank
, FESPI_REG_TXCTRL
, FESPI_TXWM(1)) != ERROR_OK
)
950 fespi_set_dir(bank
, FESPI_DIR_TX
);
952 /* Disable Hardware accesses*/
953 if (fespi_disable_hw_mode(bank
) != ERROR_OK
)
956 retval
= fespi_read_flash_id(bank
, &id
);
958 if (fespi_enable_hw_mode(bank
) != ERROR_OK
)
960 if (retval
!= ERROR_OK
)
963 fespi_info
->dev
= NULL
;
964 for (const struct flash_device
*p
= flash_devices
; p
->name
; p
++)
965 if (p
->device_id
== id
) {
970 if (!fespi_info
->dev
) {
971 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32
")", id
);
975 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")",
976 fespi_info
->dev
->name
, fespi_info
->dev
->device_id
);
978 /* Set correct size value */
979 bank
->size
= fespi_info
->dev
->size_in_bytes
;
981 if (bank
->size
<= (1UL << 16))
982 LOG_WARNING("device needs 2-byte addresses - not implemented");
983 if (bank
->size
> (1UL << 24))
984 LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
986 /* if no sectors, treat whole bank as single sector */
987 sectorsize
= fespi_info
->dev
->sectorsize
?
988 fespi_info
->dev
->sectorsize
: fespi_info
->dev
->size_in_bytes
;
990 /* create and fill sectors array */
991 bank
->num_sectors
= fespi_info
->dev
->size_in_bytes
/ sectorsize
;
992 sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
993 if (sectors
== NULL
) {
994 LOG_ERROR("not enough memory");
998 for (int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
999 sectors
[sector
].offset
= sector
* sectorsize
;
1000 sectors
[sector
].size
= sectorsize
;
1001 sectors
[sector
].is_erased
= -1;
1002 sectors
[sector
].is_protected
= 0;
1005 bank
->sectors
= sectors
;
1006 fespi_info
->probed
= 1;
1010 static int fespi_auto_probe(struct flash_bank
*bank
)
1012 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
1013 if (fespi_info
->probed
)
1015 return fespi_probe(bank
);
1018 static int fespi_protect_check(struct flash_bank
*bank
)
1020 /* Nothing to do. Protection is only handled in SW. */
1024 static int get_fespi_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
1026 struct fespi_flash_bank
*fespi_info
= bank
->driver_priv
;
1028 if (!(fespi_info
->probed
)) {
1029 snprintf(buf
, buf_size
,
1030 "\nFESPI flash bank not probed yet\n");
1034 snprintf(buf
, buf_size
, "\nFESPI flash information:\n"
1035 " Device \'%s\' (ID 0x%08" PRIx32
")\n",
1036 fespi_info
->dev
->name
, fespi_info
->dev
->device_id
);
1041 struct flash_driver fespi_flash
= {
1043 .flash_bank_command
= fespi_flash_bank_command
,
1044 .erase
= fespi_erase
,
1045 .protect
= fespi_protect
,
1046 .write
= fespi_write
,
1047 .read
= default_flash_read
,
1048 .probe
= fespi_probe
,
1049 .auto_probe
= fespi_auto_probe
,
1050 .erase_check
= default_flash_blank_check
,
1051 .protect_check
= fespi_protect_check
,
1052 .info
= get_fespi_info
,
1053 .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)