aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--COPYING13
-rw-r--r--icepack/icepack.cc85
-rw-r--r--iceprog/iceprog.c62
3 files changed, 120 insertions, 40 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..a01b7b6
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,13 @@
+Copyright (C) 2012 - 2017 Clifford Wolf <clifford@clifford.at>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/icepack/icepack.cc b/icepack/icepack.cc
index b67241f..ac3e8c6 100644
--- a/icepack/icepack.cc
+++ b/icepack/icepack.cc
@@ -98,6 +98,7 @@ struct FpgaConfig
{
string device;
string freqrange;
+ string nosleep;
string warmboot;
// cram[BANK][X][Y]
@@ -116,7 +117,7 @@ struct FpgaConfig
void write_bits(std::ostream &ofs) const;
// icebox i/o
- void read_ascii(std::istream &ifs);
+ void read_ascii(std::istream &ifs, bool nosleep);
void write_ascii(std::ostream &ofs) const;
// netpbm i/o
@@ -376,13 +377,28 @@ void FpgaConfig::read_bits(std::istream &ifs)
break;
case 0x90:
- if (payload == 0)
- this->warmboot = "disabled";
- else if (payload == 32)
- this->warmboot = "enabled";
- else
- error("Unknown warmboot payload 0x%02x\n", payload);
- info("Setting warmboot to '%s'.\n", this->warmboot.c_str());
+ switch(payload)
+ {
+ case 0:
+ this->warmboot = "disabled";
+ this->nosleep = "disabled";
+ break;
+ case 1:
+ this->warmboot = "disabled";
+ this->nosleep = "enabled";
+ break;
+ case 32:
+ this->warmboot = "enabled";
+ this->nosleep = "disabled";
+ break;
+ case 33:
+ this->warmboot = "enabled";
+ this->nosleep = "enabled";
+ break;
+ default:
+ error("Unknown warmboot/nosleep payload 0x%02x\n", payload);
+ }
+ info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str());
break;
default:
@@ -437,15 +453,26 @@ void FpgaConfig::write_bits(std::ostream &ofs) const
write_byte(ofs, crc_value, file_offset, 0x05);
crc_value = 0xffff;
- debug("Setting warmboot to '%s'.\n", this->warmboot.c_str());
- write_byte(ofs, crc_value, file_offset, 0x92);
- write_byte(ofs, crc_value, file_offset, 0x00);
- if (this->warmboot == "disabled")
+ {
+ uint8_t nosleep_flag;
+ debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str());
+ write_byte(ofs, crc_value, file_offset, 0x92);
write_byte(ofs, crc_value, file_offset, 0x00);
- else if (this->warmboot == "enabled")
- write_byte(ofs, crc_value, file_offset, 0x20);
- else
- error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str());
+
+ if (this->nosleep == "disabled")
+ nosleep_flag = 0;
+ else if (this->nosleep == "enabled")
+ nosleep_flag = 1;
+ else
+ error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str());
+
+ if (this->warmboot == "disabled")
+ write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag);
+ else if (this->warmboot == "enabled")
+ write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag);
+ else
+ error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str());
+ }
debug("CRAM: Setting bank width to %d.\n", this->cram_width);
write_byte(ofs, crc_value, file_offset, 0x62);
@@ -472,14 +499,14 @@ void FpgaConfig::write_bits(std::ostream &ofs) const
for (int cram_y = 0; cram_y < height; cram_y++)
for (int cram_x = 0; cram_x < this->cram_width; cram_x++)
cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]);
-
+
if(this->device == "5k") {
debug("CRAM: Setting bank height to %d.\n", height);
write_byte(ofs, crc_value, file_offset, 0x72);
write_byte(ofs, crc_value, file_offset, height >> 8);
write_byte(ofs, crc_value, file_offset, height);
}
-
+
debug("CRAM: Setting bank %d.\n", cram_bank);
write_byte(ofs, crc_value, file_offset, 0x11);
write_byte(ofs, crc_value, file_offset, cram_bank);
@@ -574,7 +601,7 @@ void FpgaConfig::write_bits(std::ostream &ofs) const
write_byte(ofs, crc_value, file_offset, 0x00);
}
-void FpgaConfig::read_ascii(std::istream &ifs)
+void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep)
{
debug("## %s\n", __PRETTY_FUNCTION__);
info("Parsing ascii file..\n");
@@ -703,6 +730,14 @@ void FpgaConfig::read_ascii(std::istream &ifs)
continue;
}
+ // No ".nosleep" section despite sharing the same byte as .warmboot.
+ // ".nosleep" is specified when icepack is invoked, which is too late.
+ // So we inject the section based on command line argument.
+ if (nosleep)
+ this->nosleep = "enabled";
+ else
+ this->nosleep = "disabled";
+
if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile")
{
if (!got_device)
@@ -821,6 +856,10 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const
if (this->warmboot != "enabled")
ofs << stringf(".warmboot %s\n", this->warmboot.c_str());
+ // As "nosleep" is an icepack command, we do not write out a ".nosleep"
+ // section. However, we parse it in read_bits() and notify the user in
+ // info.
+
typedef std::tuple<int, int, int> tile_bit_t;
std::set<tile_bit_t> tile_bits;
@@ -1251,6 +1290,9 @@ void usage()
log(" -v\n");
log(" verbose (repeat to increase verbosity)\n");
log("\n");
+ log(" -s\n");
+ log(" disable final deep-sleep SPI flash command after bitstream is loaded\n");
+ log("\n");
log(" -b\n");
log(" write cram bitmap as netpbm file\n");
log("\n");
@@ -1274,6 +1316,7 @@ int main(int argc, char **argv)
{
vector<string> parameters;
bool unpack_mode = false;
+ bool nosleep_mode = false;
bool netpbm_mode = false;
bool netpbm_bram = false;
bool netpbm_fill_tiles = false;
@@ -1308,6 +1351,8 @@ int main(int argc, char **argv)
} else if (arg[i] == 'B') {
netpbm_mode = true;
netpbm_banknum = arg[++i] - '0';
+ } else if (arg[i] == 's') {
+ nosleep_mode = true;
} else if (arg[i] == 'v') {
log_level++;
} else
@@ -1352,7 +1397,7 @@ int main(int argc, char **argv)
if (!netpbm_mode)
fpga_config.write_ascii(*osp);
} else {
- fpga_config.read_ascii(*isp);
+ fpga_config.read_ascii(*isp, nosleep_mode);
if (!netpbm_mode)
fpga_config.write_bits(*osp);
}
diff --git a/iceprog/iceprog.c b/iceprog/iceprog.c
index 27f3589..4a634c5 100644
--- a/iceprog/iceprog.c
+++ b/iceprog/iceprog.c
@@ -315,6 +315,7 @@ static void help(const char *progname)
fprintf(stderr, " This means that some data after the written data (or\n");
fprintf(stderr, " even before when -o is used) may be erased as well.\n");
fprintf(stderr, " -b bulk erase entire flash before writing\n");
+ fprintf(stderr, " -e <size in bytes> erase flash as if we were writing that number of bytes\n");
fprintf(stderr, " -n do not erase flash before writing\n");
fprintf(stderr, "\n");
fprintf(stderr, "Miscellaneous options:\n");
@@ -354,10 +355,12 @@ int main(int argc, char **argv)
my_name = argv[0] + i + 1;
int read_size = 256 * 1024;
+ int erase_size = 0;
int rw_offset = 0;
bool read_mode = false;
bool check_mode = false;
+ bool erase_mode = false;
bool bulk_erase = false;
bool dont_erase = false;
bool prog_sram = false;
@@ -373,7 +376,7 @@ int main(int argc, char **argv)
int opt;
char *endptr;
- while ((opt = getopt_long(argc, argv, "d:I:rR:o:cbnStv", long_options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "d:I:rR:e:o:cbnStv", long_options, NULL)) != -1) {
switch (opt) {
case 'd':
devstr = optarg;
@@ -409,6 +412,20 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
break;
+ case 'e':
+ erase_mode = true;
+ erase_size = strtol(optarg, &endptr, 0);
+ if (*endptr == '\0')
+ /* ok */;
+ else if (!strcmp(endptr, "k"))
+ erase_size *= 1024;
+ else if (!strcmp(endptr, "M"))
+ erase_size *= 1024 * 1024;
+ else {
+ fprintf(stderr, "%s: `%s' is not a valid size\n", my_name, optarg);
+ return EXIT_FAILURE;
+ }
+ break;
case 'o':
rw_offset = strtol(optarg, &endptr, 0);
if (*endptr == '\0')
@@ -450,8 +467,8 @@ int main(int argc, char **argv)
}
}
- if (read_mode + check_mode + prog_sram + test_mode > 1) {
- fprintf(stderr, "%s: options `-r'/`-R', `-c', `-S', and `-t' are mutually exclusive\n", my_name);
+ if (read_mode + erase_mode + check_mode + prog_sram + test_mode > 1) {
+ fprintf(stderr, "%s: options `-r'/`-R', `-e`, `-c', `-S', and `-t' are mutually exclusive\n", my_name);
return EXIT_FAILURE;
}
@@ -493,7 +510,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
} else if (bulk_erase) {
filename = "/dev/null";
- } else if (!test_mode) {
+ } else if (!test_mode && !erase_mode) {
fprintf(stderr, "%s: missing argument\n", my_name);
fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
return EXIT_FAILURE;
@@ -505,9 +522,11 @@ int main(int argc, char **argv)
FILE *f = NULL;
long file_size = -1;
- if (test_mode)
+ if (test_mode) {
/* nop */;
- else if (read_mode) {
+ } else if (erase_mode) {
+ file_size = erase_size;
+ } else if (read_mode) {
f = (strcmp(filename, "-") == 0) ? stdout : fopen(filename, "wb");
if (f == NULL) {
fprintf(stderr, "%s: can't open '%s' for writing: ", my_name, filename);
@@ -751,21 +770,24 @@ int main(int argc, char **argv)
}
}
- fprintf(stderr, "programming..\n");
+ if (!erase_mode)
+ {
+ fprintf(stderr, "programming..\n");
+
+ for (int rc, addr = 0; true; addr += rc) {
+ uint8_t buffer[256];
+ int page_size = 256 - (rw_offset + addr) % 256;
+ rc = fread(buffer, 1, page_size, f);
+ if (rc <= 0)
+ break;
+ flash_write_enable();
+ flash_prog(rw_offset + addr, buffer, rc);
+ flash_wait();
+ }
- for (int rc, addr = 0; true; addr += rc) {
- uint8_t buffer[256];
- int page_size = 256 - (rw_offset + addr) % 256;
- rc = fread(buffer, 1, page_size, f);
- if (rc <= 0)
- break;
- flash_write_enable();
- flash_prog(rw_offset + addr, buffer, rc);
- flash_wait();
+ /* seek to the beginning for second pass */
+ fseek(f, 0, SEEK_SET);
}
-
- /* seek to the beginning for second pass */
- fseek(f, 0, SEEK_SET);
}
// ---------------------------------------------------------
@@ -779,7 +801,7 @@ int main(int argc, char **argv)
flash_read(rw_offset + addr, buffer, 256);
fwrite(buffer, read_size - addr > 256 ? 256 : read_size - addr, 1, f);
}
- } else {
+ } else if (!erase_mode) {
fprintf(stderr, "reading..\n");
for (int addr = 0; true; addr += 256) {
uint8_t buffer_flash[256], buffer_file[256];