xilinx: add dumpFlash support
This commit is contained in:
parent
2af64e9af4
commit
d32b81037a
|
|
@ -21,7 +21,9 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
||||||
Device(jtag, filename, file_type, verify, verbose),
|
Device(jtag, filename, file_type, verify, verbose),
|
||||||
_device_package(device_package)
|
_device_package(device_package)
|
||||||
{
|
{
|
||||||
if (!_file_extension.empty()) {
|
if (prg_type == Device::RD_FLASH) {
|
||||||
|
_mode = Device::READ_MODE;
|
||||||
|
} else if (!_file_extension.empty()) {
|
||||||
if (_file_extension == "mcs") {
|
if (_file_extension == "mcs") {
|
||||||
_mode = Device::SPI_MODE;
|
_mode = Device::SPI_MODE;
|
||||||
} else if (_file_extension == "bit" || _file_extension == "bin") {
|
} else if (_file_extension == "bit" || _file_extension == "bin") {
|
||||||
|
|
@ -81,7 +83,7 @@ void Xilinx::program(unsigned int offset)
|
||||||
bool reverse = false;
|
bool reverse = false;
|
||||||
|
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
if (_mode == Device::NONE_MODE)
|
if (_mode == Device::NONE_MODE || _mode == Device::READ_MODE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_mode == Device::MEM_MODE)
|
if (_mode == Device::MEM_MODE)
|
||||||
|
|
@ -124,11 +126,11 @@ void Xilinx::program(unsigned int offset)
|
||||||
delete bit;
|
delete bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Xilinx::program_spi(ConfigBitstreamParser * bit, unsigned int offset)
|
bool Xilinx::load_bridge()
|
||||||
{
|
{
|
||||||
if (_device_package.empty()) {
|
if (_device_package.empty()) {
|
||||||
printError("Can't program SPI flash: missing device-package information");
|
printError("Can't program SPI flash: missing device-package information");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DATA_DIR is defined at compile time.
|
// DATA_DIR is defined at compile time.
|
||||||
|
|
@ -146,6 +148,14 @@ void Xilinx::program_spi(ConfigBitstreamParser * bit, unsigned int offset)
|
||||||
printError(e.what());
|
printError(e.what());
|
||||||
throw std::runtime_error(e.what());
|
throw std::runtime_error(e.what());
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xilinx::program_spi(ConfigBitstreamParser * bit, unsigned int offset)
|
||||||
|
{
|
||||||
|
/* first need to have bridge in RAM */
|
||||||
|
if (load_bridge() == false)
|
||||||
|
return;
|
||||||
|
|
||||||
uint8_t *data = bit->getData();
|
uint8_t *data = bit->getData();
|
||||||
int length = bit->getLength() / 8;
|
int length = bit->getLength() / 8;
|
||||||
|
|
@ -296,6 +306,54 @@ void Xilinx::program_mem(ConfigBitstreamParser *bitfile)
|
||||||
_jtag->go_test_logic_reset();
|
_jtag->go_test_logic_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Xilinx::dumpFlash(const std::string &filename,
|
||||||
|
uint32_t base_addr, uint32_t len)
|
||||||
|
{
|
||||||
|
/* first need to have bridge in RAM */
|
||||||
|
if (load_bridge() == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* prepare SPI access */
|
||||||
|
SPIFlash flash(this, _verbose);
|
||||||
|
flash.reset();
|
||||||
|
flash.read_id();
|
||||||
|
flash.read_status_reg();
|
||||||
|
|
||||||
|
FILE *fd = fopen(filename.c_str(), "wb");
|
||||||
|
if (!fd) {
|
||||||
|
printError("Open dump file failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rd_length = 256;
|
||||||
|
std::string data;
|
||||||
|
data.resize(rd_length);
|
||||||
|
|
||||||
|
ProgressBar progress("Dump flash", len, 50, _quiet);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < len; i+=rd_length) {
|
||||||
|
if (rd_length + i > len)
|
||||||
|
rd_length = len - i;
|
||||||
|
if (0 != flash.read(base_addr + i, (uint8_t*)&data[0],
|
||||||
|
rd_length)) {
|
||||||
|
progress.fail();
|
||||||
|
printError("Failed to read flash");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(data.c_str(), sizeof(uint8_t), rd_length, fd);
|
||||||
|
|
||||||
|
progress.display(i);
|
||||||
|
}
|
||||||
|
progress.done();
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
/* reset device */
|
||||||
|
reset();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* jtag : jtag interface
|
* jtag : jtag interface
|
||||||
* cmd : opcode for SPI flash
|
* cmd : opcode for SPI flash
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ class Xilinx: public Device, SPIInterface {
|
||||||
void program(unsigned int offset = 0) override;
|
void program(unsigned int offset = 0) override;
|
||||||
void program_spi(ConfigBitstreamParser * bit, unsigned int offset = 0);
|
void program_spi(ConfigBitstreamParser * bit, unsigned int offset = 0);
|
||||||
void program_mem(ConfigBitstreamParser *bitfile);
|
void program_mem(ConfigBitstreamParser *bitfile);
|
||||||
|
bool dumpFlash(const std::string &filename,
|
||||||
|
uint32_t base_addr, uint32_t len);
|
||||||
int idCode() override;
|
int idCode() override;
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
|
|
@ -31,6 +33,12 @@ class Xilinx: public Device, SPIInterface {
|
||||||
uint32_t timeout, bool verbose = false) override;
|
uint32_t timeout, bool verbose = false) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*!
|
||||||
|
* \brief with xilinx devices SPI flash direct access is not possible
|
||||||
|
* so a bridge must be loaded in RAM to access flash
|
||||||
|
* \return false if missing device mode, true otherwise
|
||||||
|
*/
|
||||||
|
bool load_bridge();
|
||||||
std::string _device_package;
|
std::string _device_package;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue