From 471fbb6a819ccd08d8e45c375d27cd7996988b07 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Wed, 18 Aug 2021 15:38:24 +0200 Subject: [PATCH] jedParser: add xilinx compatibility --- src/jedParser.cpp | 148 +++++++++++++++++++++++++++++++--------------- src/jedParser.hpp | 9 +++ 2 files changed, 110 insertions(+), 47 deletions(-) diff --git a/src/jedParser.cpp b/src/jedParser.cpp index d44fc0a..c2e0d8e 100644 --- a/src/jedParser.cpp +++ b/src/jedParser.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -32,8 +33,11 @@ using namespace std; JedParser::JedParser(string filename, bool verbose): ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose), - _fuse_count(0), _pin_count(0), _featuresRow(0), _feabits(0), _checksum(0), - _userCode(0), _security_settings(0), _default_fuse_state(0) + _fuse_count(0), _pin_count(0), _max_vect_test(0), + _featuresRow(0), _feabits(0), _has_feabits(false), _checksum(0), + _compute_checksum(0), + _userCode(0), _security_settings(0), _default_fuse_state(0), + _default_test_condition(0), _arch_code(0), _pinout_code(0) { } @@ -91,6 +95,29 @@ void JedParser::buildDataArray(const string &content, struct jed_data &jed) data |= val << ii; } tmp_buff += data; + _compute_checksum += data; + } + jed.data.push_back(std::move(tmp_buff)); + jed.len += data_len; +} + +/* convert one serie ASCII 1/0 to a vector of + * unsigned char + * string must be up to 8 bits + */ +void JedParser::buildDataArray(const vector &content, + struct jed_data &jed) +{ + size_t data_len = 0; + string tmp_buff; + for (size_t i = 0; i < content.size(); i++) { + uint8_t data = 0; + data_len += content[i].size(); + for (size_t ii = 0; ii < content[i].size(); ii++) { + uint8_t val = (content[i][ii] == '1'?1:0); + data |= val << ii; + } + tmp_buff += data; } jed.data.push_back(std::move(tmp_buff)); jed.len += data_len; @@ -98,48 +125,57 @@ void JedParser::buildDataArray(const string &content, struct jed_data &jed) void JedParser::displayHeader() { - printf("feabits :\n"); - printf("%04x <-> %d\n", _feabits, _feabits); - /* 15-14: always 0 */ - printf("\tBoot Mode : "); - switch ((_feabits>>11)&0x07) { - case 0: - printf("Single Boot from Configuration Flash\n"); - break; - case 1: - printf("Dual Boot from Configuration Flash then External if there is a failure\n"); - break; - case 3: - printf("Single Boot from External Flash\n"); - break; - default: - printf("Error\n"); - } + /* only lattice jed */ + if (_has_feabits) { + printf("feabits :\n"); + printf("%04x <-> %d\n", _feabits, _feabits); + /* 15-14: always 0 */ + printf("\tBoot Mode : "); + switch ((_feabits>>11)&0x07) { + case 0: + printf("Single Boot from Configuration Flash\n"); + break; + case 1: + printf("Dual Boot from Configuration Flash then External if there is a failure\n"); + break; + case 3: + printf("Single Boot from External Flash\n"); + break; + default: + printf("Error\n"); + } - printf("\tMaster Mode SPI : %s\n", - (((_feabits>>11)&0x01)?"enable":"disable")); - printf("\tI2c port : %s\n", - (((_feabits>>10)&0x01)?"disable":"enable")); - printf("\tSlave SPI port : %s\n", - (((_feabits>>9)&0x01)?"disable":"enable")); - printf("\tJTAG port : %s\n", - (((_feabits>>8)&0x01)?"disable":"enable")); - printf("\tDONE : %s\n", - (((_feabits>>7)&0x01)?"enable":"disable")); - printf("\tINITN : %s\n", - (((_feabits>>6)&0x01)?"enable":"disable")); - printf("\tPROGRAMN : %s\n", - (((_feabits>>5)&0x01)?"disable":"enable")); - printf("\tMy_ASSP : %s\n", - (((_feabits>>4)&0x01)?"enable":"disable")); - /* 3-0: always 0 */ + printf("\tMaster Mode SPI : %s\n", + (((_feabits>>11)&0x01)?"enable":"disable")); + printf("\tI2c port : %s\n", + (((_feabits>>10)&0x01)?"disable":"enable")); + printf("\tSlave SPI port : %s\n", + (((_feabits>>9)&0x01)?"disable":"enable")); + printf("\tJTAG port : %s\n", + (((_feabits>>8)&0x01)?"disable":"enable")); + printf("\tDONE : %s\n", + (((_feabits>>7)&0x01)?"enable":"disable")); + printf("\tINITN : %s\n", + (((_feabits>>6)&0x01)?"enable":"disable")); + printf("\tPROGRAMN : %s\n", + (((_feabits>>5)&0x01)?"disable":"enable")); + printf("\tMy_ASSP : %s\n", + (((_feabits>>4)&0x01)?"enable":"disable")); + /* 3-0: always 0 */ + } printf("Pin Count : %d\n", _pin_count); printf("Fuse Count : %d\n", _fuse_count); for (size_t i = 0; i < _data_list.size(); i++) { - printf("area[%zd] %d %d ", i, _data_list[i].offset, _data_list[i].len); - printf("%s\n", _data_list[i].associatedPrevNote.c_str()); + printf("area[%zd] %4d %4d ", i, _data_list[i].offset, _data_list[i].len); + printf("%ld ", _data_list[i].data.size()); + for (size_t ii = 0; ii < _data_list[i].data.size(); ii++) + for (size_t iii = 0; iii < _data_list[i].data[ii].size(); iii++) + printf("%02x", (uint8_t)_data_list[i].data[ii][iii]); + printf(" %s\n", _data_list[i].associatedPrevNote.c_str()); + if (_data_list[i].offset == 2656) + break; } } @@ -182,8 +218,20 @@ void JedParser::parseLField(const vector &content) std::istringstream iss(content[0]); vector myList((std::istream_iterator(iss)), std::istream_iterator()); - myList[1].pop_back(); - buildDataArray(myList[1], d); + + myList.erase(myList.begin()); + + /* merge all to compute checksum by 8bits */ + std::stringstream imploded; + std::copy(myList.begin(), myList.end(), + std::ostream_iterator(imploded, "")); + string t = imploded.str(); + + for (size_t i = 0; i < t.size(); i+=8) + _compute_checksum += reverseByte(std::stoi(t.substr(i, 8), + nullptr, 2)); + + buildDataArray(myList, d); } _data_list.push_back(std::move(d)); } @@ -246,6 +294,9 @@ int JedParser::parse() case 'P': // pin count _pin_count = count; break; + case 'V': // pin count + _max_vect_test = count; + break; default: cerr << "Error for 'Q' unknown qualifier " << lines[0] << endl; return EXIT_FAILURE; @@ -257,6 +308,10 @@ int JedParser::parse() case 'F': _default_fuse_state = lines[0][1] - '0'; break; + case 'J': + sscanf(lines[0].c_str() + 1, "%d", &_arch_code); + sscanf(lines[0].c_str() + 3, "%d", &_pinout_code); + break; case 'C': sscanf(lines[0].c_str() + 1, "%hx", &_checksum); break; @@ -266,6 +321,7 @@ int JedParser::parse() break; case 'E': parseEField(lines); + _has_feabits = true; break; case 'L': // fuse offset parseLField(lines); @@ -284,6 +340,9 @@ int JedParser::parse() _userCode = ((_userCode << 1) | (lines[0][ii] - '0')); } break; + case 'X': // default test condition + sscanf(lines[0].c_str() + 1, "%d", &_default_test_condition); + break; default: printf("inconnu\n"); cout << lines[0]<< endl; @@ -292,18 +351,13 @@ int JedParser::parse() } while (lines[0][0] != 0x03); int size = 0; - uint16_t checksum = 0; for (size_t area = 0; area < _data_list.size(); area++) { size += _data_list[area].len; - for (size_t line = 0; line < _data_list[area].data.size(); line++) { - for (size_t col = 0; col < _data_list[area].data[line].size(); col++) - checksum += (uint8_t)_data_list[area].data[line][col]; - } } if (_verbose) - printf("theorical checksum %x -> %x\n", _checksum, checksum); - if (_checksum != checksum) { + printf("theorical checksum %x -> %x\n", _checksum, _compute_checksum); + if (_checksum != _compute_checksum) { printError("Error: wrong checksum"); return EXIT_FAILURE; } diff --git a/src/jedParser.hpp b/src/jedParser.hpp index d556c8d..2bf725c 100644 --- a/src/jedParser.hpp +++ b/src/jedParser.hpp @@ -31,6 +31,7 @@ class JedParser: public ConfigBitstreamParser { size_t nb_section() { return _data_list.size();} size_t offset_for_section(int id) {return _data_list[id].offset;} + int len_for_section(int id) {return _data_list[id].len;} std::vector data_for_section(int id) { return _data_list[id].data; } @@ -42,19 +43,27 @@ class JedParser: public ConfigBitstreamParser { std::string readline(); std::vectorreadJEDLine(); void buildDataArray(const std::string &content, struct jed_data &jed); + void buildDataArray(const std::vector &content, + struct jed_data &jed); void parseEField(const std::vector &content); void parseLField(const std::vector &content); std::vector _data_list; int _fuse_count; int _pin_count; + int _max_vect_test; uint64_t _featuresRow; uint16_t _feabits; + bool _has_feabits; uint16_t _checksum; + uint16_t _compute_checksum; uint32_t _userCode; uint8_t _security_settings; uint8_t _default_fuse_state; std::istringstream _ss; + int _default_test_condition; + int _arch_code; + int _pinout_code; }; #endif // JEDPARSER_HPP_