Merge pull request #192 from rwhitby/bulk_erase_option

spiFlash: Add --bulk-erase command line option
This commit is contained in:
Gwenhael Goavec-Merou 2022-11-06 09:31:05 +01:00 committed by GitHub
commit 00a57576f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 106 additions and 6 deletions

View File

@ -57,6 +57,12 @@ class Altera: public Device, SPIInterface {
bool unprotect_flash() override {
return SPIInterface::unprotect_flash();
}
/*!
* \brief bulk erase SPI flash
*/
bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash();
}
int spi_put(uint8_t cmd, uint8_t *tx, uint8_t *rx,
uint32_t len) override;

View File

@ -40,6 +40,13 @@ class Anlogic: public Device, SPIInterface {
return SPIInterface::unprotect_flash();
}
/*!
* \brief bulk erase SPI flash
*/
bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash();
}
/*!
* \brief dump len byte from base_addr from SPI flash
* \param[in] base_addr: start offset

View File

@ -40,6 +40,8 @@ class CologneChip: public Device, SPIInterface {
printError("protect flash not supported"); return false;}
virtual bool unprotect_flash() override {
printError("unprotect flash not supported"); return false;}
virtual bool bulk_erase_flash() override {
printError("bulk erase flash not supported"); return false;}
void program(unsigned int offset, bool unprotect_flash) override;
int idCode() override {return 0;}

View File

@ -48,6 +48,7 @@ class Device {
printError("dump flash not supported"); return false;}
virtual bool protect_flash(uint32_t len) = 0;
virtual bool unprotect_flash() = 0;
virtual bool bulk_erase_flash() = 0;
virtual int idCode() = 0;
virtual void reset();

View File

@ -32,6 +32,8 @@ class Efinix: public Device {
printError("protect flash not supported"); return false;}
virtual bool unprotect_flash() override {
printError("unprotect flash not supported"); return false;}
virtual bool bulk_erase_flash() override {
printError("bulk erase flash not supported"); return false;}
/* not supported in SPI Active mode */
int idCode() override {return 0;}
void reset() override;

View File

@ -34,6 +34,8 @@ class Gowin: public Device, SPIInterface {
printError("protect flash not supported"); return false;}
virtual bool unprotect_flash() override {
printError("unprotect flash not supported"); return false;}
virtual bool bulk_erase_flash() override {
printError("bulk erase flash not supported"); return false;}
int spi_put(uint8_t cmd, uint8_t *tx, uint8_t *rx,
uint32_t len) override;
int spi_put(uint8_t *tx, uint8_t *rx, uint32_t len) override;

View File

@ -237,6 +237,26 @@ bool Ice40::unprotect_flash()
return post_flash_access();
}
bool Ice40::bulk_erase_flash()
{
/* SPI access */
prepare_flash_access();
/* acess */
try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose);
/* bulk erase flash */
if (flash.bulk_erase() == -1)
return false;
} catch (std::exception &e) {
printError("Fail");
printError(std::string(e.what()));
return false;
}
/* reload */
return post_flash_access();
}
bool Ice40::prepare_flash_access()
{
/* SPI access: shutdown ICE40 */

View File

@ -26,6 +26,7 @@ class Ice40: public Device, SPIInterface {
bool dumpFlash(uint32_t base_addr, uint32_t len) override;
bool protect_flash(uint32_t len) override;
bool unprotect_flash() override;
bool bulk_erase_flash() override;
/* not supported in SPI Active mode */
int idCode() override {return 0;}
void reset() override;

View File

@ -47,6 +47,12 @@ class Lattice: public Device, SPIInterface {
bool unprotect_flash() override {
return SPIInterface::unprotect_flash();
}
/*!
* \brief bulk erase SPI flash
*/
bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash();
}
/* spi interface */
int spi_put(uint8_t cmd, uint8_t *tx, uint8_t *rx,

View File

@ -74,6 +74,7 @@ struct arguments {
string ip_adr;
uint32_t protect_flash;
bool unprotect_flash;
bool bulk_erase_flash;
string flash_sector;
bool skip_load_bridge;
bool skip_reset;
@ -104,7 +105,7 @@ int main(int argc, char **argv)
false, false, "", "", "", -1, 0, false, -1,
/* vid, pid, index bus_addr, device_addr */
0, 0, -1, 0, 0,
"127.0.0.1", 0, false, "", false, false,
"127.0.0.1", 0, false, false, "", false, false,
/* xvc server */
false, 3721, "-",
"", false, // mcufw conmcu
@ -275,6 +276,9 @@ int main(int argc, char **argv)
if (args.unprotect_flash && args.bit_file.empty())
if (!target->unprotect_flash())
spi_ret = EXIT_FAILURE;
if (args.bulk_erase_flash && args.bit_file.empty())
if (!target->bulk_erase_flash())
spi_ret = EXIT_FAILURE;
if (args.protect_flash)
if (!target->protect_flash(args.protect_flash))
spi_ret = EXIT_FAILURE;
@ -326,6 +330,9 @@ int main(int argc, char **argv)
if (args.unprotect_flash && args.bit_file.empty())
if (!flash.disable_protection())
spi_ret = EXIT_FAILURE;
if (args.bulk_erase_flash && args.bit_file.empty())
if (!flash.bulk_erase())
spi_ret = EXIT_FAILURE;
if (args.protect_flash)
if (!flash.enable_protection(args.protect_flash))
spi_ret = EXIT_FAILURE;
@ -557,6 +564,11 @@ int main(int argc, char **argv)
fpga->unprotect_flash();
}
/* bulk erase SPI flash */
if (args.bulk_erase_flash && args.bit_file.empty()) {
fpga->bulk_erase_flash();
}
/* protect SPI flash */
if (args.protect_flash != 0) {
fpga->protect_flash(args.protect_flash);
@ -673,6 +685,8 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
cxxopts::value<bool>(args->detect))
("dfu", "DFU mode", cxxopts::value<bool>(args->dfu))
("dump-flash", "Dump flash mode")
("bulk-erase", "Bulk erase flash",
cxxopts::value<bool>(args->bulk_erase_flash))
("external-flash",
"select ext flash for device with internal and external storage",
cxxopts::value<bool>(args->external_flash))
@ -873,6 +887,7 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
!args->detect &&
!args->protect_flash &&
!args->unprotect_flash &&
!args->bulk_erase_flash &&
!args->xvc &&
!args->reset &&
!args->conmcu) {

View File

@ -79,7 +79,7 @@ SPIFlash::SPIFlash(SPIInterface *spi, bool unprotect, int8_t verbose):
int SPIFlash::bulk_erase()
{
int ret, ret2 = 0;
uint32_t timeout=100000;
uint32_t timeout=1000000;
uint8_t bp = get_bp();
if (bp != 0) {
if (!_unprotect) {
@ -96,7 +96,7 @@ int SPIFlash::bulk_erase()
return ret;
ret2 = _spi->spi_put(FLASH_CE, NULL, NULL, 0);
if (ret2 == 0)
ret2 = _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, timeout, true);
ret2 = _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, timeout);
if (bp != 0)
ret = enable_protection(bp);

View File

@ -39,8 +39,8 @@ bool SPIInterface::protect_flash(uint32_t len)
SPIFlash flash(this, false, _spif_verbose);
/* configure flash protection */
ret = flash.enable_protection(len) != 0;
if (ret != 0)
ret = (flash.enable_protection(len) == 0);
if (!ret)
printError("Fail");
else
printSuccess("Done");
@ -72,7 +72,7 @@ bool SPIInterface::unprotect_flash()
printInfo("unprotect_flash: ", false);
ret = (flash.disable_protection() == 0);
if (!ret)
printError("Fail " + std::to_string(ret));
printError("Fail");
else
printSuccess("Done");
} catch (std::exception &e) {
@ -85,6 +85,37 @@ bool SPIInterface::unprotect_flash()
return post_flash_access() && ret;
}
bool SPIInterface::bulk_erase_flash()
{
bool ret = true;
printInfo("bulk_erase: ", false);
/* move device to spi access */
if (!prepare_flash_access()) {
printError("Fail");
return false;
}
/* spi flash access */
try {
SPIFlash flash(this, false, _spif_verbose);
/* bulk erase flash */
ret = (flash.bulk_erase() == 0);
if (!ret)
printError("Fail");
else
printSuccess("Done");
} catch (std::exception &e) {
printError("Fail");
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret;
}
bool SPIInterface::write(uint32_t offset, uint8_t *data, uint32_t len,
bool unprotect_flash)
{

View File

@ -26,6 +26,7 @@ class SPIInterface {
bool protect_flash(uint32_t len);
bool unprotect_flash();
bool bulk_erase_flash();
/*!
* \brief write len byte into flash starting at offset,
* optionnally verify after write and unprotect

View File

@ -40,6 +40,12 @@ class Xilinx: public Device, SPIInterface {
bool unprotect_flash() override {
return SPIInterface::unprotect_flash();
}
/*!
* \brief erase SPI flash blocks
*/
bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash();
}
int idCode() override;
void reset() override;