diff --git a/.gitignore b/.gitignore index 065ae6888..f3fbe950a 100644 --- a/.gitignore +++ b/.gitignore @@ -58,4 +58,5 @@ ppls patches/* client/lualibs/mf_default_keys.lua client/lualibs/usb_cmd.lua - +# recompiled +fpga_version_info.c diff --git a/armsrc/Makefile b/armsrc/Makefile index 37b77c570..a0f5c7f5c 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -113,6 +113,8 @@ ARMSRC = fpgaloader.c \ # lf_proxbrute.c \ # hf_mattyrun.c \ +VERSIONSRC = version.c \ + fpga_version_info.c # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common/Makefile.common @@ -126,6 +128,14 @@ all: $(OBJS) .DELETE_ON_ERROR: +# version.c should be remade on every compilation +.PHONY: version.c +version.c: default_version.c + perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ + +fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) + $(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@ + $(OBJDIR)/fpga_all.o: $(OBJDIR)/fpga_all.bit.z $(OBJCOPY) -O elf32-littlearm -I binary -B arm --prefix-sections=fpga_all_bit $^ $@ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index bfc21cf76..194f4b6bc 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -14,6 +14,7 @@ #include "usb_cdc.h" #include "proxmark3.h" #include "apps.h" +#include "fpga.h" #include "util.h" #include "printf.h" #include "string.h" @@ -333,14 +334,14 @@ void SendVersion(void) { FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); - strncat(VersionString, " [ FPGA ]\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, "\n [ FPGA ]\n", sizeof(VersionString) - strlen(VersionString) - 1); - FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp)); - strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); - - FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp)); - strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); - + for (int i = 0; i < fpga_bitstream_num; i++) { + strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); + if (i < fpga_bitstream_num - 1) { + strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); + } + } // Send Chip ID and used flash memory uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start; uint32_t compressed_data_section_size = common_area.arg1; @@ -350,7 +351,7 @@ void SendVersion(void) { // measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included. void printUSBSpeed(void) { - Dbprintf("USB Speed:"); + Dbprintf("USB Speed"); Dbprintf(" Sending USB packets to client..."); #define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index fe4c82d60..86aa01241 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -11,11 +11,9 @@ //----------------------------------------------------------------------------- #include "fpgaloader.h" -extern void DbpString(char *str); -extern void Dbprintf(const char *fmt, ...); // remember which version of the bitstream we have already downloaded to the FPGA -static int downloaded_bitstream = FPGA_BITSTREAM_ERR; +static int downloaded_bitstream = 0; // this is where the bitstreams are located in memory: extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end; @@ -23,10 +21,7 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end; static uint8_t *fpga_image_ptr = NULL; static uint32_t uncompressed_bytes_cnt; -static const uint8_t _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01}; -#define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(_bitparse_fixed_header) #define OUTPUT_BUFFER_LEN 80 -#define FPGA_INTERLEAVE_SIZE 288 //----------------------------------------------------------------------------- // Set up the Serial Peripheral Interface as master @@ -205,7 +200,7 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8 // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc. //---------------------------------------------------------------------------- static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { - while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % FPGA_BITSTREAM_MAX != (bitstream_version - 1)) { + while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) { // skip undesired data belonging to other bitstream_versions get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); } @@ -232,7 +227,7 @@ static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_s // initialize z_stream structure for inflate: compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start; - compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_start - &_binary_obj_fpga_all_bit_z_end; + compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start; compressed_fpga_stream->next_out = output_buffer; compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; compressed_fpga_stream->zalloc = &fpga_inflate_malloc; @@ -245,8 +240,8 @@ static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_s for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); - // Check for a valid .bit file (starts with _bitparse_fixed_header) - if (memcmp(_bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) + // Check for a valid .bit file (starts with bitparse_fixed_header) + if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) return true; return false; @@ -427,6 +422,7 @@ void FpgaDownloadAndGo(int bitstream_version) { // free eventually allocated BigBuf memory BigBuf_free(); BigBuf_Clear_ext(false); } +/* //----------------------------------------------------------------------------- // Gather version information from FPGA image. Needs to decompress the begin @@ -496,7 +492,7 @@ void FpgaGatherVersion(int bitstream_version, char *dst, int len) { inflateEnd(&compressed_fpga_stream); } - +*/ //----------------------------------------------------------------------------- // Send a 16 bit command/data pair to the FPGA. // The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 @@ -544,12 +540,8 @@ void SetAdcMuxFor(uint32_t whichGpio) { } void Fpga_print_status(void) { - DbpString("Fpga"); - switch(downloaded_bitstream) { - case FPGA_BITSTREAM_HF: DbpString(" mode....................HF"); break; - case FPGA_BITSTREAM_LF: DbpString(" mode....................LF"); break; - default: Dbprintf(" mode....................%d", downloaded_bitstream); break; - } + Dbprintf("Currently loaded FPGA image"); + Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream-1]); } int FpgaGetCurrent(void) { diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 951260046..66cca0510 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -12,16 +12,21 @@ #ifndef __FPGALOADER_H #define __FPGALOADER_H +#include +#include +#include "apps.h" +#include "fpga.h" #include "common.h" // standard definitions #include "proxmark3.h" // common area #include "string.h" #include "BigBuf.h" // bigbuf mem #include "zlib.h" // uncompress + void FpgaSendCommand(uint16_t cmd, uint16_t v); void FpgaWriteConfWord(uint8_t v); void FpgaDownloadAndGo(int bitstream_version); -void FpgaGatherVersion(int bitstream_version, char *dst, int len); +// void FpgaGatherVersion(int bitstream_version, char *dst, int len); void FpgaSetupSscExt(uint8_t clearPCER); void FpgaSetupSsc(void); void SetupSpi(int mode); @@ -36,10 +41,9 @@ void SetAdcMuxFor(uint32_t whichGpio); extern void switch_off(void); // definitions for multiple FPGA config files support -#define FPGA_BITSTREAM_MAX 2 // the total number of FPGA bitstreams (configs) -#define FPGA_BITSTREAM_ERR 0 #define FPGA_BITSTREAM_LF 1 #define FPGA_BITSTREAM_HF 2 +//#define FPGA_BITSTREAM_FELICA 3 // Definitions for the FPGA commands. #define FPGA_CMD_SET_CONFREG (1<<12) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index a14df1400..972067a72 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -19,7 +19,7 @@ Default LF config is set to: sample_config config = { 1, 8, 1, 95, 0 } ; void printConfig() { - Dbprintf("LF Sampling config:"); + Dbprintf("LF Sampling config"); Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1)); Dbprintf(" [b] bps.................%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); diff --git a/armsrc/util.c b/armsrc/util.c index 7ed190162..b5be57923 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -266,23 +266,23 @@ void FormatVersionInformation(char *dst, int len, const char *prefix, void *vers struct version_information *v = (struct version_information*)version_information; dst[0] = 0; strncat(dst, prefix, len-1); - if(v->magic != VERSION_INFORMATION_MAGIC) { + if (v->magic != VERSION_INFORMATION_MAGIC) { strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1); return; } - if(v->versionversion != 1) { + if (v->versionversion != 1) { strncat(dst, "Version information not understood\n", len - strlen(dst) - 1); return; } - if(!v->present) { + if (!v->present) { strncat(dst, "Version information not available\n", len - strlen(dst) - 1); return; } strncat(dst, v->gitversion, len - strlen(dst) - 1); - if(v->clean == 0) { + if (v->clean == 0) { strncat(dst, "-unclean", len - strlen(dst) - 1); - } else if(v->clean == 2) { + } else if (v->clean == 2) { strncat(dst, "-suspect", len - strlen(dst) - 1); } diff --git a/bootrom/Makefile b/bootrom/Makefile index 2135aab6d..a579c46d3 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -13,6 +13,7 @@ THUMBSRC = cmd.c \ bootrom.c ASMSRC = ram-reset.s flash-reset.s +VERSIONSRC = version.c ## There is a strange bug with the linker: Sometimes it will not emit the glue to call ## BootROM from ARM mode. The symbol is emitted, but the section will be filled with @@ -29,6 +30,10 @@ include ../common/Makefile.common OBJS = $(OBJDIR)/bootrom.s19 +# version.c should be remade on every compilation +version.c: default_version.c + perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ + all: $(OBJS) tarbin: $(OBJS) diff --git a/client/Makefile b/client/Makefile index e3edb0b08..af2efb26c 100644 --- a/client/Makefile +++ b/client/Makefile @@ -258,7 +258,7 @@ all-static: proxmark3 flasher fpga_compress proxmark3: LDLIBS+=$(LUALIB) $(QTLDLIBS) proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/usb_cmd.lua lualibs/mf_default_keys.lua - $(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@ + $(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@ flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ diff --git a/client/cmdhw.c b/client/cmdhw.c index ca73eb234..82b4549e2 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -27,7 +27,7 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) { char asBuff[120]; memset(asBuff, 0, sizeof(asBuff)); uint32_t mem_avail = 0; - PrintAndLogEx(NORMAL, " [ Hardware ] "); + PrintAndLogEx(NORMAL, "\n [ Hardware ] "); switch(iChipID) { case 0x270B0A40: sprintf(asBuff,"AT91SAM7S512 Rev A"); break; @@ -242,32 +242,37 @@ int CmdVersion(const char *Cmd) { if ( silent ) return 0; - UsbCommand c = {CMD_VERSION}; - static UsbCommand resp = {0, {0, 0, 0}}; - - if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available - clearCommandBuffer(); - SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { + UsbCommand c = {CMD_VERSION, {0, 0, 0}}; + UsbCommand resp; + clearCommandBuffer(); + SendCommand(&c); + if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { #ifdef __WIN32 - PrintAndLogEx(NORMAL, "\nProxmark3 RFID instrument\n"); + PrintAndLogEx(NORMAL, "\nProxmark3 RFID instrument\n"); #else - PrintAndLogEx(NORMAL, "\n\e[34mProxmark3 RFID instrument\e[0m\n"); + PrintAndLogEx(NORMAL, "\n\e[34mProxmark3 RFID instrument\e[0m\n"); #endif - PrintAndLogEx(NORMAL, (char*)resp.d.asBytes); - lookupChipID(resp.arg[0], resp.arg[1]); - } - } else { - PrintAndLogEx(NORMAL, "[[[ Cached information ]]]\n"); -#ifdef __WIN32 - PrintAndLogEx(NORMAL, "\nProxmark3 RFID instrument\n"); -#else - PrintAndLogEx(NORMAL, "\n\e[33mProxmark3 RFID instrument\e[0m\n"); + char s[40] = {0}; + int i = 0; +#if defined(WITH_FLASH) || defined(WITH_SMARTCARD) + strncat(s, "build for RDV40 with ", 22); + i = 15; +#endif + +#ifdef WITH_FLASH + strncat(s, "flashmem; ", 10); + i += 10; #endif +#ifdef WITH_SMARTCARD + strncat(s+i, "smartcard; ", 11); + i += 11; +#endif + PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); + PrintAndLogEx(NORMAL, " client: iceman %s \n", s); + PrintAndLogEx(NORMAL, (char*)resp.d.asBytes); - lookupChipID(resp.arg[0], resp.arg[1]); - PrintAndLogEx(NORMAL, ""); - } + lookupChipID(resp.arg[0], resp.arg[1]); + } PrintAndLogEx(NORMAL, "\n"); return 0; } diff --git a/client/fpga_compress.c b/client/fpga_compress.c index 26a2c2945..5020914ae 100644 --- a/client/fpga_compress.c +++ b/client/fpga_compress.c @@ -1,4 +1,6 @@ //----------------------------------------------------------------------------- +// piwi, 2017, 2018 +// // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of // the license. @@ -11,10 +13,12 @@ #include #include +#include #include #include #include #include +#include "fpga.h" #include "zlib.h" #define MAX(a,b) ((a)>(b)?(a):(b)) @@ -30,6 +34,7 @@ Z_RLE (distances limited to one) Z_FIXED (prevents the use of dynamic Huffman codes) */ + #define COMPRESS_STRATEGY Z_DEFAULT_STRATEGY // zlib tuning parameters: #define COMPRESS_GOOD_LENGTH 258 @@ -37,18 +42,18 @@ #define COMPRESS_MAX_NICE_LENGTH 258 #define COMPRESS_MAX_CHAIN 8192 -#define FPGA_INTERLEAVE_SIZE 288 // (the FPGA's internal config frame size is 288 bits. Interleaving with 288 bytes should give best compression) -#define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE #define HARDNESTED_TABLE_SIZE (sizeof(uint32_t) * ((1L<<19)+1)) static void usage(void) { fprintf(stdout, "Usage: fpga_compress ... \n"); fprintf(stdout, " Combine n FPGA bitstream files and compress them into one.\n\n"); - fprintf(stdout, " fpga_compress -d "); - fprintf(stdout, " Decompress . Write result to "); - fprintf(stdout, " fpga_compress -t "); - fprintf(stdout, " Compress hardnested table . Write result to "); + fprintf(stdout, " fpga_compress -v ... \n"); + fprintf(stdout, " Extract Version Information from FPGA bitstream files and write it to \n\n"); + fprintf(stdout, " fpga_compress -d \n"); + fprintf(stdout, " Decompress . Write result to \n\n"); + fprintf(stdout, " fpga_compress -t \n"); + fprintf(stdout, " Compress hardnested table . Write result to \n\n"); } @@ -60,7 +65,7 @@ static voidpf fpga_deflate_malloc(voidpf opaque, uInt items, uInt size) static void fpga_deflate_free(voidpf opaque, voidpf address) { - return free(address); + free(address); } @@ -252,9 +257,152 @@ int zlib_decompress(FILE *infile, FILE *outfile) } +/* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence + * 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01 + * After that the format is 1 byte section type (ASCII character), 2 byte length + * (big endian), bytes content. Except for section 'e' which has 4 bytes + * length. + */ +static int bitparse_find_section(FILE *infile, char section_name, unsigned int *section_length) +{ + int result = 0; + #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section + uint16_t numbytes = 0; + while (numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) { + char current_name = (char)fgetc(infile); + numbytes++; + if (current_name < 'a' || current_name > 'e') { + /* Strange section name, abort */ + break; + } + unsigned int current_length = 0; + switch (current_name) { + case 'e': + /* Four byte length field */ + current_length += fgetc(infile) << 24; + current_length += fgetc(infile) << 16; + numbytes += 2; + default: /* Fall through, two byte length field */ + current_length += fgetc(infile) << 8; + current_length += fgetc(infile) << 0; + numbytes += 2; + } + + if (current_name != 'e' && current_length > 255) { + /* Maybe a parse error */ + break; + } + + if (current_name == section_name) { + /* Found it */ + *section_length = current_length; + result = 1; + break; + } + + for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) { + (void)fgetc(infile); + numbytes++; + } + } + return result; +} + +static int FpgaGatherVersion(FILE *infile, char* infile_name, char *dst, int len) +{ + unsigned int fpga_info_len; + char tempstr[40] = {0x00}; + + dst[0] = '\0'; + + for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) { + if (fgetc(infile) != bitparse_fixed_header[i]) { + fprintf(stderr, "Invalid FPGA file. Aborting...\n\n"); + return(EXIT_FAILURE); + } + } + + if (!memcmp("fpga_lf", basename(infile_name), 7)) + strncat(dst, "LF", len-1); + else if (!memcmp("fpga_hf", basename(infile_name), 7)) + strncat(dst, "HF", len-1); + + strncat(dst, " image built", len-1); + if (bitparse_find_section(infile, 'b', &fpga_info_len)) { + strncat(dst, " for ", len-1); + for (uint16_t i = 0; i < fpga_info_len; i++) { + char c = (char)fgetc(infile); + if (i < sizeof(tempstr)) { + tempstr[i] = c; + } + } + strncat(dst, tempstr, len-1); + } + + if (bitparse_find_section(infile, 'c', &fpga_info_len)) { + strncat(dst, " on ", len-1); + for (uint16_t i = 0; i < fpga_info_len; i++) { + char c = (char)fgetc(infile); + if (i < sizeof(tempstr)) { + tempstr[i] = c; + } + } + strncat(dst, tempstr, len-1); + } + + if (bitparse_find_section(infile, 'd', &fpga_info_len)) { + strncat(dst, " at ", len-1); + for (uint16_t i = 0; i < fpga_info_len; i++) { + char c = (char)fgetc(infile); + if (i < sizeof(tempstr)) { + tempstr[i] = c; + } + } + strncat(dst, tempstr, len-1); + } + return 0; +} + +static void print_version_info_preamble(FILE *outfile, int num_infiles) { + fprintf(outfile, "//-----------------------------------------------------------------------------\n"); + fprintf(outfile, "// piwi, 2018\n"); + fprintf(outfile, "//\n"); + fprintf(outfile, "// This code is licensed to you under the terms of the GNU GPL, version 2 or,\n"); + fprintf(outfile, "// at your option, any later version. See the LICENSE.txt file for the text of\n"); + fprintf(outfile, "// the license.\n"); + fprintf(outfile, "//-----------------------------------------------------------------------------\n"); + fprintf(outfile, "// Version information on fpga images\n"); + fprintf(outfile, "//\n"); + fprintf(outfile, "// This file is generated by fpga_compress. Don't edit!\n"); + fprintf(outfile, "//-----------------------------------------------------------------------------\n"); + fprintf(outfile, "\n"); + fprintf(outfile, "\n"); + fprintf(outfile, "const int fpga_bitstream_num = %d;\n", num_infiles); + fprintf(outfile, "const char* const fpga_version_information[%d] = {\n", num_infiles); +} + +static int generate_fpga_version_info(FILE *infile[], char *infile_names[], int num_infiles, FILE *outfile) { + + char version_string[80] = ""; + + print_version_info_preamble(outfile, num_infiles); + + for (int i = 0; i < num_infiles; i++) { + FpgaGatherVersion(infile[i], infile_names[i], version_string, sizeof(version_string)); + fprintf(outfile, "\t\" %s\"", version_string); + if (i != num_infiles-1) { + fprintf(outfile, ","); + } + fprintf(outfile,"\n"); + } + fprintf(outfile, "};\n"); + return 0; +} + int main(int argc, char **argv) { FILE **infiles; + char **infile_names; FILE *outfile; if (argc == 1 || argc == 2) { @@ -263,6 +411,7 @@ int main(int argc, char **argv) } if (!strcmp(argv[1], "-d")) { // Decompress + infiles = calloc(1, sizeof(FILE*)); if (argc != 4) { usage(); @@ -270,47 +419,56 @@ int main(int argc, char **argv) } infiles[0] = fopen(argv[2], "rb"); if (infiles[0] == NULL) { - fprintf(stderr, "Error. Cannot open input file %s", argv[2]); + fprintf(stderr, "Error. Cannot open input file %s\n\n", argv[2]); return(EXIT_FAILURE); } outfile = fopen(argv[3], "wb"); if (outfile == NULL) { - fprintf(stderr, "Error. Cannot open output file %s", argv[3]); + fprintf(stderr, "Error. Cannot open output file %s\n\n", argv[3]); return(EXIT_FAILURE); } return zlib_decompress(infiles[0], outfile); - } else { // Compress + } else { // Compress or gemerate version info bool hardnested_mode = false; + bool generate_version_file = false; int num_input_files = 0; - if (!strcmp(argv[1], "-t")) { // hardnested table + if (!strcmp(argv[1], "-t")) { // compress one hardnested table if (argc != 4) { usage(); return(EXIT_FAILURE); } hardnested_mode = true; num_input_files = 1; - } else { + } else if (!strcmp(argv[1], "-v")) { // generate version info + generate_version_file = true; + num_input_files = argc-3; + } else { // compress 1..n fpga files num_input_files = argc-2; } - int adder = (hardnested_mode) ? 2 : 1; infiles = calloc(num_input_files, sizeof(FILE*)); + infile_names = calloc(num_input_files, sizeof(char*)); for (uint16_t i = 0; i < num_input_files; i++) { - infiles[i] = fopen(argv[i + adder ] , "rb"); + infile_names[i] = argv[i+((hardnested_mode || generate_version_file)?2:1)]; + infiles[i] = fopen(infile_names[i], "rb"); if (infiles[i] == NULL) { - fprintf(stderr, "Error. Cannot open input file %s", argv[i + adder] ); + fprintf(stderr, "Error. Cannot open input file %s\n\n", infile_names[i]); return(EXIT_FAILURE); - } else { - printf("Opening %s %d \n", argv[i + adder], i+adder ); } } outfile = fopen(argv[argc-1], "wb"); if (outfile == NULL) { - fprintf(stderr, "Error. Cannot open output file %s", argv[argc-1]); + fprintf(stderr, "Error. Cannot open output file %s\n\n", argv[argc-1]); return(EXIT_FAILURE); } + if (generate_version_file) { + if (generate_fpga_version_info(infiles, infile_names, num_input_files, outfile)) { + return(EXIT_FAILURE); + } + } else { return zlib_compress(infiles, num_input_files, outfile, hardnested_mode); + } } } diff --git a/common/Makefile.common b/common/Makefile.common index ec291e44a..59ac01f29 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -71,7 +71,7 @@ LIBS = -lgcc THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(THUMBSRC))) ARMOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(ARMSRC))) ASMOBJ = $(patsubst %.s,$(OBJDIR)/%.o,$(notdir $(ASMSRC))) -VERSIONOBJ = $(OBJDIR)/version.o +VERSIONOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(VERSIONSRC))) $(THUMBOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(CC) $(CFLAGS) -mthumb -mthumb-interwork -o $@ $< @@ -95,11 +95,6 @@ OBJCOPY_TRANSLATIONS = --no-change-warnings \ $(OBJDIR)/%.s19: $(OBJDIR)/%.elf $(OBJCOPY) -Osrec --srec-forceS3 --strip-debug $(OBJCOPY_TRANSLATIONS) $^ $@ -# version.c should be remade on every compilation -.PHONY: version.c -version.c: default_version.c - perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ - # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/common/fpga.h b/common/fpga.h new file mode 100644 index 000000000..b99a75935 --- /dev/null +++ b/common/fpga.h @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- + +#ifndef __FPGA_H +#define __FPGA_H + +#define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(bitparse_fixed_header) +#define FPGA_INTERLEAVE_SIZE 288 +#define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE + +static const uint8_t bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01}; +extern const int fpga_bitstream_num; +extern const char* const fpga_version_information[]; + +#endif