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 (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<std::string, std::map<uint32_t, device_model>>::iterator vnd_list;
device_model *fpga;
std::map<uint32_t, device_model>::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);

View File

@ -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<int> get_devices_list() {return _devices_list;}
std::vector<found_device> 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<int32_t> _devices_list; /*!< ordered list of devices idcode */
std::vector<int16_t> _irlength_list; /*!< ordered list of irlength */
std::vector<found_device> _f_device_list;
};
#endif

View File

@ -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<Jtag::found_device> 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();

View File

@ -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 <uint32_t, fpga_model> fpga_list = {
static std::map <uint32_t, device_model> fpga_list = {
/**************************************************************************/
/* Anlogic */
/**************************************************************************/
@ -236,7 +236,7 @@ static std::map <uint32_t, fpga_model> fpga_list = {
};
/* 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 */
/**************************************************************************/
@ -473,10 +473,10 @@ typedef struct {
int irlength;
} misc_device;
static std::map <uint32_t, misc_device> misc_dev_list = {
{0x4ba00477, {"ARM cortex A9", 4}},
{0x5ba00477, {"ARM cortex A53", 4}},
{0xfffffffe, {"ZynqMP dummy device", 12}},
static std::map <uint32_t, device_model> misc_dev_list = {
{0x4ba00477, {"ARM", "cortex", "A9", 4}},
{0x5ba00477, {"ARM", "cortex", "A53", 4}},
{0xfffffffe, {"xilinx", "ZynqMP", "dummy device", 12}},
};
/* list of JTAG manufacturer ID */

View File

@ -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;