Easy @Utkk it’s pretty simple with a single CLI command. See file riscv.mk shown in Demonstrating AMO
make -f riscv.mk [romload | romrun | romdebug]
Discussion in more detail is at Demystifying OpenOCD
Basically, you define a bank item for each Flash device and/or memory range. You can use any name you wish, spi0 is a good choice. You can have as many banks as you want.
The SPI peripheral base address which is wired to the Flash memory is 0x10014000, and the Flash memory device is mapped at address 0x20000000, both are constants specified in the Data Sheet and User Manual for the FE310 SoC of the HiFive 1 Rev B board.
flash bank spi0 fespi 0x20000000 0 0 0 riscv.cpu.0 0x10014000
It’s a five-step procedure to write the Flash memory: First, turn off the write protection for the sector(s) you will write; then erase the desired sector(s); followed by writing and verifying those sectors; lastly and optionally turn on the write protection.
flash protect 0 0 4 off
flash erase_sector 0 0 4
flash write_bank 0 filename
flash verify_bank 0 filename
flash protect 0 0 4 on
The two numbers {0, 4} above are the beginning and ending sector numbers of the Flash memory. Computing them for desired length of filename is a little tricky, to do a proper integer-based calculation. The number 4 the example steps is ENDSEC below; the number 0 in the example is trivial, starting from beginning of Flash memory.
In tcl script, for use in openocd files:
set secsz [expr 0x1000] ;# 4K sectors issi is25lp128d, typ. most NOR flash
set len [file size filename]
set endsec [expr (${len}/${secsz})+((${len}-(${len}/${secsz})*${secsz})>0)-1]
In /bin/bash script, for use in, e.g., make files:
$(eval SECSZ=$(shell echo "ibase=16; 1000" | bc))
$(eval LEN=$(shell <filename wc -c))
$(eval ENDSEC=$(shell echo "(${LEN}/${SECSZ})+((${LEN}-(${LEN}/${SECSZ})*${SECSZ})>0)-1" | bc))
Where SECSZ for the issi is25lp128d Flash memory chip is 4K, or 0x1000 bytes. It is also defined in …src/flash/nor/core.h:45 of the openocd library.