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; | 
