diff options
-rw-r--r-- | COPYING | 13 | ||||
-rw-r--r-- | icepack/icepack.cc | 85 | ||||
-rw-r--r-- | iceprog/iceprog.c | 62 |
3 files changed, 120 insertions, 40 deletions
@@ -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]; |