altera: uses --flash-sector to only update a subset of internal flash sectors
This commit is contained in:
parent
719697eabe
commit
414a7259f0
|
|
@ -89,7 +89,7 @@ openFPGALoader -- a program to flash FPGA
|
||||||
with dump-flash
|
with dump-flash
|
||||||
--file-type arg provides file type instead of let's deduced
|
--file-type arg provides file type instead of let's deduced
|
||||||
by using extension
|
by using extension
|
||||||
--flash-sector arg flash sector (Lattice parts only)
|
--flash-sector arg flash sector (Lattice and Altera MAX10 parts only)
|
||||||
--fpga-part arg fpga model flavor + package
|
--fpga-part arg fpga model flavor + package
|
||||||
--freq arg jtag frequency (Hz)
|
--freq arg jtag frequency (Hz)
|
||||||
-f, --write-flash write bitstream in flash (default: false)
|
-f, --write-flash write bitstream in flash (default: false)
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,14 @@ Altera::Altera(Jtag *jtag, const std::string &filename,
|
||||||
const std::string &file_type, Device::prog_type_t prg_type,
|
const std::string &file_type, Device::prog_type_t prg_type,
|
||||||
const std::string &device_package,
|
const std::string &device_package,
|
||||||
const std::string &spiOverJtagPath, bool verify, int8_t verbose,
|
const std::string &spiOverJtagPath, bool verify, int8_t verbose,
|
||||||
|
const std::string &flash_sectors,
|
||||||
bool skip_load_bridge, bool skip_reset):
|
bool skip_load_bridge, bool skip_reset):
|
||||||
Device(jtag, filename, file_type, verify, verbose),
|
Device(jtag, filename, file_type, verify, verbose),
|
||||||
SPIInterface(filename, verbose, 256, verify, skip_load_bridge,
|
SPIInterface(filename, verbose, 256, verify, skip_load_bridge,
|
||||||
skip_reset),
|
skip_reset),
|
||||||
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath),
|
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath),
|
||||||
_vir_addr(0x1000), _vir_length(14), _clk_period(1)
|
_vir_addr(0x1000), _vir_length(14), _clk_period(1),
|
||||||
|
_flash_sectors(flash_sectors)
|
||||||
{
|
{
|
||||||
/* check device family */
|
/* check device family */
|
||||||
_idcode = _jtag->get_target_device_id();
|
_idcode = _jtag->get_target_device_id();
|
||||||
|
|
@ -403,6 +405,7 @@ bool Altera::max10_program_ufm(const Altera::max10_mem_t *mem, unsigned int offs
|
||||||
void Altera::max10_program(unsigned int offset)
|
void Altera::max10_program(unsigned int offset)
|
||||||
{
|
{
|
||||||
uint32_t base_addr;
|
uint32_t base_addr;
|
||||||
|
uint8_t update_sectors;
|
||||||
|
|
||||||
/* Needs to have some specifics informations about internal flash size/organisation
|
/* Needs to have some specifics informations about internal flash size/organisation
|
||||||
* and some magics.
|
* and some magics.
|
||||||
|
|
@ -479,27 +482,54 @@ void Altera::max10_program(unsigned int offset)
|
||||||
const uint8_t *dsm_data = _bit.getData("ICB");
|
const uint8_t *dsm_data = _bit.getData("ICB");
|
||||||
const int dsm_len = _bit.getLength("ICB") / 32; // getLength (bits) dsm_len in 32bits word
|
const int dsm_len = _bit.getLength("ICB") / 32; // getLength (bits) dsm_len in 32bits word
|
||||||
|
|
||||||
|
/* Check for a full update or only for a subset */
|
||||||
|
if (_flash_sectors.size() > 0) {
|
||||||
|
const std::vector<std::string> sectors = splitString(_flash_sectors, ',');
|
||||||
|
update_sectors = 0;
|
||||||
|
for (const auto sector: sectors) {
|
||||||
|
if (sector == "UFM1")
|
||||||
|
update_sectors |= (1 << 0);
|
||||||
|
else if (sector == "UFM0")
|
||||||
|
update_sectors |= (1 << 1);
|
||||||
|
else if (sector == "CFM2")
|
||||||
|
update_sectors |= (1 << 2);
|
||||||
|
else if (sector == "CFM1")
|
||||||
|
update_sectors |= (1 << 3);
|
||||||
|
else if (sector == "CFM0")
|
||||||
|
update_sectors |= (1 << 4);
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Unknown sector " + sector);
|
||||||
|
}
|
||||||
|
} else { // full update
|
||||||
|
update_sectors = 0x1F;
|
||||||
|
}
|
||||||
|
|
||||||
// Start!
|
// Start!
|
||||||
max10_flow_enable();
|
max10_flow_enable();
|
||||||
|
|
||||||
max10_flow_erase(&mem, 0x1F);
|
max10_flow_erase(&mem, update_sectors);
|
||||||
max10_dsm_verify();
|
if (update_sectors == 0x1f)
|
||||||
|
max10_dsm_verify();
|
||||||
|
|
||||||
/* Write */
|
/* Write */
|
||||||
|
|
||||||
// UFM 1 -> 0
|
// UFM 1 -> 0
|
||||||
base_addr = mem.ufm_addr;
|
base_addr = mem.ufm_addr;
|
||||||
for (int i = 1; i >= 0; i--) {
|
for (int i = 1; i >= 0; i--) {
|
||||||
printInfo("Write UFM" + std::to_string(i));
|
if (update_sectors & (1 << i)) {
|
||||||
writeXFM(ufm_data[i], base_addr, 0, mem.ufm_len[i]);
|
printInfo("Write UFM" + std::to_string(i));
|
||||||
|
writeXFM(ufm_data[i], base_addr, 0, mem.ufm_len[i]);
|
||||||
|
}
|
||||||
base_addr += mem.ufm_len[i];
|
base_addr += mem.ufm_len[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFM2 -> 0
|
// CFM2 -> 0
|
||||||
base_addr = mem.cfm_addr;
|
base_addr = mem.cfm_addr;
|
||||||
for (int i = 2; i >= 0; i--) {
|
for (int i = 2; i >= 0; i--) {
|
||||||
printInfo("Write CFM" + std::to_string(i));
|
if (update_sectors & (1 << ((2 - i) + 2))) {
|
||||||
writeXFM(cfm_data[i], base_addr, 0, mem.cfm_len[i]);
|
printInfo("Write CFM" + std::to_string(i));
|
||||||
|
writeXFM(cfm_data[i], base_addr, 0, mem.cfm_len[i]);
|
||||||
|
}
|
||||||
base_addr += mem.cfm_len[i];
|
base_addr += mem.cfm_len[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,29 +538,35 @@ void Altera::max10_program(unsigned int offset)
|
||||||
// UFM 1 -> 0
|
// UFM 1 -> 0
|
||||||
base_addr = mem.ufm_addr;
|
base_addr = mem.ufm_addr;
|
||||||
for (int i = 1; i >= 0; i--) {
|
for (int i = 1; i >= 0; i--) {
|
||||||
printInfo("Verify UFM" + std::to_string(i));
|
if (update_sectors & (1 << i)) {
|
||||||
verifyxFM(ufm_data[i], base_addr, 0, mem.ufm_len[i]);
|
printInfo("Verify UFM" + std::to_string(i));
|
||||||
|
verifyxFM(ufm_data[i], base_addr, 0, mem.ufm_len[i]);
|
||||||
|
}
|
||||||
base_addr += mem.ufm_len[i];
|
base_addr += mem.ufm_len[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFM2->0
|
// CFM2->0
|
||||||
base_addr = mem.cfm_addr;
|
base_addr = mem.cfm_addr;
|
||||||
for (int i = 2; i >= 0; i--) {
|
for (int i = 2; i >= 0; i--) {
|
||||||
printInfo("Verify CFM" + std::to_string(i));
|
if (update_sectors & (1 << ((2 - i) + 2))) {
|
||||||
verifyxFM(cfm_data[i], base_addr, 0, mem.cfm_len[i]);
|
printInfo("Verify CFM" + std::to_string(i));
|
||||||
|
verifyxFM(cfm_data[i], base_addr, 0, mem.cfm_len[i]);
|
||||||
|
}
|
||||||
base_addr += mem.cfm_len[i];
|
base_addr += mem.cfm_len[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DSM
|
// DSM
|
||||||
|
|
||||||
max10_dsm_program(dsm_data, dsm_len);
|
if (update_sectors == 0x1F) {
|
||||||
max10_dsm_verify();
|
max10_dsm_program(dsm_data, dsm_len);
|
||||||
|
max10_dsm_verify();
|
||||||
|
|
||||||
max10_flow_program_donebit(mem.done_bit_addr);
|
max10_flow_program_donebit(mem.done_bit_addr);
|
||||||
max10_dsm_verify();
|
max10_dsm_verify();
|
||||||
max10_dsm_program_success(mem.pgm_success_addr);
|
max10_dsm_program_success(mem.pgm_success_addr);
|
||||||
max10_dsm_verify();
|
max10_dsm_verify();
|
||||||
|
}
|
||||||
|
|
||||||
/* disable ISC flow */
|
/* disable ISC flow */
|
||||||
max10_flow_disable();
|
max10_flow_disable();
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class Altera: public Device, SPIInterface {
|
||||||
const std::string &device_package,
|
const std::string &device_package,
|
||||||
const std::string &spiOverJtagPath,
|
const std::string &spiOverJtagPath,
|
||||||
bool verify, int8_t verbose,
|
bool verify, int8_t verbose,
|
||||||
|
const std::string &flash_sectors,
|
||||||
bool skip_load_bridge, bool skip_reset);
|
bool skip_load_bridge, bool skip_reset);
|
||||||
~Altera();
|
~Altera();
|
||||||
|
|
||||||
|
|
@ -152,6 +153,7 @@ class Altera: public Device, SPIInterface {
|
||||||
|
|
||||||
altera_family_t _fpga_family;
|
altera_family_t _fpga_family;
|
||||||
uint32_t _idcode;
|
uint32_t _idcode;
|
||||||
|
std::string _flash_sectors; /**< MAX10 Only: list of sectors to erase/write */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SRC_ALTERA_HPP_
|
#endif // SRC_ALTERA_HPP_
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include "board.hpp"
|
#include "board.hpp"
|
||||||
#include "cable.hpp"
|
#include "cable.hpp"
|
||||||
#include "colognechip.hpp"
|
#include "colognechip.hpp"
|
||||||
|
#include "common.hpp"
|
||||||
#include "cxxopts.hpp"
|
#include "cxxopts.hpp"
|
||||||
#include "device.hpp"
|
#include "device.hpp"
|
||||||
#include "dfu.hpp"
|
#include "dfu.hpp"
|
||||||
|
|
@ -141,6 +142,7 @@ int main(int argc, char **argv)
|
||||||
printError("Error in parse arg step");
|
printError("Error in parse arg step");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
printf("sectors: %s\n", args.flash_sector.c_str());
|
||||||
|
|
||||||
if (args.is_list_command) {
|
if (args.is_list_command) {
|
||||||
displaySupported(args);
|
displaySupported(args);
|
||||||
|
|
@ -574,7 +576,7 @@ int main(int argc, char **argv)
|
||||||
} else if (fab == "altera") {
|
} else if (fab == "altera") {
|
||||||
fpga = new Altera(jtag, args.bit_file, args.file_type,
|
fpga = new Altera(jtag, args.bit_file, args.file_type,
|
||||||
args.prg_type, args.fpga_part, args.bridge_path, args.verify,
|
args.prg_type, args.fpga_part, args.bridge_path, args.verify,
|
||||||
args.verbose, args.skip_load_bridge, args.skip_reset);
|
args.verbose, args.flash_sector, args.skip_load_bridge, args.skip_reset);
|
||||||
} else if (fab == "anlogic") {
|
} else if (fab == "anlogic") {
|
||||||
fpga = new Anlogic(jtag, args.bit_file, args.file_type,
|
fpga = new Anlogic(jtag, args.bit_file, args.file_type,
|
||||||
args.prg_type, args.verify, args.verbose);
|
args.prg_type, args.verify, args.verbose);
|
||||||
|
|
@ -808,7 +810,7 @@ int parse_opt(int argc, char **argv, struct arguments *args,
|
||||||
("file-type",
|
("file-type",
|
||||||
"provides file type instead of let's deduced by using extension",
|
"provides file type instead of let's deduced by using extension",
|
||||||
cxxopts::value<string>(args->file_type))
|
cxxopts::value<string>(args->file_type))
|
||||||
("flash-sector", "flash sector (Lattice parts only)",
|
("flash-sector", "flash sector (Lattice and Altera MAX10 parts only)",
|
||||||
cxxopts::value<string>(args->flash_sector))
|
cxxopts::value<string>(args->flash_sector))
|
||||||
("fpga-part", "fpga model flavor + package",
|
("fpga-part", "fpga model flavor + package",
|
||||||
cxxopts::value<string>(args->fpga_part))
|
cxxopts::value<string>(args->fpga_part))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue