trabucayre / openFPGALoader

Universal utility for programming FPGA
https://trabucayre.github.io/openFPGALoader/
Apache License 2.0
1.19k stars 254 forks source link

flash chip write protection #124

Open emard opened 3 years ago

emard commented 3 years ago

HI

Is there some support for write protection of flash chips, usually I need to protect bootloader in first 2MB of flash from accidental overwriting. My chips of interest are some ISSI and Winbond 16MB.

emard commented 2 years ago

It should be good! I'm going to compile and test master

On 12/22/21, Gwenhael Goavec-Merou @.***> wrote:

I've integrated everything into master branch. It's good for you? Thanks for motivation!

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-999876302 You are receiving this because you authored the thread.

Message ID: @.***>

trabucayre commented 2 years ago

Thanks! My worry is your problem with cycloneV

emard commented 2 years ago

It is a lot of things to test, quick test of normal programming works. I'm getting segmentation fault in DFU mode:

openFPGALoader --dfu --altsetting 0 ulx3s_12f_ecp5pll.bit write to ram Open file DONE Parse file DONE Segmentation fault

On 12/22/21, D EMARD @.***> wrote:

It should be good! I'm going to compile and test master

On 12/22/21, Gwenhael Goavec-Merou @.***> wrote:

I've integrated everything into master branch. It's good for you? Thanks for motivation!

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-999876302 You are receiving this because you authored the thread.

Message ID: @.***>

emard commented 2 years ago

CycloneV will be later tested, I must clean the desktop with some ongoing projects and connect C5 on.

On 12/22/21, D EMARD @.***> wrote:

It is a lot of things to test, quick test of normal programming works. I'm getting segmentation fault in DFU mode:

openFPGALoader --dfu --altsetting 0 ulx3s_12f_ecp5pll.bit write to ram Open file DONE Parse file DONE Segmentation fault

On 12/22/21, D EMARD @.***> wrote:

It should be good! I'm going to compile and test master

On 12/22/21, Gwenhael Goavec-Merou @.***> wrote:

I've integrated everything into master branch. It's good for you? Thanks for motivation!

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-999876302 You are receiving this because you authored the thread.

Message ID: @.***>

emard commented 2 years ago

New DFU multiboot.img for 12F 85F and other boards and its pcb versions are here:

https://github.com/emard/ulx3s-bin/tree/master/fpga/dfu

check your board versions written on bottom like v3.0.8 It's not big deal if wrong versions is flashed, Most of things will work, something around esp32 will not

On 12/22/21, D EMARD @.***> wrote:

CycloneV will be later tested, I must clean the desktop with some ongoing projects and connect C5 on.

On 12/22/21, D EMARD @.***> wrote:

It is a lot of things to test, quick test of normal programming works. I'm getting segmentation fault in DFU mode:

openFPGALoader --dfu --altsetting 0 ulx3s_12f_ecp5pll.bit write to ram Open file DONE Parse file DONE Segmentation fault

On 12/22/21, D EMARD @.***> wrote:

It should be good! I'm going to compile and test master

On 12/22/21, Gwenhael Goavec-Merou @.***> wrote:

I've integrated everything into master branch. It's good for you? Thanks for motivation!

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-999876302 You are receiving this because you authored the thread.

Message ID: @.***>

trabucayre commented 2 years ago

Thanks for your feeback! I'm unable to reproduce (but using a bit file you can't omit --vid --pid);

penFPGALoader --dfu --altsetting 0 blink.bit 
write to ram
Open file DONE
Parse file DONE
DFU init failed with: Can't open device vid/pid == 0

But a weird thing: after programing through DFU, new bitstream must be loaded, it's not true. I think something is wrong in my DFU class.

trabucayre commented 2 years ago

Okay. I've updated dfu.cpp. Missing USB reset when download end in DFUIdle state.

emard commented 2 years ago

Great, when I use --vid --pid then it works and resets usb!

The bitstream can start without usb reset using "exit/execute" option, it is more recommended way than reset because depending on DIP switch position, usb reset may not jump to uploaded bitstream but again to DFU bootloader

example how bitstream is uploaded and started using dfu-util:

dfu-util -a0 -D ulx3s_12f_ecp5pll.bit dfu-util -a0 -e

However, without --vid -pid I get segfault ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit .. segfault like before

If segfault is fixed, it could print message about vid/pid options missing

On 12/23/21, Gwenhael Goavec-Merou @.***> wrote:

Okay. I've updated dfu.cpp. Missing USB reset when download end in DFUIdle state.

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000073129 You are receiving this because you authored the thread.

Message ID: @.***>

emard commented 2 years ago

Apart from segfault, your dfu mode starts correctly uploaded bitstream from DFU mode. On ULX3S board, DIP SW 1 controls DFU: Same as DIP SW ON is holding BTN1 (F1) during power on

DIP SW 1 ON (up) board powers up running DFU bitstream DIP SW 1: OFF (down) board powers on running user (uploaded) bitstream

On 12/23/21, D EMARD @.***> wrote:

Great, when I use --vid --pid then it works and resets usb!

The bitstream can start without usb reset using "exit/execute" option, it is more recommended way than reset because depending on DIP switch position, usb reset may not jump to uploaded bitstream but again to DFU bootloader

example how bitstream is uploaded and started using dfu-util:

dfu-util -a0 -D ulx3s_12f_ecp5pll.bit dfu-util -a0 -e

However, without --vid -pid I get segfault ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit .. segfault like before

If segfault is fixed, it could print message about vid/pid options missing

On 12/23/21, Gwenhael Goavec-Merou @.***> wrote:

Okay. I've updated dfu.cpp. Missing USB reset when download end in DFUIdle state.

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000073129 You are receiving this because you authored the thread.

Message ID: @.***>

emard commented 2 years ago

I can see unpredictable behaviour, sometimes reported ok, sometimes segfault (valgrinding needed :)?

$ ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit write to ram Open file DONE Parse file DONE DFU init failed with: No DFU compatible device found

$ ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit write to ram Open file DONE Parse file DONE Segmentation fault

On 12/23/21, D EMARD @.***> wrote:

Apart from segfault, your dfu mode starts correctly uploaded bitstream from DFU mode. On ULX3S board, DIP SW 1 controls DFU: Same as DIP SW ON is holding BTN1 (F1) during power on

DIP SW 1 ON (up) board powers up running DFU bitstream DIP SW 1: OFF (down) board powers on running user (uploaded) bitstream

On 12/23/21, D EMARD @.***> wrote:

Great, when I use --vid --pid then it works and resets usb!

The bitstream can start without usb reset using "exit/execute" option, it is more recommended way than reset because depending on DIP switch position, usb reset may not jump to uploaded bitstream but again to DFU bootloader

example how bitstream is uploaded and started using dfu-util:

dfu-util -a0 -D ulx3s_12f_ecp5pll.bit dfu-util -a0 -e

However, without --vid -pid I get segfault ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit .. segfault like before

If segfault is fixed, it could print message about vid/pid options missing

On 12/23/21, Gwenhael Goavec-Merou @.***> wrote:

Okay. I've updated dfu.cpp. Missing USB reset when download end in DFUIdle state.

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000073129 You are receiving this because you authored the thread.

Message ID: @.***>

trabucayre commented 2 years ago

I've fixed, using valgrind, some memory leaks. But with or without this fix I always have the message and no segfault... You use master branch?

maybe with gdb to have a backtrack ?

ulimit -c unlimited
ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit
gdb ofl core
emard commented 2 years ago

HI

I recompiled latest branch (it should be master) @.***:/tmp/openFPGALoader/build$ git branch

this is what gdb says:

***@***.***:~/src/fpga/ulx3s/ulx3s-misc/examples/ecp5pll$ ulimit -c unlimited
***@***.***:~/src/fpga/ulx3s/ulx3s-misc/examples/ecp5pll$ ofl --dfu
--altsetting=0 ulx3s_12f_ecp5pll.bit
write to ram
Open file DONE
Parse file DONE
Segmentacijska greška (**krah**: stanje (dump) memorije je zapisano!)
***@***.***:~/src/fpga/ulx3s/ulx3s-misc/examples/ecp5pll$ gdb ofl core
GNU gdb (Debian 10.1-2) 10.1.90.20210103-git
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ofl...
(No debugging symbols found in ofl)

warning: core file may not match specified executable file.
[New LWP 58336]
[New LWP 58337]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f3ac3812101 in libusb_close () from
/lib/x86_64-linux-gnu/libusb-1.0.so.0
[Current thread is 1 (Thread 0x7f3ac323a780 (LWP 58336))]
(gdb)

On 12/23/21, Gwenhael Goavec-Merou @.***> wrote:

I've fixed, using valgrind, some memory leaks. But with or without this fix I always have the message and no segfault... You use master branch?

maybe with gdb to have a backtrack ?

ulimit -c unlimited
ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit
gdb ofl core

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000167539 You are receiving this because you authored the thread.

Message ID: @.***>

trabucayre commented 2 years ago

could you use bt in gdb prompt ? And compile using cmake -DCMAKE_BUILD_TYPE=Debug

emard commented 2 years ago

HI

yes, bt gets a more detailed report:


***@***.***:~/src/fpga/ulx3s/ulx3s-misc/examples/ecp5pll$ ofl --dfu
--altsetting=0 ulx3s_12f_ecp5pll.bit
write to ram
Open file DONE
Parse file DONE
Segmentacijska greška (**krah**: stanje (dump) memorije je zapisano!)
***@***.***:~/src/fpga/ulx3s/ulx3s-misc/examples/ecp5pll$ ulimit -c unlimited
***@***.***:~/src/fpga/ulx3s/ulx3s-misc/examples/ecp5pll$ gdb ofl core
GNU gdb (Debian 10.1-2) 10.1.90.20210103-git
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ofl...

warning: core file may not match specified executable file.
[New LWP 58946]
[New LWP 58947]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f5f8587e101 in libusb_close () from
/lib/x86_64-linux-gnu/libusb-1.0.so.0
[Current thread is 1 (Thread 0x7f5f852a6780 (LWP 58946))]
(gdb) bt
#0  0x00007f5f8587e101 in libusb_close () from
/lib/x86_64-linux-gnu/libusb-1.0.so.0
#1  0x00005613e87b9f6d in DFU::searchDFUDevices (this=0x5613e9882f80)
    at /tmp/openFPGALoader/src/dfu.cpp:309
#2  0x00005613e87b882d in DFU::DFU (this=0x5613e9882f80,
filename="ulx3s_12f_ecp5pll.bit", vid=0,
    pid=0, altsetting=0, verbose_lvl=0) at /tmp/openFPGALoader/src/dfu.cpp:100
#3  0x00005613e881cb8b in main (argc=4, argv=0x7ffd3d7322d8) at
/tmp/openFPGALoader/src/main.cpp:333
(gdb)
``

On 12/23/21, Gwenhael Goavec-Merou ***@***.***> wrote:
> could you use `bt` in gdb prompt ?
> And compile using `cmake -DCMAKE_BUILD_TYPE=Debug`
>
> --
> Reply to this email directly or view it on GitHub:
> https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000212271
> You are receiving this because you authored the thread.
>
> Message ID: ***@***.***>
trabucayre commented 2 years ago

Yes. This is useful. I have added a check on libusb_open just before libusb_close. Maybe one device on your computer can't be opened and consequently fails at close time.

emard commented 2 years ago

Yes, recent change fixes the segfault issuse

$ ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit write to ram Open file DONE Parse file DONE Unable to open device: 1d6b:0003 (bus 4, device 1) Error: LIBUSB_ERROR_ACCESS

DFU init failed with: Devices enumeration failed

This device is the root hub

lsusb

Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

On 12/23/21, Gwenhael Goavec-Merou @.***> wrote:

Yes. This is useful. I have added a check on libusb_open just before libusb_close. Maybe one device on your computer can't be opened and consequently fails at close time.

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000295200 You are receiving this because you authored the thread.

Message ID: @.***>

trabucayre commented 2 years ago

Cool! I have modified a bit: now if libusb_open fails, move directly to next one instead of producing an error. Thanks!

emard commented 2 years ago

OK, now I tested, it works if specific vid/pid is given and if it is not, then it lists probing all devices except the DFU one and exits. Maybe it is possible to autodetect or if given -b ulx3s --dfu to assume this vid/pid

$ ofl --dfu --altsetting=0 --vid 0x1d50 --pid 0x614b ulx3s_12f_ecp5pll.bit.gz write to ram Cable VID overridden Cable PID overridden Open file DONE Parse file DONE Open device 1d50:614b DONE 1d50 614b Loading: [==================================================] 100.00% Done

$ ofl --dfu --altsetting=0 ulx3s_12f_ecp5pll.bit.gz write to ram Open file DONE Parse file DONE Unable to open device: 1d6b:0003 (bus 4, device 1) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 1d6b:0002 (bus 3, device 1) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 0bda:0316 (bus 2, device 2) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 1d6b:0003 (bus 2, device 1) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 0424:2514 (bus 1, device 35) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 8087:0a2a (bus 1, device 4) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 4242:e131 (bus 1, device 3) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 045e:0039 (bus 1, device 2) Error: LIBUSB_ERROR_ACCESS -> skip

Unable to open device: 1d6b:0002 (bus 1, device 1) Error: LIBUSB_ERROR_ACCESS -> skip

DFU init failed with: Can't open device vid/pid == 0

On 12/24/21, Gwenhael Goavec-Merou @.***> wrote:

Cool! I have modified a bit: now if libusb_open fails, move directly to next one instead of producing an error. Thanks!

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000751289 You are receiving this because you authored the thread.

Message ID: @.***>

trabucayre commented 2 years ago

I've added a level of verbosity to avoid this big list... Adding a board in dfu mode (as orangeCrab, fomu or icebreaker-bitsy) make sense. I'm not happy by autodetecting approach -> my wifi card has dfu compatible interface -> it's too risky...

emard commented 2 years ago

OK I compiled, seems fine.

I was also thinking that autodetect can flash wrong device :)

If it's easy code that can iterates over dfu-compatible interfaces I think it could print --vid= --pid= parameters for each and let user copy-paste.

Other option is board preset, maybe something like -b ulx3s --dfu or -b ulx3s-dfu

On 12/24/21, Gwenhael Goavec-Merou @.***> wrote:

I've added a level of verbosity to avoid this big list... Adding a board in dfu mode (as orangeCrab, fomu or icebreaker-bitsy) make sense. I'm not happy by autodetecting approach -> my wifi card has dfu compatible interface -> it's too risky...

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000869891 You are receiving this because you authored the thread.

Message ID: @.***>

trabucayre commented 2 years ago

Added this

emard commented 2 years ago

Hey thanx, I compiled that works great!!! Wonderful!

On 12/24/21, Gwenhael Goavec-Merou @.***> wrote:

Added this

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1000902706 You are receiving this because you authored the thread.

Message ID: @.***>

sylefeb commented 1 year ago

Hi everyone, I have an issue that I think is related to this discussion, but otherwise I can open a different issue, let me know.

Using openFPGALoader openFPGALoader v0.10.0 under MinGW.

On two ULX3S using the W25Q128JV flash chips, after programming the flash with openFPGALoader (-f option), the flash is no longer accessible.

The first programming went well with openFPGALoader recognizing the flash as the correct chip. On second programming and since then I get:

$ ./openFPGALoader.exe -f -b ulx3s ~/Silice/projects/blinky/BUILD_ulx3s/build.bit
write to flash
Jtag probe limited to 3MHz
Jtag frequency : requested 6000000Hz -> real 3000000Hz
ret 0
Open file DONE
Parse file DONE
Enable configuration: DONE
SRAM erase: DONE
Detail:
Jedec ID          : ff
memory type       : ff
memory capacity   : ff
EDID + CFD length : ff
EDID              : ffff
CFD               :
flash chip unknown: use basic protection detection
unlock blocks
Error: block protection is set
       can't unlock without --unprotect-flash
Enable configuration: DONE
SRAM erase: DONE
Detail:
Jedec ID          : ff
memory type       : ff
memory capacity   : ff
EDID + CFD length : ff
EDID              : ffff
CFD               :
Skip resetting device
Refresh: DONE
Flash is blank
Error: Failed to program FPGA: std::exception

The --unprotect-flash does not work either (showing only relevant exert):

flash chip unknown: use basic protection detection
unlock blocks
timeout: ff ff 1000
ff
wait: Error

I also tried with fujprog to no avail:

$ fujprog -j flash ~/Silice/projects/blinky/BUILD_ulx3s/build.bit
ULX2S / ULX3S JTAG programmer v4.8 (git cc3ea93 built May 10 2023 19:51:22)
Copyright (C) Marko Zec, EMARD, gojimmypi, kost and contributors
Using USB cable: ULX3S FPGA 85K v3.0.8
Erasing sectors, please wait.
Programming: 0% - Received and expected data do not match!
TDO: C100 Expected: 4000 mask: C100
Line 32: Operation not permitted

Failed.

I usually programmed the flash with fujprog and it has always worked on both boards before, but I don't think I had tried with openFPGAloader until now. SRAM programming still works fine.

The flash seems no longer accessible. Problem is, I don't know how to resurrect it. Read through this issue (this is why I tried --unprotect-flash) but could not find a fix for this particular problem. Suggestions welcome - thanks!

[edit] I should precise that the design I flashed is itself using the flash and setting it up in QSPI mode, could this interfere? (unsure whether I flashed it with fujprog before).

trabucayre commented 1 year ago

My first idea is, indeed an conflict between gateware currently used and ECP5's state. Maybe SPI pins are configured as simple GPIO and, consequenctly, can't be used by internal jtag<->spi controler.

I have tested with my ULX3S with a blink in both SRAM and FLASH and can't reproduce your situation.

sylefeb commented 1 year ago

Thanks for the tests! So very likely something wrong with my gateware preventing reprog through JTAG (and indeed the SPIflash is no longer enumerated properly, if I understand the logs).

I do use SPI through a USRMCLK for the clock, running 50MHz. Otherwise nothing fancy. I did have similar issues in the past with QSPI, eg. with iceprog due to the flash staying in this mode, so that is a good suspect.

However I checked the code and I believe openFPGAloader SPI reset (with FF) should reset QSPI (which is otherwise enabled by 38h from the gateware). Also the gateware still does read properly (it sends over UART and I get the correct bytes). I also tried to flash over SRAM with a gateware resetting QSPI, and a gateware not using SPIflash, no change so far. I'll try something that powers it down next [edit: done, no change].

@emard Is there a way I could prevent the FPGA to configure from the current bitstream in SPIflash on power up?

Unsure for the ESP32, I do not use it at all (always only used the fpga). Could its state have been changed by openFPGAloader?

Thanks!

trabucayre commented 1 year ago

For icebreaker I have seen this issue, and reset sequence seems not reverting behaviour... I don't remember exactly but ESP32 must be disabled to avoid this one keep SPI flash?

trabucayre commented 1 year ago

I'm wrong: ESP32 is connected to SD slot not to the SPI flash

sylefeb commented 1 year ago

I feel this is due to QPI staying on, and it seems my attempts at disabling it are failing so far (while the simulation model from Winbond recognizes my end QPI commands). I'll keep trying -- also ordered a programming clip just in case. I'll send my results (but if anyone knows a way to prevent the FPGA from reading the flash -- like the CRESET jumper on the icebreaker -- please let me know :) ). Thanks!

trabucayre commented 1 year ago

Maybe you can try to apply 3.3V (or to shunt) R30 to force CS high -> EPC5 will not be able to receive configuration from SPI flash. Unfortunately I'm not sure there is something equivalent to CRESET (programming flash for ICE40 doesn't need to pass through FPGA).

Another idea: clearing first sectors (or the full FLASH) by using a gateware with a uC (or something like that).

emard commented 1 year ago

HI

I think flash SPI is alone depending only on JTAG, no other hardware state can interfere, so not ESP32 neither user bitstream can affect flash SPI interface.

ECP5 has factory internal bridge for SPI flash that works over its JTAG and it works regardless of what user has loaded. So if JTAG works for other things like programming FPGA it should work for SPI too.

However flash chip can be in some state, either temporary by already using it from user bitstream or permanently by writing something to its flash memory. Probaby in most cases it should be able to resurrect it, in worst case it's relatively easy to unsolder 8 pins and place new chip. I think nobody yet bricked it but Goran will help you even in this case

Of course problem can be that SPI flash chip has locked itself. I have some tools in ulx3s-bin ecp5wp.py that could be tried to unlock the flash using esp32, although it's quite cumbersome

this tool probably needs newer passthru from dfu (esp32 needs a user bitstream to access spi flash, otherwise it couldn't) - for v3.1.7 and later try https://github.com/emard/ulx3s-bin/tree/master/fpga/dfu/85f-v317 or 85f-v20 for v3.0.x boards

On Mon, Jun 26, 2023 at 7:41 AM Gwenhael Goavec-Merou < @.***> wrote:

Maybe you can try to apply 3.3V (or to shunt) R30 to force CS high -> EPC5 will not be able to receive configuration from SPI flash. Unfortunately I'm not sure there is something equivalent to CRESET (programming flash for ICE40 doesn't need to pass through FPGA).

Another idea: clearing first sectors (or the full FLASH) by using a gateware with a uC (or something like that).

— Reply to this email directly, view it on GitHub https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1606689416, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4K2R3DG4VT5IOUYUJTOTTXNEOKDANCNFSM5FICSZSA . You are receiving this because you were mentioned.Message ID: @.***>

emard commented 1 year ago

here is the small esp32 tool that I used to remove write protection from SPI flash chips on ulx3s boards before openFPGAloader made support for the chips

https://github.com/emard/esp32ecp5/blob/master/ecp5wp.py

On Mon, Jun 26, 2023 at 10:31 AM D EMARD @.***> wrote:

HI

I think flash SPI is alone depending only on JTAG, no other hardware state can interfere, so not ESP32 neither user bitstream can affect flash SPI interface.

ECP5 has factory internal bridge for SPI flash that works over its JTAG and it works regardless of what user has loaded. So if JTAG works for other things like programming FPGA it should work for SPI too.

However flash chip can be in some state, either temporary by already using it from user bitstream or permanently by writing something to its flash memory. Probaby in most cases it should be able to resurrect it, in worst case it's relatively easy to unsolder 8 pins and place new chip. I think nobody yet bricked it but Goran will help you even in this case

Of course problem can be that SPI flash chip has locked itself. I have some tools in ulx3s-bin ecp5wp.py that could be tried to unlock the flash using esp32, although it's quite cumbersome

this tool probably needs newer passthru from dfu (esp32 needs a user bitstream to access spi flash, otherwise it couldn't) - for v3.1.7 and later try https://github.com/emard/ulx3s-bin/tree/master/fpga/dfu/85f-v317 or 85f-v20 for v3.0.x boards

On Mon, Jun 26, 2023 at 7:41 AM Gwenhael Goavec-Merou < @.***> wrote:

Maybe you can try to apply 3.3V (or to shunt) R30 to force CS high -> EPC5 will not be able to receive configuration from SPI flash. Unfortunately I'm not sure there is something equivalent to CRESET (programming flash for ICE40 doesn't need to pass through FPGA).

Another idea: clearing first sectors (or the full FLASH) by using a gateware with a uC (or something like that).

— Reply to this email directly, view it on GitHub https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1606689416, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4K2R3DG4VT5IOUYUJTOTTXNEOKDANCNFSM5FICSZSA . You are receiving this because you were mentioned.Message ID: @.***>

sylefeb commented 1 year ago

Thanks @trabucayre and @emard for the help. I had access to a third board today for testing, and I think it confirms the problem has nothing to do with openFPGALoader and is solely due to my gateware. I have two designs that read from SPIflash and send the data through UART, one using SPI, the other QSPI.

So the flash is stuck in QSPI and I can't seem to be able to exit it, I guess I have to spend more time in the datasheet ;) Thanks for the help, I'll try to find a 'soft' way to resolve this, otherwise I'll use a more aggressive approach. I'll report results for completeness but I am now confident this is absolutely not an issue with openFPGALoader.

emard commented 1 year ago

I know, this QSPI is annoyying, if you want to prevent booting from flash, carefully stick small screwdriver between 2 flash pins to spoil initial communication at power up and then remove screwdriver and reflash it normally

It is also possible to remove running bitstream from JTAG by issuing some JTAG commands and wait faw ms to become effective

openFPGALoader maybe misses this initialization so flash appears like unreflashable when containing QSPI capable bitstream

I forgot to mention, if ESP32 is operable and actually flash chip hasn't been locked but in QSPI mode, you can try reflashing using ESP32 micropython tools (from ecp5esp32, tools should be already in ESP32 as factory default shipped on every newer board)

On 6/26/23, sylefeb @.***> wrote:

Thanks @trabucayre and @emard for the help. I had access to a third board today for testing, and I think it confirms the problem has nothing to do with openFPGALoader and is solely due to my gateware. I have two designs that read from SPIflash and send the data through UART, one using SPI, the other QSPI.

  • If after power-up I program (through SRAM) the SPI design it works just fine.
  • If after power-up I program (through SRAM) the QSPI design it works just fine, but if I next program (without cutting power) the SPI design it no longer works and reports only 'FF'. This exactly matches what happens on the flashed boards: QSPI reads work, but any normal SPI read reports FF.

So the flash is stuck in QSPI and I can't seem to be able to exit it, I guess I have to spend more time in the datasheet ;) Thanks for the help, I'll try to find a 'soft' way to resolve this, otherwise I'll use a more aggressive approach. I'll report results for completeness but I am now confident this is absolutely not an issue with openFPGALoader.

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1608034888 You are receiving this because you were mentioned.

Message ID: @.***>

trabucayre commented 1 year ago

Thanks @sylefeb and @emard ! Yes QSPI is annoyying. I have to look to the datasheet to check if it's possible using only 2 wires to reconfigure flash in SPI mode when openFPGALoader is unable to detect device (a sort of tryBeforeFail approach). ECP5's internal Flash access controller is not really documented so I'm not sure to be able to have access to the QSPI. Maybe a small note, in FAQ section, may relevant.

emard commented 1 year ago

Hmmm you have right, the ECP5-JTAG bridge for flash programming (i think) does only simple SPI MOSI/MISO/CLK signaling. Programming is in all vendor tools done like this and then FPGA when loading starts and SPI and if bitstream contains some additional command then it transitions to QSPI for faster loading and probably leaves flash chip in QSPI mode.

Maybe there is some flash SPI default reset command that would work the same from both spi and qspi mode, it would be sent from JTAG bridge normally. but if flash chip needs some special reset sequence outside of SPI standard then still we need some info about JTAG-ECP5 bridge commands

I guess something must be there otherwise once QSPI bitstream loads, it would be practically be bricked but we experience that even from QSPI mode and few retries, fujprog or openFPGALoader can reflash it again

documentation

On Tue, Jun 27, 2023 at 7:47 AM Gwenhael Goavec-Merou < @.***> wrote:

Thanks @sylefeb https://github.com/sylefeb and @emard https://github.com/emard ! Yes QSPI is annoyying. I have to look to the datasheet to check if it's possible using only 2 wires to reconfigure flash in SPI mode when openFPGALoader is unable to detect device (a sort of tryBeforeFail approach). ECP5's internal Flash access controller is not really documented so I'm not sure to be able to have access to the QSPI. Maybe a small note, in FAQ section, may relevant.

— Reply to this email directly, view it on GitHub https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1608836992, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4K2RYJTEZTUYE5LIOCUFDXNJXYJANCNFSM5FICSZSA . You are receiving this because you were mentioned.Message ID: @.***>

trabucayre commented 1 year ago

QPIDI (QSPI mode disabling) can't be sent in SPI mode: it's not the good way But it may be possible to reset device to default state (non-volatile confiiguration) using RSTEN followed by RST @sylefeb could you try to adapt openFPGALoader with this modification:

diff --git a/src/spiFlash.cpp b/src/spiFlash.cpp
index e97cc6c..5d30708 100644
--- a/src/spiFlash.cpp
+++ b/src/spiFlash.cpp
@@ -73,6 +73,9 @@
 /* */
 #define FLASH_WRVECR   0x61
 #define FLASH_RDVECR   0x65
+/* reset-enable + reset */
+#define FLASH_RSTEN   0x66
+#define FLASH_RST      0x99

 /* microchip SST26VF032B / SST26VF032BA */
 /* Read Block Protection Register */
@@ -500,6 +503,8 @@ void SPIFlash::reset()
        uint8_t data[8];
        memset(data, 0xff, 8);
        _spi->spi_put(0xff, data, NULL, 8);
+       _spi->spi_put(FLASH_RSTEN, NULL, NULL, 0);
+       _spi->spi_put(FLASH_RST, NULL, NULL, 0);
 }

 void SPIFlash::read_id()

If it's works I have to check if this sequence is also supported by others (all) chip to have a real/efficient reset sequence.

sylefeb commented 1 year ago

@trabucayre Thanks! just tried but the issue remains. I had actually tried from a design to send 66h, 99h, but that did not work, not even sending as QSPI (the simulation model says these are not QSPI commands, so likely only works in SPI

[edit] I likely got confused as the datasheet for W25Q128FV and the simulation model code seems to indicate reset is supported in QSPI, see messages below).

My understanding of the datasheet is that FFh has to be send as a QSPI command once QSPI enabled with 38h, but that did not work for me either. I am thinking this might be due to using the continuous read mode, I'm investigating further tonight. (@emard, very interesting that the FPGA can load in QSPI too, I'm also convinced there has to be a software way to resolve this ...).

sylefeb commented 1 year ago

Some progress: while I still could not produce a bitstream that would properly exit QSPI/continuous read (even though the simulation model from Winbond happily accepts my commands and exits QSPI ...), I was able to "resurrect" one board taking @trabucayre suggestion of physically preventing configuration. I shorted CS and IO1 as they are neighboring and it seemed safe enough.

It worked!

This board is back to normal, flash is detected as before. So this really is an issue with QSPI. I'll run tests to see if this is due to QSPI mode (38h) or to the continuous read mode with EBh. [edit: both boards are back to normal]

sylefeb commented 1 year ago

So I can confirm that:

A 'safe' way to test is simply to program a design enabling QSPI (38h) in SRAM and then try to program the flash (e.g. with a blinky). Programming the flash then fails.

I am somewhat puzzled that I cannot exit QSPI as per datasheet ... and unfortunately it is faster to enable QSPI and then use EBh as some dummy cycles can be skipped...

trabucayre commented 1 year ago

Just checked correct datasheet (W25Q) instead of IL25LP. This datasheet is more clear with chrono. In p.79 section 8.2.43 the reset sequence uses 4 pins when chip is in QPI: to force flash switching to SPI... the flash must be already in SPI mode. In fact without a screwdriver or a specific bitstream dedicated to switch the flash in SPI mode I don't see how to revert.

Idea: Maybe using the DFU bootloader: it has access to flash directly.

emard commented 1 year ago

Of course, DFU bitstream is recommended (and should be factory default on new boards) Flashing is much faster with DFU and should have no problems with QSPI, at least because user can power off/on board, then will multiboot run DFU bitstream first and then checks if it should transition to user's bitstream which is second in multiboot chain

On 6/28/23, Gwenhael Goavec-Merou @.***> wrote:

Just checked correct datasheet (W25Q) instead of IL25LP. This datasheet is more clear with chrono. In p.79 section 8.2.43 the reset sequence uses 4 pins when chip is in QPI: to force flash switching to SPI... the flash must be already in SPI mode. In fact without a screwdriver or a specific bitstream dedicated to switch the flash in SPI mode I don't see how to revert.

Idea: Maybe using the DFU bootloader: it has access to flash directly.

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1610728620 You are receiving this because you were mentioned.

Message ID: @.***>

sylefeb commented 1 year ago

In p.79 section 8.2.43 the reset sequence uses 4 pins when chip is in QSPI:

It's promising that table 57b gives the reset sequence for QSPI. I'll give it another try! (I somehow got confused last I tried that these were not supported in QSPI).

DFU and should have no problems with QSPI

Good point ; I'll also make sure that my designs do not enable QSPI before a sufficient delay to allow re-flashing.

trabucayre commented 1 year ago

Yes DFU is a good solution to simplify programming (and this protocol is also supported by openFPGALoader) and to avoid to take care about flash mode.

In fact this issue is a real problem. Most of the case I only use SPI mode (with internal controler or with spiOverJtag). It seems not possible to access flash (or to reset in) when the chip is in QSPI mode without using QSPI communication. A real solution must be found at openFPGALoader level to deal with this situation.

emard commented 1 year ago

I agree we have to experiment more on this, make bitstream QSPI and try to reflash it somehow

I tried something with esp32ecp5 code, got inspiration from .svf code generated by fujprog and diamond

In schematics, there are pull up resistors at flash which have specified values in datasheet, some are 10k some 15k I think it doesn't matter so I tried without pullups, then didn't work so I placed 15k worked somehow but QSPI refashing was really difficult, having there proper values of pullups as specified, situation about QSPI has much improved but obviously it's still not ideal

On 6/28/23, Gwenhael Goavec-Merou @.***> wrote:

Yes DFU is a good solution to simplify programming (and this protocol is also supported by openFPGALoader) and to avoid to take care about flash mode.

In fact this issue is a real problem. Most of the case I only use SPI mode (with internal controler or with spiOverJtag). It seems not possible to access flash (or to reset in) when the chip is in QSPI mode without using QSPI communication. A real solution must be found at openFPGALoader level to deal with this situation.

-- Reply to this email directly or view it on GitHub: https://github.com/trabucayre/openFPGALoader/issues/124#issuecomment-1611022098 You are receiving this because you were mentioned.

Message ID: @.***>

sylefeb commented 1 year ago

At least one mystery solved: I can now exit QSPI from a gateware. I had a timing bug on CS, on ECP5 + flash only (special path through USRMCLK...). That apparently would not affect reading at this frequency (50 MHz), but did affect the exit QSPI that is FFh on two cycles (worse, my sim was not reflecting this). So I first send FFh on 8 clocks to exit continuous read, then FFh on 2 clocks to exit QSPI.

(From QSPI enabled with 38h and continuous read enabled from EBh) image

However, this exit QSPI is done from QSPI mode. I did not see a way from simple SPI...