From 33b393cbc83c78a65a786d34a639072cfa85cd44 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sat, 5 Aug 2023 08:39:07 +0200 Subject: [PATCH] adapt code to the new list, simplify search --- src/jtag.cpp | 73 +++++++++++++++++++++++++++++++++++--------------- src/jtag.hpp | 22 ++++++++++++++- src/main.cpp | 55 +++++++++++++++---------------------- src/part.hpp | 14 +++++----- src/xilinx.cpp | 2 +- 5 files changed, 101 insertions(+), 65 deletions(-) diff --git a/src/jtag.cpp b/src/jtag.cpp index ea359af..82c665f 100644 --- a/src/jtag.cpp +++ b/src/jtag.cpp @@ -192,15 +192,7 @@ int Jtag::detectChain(int max_dev) * if IDCODE has no match: try the same with version unmasked */ if (tmp != 0 && tmp != 0xffffffff) { - bool found = false; - /* ckeck highest nibble to prevent confusion between Cologne Chip - * GateMate and Efinix Trion T4/T8 devices - */ - if (tmp != 0x20000001) - found = search_and_insert_device_with_idcode(tmp & 0x0fffffff); - if (!found) /* if masked not found -> search for full */ - found = search_and_insert_device_with_idcode(tmp); - + bool found = search_and_insert_device_with_idcode(tmp); if (!found) { uint16_t mfg = IDCODE2MANUFACTURERID(tmp); uint8_t part = IDCODE2PART(tmp); @@ -223,23 +215,60 @@ int Jtag::detectChain(int max_dev) bool Jtag::search_and_insert_device_with_idcode(uint32_t idcode) { - int irlength = -1; - auto dev = fpga_list.find(idcode); - if (dev != fpga_list.end()) - irlength = dev->second.irlength; - if (irlength == -1) { - auto misc = misc_dev_list.find(idcode); - if (misc != misc_dev_list.end()) - irlength = misc->second.irlength; - } - if (irlength == -1) - return false; + std::map>::iterator vnd_list; + device_model *fpga; + std::map::iterator fpga2; + std::string manufacturer; + bool found = false; - return insert_first(idcode, irlength); + switch (idcode) { + case 0x20000001: // colognechip + manufacturer = "colognechip"; + break; + case 0x01: + manufacturer = "efinix"; + break; + default: + manufacturer = list_manufacturer[IDCODE2MANUFACTURERID(idcode)]; + } + + /* search entry at vendor level */ + vnd_list = fpga_vnd_list.find(manufacturer); + if (vnd_list != fpga_vnd_list.end()) { + /* try to find direct idcode (no mask) */ + fpga2 = vnd_list->second.find(idcode); + /* direct not found -> search for idcode with mask */ + if (fpga2 == fpga_vnd_list[manufacturer].end()) { + idcode = idcode & 0x0FFFFFFF; + fpga2 = vnd_list->second.find(idcode); + if (fpga2 != fpga_vnd_list[manufacturer].end()) + found = true; + } else { + found = true; + } + } + + /* device found: insert has a potential target */ + if (found) { + fpga = &fpga2->second; + insert_first(idcode, false, fpga->irlength, fpga); + } else { // when not found -> try for a misc device */ + auto misc = misc_dev_list.find(idcode); + if (misc != misc_dev_list.end()) { + insert_first(idcode, true, misc->second.irlength, &misc->second); + found = true; + } + } + if (!found) { + printf("Error: try to insert unknown device\n"); + } + return found; } -bool Jtag::insert_first(uint32_t device_id, uint16_t irlength) +bool Jtag::insert_first(uint32_t device_id, bool is_misc, uint16_t irlength, device_model *device) { + found_device dev = {device_id, irlength, is_misc, device}; + _f_device_list.insert(_f_device_list.begin(), dev); _devices_list.insert(_devices_list.begin(), device_id); _irlength_list.insert(_irlength_list.begin(), irlength); diff --git a/src/jtag.hpp b/src/jtag.hpp index e2ef671..424a3a9 100644 --- a/src/jtag.hpp +++ b/src/jtag.hpp @@ -13,6 +13,7 @@ #include "board.hpp" #include "cable.hpp" #include "jtagInterface.hpp" +#include "part.hpp" class Jtag { public: @@ -28,6 +29,13 @@ class Jtag { int setClkFreq(uint32_t clkHZ) { return _jtag->setClkFreq(clkHZ);} uint32_t getClkFreq() { return _jtag->getClkFreq();} + typedef struct { + uint32_t idcode; + uint16_t irlength; + bool is_misc; + device_model *model; + } found_device; + /*! * \brief scan JTAG chain to obtain IDCODE. Fill * a vector with all idcode and another @@ -41,6 +49,7 @@ class Jtag { * \return list of devices */ std::vector get_devices_list() {return _devices_list;} + std::vector get_devices_list2() {return _f_device_list;} /*! * \brief return current selected device idcode @@ -60,7 +69,16 @@ class Jtag { * \param[in] irlength: device irlength * \return false if fails */ - bool insert_first(uint32_t device_id, uint16_t irlength); + //bool insert_first(uint32_t device_id, uint16_t irlength); + bool insert_first(uint32_t idcode, bool is_misc, uint16_t irlength, device_model *device); + + int get_nb_targets() { + int nb = 0; + for (auto t: _f_device_list) + if (!t.is_misc) + nb++; + return nb; + } /*! * \brief return a pointer to the transport subclass @@ -109,6 +127,7 @@ class Jtag { JtagInterface *_jtag; + private: /*! * \brief search in fpga_list and misc_dev_list for a device with idcode @@ -128,5 +147,6 @@ class Jtag { int device_index; /*!< index for targeted FPGA */ std::vector _devices_list; /*!< ordered list of devices idcode */ std::vector _irlength_list; /*!< ordered list of irlength */ + std::vector _f_device_list; }; #endif diff --git a/src/main.cpp b/src/main.cpp index 9c55030..716fb8d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -464,22 +464,14 @@ int main(int argc, char **argv) * display full chain with details */ if (args.verbose > 0 || args.detect) { - for (int i = 0; i < found; i++) { - int t = listDev[i]; - printf("index %d:\n", i); - if (fpga_list.find(t) != fpga_list.end()) { - printf("\tidcode 0x%x\n\tmanufacturer %s\n\tfamily %s\n\tmodel %s\n", - t, - fpga_list[t].manufacturer.c_str(), - fpga_list[t].family.c_str(), - fpga_list[t].model.c_str()); - printf("\tirlength %d\n", fpga_list[t].irlength); - } else if (misc_dev_list.find(t) != misc_dev_list.end()) { - printf("\tidcode 0x%x\n\ttype %s\n\tirlength %d\n", - t, - misc_dev_list[t].name.c_str(), - misc_dev_list[t].irlength); - } + std::vector fd = jtag->get_devices_list2(); + for (auto f: fd) { + printf("\tidcode 0x%x\n\tmanufacturer %s\n\tfamily %s\n\tmodel %s\n", + f.idcode, + f.model->manufacturer.c_str(), + f.model->family.c_str(), + f.model->model.c_str()); + printf("\tirlength %d\n", f.irlength); } if (args.detect == true) { delete jtag; @@ -1009,13 +1001,25 @@ void displaySupported(const struct arguments &args) } if (args.list_boards) { + stringstream t; + t << setw(25) << left << "board name" << "cable_name"; + printSuccess(t.str()); + for (auto b = board_list.begin(); b != board_list.end(); b++) { + stringstream ss; + target_board_t c = (*b).second; + ss << setw(25) << left << (*b).first << c.cable_name; + printInfo(ss.str()); + } + } + + if (args.list_fpga) { for (auto &&vendor: fpga_vnd_list) { stringstream t; t << setw(12) << left << "IDCode" << setw(14) << "manufacturer"; t << setw(16) << "family" << setw(20) << "model"; printSuccess(t.str()); for (auto &&part: vendor.second) { - fpga_model fpga = part.second; + device_model fpga = part.second; stringstream ss, idCode; idCode << "0x" << hex << setw(8) << setfill('0') << part.first; ss << setw(12) << left << idCode.str(); @@ -1027,23 +1031,6 @@ void displaySupported(const struct arguments &args) } } - if (args.list_fpga) { - stringstream t; - t << setw(12) << left << "IDCode" << setw(14) << "manufacturer"; - t << setw(16) << "family" << setw(20) << "model"; - printSuccess(t.str()); - for (auto b = fpga_list.begin(); b != fpga_list.end(); b++) { - fpga_model fpga = (*b).second; - stringstream ss, idCode; - idCode << "0x" << hex << setw(8) << setfill('0') << (*b).first; - ss << setw(12) << left << idCode.str(); - ss << setw(14) << fpga.manufacturer << setw(16) << fpga.family; - ss << setw(20) << fpga.model; - printInfo(ss.str()); - } - cout << endl; - } - if (args.scan_usb) { libusb_ll usb(0, 0); usb.scan(); diff --git a/src/part.hpp b/src/part.hpp index 70cfea8..d99342a 100644 --- a/src/part.hpp +++ b/src/part.hpp @@ -15,10 +15,10 @@ typedef struct { std::string family; std::string model; int irlength; -} fpga_model; +} device_model; /* Highest nibble (version) must always be set to 0 */ -static std::map fpga_list = { +static std::map fpga_list = { /**************************************************************************/ /* Anlogic */ /**************************************************************************/ @@ -236,7 +236,7 @@ static std::map fpga_list = { }; /* Highest nibble (version) must always be set to 0 */ -static std::map > fpga_vnd_list = { +static std::map > fpga_vnd_list = { /**************************************************************************/ /* Altera */ /**************************************************************************/ @@ -473,10 +473,10 @@ typedef struct { int irlength; } misc_device; -static std::map misc_dev_list = { - {0x4ba00477, {"ARM cortex A9", 4}}, - {0x5ba00477, {"ARM cortex A53", 4}}, - {0xfffffffe, {"ZynqMP dummy device", 12}}, +static std::map misc_dev_list = { + {0x4ba00477, {"ARM", "cortex", "A9", 4}}, + {0x5ba00477, {"ARM", "cortex", "A53", 4}}, + {0xfffffffe, {"xilinx", "ZynqMP", "dummy device", 12}}, }; /* list of JTAG manufacturer ID */ diff --git a/src/xilinx.cpp b/src/xilinx.cpp index 7785682..bcd6f4b 100644 --- a/src/xilinx.cpp +++ b/src/xilinx.cpp @@ -308,7 +308,7 @@ bool Xilinx::zynqmp_init(const std::string &family) return false; } - _jtag->insert_first(0xdeadbeef, 6); + _jtag->insert_first(0xdeadbeef, true, 6, NULL); _jtag->device_select(1); _irlen = 6;