From b7a43cd4ea77cb93230778a52ef4b6f7d4e34eca Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Tue, 24 May 2022 12:04:08 -0230 Subject: [PATCH 01/24] Create Makefile --- lib_jtag_core/test/linux/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 lib_jtag_core/test/linux/Makefile diff --git a/lib_jtag_core/test/linux/Makefile b/lib_jtag_core/test/linux/Makefile new file mode 100644 index 0000000..ce3d3a4 --- /dev/null +++ b/lib_jtag_core/test/linux/Makefile @@ -0,0 +1,9 @@ +EXEC=a.out + +clean: + rm -rf *.o + +mrproper: clean + rm -rf $(EXEC) + +.PHONY: clean mrproper From 9b7ad98e41545ec90f41e072dfad31474b237ee8 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Tue, 24 May 2022 12:06:05 -0230 Subject: [PATCH 02/24] Demonstration of BSDL File Parser --- lib_jtag_core/test/linux/BSDLtoFloorplan.c | 33 ++++++++++++++ lib_jtag_core/test/linux/Makefile | 50 ++++++++++++++++++---- 2 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 lib_jtag_core/test/linux/BSDLtoFloorplan.c diff --git a/lib_jtag_core/test/linux/BSDLtoFloorplan.c b/lib_jtag_core/test/linux/BSDLtoFloorplan.c new file mode 100644 index 0000000..b0e59bb --- /dev/null +++ b/lib_jtag_core/test/linux/BSDLtoFloorplan.c @@ -0,0 +1,33 @@ +#include +#include +#include "jtag_core.h" +#include "bsdl_parser/bsdl_loader.h" +#include "bsdl_parser/bsdl_strings.h" + +int main(int argc,char * argv[]) { + if(argc > 1) { + jtag_core * jc = jtagcore_init(); + if (jc != NULL ) { + jtag_bsdl * details = load_bsdlfile(jc, argv[1]); + if ( details != NULL ) { + unsigned long id = details->chip_id; + int irLength = details->number_of_bits_per_instruction; + if(irLength>0) { + printf("Chip ID %0lx OK: uses %i-bit OPCODES\r\n",id,irLength); + } else { + printf("BSDL file for chip ID %0lx has unsupported OPCODE length\r\n",id); + } + unload_bsdlfile(jc,details); + details = NULL; + } else { + printf("Unable to parse file %s\r\n",argv[1]); + } + + jtagcore_deinit(jc); + return 0; + } + jtagcore_deinit(NULL); + return 1; + } + return -1; +} diff --git a/lib_jtag_core/test/linux/Makefile b/lib_jtag_core/test/linux/Makefile index ce3d3a4..4a0ee42 100644 --- a/lib_jtag_core/test/linux/Makefile +++ b/lib_jtag_core/test/linux/Makefile @@ -1,9 +1,41 @@ -EXEC=a.out - -clean: - rm -rf *.o - -mrproper: clean - rm -rf $(EXEC) - -.PHONY: clean mrproper +CC ?= gcc +AR ?= ar + +UNAME := $(shell uname) + +BASEDIR=../../src +INCLUDES = -I$(BASEDIR)/ + +CFLAGS=-O3 $(INCLUDES) -Wall -pthread + +LIBDIR=../../build/linux +LIB=libjtag_core.so +EXEC=BSDLtoFloorplan + +ifeq ($(UNAME), Linux) +CFLAGS += -fPIC +endif + +ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) +LIB=libjtag_core.dll +EXEC=BSDLtoFloorplan.exe +endif + +ifeq ($(UNAME), Darwin) +CFLAGS += -arch i386 -mmacosx-version-min=10.5 +LIB=libjtag_core.dylib +EXEC=BSDLtoFloorplan.exe +endif + +all: $(EXEC) + +BSDLtoFloorplan: BSDLtoFloorplan.c + $(CC) -o $@ $^ $(CFLAGS) "$(LIBDIR)/$(LIB)" + +clean: + rm -rf *.o + +mrproper: clean + rm -rf $(EXEC) + +.PHONY: clean mrproper From b06b225fb6b191db43a8b8df4dfa939966969bb3 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Mon, 6 Jun 2022 13:36:23 -0230 Subject: [PATCH 03/24] Converted test application to C++ --- lib_jtag_core/src/bsdl_parser/bsdl_loader.h | 7 +++++++ lib_jtag_core/src/bsdl_parser/bsdl_strings.h | 8 ++++++++ lib_jtag_core/src/jtag_core.h | 7 +++++++ .../linux/{BSDLtoFloorplan.c => BSDLtoFloorplan.cpp} | 10 +++++++--- lib_jtag_core/test/linux/Makefile | 4 ++-- 5 files changed, 31 insertions(+), 5 deletions(-) rename lib_jtag_core/test/linux/{BSDLtoFloorplan.c => BSDLtoFloorplan.cpp} (62%) diff --git a/lib_jtag_core/src/bsdl_parser/bsdl_loader.h b/lib_jtag_core/src/bsdl_parser/bsdl_loader.h index 3237815..bc6c0e4 100644 --- a/lib_jtag_core/src/bsdl_parser/bsdl_loader.h +++ b/lib_jtag_core/src/bsdl_parser/bsdl_loader.h @@ -22,6 +22,9 @@ * @brief bsdl file parser header * @author Jean-François DEL NERO */ +#ifdef __cplusplus +extern "C" { +#endif #define MAX_ELEMENT_SIZE (64+1) @@ -78,3 +81,7 @@ typedef struct _jtag_bsdl jtag_bsdl * load_bsdlfile(jtag_core * jc,char *filename); void unload_bsdlfile(jtag_core * jc, jtag_bsdl * bsdl); + +#ifdef __cplusplus +} +#endif diff --git a/lib_jtag_core/src/bsdl_parser/bsdl_strings.h b/lib_jtag_core/src/bsdl_parser/bsdl_strings.h index 0781cb4..c1b5256 100644 --- a/lib_jtag_core/src/bsdl_parser/bsdl_strings.h +++ b/lib_jtag_core/src/bsdl_parser/bsdl_strings.h @@ -22,6 +22,10 @@ * @brief bsdl file string keywords header * @author Jean-François DEL NERO */ +#ifdef __cplusplus +extern "C" { +#endif + typedef struct type_strings_ { @@ -75,3 +79,7 @@ extern type_strings statetype_str[]; extern type_strings pintype_str[]; int get_typecode(type_strings * typelist,char * name); + +#ifdef __cplusplus +} +#endif diff --git a/lib_jtag_core/src/jtag_core.h b/lib_jtag_core/src/jtag_core.h index a84b342..e2db94e 100644 --- a/lib_jtag_core/src/jtag_core.h +++ b/lib_jtag_core/src/jtag_core.h @@ -22,6 +22,9 @@ * @brief Main jtag core library header * @author Jean-François DEL NERO */ +#ifdef __cplusplus +extern "C" { +#endif #ifndef _jtag_core_ typedef void jtag_core; @@ -318,3 +321,7 @@ int jtagcore_execScriptRam( script_ctx * ctx, unsigned char * script_buffer, in script_ctx * jtagcore_deinitScript( script_ctx * ctx ); int jtagcore_savePinsStateScript( jtag_core * jc, int device, char * script_path ); + +#ifdef __cplusplus +} +#endif diff --git a/lib_jtag_core/test/linux/BSDLtoFloorplan.c b/lib_jtag_core/test/linux/BSDLtoFloorplan.cpp similarity index 62% rename from lib_jtag_core/test/linux/BSDLtoFloorplan.c rename to lib_jtag_core/test/linux/BSDLtoFloorplan.cpp index b0e59bb..867a609 100644 --- a/lib_jtag_core/test/linux/BSDLtoFloorplan.c +++ b/lib_jtag_core/test/linux/BSDLtoFloorplan.cpp @@ -11,11 +11,15 @@ int main(int argc,char * argv[]) { jtag_bsdl * details = load_bsdlfile(jc, argv[1]); if ( details != NULL ) { unsigned long id = details->chip_id; - int irLength = details->number_of_bits_per_instruction; + int irLength = details->number_of_bits_per_instruction; if(irLength>0) { - printf("Chip ID %0lx OK: uses %i-bit OPCODES\r\n",id,irLength); + int chainCount = details->number_of_chainbits; + int pinCount = details->number_of_pins; + printf("Chip ID %0lx OK: uses %i-bit OPCODES\r\n",id,irLength); + printf("Chip ID %0lx OK: has %i pins with %i chains\r\n",id,pinCount,chainCount); + } else { - printf("BSDL file for chip ID %0lx has unsupported OPCODE length\r\n",id); + printf("BSDL file for chip ID %0lx has unsupported OPCODE length\r\n",id); } unload_bsdlfile(jc,details); details = NULL; diff --git a/lib_jtag_core/test/linux/Makefile b/lib_jtag_core/test/linux/Makefile index 4a0ee42..df1502d 100644 --- a/lib_jtag_core/test/linux/Makefile +++ b/lib_jtag_core/test/linux/Makefile @@ -1,4 +1,4 @@ -CC ?= gcc +CC ?= g++ AR ?= ar UNAME := $(shell uname) @@ -29,7 +29,7 @@ endif all: $(EXEC) -BSDLtoFloorplan: BSDLtoFloorplan.c +BSDLtoFloorplan: BSDLtoFloorplan.cpp $(CC) -o $@ $^ $(CFLAGS) "$(LIBDIR)/$(LIB)" clean: From 50894281bba6024f32ba6a599bd1b325734a8c24 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Mon, 6 Jun 2022 16:14:13 -0230 Subject: [PATCH 04/24] Update ccpp.yml --- .github/workflows/ccpp.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 62a19e1..c400af7 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -1,6 +1,8 @@ name: C/C++ CI -on: [push] +on: + - push + - workflow_dispatch defaults: run: From 63b1511232d8f32af5200d9e97450071c50aa2b4 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Mon, 6 Jun 2022 16:17:34 -0230 Subject: [PATCH 05/24] test linkage --- .github/workflows/ccpp.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index c400af7..f29950d 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -16,3 +16,6 @@ jobs: - uses: actions/checkout@v1 - name: make run: make + - name: test + working-directory: ./lib_jtag_core/test/linux + run: make From 5cd743d69cdacefae6d0585a1797d4c9b3a74990 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Wed, 8 Jun 2022 15:43:43 -0230 Subject: [PATCH 06/24] Refactoring to eliminate unnecessary dependencies for BSDL parsing --- lib_jtag_core/CMakeLists.txt | 11 + lib_jtag_core/build/CMakeLists.txt | 5 + lib_jtag_core/build/linux/CMakeLists.txt | 17 + lib_jtag_core/build/linux/Makefile | 7 +- lib_jtag_core/src/CMakeLists.txt | 9 + lib_jtag_core/src/bsdl_parser/bsdl_loader.c | 1431 +---------------- lib_jtag_core/src/bsdl_parser/bsdl_loader.h | 57 +- lib_jtag_core/src/bsdl_parser/jtag_bsdl.c | 1520 +++++++++++++++++++ lib_jtag_core/src/bsdl_parser/jtag_bsdl.h | 92 ++ lib_jtag_core/src/libjtag_bsdl.h | 30 + lib_jtag_core/test/CMakeLists.txt | 5 + lib_jtag_core/test/linux/CMakeLists.txt | 9 + 12 files changed, 1711 insertions(+), 1482 deletions(-) create mode 100644 lib_jtag_core/CMakeLists.txt create mode 100644 lib_jtag_core/build/CMakeLists.txt create mode 100644 lib_jtag_core/build/linux/CMakeLists.txt create mode 100644 lib_jtag_core/src/CMakeLists.txt create mode 100644 lib_jtag_core/src/bsdl_parser/jtag_bsdl.c create mode 100644 lib_jtag_core/src/bsdl_parser/jtag_bsdl.h create mode 100644 lib_jtag_core/src/libjtag_bsdl.h create mode 100644 lib_jtag_core/test/CMakeLists.txt create mode 100644 lib_jtag_core/test/linux/CMakeLists.txt diff --git a/lib_jtag_core/CMakeLists.txt b/lib_jtag_core/CMakeLists.txt new file mode 100644 index 0000000..cddf621 --- /dev/null +++ b/lib_jtag_core/CMakeLists.txt @@ -0,0 +1,11 @@ +# CMakeLists files in this project can +# refer to the root source directory of the project as ${STREETVIEWJTAG_SOURCE_DIR} and +# to the root binary directory of the project as ${STREETVIEWJTAG_BINARY_DIR}. +cmake_minimum_required (VERSION 2.8.11) +project (STREETVIEWJTAG) + +# Recurse into the "build", "src" and "test" subdirectories. +add_subdirectory (build) +add_subdirectory (src) +add_subdirectory (test) + diff --git a/lib_jtag_core/build/CMakeLists.txt b/lib_jtag_core/build/CMakeLists.txt new file mode 100644 index 0000000..f85c8e0 --- /dev/null +++ b/lib_jtag_core/build/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 2.8.11) + +# Recurse into the "linux" subdirectory. +add_subdirectory (linux) + diff --git a/lib_jtag_core/build/linux/CMakeLists.txt b/lib_jtag_core/build/linux/CMakeLists.txt new file mode 100644 index 0000000..0f87492 --- /dev/null +++ b/lib_jtag_core/build/linux/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required (VERSION 2.8.11) + +# Build shared library in place for legacy support +add_custom_target( + libjtag_core ALL + COMMAND make all + COMMENT "Building shared library using legacy support" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_custom_target( + libjtag_static + COMMAND make libjtag_core.a + COMMENT "Building static library using legacy support" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + diff --git a/lib_jtag_core/build/linux/Makefile b/lib_jtag_core/build/linux/Makefile index 8312f24..1b6ef4c 100644 --- a/lib_jtag_core/build/linux/Makefile +++ b/lib_jtag_core/build/linux/Makefile @@ -27,7 +27,7 @@ LDFLAGS +=-arch i386 -dynamiclib -current_version 2.0 -install_name @executable_ EXEC=libjtag_core.dylib endif -LIB_JTAG_CORE = jtag_core.o dbg_logs.o bsdl_loader.o bsdl_strings.o drv_loader.o script.o env.o fs.o os_interface.o network.o +LIB_JTAG_CORE = jtag_core.o dbg_logs.o bsdl_loader.o jtag_bsdl.o bsdl_strings.o drv_loader.o script.o env.o fs.o os_interface.o network.o PROBES_DRIVERS = drivers_list.o jlink_jtag_drv.o linux_gpio_jtag_drv.o #lpt_jtag_drv.o ftdi_jtag_drv.o PROTOCOLS_DRIVERS = i2c_over_jtag.o mdio_over_jtag.o spi_over_jtag.o memory_over_jtag.o NATSORT = strnatcmp.o @@ -55,6 +55,9 @@ dbg_logs.o: $(BASEDIR)/dbg_logs.c bsdl_loader.o: $(BASEDIR)/bsdl_parser/bsdl_loader.c $(CC) -o $@ -c $< $(CFLAGS) +jtag_bsdl.o: $(BASEDIR)/bsdl_parser/jtag_bsdl.c + $(CC) -o $@ -c $< $(CFLAGS) + bsdl_strings.o: $(BASEDIR)/bsdl_parser/bsdl_strings.c $(CC) -o $@ -c $< $(CFLAGS) @@ -113,6 +116,6 @@ clean: rm -rf *.o mrproper: clean - rm -rf $(EXEC) + rm -rf $(EXEC) libjtag_core.a .PHONY: clean mrproper diff --git a/lib_jtag_core/src/CMakeLists.txt b/lib_jtag_core/src/CMakeLists.txt new file mode 100644 index 0000000..85a400d --- /dev/null +++ b/lib_jtag_core/src/CMakeLists.txt @@ -0,0 +1,9 @@ +# build a reduced library that supports BSDL parsing only +set(JTAG_BSDL_SRC + bsdl_parser/jtag_bsdl.c + bsdl_parser/bsdl_strings.c + natsort/strnatcmp.c +) + +add_library(jtag_bsdl ${JTAG_BSDL_SRC}) + diff --git a/lib_jtag_core/src/bsdl_parser/bsdl_loader.c b/lib_jtag_core/src/bsdl_parser/bsdl_loader.c index b5612c0..4ddf4f5 100644 --- a/lib_jtag_core/src/bsdl_parser/bsdl_loader.c +++ b/lib_jtag_core/src/bsdl_parser/bsdl_loader.c @@ -40,1439 +40,14 @@ #include "../dbg_logs.h" #define DEBUG 1 -char *string_upper(char *str) -{ - while (*str != '\0') - { - *str = toupper((unsigned char)*str); - str++; - } - return str; -} - -int strcmp_nocase(char *str1,char *str2) -{ - int d; - - for(;; str1++, str2++) - { - d = tolower(*str1) - tolower(*str2); - - if(d != 0 || !*str1) - return d; - } - - return 0; -} - -int getnextvalidline(char *buffer,int buffersize,int * offset) -{ - int l_offset; - int current_line_offset; - - l_offset = *offset; - current_line_offset = *offset; - - do - { - // Skip all the blank characters - while( (l_offset < buffersize) && (buffer[l_offset] == ' ' || buffer[l_offset] == '\t') ) - { - l_offset++; - } - - // Is it a return or comment ? - if( buffer[l_offset] != '\r' && buffer[l_offset] != '\n' && (buffer[l_offset] != '-' || buffer[l_offset+1] != '-')) - { - // No. There is something interesting into this line. - *offset = current_line_offset; - return 0; - } - else - { - // Is it a comment ? - if(buffer[l_offset] == '-' && buffer[l_offset+1] == '-') - { - // Yes. Go to the end of the line... - while(buffer[l_offset] != 0 && buffer[l_offset] != '\r' && buffer[l_offset] != '\n') - { - l_offset += 1; - } - } - } - - if( buffer[l_offset] == '\r' || buffer[l_offset] == '\n') - { - l_offset++; - if( buffer[l_offset] == '\n' ) - { - l_offset++; - } - - current_line_offset = l_offset; - } - }while ( buffer[l_offset] ); - - *offset = l_offset; - - return 1; - -} - -char getnextchar(char *buffer,int buffersize,int * offset) -{ - char c; - - if (*offset < buffersize) - { - c = buffer[*offset]; - - switch (c) - { - case 0: - return 0; - break; - - case '\r': - *offset += 1; - - if (*offset < buffersize) - { - if (buffer[*offset] == '\n') - { - *offset += 1; - } - - getnextvalidline(buffer, buffersize, offset); - } - - return ' '; - break; - case '\t': - *offset += 1; - return ' '; - break; - case '\n': - *offset += 1; - getnextvalidline(buffer, buffersize, offset); - return ' '; - break; - case '-': - if (buffer[*offset + 1] == '-') - { - while ((*offset < buffersize) && buffer[*offset] != 0 && buffer[*offset] != '\r' && buffer[*offset] != '\n') - { - *offset += 1; - } - - if (*offset < buffersize) - { - if (buffer[*offset] == '\r') - { - *offset += 1; - if (buffer[*offset] == '\n') - { - *offset += 1; - } - - getnextvalidline(buffer, buffersize, offset); - - return ' '; - } - - if (buffer[*offset] == '\n') - { - *offset += 1; - getnextvalidline(buffer, buffersize, offset); - - return ' '; - } - } - else - return 0; - - return ' '; - } - else - { - *offset += 1; - return '-'; - } - - break; - - default: - *offset += 1; - return c; - break; - } - } - - return 0; -} - -int extract_bsdl_lines(char * bsdl_txt, char ** lines) -{ - int offset; - int line_start_offset; - int line_end_offset; - int endofline; - int parenthesis_number; - int inside_quote; - int number_of_lines; - - offset = 0; - number_of_lines = 0; - - do - { - // Find the first word offset into the line... - while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) - { - offset++; - } - - line_start_offset = offset; - - parenthesis_number = 0; - endofline = 0; - inside_quote = 0; - - // Scan the line - while( !endofline ) - { - switch( bsdl_txt[offset] ) - { - case 0: - endofline = 1; - break; - - case '(': - if( !inside_quote ) - parenthesis_number++; - offset++; - break; - case ')': - if(parenthesis_number && !inside_quote) - parenthesis_number--; - offset++; - break; - case ';': - if( !parenthesis_number && !inside_quote ) - { - line_end_offset = offset; - - if( line_end_offset - line_start_offset > 0 ) - { - if(lines) - { - lines[number_of_lines] = malloc( (line_end_offset - line_start_offset) + 2 ); - if( lines[number_of_lines] ) - { - memset(lines[number_of_lines],0, (line_end_offset - line_start_offset) + 2 ); - memcpy(lines[number_of_lines],&bsdl_txt[line_start_offset], (line_end_offset - line_start_offset) ); - } - } - - number_of_lines++; - } - - endofline = 1; - - } - offset++; - break; - - case '"': - if(!inside_quote) - inside_quote = 1; - else - inside_quote = 0; - - offset++; - break; - - default: - offset++; - break; - } - } - }while(bsdl_txt[offset]); - - return number_of_lines; -} - -void preprocess_line(char * line) -{ - int inside_quote; - int read_offset,write_offset; - int is_string; - int number_of_spaces; - - inside_quote = 0; - read_offset = 0; - write_offset = 0; - number_of_spaces = 0; - - // first pass : remove extra blank - while( line[read_offset] ) - { - switch( line[read_offset] ) - { - case ' ': - - if(!number_of_spaces || inside_quote) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - - read_offset++; - number_of_spaces++; - - break; - - case '"': - if(!inside_quote) - inside_quote = 1; - else - inside_quote = 0; - - line[write_offset] = line[read_offset]; - write_offset++; - read_offset++; - number_of_spaces = 0; - - break; - - default: - line[write_offset] = line[read_offset]; - number_of_spaces = 0; - - write_offset++; - read_offset++; - break; - - } - } - - line[write_offset] = 0; - - // second pass : concatenate strings. - - inside_quote = 0; - read_offset = 0; - write_offset = 0; - number_of_spaces = 0; - is_string = 0; - - while( line[read_offset] ) - { - switch( line[read_offset] ) - { - - case '&': - if( inside_quote || !is_string) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - read_offset++; - break; - - case ' ': - if( inside_quote || !is_string) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - read_offset++; - break; - - case '"': - if(!inside_quote) - { - inside_quote = 1; - if( !is_string ) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - - is_string = 1; - } - else - { - inside_quote = 0; - - } - - read_offset++; - break; - - default: - if( !inside_quote ) - { - if( is_string ) - { - line[write_offset] = '"'; - write_offset++; - } - is_string = 0; - } - - line[write_offset] = line[read_offset]; - - write_offset++; - read_offset++; - break; - - } - } - - if( is_string ) - { - line[write_offset] = '"'; - write_offset++; - line[write_offset] = 0; - } -}; - -char * check_next_keyword(char * buffer, char * keyword) -{ - int i; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\"() ", buffer[i]) ) - { - i++; - } - - // skip the following blank - while (buffer[i] && strchr("\"() ", buffer[i]) ) - { - i++; - } - - if( !strncmp(&buffer[i],keyword,strlen(keyword)) ) - { - return &buffer[i + strlen(keyword)]; - } - - return 0; -} - -int get_next_keyword(jtag_core * jc,char * buffer, char * keyword) -{ - int i,j; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\"():, ", buffer[i]) ) - { - i++; - } - - // skip the following blank - while (buffer[i] && strchr("\"():, ", buffer[i])) - { - i++; - } - - // copy the word - j = 0; - while (buffer[i] && !strchr("\"():;, ", buffer[i])) - { - if(j < MAX_ELEMENT_SIZE-1) - { - keyword[j] = buffer[i]; - j++; - } - i++; - } - - keyword[j] = 0; - - if( j >= (MAX_ELEMENT_SIZE-1) ) - { - jtagcore_logs_printf(jc,MSG_WARNING,"BSDL loader / get_next_keyword : element too long / truncated : %s\r\n",keyword); - } - - return i; -} - -int get_next_parameter(jtag_core * jc,char * buffer, char * parameter) -{ - int i,j; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\":, ", buffer[i])) - { - i++; - } - - // skip the following blank - while (buffer[i] && strchr("\":, ", buffer[i])) - { - i++; - } - - // copy the word - j = 0; - while (buffer[i] && !strchr("\":, ;", buffer[i])) - { - if(j < MAX_ELEMENT_SIZE-1) - { - parameter[j] = buffer[i]; - j++; - } - i++; - } - - parameter[j] = 0; - - if( j >= (MAX_ELEMENT_SIZE-1) ) - { - jtagcore_logs_printf(jc,MSG_WARNING,"BSDL loader / get_next_parameter : element too long / truncated : %s\r\n",parameter); - } - - return i; -} - -int check_next_symbol(char * buffer, char c ) -{ - int i; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\"(): ", buffer[i]) && buffer[i] != c) - { - i++; - } - - // skip the following blank - while(buffer[i] && ( buffer[i] == ' ') ) - { - i++; - } - - if( buffer[i] == c ) - { - return i; - } - else - { - return -1; - } -} - -char * get_attribut(char ** lines,char * name, char * entity) -{ - int i,j; - char * ptr; - i = 0; - - do - { - if(!strncmp(lines[i],"attribute ",10)) - { - if(!strncmp(&lines[i][10],name,strlen(name))) - { - ptr = check_next_keyword(&lines[i][10], "of"); - ptr = check_next_keyword(ptr, entity); - - if( ptr ) - { - j = 0; - while( ptr[j] && ptr[j] != ':' && ptr[j] == ' ') - { - j++; - } - - if( ptr[j] == ':' ) - { - ptr = check_next_keyword(&ptr[j], "entity"); - ptr = check_next_keyword(ptr, "is"); - - return ptr; - - } - } - - return 0; - } - } - i++; - }while( lines[i] ); - - return 0; -} - -char * get_attribut_txt(char ** lines,char * name, char * entity) -{ - int i; - char * attribut_data; - - attribut_data = get_attribut(lines,name, entity); - - if( attribut_data ) - { - i = 0; - while( attribut_data[i] && attribut_data[i]!='"') - { - i++; - } - - if( attribut_data[i] == '"' ) - { - return &attribut_data[i]; - } - - return 0; - } - - return 0; -} - -int get_attribut_int(char ** lines,char * name, char * entity) -{ - int i; - char * attribut_data; - - attribut_data = get_attribut(lines,name, entity); - - if( attribut_data ) - { - i = 0; - while( attribut_data[i] && !( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) - { - i++; - } - - if( ( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) - { - return atoi(&attribut_data[i]); - } - - return 0; - } - - return 0; -} - -int get_next_pin(jtag_core * jc,char * name,int * type, char *line, int * start_index, int * end_index ) -{ - int i; - int io_list_offset; - char tmp_str[256]; - int line_parsed,inside_block; - - i = get_next_keyword(jc,line,name); - - io_list_offset = 0; - - while(line[i] == ' ') - i++; - - if( line[i] == ':' || line[i] == ',' ) - { - *start_index = 0; - *end_index = 0; - - if( line[i] == ',' ) - { - io_list_offset = i + 1; - - while(line[i] != ':' && line[i] != ';' && line[i]) - i++; - if( line[i] != ':' ) - return 0; - } - - i += get_next_keyword(jc,&line[i],(char*)&tmp_str); - - string_upper(tmp_str); - - *type = get_typecode(pintype_str,tmp_str); - - i += get_next_keyword(jc,&line[i],(char*)&tmp_str); - - if (!strcmp_nocase("bit_vector",tmp_str)) - { - while(line[i] != '(' && line[i] != ')' && line[i] != ';') - { - i++; - } - - line_parsed = 0; - inside_block = 0; - - do - { - - switch( line[i] ) - { - case '(': - inside_block++; - if(!line_parsed) - { - i += get_next_keyword(jc,&line[i],(char*)&tmp_str); - *start_index = atoi(tmp_str); - - i += get_next_keyword(jc,&line[i],(char*)&tmp_str); - - i += get_next_keyword(jc,&line[i],(char*)&tmp_str); - *end_index = atoi(tmp_str); - - line_parsed = 1; - - } - break; - case ')': - if ( !inside_block ) - { - return 0; - } - - inside_block--; - break; - case ';': - if( io_list_offset ) - return io_list_offset; - else - return i; - break; - case 0: - break; - - } - i++; - }while (line[i]); - - return 0; - } - - if (!strcmp_nocase("bit",tmp_str)) - { - do - { - switch( line[i] ) - { - case ';': - if( io_list_offset ) - return io_list_offset; - else - return i; - break; - case 0: - break; - } - i++; - }while (line[i]); - } - - } - - return 0; -} - -int get_pins_list(jtag_core * jc,jtag_bsdl * bsdl_desc,char ** lines) -{ - int i,j,k,inc,offset, number_of_pins,vector_size; - char tmp_str[MAX_ELEMENT_SIZE]; - int tmp_type,tmp_start,tmp_end; - i = 0; - - while( lines[i] ) - { - if( !strncmp(lines[i],"port ",5) || !strncmp(lines[i],"port(",5)) - { - j = 0; - number_of_pins = 0; - - while( lines[i][j] != '(' && lines[i][j]) - { - j++; - } - - do - { - offset = get_next_pin(jc,(char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); - - if( tmp_start <=tmp_end) - { - number_of_pins += ( (tmp_end - tmp_start) + 1 ); - } - else - { - number_of_pins += ( (tmp_start - tmp_end) + 1 ); - } - - j += offset; - - } while( offset); - - if (number_of_pins == 0 || ( number_of_pins > MAX_NUMBER_PINS_PER_DEV ) ) - { - jtagcore_logs_printf(jc, MSG_ERROR, "get_pins_list : bad number of pin found ! : %d\r\n", number_of_pins); - return -1; - } - - bsdl_desc->pins_list = malloc (sizeof(pin_ctrl) * (number_of_pins+1)); - if( bsdl_desc->pins_list ) - { - memset( bsdl_desc->pins_list, 0, sizeof(pin_ctrl) * (number_of_pins+1) ); - - j = 0; - number_of_pins = 0; - - while( lines[i][j] != '(' && lines[i][j]) - { - j++; - } - - do - { - offset = get_next_pin(jc,(char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); - - if( tmp_start <= tmp_end ) - { - vector_size = ( (tmp_end - tmp_start) + 1 ); - inc = 1; - } - else - { - vector_size = ( (tmp_start - tmp_end) + 1 ); - inc = -1; - } - - j += offset; - - for(k = 0;k < vector_size; k++) - { - snprintf((char*)&bsdl_desc->pins_list[number_of_pins].pinname,sizeof(((pin_ctrl *)0)->pinname),"%s",(char*)tmp_str); - - if( vector_size > 1 ) - { - char digistr[32]; - snprintf((char*)digistr,sizeof(digistr),"(%d)",tmp_start); - strncat((char*)&bsdl_desc->pins_list[number_of_pins].pinname,digistr,sizeof(((pin_ctrl *)0)->pinname)-1); - } - - bsdl_desc->pins_list[number_of_pins].pintype = tmp_type; - number_of_pins++; - tmp_start += inc; - } - - } while( offset ); - - bsdl_desc->number_of_pins = number_of_pins; - - return number_of_pins; - } - } - i++; - }; - - return 0; -} - -int get_jtag_chain(jtag_core * jc,jtag_bsdl * bsdl_desc,char ** lines, char * entityname) -{ - char * jtagchain_str; - int i,j,bit_count,end_parse; - char tmp_str[MAX_ELEMENT_SIZE]; - int bit_index; - - bit_count = 0; - bsdl_desc->number_of_chainbits = get_attribut_int(lines,"BOUNDARY_LENGTH", entityname); - if ( ( bsdl_desc->number_of_chainbits > 0 ) && ( bsdl_desc->number_of_chainbits < MAX_NUMBER_BITS_IN_CHAIN ) ) - { - jtagcore_logs_printf(jc,MSG_DEBUG,"Number of bit in the chain = %d\r\n",bsdl_desc->number_of_chainbits); - - bsdl_desc->chain_list = malloc( sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); - if( !bsdl_desc->chain_list ) - { - jtagcore_logs_printf(jc,MSG_ERROR,"get_jtag_chain : memory alloc error !\r\n"); - return -1; - } - - memset(bsdl_desc->chain_list,0, sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); - - jtagchain_str = get_attribut_txt(lines,"BOUNDARY_REGISTER", entityname); - - end_parse = 0; - - if(jtagchain_str) - { - if( jtagchain_str[0] == '"' ) - { - i = 0; - while( jtagchain_str[i] && !end_parse ) - { - jtagcore_logs_printf(jc,MSG_DEBUG,"--------------\r\n"); - - // Get index - i += get_next_keyword(jc,&jtagchain_str[i], tmp_str); - bit_index = atoi(tmp_str); - if (bit_index >= 0 && bit_index < bsdl_desc->number_of_chainbits) - { - bsdl_desc->chain_list[bit_index].bit_index = bit_index; - - jtagcore_logs_printf(jc, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_index); - - // Look for ( - while (jtagchain_str[i] != '(' && jtagchain_str[i]) - i++; - - // Get the pin type - i += get_next_keyword(jc,&jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].bit_cell_type = get_typecode(celltype_str, tmp_str); - - jtagcore_logs_printf(jc, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_cell_type); - - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the name - i += get_next_parameter(jc,&jtagchain_str[i], bsdl_desc->chain_list[bit_index].pinname); - - jtagcore_logs_printf(jc, MSG_DEBUG, "%s\r\n", bsdl_desc->chain_list[bit_index].pinname); - - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the type - i += get_next_keyword(jc,&jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].bit_type = get_typecode(bittype_str, tmp_str); - - jtagcore_logs_printf(jc, MSG_DEBUG, "%s , %d\r\n", tmp_str, bsdl_desc->chain_list[bit_index].bit_type); - - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the default state - i += get_next_keyword(jc,&jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].safe_state = get_typecode(statetype_str, tmp_str); - - bsdl_desc->chain_list[bit_index].control_bit_index = -1; - - // If no ) Get the ctrl index - j = check_next_symbol(&jtagchain_str[i], ')'); - - if (jtagchain_str[i]==',' || j < 0) - { - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the control bit - i += get_next_keyword(jc,&jtagchain_str[i], tmp_str); - - bsdl_desc->chain_list[bit_index].control_bit_index = atoi(tmp_str); - - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the polarity - i += get_next_keyword(jc,&jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].control_disable_state = get_typecode(statetype_str, tmp_str); - - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the off state - i += get_next_keyword(jc,&jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].control_disable_result = get_typecode(statetype_str, tmp_str); - - // Find and skip ) - j = check_next_symbol(&jtagchain_str[i], ')'); - if (j < 0) - return -1; - } - - i += j; - - // Find , (Next bit) or " (End of the chain) - i++; - bit_count++; - - if (check_next_symbol(&jtagchain_str[i], '"') >= 0) - { - end_parse = 1; - } - } - else - { - jtagcore_logs_printf(jc, MSG_ERROR, "get_jtag_chain : Error bit index overrun !\r\n"); - } - } - } - } - } - - if( ( bit_count == bsdl_desc->number_of_chainbits ) && ( bsdl_desc->number_of_chainbits != 0 ) ) - { - jtagcore_logs_printf(jc,MSG_DEBUG,"Jtag chain parsing Ok !\r\n"); - - for( i = 0 ; i < (long)bsdl_desc->number_of_pins ; i++ ) - { - - bsdl_desc->pins_list[i].in_bit_number = -1; - bsdl_desc->pins_list[i].out_bit_number = -1; - bsdl_desc->pins_list[i].ctrl_bit_number = -1; - - switch( bsdl_desc->pins_list[i].pintype) - { - case IO_IN: - case IO_OUT: - case IO_INOUT: - - for( j = 0 ; j < (long)bsdl_desc->number_of_chainbits ; j++ ) - { - if(!strcmp(bsdl_desc->chain_list[j].pinname, bsdl_desc->pins_list[i].pinname)) - { - switch( bsdl_desc->chain_list[j].bit_type) - { - case BITTYPE_INPUT: - bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; - break; - case BITTYPE_OUTPUT: - bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; - break; - case BITTYPE_TRISTATE_OUTPUT: - bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; - bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; - break; - case BITTYPE_INOUT: - bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; - bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; - bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; - break; - } - } - } - break; - } - } - - return 1; - } - else - { - jtagcore_logs_printf(jc,MSG_DEBUG,"JTAG chain parsing error : %d - %d !\r\n",bit_count,bsdl_desc->number_of_chainbits); - return -1; - } -} - -static int compare_pin_name(const void *a, const void *b) -{ - int ret; - pin_ctrl const *pa = (pin_ctrl const *)a; - pin_ctrl const *pb = (pin_ctrl const *)b; - - ret = strnatcmp(pa->pinname, pb->pinname); - - return ret; -} jtag_bsdl * load_bsdlfile(jtag_core * jc,char *filename) { - FILE * bsdl_file; - jtag_bsdl * bsdl; - int file_size,offset; - char * bsdl_txt,*tmp_bsdl_txt; - char * tmp_ptr; - int i,number_of_bsdl_lines; - char entityname[256]; - char * chipid_str,* instruct_str; - char * instruct_strchr; - char ** lines; - - jtagcore_logs_printf(jc,MSG_INFO_0,"Open BSDL file %s\r\n",filename); - - bsdl = 0; - - bsdl_file = fopen(filename,"rb"); - if (bsdl_file) - { - fseek(bsdl_file, 0, SEEK_END); - file_size = ftell(bsdl_file); - fseek(bsdl_file, 0, SEEK_SET); - - if ( file_size <= 0 || file_size > MAX_BSDL_FILE_SIZE ) - { - jtagcore_logs_printf(jc, MSG_ERROR, "Bad BSDL File size ! : %d\r\n", file_size); - fclose(bsdl_file); - return 0; - } - - jtagcore_logs_printf(jc, MSG_DEBUG, "BSDL file size : %d\r\n", file_size); - - bsdl_txt = malloc(file_size + 1); - if (bsdl_txt) - { - memset(bsdl_txt, 0, file_size + 1); - if( fread(bsdl_txt, file_size, 1, bsdl_file) != 1 ) - { - free(bsdl_txt); - jtagcore_logs_printf(jc, MSG_ERROR, "BSDL File read error !\r\n"); - fclose(bsdl_file); - return 0; - } - - tmp_bsdl_txt = malloc(file_size + 1); - if (tmp_bsdl_txt) - { - memset(tmp_bsdl_txt, 0, file_size + 1); - offset = 0; - - i = 0; - while (offset < file_size && i < file_size) - { - tmp_bsdl_txt[i] = getnextchar(bsdl_txt, file_size, &offset); - i++; - } - - free(bsdl_txt); - - if (offset < i) - { - jtagcore_logs_printf(jc, MSG_ERROR, "Preprocessing error !\r\n"); - free(tmp_bsdl_txt); - return 0; - } - - bsdl_txt = tmp_bsdl_txt; - } - else - { - jtagcore_logs_printf(jc, MSG_ERROR, "Can't allocate file memory !\r\n"); - free(bsdl_txt); - fclose(bsdl_file); - return 0; - } - } - else - { - jtagcore_logs_printf(jc, MSG_ERROR, "Can't allocate file memory !\r\n"); - fclose(bsdl_file); - return 0; - } - } - else - { - jtagcore_logs_printf(jc, MSG_ERROR, "Can't open %s !\r\n", filename); - return 0; - } - - fclose(bsdl_file); - - // Get the first entity offset - tmp_ptr = strstr(bsdl_txt,"entity"); - if (!tmp_ptr) - { - jtagcore_logs_printf(jc, MSG_ERROR, "entry \"entity\" not found !\r\n"); - free(bsdl_txt); - return 0; - } - - offset = tmp_ptr - bsdl_txt; - - // skip the entity keyword - while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] ) - offset++; - - // skip the blank spaces - while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) - offset++; - - // copy the entity name - i = 0; - memset(entityname,0,sizeof(entityname)); - while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] && i < ( sizeof(entityname) - 1 )) - { - entityname[i] = bsdl_txt[offset]; - - offset++; - i++; - } - - // skip the blank spaces - while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) - offset++; - - // Check the "is" keyword presence - if( strncmp(&bsdl_txt[offset],"is",2) ) - { - jtagcore_logs_printf(jc, MSG_ERROR, "Bad entity entry (\"is\" not found)\r\n"); - free(bsdl_txt); - return 0; - } - - jtagcore_logs_printf(jc,MSG_DEBUG,"Entity : %s\r\n",entityname); - - offset += 2; - - // extract and separate each bsdl line - number_of_bsdl_lines = extract_bsdl_lines(&bsdl_txt[offset],0); - jtagcore_logs_printf(jc,MSG_DEBUG,"lines :%d\r\n",number_of_bsdl_lines); - - if (number_of_bsdl_lines <= 0 || number_of_bsdl_lines > MAX_NUMBER_OF_BSDL_LINES) - { - jtagcore_logs_printf(jc, MSG_ERROR, "No line found !\r\n"); - free(bsdl_txt); - return 0; - } - - lines = malloc( sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); - if( !lines ) - { - jtagcore_logs_printf(jc,MSG_ERROR,"load_bsdlfile : memory alloc error !\r\n"); - free(tmp_bsdl_txt); - return 0; - } - - memset( lines, 0, sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); - - extract_bsdl_lines(&bsdl_txt[offset],lines); - - for(i= 0 ;i< number_of_bsdl_lines;i++) - { - preprocess_line(lines[i]); - } - - bsdl = malloc ( sizeof(jtag_bsdl) ); - if (!bsdl) - { - jtagcore_logs_printf(jc, MSG_ERROR, "load_bsdlfile : memory alloc error !\r\n"); - for( i = 0 ;i < number_of_bsdl_lines ; i++ ) - { - if(lines[i]) - { - free(lines[i]); - lines[i] = 0; - } - } - free(lines); - - free(bsdl_txt); - - return 0; - } - - memset( bsdl , 0 , sizeof(jtag_bsdl) ); - - /////////////////////// - // copy the entity name & the file name - strncpy(bsdl->entity_name,entityname,sizeof(((jtag_bsdl *)0)->entity_name) - 1); - i = strlen(filename); - while(i && filename[i] != '\\') - { - i--; - } - - if(filename[i] == '\\') - i++; - - strncpy(bsdl->src_filename,&filename[i],sizeof(bsdl->src_filename)-1); - - /////////////////////// - // Extract the chip ID - bsdl->chip_id = 0x00000000; - chipid_str = get_attribut_txt(lines,"IDCODE_REGISTER", entityname); - if(chipid_str) - { - if( chipid_str[0] == '"' ) - { - chipid_str++; - i = 0; - while(chipid_str[i]!='"' && chipid_str[i]!=';' && chipid_str[i] && i < 32) - { - if(chipid_str[i] == '1') - { - bsdl->chip_id |= 0x80000000 >> i; - } - i++; - } - } - } - - jtagcore_logs_printf(jc,MSG_INFO_0,"ID Code: 0x%.8X\r\n",bsdl->chip_id); - - /////////////////////// - // Extract the pins list - get_pins_list(jc,bsdl,lines); - - /////////////////////// - // Extract the JTAG Chain - if(get_jtag_chain(jc,bsdl,lines,entityname)<0) - { - jtagcore_logs_printf(jc,MSG_ERROR,"load_bsdlfile : Error during jtag chain parsing !\r\n"); - } - - if(jtagcore_getEnvVarValue( jc, "BSDL_LOADER_SORT_PINS_NAME" ) > 0) - { - // Count the pins - i = 0; - while(bsdl->pins_list[i].pinname[0]) - { - i++; - } - - // Sort them - qsort(bsdl->pins_list, i, sizeof bsdl->pins_list[0], compare_pin_name); - } - - i = 0; - while(bsdl->pins_list[i].pinname[0]) - { - char dbg_str[512]; - int namelen,j,k; - char disval; - - namelen = strlen(bsdl->pins_list[i].pinname); - - sprintf(dbg_str,"Pin %s",bsdl->pins_list[i].pinname); - for(j=0;j<(16 - namelen);j++) - { - strcat(dbg_str," "); - } - - k = strlen(dbg_str); - - disval = 'X'; - - if(bsdl->pins_list[i].out_bit_number >=0 ) - { - if( bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state >= 0 ) - { - disval = '0' + bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state; - } - } - - sprintf(&dbg_str[k]," type %.2d, ctrl %.3d (disval:%c), out %.3d, in %.3d\r\n", - bsdl->pins_list[i].pintype, - bsdl->pins_list[i].ctrl_bit_number, - disval, - bsdl->pins_list[i].out_bit_number, - bsdl->pins_list[i].in_bit_number); - - jtagcore_logs_printf(jc,MSG_DEBUG,dbg_str); - - i++; - } - - /////////////////////// - // Get the instruction code - - bsdl->number_of_bits_per_instruction = get_attribut_int(lines,"INSTRUCTION_LENGTH", entityname); - - jtagcore_logs_printf(jc,MSG_INFO_0,"Instructions lenght : %d\r\n",bsdl->number_of_bits_per_instruction); - - instruct_str = get_attribut_txt(lines,"INSTRUCTION_OPCODE", entityname); - if(instruct_str) - { - instruct_strchr = strstr(instruct_str,"IDCODE"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"idcode"); - if(instruct_strchr) - { - get_next_keyword(jc,instruct_strchr, bsdl->IDCODE_Instruction); - jtagcore_logs_printf(jc,MSG_DEBUG,"IDCODE : %s\r\n",bsdl->IDCODE_Instruction); - } - - instruct_strchr = strstr(instruct_str,"EXTEST"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"extest"); - - if(instruct_strchr) - { - get_next_keyword(jc,instruct_strchr, bsdl->EXTEST_Instruction); - jtagcore_logs_printf(jc,MSG_DEBUG,"EXTEST : %s\r\n",bsdl->EXTEST_Instruction); - } - - instruct_strchr = strstr(instruct_str,"BYPASS"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"bypass"); - - if(instruct_strchr) - { - get_next_keyword(jc,instruct_strchr, bsdl->BYPASS_Instruction); - jtagcore_logs_printf(jc,MSG_DEBUG,"BYPASS : %s\r\n",bsdl->BYPASS_Instruction); - } - - instruct_strchr = strstr(instruct_str,"SAMPLE"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"sample"); - if(instruct_strchr) - { - get_next_keyword(jc,instruct_strchr, bsdl->SAMPLE_Instruction); - jtagcore_logs_printf(jc,MSG_DEBUG,"SAMPLE : %s\r\n",bsdl->SAMPLE_Instruction); - } - } - - free( bsdl_txt ); - - for( i = 0 ;i < number_of_bsdl_lines ; i++ ) - { - if(lines[i]) - { - free(lines[i]); - lines[i] = 0; - } - } - free(lines); - - jtagcore_logs_printf(jc,MSG_INFO_0,"BSDL file %s loaded and parsed\r\n",filename); - - return bsdl; + int sort_pins = jtagcore_getEnvVarValue( jc, "BSDL_LOADER_SORT_PINS_NAME" ); + return jtag_bsdl_load_file(jc->jtagcore_print_callback,jc->logs_level,sort_pins,filename); } void unload_bsdlfile(jtag_core * jc, jtag_bsdl * bsdl) { - if( bsdl ) - { - if(bsdl->chain_list) - free(bsdl->chain_list); - - if(bsdl->pins_list) - free(bsdl->pins_list); - - free( bsdl ); - } + jtag_bsdl_unload_file(bsdl); } diff --git a/lib_jtag_core/src/bsdl_parser/bsdl_loader.h b/lib_jtag_core/src/bsdl_parser/bsdl_loader.h index bc6c0e4..b9a0354 100644 --- a/lib_jtag_core/src/bsdl_parser/bsdl_loader.h +++ b/lib_jtag_core/src/bsdl_parser/bsdl_loader.h @@ -26,58 +26,11 @@ extern "C" { #endif -#define MAX_ELEMENT_SIZE (64+1) - -typedef struct _pin_ctrl -{ - char pinname[MAX_ELEMENT_SIZE]; - int pintype; - - char physical_pin[MAX_ELEMENT_SIZE]; - - int ctrl_bit_number; - int out_bit_number; - int in_bit_number; -}pin_ctrl; - -typedef struct _jtag_chain -{ - int bit_index; - - int bit_cell_type; // BC_1,BC_2,... - - char pinname[MAX_ELEMENT_SIZE]; // Pin name. - - int bit_type; // None , ctrl , in, out. - - int safe_state; // Default - Safe state. (0,1,-1) - - int control_bit_index; // Indicate the associated control bit. -1 if no control bit. - int control_disable_state; - int control_disable_result; - -}jtag_chain; - -typedef struct _jtag_bsdl -{ - unsigned long chip_id; - - char src_filename[512]; - char entity_name[512]; - - int number_of_chainbits; - jtag_chain * chain_list; - - int number_of_pins; - pin_ctrl * pins_list; - - int number_of_bits_per_instruction; - char IDCODE_Instruction[MAX_ELEMENT_SIZE]; - char EXTEST_Instruction[MAX_ELEMENT_SIZE]; - char BYPASS_Instruction[MAX_ELEMENT_SIZE]; - char SAMPLE_Instruction[MAX_ELEMENT_SIZE]; - -}jtag_bsdl; +#ifdef _jtag_core_ +#include "jtag_bsdl.h" +#else +#include "../libjtag_bsdl.h" +#endif jtag_bsdl * load_bsdlfile(jtag_core * jc,char *filename); void unload_bsdlfile(jtag_core * jc, jtag_bsdl * bsdl); diff --git a/lib_jtag_core/src/bsdl_parser/jtag_bsdl.c b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.c new file mode 100644 index 0000000..e4c2fd9 --- /dev/null +++ b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.c @@ -0,0 +1,1520 @@ +/* + * JTAG Core library + * Copyright (c) 2008 - 2021 Viveris Technologies + * + * JTAG Core library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * JTAG Core library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with JTAG Core library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file jtag_bsdl.c + * @brief bsdl file parser with minimal dependencies + * @author Jean-François DEL NERO + */ + +#include +#include +#include +#include +#include +#include + +#include "../libjtag_bsdl.h" +#include "bsdl_strings.h" + +#include "../natsort/strnatcmp.h" + +#define DEBUG 1 + +int dbg_logs_printf(JTAGCORE_PRINT_FUNC print_callback,int logs_level, int MSGTYPE,char * chaine, ...) +{ + char tmp_msg[1024+1]; + char tmp_msg2[1024]; + + if( logs_level > MSGTYPE ) + { + if( print_callback ) + { + va_list marker; + va_start( marker, chaine ); + + switch(MSGTYPE) + { + case MSG_INFO_0: + strcpy(tmp_msg,"Info : "); + break; + case MSG_INFO_1: + strcpy(tmp_msg,"Info : "); + break; + case MSG_WARNING: + strcpy(tmp_msg,"Warning : "); + break; + case MSG_ERROR: + strcpy(tmp_msg,"Error : "); + break; + case MSG_DEBUG: + strcpy(tmp_msg,"Debug : "); + break; + default: + strcpy(tmp_msg,"Unknown : "); + break; + } + + vsprintf(tmp_msg2,chaine,marker); + strncat(tmp_msg,tmp_msg2,sizeof(tmp_msg) - ( strlen(tmp_msg) + 1 ) ); + + print_callback(tmp_msg); + + va_end( marker ); + } + } + return 0; +} + +char *string_upper(char *str) +{ + while (*str != '\0') + { + *str = toupper((unsigned char)*str); + str++; + } + return str; +} + +int strcmp_nocase(char *str1,char *str2) +{ + int d; + + for(;; str1++, str2++) + { + d = tolower(*str1) - tolower(*str2); + + if(d != 0 || !*str1) + return d; + } + + return 0; +} + +int getnextvalidline(char *buffer,int buffersize,int * offset) +{ + int l_offset; + int current_line_offset; + + l_offset = *offset; + current_line_offset = *offset; + + do + { + // Skip all the blank characters + while( (l_offset < buffersize) && (buffer[l_offset] == ' ' || buffer[l_offset] == '\t') ) + { + l_offset++; + } + + // Is it a return or comment ? + if( buffer[l_offset] != '\r' && buffer[l_offset] != '\n' && (buffer[l_offset] != '-' || buffer[l_offset+1] != '-')) + { + // No. There is something interesting into this line. + *offset = current_line_offset; + return 0; + } + else + { + // Is it a comment ? + if(buffer[l_offset] == '-' && buffer[l_offset+1] == '-') + { + // Yes. Go to the end of the line... + while(buffer[l_offset] != 0 && buffer[l_offset] != '\r' && buffer[l_offset] != '\n') + { + l_offset += 1; + } + } + } + + if( buffer[l_offset] == '\r' || buffer[l_offset] == '\n') + { + l_offset++; + if( buffer[l_offset] == '\n' ) + { + l_offset++; + } + + current_line_offset = l_offset; + } + }while ( buffer[l_offset] ); + + *offset = l_offset; + + return 1; + +} + +char getnextchar(char *buffer,int buffersize,int * offset) +{ + char c; + + if (*offset < buffersize) + { + c = buffer[*offset]; + + switch (c) + { + case 0: + return 0; + break; + + case '\r': + *offset += 1; + + if (*offset < buffersize) + { + if (buffer[*offset] == '\n') + { + *offset += 1; + } + + getnextvalidline(buffer, buffersize, offset); + } + + return ' '; + break; + case '\t': + *offset += 1; + return ' '; + break; + case '\n': + *offset += 1; + getnextvalidline(buffer, buffersize, offset); + return ' '; + break; + case '-': + if (buffer[*offset + 1] == '-') + { + while ((*offset < buffersize) && buffer[*offset] != 0 && buffer[*offset] != '\r' && buffer[*offset] != '\n') + { + *offset += 1; + } + + if (*offset < buffersize) + { + if (buffer[*offset] == '\r') + { + *offset += 1; + if (buffer[*offset] == '\n') + { + *offset += 1; + } + + getnextvalidline(buffer, buffersize, offset); + + return ' '; + } + + if (buffer[*offset] == '\n') + { + *offset += 1; + getnextvalidline(buffer, buffersize, offset); + + return ' '; + } + } + else + return 0; + + return ' '; + } + else + { + *offset += 1; + return '-'; + } + + break; + + default: + *offset += 1; + return c; + break; + } + } + + return 0; +} + +int extract_bsdl_lines(char * bsdl_txt, char ** lines) +{ + int offset; + int line_start_offset; + int line_end_offset; + int endofline; + int parenthesis_number; + int inside_quote; + int number_of_lines; + + offset = 0; + number_of_lines = 0; + + do + { + // Find the first word offset into the line... + while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) + { + offset++; + } + + line_start_offset = offset; + + parenthesis_number = 0; + endofline = 0; + inside_quote = 0; + + // Scan the line + while( !endofline ) + { + switch( bsdl_txt[offset] ) + { + case 0: + endofline = 1; + break; + + case '(': + if( !inside_quote ) + parenthesis_number++; + offset++; + break; + case ')': + if(parenthesis_number && !inside_quote) + parenthesis_number--; + offset++; + break; + case ';': + if( !parenthesis_number && !inside_quote ) + { + line_end_offset = offset; + + if( line_end_offset - line_start_offset > 0 ) + { + if(lines) + { + lines[number_of_lines] = malloc( (line_end_offset - line_start_offset) + 2 ); + if( lines[number_of_lines] ) + { + memset(lines[number_of_lines],0, (line_end_offset - line_start_offset) + 2 ); + memcpy(lines[number_of_lines],&bsdl_txt[line_start_offset], (line_end_offset - line_start_offset) ); + } + } + + number_of_lines++; + } + + endofline = 1; + + } + offset++; + break; + + case '"': + if(!inside_quote) + inside_quote = 1; + else + inside_quote = 0; + + offset++; + break; + + default: + offset++; + break; + } + } + }while(bsdl_txt[offset]); + + return number_of_lines; +} + +void preprocess_line(char * line) +{ + int inside_quote; + int read_offset,write_offset; + int is_string; + int number_of_spaces; + + inside_quote = 0; + read_offset = 0; + write_offset = 0; + number_of_spaces = 0; + + // first pass : remove extra blank + while( line[read_offset] ) + { + switch( line[read_offset] ) + { + case ' ': + + if(!number_of_spaces || inside_quote) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + + read_offset++; + number_of_spaces++; + + break; + + case '"': + if(!inside_quote) + inside_quote = 1; + else + inside_quote = 0; + + line[write_offset] = line[read_offset]; + write_offset++; + read_offset++; + number_of_spaces = 0; + + break; + + default: + line[write_offset] = line[read_offset]; + number_of_spaces = 0; + + write_offset++; + read_offset++; + break; + + } + } + + line[write_offset] = 0; + + // second pass : concatenate strings. + + inside_quote = 0; + read_offset = 0; + write_offset = 0; + number_of_spaces = 0; + is_string = 0; + + while( line[read_offset] ) + { + switch( line[read_offset] ) + { + + case '&': + if( inside_quote || !is_string) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + read_offset++; + break; + + case ' ': + if( inside_quote || !is_string) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + read_offset++; + break; + + case '"': + if(!inside_quote) + { + inside_quote = 1; + if( !is_string ) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + + is_string = 1; + } + else + { + inside_quote = 0; + + } + + read_offset++; + break; + + default: + if( !inside_quote ) + { + if( is_string ) + { + line[write_offset] = '"'; + write_offset++; + } + is_string = 0; + } + + line[write_offset] = line[read_offset]; + + write_offset++; + read_offset++; + break; + + } + } + + if( is_string ) + { + line[write_offset] = '"'; + write_offset++; + line[write_offset] = 0; + } +}; + +char * check_next_keyword(char * buffer, char * keyword) +{ + int i; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\"() ", buffer[i]) ) + { + i++; + } + + // skip the following blank + while (buffer[i] && strchr("\"() ", buffer[i]) ) + { + i++; + } + + if( !strncmp(&buffer[i],keyword,strlen(keyword)) ) + { + return &buffer[i + strlen(keyword)]; + } + + return 0; +} + +int get_next_keyword(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * buffer, char * keyword) +{ + int i,j; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\"():, ", buffer[i]) ) + { + i++; + } + + // skip the following blank + while (buffer[i] && strchr("\"():, ", buffer[i])) + { + i++; + } + + // copy the word + j = 0; + while (buffer[i] && !strchr("\"():;, ", buffer[i])) + { + if(j < MAX_ELEMENT_SIZE-1) + { + keyword[j] = buffer[i]; + j++; + } + i++; + } + + keyword[j] = 0; + + if( j >= (MAX_ELEMENT_SIZE-1) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_WARNING,"BSDL loader / get_next_keyword : element too long / truncated : %s\r\n",keyword); + } + + return i; +} + +int get_next_parameter(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * buffer, char * parameter) +{ + int i,j; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\":, ", buffer[i])) + { + i++; + } + + // skip the following blank + while (buffer[i] && strchr("\":, ", buffer[i])) + { + i++; + } + + // copy the word + j = 0; + while (buffer[i] && !strchr("\":, ;", buffer[i])) + { + if(j < MAX_ELEMENT_SIZE-1) + { + parameter[j] = buffer[i]; + j++; + } + i++; + } + + parameter[j] = 0; + + if( j >= (MAX_ELEMENT_SIZE-1) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_WARNING,"BSDL loader / get_next_parameter : element too long / truncated : %s\r\n",parameter); + } + + return i; +} + +int check_next_symbol(char * buffer, char c ) +{ + int i; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\"(): ", buffer[i]) && buffer[i] != c) + { + i++; + } + + // skip the following blank + while(buffer[i] && ( buffer[i] == ' ') ) + { + i++; + } + + if( buffer[i] == c ) + { + return i; + } + else + { + return -1; + } +} + +char * get_attribut(char ** lines,char * name, char * entity) +{ + int i,j; + char * ptr; + i = 0; + + do + { + if(!strncmp(lines[i],"attribute ",10)) + { + if(!strncmp(&lines[i][10],name,strlen(name))) + { + ptr = check_next_keyword(&lines[i][10], "of"); + ptr = check_next_keyword(ptr, entity); + + if( ptr ) + { + j = 0; + while( ptr[j] && ptr[j] != ':' && ptr[j] == ' ') + { + j++; + } + + if( ptr[j] == ':' ) + { + ptr = check_next_keyword(&ptr[j], "entity"); + ptr = check_next_keyword(ptr, "is"); + + return ptr; + + } + } + + return 0; + } + } + i++; + }while( lines[i] ); + + return 0; +} + +char * get_attribut_txt(char ** lines,char * name, char * entity) +{ + int i; + char * attribut_data; + + attribut_data = get_attribut(lines,name, entity); + + if( attribut_data ) + { + i = 0; + while( attribut_data[i] && attribut_data[i]!='"') + { + i++; + } + + if( attribut_data[i] == '"' ) + { + return &attribut_data[i]; + } + + return 0; + } + + return 0; +} + +int get_attribut_int(char ** lines,char * name, char * entity) +{ + int i; + char * attribut_data; + + attribut_data = get_attribut(lines,name, entity); + + if( attribut_data ) + { + i = 0; + while( attribut_data[i] && !( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) + { + i++; + } + + if( ( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) + { + return atoi(&attribut_data[i]); + } + + return 0; + } + + return 0; +} + +int get_next_pin(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * name,int * type, char *line, int * start_index, int * end_index ) +{ + int i; + int io_list_offset; + char tmp_str[256]; + int line_parsed,inside_block; + + i = get_next_keyword(print_callback,logs_level, line,name); + + io_list_offset = 0; + + while(line[i] == ' ') + i++; + + if( line[i] == ':' || line[i] == ',' ) + { + *start_index = 0; + *end_index = 0; + + if( line[i] == ',' ) + { + io_list_offset = i + 1; + + while(line[i] != ':' && line[i] != ';' && line[i]) + i++; + if( line[i] != ':' ) + return 0; + } + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + + string_upper(tmp_str); + + *type = get_typecode(pintype_str,tmp_str); + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + + if (!strcmp_nocase("bit_vector",tmp_str)) + { + while(line[i] != '(' && line[i] != ')' && line[i] != ';') + { + i++; + } + + line_parsed = 0; + inside_block = 0; + + do + { + + switch( line[i] ) + { + case '(': + inside_block++; + if(!line_parsed) + { + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + *start_index = atoi(tmp_str); + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + *end_index = atoi(tmp_str); + + line_parsed = 1; + + } + break; + case ')': + if ( !inside_block ) + { + return 0; + } + + inside_block--; + break; + case ';': + if( io_list_offset ) + return io_list_offset; + else + return i; + break; + case 0: + break; + + } + i++; + }while (line[i]); + + return 0; + } + + if (!strcmp_nocase("bit",tmp_str)) + { + do + { + switch( line[i] ) + { + case ';': + if( io_list_offset ) + return io_list_offset; + else + return i; + break; + case 0: + break; + } + i++; + }while (line[i]); + } + + } + + return 0; +} + +int get_pins_list(JTAGCORE_PRINT_FUNC print_callback,int logs_level, jtag_bsdl * bsdl_desc,char ** lines) +{ + int i,j,k,inc,offset, number_of_pins,vector_size; + char tmp_str[MAX_ELEMENT_SIZE]; + int tmp_type,tmp_start,tmp_end; + i = 0; + + while( lines[i] ) + { + if( !strncmp(lines[i],"port ",5) || !strncmp(lines[i],"port(",5)) + { + j = 0; + number_of_pins = 0; + + while( lines[i][j] != '(' && lines[i][j]) + { + j++; + } + + do + { + offset = get_next_pin(print_callback,logs_level, (char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); + + if( tmp_start <=tmp_end) + { + number_of_pins += ( (tmp_end - tmp_start) + 1 ); + } + else + { + number_of_pins += ( (tmp_start - tmp_end) + 1 ); + } + + j += offset; + + } while( offset); + + if (number_of_pins == 0 || ( number_of_pins > MAX_NUMBER_PINS_PER_DEV ) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "get_pins_list : bad number of pin found ! : %d\r\n", number_of_pins); + return -1; + } + + bsdl_desc->pins_list = malloc (sizeof(pin_ctrl) * (number_of_pins+1)); + if( bsdl_desc->pins_list ) + { + memset( bsdl_desc->pins_list, 0, sizeof(pin_ctrl) * (number_of_pins+1) ); + + j = 0; + number_of_pins = 0; + + while( lines[i][j] != '(' && lines[i][j]) + { + j++; + } + + do + { + offset = get_next_pin(print_callback,logs_level, (char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); + + if( tmp_start <= tmp_end ) + { + vector_size = ( (tmp_end - tmp_start) + 1 ); + inc = 1; + } + else + { + vector_size = ( (tmp_start - tmp_end) + 1 ); + inc = -1; + } + + j += offset; + + for(k = 0;k < vector_size; k++) + { + snprintf((char*)&bsdl_desc->pins_list[number_of_pins].pinname,sizeof(((pin_ctrl *)0)->pinname),"%s",(char*)tmp_str); + + if( vector_size > 1 ) + { + char digistr[32]; + snprintf((char*)digistr,sizeof(digistr),"(%d)",tmp_start); + strncat((char*)&bsdl_desc->pins_list[number_of_pins].pinname,digistr,sizeof(((pin_ctrl *)0)->pinname)-1); + } + + bsdl_desc->pins_list[number_of_pins].pintype = tmp_type; + number_of_pins++; + tmp_start += inc; + } + + } while( offset ); + + bsdl_desc->number_of_pins = number_of_pins; + + return number_of_pins; + } + } + i++; + }; + + return 0; +} + +int get_jtag_chain(JTAGCORE_PRINT_FUNC print_callback,int logs_level, jtag_bsdl * bsdl_desc,char ** lines, char * entityname) +{ + char * jtagchain_str; + int i,j,bit_count,end_parse; + char tmp_str[MAX_ELEMENT_SIZE]; + int bit_index; + + bit_count = 0; + bsdl_desc->number_of_chainbits = get_attribut_int(lines,"BOUNDARY_LENGTH", entityname); + if ( ( bsdl_desc->number_of_chainbits > 0 ) && ( bsdl_desc->number_of_chainbits < MAX_NUMBER_BITS_IN_CHAIN ) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Number of bit in the chain = %d\r\n",bsdl_desc->number_of_chainbits); + + bsdl_desc->chain_list = malloc( sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); + if( !bsdl_desc->chain_list ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"get_jtag_chain : memory alloc error !\r\n"); + return -1; + } + + memset(bsdl_desc->chain_list,0, sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); + + jtagchain_str = get_attribut_txt(lines,"BOUNDARY_REGISTER", entityname); + + end_parse = 0; + + if(jtagchain_str) + { + if( jtagchain_str[0] == '"' ) + { + i = 0; + while( jtagchain_str[i] && !end_parse ) + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"--------------\r\n"); + + // Get index + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + bit_index = atoi(tmp_str); + if (bit_index >= 0 && bit_index < bsdl_desc->number_of_chainbits) + { + bsdl_desc->chain_list[bit_index].bit_index = bit_index; + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_index); + + // Look for ( + while (jtagchain_str[i] != '(' && jtagchain_str[i]) + i++; + + // Get the pin type + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].bit_cell_type = get_typecode(celltype_str, tmp_str); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_cell_type); + + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the name + i += get_next_parameter(print_callback,logs_level, &jtagchain_str[i], bsdl_desc->chain_list[bit_index].pinname); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%s\r\n", bsdl_desc->chain_list[bit_index].pinname); + + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the type + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].bit_type = get_typecode(bittype_str, tmp_str); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%s , %d\r\n", tmp_str, bsdl_desc->chain_list[bit_index].bit_type); + + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the default state + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].safe_state = get_typecode(statetype_str, tmp_str); + + bsdl_desc->chain_list[bit_index].control_bit_index = -1; + + // If no ) Get the ctrl index + j = check_next_symbol(&jtagchain_str[i], ')'); + + if (jtagchain_str[i]==',' || j < 0) + { + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the control bit + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + + bsdl_desc->chain_list[bit_index].control_bit_index = atoi(tmp_str); + + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the polarity + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].control_disable_state = get_typecode(statetype_str, tmp_str); + + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the off state + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].control_disable_result = get_typecode(statetype_str, tmp_str); + + // Find and skip ) + j = check_next_symbol(&jtagchain_str[i], ')'); + if (j < 0) + return -1; + } + + i += j; + + // Find , (Next bit) or " (End of the chain) + i++; + bit_count++; + + if (check_next_symbol(&jtagchain_str[i], '"') >= 0) + { + end_parse = 1; + } + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "get_jtag_chain : Error bit index overrun !\r\n"); + } + } + } + } + } + + if( ( bit_count == bsdl_desc->number_of_chainbits ) && ( bsdl_desc->number_of_chainbits != 0 ) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Jtag chain parsing Ok !\r\n"); + + for( i = 0 ; i < (long)bsdl_desc->number_of_pins ; i++ ) + { + + bsdl_desc->pins_list[i].in_bit_number = -1; + bsdl_desc->pins_list[i].out_bit_number = -1; + bsdl_desc->pins_list[i].ctrl_bit_number = -1; + + switch( bsdl_desc->pins_list[i].pintype) + { + case IO_IN: + case IO_OUT: + case IO_INOUT: + + for( j = 0 ; j < (long)bsdl_desc->number_of_chainbits ; j++ ) + { + if(!strcmp(bsdl_desc->chain_list[j].pinname, bsdl_desc->pins_list[i].pinname)) + { + switch( bsdl_desc->chain_list[j].bit_type) + { + case BITTYPE_INPUT: + bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; + break; + case BITTYPE_OUTPUT: + bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; + break; + case BITTYPE_TRISTATE_OUTPUT: + bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; + bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; + break; + case BITTYPE_INOUT: + bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; + bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; + bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; + break; + } + } + } + break; + } + } + + return 1; + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"JTAG chain parsing error : %d - %d !\r\n",bit_count,bsdl_desc->number_of_chainbits); + return -1; + } +} + +static int compare_pin_name(const void *a, const void *b) +{ + int ret; + pin_ctrl const *pa = (pin_ctrl const *)a; + pin_ctrl const *pb = (pin_ctrl const *)b; + + ret = strnatcmp(pa->pinname, pb->pinname); + + return ret; +} + +jtag_bsdl * jtag_bsdl_load_file(JTAGCORE_PRINT_FUNC print_callback,int logs_level, int sort_pins, char *filename) +{ + FILE * bsdl_file; + jtag_bsdl * bsdl; + int file_size,offset; + char * bsdl_txt,*tmp_bsdl_txt; + char * tmp_ptr; + int i,number_of_bsdl_lines; + char entityname[256]; + char * chipid_str,* instruct_str; + char * instruct_strchr; + char ** lines; + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"Open BSDL file %s\r\n",filename); + + bsdl = 0; + + bsdl_file = fopen(filename,"rb"); + if (bsdl_file) + { + fseek(bsdl_file, 0, SEEK_END); + file_size = ftell(bsdl_file); + fseek(bsdl_file, 0, SEEK_SET); + + if ( file_size <= 0 || file_size > MAX_BSDL_FILE_SIZE ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Bad BSDL File size ! : %d\r\n", file_size); + fclose(bsdl_file); + return 0; + } + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "BSDL file size : %d\r\n", file_size); + + bsdl_txt = malloc(file_size + 1); + if (bsdl_txt) + { + memset(bsdl_txt, 0, file_size + 1); + if( fread(bsdl_txt, file_size, 1, bsdl_file) != 1 ) + { + free(bsdl_txt); + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "BSDL File read error !\r\n"); + fclose(bsdl_file); + return 0; + } + + tmp_bsdl_txt = malloc(file_size + 1); + if (tmp_bsdl_txt) + { + memset(tmp_bsdl_txt, 0, file_size + 1); + offset = 0; + + i = 0; + while (offset < file_size && i < file_size) + { + tmp_bsdl_txt[i] = getnextchar(bsdl_txt, file_size, &offset); + i++; + } + + free(bsdl_txt); + + if (offset < i) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Preprocessing error !\r\n"); + free(tmp_bsdl_txt); + return 0; + } + + bsdl_txt = tmp_bsdl_txt; + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't allocate file memory !\r\n"); + free(bsdl_txt); + fclose(bsdl_file); + return 0; + } + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't allocate file memory !\r\n"); + fclose(bsdl_file); + return 0; + } + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't open %s !\r\n", filename); + return 0; + } + + fclose(bsdl_file); + + // Get the first entity offset + tmp_ptr = strstr(bsdl_txt,"entity"); + if (!tmp_ptr) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "entry \"entity\" not found !\r\n"); + free(bsdl_txt); + return 0; + } + + offset = tmp_ptr - bsdl_txt; + + // skip the entity keyword + while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] ) + offset++; + + // skip the blank spaces + while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) + offset++; + + // copy the entity name + i = 0; + memset(entityname,0,sizeof(entityname)); + while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] && i < ( sizeof(entityname) - 1 )) + { + entityname[i] = bsdl_txt[offset]; + + offset++; + i++; + } + + // skip the blank spaces + while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) + offset++; + + // Check the "is" keyword presence + if( strncmp(&bsdl_txt[offset],"is",2) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Bad entity entry (\"is\" not found)\r\n"); + free(bsdl_txt); + return 0; + } + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Entity : %s\r\n",entityname); + + offset += 2; + + // extract and separate each bsdl line + number_of_bsdl_lines = extract_bsdl_lines(&bsdl_txt[offset],0); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"lines :%d\r\n",number_of_bsdl_lines); + + if (number_of_bsdl_lines <= 0 || number_of_bsdl_lines > MAX_NUMBER_OF_BSDL_LINES) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "No line found !\r\n"); + free(bsdl_txt); + return 0; + } + + lines = malloc( sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); + if( !lines ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"load_bsdlfile : memory alloc error !\r\n"); + free(tmp_bsdl_txt); + return 0; + } + + memset( lines, 0, sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); + + extract_bsdl_lines(&bsdl_txt[offset],lines); + + for(i= 0 ;i< number_of_bsdl_lines;i++) + { + preprocess_line(lines[i]); + } + + bsdl = malloc ( sizeof(jtag_bsdl) ); + if (!bsdl) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "load_bsdlfile : memory alloc error !\r\n"); + for( i = 0 ;i < number_of_bsdl_lines ; i++ ) + { + if(lines[i]) + { + free(lines[i]); + lines[i] = 0; + } + } + free(lines); + + free(bsdl_txt); + + return 0; + } + + memset( bsdl , 0 , sizeof(jtag_bsdl) ); + + /////////////////////// + // copy the entity name & the file name + strncpy(bsdl->entity_name,entityname,sizeof(((jtag_bsdl *)0)->entity_name) - 1); + i = strlen(filename); + while(i && filename[i] != '\\') + { + i--; + } + + if(filename[i] == '\\') + i++; + + strncpy(bsdl->src_filename,&filename[i],sizeof(bsdl->src_filename)-1); + + /////////////////////// + // Extract the chip ID + bsdl->chip_id = 0x00000000; + chipid_str = get_attribut_txt(lines,"IDCODE_REGISTER", entityname); + if(chipid_str) + { + if( chipid_str[0] == '"' ) + { + chipid_str++; + i = 0; + while(chipid_str[i]!='"' && chipid_str[i]!=';' && chipid_str[i] && i < 32) + { + if(chipid_str[i] == '1') + { + bsdl->chip_id |= 0x80000000 >> i; + } + i++; + } + } + } + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"ID Code: 0x%.8X\r\n",bsdl->chip_id); + + /////////////////////// + // Extract the pins list + get_pins_list(print_callback,logs_level, bsdl,lines); + + /////////////////////// + // Extract the JTAG Chain + if(get_jtag_chain(print_callback,logs_level, bsdl,lines,entityname)<0) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"load_bsdlfile : Error during jtag chain parsing !\r\n"); + } + + if(sort_pins > 0) + { + // Count the pins + i = 0; + while(bsdl->pins_list[i].pinname[0]) + { + i++; + } + + // Sort them + qsort(bsdl->pins_list, i, sizeof bsdl->pins_list[0], compare_pin_name); + } + + i = 0; + while(bsdl->pins_list[i].pinname[0]) + { + char dbg_str[512]; + int namelen,j,k; + char disval; + + namelen = strlen(bsdl->pins_list[i].pinname); + + sprintf(dbg_str,"Pin %s",bsdl->pins_list[i].pinname); + for(j=0;j<(16 - namelen);j++) + { + strcat(dbg_str," "); + } + + k = strlen(dbg_str); + + disval = 'X'; + + if(bsdl->pins_list[i].out_bit_number >=0 ) + { + if( bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state >= 0 ) + { + disval = '0' + bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state; + } + } + + sprintf(&dbg_str[k]," type %.2d, ctrl %.3d (disval:%c), out %.3d, in %.3d\r\n", + bsdl->pins_list[i].pintype, + bsdl->pins_list[i].ctrl_bit_number, + disval, + bsdl->pins_list[i].out_bit_number, + bsdl->pins_list[i].in_bit_number); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,dbg_str); + + i++; + } + + /////////////////////// + // Get the instruction code + + bsdl->number_of_bits_per_instruction = get_attribut_int(lines,"INSTRUCTION_LENGTH", entityname); + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"Instructions lenght : %d\r\n",bsdl->number_of_bits_per_instruction); + + instruct_str = get_attribut_txt(lines,"INSTRUCTION_OPCODE", entityname); + if(instruct_str) + { + instruct_strchr = strstr(instruct_str,"IDCODE"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"idcode"); + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->IDCODE_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"IDCODE : %s\r\n",bsdl->IDCODE_Instruction); + } + + instruct_strchr = strstr(instruct_str,"EXTEST"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"extest"); + + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->EXTEST_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"EXTEST : %s\r\n",bsdl->EXTEST_Instruction); + } + + instruct_strchr = strstr(instruct_str,"BYPASS"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"bypass"); + + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->BYPASS_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"BYPASS : %s\r\n",bsdl->BYPASS_Instruction); + } + + instruct_strchr = strstr(instruct_str,"SAMPLE"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"sample"); + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->SAMPLE_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"SAMPLE : %s\r\n",bsdl->SAMPLE_Instruction); + } + } + + free( bsdl_txt ); + + for( i = 0 ;i < number_of_bsdl_lines ; i++ ) + { + if(lines[i]) + { + free(lines[i]); + lines[i] = 0; + } + } + free(lines); + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"BSDL file %s loaded and parsed\r\n",filename); + + return bsdl; +} + +void jtag_bsdl_unload_file(jtag_bsdl * bsdl) +{ + if( bsdl ) + { + if(bsdl->chain_list) + free(bsdl->chain_list); + + if(bsdl->pins_list) + free(bsdl->pins_list); + + free( bsdl ); + } +} diff --git a/lib_jtag_core/src/bsdl_parser/jtag_bsdl.h b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.h new file mode 100644 index 0000000..616fd17 --- /dev/null +++ b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.h @@ -0,0 +1,92 @@ +/* + * JTAG Core library + * Copyright (c) 2008 - 2021 Viveris Technologies + * + * JTAG Core library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * JTAG Core library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with JTAG Core library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file jtag_bsdl.h + * @brief bsdl file parser header with minimal dependencies + * @author Jean-François DEL NERO + */ +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_ELEMENT_SIZE (64+1) + +typedef struct _pin_ctrl +{ + char pinname[MAX_ELEMENT_SIZE]; + int pintype; + + char physical_pin[MAX_ELEMENT_SIZE]; + + int ctrl_bit_number; + int out_bit_number; + int in_bit_number; +}pin_ctrl; + +typedef struct _jtag_chain +{ + int bit_index; + + int bit_cell_type; // BC_1,BC_2,... + + char pinname[MAX_ELEMENT_SIZE]; // Pin name. + + int bit_type; // None , ctrl , in, out. + + int safe_state; // Default - Safe state. (0,1,-1) + + int control_bit_index; // Indicate the associated control bit. -1 if no control bit. + int control_disable_state; + int control_disable_result; + +}jtag_chain; + +typedef struct _jtag_bsdl +{ + unsigned long chip_id; + + char src_filename[512]; + char entity_name[512]; + + int number_of_chainbits; + jtag_chain * chain_list; + + int number_of_pins; + pin_ctrl * pins_list; + + int number_of_bits_per_instruction; + char IDCODE_Instruction[MAX_ELEMENT_SIZE]; + char EXTEST_Instruction[MAX_ELEMENT_SIZE]; + char BYPASS_Instruction[MAX_ELEMENT_SIZE]; + char SAMPLE_Instruction[MAX_ELEMENT_SIZE]; + +}jtag_bsdl; + +#ifndef _JTAGCORE_PRINT_FUNC_ +typedef void (*JTAGCORE_PRINT_FUNC)(char * string); +#define _JTAGCORE_PRINT_FUNC_ +#endif + +jtag_bsdl * jtag_bsdl_load_file(JTAGCORE_PRINT_FUNC print_callback, int logs_level, int sort_pins, char *filename); +void jtag_bsdl_unload_file(jtag_bsdl * bsdl); + +#ifdef __cplusplus +} +#endif diff --git a/lib_jtag_core/src/libjtag_bsdl.h b/lib_jtag_core/src/libjtag_bsdl.h new file mode 100644 index 0000000..1da4a1d --- /dev/null +++ b/lib_jtag_core/src/libjtag_bsdl.h @@ -0,0 +1,30 @@ +#ifndef _libjtag_bsdl_ +#define _libjtag_bsdl_ + +#ifdef __cplusplus +extern "C" { +#endif + +// Output message types/levels +enum MSGTYPE +{ + MSG_NONE = 0, + MSG_INFO_0, + MSG_INFO_1, + MSG_WARNING, + MSG_ERROR, + MSG_DEBUG +}; + +#define MAX_NUMBER_BITS_IN_CHAIN ( 256 * 1024 ) +#define MAX_NUMBER_PINS_PER_DEV ( 64 * 1024 ) +#define MAX_BSDL_FILE_SIZE ( 1024 * 1024 ) +#define MAX_NUMBER_OF_BSDL_LINES ( 64 * 1024 ) + +#include "bsdl_parser/jtag_bsdl.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_jtag_core/test/CMakeLists.txt b/lib_jtag_core/test/CMakeLists.txt new file mode 100644 index 0000000..f85c8e0 --- /dev/null +++ b/lib_jtag_core/test/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 2.8.11) + +# Recurse into the "linux" subdirectory. +add_subdirectory (linux) + diff --git a/lib_jtag_core/test/linux/CMakeLists.txt b/lib_jtag_core/test/linux/CMakeLists.txt new file mode 100644 index 0000000..cc48c66 --- /dev/null +++ b/lib_jtag_core/test/linux/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required (VERSION 2.8.11) + +# Build shared library in place for legacy support +add_custom_target(BSLDtoFloorplan ALL + COMMENT "Building app using legacy support" + COMMAND make all + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + From b9e0078cfd37369547ff8106a81231d055c13c7c Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:25:59 -0230 Subject: [PATCH 07/24] Language independent interface to bsdl parser --- lib_jtag_core/test/CMakeLists.txt | 4 +- lib_jtag_core/test/imports/CMakeLists.txt | 22 +++++++ lib_jtag_core/test/imports/epCoreJTAG.cxx | 72 +++++++++++++++++++++++ lib_jtag_core/test/imports/epSwigHere.h | 20 +++++++ lib_jtag_core/test/imports/uiCoreJTAG.cxx | 19 ++++++ 5 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 lib_jtag_core/test/imports/CMakeLists.txt create mode 100644 lib_jtag_core/test/imports/epCoreJTAG.cxx create mode 100644 lib_jtag_core/test/imports/epSwigHere.h create mode 100644 lib_jtag_core/test/imports/uiCoreJTAG.cxx diff --git a/lib_jtag_core/test/CMakeLists.txt b/lib_jtag_core/test/CMakeLists.txt index f85c8e0..59340cf 100644 --- a/lib_jtag_core/test/CMakeLists.txt +++ b/lib_jtag_core/test/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required (VERSION 2.8.11) -# Recurse into the "linux" subdirectory. +# Recurse into the linux, imports and apps subdirectories. add_subdirectory (linux) +add_subdirectory (imports) +#add_subdirectory (apps) diff --git a/lib_jtag_core/test/imports/CMakeLists.txt b/lib_jtag_core/test/imports/CMakeLists.txt new file mode 100644 index 0000000..094bd70 --- /dev/null +++ b/lib_jtag_core/test/imports/CMakeLists.txt @@ -0,0 +1,22 @@ +# Create static and shared libraries and specify the source files. +# Any number of sources could be listed here. + +add_library(epCoreJTAG_ STATIC epCoreJTAG.cxx) +add_library(epCoreJTAG SHARED epCoreJTAG.cxx) + +# For static library, enable position independent code +set_property(TARGET epCoreJTAG_ PROPERTY POSITION_INDEPENDENT_CODE ON) + +# Make sure the compiler can find include files for our library +# when other libraries or executables link to fftTOO +target_include_directories (epCoreJTAG_ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "${STREETVIEWJTAG_SOURCE_DIR}/src") +target_include_directories (epCoreJTAG PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "${STREETVIEWJTAG_SOURCE_DIR}/src") + +set_property(TARGET epCoreJTAG PROPERTY INTERFACE_LINK_LIBRARIES jtag_bsdl) +set_property(TARGET epCoreJTAG_ PROPERTY INTERFACE_LINK_LIBRARIES jtag_bsdl) + +add_executable(uiCoreJTAG uiCoreJTAG.cxx) +target_link_libraries(uiCoreJTAG epCoreJTAG jtag_bsdl) + +add_executable(uiCoreJTAG_ uiCoreJTAG.cxx) +target_link_libraries(uiCoreJTAG_ epCoreJTAG jtag_bsdl) diff --git a/lib_jtag_core/test/imports/epCoreJTAG.cxx b/lib_jtag_core/test/imports/epCoreJTAG.cxx new file mode 100644 index 0000000..7f6117c --- /dev/null +++ b/lib_jtag_core/test/imports/epCoreJTAG.cxx @@ -0,0 +1,72 @@ +#include +#include +#include "libjtag_bsdl.h" + +#include "epSwigHere.h" +#include +#include +#include + + +static void logger(char * string) { + printf("%s",string); +} + +static class CLitterPile : private std::vector { +private: + JTAGCORE_PRINT_FUNC logger; +public: + CLitterPile() {logger=::logger;} + void ensureInit() { + } + void deinit() { + } + void clear() { + //std::vector &self=*this; + for(SWIGHERE_CAST typedPtr : *this) { + switch(typedPtr.first) { + case SWIGHERE_TYPE::INTPTR: { + int * litter=(int*)typedPtr.second; + delete [] litter; + } + break; + default: // don't scope the default block + break;} + } + std::vector::clear(); + } + SWIGHERE_CAST push_back(const int * p) { + SWIGHERE_CAST tail(SWIGHERE_TYPE::INTPTR,(void*)p); + std::vector::push_back(tail); + return tail; + } + ~CLitterPile() { + clear(); + } +} garbageCollector; + +extern SWIGHERE_CONTEXT epInitSwigHere() { + garbageCollector.ensureInit(); + return (SWIGHERE_CONTEXT) &garbageCollector; +} + +extern void epUninitSwigHere(SWIGHERE_CONTEXT oContext) { + if(oContext == (SWIGHERE_CONTEXT) &garbageCollector) { + garbageCollector.clear(); + garbageCollector.deinit(); + } +} + +extern long unsigned int epBSDLDeviceId(SWIGHERE_CONTEXT oContext, char * pathToBSDL) { + long int result = -1; + if(oContext == (SWIGHERE_CONTEXT)&garbageCollector) { + jtag_bsdl * details = jtag_bsdl_load_file(logger,MSG_DEBUG, 0, pathToBSDL); + if ( details != NULL ) { + result = details->chip_id; + jtag_bsdl_unload_file(details); + } else { + result = 0; + } + } + return (long unsigned int) result; +} diff --git a/lib_jtag_core/test/imports/epSwigHere.h b/lib_jtag_core/test/imports/epSwigHere.h new file mode 100644 index 0000000..18d7dd6 --- /dev/null +++ b/lib_jtag_core/test/imports/epSwigHere.h @@ -0,0 +1,20 @@ +// epSWIGHere.h for CoreJTAG +#pragma once +#include +#include + +typedef enum _SWIGHERE_TYPE { + VOIDPTR=0, + INTPTR +} SWIGHERE_TYPE; + +typedef std::pair SWIGHERE_CAST; +typedef std::pair SWIGHERE_INTLIST; + +typedef volatile void * SWIGHERE_CONTEXT; + +extern SWIGHERE_CONTEXT epInitSwigHere(); +extern long unsigned int epBSDLDeviceId(SWIGHERE_CONTEXT oContext, char * pathToFile); +extern SWIGHERE_INTLIST epSequence(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); +//extern SWIGHERE_INTLIST epBSDLPinMap(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); +extern void epUninitSwigHere(SWIGHERE_CONTEXT oContext); diff --git a/lib_jtag_core/test/imports/uiCoreJTAG.cxx b/lib_jtag_core/test/imports/uiCoreJTAG.cxx new file mode 100644 index 0000000..439f7ec --- /dev/null +++ b/lib_jtag_core/test/imports/uiCoreJTAG.cxx @@ -0,0 +1,19 @@ +#include "epSwigHere.h" + +#include "libjtag_bsdl.h" + +int main(int argc, char * argv[], char ** envp) { + SWIGHERE_CONTEXT context = epInitSwigHere(); + if(context != NULL) { + if(argc>1) { + long unsigned int id = epBSDLDeviceId(context, argv[1]); + //SWIGHERE_INTLIST epSequence(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); + //extern SWIGHERE_INTLIST epBSDLPinMap(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); + printf("BSDL file describes device id %lx\r\n",id); + } + epUninitSwigHere(context); + context = NULL; + } + return 0; +} + From f47f874d491727e558ba1920c2123d1a360f5ab8 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Thu, 9 Jun 2022 11:15:15 -0230 Subject: [PATCH 08/24] Maintaining compatibility with existing Windows build/makefiles --- lib_jtag_core/build/linux/Makefile | 5 +- lib_jtag_core/src/CMakeLists.txt | 1 + lib_jtag_core/src/bsdl_parser/bsdl_loader.c | 1 + lib_jtag_core/src/bsdl_parser/jtag_bsdl.c | 1482 +------------------ lib_jtag_core/src/bsdl_parser/jtag_bsdl.cc | 1443 ++++++++++++++++++ lib_jtag_core/src/dbg_logs.c | 10 +- lib_jtag_core/src/dbg_logs.h | 5 +- lib_jtag_core/src/libjtag_bsdl.h | 1 + 8 files changed, 1456 insertions(+), 1492 deletions(-) create mode 100644 lib_jtag_core/src/bsdl_parser/jtag_bsdl.cc diff --git a/lib_jtag_core/build/linux/Makefile b/lib_jtag_core/build/linux/Makefile index 1b6ef4c..de5ea94 100644 --- a/lib_jtag_core/build/linux/Makefile +++ b/lib_jtag_core/build/linux/Makefile @@ -27,7 +27,7 @@ LDFLAGS +=-arch i386 -dynamiclib -current_version 2.0 -install_name @executable_ EXEC=libjtag_core.dylib endif -LIB_JTAG_CORE = jtag_core.o dbg_logs.o bsdl_loader.o jtag_bsdl.o bsdl_strings.o drv_loader.o script.o env.o fs.o os_interface.o network.o +LIB_JTAG_CORE = jtag_core.o dbg_logs.o bsdl_loader.o bsdl_strings.o drv_loader.o script.o env.o fs.o os_interface.o network.o PROBES_DRIVERS = drivers_list.o jlink_jtag_drv.o linux_gpio_jtag_drv.o #lpt_jtag_drv.o ftdi_jtag_drv.o PROTOCOLS_DRIVERS = i2c_over_jtag.o mdio_over_jtag.o spi_over_jtag.o memory_over_jtag.o NATSORT = strnatcmp.o @@ -55,9 +55,6 @@ dbg_logs.o: $(BASEDIR)/dbg_logs.c bsdl_loader.o: $(BASEDIR)/bsdl_parser/bsdl_loader.c $(CC) -o $@ -c $< $(CFLAGS) -jtag_bsdl.o: $(BASEDIR)/bsdl_parser/jtag_bsdl.c - $(CC) -o $@ -c $< $(CFLAGS) - bsdl_strings.o: $(BASEDIR)/bsdl_parser/bsdl_strings.c $(CC) -o $@ -c $< $(CFLAGS) diff --git a/lib_jtag_core/src/CMakeLists.txt b/lib_jtag_core/src/CMakeLists.txt index 85a400d..b016891 100644 --- a/lib_jtag_core/src/CMakeLists.txt +++ b/lib_jtag_core/src/CMakeLists.txt @@ -3,6 +3,7 @@ set(JTAG_BSDL_SRC bsdl_parser/jtag_bsdl.c bsdl_parser/bsdl_strings.c natsort/strnatcmp.c + dbg_logs.c ) add_library(jtag_bsdl ${JTAG_BSDL_SRC}) diff --git a/lib_jtag_core/src/bsdl_parser/bsdl_loader.c b/lib_jtag_core/src/bsdl_parser/bsdl_loader.c index 4ddf4f5..968fd35 100644 --- a/lib_jtag_core/src/bsdl_parser/bsdl_loader.c +++ b/lib_jtag_core/src/bsdl_parser/bsdl_loader.c @@ -40,6 +40,7 @@ #include "../dbg_logs.h" #define DEBUG 1 +#include "jtag_bsdl.cc" jtag_bsdl * load_bsdlfile(jtag_core * jc,char *filename) { diff --git a/lib_jtag_core/src/bsdl_parser/jtag_bsdl.c b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.c index e4c2fd9..d51af85 100644 --- a/lib_jtag_core/src/bsdl_parser/jtag_bsdl.c +++ b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.c @@ -37,1484 +37,4 @@ #define DEBUG 1 -int dbg_logs_printf(JTAGCORE_PRINT_FUNC print_callback,int logs_level, int MSGTYPE,char * chaine, ...) -{ - char tmp_msg[1024+1]; - char tmp_msg2[1024]; - - if( logs_level > MSGTYPE ) - { - if( print_callback ) - { - va_list marker; - va_start( marker, chaine ); - - switch(MSGTYPE) - { - case MSG_INFO_0: - strcpy(tmp_msg,"Info : "); - break; - case MSG_INFO_1: - strcpy(tmp_msg,"Info : "); - break; - case MSG_WARNING: - strcpy(tmp_msg,"Warning : "); - break; - case MSG_ERROR: - strcpy(tmp_msg,"Error : "); - break; - case MSG_DEBUG: - strcpy(tmp_msg,"Debug : "); - break; - default: - strcpy(tmp_msg,"Unknown : "); - break; - } - - vsprintf(tmp_msg2,chaine,marker); - strncat(tmp_msg,tmp_msg2,sizeof(tmp_msg) - ( strlen(tmp_msg) + 1 ) ); - - print_callback(tmp_msg); - - va_end( marker ); - } - } - return 0; -} - -char *string_upper(char *str) -{ - while (*str != '\0') - { - *str = toupper((unsigned char)*str); - str++; - } - return str; -} - -int strcmp_nocase(char *str1,char *str2) -{ - int d; - - for(;; str1++, str2++) - { - d = tolower(*str1) - tolower(*str2); - - if(d != 0 || !*str1) - return d; - } - - return 0; -} - -int getnextvalidline(char *buffer,int buffersize,int * offset) -{ - int l_offset; - int current_line_offset; - - l_offset = *offset; - current_line_offset = *offset; - - do - { - // Skip all the blank characters - while( (l_offset < buffersize) && (buffer[l_offset] == ' ' || buffer[l_offset] == '\t') ) - { - l_offset++; - } - - // Is it a return or comment ? - if( buffer[l_offset] != '\r' && buffer[l_offset] != '\n' && (buffer[l_offset] != '-' || buffer[l_offset+1] != '-')) - { - // No. There is something interesting into this line. - *offset = current_line_offset; - return 0; - } - else - { - // Is it a comment ? - if(buffer[l_offset] == '-' && buffer[l_offset+1] == '-') - { - // Yes. Go to the end of the line... - while(buffer[l_offset] != 0 && buffer[l_offset] != '\r' && buffer[l_offset] != '\n') - { - l_offset += 1; - } - } - } - - if( buffer[l_offset] == '\r' || buffer[l_offset] == '\n') - { - l_offset++; - if( buffer[l_offset] == '\n' ) - { - l_offset++; - } - - current_line_offset = l_offset; - } - }while ( buffer[l_offset] ); - - *offset = l_offset; - - return 1; - -} - -char getnextchar(char *buffer,int buffersize,int * offset) -{ - char c; - - if (*offset < buffersize) - { - c = buffer[*offset]; - - switch (c) - { - case 0: - return 0; - break; - - case '\r': - *offset += 1; - - if (*offset < buffersize) - { - if (buffer[*offset] == '\n') - { - *offset += 1; - } - - getnextvalidline(buffer, buffersize, offset); - } - - return ' '; - break; - case '\t': - *offset += 1; - return ' '; - break; - case '\n': - *offset += 1; - getnextvalidline(buffer, buffersize, offset); - return ' '; - break; - case '-': - if (buffer[*offset + 1] == '-') - { - while ((*offset < buffersize) && buffer[*offset] != 0 && buffer[*offset] != '\r' && buffer[*offset] != '\n') - { - *offset += 1; - } - - if (*offset < buffersize) - { - if (buffer[*offset] == '\r') - { - *offset += 1; - if (buffer[*offset] == '\n') - { - *offset += 1; - } - - getnextvalidline(buffer, buffersize, offset); - - return ' '; - } - - if (buffer[*offset] == '\n') - { - *offset += 1; - getnextvalidline(buffer, buffersize, offset); - - return ' '; - } - } - else - return 0; - - return ' '; - } - else - { - *offset += 1; - return '-'; - } - - break; - - default: - *offset += 1; - return c; - break; - } - } - - return 0; -} - -int extract_bsdl_lines(char * bsdl_txt, char ** lines) -{ - int offset; - int line_start_offset; - int line_end_offset; - int endofline; - int parenthesis_number; - int inside_quote; - int number_of_lines; - - offset = 0; - number_of_lines = 0; - - do - { - // Find the first word offset into the line... - while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) - { - offset++; - } - - line_start_offset = offset; - - parenthesis_number = 0; - endofline = 0; - inside_quote = 0; - - // Scan the line - while( !endofline ) - { - switch( bsdl_txt[offset] ) - { - case 0: - endofline = 1; - break; - - case '(': - if( !inside_quote ) - parenthesis_number++; - offset++; - break; - case ')': - if(parenthesis_number && !inside_quote) - parenthesis_number--; - offset++; - break; - case ';': - if( !parenthesis_number && !inside_quote ) - { - line_end_offset = offset; - - if( line_end_offset - line_start_offset > 0 ) - { - if(lines) - { - lines[number_of_lines] = malloc( (line_end_offset - line_start_offset) + 2 ); - if( lines[number_of_lines] ) - { - memset(lines[number_of_lines],0, (line_end_offset - line_start_offset) + 2 ); - memcpy(lines[number_of_lines],&bsdl_txt[line_start_offset], (line_end_offset - line_start_offset) ); - } - } - - number_of_lines++; - } - - endofline = 1; - - } - offset++; - break; - - case '"': - if(!inside_quote) - inside_quote = 1; - else - inside_quote = 0; - - offset++; - break; - - default: - offset++; - break; - } - } - }while(bsdl_txt[offset]); - - return number_of_lines; -} - -void preprocess_line(char * line) -{ - int inside_quote; - int read_offset,write_offset; - int is_string; - int number_of_spaces; - - inside_quote = 0; - read_offset = 0; - write_offset = 0; - number_of_spaces = 0; - - // first pass : remove extra blank - while( line[read_offset] ) - { - switch( line[read_offset] ) - { - case ' ': - - if(!number_of_spaces || inside_quote) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - - read_offset++; - number_of_spaces++; - - break; - - case '"': - if(!inside_quote) - inside_quote = 1; - else - inside_quote = 0; - - line[write_offset] = line[read_offset]; - write_offset++; - read_offset++; - number_of_spaces = 0; - - break; - - default: - line[write_offset] = line[read_offset]; - number_of_spaces = 0; - - write_offset++; - read_offset++; - break; - - } - } - - line[write_offset] = 0; - - // second pass : concatenate strings. - - inside_quote = 0; - read_offset = 0; - write_offset = 0; - number_of_spaces = 0; - is_string = 0; - - while( line[read_offset] ) - { - switch( line[read_offset] ) - { - - case '&': - if( inside_quote || !is_string) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - read_offset++; - break; - - case ' ': - if( inside_quote || !is_string) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - read_offset++; - break; - - case '"': - if(!inside_quote) - { - inside_quote = 1; - if( !is_string ) - { - line[write_offset] = line[read_offset]; - write_offset++; - } - - is_string = 1; - } - else - { - inside_quote = 0; - - } - - read_offset++; - break; - - default: - if( !inside_quote ) - { - if( is_string ) - { - line[write_offset] = '"'; - write_offset++; - } - is_string = 0; - } - - line[write_offset] = line[read_offset]; - - write_offset++; - read_offset++; - break; - - } - } - - if( is_string ) - { - line[write_offset] = '"'; - write_offset++; - line[write_offset] = 0; - } -}; - -char * check_next_keyword(char * buffer, char * keyword) -{ - int i; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\"() ", buffer[i]) ) - { - i++; - } - - // skip the following blank - while (buffer[i] && strchr("\"() ", buffer[i]) ) - { - i++; - } - - if( !strncmp(&buffer[i],keyword,strlen(keyword)) ) - { - return &buffer[i + strlen(keyword)]; - } - - return 0; -} - -int get_next_keyword(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * buffer, char * keyword) -{ - int i,j; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\"():, ", buffer[i]) ) - { - i++; - } - - // skip the following blank - while (buffer[i] && strchr("\"():, ", buffer[i])) - { - i++; - } - - // copy the word - j = 0; - while (buffer[i] && !strchr("\"():;, ", buffer[i])) - { - if(j < MAX_ELEMENT_SIZE-1) - { - keyword[j] = buffer[i]; - j++; - } - i++; - } - - keyword[j] = 0; - - if( j >= (MAX_ELEMENT_SIZE-1) ) - { - dbg_logs_printf(print_callback,logs_level, MSG_WARNING,"BSDL loader / get_next_keyword : element too long / truncated : %s\r\n",keyword); - } - - return i; -} - -int get_next_parameter(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * buffer, char * parameter) -{ - int i,j; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\":, ", buffer[i])) - { - i++; - } - - // skip the following blank - while (buffer[i] && strchr("\":, ", buffer[i])) - { - i++; - } - - // copy the word - j = 0; - while (buffer[i] && !strchr("\":, ;", buffer[i])) - { - if(j < MAX_ELEMENT_SIZE-1) - { - parameter[j] = buffer[i]; - j++; - } - i++; - } - - parameter[j] = 0; - - if( j >= (MAX_ELEMENT_SIZE-1) ) - { - dbg_logs_printf(print_callback,logs_level, MSG_WARNING,"BSDL loader / get_next_parameter : element too long / truncated : %s\r\n",parameter); - } - - return i; -} - -int check_next_symbol(char * buffer, char c ) -{ - int i; - - if( !buffer ) - return 0; - - // skip the current word - i = 0; - while (buffer[i] && !strchr("\"(): ", buffer[i]) && buffer[i] != c) - { - i++; - } - - // skip the following blank - while(buffer[i] && ( buffer[i] == ' ') ) - { - i++; - } - - if( buffer[i] == c ) - { - return i; - } - else - { - return -1; - } -} - -char * get_attribut(char ** lines,char * name, char * entity) -{ - int i,j; - char * ptr; - i = 0; - - do - { - if(!strncmp(lines[i],"attribute ",10)) - { - if(!strncmp(&lines[i][10],name,strlen(name))) - { - ptr = check_next_keyword(&lines[i][10], "of"); - ptr = check_next_keyword(ptr, entity); - - if( ptr ) - { - j = 0; - while( ptr[j] && ptr[j] != ':' && ptr[j] == ' ') - { - j++; - } - - if( ptr[j] == ':' ) - { - ptr = check_next_keyword(&ptr[j], "entity"); - ptr = check_next_keyword(ptr, "is"); - - return ptr; - - } - } - - return 0; - } - } - i++; - }while( lines[i] ); - - return 0; -} - -char * get_attribut_txt(char ** lines,char * name, char * entity) -{ - int i; - char * attribut_data; - - attribut_data = get_attribut(lines,name, entity); - - if( attribut_data ) - { - i = 0; - while( attribut_data[i] && attribut_data[i]!='"') - { - i++; - } - - if( attribut_data[i] == '"' ) - { - return &attribut_data[i]; - } - - return 0; - } - - return 0; -} - -int get_attribut_int(char ** lines,char * name, char * entity) -{ - int i; - char * attribut_data; - - attribut_data = get_attribut(lines,name, entity); - - if( attribut_data ) - { - i = 0; - while( attribut_data[i] && !( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) - { - i++; - } - - if( ( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) - { - return atoi(&attribut_data[i]); - } - - return 0; - } - - return 0; -} - -int get_next_pin(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * name,int * type, char *line, int * start_index, int * end_index ) -{ - int i; - int io_list_offset; - char tmp_str[256]; - int line_parsed,inside_block; - - i = get_next_keyword(print_callback,logs_level, line,name); - - io_list_offset = 0; - - while(line[i] == ' ') - i++; - - if( line[i] == ':' || line[i] == ',' ) - { - *start_index = 0; - *end_index = 0; - - if( line[i] == ',' ) - { - io_list_offset = i + 1; - - while(line[i] != ':' && line[i] != ';' && line[i]) - i++; - if( line[i] != ':' ) - return 0; - } - - i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); - - string_upper(tmp_str); - - *type = get_typecode(pintype_str,tmp_str); - - i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); - - if (!strcmp_nocase("bit_vector",tmp_str)) - { - while(line[i] != '(' && line[i] != ')' && line[i] != ';') - { - i++; - } - - line_parsed = 0; - inside_block = 0; - - do - { - - switch( line[i] ) - { - case '(': - inside_block++; - if(!line_parsed) - { - i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); - *start_index = atoi(tmp_str); - - i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); - - i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); - *end_index = atoi(tmp_str); - - line_parsed = 1; - - } - break; - case ')': - if ( !inside_block ) - { - return 0; - } - - inside_block--; - break; - case ';': - if( io_list_offset ) - return io_list_offset; - else - return i; - break; - case 0: - break; - - } - i++; - }while (line[i]); - - return 0; - } - - if (!strcmp_nocase("bit",tmp_str)) - { - do - { - switch( line[i] ) - { - case ';': - if( io_list_offset ) - return io_list_offset; - else - return i; - break; - case 0: - break; - } - i++; - }while (line[i]); - } - - } - - return 0; -} - -int get_pins_list(JTAGCORE_PRINT_FUNC print_callback,int logs_level, jtag_bsdl * bsdl_desc,char ** lines) -{ - int i,j,k,inc,offset, number_of_pins,vector_size; - char tmp_str[MAX_ELEMENT_SIZE]; - int tmp_type,tmp_start,tmp_end; - i = 0; - - while( lines[i] ) - { - if( !strncmp(lines[i],"port ",5) || !strncmp(lines[i],"port(",5)) - { - j = 0; - number_of_pins = 0; - - while( lines[i][j] != '(' && lines[i][j]) - { - j++; - } - - do - { - offset = get_next_pin(print_callback,logs_level, (char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); - - if( tmp_start <=tmp_end) - { - number_of_pins += ( (tmp_end - tmp_start) + 1 ); - } - else - { - number_of_pins += ( (tmp_start - tmp_end) + 1 ); - } - - j += offset; - - } while( offset); - - if (number_of_pins == 0 || ( number_of_pins > MAX_NUMBER_PINS_PER_DEV ) ) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "get_pins_list : bad number of pin found ! : %d\r\n", number_of_pins); - return -1; - } - - bsdl_desc->pins_list = malloc (sizeof(pin_ctrl) * (number_of_pins+1)); - if( bsdl_desc->pins_list ) - { - memset( bsdl_desc->pins_list, 0, sizeof(pin_ctrl) * (number_of_pins+1) ); - - j = 0; - number_of_pins = 0; - - while( lines[i][j] != '(' && lines[i][j]) - { - j++; - } - - do - { - offset = get_next_pin(print_callback,logs_level, (char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); - - if( tmp_start <= tmp_end ) - { - vector_size = ( (tmp_end - tmp_start) + 1 ); - inc = 1; - } - else - { - vector_size = ( (tmp_start - tmp_end) + 1 ); - inc = -1; - } - - j += offset; - - for(k = 0;k < vector_size; k++) - { - snprintf((char*)&bsdl_desc->pins_list[number_of_pins].pinname,sizeof(((pin_ctrl *)0)->pinname),"%s",(char*)tmp_str); - - if( vector_size > 1 ) - { - char digistr[32]; - snprintf((char*)digistr,sizeof(digistr),"(%d)",tmp_start); - strncat((char*)&bsdl_desc->pins_list[number_of_pins].pinname,digistr,sizeof(((pin_ctrl *)0)->pinname)-1); - } - - bsdl_desc->pins_list[number_of_pins].pintype = tmp_type; - number_of_pins++; - tmp_start += inc; - } - - } while( offset ); - - bsdl_desc->number_of_pins = number_of_pins; - - return number_of_pins; - } - } - i++; - }; - - return 0; -} - -int get_jtag_chain(JTAGCORE_PRINT_FUNC print_callback,int logs_level, jtag_bsdl * bsdl_desc,char ** lines, char * entityname) -{ - char * jtagchain_str; - int i,j,bit_count,end_parse; - char tmp_str[MAX_ELEMENT_SIZE]; - int bit_index; - - bit_count = 0; - bsdl_desc->number_of_chainbits = get_attribut_int(lines,"BOUNDARY_LENGTH", entityname); - if ( ( bsdl_desc->number_of_chainbits > 0 ) && ( bsdl_desc->number_of_chainbits < MAX_NUMBER_BITS_IN_CHAIN ) ) - { - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Number of bit in the chain = %d\r\n",bsdl_desc->number_of_chainbits); - - bsdl_desc->chain_list = malloc( sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); - if( !bsdl_desc->chain_list ) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"get_jtag_chain : memory alloc error !\r\n"); - return -1; - } - - memset(bsdl_desc->chain_list,0, sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); - - jtagchain_str = get_attribut_txt(lines,"BOUNDARY_REGISTER", entityname); - - end_parse = 0; - - if(jtagchain_str) - { - if( jtagchain_str[0] == '"' ) - { - i = 0; - while( jtagchain_str[i] && !end_parse ) - { - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"--------------\r\n"); - - // Get index - i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); - bit_index = atoi(tmp_str); - if (bit_index >= 0 && bit_index < bsdl_desc->number_of_chainbits) - { - bsdl_desc->chain_list[bit_index].bit_index = bit_index; - - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_index); - - // Look for ( - while (jtagchain_str[i] != '(' && jtagchain_str[i]) - i++; - - // Get the pin type - i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].bit_cell_type = get_typecode(celltype_str, tmp_str); - - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_cell_type); - - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the name - i += get_next_parameter(print_callback,logs_level, &jtagchain_str[i], bsdl_desc->chain_list[bit_index].pinname); - - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%s\r\n", bsdl_desc->chain_list[bit_index].pinname); - - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the type - i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].bit_type = get_typecode(bittype_str, tmp_str); - - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%s , %d\r\n", tmp_str, bsdl_desc->chain_list[bit_index].bit_type); - - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the default state - i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].safe_state = get_typecode(statetype_str, tmp_str); - - bsdl_desc->chain_list[bit_index].control_bit_index = -1; - - // If no ) Get the ctrl index - j = check_next_symbol(&jtagchain_str[i], ')'); - - if (jtagchain_str[i]==',' || j < 0) - { - // , - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the control bit - i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); - - bsdl_desc->chain_list[bit_index].control_bit_index = atoi(tmp_str); - - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the polarity - i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].control_disable_state = get_typecode(statetype_str, tmp_str); - - j = check_next_symbol(&jtagchain_str[i], ','); - if (j < 0) - return -1; - i += j; - - // Get the off state - i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); - string_upper(tmp_str); - bsdl_desc->chain_list[bit_index].control_disable_result = get_typecode(statetype_str, tmp_str); - - // Find and skip ) - j = check_next_symbol(&jtagchain_str[i], ')'); - if (j < 0) - return -1; - } - - i += j; - - // Find , (Next bit) or " (End of the chain) - i++; - bit_count++; - - if (check_next_symbol(&jtagchain_str[i], '"') >= 0) - { - end_parse = 1; - } - } - else - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "get_jtag_chain : Error bit index overrun !\r\n"); - } - } - } - } - } - - if( ( bit_count == bsdl_desc->number_of_chainbits ) && ( bsdl_desc->number_of_chainbits != 0 ) ) - { - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Jtag chain parsing Ok !\r\n"); - - for( i = 0 ; i < (long)bsdl_desc->number_of_pins ; i++ ) - { - - bsdl_desc->pins_list[i].in_bit_number = -1; - bsdl_desc->pins_list[i].out_bit_number = -1; - bsdl_desc->pins_list[i].ctrl_bit_number = -1; - - switch( bsdl_desc->pins_list[i].pintype) - { - case IO_IN: - case IO_OUT: - case IO_INOUT: - - for( j = 0 ; j < (long)bsdl_desc->number_of_chainbits ; j++ ) - { - if(!strcmp(bsdl_desc->chain_list[j].pinname, bsdl_desc->pins_list[i].pinname)) - { - switch( bsdl_desc->chain_list[j].bit_type) - { - case BITTYPE_INPUT: - bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; - break; - case BITTYPE_OUTPUT: - bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; - break; - case BITTYPE_TRISTATE_OUTPUT: - bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; - bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; - break; - case BITTYPE_INOUT: - bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; - bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; - bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; - break; - } - } - } - break; - } - } - - return 1; - } - else - { - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"JTAG chain parsing error : %d - %d !\r\n",bit_count,bsdl_desc->number_of_chainbits); - return -1; - } -} - -static int compare_pin_name(const void *a, const void *b) -{ - int ret; - pin_ctrl const *pa = (pin_ctrl const *)a; - pin_ctrl const *pb = (pin_ctrl const *)b; - - ret = strnatcmp(pa->pinname, pb->pinname); - - return ret; -} - -jtag_bsdl * jtag_bsdl_load_file(JTAGCORE_PRINT_FUNC print_callback,int logs_level, int sort_pins, char *filename) -{ - FILE * bsdl_file; - jtag_bsdl * bsdl; - int file_size,offset; - char * bsdl_txt,*tmp_bsdl_txt; - char * tmp_ptr; - int i,number_of_bsdl_lines; - char entityname[256]; - char * chipid_str,* instruct_str; - char * instruct_strchr; - char ** lines; - - dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"Open BSDL file %s\r\n",filename); - - bsdl = 0; - - bsdl_file = fopen(filename,"rb"); - if (bsdl_file) - { - fseek(bsdl_file, 0, SEEK_END); - file_size = ftell(bsdl_file); - fseek(bsdl_file, 0, SEEK_SET); - - if ( file_size <= 0 || file_size > MAX_BSDL_FILE_SIZE ) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Bad BSDL File size ! : %d\r\n", file_size); - fclose(bsdl_file); - return 0; - } - - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "BSDL file size : %d\r\n", file_size); - - bsdl_txt = malloc(file_size + 1); - if (bsdl_txt) - { - memset(bsdl_txt, 0, file_size + 1); - if( fread(bsdl_txt, file_size, 1, bsdl_file) != 1 ) - { - free(bsdl_txt); - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "BSDL File read error !\r\n"); - fclose(bsdl_file); - return 0; - } - - tmp_bsdl_txt = malloc(file_size + 1); - if (tmp_bsdl_txt) - { - memset(tmp_bsdl_txt, 0, file_size + 1); - offset = 0; - - i = 0; - while (offset < file_size && i < file_size) - { - tmp_bsdl_txt[i] = getnextchar(bsdl_txt, file_size, &offset); - i++; - } - - free(bsdl_txt); - - if (offset < i) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Preprocessing error !\r\n"); - free(tmp_bsdl_txt); - return 0; - } - - bsdl_txt = tmp_bsdl_txt; - } - else - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't allocate file memory !\r\n"); - free(bsdl_txt); - fclose(bsdl_file); - return 0; - } - } - else - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't allocate file memory !\r\n"); - fclose(bsdl_file); - return 0; - } - } - else - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't open %s !\r\n", filename); - return 0; - } - - fclose(bsdl_file); - - // Get the first entity offset - tmp_ptr = strstr(bsdl_txt,"entity"); - if (!tmp_ptr) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "entry \"entity\" not found !\r\n"); - free(bsdl_txt); - return 0; - } - - offset = tmp_ptr - bsdl_txt; - - // skip the entity keyword - while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] ) - offset++; - - // skip the blank spaces - while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) - offset++; - - // copy the entity name - i = 0; - memset(entityname,0,sizeof(entityname)); - while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] && i < ( sizeof(entityname) - 1 )) - { - entityname[i] = bsdl_txt[offset]; - - offset++; - i++; - } - - // skip the blank spaces - while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) - offset++; - - // Check the "is" keyword presence - if( strncmp(&bsdl_txt[offset],"is",2) ) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Bad entity entry (\"is\" not found)\r\n"); - free(bsdl_txt); - return 0; - } - - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Entity : %s\r\n",entityname); - - offset += 2; - - // extract and separate each bsdl line - number_of_bsdl_lines = extract_bsdl_lines(&bsdl_txt[offset],0); - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"lines :%d\r\n",number_of_bsdl_lines); - - if (number_of_bsdl_lines <= 0 || number_of_bsdl_lines > MAX_NUMBER_OF_BSDL_LINES) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "No line found !\r\n"); - free(bsdl_txt); - return 0; - } - - lines = malloc( sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); - if( !lines ) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"load_bsdlfile : memory alloc error !\r\n"); - free(tmp_bsdl_txt); - return 0; - } - - memset( lines, 0, sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); - - extract_bsdl_lines(&bsdl_txt[offset],lines); - - for(i= 0 ;i< number_of_bsdl_lines;i++) - { - preprocess_line(lines[i]); - } - - bsdl = malloc ( sizeof(jtag_bsdl) ); - if (!bsdl) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "load_bsdlfile : memory alloc error !\r\n"); - for( i = 0 ;i < number_of_bsdl_lines ; i++ ) - { - if(lines[i]) - { - free(lines[i]); - lines[i] = 0; - } - } - free(lines); - - free(bsdl_txt); - - return 0; - } - - memset( bsdl , 0 , sizeof(jtag_bsdl) ); - - /////////////////////// - // copy the entity name & the file name - strncpy(bsdl->entity_name,entityname,sizeof(((jtag_bsdl *)0)->entity_name) - 1); - i = strlen(filename); - while(i && filename[i] != '\\') - { - i--; - } - - if(filename[i] == '\\') - i++; - - strncpy(bsdl->src_filename,&filename[i],sizeof(bsdl->src_filename)-1); - - /////////////////////// - // Extract the chip ID - bsdl->chip_id = 0x00000000; - chipid_str = get_attribut_txt(lines,"IDCODE_REGISTER", entityname); - if(chipid_str) - { - if( chipid_str[0] == '"' ) - { - chipid_str++; - i = 0; - while(chipid_str[i]!='"' && chipid_str[i]!=';' && chipid_str[i] && i < 32) - { - if(chipid_str[i] == '1') - { - bsdl->chip_id |= 0x80000000 >> i; - } - i++; - } - } - } - - dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"ID Code: 0x%.8X\r\n",bsdl->chip_id); - - /////////////////////// - // Extract the pins list - get_pins_list(print_callback,logs_level, bsdl,lines); - - /////////////////////// - // Extract the JTAG Chain - if(get_jtag_chain(print_callback,logs_level, bsdl,lines,entityname)<0) - { - dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"load_bsdlfile : Error during jtag chain parsing !\r\n"); - } - - if(sort_pins > 0) - { - // Count the pins - i = 0; - while(bsdl->pins_list[i].pinname[0]) - { - i++; - } - - // Sort them - qsort(bsdl->pins_list, i, sizeof bsdl->pins_list[0], compare_pin_name); - } - - i = 0; - while(bsdl->pins_list[i].pinname[0]) - { - char dbg_str[512]; - int namelen,j,k; - char disval; - - namelen = strlen(bsdl->pins_list[i].pinname); - - sprintf(dbg_str,"Pin %s",bsdl->pins_list[i].pinname); - for(j=0;j<(16 - namelen);j++) - { - strcat(dbg_str," "); - } - - k = strlen(dbg_str); - - disval = 'X'; - - if(bsdl->pins_list[i].out_bit_number >=0 ) - { - if( bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state >= 0 ) - { - disval = '0' + bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state; - } - } - - sprintf(&dbg_str[k]," type %.2d, ctrl %.3d (disval:%c), out %.3d, in %.3d\r\n", - bsdl->pins_list[i].pintype, - bsdl->pins_list[i].ctrl_bit_number, - disval, - bsdl->pins_list[i].out_bit_number, - bsdl->pins_list[i].in_bit_number); - - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,dbg_str); - - i++; - } - - /////////////////////// - // Get the instruction code - - bsdl->number_of_bits_per_instruction = get_attribut_int(lines,"INSTRUCTION_LENGTH", entityname); - - dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"Instructions lenght : %d\r\n",bsdl->number_of_bits_per_instruction); - - instruct_str = get_attribut_txt(lines,"INSTRUCTION_OPCODE", entityname); - if(instruct_str) - { - instruct_strchr = strstr(instruct_str,"IDCODE"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"idcode"); - if(instruct_strchr) - { - get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->IDCODE_Instruction); - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"IDCODE : %s\r\n",bsdl->IDCODE_Instruction); - } - - instruct_strchr = strstr(instruct_str,"EXTEST"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"extest"); - - if(instruct_strchr) - { - get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->EXTEST_Instruction); - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"EXTEST : %s\r\n",bsdl->EXTEST_Instruction); - } - - instruct_strchr = strstr(instruct_str,"BYPASS"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"bypass"); - - if(instruct_strchr) - { - get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->BYPASS_Instruction); - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"BYPASS : %s\r\n",bsdl->BYPASS_Instruction); - } - - instruct_strchr = strstr(instruct_str,"SAMPLE"); - if(!instruct_strchr) - instruct_strchr = strstr(instruct_str,"sample"); - if(instruct_strchr) - { - get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->SAMPLE_Instruction); - dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"SAMPLE : %s\r\n",bsdl->SAMPLE_Instruction); - } - } - - free( bsdl_txt ); - - for( i = 0 ;i < number_of_bsdl_lines ; i++ ) - { - if(lines[i]) - { - free(lines[i]); - lines[i] = 0; - } - } - free(lines); - - dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"BSDL file %s loaded and parsed\r\n",filename); - - return bsdl; -} - -void jtag_bsdl_unload_file(jtag_bsdl * bsdl) -{ - if( bsdl ) - { - if(bsdl->chain_list) - free(bsdl->chain_list); - - if(bsdl->pins_list) - free(bsdl->pins_list); - - free( bsdl ); - } -} +#include "jtag_bsdl.cc" \ No newline at end of file diff --git a/lib_jtag_core/src/bsdl_parser/jtag_bsdl.cc b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.cc new file mode 100644 index 0000000..f6bf310 --- /dev/null +++ b/lib_jtag_core/src/bsdl_parser/jtag_bsdl.cc @@ -0,0 +1,1443 @@ +/* +This CC file is to be included into the appropriate C file, either: +1) bsdl_loader.c for the standard build; or, +2) jtag_bsdl.c for the redued dependency build + +This is a temporary measure required only until Makefiles for Win32 can be updated +*/ +char *string_upper(char *str) +{ + while (*str != '\0') + { + *str = toupper((unsigned char)*str); + str++; + } + return str; +} + +int strcmp_nocase(char *str1,char *str2) +{ + int d; + + for(;; str1++, str2++) + { + d = tolower(*str1) - tolower(*str2); + + if(d != 0 || !*str1) + return d; + } + + return 0; +} + +int getnextvalidline(char *buffer,int buffersize,int * offset) +{ + int l_offset; + int current_line_offset; + + l_offset = *offset; + current_line_offset = *offset; + + do + { + // Skip all the blank characters + while( (l_offset < buffersize) && (buffer[l_offset] == ' ' || buffer[l_offset] == '\t') ) + { + l_offset++; + } + + // Is it a return or comment ? + if( buffer[l_offset] != '\r' && buffer[l_offset] != '\n' && (buffer[l_offset] != '-' || buffer[l_offset+1] != '-')) + { + // No. There is something interesting into this line. + *offset = current_line_offset; + return 0; + } + else + { + // Is it a comment ? + if(buffer[l_offset] == '-' && buffer[l_offset+1] == '-') + { + // Yes. Go to the end of the line... + while(buffer[l_offset] != 0 && buffer[l_offset] != '\r' && buffer[l_offset] != '\n') + { + l_offset += 1; + } + } + } + + if( buffer[l_offset] == '\r' || buffer[l_offset] == '\n') + { + l_offset++; + if( buffer[l_offset] == '\n' ) + { + l_offset++; + } + + current_line_offset = l_offset; + } + }while ( buffer[l_offset] ); + + *offset = l_offset; + + return 1; + +} + +char getnextchar(char *buffer,int buffersize,int * offset) +{ + char c; + + if (*offset < buffersize) + { + c = buffer[*offset]; + + switch (c) + { + case 0: + return 0; + break; + + case '\r': + *offset += 1; + + if (*offset < buffersize) + { + if (buffer[*offset] == '\n') + { + *offset += 1; + } + + getnextvalidline(buffer, buffersize, offset); + } + + return ' '; + break; + case '\t': + *offset += 1; + return ' '; + break; + case '\n': + *offset += 1; + getnextvalidline(buffer, buffersize, offset); + return ' '; + break; + case '-': + if (buffer[*offset + 1] == '-') + { + while ((*offset < buffersize) && buffer[*offset] != 0 && buffer[*offset] != '\r' && buffer[*offset] != '\n') + { + *offset += 1; + } + + if (*offset < buffersize) + { + if (buffer[*offset] == '\r') + { + *offset += 1; + if (buffer[*offset] == '\n') + { + *offset += 1; + } + + getnextvalidline(buffer, buffersize, offset); + + return ' '; + } + + if (buffer[*offset] == '\n') + { + *offset += 1; + getnextvalidline(buffer, buffersize, offset); + + return ' '; + } + } + else + return 0; + + return ' '; + } + else + { + *offset += 1; + return '-'; + } + + break; + + default: + *offset += 1; + return c; + break; + } + } + + return 0; +} + +int extract_bsdl_lines(char * bsdl_txt, char ** lines) +{ + int offset; + int line_start_offset; + int line_end_offset; + int endofline; + int parenthesis_number; + int inside_quote; + int number_of_lines; + + offset = 0; + number_of_lines = 0; + + do + { + // Find the first word offset into the line... + while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) + { + offset++; + } + + line_start_offset = offset; + + parenthesis_number = 0; + endofline = 0; + inside_quote = 0; + + // Scan the line + while( !endofline ) + { + switch( bsdl_txt[offset] ) + { + case 0: + endofline = 1; + break; + + case '(': + if( !inside_quote ) + parenthesis_number++; + offset++; + break; + case ')': + if(parenthesis_number && !inside_quote) + parenthesis_number--; + offset++; + break; + case ';': + if( !parenthesis_number && !inside_quote ) + { + line_end_offset = offset; + + if( line_end_offset - line_start_offset > 0 ) + { + if(lines) + { + lines[number_of_lines] = malloc( (line_end_offset - line_start_offset) + 2 ); + if( lines[number_of_lines] ) + { + memset(lines[number_of_lines],0, (line_end_offset - line_start_offset) + 2 ); + memcpy(lines[number_of_lines],&bsdl_txt[line_start_offset], (line_end_offset - line_start_offset) ); + } + } + + number_of_lines++; + } + + endofline = 1; + + } + offset++; + break; + + case '"': + if(!inside_quote) + inside_quote = 1; + else + inside_quote = 0; + + offset++; + break; + + default: + offset++; + break; + } + } + }while(bsdl_txt[offset]); + + return number_of_lines; +} + +void preprocess_line(char * line) +{ + int inside_quote; + int read_offset,write_offset; + int is_string; + int number_of_spaces; + + inside_quote = 0; + read_offset = 0; + write_offset = 0; + number_of_spaces = 0; + + // first pass : remove extra blank + while( line[read_offset] ) + { + switch( line[read_offset] ) + { + case ' ': + + if(!number_of_spaces || inside_quote) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + + read_offset++; + number_of_spaces++; + + break; + + case '"': + if(!inside_quote) + inside_quote = 1; + else + inside_quote = 0; + + line[write_offset] = line[read_offset]; + write_offset++; + read_offset++; + number_of_spaces = 0; + + break; + + default: + line[write_offset] = line[read_offset]; + number_of_spaces = 0; + + write_offset++; + read_offset++; + break; + + } + } + + line[write_offset] = 0; + + // second pass : concatenate strings. + + inside_quote = 0; + read_offset = 0; + write_offset = 0; + number_of_spaces = 0; + is_string = 0; + + while( line[read_offset] ) + { + switch( line[read_offset] ) + { + + case '&': + if( inside_quote || !is_string) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + read_offset++; + break; + + case ' ': + if( inside_quote || !is_string) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + read_offset++; + break; + + case '"': + if(!inside_quote) + { + inside_quote = 1; + if( !is_string ) + { + line[write_offset] = line[read_offset]; + write_offset++; + } + + is_string = 1; + } + else + { + inside_quote = 0; + + } + + read_offset++; + break; + + default: + if( !inside_quote ) + { + if( is_string ) + { + line[write_offset] = '"'; + write_offset++; + } + is_string = 0; + } + + line[write_offset] = line[read_offset]; + + write_offset++; + read_offset++; + break; + + } + } + + if( is_string ) + { + line[write_offset] = '"'; + write_offset++; + line[write_offset] = 0; + } +}; + +char * check_next_keyword(char * buffer, char * keyword) +{ + int i; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\"() ", buffer[i]) ) + { + i++; + } + + // skip the following blank + while (buffer[i] && strchr("\"() ", buffer[i]) ) + { + i++; + } + + if( !strncmp(&buffer[i],keyword,strlen(keyword)) ) + { + return &buffer[i + strlen(keyword)]; + } + + return 0; +} + +int get_next_keyword(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * buffer, char * keyword) +{ + int i,j; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\"():, ", buffer[i]) ) + { + i++; + } + + // skip the following blank + while (buffer[i] && strchr("\"():, ", buffer[i])) + { + i++; + } + + // copy the word + j = 0; + while (buffer[i] && !strchr("\"():;, ", buffer[i])) + { + if(j < MAX_ELEMENT_SIZE-1) + { + keyword[j] = buffer[i]; + j++; + } + i++; + } + + keyword[j] = 0; + + if( j >= (MAX_ELEMENT_SIZE-1) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_WARNING,"BSDL loader / get_next_keyword : element too long / truncated : %s\r\n",keyword); + } + + return i; +} + +int get_next_parameter(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * buffer, char * parameter) +{ + int i,j; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\":, ", buffer[i])) + { + i++; + } + + // skip the following blank + while (buffer[i] && strchr("\":, ", buffer[i])) + { + i++; + } + + // copy the word + j = 0; + while (buffer[i] && !strchr("\":, ;", buffer[i])) + { + if(j < MAX_ELEMENT_SIZE-1) + { + parameter[j] = buffer[i]; + j++; + } + i++; + } + + parameter[j] = 0; + + if( j >= (MAX_ELEMENT_SIZE-1) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_WARNING,"BSDL loader / get_next_parameter : element too long / truncated : %s\r\n",parameter); + } + + return i; +} + +int check_next_symbol(char * buffer, char c ) +{ + int i; + + if( !buffer ) + return 0; + + // skip the current word + i = 0; + while (buffer[i] && !strchr("\"(): ", buffer[i]) && buffer[i] != c) + { + i++; + } + + // skip the following blank + while(buffer[i] && ( buffer[i] == ' ') ) + { + i++; + } + + if( buffer[i] == c ) + { + return i; + } + else + { + return -1; + } +} + +char * get_attribut(char ** lines,char * name, char * entity) +{ + int i,j; + char * ptr; + i = 0; + + do + { + if(!strncmp(lines[i],"attribute ",10)) + { + if(!strncmp(&lines[i][10],name,strlen(name))) + { + ptr = check_next_keyword(&lines[i][10], "of"); + ptr = check_next_keyword(ptr, entity); + + if( ptr ) + { + j = 0; + while( ptr[j] && ptr[j] != ':' && ptr[j] == ' ') + { + j++; + } + + if( ptr[j] == ':' ) + { + ptr = check_next_keyword(&ptr[j], "entity"); + ptr = check_next_keyword(ptr, "is"); + + return ptr; + + } + } + + return 0; + } + } + i++; + }while( lines[i] ); + + return 0; +} + +char * get_attribut_txt(char ** lines,char * name, char * entity) +{ + int i; + char * attribut_data; + + attribut_data = get_attribut(lines,name, entity); + + if( attribut_data ) + { + i = 0; + while( attribut_data[i] && attribut_data[i]!='"') + { + i++; + } + + if( attribut_data[i] == '"' ) + { + return &attribut_data[i]; + } + + return 0; + } + + return 0; +} + +int get_attribut_int(char ** lines,char * name, char * entity) +{ + int i; + char * attribut_data; + + attribut_data = get_attribut(lines,name, entity); + + if( attribut_data ) + { + i = 0; + while( attribut_data[i] && !( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) + { + i++; + } + + if( ( attribut_data[i]>='0' && attribut_data[i]<='9' ) ) + { + return atoi(&attribut_data[i]); + } + + return 0; + } + + return 0; +} + +int get_next_pin(JTAGCORE_PRINT_FUNC print_callback,int logs_level, char * name,int * type, char *line, int * start_index, int * end_index ) +{ + int i; + int io_list_offset; + char tmp_str[256]; + int line_parsed,inside_block; + + i = get_next_keyword(print_callback,logs_level, line,name); + + io_list_offset = 0; + + while(line[i] == ' ') + i++; + + if( line[i] == ':' || line[i] == ',' ) + { + *start_index = 0; + *end_index = 0; + + if( line[i] == ',' ) + { + io_list_offset = i + 1; + + while(line[i] != ':' && line[i] != ';' && line[i]) + i++; + if( line[i] != ':' ) + return 0; + } + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + + string_upper(tmp_str); + + *type = get_typecode(pintype_str,tmp_str); + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + + if (!strcmp_nocase("bit_vector",tmp_str)) + { + while(line[i] != '(' && line[i] != ')' && line[i] != ';') + { + i++; + } + + line_parsed = 0; + inside_block = 0; + + do + { + + switch( line[i] ) + { + case '(': + inside_block++; + if(!line_parsed) + { + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + *start_index = atoi(tmp_str); + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + + i += get_next_keyword(print_callback,logs_level, &line[i],(char*)&tmp_str); + *end_index = atoi(tmp_str); + + line_parsed = 1; + + } + break; + case ')': + if ( !inside_block ) + { + return 0; + } + + inside_block--; + break; + case ';': + if( io_list_offset ) + return io_list_offset; + else + return i; + break; + case 0: + break; + + } + i++; + }while (line[i]); + + return 0; + } + + if (!strcmp_nocase("bit",tmp_str)) + { + do + { + switch( line[i] ) + { + case ';': + if( io_list_offset ) + return io_list_offset; + else + return i; + break; + case 0: + break; + } + i++; + }while (line[i]); + } + + } + + return 0; +} + +int get_pins_list(JTAGCORE_PRINT_FUNC print_callback,int logs_level, jtag_bsdl * bsdl_desc,char ** lines) +{ + int i,j,k,inc,offset, number_of_pins,vector_size; + char tmp_str[MAX_ELEMENT_SIZE]; + int tmp_type,tmp_start,tmp_end; + i = 0; + + while( lines[i] ) + { + if( !strncmp(lines[i],"port ",5) || !strncmp(lines[i],"port(",5)) + { + j = 0; + number_of_pins = 0; + + while( lines[i][j] != '(' && lines[i][j]) + { + j++; + } + + do + { + offset = get_next_pin(print_callback,logs_level, (char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); + + if( tmp_start <=tmp_end) + { + number_of_pins += ( (tmp_end - tmp_start) + 1 ); + } + else + { + number_of_pins += ( (tmp_start - tmp_end) + 1 ); + } + + j += offset; + + } while( offset); + + if (number_of_pins == 0 || ( number_of_pins > MAX_NUMBER_PINS_PER_DEV ) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "get_pins_list : bad number of pin found ! : %d\r\n", number_of_pins); + return -1; + } + + bsdl_desc->pins_list = malloc (sizeof(pin_ctrl) * (number_of_pins+1)); + if( bsdl_desc->pins_list ) + { + memset( bsdl_desc->pins_list, 0, sizeof(pin_ctrl) * (number_of_pins+1) ); + + j = 0; + number_of_pins = 0; + + while( lines[i][j] != '(' && lines[i][j]) + { + j++; + } + + do + { + offset = get_next_pin(print_callback,logs_level, (char*)&tmp_str,&tmp_type, &lines[i][j], &tmp_start, &tmp_end ); + + if( tmp_start <= tmp_end ) + { + vector_size = ( (tmp_end - tmp_start) + 1 ); + inc = 1; + } + else + { + vector_size = ( (tmp_start - tmp_end) + 1 ); + inc = -1; + } + + j += offset; + + for(k = 0;k < vector_size; k++) + { + snprintf((char*)&bsdl_desc->pins_list[number_of_pins].pinname,sizeof(((pin_ctrl *)0)->pinname),"%s",(char*)tmp_str); + + if( vector_size > 1 ) + { + char digistr[32]; + snprintf((char*)digistr,sizeof(digistr),"(%d)",tmp_start); + strncat((char*)&bsdl_desc->pins_list[number_of_pins].pinname,digistr,sizeof(((pin_ctrl *)0)->pinname)-1); + } + + bsdl_desc->pins_list[number_of_pins].pintype = tmp_type; + number_of_pins++; + tmp_start += inc; + } + + } while( offset ); + + bsdl_desc->number_of_pins = number_of_pins; + + return number_of_pins; + } + } + i++; + }; + + return 0; +} + +int get_jtag_chain(JTAGCORE_PRINT_FUNC print_callback,int logs_level, jtag_bsdl * bsdl_desc,char ** lines, char * entityname) +{ + char * jtagchain_str; + int i,j,bit_count,end_parse; + char tmp_str[MAX_ELEMENT_SIZE]; + int bit_index; + + bit_count = 0; + bsdl_desc->number_of_chainbits = get_attribut_int(lines,"BOUNDARY_LENGTH", entityname); + if ( ( bsdl_desc->number_of_chainbits > 0 ) && ( bsdl_desc->number_of_chainbits < MAX_NUMBER_BITS_IN_CHAIN ) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Number of bit in the chain = %d\r\n",bsdl_desc->number_of_chainbits); + + bsdl_desc->chain_list = malloc( sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); + if( !bsdl_desc->chain_list ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"get_jtag_chain : memory alloc error !\r\n"); + return -1; + } + + memset(bsdl_desc->chain_list,0, sizeof(jtag_chain) * bsdl_desc->number_of_chainbits ); + + jtagchain_str = get_attribut_txt(lines,"BOUNDARY_REGISTER", entityname); + + end_parse = 0; + + if(jtagchain_str) + { + if( jtagchain_str[0] == '"' ) + { + i = 0; + while( jtagchain_str[i] && !end_parse ) + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"--------------\r\n"); + + // Get index + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + bit_index = atoi(tmp_str); + if (bit_index >= 0 && bit_index < bsdl_desc->number_of_chainbits) + { + bsdl_desc->chain_list[bit_index].bit_index = bit_index; + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_index); + + // Look for ( + while (jtagchain_str[i] != '(' && jtagchain_str[i]) + i++; + + // Get the pin type + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].bit_cell_type = get_typecode(celltype_str, tmp_str); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%d\r\n", bsdl_desc->chain_list[bit_index].bit_cell_type); + + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the name + i += get_next_parameter(print_callback,logs_level, &jtagchain_str[i], bsdl_desc->chain_list[bit_index].pinname); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%s\r\n", bsdl_desc->chain_list[bit_index].pinname); + + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the type + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].bit_type = get_typecode(bittype_str, tmp_str); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "%s , %d\r\n", tmp_str, bsdl_desc->chain_list[bit_index].bit_type); + + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the default state + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].safe_state = get_typecode(statetype_str, tmp_str); + + bsdl_desc->chain_list[bit_index].control_bit_index = -1; + + // If no ) Get the ctrl index + j = check_next_symbol(&jtagchain_str[i], ')'); + + if (jtagchain_str[i]==',' || j < 0) + { + // , + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the control bit + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + + bsdl_desc->chain_list[bit_index].control_bit_index = atoi(tmp_str); + + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the polarity + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].control_disable_state = get_typecode(statetype_str, tmp_str); + + j = check_next_symbol(&jtagchain_str[i], ','); + if (j < 0) + return -1; + i += j; + + // Get the off state + i += get_next_keyword(print_callback,logs_level, &jtagchain_str[i], tmp_str); + string_upper(tmp_str); + bsdl_desc->chain_list[bit_index].control_disable_result = get_typecode(statetype_str, tmp_str); + + // Find and skip ) + j = check_next_symbol(&jtagchain_str[i], ')'); + if (j < 0) + return -1; + } + + i += j; + + // Find , (Next bit) or " (End of the chain) + i++; + bit_count++; + + if (check_next_symbol(&jtagchain_str[i], '"') >= 0) + { + end_parse = 1; + } + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "get_jtag_chain : Error bit index overrun !\r\n"); + } + } + } + } + } + + if( ( bit_count == bsdl_desc->number_of_chainbits ) && ( bsdl_desc->number_of_chainbits != 0 ) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Jtag chain parsing Ok !\r\n"); + + for( i = 0 ; i < (long)bsdl_desc->number_of_pins ; i++ ) + { + + bsdl_desc->pins_list[i].in_bit_number = -1; + bsdl_desc->pins_list[i].out_bit_number = -1; + bsdl_desc->pins_list[i].ctrl_bit_number = -1; + + switch( bsdl_desc->pins_list[i].pintype) + { + case IO_IN: + case IO_OUT: + case IO_INOUT: + + for( j = 0 ; j < (long)bsdl_desc->number_of_chainbits ; j++ ) + { + if(!strcmp(bsdl_desc->chain_list[j].pinname, bsdl_desc->pins_list[i].pinname)) + { + switch( bsdl_desc->chain_list[j].bit_type) + { + case BITTYPE_INPUT: + bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; + break; + case BITTYPE_OUTPUT: + bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; + break; + case BITTYPE_TRISTATE_OUTPUT: + bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; + bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; + break; + case BITTYPE_INOUT: + bsdl_desc->pins_list[i].in_bit_number = bsdl_desc->chain_list[j].bit_index; + bsdl_desc->pins_list[i].out_bit_number = bsdl_desc->chain_list[j].bit_index; + bsdl_desc->pins_list[i].ctrl_bit_number = bsdl_desc->chain_list[j].control_bit_index; + break; + } + } + } + break; + } + } + + return 1; + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"JTAG chain parsing error : %d - %d !\r\n",bit_count,bsdl_desc->number_of_chainbits); + return -1; + } +} + +static int compare_pin_name(const void *a, const void *b) +{ + int ret; + pin_ctrl const *pa = (pin_ctrl const *)a; + pin_ctrl const *pb = (pin_ctrl const *)b; + + ret = strnatcmp(pa->pinname, pb->pinname); + + return ret; +} + +jtag_bsdl * jtag_bsdl_load_file(JTAGCORE_PRINT_FUNC print_callback,int logs_level, int sort_pins, char *filename) +{ + FILE * bsdl_file; + jtag_bsdl * bsdl; + int file_size,offset; + char * bsdl_txt,*tmp_bsdl_txt; + char * tmp_ptr; + int i,number_of_bsdl_lines; + char entityname[256]; + char * chipid_str,* instruct_str; + char * instruct_strchr; + char ** lines; + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"Open BSDL file %s\r\n",filename); + + bsdl = 0; + + bsdl_file = fopen(filename,"rb"); + if (bsdl_file) + { + fseek(bsdl_file, 0, SEEK_END); + file_size = ftell(bsdl_file); + fseek(bsdl_file, 0, SEEK_SET); + + if ( file_size <= 0 || file_size > MAX_BSDL_FILE_SIZE ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Bad BSDL File size ! : %d\r\n", file_size); + fclose(bsdl_file); + return 0; + } + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG, "BSDL file size : %d\r\n", file_size); + + bsdl_txt = malloc(file_size + 1); + if (bsdl_txt) + { + memset(bsdl_txt, 0, file_size + 1); + if( fread(bsdl_txt, file_size, 1, bsdl_file) != 1 ) + { + free(bsdl_txt); + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "BSDL File read error !\r\n"); + fclose(bsdl_file); + return 0; + } + + tmp_bsdl_txt = malloc(file_size + 1); + if (tmp_bsdl_txt) + { + memset(tmp_bsdl_txt, 0, file_size + 1); + offset = 0; + + i = 0; + while (offset < file_size && i < file_size) + { + tmp_bsdl_txt[i] = getnextchar(bsdl_txt, file_size, &offset); + i++; + } + + free(bsdl_txt); + + if (offset < i) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Preprocessing error !\r\n"); + free(tmp_bsdl_txt); + return 0; + } + + bsdl_txt = tmp_bsdl_txt; + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't allocate file memory !\r\n"); + free(bsdl_txt); + fclose(bsdl_file); + return 0; + } + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't allocate file memory !\r\n"); + fclose(bsdl_file); + return 0; + } + } + else + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Can't open %s !\r\n", filename); + return 0; + } + + fclose(bsdl_file); + + // Get the first entity offset + tmp_ptr = strstr(bsdl_txt,"entity"); + if (!tmp_ptr) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "entry \"entity\" not found !\r\n"); + free(bsdl_txt); + return 0; + } + + offset = tmp_ptr - bsdl_txt; + + // skip the entity keyword + while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] ) + offset++; + + // skip the blank spaces + while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) + offset++; + + // copy the entity name + i = 0; + memset(entityname,0,sizeof(entityname)); + while( bsdl_txt[offset] !=' ' && bsdl_txt[offset] && i < ( sizeof(entityname) - 1 )) + { + entityname[i] = bsdl_txt[offset]; + + offset++; + i++; + } + + // skip the blank spaces + while( bsdl_txt[offset] ==' ' && bsdl_txt[offset] ) + offset++; + + // Check the "is" keyword presence + if( strncmp(&bsdl_txt[offset],"is",2) ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "Bad entity entry (\"is\" not found)\r\n"); + free(bsdl_txt); + return 0; + } + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"Entity : %s\r\n",entityname); + + offset += 2; + + // extract and separate each bsdl line + number_of_bsdl_lines = extract_bsdl_lines(&bsdl_txt[offset],0); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"lines :%d\r\n",number_of_bsdl_lines); + + if (number_of_bsdl_lines <= 0 || number_of_bsdl_lines > MAX_NUMBER_OF_BSDL_LINES) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "No line found !\r\n"); + free(bsdl_txt); + return 0; + } + + lines = malloc( sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); + if( !lines ) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"load_bsdlfile : memory alloc error !\r\n"); + free(tmp_bsdl_txt); + return 0; + } + + memset( lines, 0, sizeof(char*) * ( number_of_bsdl_lines + 1 ) ); + + extract_bsdl_lines(&bsdl_txt[offset],lines); + + for(i= 0 ;i< number_of_bsdl_lines;i++) + { + preprocess_line(lines[i]); + } + + bsdl = malloc ( sizeof(jtag_bsdl) ); + if (!bsdl) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR, "load_bsdlfile : memory alloc error !\r\n"); + for( i = 0 ;i < number_of_bsdl_lines ; i++ ) + { + if(lines[i]) + { + free(lines[i]); + lines[i] = 0; + } + } + free(lines); + + free(bsdl_txt); + + return 0; + } + + memset( bsdl , 0 , sizeof(jtag_bsdl) ); + + /////////////////////// + // copy the entity name & the file name + strncpy(bsdl->entity_name,entityname,sizeof(((jtag_bsdl *)0)->entity_name) - 1); + i = strlen(filename); + while(i && filename[i] != '\\') + { + i--; + } + + if(filename[i] == '\\') + i++; + + strncpy(bsdl->src_filename,&filename[i],sizeof(bsdl->src_filename)-1); + + /////////////////////// + // Extract the chip ID + bsdl->chip_id = 0x00000000; + chipid_str = get_attribut_txt(lines,"IDCODE_REGISTER", entityname); + if(chipid_str) + { + if( chipid_str[0] == '"' ) + { + chipid_str++; + i = 0; + while(chipid_str[i]!='"' && chipid_str[i]!=';' && chipid_str[i] && i < 32) + { + if(chipid_str[i] == '1') + { + bsdl->chip_id |= 0x80000000 >> i; + } + i++; + } + } + } + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"ID Code: 0x%.8X\r\n",bsdl->chip_id); + + /////////////////////// + // Extract the pins list + get_pins_list(print_callback,logs_level, bsdl,lines); + + /////////////////////// + // Extract the JTAG Chain + if(get_jtag_chain(print_callback,logs_level, bsdl,lines,entityname)<0) + { + dbg_logs_printf(print_callback,logs_level, MSG_ERROR,"load_bsdlfile : Error during jtag chain parsing !\r\n"); + } + + if(sort_pins > 0) + { + // Count the pins + i = 0; + while(bsdl->pins_list[i].pinname[0]) + { + i++; + } + + // Sort them + qsort(bsdl->pins_list, i, sizeof bsdl->pins_list[0], compare_pin_name); + } + + i = 0; + while(bsdl->pins_list[i].pinname[0]) + { + char dbg_str[512]; + int namelen,j,k; + char disval; + + namelen = strlen(bsdl->pins_list[i].pinname); + + sprintf(dbg_str,"Pin %s",bsdl->pins_list[i].pinname); + for(j=0;j<(16 - namelen);j++) + { + strcat(dbg_str," "); + } + + k = strlen(dbg_str); + + disval = 'X'; + + if(bsdl->pins_list[i].out_bit_number >=0 ) + { + if( bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state >= 0 ) + { + disval = '0' + bsdl->chain_list[bsdl->pins_list[i].out_bit_number].control_disable_state; + } + } + + sprintf(&dbg_str[k]," type %.2d, ctrl %.3d (disval:%c), out %.3d, in %.3d\r\n", + bsdl->pins_list[i].pintype, + bsdl->pins_list[i].ctrl_bit_number, + disval, + bsdl->pins_list[i].out_bit_number, + bsdl->pins_list[i].in_bit_number); + + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,dbg_str); + + i++; + } + + /////////////////////// + // Get the instruction code + + bsdl->number_of_bits_per_instruction = get_attribut_int(lines,"INSTRUCTION_LENGTH", entityname); + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"Instructions lenght : %d\r\n",bsdl->number_of_bits_per_instruction); + + instruct_str = get_attribut_txt(lines,"INSTRUCTION_OPCODE", entityname); + if(instruct_str) + { + instruct_strchr = strstr(instruct_str,"IDCODE"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"idcode"); + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->IDCODE_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"IDCODE : %s\r\n",bsdl->IDCODE_Instruction); + } + + instruct_strchr = strstr(instruct_str,"EXTEST"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"extest"); + + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->EXTEST_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"EXTEST : %s\r\n",bsdl->EXTEST_Instruction); + } + + instruct_strchr = strstr(instruct_str,"BYPASS"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"bypass"); + + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->BYPASS_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"BYPASS : %s\r\n",bsdl->BYPASS_Instruction); + } + + instruct_strchr = strstr(instruct_str,"SAMPLE"); + if(!instruct_strchr) + instruct_strchr = strstr(instruct_str,"sample"); + if(instruct_strchr) + { + get_next_keyword(print_callback,logs_level, instruct_strchr, bsdl->SAMPLE_Instruction); + dbg_logs_printf(print_callback,logs_level, MSG_DEBUG,"SAMPLE : %s\r\n",bsdl->SAMPLE_Instruction); + } + } + + free( bsdl_txt ); + + for( i = 0 ;i < number_of_bsdl_lines ; i++ ) + { + if(lines[i]) + { + free(lines[i]); + lines[i] = 0; + } + } + free(lines); + + dbg_logs_printf(print_callback,logs_level, MSG_INFO_0,"BSDL file %s loaded and parsed\r\n",filename); + + return bsdl; +} + +void jtag_bsdl_unload_file(jtag_bsdl * bsdl) +{ + if( bsdl ) + { + if(bsdl->chain_list) + free(bsdl->chain_list); + + if(bsdl->pins_list) + free(bsdl->pins_list); + + free( bsdl ); + } +} diff --git a/lib_jtag_core/src/dbg_logs.c b/lib_jtag_core/src/dbg_logs.c index dee0fc8..480472e 100644 --- a/lib_jtag_core/src/dbg_logs.c +++ b/lib_jtag_core/src/dbg_logs.c @@ -35,21 +35,18 @@ #include "dbg_logs.h" -int jtagcore_logs_printf(jtag_core * jc,int MSGTYPE,char * chaine, ...) +int dbg_logs_printf(JTAGCORE_PRINT_FUNC print_callback,int logs_level, int MSGTYPE,char * chaine, ...) { char tmp_msg[1024+1]; char tmp_msg2[1024]; - JTAGCORE_PRINT_FUNC print_callback; - if( jc->logs_level > MSGTYPE ) + if( logs_level > MSGTYPE ) { - if( jc->jtagcore_print_callback ) + if( print_callback ) { va_list marker; va_start( marker, chaine ); - print_callback = jc->jtagcore_print_callback; - switch(MSGTYPE) { case MSG_INFO_0: @@ -83,6 +80,7 @@ int jtagcore_logs_printf(jtag_core * jc,int MSGTYPE,char * chaine, ...) return 0; } + int jtagcore_set_logs_callback(jtag_core * jc, JTAGCORE_PRINT_FUNC jtag_core_print) { if(jc) diff --git a/lib_jtag_core/src/dbg_logs.h b/lib_jtag_core/src/dbg_logs.h index 5ecc5b2..8307126 100644 --- a/lib_jtag_core/src/dbg_logs.h +++ b/lib_jtag_core/src/dbg_logs.h @@ -23,4 +23,7 @@ * @author Jean-François DEL NERO */ -int jtagcore_logs_printf(jtag_core * jc, int MSGTYPE, char * chaine, ...); +#ifndef jtagcore_logs_printf +int dbg_logs_printf(JTAGCORE_PRINT_FUNC print_callback,int logs_level, int MSGTYPE,char * chaine, ...); +#define jtagcore_logs_printf(jc, MSGTYPE, ...) dbg_logs_printf(jc->jtagcore_print_callback,jc->logs_level, MSGTYPE, __VA_ARGS__) +#endif diff --git a/lib_jtag_core/src/libjtag_bsdl.h b/lib_jtag_core/src/libjtag_bsdl.h index 1da4a1d..63cbcb6 100644 --- a/lib_jtag_core/src/libjtag_bsdl.h +++ b/lib_jtag_core/src/libjtag_bsdl.h @@ -22,6 +22,7 @@ enum MSGTYPE #define MAX_NUMBER_OF_BSDL_LINES ( 64 * 1024 ) #include "bsdl_parser/jtag_bsdl.h" +#include "dbg_logs.h" #ifdef __cplusplus } From e733c5c50b5fc2ec63206c515ce3f98657c32b17 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Thu, 9 Jun 2022 17:43:33 -0230 Subject: [PATCH 09/24] Exporting to C++ and Python3 --- lib_jtag_core/src/CMakeLists.txt | 1 + lib_jtag_core/test/CMakeLists.txt | 2 +- lib_jtag_core/test/apps/CMakeLists.txt | 10 +++++ lib_jtag_core/test/apps/cxx/CMakeLists.txt | 13 ++++++ .../test/apps/cxx/bindings/CMakeLists.txt | 18 ++++++++ .../test/apps/cxx/bindings/xcSwigHere.cxx | 34 +++++++++++++++ .../test/apps/cxx/bindings/xcSwigHere.h | 10 +++++ lib_jtag_core/test/apps/cxx/cppUI.cxx | 26 +++++++++++ lib_jtag_core/test/apps/py3/CMakeLists.txt | 7 +++ .../test/apps/py3/bindings/CMakeLists.txt | 36 ++++++++++++++++ lib_jtag_core/test/apps/py3/bindings/init.in | 2 + .../test/apps/py3/bindings/py3SwigHere.cxx | 43 +++++++++++++++++++ .../test/apps/py3/bindings/py3SwigHere.h | 10 +++++ .../test/apps/py3/bindings/py3SwigHere.i | 29 +++++++++++++ lib_jtag_core/test/apps/py3/py3UI.py | 32 ++++++++++++++ lib_jtag_core/test/imports/CMakeLists.txt | 6 ++- lib_jtag_core/test/imports/epCoreJTAG.cxx | 31 +++++++++++-- lib_jtag_core/test/imports/epSwigHere.h | 11 +++-- lib_jtag_core/test/imports/uiCoreJTAG.cxx | 2 - 19 files changed, 311 insertions(+), 12 deletions(-) create mode 100644 lib_jtag_core/test/apps/CMakeLists.txt create mode 100644 lib_jtag_core/test/apps/cxx/CMakeLists.txt create mode 100644 lib_jtag_core/test/apps/cxx/bindings/CMakeLists.txt create mode 100644 lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.cxx create mode 100644 lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.h create mode 100644 lib_jtag_core/test/apps/cxx/cppUI.cxx create mode 100644 lib_jtag_core/test/apps/py3/CMakeLists.txt create mode 100644 lib_jtag_core/test/apps/py3/bindings/CMakeLists.txt create mode 100644 lib_jtag_core/test/apps/py3/bindings/init.in create mode 100644 lib_jtag_core/test/apps/py3/bindings/py3SwigHere.cxx create mode 100644 lib_jtag_core/test/apps/py3/bindings/py3SwigHere.h create mode 100644 lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i create mode 100644 lib_jtag_core/test/apps/py3/py3UI.py diff --git a/lib_jtag_core/src/CMakeLists.txt b/lib_jtag_core/src/CMakeLists.txt index b016891..ac81edf 100644 --- a/lib_jtag_core/src/CMakeLists.txt +++ b/lib_jtag_core/src/CMakeLists.txt @@ -7,4 +7,5 @@ set(JTAG_BSDL_SRC ) add_library(jtag_bsdl ${JTAG_BSDL_SRC}) +set_property(TARGET jtag_bsdl PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/lib_jtag_core/test/CMakeLists.txt b/lib_jtag_core/test/CMakeLists.txt index 59340cf..814c364 100644 --- a/lib_jtag_core/test/CMakeLists.txt +++ b/lib_jtag_core/test/CMakeLists.txt @@ -3,5 +3,5 @@ cmake_minimum_required (VERSION 2.8.11) # Recurse into the linux, imports and apps subdirectories. add_subdirectory (linux) add_subdirectory (imports) -#add_subdirectory (apps) +add_subdirectory (apps) diff --git a/lib_jtag_core/test/apps/CMakeLists.txt b/lib_jtag_core/test/apps/CMakeLists.txt new file mode 100644 index 0000000..89d5a09 --- /dev/null +++ b/lib_jtag_core/test/apps/CMakeLists.txt @@ -0,0 +1,10 @@ +# Include language-specific user-interfaces +add_subdirectory(cxx) +find_package(PythonInterp 3 EXACT QUIET) +if(${PYTHONINTERP_FOUND}) + find_package(PythonLibs 3 EXACT QUIET) + if(${PYTHONLIBS_FOUND}) + add_subdirectory(py3) + endif() +endif() + diff --git a/lib_jtag_core/test/apps/cxx/CMakeLists.txt b/lib_jtag_core/test/apps/cxx/CMakeLists.txt new file mode 100644 index 0000000..f955d1d --- /dev/null +++ b/lib_jtag_core/test/apps/cxx/CMakeLists.txt @@ -0,0 +1,13 @@ +# Create a library called "xcSwigHere" and specify the source files. +# The extension is already found. Any number of sources could be listed here. +add_subdirectory(bindings) + +# CPP console application +add_executable (cppUI cppUI.cxx) +set_property(TARGET cppUI PROPERTY POSITION_INDEPENDENT_CODE ON) +#set_target_properties(cppUI PROPERTIES LINK_LIBRARIES -pthread) + +# Link the executable to the libraries upon which it depends. +# Libraries with public include directories will have those link +# directories automatically configured when building the executable +target_link_libraries (cppUI PUBLIC xcSwigHere epCoreJTAG_ jtag_bsdl) diff --git a/lib_jtag_core/test/apps/cxx/bindings/CMakeLists.txt b/lib_jtag_core/test/apps/cxx/bindings/CMakeLists.txt new file mode 100644 index 0000000..f090f90 --- /dev/null +++ b/lib_jtag_core/test/apps/cxx/bindings/CMakeLists.txt @@ -0,0 +1,18 @@ +# Create static and shared libraries and specify the source files. +# Any number of sources could be listed here. +add_library(xcSwigHere_ STATIC xcSwigHere.cxx) +add_library(xcSwigHere SHARED xcSwigHere.cxx) + +# For static library, enable position independent code +set_property(TARGET xcSwigHere_ PROPERTY POSITION_INDEPENDENT_CODE ON) + +# Follow these directions to minimize the number of shared libraries generated: +# Link the static binding to the shared version of the project's API library +target_link_libraries (xcSwigHere_ LINK_PUBLIC epCoreJTAG) +# Link the shared binding to the static version of the project's API library +target_link_libraries (xcSwigHere LINK_PUBLIC epCoreJTAG_) + +# Make sure the compiler can find include files for our library +# when other libraries or executables link to fftTOO +target_include_directories(xcSwigHere_ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(xcSwigHere PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.cxx b/lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.cxx new file mode 100644 index 0000000..91af77b --- /dev/null +++ b/lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.cxx @@ -0,0 +1,34 @@ +// xcSwigHere.cpp + +#include "xcSwigHere.h" +#include +#include "stdio.h" // for debugging + +static SWIGHERE_CONTEXT pContext=NULL; + +extern void xcUninitSwigHere() { + if(pContext != NULL) { + epUninitSwigHere(pContext); + pContext=NULL; + } +} + +extern void xcInitSwigHere() { + xcUninitSwigHere(); + pContext=epInitSwigHere(); + //return pContext; +} + +extern unsigned long int xcBSDLDeviceId(char * pathToBSDL) { + return epBSDLDeviceId(pContext,pathToBSDL); +} + +extern std::vector xcBSDLPinSequence(char * pathToBSDL) { + std::vector noresult; + unsigned bytesPerElement=0; + std::vector pinSequence = epBSDLPinSequence(pContext, pathToBSDL,&bytesPerElement); + if( bytesPerElement == sizeof(pin_ctrl)) { + return pinSequence; + } + return noresult; +} diff --git a/lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.h b/lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.h new file mode 100644 index 0000000..d286a58 --- /dev/null +++ b/lib_jtag_core/test/apps/cxx/bindings/xcSwigHere.h @@ -0,0 +1,10 @@ +// xcSwigHere.h +#pragma once + +#include +#include "epSwigHere.h" + +extern void xcInitSwigHere(); +extern unsigned long int xcBSDLDeviceId(char * pathToBSDL); +extern std::vector xcBSDLPinSequence(char * pathToBSDL); +extern void xcUninitSwigHere(); diff --git a/lib_jtag_core/test/apps/cxx/cppUI.cxx b/lib_jtag_core/test/apps/cxx/cppUI.cxx new file mode 100644 index 0000000..0af8829 --- /dev/null +++ b/lib_jtag_core/test/apps/cxx/cppUI.cxx @@ -0,0 +1,26 @@ +#include +#include +#include + +#include "xcSwigHere.h" + +int main(int argc, char * argv[]) { + int lastResult=-1; + unsigned cbInt=0; + unsigned nInts=0; + const int * ptr; + xcInitSwigHere(); + if(argc>1) { + long unsigned int id = xcBSDLDeviceId(argv[1]); + if(id > 0 ) { + std::vector pinSequence = xcBSDLPinSequence(argv[1]); + printf("BSDL file describes device id %lx\r\n",id); + for(unsigned i = 0; i + +static SWIGHERE_CONTEXT pContext=NULL; + +extern void pyUninitSwigHere() { + if(pContext != NULL) { + epUninitSwigHere(pContext); + pContext=NULL; + } +} + +extern void pyInitSwigHere() { + pyUninitSwigHere(); + pContext=epInitSwigHere(); + //return pContext; +} + +extern unsigned long int pyBSDLDeviceId(std::string pathToBSDL) { + if(pContext) { + return epBSDLDeviceId(pContext,(char*)pathToBSDL.c_str()); + } + return 0; +} + +extern std::vector pyBSDLPinSequence(std::string pathToBSDL) { + std::vector result; + if(pContext) { + unsigned bytesPerElement=0, elementCount=0; + std::vector pinSequence = epBSDLPinSequence(pContext, (char*)pathToBSDL.c_str(), &bytesPerElement); + if( bytesPerElement == sizeof(pin_ctrl) ) { + for(unsigned i = 0; i +#include + +extern void pyInitSwigHere(); +extern void pyUninitSwigHere(); +extern unsigned long int pyBSDLDeviceId(std::string pathToBSDL); +extern std::vector pyBSDLPinSequence(std::string pathToBSDL); diff --git a/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i new file mode 100644 index 0000000..af78d47 --- /dev/null +++ b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i @@ -0,0 +1,29 @@ +// py3SwigHere.i +%module pySwigHere + +%{ +#define SWIG_FILE_WITH_INIT +%} + +%init %{ +%} + +%include "std_vector.i" +%include "std_string.i" + +%{ +#include "py3SwigHere.h" +%} + +%template(vectori) std::vector; + +%extend std::vector { + void empty_and_delete() { + for (std::vector::iterator it = $self->begin(); + it != $self->end(); ++it) { + // if it was a pointer, we could delete *it; + } + $self->clear(); + } +} +%include "py3SwigHere.h" diff --git a/lib_jtag_core/test/apps/py3/py3UI.py b/lib_jtag_core/test/apps/py3/py3UI.py new file mode 100644 index 0000000..8cb4f5f --- /dev/null +++ b/lib_jtag_core/test/apps/py3/py3UI.py @@ -0,0 +1,32 @@ +""" +Sample program showing import of external library in Python 3 +""" +from __future__ import print_function +import bindings as SWIGHERE + +class CSwigHere: + def __init__(self): + pass + + def pyBSDLDeviceId(self,pathToBSDL): + return SWIGHERE.pyBSDLDeviceId(pathToBSDL); + + def pyBSDLPinSequence(self,pathToBSDL): + return SWIGHERE.pyBSDLPinSequence(pathToBSDL); + + def __enter__(self): + SWIGHERE.pyInitSwigHere(); + return self + + def __exit__(self,exType,exValue,trace): + SWIGHERE.pyUninitSwigHere(); + +if __name__=="__main__": + import sys + with CSwigHere() as instance: + if len(sys.argv) > 1: + deviceId = instance.pyBSDLDeviceId(sys.argv[1]) + if deviceId > 0: + pinList = instance.pyBSDLPinSequence(sys.argv[1]) + print(pinList) + diff --git a/lib_jtag_core/test/imports/CMakeLists.txt b/lib_jtag_core/test/imports/CMakeLists.txt index 094bd70..040a0e5 100644 --- a/lib_jtag_core/test/imports/CMakeLists.txt +++ b/lib_jtag_core/test/imports/CMakeLists.txt @@ -10,10 +10,12 @@ set_property(TARGET epCoreJTAG_ PROPERTY POSITION_INDEPENDENT_CODE ON) # Make sure the compiler can find include files for our library # when other libraries or executables link to fftTOO target_include_directories (epCoreJTAG_ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "${STREETVIEWJTAG_SOURCE_DIR}/src") -target_include_directories (epCoreJTAG PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "${STREETVIEWJTAG_SOURCE_DIR}/src") +set_property(TARGET epCoreJTAG_ PROPERTY INTERFACE_LINK_LIBRARIES jtag_bsdl) +target_link_libraries(epCoreJTAG_ jtag_bsdl) +target_include_directories (epCoreJTAG PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "${STREETVIEWJTAG_SOURCE_DIR}/src") set_property(TARGET epCoreJTAG PROPERTY INTERFACE_LINK_LIBRARIES jtag_bsdl) -set_property(TARGET epCoreJTAG_ PROPERTY INTERFACE_LINK_LIBRARIES jtag_bsdl) +target_link_libraries(epCoreJTAG jtag_bsdl) add_executable(uiCoreJTAG uiCoreJTAG.cxx) target_link_libraries(uiCoreJTAG epCoreJTAG jtag_bsdl) diff --git a/lib_jtag_core/test/imports/epCoreJTAG.cxx b/lib_jtag_core/test/imports/epCoreJTAG.cxx index 7f6117c..0c12a3c 100644 --- a/lib_jtag_core/test/imports/epCoreJTAG.cxx +++ b/lib_jtag_core/test/imports/epCoreJTAG.cxx @@ -1,12 +1,9 @@ #include #include -#include "libjtag_bsdl.h" #include "epSwigHere.h" #include #include -#include - static void logger(char * string) { printf("%s",string); @@ -70,3 +67,31 @@ extern long unsigned int epBSDLDeviceId(SWIGHERE_CONTEXT oContext, char * pathTo } return (long unsigned int) result; } + +extern std::vector epBSDLPinSequence(SWIGHERE_CONTEXT oContext, char * pathToBSDL, unsigned * pBytesPerElement) { + int * p=NULL; + std::vector result; + + if(pBytesPerElement != NULL) { + *pBytesPerElement = sizeof(pin_ctrl); + } + if(oContext==(SWIGHERE_CONTEXT)&garbageCollector) { + jtag_bsdl * details = jtag_bsdl_load_file(logger,MSG_DEBUG, 0, pathToBSDL); + if ( details != NULL ) { + int number_of_pins = details->number_of_pins; + int i = 0; + if(number_of_pins>0) { + while(ipins_list; + result.push_back(pins_list[i]); + i++; + } + } + } + } + + return result; +}; + +//extern std::vector epBSDLChainSequence(SWIGHERE_CONTEXT oContext, char * pathToFile, unsigned * pBytesPerElement,unsigned * pElementCount); +//extern std::vector epBSDLPinSequence(SWIGHERE_CONTEXT oContext, char * pathToBSDL, unsigned * pBytesPerElement,unsigned * pElementCount) { diff --git a/lib_jtag_core/test/imports/epSwigHere.h b/lib_jtag_core/test/imports/epSwigHere.h index 18d7dd6..307bd8c 100644 --- a/lib_jtag_core/test/imports/epSwigHere.h +++ b/lib_jtag_core/test/imports/epSwigHere.h @@ -1,8 +1,11 @@ -// epSWIGHere.h for CoreJTAG +// epSWIGHere.h for libjtag_bsdl #pragma once #include +#include #include +#include "libjtag_bsdl.h" + typedef enum _SWIGHERE_TYPE { VOIDPTR=0, INTPTR @@ -14,7 +17,7 @@ typedef std::pair SWIGHERE_INTLIST; typedef volatile void * SWIGHERE_CONTEXT; extern SWIGHERE_CONTEXT epInitSwigHere(); -extern long unsigned int epBSDLDeviceId(SWIGHERE_CONTEXT oContext, char * pathToFile); -extern SWIGHERE_INTLIST epSequence(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); -//extern SWIGHERE_INTLIST epBSDLPinMap(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); +extern long unsigned int epBSDLDeviceId(SWIGHERE_CONTEXT oContext, char * pathToBSDL); +extern std::vector epBSDLPinSequence(SWIGHERE_CONTEXT oContext, char * pathToBSDL, unsigned * pBytesPerElement); +extern std::vector epBSDLChainSequence(SWIGHERE_CONTEXT oContext, char * pathToBSDL, unsigned * pBytesPerElement); extern void epUninitSwigHere(SWIGHERE_CONTEXT oContext); diff --git a/lib_jtag_core/test/imports/uiCoreJTAG.cxx b/lib_jtag_core/test/imports/uiCoreJTAG.cxx index 439f7ec..6cfd3c8 100644 --- a/lib_jtag_core/test/imports/uiCoreJTAG.cxx +++ b/lib_jtag_core/test/imports/uiCoreJTAG.cxx @@ -7,8 +7,6 @@ int main(int argc, char * argv[], char ** envp) { if(context != NULL) { if(argc>1) { long unsigned int id = epBSDLDeviceId(context, argv[1]); - //SWIGHERE_INTLIST epSequence(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); - //extern SWIGHERE_INTLIST epBSDLPinMap(SWIGHERE_CONTEXT oContext,unsigned * pBytesPerElement,unsigned * pElementCount); printf("BSDL file describes device id %lx\r\n",id); } epUninitSwigHere(context); From a8dcccd7e3c58764fbe2829b1a8973a60d1cd02d Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Thu, 9 Jun 2022 22:09:11 -0230 Subject: [PATCH 10/24] JSON-parsable results --- .../test/apps/py3/bindings/py3SwigHere.cxx | 88 ++++++++++++++++++- .../test/apps/py3/bindings/py3SwigHere.h | 3 +- .../test/apps/py3/bindings/py3SwigHere.i | 7 +- lib_jtag_core/test/apps/py3/py3UI.py | 15 +++- lib_jtag_core/test/imports/epCoreJTAG.cxx | 32 ++++++- 5 files changed, 133 insertions(+), 12 deletions(-) diff --git a/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.cxx b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.cxx index e2d7789..bceadb1 100644 --- a/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.cxx +++ b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.cxx @@ -26,15 +26,97 @@ extern unsigned long int pyBSDLDeviceId(std::string pathToBSDL) { } return 0; } +/* +typedef struct _pin_ctrl +{ + char pinname[MAX_ELEMENT_SIZE]; + int pintype; -extern std::vector pyBSDLPinSequence(std::string pathToBSDL) { - std::vector result; + char physical_pin[MAX_ELEMENT_SIZE]; + + int ctrl_bit_number; + int out_bit_number; + int in_bit_number; +}pin_ctrl; +*/ + +extern std::vector pyBSDLPinSequence(std::string pathToBSDL) { + std::vector result; if(pContext) { unsigned bytesPerElement=0, elementCount=0; std::vector pinSequence = epBSDLPinSequence(pContext, (char*)pathToBSDL.c_str(), &bytesPerElement); if( bytesPerElement == sizeof(pin_ctrl) ) { for(unsigned i = 0; i pyBSDLChainSequence(std::string pathToBSDL) { + std::vector result; + if(pContext) { + unsigned bytesPerElement=0, elementCount=0; + std::vector chainSequence = epBSDLChainSequence(pContext, (char*)pathToBSDL.c_str(), &bytesPerElement); + if( bytesPerElement == sizeof(jtag_chain) ) { + for(unsigned i = 0; i < chainSequence.size(); i++) { + static char formatter[] = { + "{" + "\"name\":\"%0.64s\"," + "\"index\": %8i," + "\"cell_type\": %8i," + "\"bit_type\": %8i" + "}" + }; + char bfJsonConversion[256]=""; + sprintf(bfJsonConversion,formatter, + chainSequence[i].pinname, + chainSequence[i].bit_index, + chainSequence[i].bit_cell_type, + chainSequence[i].bit_type + ); + result.push_back(bfJsonConversion); } } } diff --git a/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.h b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.h index 0bd5f6e..456d632 100644 --- a/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.h +++ b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.h @@ -7,4 +7,5 @@ extern void pyInitSwigHere(); extern void pyUninitSwigHere(); extern unsigned long int pyBSDLDeviceId(std::string pathToBSDL); -extern std::vector pyBSDLPinSequence(std::string pathToBSDL); +extern std::vector pyBSDLPinSequence(std::string pathToBSDL); +extern std::vector pyBSDLChainSequence(std::string pathToBSDL); diff --git a/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i index af78d47..ba00dee 100644 --- a/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i +++ b/lib_jtag_core/test/apps/py3/bindings/py3SwigHere.i @@ -15,15 +15,16 @@ #include "py3SwigHere.h" %} -%template(vectori) std::vector; +%template(c2json) std::vector; -%extend std::vector { +%extend std::vector { void empty_and_delete() { - for (std::vector::iterator it = $self->begin(); + for (std::vector::iterator it = $self->begin(); it != $self->end(); ++it) { // if it was a pointer, we could delete *it; } $self->clear(); } } + %include "py3SwigHere.h" diff --git a/lib_jtag_core/test/apps/py3/py3UI.py b/lib_jtag_core/test/apps/py3/py3UI.py index 8cb4f5f..57b80ff 100644 --- a/lib_jtag_core/test/apps/py3/py3UI.py +++ b/lib_jtag_core/test/apps/py3/py3UI.py @@ -3,6 +3,7 @@ """ from __future__ import print_function import bindings as SWIGHERE +import json class CSwigHere: def __init__(self): @@ -14,6 +15,9 @@ def pyBSDLDeviceId(self,pathToBSDL): def pyBSDLPinSequence(self,pathToBSDL): return SWIGHERE.pyBSDLPinSequence(pathToBSDL); + def pyBSDLChainSequence(self,pathToBSDL): + return SWIGHERE.pyBSDLChainSequence(pathToBSDL); + def __enter__(self): SWIGHERE.pyInitSwigHere(); return self @@ -27,6 +31,15 @@ def __exit__(self,exType,exValue,trace): if len(sys.argv) > 1: deviceId = instance.pyBSDLDeviceId(sys.argv[1]) if deviceId > 0: + chainMembers = [] pinList = instance.pyBSDLPinSequence(sys.argv[1]) - print(pinList) + chainList = instance.pyBSDLChainSequence(sys.argv[1]) + pinListJSON = [json.loads(s) for s in pinList] + chainListJSON = [ json.loads(s) for s in chainList] + chainListDict = { chain["index"]: chain for chain in chainListJSON} + for pin in pinListJSON: + chain_positions=[pin[key] for key in ["ctrl_bit","out_bit","in_bit"] if pin[key]>=0] + if any(chain_positions): + chainMembers.append(pin) + print(chainListDict) diff --git a/lib_jtag_core/test/imports/epCoreJTAG.cxx b/lib_jtag_core/test/imports/epCoreJTAG.cxx index 0c12a3c..623e213 100644 --- a/lib_jtag_core/test/imports/epCoreJTAG.cxx +++ b/lib_jtag_core/test/imports/epCoreJTAG.cxx @@ -76,7 +76,8 @@ extern std::vector epBSDLPinSequence(SWIGHERE_CONTEXT oContext, char * *pBytesPerElement = sizeof(pin_ctrl); } if(oContext==(SWIGHERE_CONTEXT)&garbageCollector) { - jtag_bsdl * details = jtag_bsdl_load_file(logger,MSG_DEBUG, 0, pathToBSDL); + const int sortPins=1; + jtag_bsdl * details = jtag_bsdl_load_file(logger,MSG_DEBUG, sortPins, pathToBSDL); if ( details != NULL ) { int number_of_pins = details->number_of_pins; int i = 0; @@ -91,7 +92,30 @@ extern std::vector epBSDLPinSequence(SWIGHERE_CONTEXT oContext, char * } return result; -}; +} -//extern std::vector epBSDLChainSequence(SWIGHERE_CONTEXT oContext, char * pathToFile, unsigned * pBytesPerElement,unsigned * pElementCount); -//extern std::vector epBSDLPinSequence(SWIGHERE_CONTEXT oContext, char * pathToBSDL, unsigned * pBytesPerElement,unsigned * pElementCount) { +extern std::vector epBSDLChainSequence(SWIGHERE_CONTEXT oContext, char * pathToBSDL, unsigned * pBytesPerElement) { + int * p=NULL; + std::vector result; + + if(pBytesPerElement != NULL) { + *pBytesPerElement = sizeof(jtag_chain); + } + if(oContext==(SWIGHERE_CONTEXT)&garbageCollector) { + const int sortPins=1; + jtag_bsdl * details = jtag_bsdl_load_file(logger,MSG_DEBUG, sortPins, pathToBSDL); + if ( details != NULL ) { + int number_of_chains = details->number_of_chainbits; + int i = 0; + if(number_of_chains>0) { + while(ichain_list; + result.push_back(chain_list[i]); + i++; + } + } + } + } + + return result; +} From d56d2f47bacd6a11c7c75fa551a2622cef6bd800 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 08:58:57 -0230 Subject: [PATCH 11/24] Create InterfaceSWIG.yml --- .github/workflows/InterfaceSWIG.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/InterfaceSWIG.yml diff --git a/.github/workflows/InterfaceSWIG.yml b/.github/workflows/InterfaceSWIG.yml new file mode 100644 index 0000000..ee0f042 --- /dev/null +++ b/.github/workflows/InterfaceSWIG.yml @@ -0,0 +1,23 @@ +name: SWIG and CMake + +on: + - workflow_dispatch + +defaults: + run: + working-directory: ./lib_jtag_core + +jobs: + build: + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: install swig + run: sudo apt install swig + - name: build using CMakw + run | + mkdir -p cmake + cmake .. . + make + From 49c2122e871680bc2fa9d93b46cc798d75be1e96 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 09:04:22 -0230 Subject: [PATCH 12/24] Update ccpp.yml do not automatically trigger action when editing workfolws --- .github/workflows/ccpp.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index f29950d..205e525 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -1,7 +1,9 @@ name: C/C++ CI on: - - push + - push: + paths-ignore: + - .github/workflows - workflow_dispatch defaults: From a825a3cb8a9cfff98b6becab333bd533b4162241 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 09:06:19 -0230 Subject: [PATCH 13/24] YML syntax --- .github/workflows/InterfaceSWIG.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/InterfaceSWIG.yml b/.github/workflows/InterfaceSWIG.yml index ee0f042..2aaf83e 100644 --- a/.github/workflows/InterfaceSWIG.yml +++ b/.github/workflows/InterfaceSWIG.yml @@ -16,8 +16,8 @@ jobs: - name: install swig run: sudo apt install swig - name: build using CMakw - run | + run: | mkdir -p cmake cmake .. . - make + cmake --build . From 4bf6562e49dd8f3bc4045c5ad140c436670ecfab Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 09:13:51 -0230 Subject: [PATCH 14/24] Update ccpp.yml --- .github/workflows/ccpp.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 205e525..89e7d66 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -1,10 +1,9 @@ name: C/C++ CI on: - - push: + push: paths-ignore: - - .github/workflows - - workflow_dispatch + - ".github/workflows" defaults: run: From 60bc81c7ed2f9d9a2a6d5ad6b694f0fdb2b84a52 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 09:21:05 -0230 Subject: [PATCH 15/24] Update InterfaceSWIG.yml --- .github/workflows/InterfaceSWIG.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/InterfaceSWIG.yml b/.github/workflows/InterfaceSWIG.yml index 2aaf83e..93ab9e1 100644 --- a/.github/workflows/InterfaceSWIG.yml +++ b/.github/workflows/InterfaceSWIG.yml @@ -1,7 +1,6 @@ name: SWIG and CMake -on: - - workflow_dispatch +on: workflow_dispatch defaults: run: From 1a5fbe4fd477c3015976615d5090f7360356cc87 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 09:27:28 -0230 Subject: [PATCH 16/24] Update InterfaceSWIG.yml --- .github/workflows/InterfaceSWIG.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/InterfaceSWIG.yml b/.github/workflows/InterfaceSWIG.yml index 93ab9e1..3613317 100644 --- a/.github/workflows/InterfaceSWIG.yml +++ b/.github/workflows/InterfaceSWIG.yml @@ -17,6 +17,7 @@ jobs: - name: build using CMakw run: | mkdir -p cmake + cd cmake cmake .. . cmake --build . From 7fa2a6f48e872b2bff42f1e34945a612ca8f42de Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 12:16:27 -0230 Subject: [PATCH 17/24] Using TCL/Tk via Python to visualize BSDL contents --- lib_jtag_core/test/apps/py3/py3UI.py | 98 ++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/lib_jtag_core/test/apps/py3/py3UI.py b/lib_jtag_core/test/apps/py3/py3UI.py index 57b80ff..0e8ec82 100644 --- a/lib_jtag_core/test/apps/py3/py3UI.py +++ b/lib_jtag_core/test/apps/py3/py3UI.py @@ -4,6 +4,7 @@ from __future__ import print_function import bindings as SWIGHERE import json +from tkinter import * class CSwigHere: def __init__(self): @@ -25,21 +26,110 @@ def __enter__(self): def __exit__(self,exType,exValue,trace): SWIGHERE.pyUninitSwigHere(); +def pinsToChains(chainListDict,pincount,chainMembers): + chaincount = len(chainListDict.keys()) + canvasWidth = max(400,6*chaincount//4) + canvasHeight = canvasWidth + app = Tk() + app.geometry("%ix%i"%(canvasWidth,canvasHeight)) + canvas = Canvas(app, bg='black') + canvas.pack(anchor='nw', fill='both', expand=1) + chainMargin=30 + pinMargin=90 + canvas.create_rectangle( + chainMargin, chainMargin, canvasWidth-chainMargin, canvasHeight-chainMargin, + outline="grey", + fill="white" + ) + canvas.create_rectangle( + pinMargin, pinMargin, canvasWidth-pinMargin, canvasHeight-pinMargin, + outline="black", + fill="grey" + ) + chainSize = (canvasWidth-2*chainMargin,canvasHeight-2*chainMargin) + chainSpacing = (chainSize[0]/(chaincount//4),chainSize[1]/(chaincount//4)) + canvas.create_text( + canvasWidth - chainMargin - chainSpacing[0],chainMargin + chainSpacing[1], + anchor=NE, + fill="darkblue", + font="Times 20 italic bold", + text="1" + ) + + for chain in range(chaincount): + if chain in range(chaincount//4): + x = canvasWidth - chainMargin - chainSpacing[0]//2 + y = chainMargin + chainSpacing[1]//2 + chainSpacing[1]*(chain%(chaincount//4)) + elif chain in range(chaincount//4,chaincount//2): + y = canvasWidth-chainMargin-chainSpacing[1]//2 + x = canvasWidth - chainMargin - chainSpacing[0]//2 - chainSpacing[0]*(chain%(chaincount//4)) + elif chain in range(chaincount//2,3*chaincount//4): + x = chainMargin + chainSpacing[0]//2 + y = canvasWidth - chainMargin - chainSpacing[1]//2 - chainSpacing[1]*(chain%(chaincount//4)) + else: + y = chainMargin + chainSpacing[1]//2 + x = chainMargin + chainSpacing[0]//2 + chainSpacing[0]*(chain%(chaincount//4)) + + canvas.create_oval( + x-2, y-2, x+2, y+2, + fill="grey", + tag="chain%i"%chain + ) + + pinoutSize = (canvasWidth-2*pinMargin,canvasHeight-2*pinMargin) + pinSpacing = (pinoutSize[0]/(pincount//4),pinoutSize[1]/(pincount//4)) + canvas.create_text( + canvasWidth - pinMargin - pinSpacing[0],pinMargin + pinSpacing[1], + anchor=NE, + fill="darkblue", + font="Times 20 italic bold", + text="1" + ) + + for pin in range(pincount): + if pin in range(pincount//4): + x = canvasWidth - pinMargin - pinSpacing[0]//2 + y = pinMargin + pinSpacing[1]//2 + pinSpacing[1]*(pin%(pincount//4)) + elif pin in range(pincount//4,pincount//2): + y = canvasWidth-pinMargin-pinSpacing[1]//2 + x = canvasWidth - pinMargin - pinSpacing[0]//2 - pinSpacing[0]*(pin%(pincount//4)) + elif pin in range(pincount//2,3*pincount//4): + x = pinMargin + pinSpacing[0]//2 + y = canvasWidth - pinMargin - pinSpacing[1]//2 - pinSpacing[1]*(pin%(pincount//4)) + else: + y = pinMargin + pinSpacing[1]//2 + x = pinMargin + pinSpacing[0]//2 + pinSpacing[0]*(pin%(pincount//4)) + + canvas.create_oval( + x-2.5, y-2.5, x+2.5, y+2.5, + fill="white", + tag="pin%i"%pin + ) + + canvas.create_text( + canvasWidth//2,canvasHeight//2, + fill="darkblue", + font="Times 20 italic bold", + text="Floorplan showing relationship between pins and chains" + ) + + app.mainloop() + if __name__=="__main__": import sys with CSwigHere() as instance: if len(sys.argv) > 1: deviceId = instance.pyBSDLDeviceId(sys.argv[1]) if deviceId > 0: - chainMembers = [] + chainMembers = {} pinList = instance.pyBSDLPinSequence(sys.argv[1]) chainList = instance.pyBSDLChainSequence(sys.argv[1]) pinListJSON = [json.loads(s) for s in pinList] chainListJSON = [ json.loads(s) for s in chainList] chainListDict = { chain["index"]: chain for chain in chainListJSON} - for pin in pinListJSON: + for pinnumber,pin in enumerate(pinListJSON): chain_positions=[pin[key] for key in ["ctrl_bit","out_bit","in_bit"] if pin[key]>=0] if any(chain_positions): - chainMembers.append(pin) - print(chainListDict) + chainMembers[pinnumber]=pin + pinsToChains(chainListDict,len(pinList),chainMembers) From 2218c7183ed6cd3d95be86a1b860323097371197 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 14:28:02 -0230 Subject: [PATCH 18/24] Sample Program for article on Medium --- lib_jtag_core/test/apps/py3/py3UI.py | 84 ++++++++++++++++++----- lib_jtag_core/test/imports/epCoreJTAG.cxx | 4 +- 2 files changed, 69 insertions(+), 19 deletions(-) diff --git a/lib_jtag_core/test/apps/py3/py3UI.py b/lib_jtag_core/test/apps/py3/py3UI.py index 0e8ec82..47c91d8 100644 --- a/lib_jtag_core/test/apps/py3/py3UI.py +++ b/lib_jtag_core/test/apps/py3/py3UI.py @@ -2,6 +2,7 @@ Sample program showing import of external library in Python 3 """ from __future__ import print_function +from turtle import color import bindings as SWIGHERE import json from tkinter import * @@ -26,7 +27,54 @@ def __enter__(self): def __exit__(self,exType,exValue,trace): SWIGHERE.pyUninitSwigHere(); -def pinsToChains(chainListDict,pincount,chainMembers): +def connectPinToChains(canvas,pin,member,pincount,chaincountCeil3,canvasWidth,canvasHeight,chainMargin,chainSpacing,pinMargin,pinSpacing): + print(member) + if pin in range(pincount//4): + x = canvasWidth - pinMargin - pinSpacing[0]//2 + y = pinMargin + pinSpacing[1]//2 + pinSpacing[1]*(pin%(pincount//4)) + elif pin in range(pincount//4,pincount//2): + y = canvasWidth-pinMargin-pinSpacing[1]//2 + x = canvasWidth - pinMargin - pinSpacing[0]//2 - pinSpacing[0]*(pin%(pincount//4)) + elif pin in range(pincount//2,3*pincount//4): + x = pinMargin + pinSpacing[0]//2 + y = canvasWidth - pinMargin - pinSpacing[1]//2 - pinSpacing[1]*(pin%(pincount//4)) + else: + y = pinMargin + pinSpacing[1]//2 + x = pinMargin + pinSpacing[0]//2 + pinSpacing[0]*(pin%(pincount//4)) + + for key in ["ctrl_bit","out_bit","in_bit"]: + chain = member[key] + if chain > 0: + if chain in range(chaincountCeil3//3): + xx = canvasWidth - chainMargin - chainSpacing[0]/2 + yy = chainMargin + chainSpacing[1]/2 + chainSpacing[1]*(chain%(chaincountCeil3//3)) + elif chain in range(chaincountCeil3//3,2*chaincountCeil3//3): + yy = canvasHeight-chainMargin-chainSpacing[1]/2 + xx = canvasWidth - chainMargin - chainSpacing[0]/2 - chainSpacing[0]*(chain%(chaincountCeil3//3)) + else: + xx = chainMargin + chainSpacing[0]/2 + yy = canvasHeight - chainMargin - chainSpacing[1]/2 - chainSpacing[1]*(chain%(chaincountCeil3//3)) + + if key == "ctrl_bit": + lwidth = 2 + fcolor = "gray" + larrow = NONE + else: + lwidth=1 + fcolor="black" + if member["in_bit"] == member["out_bit"]: + larrow=BOTH + elif key=="out_bit": + larrow=LAST + else: + larrow=FIRST + + canvas.create_line( + x,y,xx,yy,fill=fcolor,arrow=larrow,width=lwidth + ) + +def pinsToChains(chainListDict,pinListJSON,chainMembers): + pincount = len(pinListJSON) chaincount = len(chainListDict.keys()) canvasWidth = max(400,6*chaincount//4) canvasHeight = canvasWidth @@ -35,7 +83,7 @@ def pinsToChains(chainListDict,pincount,chainMembers): canvas = Canvas(app, bg='black') canvas.pack(anchor='nw', fill='both', expand=1) chainMargin=30 - pinMargin=90 + pinMargin=chainMargin*8 canvas.create_rectangle( chainMargin, chainMargin, canvasWidth-chainMargin, canvasHeight-chainMargin, outline="grey", @@ -46,8 +94,9 @@ def pinsToChains(chainListDict,pincount,chainMembers): outline="black", fill="grey" ) + chaincountCeil3=chaincount+2 chainSize = (canvasWidth-2*chainMargin,canvasHeight-2*chainMargin) - chainSpacing = (chainSize[0]/(chaincount//4),chainSize[1]/(chaincount//4)) + chainSpacing = (chainSize[0]/(chaincountCeil3//3),chainSize[1]/(chaincountCeil3//3)) canvas.create_text( canvasWidth - chainMargin - chainSpacing[0],chainMargin + chainSpacing[1], anchor=NE, @@ -57,18 +106,15 @@ def pinsToChains(chainListDict,pincount,chainMembers): ) for chain in range(chaincount): - if chain in range(chaincount//4): - x = canvasWidth - chainMargin - chainSpacing[0]//2 - y = chainMargin + chainSpacing[1]//2 + chainSpacing[1]*(chain%(chaincount//4)) - elif chain in range(chaincount//4,chaincount//2): - y = canvasWidth-chainMargin-chainSpacing[1]//2 - x = canvasWidth - chainMargin - chainSpacing[0]//2 - chainSpacing[0]*(chain%(chaincount//4)) - elif chain in range(chaincount//2,3*chaincount//4): - x = chainMargin + chainSpacing[0]//2 - y = canvasWidth - chainMargin - chainSpacing[1]//2 - chainSpacing[1]*(chain%(chaincount//4)) + if chain in range(chaincountCeil3//3): + x = canvasWidth - chainMargin - chainSpacing[0]/2 + y = chainMargin + chainSpacing[1]/2 + chainSpacing[1]*(chain%(chaincountCeil3//3)) + elif chain in range(chaincountCeil3//3,2*chaincountCeil3//3): + y = canvasHeight-chainMargin-chainSpacing[1]/2 + x = canvasWidth - chainMargin - chainSpacing[0]/2 - chainSpacing[0]*(chain%(chaincountCeil3//3)) else: - y = chainMargin + chainSpacing[1]//2 - x = chainMargin + chainSpacing[0]//2 + chainSpacing[0]*(chain%(chaincount//4)) + x = chainMargin + chainSpacing[0]/2 + y = canvasHeight - chainMargin - chainSpacing[1]/2 - chainSpacing[1]*(chain%(chaincountCeil3//3)) canvas.create_oval( x-2, y-2, x+2, y+2, @@ -83,7 +129,7 @@ def pinsToChains(chainListDict,pincount,chainMembers): anchor=NE, fill="darkblue", font="Times 20 italic bold", - text="1" + text=pinListJSON[0]["name"] ) for pin in range(pincount): @@ -106,11 +152,15 @@ def pinsToChains(chainListDict,pincount,chainMembers): tag="pin%i"%pin ) + for pin in chainMembers: + member = chainMembers[pin]; + connectPinToChains(canvas,pin,member,pincount,chaincountCeil3,canvasWidth,canvasHeight,chainMargin,chainSpacing,pinMargin,pinSpacing) + canvas.create_text( canvasWidth//2,canvasHeight//2, fill="darkblue", font="Times 20 italic bold", - text="Floorplan showing relationship between pins and chains" + text="Floorplan showing relationship \n between pins and chains" ) app.mainloop() @@ -131,5 +181,5 @@ def pinsToChains(chainListDict,pincount,chainMembers): chain_positions=[pin[key] for key in ["ctrl_bit","out_bit","in_bit"] if pin[key]>=0] if any(chain_positions): chainMembers[pinnumber]=pin - pinsToChains(chainListDict,len(pinList),chainMembers) + pinsToChains(chainListDict,pinListJSON,chainMembers) diff --git a/lib_jtag_core/test/imports/epCoreJTAG.cxx b/lib_jtag_core/test/imports/epCoreJTAG.cxx index 623e213..a53719a 100644 --- a/lib_jtag_core/test/imports/epCoreJTAG.cxx +++ b/lib_jtag_core/test/imports/epCoreJTAG.cxx @@ -76,7 +76,7 @@ extern std::vector epBSDLPinSequence(SWIGHERE_CONTEXT oContext, char * *pBytesPerElement = sizeof(pin_ctrl); } if(oContext==(SWIGHERE_CONTEXT)&garbageCollector) { - const int sortPins=1; + const int sortPins=0; jtag_bsdl * details = jtag_bsdl_load_file(logger,MSG_DEBUG, sortPins, pathToBSDL); if ( details != NULL ) { int number_of_pins = details->number_of_pins; @@ -102,7 +102,7 @@ extern std::vector epBSDLChainSequence(SWIGHERE_CONTEXT oContext, ch *pBytesPerElement = sizeof(jtag_chain); } if(oContext==(SWIGHERE_CONTEXT)&garbageCollector) { - const int sortPins=1; + const int sortPins=0; jtag_bsdl * details = jtag_bsdl_load_file(logger,MSG_DEBUG, sortPins, pathToBSDL); if ( details != NULL ) { int number_of_chains = details->number_of_chainbits; From 3fa9fd9ca069a2972b7e24450878549d9058003b Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 20:22:53 -0230 Subject: [PATCH 19/24] Preparing for pull request --- .github/workflows/InterfaceSWIG.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/InterfaceSWIG.yml b/.github/workflows/InterfaceSWIG.yml index 3613317..884e720 100644 --- a/.github/workflows/InterfaceSWIG.yml +++ b/.github/workflows/InterfaceSWIG.yml @@ -2,10 +2,6 @@ name: SWIG and CMake on: workflow_dispatch -defaults: - run: - working-directory: ./lib_jtag_core - jobs: build: @@ -14,10 +10,9 @@ jobs: - uses: actions/checkout@v1 - name: install swig run: sudo apt install swig - - name: build using CMakw + - name: build using CMake run: | mkdir -p cmake cd cmake - cmake .. . + cmake ../libjtag_core . cmake --build . - From 6db5e25c42bf412bc4fa5ee6043574df0c62496a Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 20:26:38 -0230 Subject: [PATCH 20/24] cmake syntax --- .github/workflows/InterfaceSWIG.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/InterfaceSWIG.yml b/.github/workflows/InterfaceSWIG.yml index 884e720..616c141 100644 --- a/.github/workflows/InterfaceSWIG.yml +++ b/.github/workflows/InterfaceSWIG.yml @@ -14,5 +14,5 @@ jobs: run: | mkdir -p cmake cd cmake - cmake ../libjtag_core . + cmake -S ../libjtag_core -B . cmake --build . From ea8bbb039d94c78e67ed7987cf4610216cfa650a Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 20:27:25 -0230 Subject: [PATCH 21/24] yml syntax --- .github/workflows/ccpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 89e7d66..7c444f4 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -3,7 +3,7 @@ name: C/C++ CI on: push: paths-ignore: - - ".github/workflows" + - .github/workflows defaults: run: From 3ee016766e76f5d44e68c7c032127559baaff5d3 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Fri, 10 Jun 2022 20:29:59 -0230 Subject: [PATCH 22/24] corrected source dir name --- .github/workflows/InterfaceSWIG.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/InterfaceSWIG.yml b/.github/workflows/InterfaceSWIG.yml index 616c141..c31649e 100644 --- a/.github/workflows/InterfaceSWIG.yml +++ b/.github/workflows/InterfaceSWIG.yml @@ -14,5 +14,5 @@ jobs: run: | mkdir -p cmake cd cmake - cmake -S ../libjtag_core -B . + cmake -S ../lib_jtag_core -B . cmake --build . From 2eeb03a55a82dc46f1e2764b3825136e44ccb3db Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Mon, 13 Jun 2022 15:12:27 -0230 Subject: [PATCH 23/24] Update ccpp.yml quoted paths-ignore for *.yml --- .github/workflows/ccpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 7c444f4..85885b9 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -2,8 +2,8 @@ name: C/C++ CI on: push: - paths-ignore: - - .github/workflows + paths-ignore: + - '.github/workflows/*.yml' defaults: run: From 8b967733f9853d9d0755a2f7b0d89bef913ed489 Mon Sep 17 00:00:00 2001 From: nOw Innovation Inc <57865296+nowinnovation@users.noreply.github.com> Date: Mon, 13 Jun 2022 15:18:54 -0230 Subject: [PATCH 24/24] Enable manual workflow --- .github/workflows/ccpp.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 85885b9..fb1a879 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -4,6 +4,7 @@ on: push: paths-ignore: - '.github/workflows/*.yml' + workflow_dispatch: defaults: run: