diff options
-rw-r--r-- | config.mk | 16 | ||||
-rw-r--r-- | icebox/icebox.py | 7 | ||||
-rw-r--r-- | icemulti/icemulti.cc | 124 | ||||
-rw-r--r-- | icepack/icepack.cc | 14 |
4 files changed, 114 insertions, 47 deletions
@@ -1,11 +1,19 @@ +PREFIX ?= /usr/local + CXX ?= clang++ CC ?= clang -LDLIBS = -lm -lstdc++ -CFLAGS += -MD -O0 -ggdb -Wall -std=c99 -I/usr/local/include -CXXFLAGS += -MD -O0 -ggdb -Wall -std=c++11 -I/usr/local/include PKG_CONFIG ?= pkg-config + +C_STD ?= c99 +CXX_STD ?= c++11 +OPT_LEVEL ?= 0 +WARN_LEVEL ?= all + +LDLIBS = -lm -lstdc++ +CFLAGS += -MD -O$(OPT_LEVEL) -ggdb -W$(WARN_LEVEL) -std=$(C_STD) -I$(PREFIX)/include +CXXFLAGS += -MD -O$(OPT_LEVEL) -ggdb -W$(WARN_LEVEL) -std=$(CXX_STD) -I$(PREFIX)/include + DESTDIR ?= -PREFIX ?= /usr/local CHIPDB_SUBDIR ?= icebox ifeq ($(MXE),1) diff --git a/icebox/icebox.py b/icebox/icebox.py index 982d088..41e8f12 100644 --- a/icebox/icebox.py +++ b/icebox/icebox.py @@ -26,6 +26,7 @@ class iceconfig: self.max_x = 0 self.max_y = 0 self.device = "" + self.warmboot = True self.logic_tiles = dict() self.io_tiles = dict() self.ramb_tiles = dict() @@ -668,6 +669,10 @@ class iceconfig: assert line[1] in ["1k", "5k", "8k", "384"] self.device = line[1] continue + if line[0] == ".warmboot": + assert line[1] in ["disabled", "enabled"] + self.warmboot = line[1] == "enabled" + continue if line[0] == ".sym": self.symbols.setdefault(int(line[1]), set()).add(line[2]) continue @@ -680,6 +685,8 @@ class iceconfig: def write_file(self, filename): with open(filename, "w") as f: print(".device %s" % self.device, file=f) + if not self.warmboot: + print(".warmboot disabled", file=f) for y in range(self.max_y+1): for x in range(self.max_x+1): if self.tile_pos(x, y) is not None: diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index 637c383..da90da3 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -19,12 +19,16 @@ #include <cstdint> #include <memory> +#include <getopt.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #define log(...) fprintf(stderr, __VA_ARGS__); #define info(...) do { if (log_level > 0) fprintf(stderr, __VA_ARGS__); } while (0) -#define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) +#define error(...) do { fprintf(stderr, "%s: ", program_short_name); fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } while (0) + +static char *program_short_name; int log_level = 0; @@ -55,7 +59,7 @@ static void write_bytes(std::ostream &ofs, uint32_t &file_offset, } static void write_file(std::ostream &ofs, uint32_t &file_offset, - std::istream &ifs) + std::istream &ifs, const char *filename) { const size_t bufsize = 8192; uint8_t *buffer = new uint8_t[bufsize]; @@ -63,7 +67,7 @@ static void write_file(std::ostream &ofs, uint32_t &file_offset, while(!ifs.eof()) { ifs.read(reinterpret_cast<char *>(buffer), bufsize); if (ifs.bad()) - error("Read error on input image"); + error("can't read input image `%s': %s\n", filename, strerror(errno)); write_bytes(ofs, file_offset, buffer, ifs.gcount()); } @@ -79,29 +83,42 @@ static void pad_to(std::ostream &ofs, uint32_t &file_offset, uint32_t target) } class Image { + const char *filename; std::ifstream ifs; uint32_t offs; public: - Image(const char *filename) : ifs(filename, std::ifstream::binary) {} - + Image(const char *filename); size_t size(); void write(std::ostream &ofs, uint32_t &file_offset); void place(uint32_t o) { offs = o; } uint32_t offset() const { return offs; } }; +Image::Image(const char *filename) : filename(filename), ifs(filename, std::ifstream::binary) +{ + if (ifs.fail()) + error("can't open input image `%s': %s\n", filename, strerror(errno)); +} + size_t Image::size() { ifs.seekg (0, ifs.end); + if (ifs.fail()) + error("can't seek on input image `%s': %s\n", filename, strerror(errno)); size_t length = ifs.tellg(); ifs.seekg (0, ifs.beg); + if (ifs.fail()) + error("can't seek on input image `%s': %s\n", filename, strerror(errno)); + + if (length == 0) + error("input image `%s' doesn't contain any data\n", filename); return length; } void Image::write(std::ostream &ofs, uint32_t &file_offset) { - write_file(ofs, file_offset, ifs); + write_file(ofs, file_offset, ifs, filename); } class Header { @@ -173,11 +190,13 @@ void usage() log(" -v\n"); log(" verbose (repeat to increase verbosity)\n"); log("\n"); - exit(1); + exit(EXIT_FAILURE); } int main(int argc, char **argv) { + int c; + char *endptr = NULL; bool coldboot = false; int por_image = 0; int image_count = 0; @@ -187,46 +206,65 @@ int main(int argc, char **argv) std::unique_ptr<Image> images[NUM_IMAGES]; const char *outfile_name = NULL; - for (int i = 1; i < argc; i++) - { - if (argv[i][0] == '-' && argv[i][1]) { - for (int j = 1; argv[i][j]; j++) - if (argv[i][j] == 'c') { - coldboot = true; - } else if (argv[i][j] == 'p' && argv[i][j+1]) { - por_image = argv[i][++j] - '0'; - } else if (argv[i][j] == 'a' || argv[i][j] == 'A') { - align_first = argv[i][j] == 'A'; - if (argv[i][j+1]) - align_bits = atoi(&argv[i][j+1]); - else if(i+1 < argc) - align_bits = atoi(argv[++i]); - else - usage(); - break; - } else if (argv[i][j] == 'o') { - if (argv[i][j+1]) - outfile_name = &argv[i][j+1]; - else if(i+1 < argc) - outfile_name = argv[++i]; - else - usage(); - break; - } else if (argv[i][j] == 'v') { - log_level++; - } else - usage(); - continue; + static struct option long_options[] = { + {NULL, 0, NULL, 0} + }; + + program_short_name = strrchr(argv[0], '/'); + if (program_short_name == NULL) + program_short_name = argv[0]; + else + program_short_name++; + + while ((c = getopt_long(argc, argv, "cp:a:A:o:v", + long_options, NULL)) != -1) + switch (c) { + case 'c': + coldboot = true; + break; + case 'p': + if (optarg[0] == '0' && optarg[1] == '\0') + por_image = 0; + else if (optarg[0] == '1' && optarg[1] == '\0') + por_image = 1; + else if (optarg[0] == '2' && optarg[1] == '\0') + por_image = 2; + else if (optarg[0] == '3' && optarg[1] == '\0') + por_image = 3; + else + error("`%s' is not a valid power-on/reset image (must be 0, 1, 2, or 3)\n", optarg); + break; + case 'A': + align_first = true; + /* fallthrough */ + case 'a': + align_bits = strtol(optarg, &endptr, 0); + if (*endptr != '\0') + error("`%s' is not a valid number\n", optarg); + if (align_bits < 0) + error("argument to `-%c' must be non-negative\n", c); + break; + case 'o': + outfile_name = optarg; + break; + case 'v': + log_level++; + break; + default: + usage(); } + if (optind == argc) { + fprintf(stderr, "%s: missing argument\n", program_short_name); + usage(); + } + + while (optind != argc) { if (image_count >= NUM_IMAGES) error("Too many images supplied\n"); - images[image_count++].reset(new Image(argv[i])); + images[image_count++].reset(new Image(argv[optind++])); } - if (!image_count) - usage(); - if (coldboot && por_image != 0) error("Can't select power on reset boot image in cold boot mode\n"); @@ -259,7 +297,7 @@ int main(int argc, char **argv) if (outfile_name != NULL) { ofs.open(outfile_name, std::ofstream::binary); if (!ofs.is_open()) - error("Failed to open output file.\n"); + error("can't open output file `%s': %s\n", outfile_name, strerror(errno)); osp = &ofs; } else { osp = &std::cout; @@ -278,5 +316,5 @@ int main(int argc, char **argv) } info("Done.\n"); - return 0; + return EXIT_SUCCESS; } diff --git a/icepack/icepack.cc b/icepack/icepack.cc index 4374452..2eac9c6 100644 --- a/icepack/icepack.cc +++ b/icepack/icepack.cc @@ -649,6 +649,18 @@ void FpgaConfig::read_ascii(std::istream &ifs) continue; } + if (command == ".warmboot") + { + is >> this->warmboot; + + if (this->warmboot != "disabled" && + this->warmboot != "enabled") + error("Unknown warmboot setting '%s'.\n", + this->warmboot.c_str()); + + continue; + } + if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile") { if (!got_device) @@ -764,6 +776,8 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const } ofs << stringf("\n.device %s\n", this->device.c_str()); + if (this->warmboot != "enabled") + ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); typedef std::tuple<int, int, int> tile_bit_t; std::set<tile_bit_t> tile_bits; |