diff options
-rw-r--r-- | docs/index.html | 2 | ||||
-rw-r--r-- | icebox/icebox.py | 86 | ||||
-rwxr-xr-x | icebox/icebox_hlc2asc.py | 3 | ||||
-rw-r--r-- | iceprog/iceprog.c | 355 | ||||
-rw-r--r-- | icetime/Makefile | 2 |
5 files changed, 365 insertions, 83 deletions
diff --git a/docs/index.html b/docs/index.html index 919122e..a8ab14b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -301,7 +301,7 @@ If you have a bug report please file an issue on github. (<a href="https://githu <p> Recommended reading: <a href="http://www.latticesemi.com/~/media/LatticeSemi/Documents/DataSheets/iCE/iCE40LPHXFamilyDataSheet.pdf">Lattice iCE40 LP/HX Family Datasheet</a>, -<a href="http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201504.pdf">Lattice iCE Technology Library</a> +<a href="http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201608.pdf">Lattice iCE Technology Library</a> (Especially the three pages on "Architecture Overview", "PLB Blocks", "Routing", and "Clock/Control Distribution Network" in the Lattice iCE40 LP/HX Family Datasheet. Read that first, then come back here.) </p> diff --git a/icebox/icebox.py b/icebox/icebox.py index 44f6024..f49d7ed 100644 --- a/icebox/icebox.py +++ b/icebox/icebox.py @@ -2511,43 +2511,47 @@ ieren_db = { ( 7, 6, 1, 7, 6, 0), ], "lm4k": [ + ( 4, 21, 0, 4, 21, 1), + ( 4, 21, 1, 4, 21, 0), + ( 5, 21, 1, 5, 21, 0), ( 6, 0, 0, 6, 0, 1), ( 6, 0, 1, 6, 0, 0), + ( 6, 21, 0, 6, 21, 1), ( 7, 0, 0, 7, 0, 1), ( 7, 0, 1, 7, 0, 0), + ( 7, 21, 1, 7, 21, 0), ( 8, 0, 0, 8, 0, 1), ( 8, 0, 1, 8, 0, 0), + ( 9, 21, 1, 9, 21, 0), + ( 9, 21, 0, 9, 21, 1), (10, 0, 0, 10, 0, 1), (12, 0, 0, 12, 0, 1), (12, 0, 1, 12, 0, 0), + (12, 21, 1, 12, 21, 0), (13, 0, 0, 13, 0, 1), (13, 0, 1, 13, 0, 0), - (19, 0, 0, 19, 0, 1), - (19, 0, 1, 19, 0, 0), - (21, 0, 0, 21, 0, 1), - (21, 0, 1, 21, 0, 0), - (22, 0, 0, 22, 0, 1), - (23, 0, 0, 23, 0, 1), - (23, 0, 1, 23, 0, 0), - (24, 0, 0, 24, 0, 1), - (24, 0, 1, 24, 0, 0), - ( 4, 21, 0, 4, 21, 1), - ( 4, 21, 1, 4, 21, 0), - ( 5, 21, 1, 5, 21, 0), - ( 6, 21, 0, 6, 21, 1), - ( 7, 21, 1, 7, 21, 0), - ( 9, 21, 0, 9, 21, 1), - (12, 21, 1, 12, 21, 0), (13, 21, 0, 13, 21, 1), + (14, 0, 1, 14, 0, 0), (15, 21, 0, 15, 21, 1), + (16, 21, 1, 16, 21, 0), (17, 21, 1, 17, 21, 0), (18, 21, 0, 18, 21, 1), + (19, 0, 0, 19, 0, 1), + (19, 0, 1, 19, 0, 0), (19, 21, 0, 19, 21, 1), (19, 21, 1, 19, 21, 0), + (21, 0, 0, 21, 0, 1), + (21, 0, 1, 21, 0, 0), (21, 21, 1, 21, 21, 0), + (22, 0, 0, 22, 0, 1), + (22, 0, 1, 22, 0, 0), (22, 21, 1, 22, 21, 0), + (23, 0, 0, 23, 0, 1), + (23, 0, 1, 23, 0, 0), (23, 21, 0, 23, 21, 1), (23, 21, 1, 23, 21, 0), + (24, 0, 0, 24, 0, 1), + (24, 0, 1, 24, 0, 0), ], "5k": [ ( 8, 0, 0, 8, 0, 1), @@ -4895,6 +4899,56 @@ pinloc_db = { ( "F7", 21, 0, 1), ( "G3", 13, 0, 0), ( "G6", 23, 0, 1), + ], + "lm4k-cm36": [ + ( "A1", 5, 21, 1), + ( "A2", 7, 21, 1), + ( "A3", 9, 21, 1), + ( "A4", 16, 21, 1), + ( "A5", 19, 21, 1), + ( "A6", 22, 21, 1), + ( "B1", 4, 21, 1), + ( "B2", 6, 21, 0), + ( "B3", 12, 21, 1), + ( "B4", 13, 21, 0), + ( "B5", 21, 21, 1), + ( "B6", 23, 21, 1), + ( "C1", 7, 0, 1), + ( "C5", 23, 21, 0), + ( "C6", 23, 0, 0), + ( "D1", 6, 0, 1), + ( "D6", 24, 0, 0), + ( "E1", 7, 0, 0), + ( "E2", 13, 0, 0), + ( "E3", 14, 0, 1), + ( "E5", 22, 0, 1), + ( "E6", 24, 0, 1), + ( "F1", 6, 0, 0), + ( "F2", 10, 0, 0), + ( "F3", 12, 0, 1), + ( "F4", 19, 0, 0), + ( "F5", 22, 0, 0), + ( "F6", 23, 0, 1), + ], + "lm4k-swg25tr": [ + ( "A1", 22, 21, 1), + ( "A3", 13, 21, 0), + ( "A4", 12, 21, 1), + ( "A5", 5, 21, 1), + ( "B1", 21, 21, 1), + ( "B5", 6, 21, 0), + ( "C1", 23, 0, 1), + ( "C2", 19, 21, 1), + ( "C4", 13, 0, 0), + ( "C5", 7, 0, 1), + ( "D1", 24, 0, 0), + ( "D2", 23, 0, 0), + ( "D3", 19, 0, 0), + ( "D5", 6, 0, 1), + ( "E1", 24, 0, 1), + ( "E3", 12, 0, 1), + ( "E4", 7, 0, 0), + ( "E5", 6, 0, 0), ] } diff --git a/icebox/icebox_hlc2asc.py b/icebox/icebox_hlc2asc.py index 87aafc6..8b82132 100755 --- a/icebox/icebox_hlc2asc.py +++ b/icebox/icebox_hlc2asc.py @@ -573,6 +573,9 @@ class Main: if self.device.startswith('1k'): self.ic = icebox.iceconfig() self.ic.setup_empty_1k() + elif self.device.startswith('5k'): + self.ic = icebox.iceconfig() + self.ic.setup_empty_5k() elif self.device.startswith('8k'): self.ic = icebox.iceconfig() self.ic.setup_empty_8k() diff --git a/iceprog/iceprog.c b/iceprog/iceprog.c index 29d4c22..6462b3d 100644 --- a/iceprog/iceprog.c +++ b/iceprog/iceprog.c @@ -2,6 +2,7 @@ * iceprog -- simple programming tool for FTDI-based Lattice iCE programmers * * Copyright (C) 2015 Clifford Wolf <clifford@clifford.at> + * Copyright (C) 2018 Piotr Esden-Tempski <piotr@esden.net> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -36,6 +37,23 @@ #include <sys/types.h> #include <sys/stat.h> +// --------------------------------------------------------- +// MPSSE / FTDI definitions +// --------------------------------------------------------- + +/* FTDI bank pinout typically used for iCE dev boards + * BUS IO | Signal | Control + * -------+--------+-------------- + * xDBUS0 | SCK | MPSSE + * xDBUS1 | MOSI | MPSSE + * xDBUS2 | MISO | MPSSE + * xDBUS3 | nc | + * xDBUS4 | CS | GPIO + * xDBUS5 | nc | + * xDBUS6 | CDONE | GPIO + * xDBUS7 | CRESET | GPIO + */ + static struct ftdi_context ftdic; static bool ftdic_open = false; static bool verbose = false; @@ -76,6 +94,10 @@ enum mpsse_cmd MC_CPU_WE = 0x93, /* CPUMode write extended address */ }; +// --------------------------------------------------------- +// FLASH definitions +// --------------------------------------------------------- + /* Transfer Command bits */ /* All byte based commands consist of: @@ -146,6 +168,7 @@ enum flash_cmd { FC_GBL = 0x7E, /* Global Block Lock */ FC_GBU = 0x98, /* Global Block Unlock */ FC_RBL = 0x3D, /* Read Block Lock */ + FC_RPR = 0x3C, /* Read Sector Protection Registers (adesto) */ FC_IBL = 0x36, /* Individual Block Lock */ FC_IBU = 0x39, /* Individual Block Unlock */ FC_EPS = 0x75, /* Erase / Program Suspend */ @@ -156,6 +179,10 @@ enum flash_cmd { FC_RESET = 0x99, /* Reset Device */ }; +// --------------------------------------------------------- +// MPSSE / FTDI function implementations +// --------------------------------------------------------- + static void check_rx() { while (1) { @@ -242,9 +269,22 @@ static void xfer_spi(uint8_t *data, int n) data[i] = recv_byte(); } +static uint8_t xfer_spi_bits(uint8_t data, int n) +{ + if (n < 1) + return 0; + + /* Input and output, update data on negative edge read on positive, bits. */ + send_byte(MC_DATA_IN | MC_DATA_OUT | MC_DATA_OCN | MC_DATA_BITS); + send_byte(n - 1); + send_byte(data); + + return recv_byte(); +} + static void set_gpio(int slavesel_b, int creset_b) { - uint8_t gpio = 1; + uint8_t gpio = 0; if (slavesel_b) { // ADBUS4 (GPIOL0) @@ -270,46 +310,189 @@ static int get_cdone() return (data & 0x40) != 0; } -static void flash_read_id() +// --------------------------------------------------------- +// FLASH function implementations +// --------------------------------------------------------- + +// the FPGA reset is released so also FLASH chip select should be deasserted +static void flash_release_reset() { - // fprintf(stderr, "read flash ID..\n"); + set_gpio(1, 1); +} - uint8_t data[21] = { FC_JEDECID }; +// FLASH chip select assert +// should only happen while FPGA reset is asserted +static void flash_chip_select() +{ set_gpio(0, 0); - xfer_spi(data, 21); +} + +// FLASH chip select deassert +static void flash_chip_deselect() +{ set_gpio(1, 0); +} + +// SRAM reset is the same as flash_chip_select() +// For ease of code reading we use this function instead +static void sram_reset() +{ + // Asserting chip select and reset lines + set_gpio(0, 0); +} +// SRAM chip select assert +// When accessing FPGA SRAM the reset should be released +static void sram_chip_select() +{ + set_gpio(0, 1); +} + +static void flash_read_id() +{ + /* JEDEC ID structure: + * Byte No. | Data Type + * ---------+---------- + * 0 | FC_JEDECID Request Command + * 1 | MFG ID + * 2 | Dev ID 1 + * 3 | Dev ID 2 + * 4 | Ext Dev Str Len + */ + + uint8_t data[260] = { FC_JEDECID }; + int len = 5; // command + 4 response bytes + + if (verbose) + fprintf(stderr, "read flash ID..\n"); + + flash_chip_select(); + + // Write command and read first 4 bytes + xfer_spi(data, len); + + if (data[4] == 0xFF) + fprintf(stderr, "Extended Device String Length is 0xFF, " + "this is likely a read error. Ignorig...\n"); + else { + // Read extended JEDEC ID bytes + if (data[4] != 0) { + len += data[4]; + xfer_spi(data + 5, len - 5); + } + } + + flash_chip_deselect(); + + // TODO: Add full decode of the JEDEC ID. fprintf(stderr, "flash ID:"); - for (int i = 1; i < 21; i++) + for (int i = 1; i < len; i++) fprintf(stderr, " 0x%02X", data[i]); fprintf(stderr, "\n"); } +static void flash_reset() +{ + flash_chip_select(); + xfer_spi_bits(0xFF, 8); + flash_chip_deselect(); + + flash_chip_select(); + xfer_spi_bits(0xFF, 2); + flash_chip_deselect(); +} + static void flash_power_up() { - uint8_t data[1] = { FC_RPD }; - set_gpio(0, 0); - xfer_spi(data, 1); - set_gpio(1, 0); + uint8_t data_rpd[1] = { FC_RPD }; + flash_chip_select(); + xfer_spi(data_rpd, 1); + flash_chip_deselect(); } static void flash_power_down() { uint8_t data[1] = { FC_PD }; - set_gpio(0, 0); + flash_chip_select(); xfer_spi(data, 1); - set_gpio(1, 0); + flash_chip_deselect(); +} + +static uint8_t flash_read_status() +{ + uint8_t data[2] = { FC_RSR1 }; + + flash_chip_select(); + xfer_spi(data, 2); + flash_chip_deselect(); + + if (verbose) { + fprintf(stderr, "SR1: 0x%02X\n", data[1]); + fprintf(stderr, " - SPRL: %s\n", + ((data[1] & (1 << 7)) == 0) ? + "unlocked" : + "locked"); + fprintf(stderr, " - SPM: %s\n", + ((data[1] & (1 << 6)) == 0) ? + "Byte/Page Prog Mode" : + "Sequential Prog Mode"); + fprintf(stderr, " - EPE: %s\n", + ((data[1] & (1 << 5)) == 0) ? + "Erase/Prog success" : + "Erase/Prog error"); + fprintf(stderr, "- SPM: %s\n", + ((data[1] & (1 << 4)) == 0) ? + "~WP asserted" : + "~WP deasserted"); + fprintf(stderr, " - SWP: "); + switch((data[1] >> 2) & 0x3) { + case 0: + fprintf(stderr, "All sectors unprotected\n"); + break; + case 1: + fprintf(stderr, "Some sectors protected\n"); + break; + case 2: + fprintf(stderr, "Reserved (xxxx 10xx)\n"); + break; + case 3: + fprintf(stderr, "All sectors protected\n"); + break; + } + fprintf(stderr, " - WEL: %s\n", + ((data[1] & (1 << 1)) == 0) ? + "Not write enabled" : + "Write enabled"); + fprintf(stderr, " - ~RDY: %s\n", + ((data[1] & (1 << 0)) == 0) ? + "Ready" : + "Busy"); + } + + usleep(1000); + + return data[1]; } static void flash_write_enable() { + if (verbose) { + fprintf(stderr, "status before enable:\n"); + flash_read_status(); + } + if (verbose) fprintf(stderr, "write enable..\n"); uint8_t data[1] = { FC_WE }; - set_gpio(0, 0); + flash_chip_select(); xfer_spi(data, 1); - set_gpio(1, 0); + flash_chip_deselect(); + + if (verbose) { + fprintf(stderr, "status after enable:\n"); + flash_read_status(); + } } static void flash_bulk_erase() @@ -317,9 +500,9 @@ static void flash_bulk_erase() fprintf(stderr, "bulk erase..\n"); uint8_t data[1] = { FC_CE }; - set_gpio(0, 0); + flash_chip_select(); xfer_spi(data, 1); - set_gpio(1, 0); + flash_chip_deselect(); } static void flash_64kB_sector_erase(int addr) @@ -328,9 +511,9 @@ static void flash_64kB_sector_erase(int addr) uint8_t command[4] = { FC_BE64, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr }; - set_gpio(0, 0); + flash_chip_select(); send_spi(command, 4); - set_gpio(1, 0); + flash_chip_deselect(); } static void flash_prog(int addr, uint8_t *data, int n) @@ -340,10 +523,10 @@ static void flash_prog(int addr, uint8_t *data, int n) uint8_t command[4] = { FC_PP, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr }; - set_gpio(0, 0); + flash_chip_select(); send_spi(command, 4); send_spi(data, n); - set_gpio(1, 0); + flash_chip_deselect(); if (verbose) for (int i = 0; i < n; i++) @@ -357,11 +540,11 @@ static void flash_read(int addr, uint8_t *data, int n) uint8_t command[4] = { FC_RD, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr }; - set_gpio(0, 0); + flash_chip_select(); send_spi(command, 4); memset(data, 0, n); xfer_spi(data, n); - set_gpio(1, 0); + flash_chip_deselect(); if (verbose) for (int i = 0; i < n; i++) @@ -373,52 +556,72 @@ static void flash_wait() if (verbose) fprintf(stderr, "waiting.."); + int count = 0; while (1) { uint8_t data[2] = { FC_RSR1 }; - set_gpio(0, 0); + flash_chip_select(); xfer_spi(data, 2); - set_gpio(1, 0); - - if ((data[1] & 0x01) == 0) - break; - - if (verbose) { - fprintf(stderr, "."); - fflush(stdout); + flash_chip_deselect(); + + if ((data[1] & 0x01) == 0) { + if (count < 2) { + count++; + if (verbose) { + fprintf(stderr, "r"); + fflush(stderr); + } + } else { + if (verbose) { + fprintf(stderr, "R"); + fflush(stderr); + } + break; + } + } else { + if (verbose) { + fprintf(stderr, "."); + fflush(stderr); + } + count = 0; } + usleep(1000); } if (verbose) fprintf(stderr, "\n"); + } static void flash_disable_protection() { fprintf(stderr, "disable flash protection...\n"); - //WRSR 0x00 - uint8_t data[2] = { 0x01, 0x00 }; - set_gpio(0, 0); + // Write Status Register 1 <- 0x00 + uint8_t data[2] = { FC_WSR1, 0x00 }; + flash_chip_select(); xfer_spi(data, 2); - set_gpio(1, 0); + flash_chip_deselect(); flash_wait(); - //RDSR - data[0] = 0x5; + // Read Status Register 1 + data[0] = FC_RSR1; - set_gpio(0, 0);\ + flash_chip_select(); xfer_spi(data, 2); - set_gpio(1, 0); + flash_chip_deselect(); - if(data[1] != 0x00) + if (data[1] != 0x00) fprintf(stderr, "failed to disable protection, SR now equal to 0x%02x (expected 0x00)\n", data[1]); } +// --------------------------------------------------------- +// iceprog implementation +// --------------------------------------------------------- static void help(const char *progname) { @@ -439,6 +642,7 @@ static void help(const char *progname) fprintf(stderr, " -o <offset in bytes> start address for read/write [default: 0]\n"); fprintf(stderr, " (append 'k' to the argument for size in kilobytes,\n"); fprintf(stderr, " or 'M' for size in megabytes)\n"); + fprintf(stderr, " -s slow SPI (50 kHz instead of 6 MHz)\n"); fprintf(stderr, " -v verbose output\n"); fprintf(stderr, "\n"); fprintf(stderr, "Mode of operation:\n"); @@ -509,6 +713,7 @@ int main(int argc, char **argv) bool dont_erase = false; bool prog_sram = false; bool test_mode = false; + bool slow_clock = false; bool disable_protect = false; const char *filename = NULL; const char *devstr = NULL; @@ -519,14 +724,15 @@ int main(int argc, char **argv) {NULL, 0, NULL, 0} }; + /* Decode command line parameters */ int opt; char *endptr; - while ((opt = getopt_long(argc, argv, "d:I:rR:e:o:cbnStvp", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "d:I:rR:e:o:cbnStvsp", long_options, NULL)) != -1) { switch (opt) { - case 'd': + case 'd': /* device string */ devstr = optarg; break; - case 'I': + case 'I': /* FTDI Chip interface select */ if (!strcmp(optarg, "A")) ifnum = INTERFACE_A; else if (!strcmp(optarg, "B")) @@ -540,10 +746,10 @@ int main(int argc, char **argv) return EXIT_FAILURE; } break; - case 'r': + case 'r': /* Read 256 bytes to file */ read_mode = true; break; - case 'R': + case 'R': /* Read n bytes to file */ read_mode = true; read_size = strtol(optarg, &endptr, 0); if (*endptr == '\0') @@ -557,7 +763,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } break; - case 'e': + case 'e': /* Erase blocks as if we were writing n bytes */ erase_mode = true; erase_size = strtol(optarg, &endptr, 0); if (*endptr == '\0') @@ -571,7 +777,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } break; - case 'o': + case 'o': /* set address offset */ rw_offset = strtol(optarg, &endptr, 0); if (*endptr == '\0') /* ok */; @@ -584,25 +790,28 @@ int main(int argc, char **argv) return EXIT_FAILURE; } break; - case 'c': + case 'c': /* do not write just check */ check_mode = true; break; - case 'b': + case 'b': /* bulk erase before writing */ bulk_erase = true; break; - case 'n': + case 'n': /* do not erase before writing */ dont_erase = true; break; - case 'S': + case 'S': /* write to sram directly */ prog_sram = true; break; - case 't': + case 't': /* just read flash id */ test_mode = true; break; - case 'v': + case 'v': /* provide verbose output */ verbose = true; break; - case 'p': + case 's': /* use slow SPI clock */ + slow_clock = true; + break; + case 'p': /* disable flash protect before erase/write */ disable_protect = true; break; case -2: @@ -615,6 +824,8 @@ int main(int argc, char **argv) } } + /* Make sure that the combination of provided parameters makes sense */ + 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; @@ -803,33 +1014,40 @@ int main(int argc, char **argv) // enable clock divide by 5 send_byte(MC_TCK_D5); - // set 6 MHz clock - send_byte(MC_SET_CLK_DIV); - send_byte(0x00); - send_byte(0x00); + if (slow_clock) { + // set 50 kHz clock + send_byte(MC_SET_CLK_DIV); + send_byte(119); + send_byte(0x00); + } else { + // set 6 MHz clock + send_byte(MC_SET_CLK_DIV); + send_byte(0x00); + send_byte(0x00); + } fprintf(stderr, "cdone: %s\n", get_cdone() ? "high" : "low"); - set_gpio(1, 1); + flash_release_reset(); usleep(100000); - if (test_mode) { fprintf(stderr, "reset..\n"); - set_gpio(1, 0); + flash_chip_deselect(); usleep(250000); fprintf(stderr, "cdone: %s\n", get_cdone() ? "high" : "low"); + flash_reset(); flash_power_up(); flash_read_id(); flash_power_down(); - set_gpio(1, 1); + flash_release_reset(); usleep(250000); fprintf(stderr, "cdone: %s\n", get_cdone() ? "high" : "low"); @@ -842,10 +1060,10 @@ int main(int argc, char **argv) fprintf(stderr, "reset..\n"); - set_gpio(0, 0); + sram_reset(); usleep(100); - set_gpio(0, 1); + sram_chip_select(); usleep(2000); fprintf(stderr, "cdone: %s\n", get_cdone() ? "high" : "low"); @@ -877,7 +1095,7 @@ int main(int argc, char **argv) fprintf(stderr, "cdone: %s\n", get_cdone() ? "high" : "low"); } - else + else /* program flash */ { // --------------------------------------------------------- // Reset @@ -885,11 +1103,12 @@ int main(int argc, char **argv) fprintf(stderr, "reset..\n"); - set_gpio(1, 0); + flash_chip_deselect(); usleep(250000); fprintf(stderr, "cdone: %s\n", get_cdone() ? "high" : "low"); + flash_reset(); flash_power_up(); flash_read_id(); @@ -925,6 +1144,10 @@ int main(int argc, char **argv) for (int addr = begin_addr; addr < end_addr; addr += 0x10000) { flash_write_enable(); flash_64kB_sector_erase(addr); + if (verbose) { + fprintf(stderr, "Status after block erase:\n"); + flash_read_status(); + } flash_wait(); } } diff --git a/icetime/Makefile b/icetime/Makefile index 85d31f8..d260681 100644 --- a/icetime/Makefile +++ b/icetime/Makefile @@ -37,7 +37,9 @@ timings.inc: timings.py ../icefuzz/timings_*.txt install: all mkdir -p $(DESTDIR)$(PREFIX)/bin + mkdir -p $(DESTDIR)$(PREFIX)/share/icebox cp icetime$(EXE) $(DESTDIR)$(PREFIX)/bin/icetime$(EXE) + cp ../icefuzz/timings_*.txt $(DESTDIR)$(PREFIX)/share/icebox/ uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/icetime$(EXE) |