adapt code to the new list, simplify search

This commit is contained in:
Gwenhael Goavec-Merou 2023-08-05 08:39:07 +02:00
parent 91ef2f18a0
commit 33b393cbc8
5 changed files with 101 additions and 65 deletions

View File

@ -192,15 +192,7 @@ int Jtag::detectChain(int max_dev)
* if IDCODE has no match: try the same with version unmasked * if IDCODE has no match: try the same with version unmasked
*/ */
if (tmp != 0 && tmp != 0xffffffff) { if (tmp != 0 && tmp != 0xffffffff) {
bool found = false; bool found = search_and_insert_device_with_idcode(tmp);
/* 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);
if (!found) { if (!found) {
uint16_t mfg = IDCODE2MANUFACTURERID(tmp); uint16_t mfg = IDCODE2MANUFACTURERID(tmp);
uint8_t part = IDCODE2PART(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) bool Jtag::search_and_insert_device_with_idcode(uint32_t idcode)
{ {
int irlength = -1; std::map<std::string, std::map<uint32_t, device_model>>::iterator vnd_list;
auto dev = fpga_list.find(idcode); device_model *fpga;
if (dev != fpga_list.end()) std::map<uint32_t, device_model>::iterator fpga2;
irlength = dev->second.irlength; std::string manufacturer;
if (irlength == -1) { bool found = false;
auto misc = misc_dev_list.find(idcode);
if (misc != misc_dev_list.end())
irlength = misc->second.irlength;
}
if (irlength == -1)
return 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); _devices_list.insert(_devices_list.begin(), device_id);
_irlength_list.insert(_irlength_list.begin(), irlength); _irlength_list.insert(_irlength_list.begin(), irlength);

View File

@ -13,6 +13,7 @@
#include "board.hpp" #include "board.hpp"
#include "cable.hpp" #include "cable.hpp"
#include "jtagInterface.hpp" #include "jtagInterface.hpp"
#include "part.hpp"
class Jtag { class Jtag {
public: public:
@ -28,6 +29,13 @@ class Jtag {
int setClkFreq(uint32_t clkHZ) { return _jtag->setClkFreq(clkHZ);} int setClkFreq(uint32_t clkHZ) { return _jtag->setClkFreq(clkHZ);}
uint32_t getClkFreq() { return _jtag->getClkFreq();} 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 * \brief scan JTAG chain to obtain IDCODE. Fill
* a vector with all idcode and another * a vector with all idcode and another
@ -41,6 +49,7 @@ class Jtag {
* \return list of devices * \return list of devices
*/ */
std::vector<int> get_devices_list() {return _devices_list;} std::vector<int> get_devices_list() {return _devices_list;}
std::vector<found_device> get_devices_list2() {return _f_device_list;}
/*! /*!
* \brief return current selected device idcode * \brief return current selected device idcode
@ -60,7 +69,16 @@ class Jtag {
* \param[in] irlength: device irlength * \param[in] irlength: device irlength
* \return false if fails * \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 * \brief return a pointer to the transport subclass
@ -109,6 +127,7 @@ class Jtag {
JtagInterface *_jtag; JtagInterface *_jtag;
private: private:
/*! /*!
* \brief search in fpga_list and misc_dev_list for a device with idcode * \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 */ int device_index; /*!< index for targeted FPGA */
std::vector<int32_t> _devices_list; /*!< ordered list of devices idcode */ std::vector<int32_t> _devices_list; /*!< ordered list of devices idcode */
std::vector<int16_t> _irlength_list; /*!< ordered list of irlength */ std::vector<int16_t> _irlength_list; /*!< ordered list of irlength */
std::vector<found_device> _f_device_list;
}; };
#endif #endif

View File

@ -464,22 +464,14 @@ int main(int argc, char **argv)
* display full chain with details * display full chain with details
*/ */
if (args.verbose > 0 || args.detect) { if (args.verbose > 0 || args.detect) {
for (int i = 0; i < found; i++) { std::vector<Jtag::found_device> fd = jtag->get_devices_list2();
int t = listDev[i]; for (auto f: fd) {
printf("index %d:\n", i); printf("\tidcode 0x%x\n\tmanufacturer %s\n\tfamily %s\n\tmodel %s\n",
if (fpga_list.find(t) != fpga_list.end()) { f.idcode,
printf("\tidcode 0x%x\n\tmanufacturer %s\n\tfamily %s\n\tmodel %s\n", f.model->manufacturer.c_str(),
t, f.model->family.c_str(),
fpga_list[t].manufacturer.c_str(), f.model->model.c_str());
fpga_list[t].family.c_str(), printf("\tirlength %d\n", f.irlength);
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);
}
} }
if (args.detect == true) { if (args.detect == true) {
delete jtag; delete jtag;
@ -1009,13 +1001,25 @@ void displaySupported(const struct arguments &args)
} }
if (args.list_boards) { 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) { for (auto &&vendor: fpga_vnd_list) {
stringstream t; stringstream t;
t << setw(12) << left << "IDCode" << setw(14) << "manufacturer"; t << setw(12) << left << "IDCode" << setw(14) << "manufacturer";
t << setw(16) << "family" << setw(20) << "model"; t << setw(16) << "family" << setw(20) << "model";
printSuccess(t.str()); printSuccess(t.str());
for (auto &&part: vendor.second) { for (auto &&part: vendor.second) {
fpga_model fpga = part.second; device_model fpga = part.second;
stringstream ss, idCode; stringstream ss, idCode;
idCode << "0x" << hex << setw(8) << setfill('0') << part.first; idCode << "0x" << hex << setw(8) << setfill('0') << part.first;
ss << setw(12) << left << idCode.str(); 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) { if (args.scan_usb) {
libusb_ll usb(0, 0); libusb_ll usb(0, 0);
usb.scan(); usb.scan();

View File

@ -15,10 +15,10 @@ typedef struct {
std::string family; std::string family;
std::string model; std::string model;
int irlength; int irlength;
} fpga_model; } device_model;
/* Highest nibble (version) must always be set to 0 */ /* Highest nibble (version) must always be set to 0 */
static std::map <uint32_t, fpga_model> fpga_list = { static std::map <uint32_t, device_model> fpga_list = {
/**************************************************************************/ /**************************************************************************/
/* Anlogic */ /* Anlogic */
/**************************************************************************/ /**************************************************************************/
@ -236,7 +236,7 @@ static std::map <uint32_t, fpga_model> fpga_list = {
}; };
/* Highest nibble (version) must always be set to 0 */ /* Highest nibble (version) must always be set to 0 */
static std::map <std::string, std::map <uint32_t, fpga_model>> fpga_vnd_list = { static std::map <std::string, std::map <uint32_t, device_model>> fpga_vnd_list = {
/**************************************************************************/ /**************************************************************************/
/* Altera */ /* Altera */
/**************************************************************************/ /**************************************************************************/
@ -473,10 +473,10 @@ typedef struct {
int irlength; int irlength;
} misc_device; } misc_device;
static std::map <uint32_t, misc_device> misc_dev_list = { static std::map <uint32_t, device_model> misc_dev_list = {
{0x4ba00477, {"ARM cortex A9", 4}}, {0x4ba00477, {"ARM", "cortex", "A9", 4}},
{0x5ba00477, {"ARM cortex A53", 4}}, {0x5ba00477, {"ARM", "cortex", "A53", 4}},
{0xfffffffe, {"ZynqMP dummy device", 12}}, {0xfffffffe, {"xilinx", "ZynqMP", "dummy device", 12}},
}; };
/* list of JTAG manufacturer ID */ /* list of JTAG manufacturer ID */

View File

@ -308,7 +308,7 @@ bool Xilinx::zynqmp_init(const std::string &family)
return false; return false;
} }
_jtag->insert_first(0xdeadbeef, 6); _jtag->insert_first(0xdeadbeef, true, 6, NULL);
_jtag->device_select(1); _jtag->device_select(1);
_irlen = 6; _irlen = 6;