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-i9", "", "cmsisdap", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("colorlight-i9+", "xc7a50tfgg484", "", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("crosslinknx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("certusnx_versa_evn", "", "ft2232", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("certuspronx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("certuspronx_versa_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_MHZ(1)),
JTAG_BOARD("certuspronx_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
JTAG_BOARD("certuspronx_versa_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
JTAG_BOARD("cyc1000", "10cl025256", "ft2232", 0, 0, CABLE_DEFAULT),
JTAG_BOARD("c10lp-refkit", "10cl055484", "ft2232", 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",
DBUS4, DBUS5, CBUS0, DBUS3, DBUS0, DBUS1, DBUS2, 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),
/* most ice40 boards uses the same pinout */
SPI_BOARD("ice40_generic", "lattice", "ft2232",

View File

@ -326,7 +326,7 @@ int DFU::searchDFUDevices()
}
} else if (_debug) {
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",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(usb_dev),
@ -358,23 +358,35 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
/* configuration interface iteration */
for (int if_idx=0; if_idx < cfg->bNumInterfaces; 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 */
for (int intf_idx = 0; intf_idx < uif->num_altsetting; intf_idx++) {
const struct libusb_interface_descriptor *intf = &uif->altsetting[intf_idx];
uint8_t intfClass = intf->bInterfaceClass;
uint8_t intfSubClass = intf->bInterfaceSubClass;
if (_altsetting != -1 && _altsetting != intf_idx)
continue;
if (intfClass == 0xfe && intfSubClass == 0x01) {
struct dfu_dev my_dev;
if (_verbose)
printInfo("DFU found");
/* 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),
sizeof(my_dev.dfu_desc)) != 0)
continue; // not compatible
sizeof(my_dev.dfu_desc))) {
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.pid = desc->idProduct;
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));
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);
@ -413,24 +438,29 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
* Since libusb has no support for those 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)
{
const uint8_t *extra = intf->extra;
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)
return -1;
return false;
/* map memory to structure */
for (int j = 0; j + 1 < extra_len; j++) {
if (extra[j+1] == 0x21) {
memcpy(dfu_desc, (const void *)&extra[j], dfu_desc_size);
break;
return true;
}
}
return 0;
return false;
}
/* abstraction to send/receive to control */

View File

@ -206,9 +206,9 @@ class DFU {
* \param[in] intf: interface descriptor with extra area
* \param[out] dfu_desc: DFU descriptor
* \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);
/*!
* \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));
_addr = static_cast<uint8_t>(udevstufftoint(udev_device_get_sysattr_value(
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(
udev_device_get_sysattr_value(usbdeviceparent, "idVendor"), 16);
_pid = udevstufftoint(udev_device_get_sysattr_value(

View File

@ -883,8 +883,19 @@ void Gowin::sendClkUs(unsigned us)
bool Gowin::eraseSRAM()
{
printInfo("Erase SRAM ", false);
uint32_t status = readStatusReg();
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()) {
printError("FAIL");

View File

@ -1080,7 +1080,8 @@ void Lattice::displayReadReg(uint64_t dev)
err = (dev >> 23)&0x07;
}
printf("\t");
printf("\tBSE Error Code\n");
printf("\t\t");
switch (err) {
case 0:
printf("No err\n");
@ -1106,8 +1107,17 @@ void Lattice::displayReadReg(uint64_t dev)
case 7:
printf("SDM EOF\n");
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:
printf("unknown %x\n", err);
printf("unknown error: %x\n", err);
}
if (_fpga_family == NEXUS_FAMILY) {
@ -1164,7 +1174,7 @@ void Lattice::displayReadReg(uint64_t dev)
printf("Bitstream Engine Timeout ERR\n");
break;
default:
printf("unknown %x\n", err);
printf("unknown error: %x\n", err);
}
if ((dev >> 38) & 0x01) printf("\tBypass 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");
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");
return EXIT_FAILURE;
}
@ -98,7 +99,8 @@ int LatticeBitParser::parse()
/* check preamble */
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");
return EXIT_FAILURE;
}

View File

@ -286,6 +286,20 @@ static std::map <uint32_t, flash_t> flash_list = {
.bp_len = 4,
.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, {
/* https://www.macronix.com/Lists/Datasheet/Attachments/8934/MX25L12833F,%203V,%20128Mb,%20v1.0.pdf */
.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
if (_num_bits == _buffer_size * 8) {
// write
ll_write(NULL);
if(!ll_write(NULL))
throw std::runtime_error("xvc ll_write fails");
_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;
_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;
if (rx)
@ -184,7 +186,8 @@ int XVC_client::toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len)
if (len < _num_bits)
_num_bits = len;
len -= _num_bits;
ll_write(NULL);
if(!ll_write(NULL))
throw std::runtime_error("xvc ll_write fails");
} while (len > 0);
return clk_len;
@ -242,6 +245,23 @@ bool XVC_client::open_connection(const string &ip_addr)
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,
const uint8_t *tx, uint32_t tx_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;
/* 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");
return -1;
}
if (tx) {
if (send(_sock, tx, tx_size, 0) == -1) {
if (sendall(_sock, tx, tx_size, 0) == -1) {
printError("Send error");
return -1;
}