Merge branch 'trabucayre:master' into master

This commit is contained in:
ZhiYuanNJ 2024-02-22 10:52:33 +08:00 committed by GitHub
commit 7efdad6098
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 116 additions and 29 deletions

View File

@ -131,10 +131,10 @@ static std::map <std::string, target_board_t> board_list = {
JTAG_BOARD("colorlight-i5", "", "cmsisdap", 0, 0, CABLE_DEFAULT), JTAG_BOARD("colorlight-i5", "", "cmsisdap", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("colorlight-i9", "", "cmsisdap", 0, 0, CABLE_DEFAULT), JTAG_BOARD("colorlight-i9", "", "cmsisdap", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("colorlight-i9+", "xc7a50tfgg484", "", 0, 0, CABLE_DEFAULT), JTAG_BOARD("colorlight-i9+", "xc7a50tfgg484", "", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("crosslinknx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("crosslinknx_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
JTAG_BOARD("certusnx_versa_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("certusnx_versa_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
JTAG_BOARD("certuspronx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("certuspronx_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
JTAG_BOARD("certuspronx_versa_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("certuspronx_versa_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
JTAG_BOARD("cyc1000", "10cl025256", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("cyc1000", "10cl025256", "ft2232", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("c10lp-refkit", "10cl055484", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("c10lp-refkit", "10cl055484", "ft2232", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("de0", "", "usb-blaster",0, 0, CABLE_DEFAULT), JTAG_BOARD("de0", "", "usb-blaster",0, 0, CABLE_DEFAULT),
@ -160,7 +160,7 @@ static std::map <std::string, target_board_t> board_list = {
SPI_BOARD("gatemate_evb_spi", "colognechip", "gatemate_evb_spi", SPI_BOARD("gatemate_evb_spi", "colognechip", "gatemate_evb_spi",
DBUS4, DBUS5, CBUS0, DBUS3, DBUS0, DBUS1, DBUS2, 0, 0, CABLE_DEFAULT), DBUS4, DBUS5, CBUS0, DBUS3, DBUS0, DBUS1, DBUS2, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("genesys2", "xc7k325tffg900", "digilent_b", 0, 0, CABLE_DEFAULT), JTAG_BOARD("genesys2", "xc7k325tffg900", "digilent_b", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("gr740-mini", "", "ft4232hp_b", 0, 0, CABLE_DEFAULT), JTAG_BOARD("gr740-mini", "", "ft4232hp_b", 0, 0, CABLE_MHZ(1)),
JTAG_BOARD("hseda-xc6slx16", "xc6slx16ftg256", "", 0, 0, CABLE_DEFAULT), JTAG_BOARD("hseda-xc6slx16", "xc6slx16ftg256", "", 0, 0, CABLE_DEFAULT),
/* most ice40 boards uses the same pinout */ /* most ice40 boards uses the same pinout */
SPI_BOARD("ice40_generic", "lattice", "ft2232", SPI_BOARD("ice40_generic", "lattice", "ft2232",

View File

@ -326,7 +326,7 @@ int DFU::searchDFUDevices()
} }
} else if (_debug) { } else if (_debug) {
char mess[256]; char mess[256];
sprintf(mess,"Unable to open device: " snprintf(mess, 256, "Unable to open device: "
"%04x:%04x (bus %d, device %2d) Error: %s -> skip\n", "%04x:%04x (bus %d, device %2d) Error: %s -> skip\n",
desc.idVendor, desc.idProduct, desc.idVendor, desc.idProduct,
libusb_get_bus_number(usb_dev), libusb_get_bus_number(usb_dev),
@ -358,23 +358,35 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
/* configuration interface iteration */ /* configuration interface iteration */
for (int if_idx=0; if_idx < cfg->bNumInterfaces; if_idx++) { for (int if_idx=0; if_idx < cfg->bNumInterfaces; if_idx++) {
const struct libusb_interface *uif = &cfg->interface[if_idx]; const struct libusb_interface *uif = &cfg->interface[if_idx];
std::vector<struct dfu_dev> dfu_dev_tmp;
struct dfu_desc *dfu_desc;
bool dfu_found = false;
/* altsettings interation */ /* altsettings interation */
for (int intf_idx = 0; intf_idx < uif->num_altsetting; intf_idx++) { for (int intf_idx = 0; intf_idx < uif->num_altsetting; intf_idx++) {
const struct libusb_interface_descriptor *intf = &uif->altsetting[intf_idx]; const struct libusb_interface_descriptor *intf = &uif->altsetting[intf_idx];
uint8_t intfClass = intf->bInterfaceClass; uint8_t intfClass = intf->bInterfaceClass;
uint8_t intfSubClass = intf->bInterfaceSubClass; uint8_t intfSubClass = intf->bInterfaceSubClass;
if (_altsetting != -1 && _altsetting != intf_idx)
continue;
if (intfClass == 0xfe && intfSubClass == 0x01) { if (intfClass == 0xfe && intfSubClass == 0x01) {
struct dfu_dev my_dev; struct dfu_dev my_dev;
if (_verbose) if (_verbose)
printInfo("DFU found"); printInfo("DFU found");
/* dfu functional descriptor */ /* dfu functional descriptor */
/* not all DFU implementations provides a descriptor per altsettings
* so don't stop directly.
*/
if (parseDFUDescriptor(intf, reinterpret_cast<uint8_t *>(&my_dev.dfu_desc), if (parseDFUDescriptor(intf, reinterpret_cast<uint8_t *>(&my_dev.dfu_desc),
sizeof(my_dev.dfu_desc)) != 0) sizeof(my_dev.dfu_desc))) {
continue; // not compatible dfu_desc = &my_dev.dfu_desc;
dfu_found = true;
}
/* this altsetting is a DFU interface:
* - if user has selected one altsetting current is only stored if it match
* - otherwise all are stored
*/
if (_altsetting != -1 && _altsetting != intf_idx)
continue;
my_dev.vid = desc->idVendor; my_dev.vid = desc->idVendor;
my_dev.pid = desc->idProduct; my_dev.pid = desc->idProduct;
my_dev.altsettings = intf_idx; my_dev.altsettings = intf_idx;
@ -397,9 +409,22 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
int r = libusb_get_port_numbers(dev, my_dev.path, sizeof(my_dev.path)); int r = libusb_get_port_numbers(dev, my_dev.path, sizeof(my_dev.path));
my_dev.path[r] = '\0'; my_dev.path[r] = '\0';
dfu_dev.push_back(my_dev); dfu_dev_tmp.push_back(my_dev);
} }
} }
/* At least one altsetting has a DFU descriptor */
if (dfu_found) {
/* with tinyDFU only one (the first) altsetting contains a descriptor
* fill others with this information
*/
for (struct dfu_dev &d: dfu_dev_tmp) {
if (d.dfu_desc.bDescriptorType == 0)
memcpy(&d.dfu_desc, dfu_desc, sizeof(struct dfu_desc));
}
std::move(dfu_dev_tmp.begin(), dfu_dev_tmp.end(), std::back_inserter(dfu_dev));
}
} }
libusb_free_config_descriptor(cfg); libusb_free_config_descriptor(cfg);
@ -413,24 +438,29 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
* Since libusb has no support for those structure * Since libusb has no support for those structure
* fill a custom structure * fill a custom structure
*/ */
int DFU::parseDFUDescriptor(const struct libusb_interface_descriptor *intf, bool DFU::parseDFUDescriptor(const struct libusb_interface_descriptor *intf,
uint8_t *dfu_desc, int dfu_desc_size) uint8_t *dfu_desc, int dfu_desc_size)
{ {
const uint8_t *extra = intf->extra; const uint8_t *extra = intf->extra;
int extra_len = intf->extra_length; int extra_len = intf->extra_length;
/* not all altsettings for a DFU device have a DFU descriptor
* set to 0 to be able to detect a missing descriptor
*/
memset(dfu_desc, 0, 9);
if (extra_len < 9) if (extra_len < 9)
return -1; return false;
/* map memory to structure */ /* map memory to structure */
for (int j = 0; j + 1 < extra_len; j++) { for (int j = 0; j + 1 < extra_len; j++) {
if (extra[j+1] == 0x21) { if (extra[j+1] == 0x21) {
memcpy(dfu_desc, (const void *)&extra[j], dfu_desc_size); memcpy(dfu_desc, (const void *)&extra[j], dfu_desc_size);
break; return true;
} }
} }
return 0; return false;
} }
/* abstraction to send/receive to control */ /* abstraction to send/receive to control */

View File

@ -206,9 +206,9 @@ class DFU {
* \param[in] intf: interface descriptor with extra area * \param[in] intf: interface descriptor with extra area
* \param[out] dfu_desc: DFU descriptor * \param[out] dfu_desc: DFU descriptor
* \param[in] dfu_desc_size: DFU descriptor structure size * \param[in] dfu_desc_size: DFU descriptor structure size
* \return -1 if extra len is too small, 0 otherwise * \return false if extra len is too small, true otherwise
* */ * */
int parseDFUDescriptor(const struct libusb_interface_descriptor *intf, bool parseDFUDescriptor(const struct libusb_interface_descriptor *intf,
uint8_t *dfu_desc, int dfu_desc_size); uint8_t *dfu_desc, int dfu_desc_size);
/*! /*!
* \brief try to open device specified by vid and pid. If found * \brief try to open device specified by vid and pid. If found

View File

@ -878,7 +878,7 @@ bool FTDIpp_MPSSE::search_with_dev(const string &device)
usbdeviceparent, "busnum"), 10)); usbdeviceparent, "busnum"), 10));
_addr = static_cast<uint8_t>(udevstufftoint(udev_device_get_sysattr_value( _addr = static_cast<uint8_t>(udevstufftoint(udev_device_get_sysattr_value(
usbdeviceparent, "devnum"), 10)); usbdeviceparent, "devnum"), 10));
sprintf(_product, "%s", udev_device_get_sysattr_value(usbdeviceparent, "product")); snprintf(_product, 64, "%s", udev_device_get_sysattr_value(usbdeviceparent, "product"));
_vid = udevstufftoint( _vid = udevstufftoint(
udev_device_get_sysattr_value(usbdeviceparent, "idVendor"), 16); udev_device_get_sysattr_value(usbdeviceparent, "idVendor"), 16);
_pid = udevstufftoint(udev_device_get_sysattr_value( _pid = udevstufftoint(udev_device_get_sysattr_value(

View File

@ -883,8 +883,19 @@ void Gowin::sendClkUs(unsigned us)
bool Gowin::eraseSRAM() bool Gowin::eraseSRAM()
{ {
printInfo("Erase SRAM ", false); printInfo("Erase SRAM ", false);
uint32_t status = readStatusReg();
if (_verbose) if (_verbose)
displayReadReg("before erase sram", readStatusReg()); displayReadReg("before erase sram", status);
// If flash is invalid, send extra cmd 0x3F before SRAM erase
// This is required on GW5A-25
bool auto_boot_2nd_fail = (status & 0x8) >> 3;
if ((_idcode == 0x0001281B) && auto_boot_2nd_fail)
{
disableCfg();
send_command(0x3F);
send_command(NOOP);
}
if (!enableCfg()) { if (!enableCfg()) {
printError("FAIL"); printError("FAIL");

View File

@ -1080,7 +1080,8 @@ void Lattice::displayReadReg(uint64_t dev)
err = (dev >> 23)&0x07; err = (dev >> 23)&0x07;
} }
printf("\t"); printf("\tBSE Error Code\n");
printf("\t\t");
switch (err) { switch (err) {
case 0: case 0:
printf("No err\n"); printf("No err\n");
@ -1106,8 +1107,17 @@ void Lattice::displayReadReg(uint64_t dev)
case 7: case 7:
printf("SDM EOF\n"); printf("SDM EOF\n");
break; break;
case 8:
printf("Authentication ERR\n");
break;
case 9:
printf("Authentication Setup ERR\n");
break;
case 10:
printf("Bitstream Engine Timeout ERR\n");
break;
default: default:
printf("unknown %x\n", err); printf("unknown error: %x\n", err);
} }
if (_fpga_family == NEXUS_FAMILY) { if (_fpga_family == NEXUS_FAMILY) {
@ -1164,7 +1174,7 @@ void Lattice::displayReadReg(uint64_t dev)
printf("Bitstream Engine Timeout ERR\n"); printf("Bitstream Engine Timeout ERR\n");
break; break;
default: default:
printf("unknown %x\n", err); printf("unknown error: %x\n", err);
} }
if ((dev >> 38) & 0x01) printf("\tBypass Mode\n"); if ((dev >> 38) & 0x01) printf("\tBypass Mode\n");
if ((dev >> 39) & 0x01) printf("\tFlow Through Mode\n"); if ((dev >> 39) & 0x01) printf("\tFlow Through Mode\n");

View File

@ -68,7 +68,8 @@ int LatticeBitParser::parseHeader()
printError("Preamble key not found"); printError("Preamble key not found");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if ((uint8_t)_raw_data[pos-1] != 0xbd && (uint8_t)_raw_data[pos-1] != 0xbf) { //0xbe is the key for encrypted bitstreams in Nexus fpgas
if ((uint8_t)_raw_data[pos-1] != 0xbd && (uint8_t)_raw_data[pos-1] != 0xbf && (uint8_t)_raw_data[pos-1] != 0xbe) {
printError("Wrong preamble key"); printError("Wrong preamble key");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -98,7 +99,8 @@ int LatticeBitParser::parse()
/* check preamble */ /* check preamble */
uint32_t preamble = (*(uint32_t *)&_raw_data[_endHeader+1]); uint32_t preamble = (*(uint32_t *)&_raw_data[_endHeader+1]);
if ((preamble != 0xb3bdffff) && (preamble != 0xb3bfffff)) { //0xb3beffff is the preamble for encrypted bitstreams in Nexus fpgas
if ((preamble != 0xb3bdffff) && (preamble != 0xb3bfffff) && (preamble != 0xb3beffff)) {
printError("Error: missing preamble\n"); printError("Error: missing preamble\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -286,6 +286,20 @@ static std::map <uint32_t, flash_t> flash_list = {
.bp_len = 4, .bp_len = 4,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 5)}} .bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 5)}}
}, },
{0xc22016, {
/* https://www.macronix.com/Lists/Datasheet/Attachments/8933/MX25L3233F,%203V,%2032Mb,%20v1.7.pdf */
.manufacturer = "Macronix",
.model = "MX25L3233F",
.nr_sector = 256,
.sector_erase = true,
.subsector_erase = true,
.has_extended = false,
.tb_otp = true,
.tb_offset = (1 << 3),
.tb_register = CONFR,
.bp_len = 5,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 5)}}
},
{0xc22018, { {0xc22018, {
/* https://www.macronix.com/Lists/Datasheet/Attachments/8934/MX25L12833F,%203V,%20128Mb,%20v1.0.pdf */ /* https://www.macronix.com/Lists/Datasheet/Attachments/8934/MX25L12833F,%203V,%20128Mb,%20v1.0.pdf */
.manufacturer = "Macronix", .manufacturer = "Macronix",

View File

@ -99,7 +99,8 @@ int XVC_client::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
// buffer full -> write // buffer full -> write
if (_num_bits == _buffer_size * 8) { if (_num_bits == _buffer_size * 8) {
// write // write
ll_write(NULL); if(!ll_write(NULL))
throw std::runtime_error("xvc ll_write fails");
_num_bits = 0; _num_bits = 0;
} }
@ -147,7 +148,8 @@ int XVC_client::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
uint16_t idx = _num_bits - 1; uint16_t idx = _num_bits - 1;
_tms[(idx >> 3)] |= (1 << (idx & 0x07)); _tms[(idx >> 3)] |= (1 << (idx & 0x07));
} }
ll_write((rx) ? rx_ptr : NULL); // write if(!ll_write((rx) ? rx_ptr : NULL)) // write
throw std::runtime_error("xvc ll_write fails");
tx_ptr += tt; tx_ptr += tt;
if (rx) if (rx)
@ -184,7 +186,8 @@ int XVC_client::toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len)
if (len < _num_bits) if (len < _num_bits)
_num_bits = len; _num_bits = len;
len -= _num_bits; len -= _num_bits;
ll_write(NULL); if(!ll_write(NULL))
throw std::runtime_error("xvc ll_write fails");
} while (len > 0); } while (len > 0);
return clk_len; return clk_len;
@ -242,6 +245,23 @@ bool XVC_client::open_connection(const string &ip_addr)
return true; return true;
} }
static
int sendall(int sock, const void* raw, size_t cnt, int flags)
{
const char *buf = (const char*)raw;
size_t remaining = cnt;
while (remaining) {
ssize_t ret = send(sock, buf, remaining, flags);
if (ret==0) // should not happen on Linux for a TCP socket
throw std::logic_error("platform TCP send() returns zero?!?");
if (ret < 0)
return ret;
buf += ret;
remaining -= ret;
}
return cnt; // success
}
ssize_t XVC_client::xfer_pkt(const string &instr, ssize_t XVC_client::xfer_pkt(const string &instr,
const uint8_t *tx, uint32_t tx_size, const uint8_t *tx, uint32_t tx_size,
uint8_t *rx, uint32_t rx_size) uint8_t *rx, uint32_t rx_size)
@ -249,13 +269,13 @@ ssize_t XVC_client::xfer_pkt(const string &instr,
ssize_t len = tx_size; ssize_t len = tx_size;
/* 1. instruction */ /* 1. instruction */
if (send(_sock, instr.c_str(), instr.size(), 0) == -1) { if (sendall(_sock, instr.c_str(), instr.size(), 0) == -1) {
printError("Send instruction failed"); printError("Send instruction failed");
return -1; return -1;
} }
if (tx) { if (tx) {
if (send(_sock, tx, tx_size, 0) == -1) { if (sendall(_sock, tx, tx_size, 0) == -1) {
printError("Send error"); printError("Send error");
return -1; return -1;
} }