mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-22 20:44:19 +00:00
Merge pull request #196 from nelisky/ztex-120417
Adding ZTEX 1.15y quad fpga board support
This commit is contained in:
commit
a8d50a3cb8
@ -30,17 +30,37 @@
|
||||
|
||||
#define GOLDEN_BACKLOG 5
|
||||
|
||||
struct device_api ztex_api, ztex_hotplug_api;
|
||||
struct device_api ztex_api;
|
||||
|
||||
// Forward declarations
|
||||
static void ztex_disable(struct thr_info* thr);
|
||||
static bool ztex_prepare(struct thr_info *thr);
|
||||
|
||||
static void ztex_selectFpga(struct libztex_device* ztex)
|
||||
{
|
||||
if (ztex->root->numberOfFpgas > 1) {
|
||||
if (ztex->root->selectedFpga != ztex->fpgaNum)
|
||||
mutex_lock(&ztex->root->mutex);
|
||||
libztex_selectFpga(ztex);
|
||||
}
|
||||
}
|
||||
|
||||
static void ztex_releaseFpga(struct libztex_device* ztex)
|
||||
{
|
||||
if (ztex->root->numberOfFpgas > 1) {
|
||||
ztex->root->selectedFpga = -1;
|
||||
mutex_unlock(&ztex->root->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void ztex_detect(void)
|
||||
{
|
||||
int cnt;
|
||||
int i;
|
||||
int i,j;
|
||||
int fpgacount;
|
||||
struct libztex_dev_list **ztex_devices;
|
||||
struct libztex_device *ztex_slave;
|
||||
struct cgpu_info *ztex;
|
||||
|
||||
cnt = libztex_scanDevices(&ztex_devices);
|
||||
applog(LOG_WARNING, "Found %d ztex board(s)", cnt);
|
||||
@ -48,14 +68,33 @@ static void ztex_detect(void)
|
||||
for (i = 0; i < cnt; i++) {
|
||||
if (total_devices == MAX_DEVICES)
|
||||
break;
|
||||
struct cgpu_info *ztex;
|
||||
ztex = calloc(1, sizeof(struct cgpu_info));
|
||||
ztex->api = &ztex_api;
|
||||
ztex->device_ztex = ztex_devices[i]->dev;
|
||||
ztex->threads = 1;
|
||||
ztex->device_ztex->fpgaNum = 0;
|
||||
ztex->device_ztex->root = ztex->device_ztex;
|
||||
add_cgpu(ztex);
|
||||
|
||||
applog(LOG_WARNING,"%s: Found Ztex, mark as %d", ztex->device_ztex->repr, ztex->device_id);
|
||||
fpgacount = libztex_numberOfFpgas(ztex->device_ztex);
|
||||
|
||||
if (fpgacount > 1)
|
||||
pthread_mutex_init(&ztex->device_ztex->mutex, NULL);
|
||||
|
||||
for (j = 1; j < fpgacount; j++) {
|
||||
ztex = calloc(1, sizeof(struct cgpu_info));
|
||||
ztex->api = &ztex_api;
|
||||
ztex_slave = calloc(1, sizeof(struct libztex_device));
|
||||
memcpy(ztex_slave, ztex_devices[i]->dev, sizeof(struct libztex_device));
|
||||
ztex->device_ztex = ztex_slave;
|
||||
ztex->threads = 1;
|
||||
ztex_slave->fpgaNum = j;
|
||||
ztex_slave->root = ztex_devices[i]->dev;
|
||||
ztex_slave->repr[strlen(ztex_slave->repr) - 1] = ('1' + j);
|
||||
add_cgpu(ztex);
|
||||
}
|
||||
|
||||
applog(LOG_WARNING,"%s: Found Ztex (fpga count = %d) , mark as %d", ztex->device_ztex->repr, fpgacount, ztex->device_id);
|
||||
}
|
||||
|
||||
if (cnt > 0)
|
||||
@ -88,16 +127,18 @@ static bool ztex_updateFreq(struct libztex_device* ztex)
|
||||
}
|
||||
|
||||
if (bestM != ztex->freqM) {
|
||||
libztex_selectFpga(ztex, 0);
|
||||
ztex_selectFpga(ztex);
|
||||
libztex_setFreq(ztex, bestM);
|
||||
ztex_releaseFpga(ztex);
|
||||
}
|
||||
|
||||
maxM = ztex->freqMDefault;
|
||||
while (maxM < ztex->freqMaxM && ztex->errorWeight[maxM + 1] > 100)
|
||||
maxM++;
|
||||
if ((bestM < (1.0 - LIBZTEX_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) {
|
||||
libztex_selectFpga(ztex, 0);
|
||||
ztex_selectFpga(ztex);
|
||||
libztex_resetFpga(ztex);
|
||||
ztex_releaseFpga(ztex);
|
||||
applog(LOG_ERR, "%s: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.",
|
||||
ztex->repr, (1.0 - 1.0 * bestM / maxM) * 100);
|
||||
return false;
|
||||
@ -163,7 +204,7 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
|
||||
memcpy(sendbuf, work->data + 64, 12);
|
||||
memcpy(sendbuf + 12, work->midstate, 32);
|
||||
|
||||
libztex_selectFpga(ztex, 0);
|
||||
ztex_selectFpga(ztex);
|
||||
i = libztex_sendHashData(ztex, sendbuf);
|
||||
if (i < 0) {
|
||||
// Something wrong happened in send
|
||||
@ -174,9 +215,11 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
|
||||
// And there's nothing we can do about it
|
||||
ztex_disable(thr);
|
||||
applog(LOG_ERR, "%s: Failed to send hash data with err %d, giving up", ztex->repr, i);
|
||||
ztex_releaseFpga(ztex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ztex_releaseFpga(ztex);
|
||||
|
||||
applog(LOG_DEBUG, "%s: sent hashdata", ztex->repr);
|
||||
|
||||
@ -204,7 +247,7 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
|
||||
applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
|
||||
break;
|
||||
}
|
||||
libztex_selectFpga(ztex, 0);
|
||||
ztex_selectFpga(ztex);
|
||||
i = libztex_readHashData(ztex, &hdata[0]);
|
||||
if (i < 0) {
|
||||
// Something wrong happened in read
|
||||
@ -217,9 +260,11 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
|
||||
applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i);
|
||||
free(lastnonce);
|
||||
free(backlog);
|
||||
ztex_releaseFpga(ztex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ztex_releaseFpga(ztex);
|
||||
|
||||
if (work_restart[thr->id].restart) {
|
||||
applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
|
||||
@ -302,7 +347,7 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
|
||||
static void ztex_statline_before(char *buf, struct cgpu_info *cgpu)
|
||||
{
|
||||
if (cgpu->deven == DEV_ENABLED) {
|
||||
tailsprintf(buf, "%s | ", cgpu->device_ztex->snString);
|
||||
tailsprintf(buf, "%s-%d | ", cgpu->device_ztex->snString, cgpu->device_ztex->fpgaNum+1);
|
||||
tailsprintf(buf, "%0.2fMhz | ", cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1));
|
||||
}
|
||||
}
|
||||
@ -310,24 +355,28 @@ static void ztex_statline_before(char *buf, struct cgpu_info *cgpu)
|
||||
static bool ztex_prepare(struct thr_info *thr)
|
||||
{
|
||||
struct timeval now;
|
||||
struct cgpu_info *ztex = thr->cgpu;
|
||||
struct cgpu_info *cgpu = thr->cgpu;
|
||||
struct libztex_device *ztex = cgpu->device_ztex;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
get_datestamp(ztex->init, &now);
|
||||
|
||||
if (libztex_configureFpga(ztex->device_ztex) != 0)
|
||||
get_datestamp(cgpu->init, &now);
|
||||
|
||||
ztex_selectFpga(ztex);
|
||||
if (libztex_configureFpga(ztex) != 0)
|
||||
return false;
|
||||
|
||||
ztex->device_ztex->freqM = -1;
|
||||
ztex_updateFreq(ztex->device_ztex);
|
||||
|
||||
applog(LOG_DEBUG, "%s: prepare", ztex->device_ztex->repr);
|
||||
ztex_releaseFpga(ztex);
|
||||
ztex->freqM = ztex->freqMaxM+1;;
|
||||
//ztex_updateFreq(ztex);
|
||||
libztex_setFreq(ztex, ztex->freqMDefault);
|
||||
applog(LOG_DEBUG, "%s: prepare", ztex->repr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ztex_shutdown(struct thr_info *thr)
|
||||
{
|
||||
if (thr->cgpu->device_ztex != NULL) {
|
||||
if (thr->cgpu->device_ztex->fpgaNum == 0)
|
||||
pthread_mutex_destroy(&thr->cgpu->device_ztex->mutex);
|
||||
applog(LOG_DEBUG, "%s: shutdown", thr->cgpu->device_ztex->repr);
|
||||
libztex_destroy_device(thr->cgpu->device_ztex);
|
||||
thr->cgpu->device_ztex = NULL;
|
||||
@ -350,3 +399,4 @@ struct device_api ztex_api = {
|
||||
.scanhash = ztex_scanhash,
|
||||
.thread_shutdown = ztex_shutdown,
|
||||
};
|
||||
|
||||
|
133
libztex.c
133
libztex.c
@ -125,6 +125,107 @@ static int libztex_getFpgaState(struct libztex_device *ztex, struct libztex_fpga
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libztex_configureFpgaHS(struct libztex_device *ztex, const char* firmware, bool force, char bs)
|
||||
{
|
||||
struct libztex_fpgastate state;
|
||||
const int transactionBytes = 65536;
|
||||
unsigned char buf[transactionBytes], settings[2];
|
||||
int tries, cnt, buf_p, i;
|
||||
ssize_t pos = 0;
|
||||
FILE *fp;
|
||||
|
||||
if (!libztex_checkCapability(ztex, CAPABILITY_HS_FPGA))
|
||||
return -1;
|
||||
libztex_getFpgaState(ztex, &state);
|
||||
if (!force && state.fpgaConfigured) {
|
||||
applog(LOG_INFO, "Bitstream already configured");
|
||||
return 1;
|
||||
}
|
||||
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x33, 0, 0, settings, 2, 1000);
|
||||
if (unlikely(cnt < 0)) {
|
||||
applog(LOG_ERR, "%s: Failed getHSFpgaSettings with err %d", ztex->repr, cnt);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
libusb_claim_interface(ztex->hndl, settings[1]);
|
||||
|
||||
for (tries = 3; tries > 0; tries--) {
|
||||
fp = fopen(firmware, "rb");
|
||||
if (!fp) {
|
||||
applog(LOG_ERR, "%s: failed to read firmware '%s'", ztex->repr, firmware);
|
||||
return -2;
|
||||
}
|
||||
|
||||
while (pos < transactionBytes && !feof(fp)) {
|
||||
buf[pos++] = getc(fp);
|
||||
}
|
||||
|
||||
if (feof(fp))
|
||||
pos--;
|
||||
|
||||
if (bs != 0 && bs != 1)
|
||||
bs = libztex_detectBitstreamBitOrder(buf, transactionBytes < pos? transactionBytes: pos);
|
||||
|
||||
|
||||
if (bs == 1)
|
||||
libztex_swapBits(buf, pos);
|
||||
|
||||
libusb_control_transfer(ztex->hndl, 0x40, 0x34, 0, 0, NULL, 0, 1000);
|
||||
// 0x34 - initHSFPGAConfiguration
|
||||
|
||||
buf_p = pos;
|
||||
while (1) {
|
||||
i = 0;
|
||||
while (i < buf_p) {
|
||||
if (libusb_bulk_transfer(ztex->hndl,
|
||||
settings[0],
|
||||
&buf[i],
|
||||
buf_p - i,
|
||||
&cnt, 1000) != 0) {
|
||||
applog(LOG_ERR, "%s: Failed send hs fpga data", ztex->repr);
|
||||
break;
|
||||
}
|
||||
usleep(500);
|
||||
i += cnt;
|
||||
}
|
||||
if (i < buf_p || buf_p < transactionBytes)
|
||||
break;
|
||||
buf_p = 0;
|
||||
while (buf_p < transactionBytes && !feof(fp)) {
|
||||
buf[buf_p++] = getc(fp);
|
||||
}
|
||||
if (feof(fp))
|
||||
buf_p--;
|
||||
pos += buf_p;
|
||||
if (buf_p == 0)
|
||||
break;
|
||||
if (bs == 1)
|
||||
libztex_swapBits(buf, buf_p);
|
||||
}
|
||||
|
||||
libusb_control_transfer(ztex->hndl, 0x40, 0x35, 0, 0, NULL, 0, 1000);
|
||||
// 0x35 - finishHSFPGAConfiguration
|
||||
if (cnt >= 0)
|
||||
tries = 0;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
libztex_getFpgaState(ztex, &state);
|
||||
if (!state.fpgaConfigured) {
|
||||
applog(LOG_ERR, "%s: HS FPGA configuration failed: DONE pin does not go high", ztex->repr);
|
||||
return -3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
libusb_release_interface(ztex->hndl, settings[1]);
|
||||
|
||||
usleep(200000);
|
||||
applog(LOG_INFO, "%s: HS FPGA configuration done", ztex->repr);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int libztex_configureFpgaLS(struct libztex_device *ztex, const char* firmware, bool force, char bs)
|
||||
{
|
||||
struct libztex_fpgastate state;
|
||||
@ -216,12 +317,15 @@ static int libztex_configureFpgaLS(struct libztex_device *ztex, const char* firm
|
||||
int libztex_configureFpga(struct libztex_device *ztex)
|
||||
{
|
||||
char buf[256] = "bitstreams/";
|
||||
int rv;
|
||||
|
||||
memset(&buf[11], 0, 245);
|
||||
strcpy(&buf[11], ztex->bitFileName);
|
||||
strcpy(&buf[strlen(buf)], ".bit");
|
||||
|
||||
return libztex_configureFpgaLS(ztex, buf, true, 2);
|
||||
rv = libztex_configureFpgaHS(ztex, buf, true, 2);
|
||||
if (rv != 0)
|
||||
rv = libztex_configureFpgaLS(ztex, buf, true, 2);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int libztex_numberOfFpgas(struct libztex_device *ztex) {
|
||||
@ -235,30 +339,31 @@ int libztex_numberOfFpgas(struct libztex_device *ztex) {
|
||||
return cnt;
|
||||
}
|
||||
ztex->numberOfFpgas = buf[0] + 1;
|
||||
ztex->selectedFpga = buf[1];
|
||||
ztex->selectedFpga = -1;//buf[1];
|
||||
ztex->parallelConfigSupport = (buf[2] == 1);
|
||||
} else {
|
||||
ztex->numberOfFpgas = 1;
|
||||
ztex->selectedFpga = 0;
|
||||
ztex->selectedFpga = -1;//0;
|
||||
ztex->parallelConfigSupport = false;
|
||||
}
|
||||
}
|
||||
return ztex->numberOfFpgas;
|
||||
}
|
||||
|
||||
int libztex_selectFpga(struct libztex_device *ztex, int number) {
|
||||
int cnt, fpgacnt = libztex_numberOfFpgas(ztex);
|
||||
int libztex_selectFpga(struct libztex_device *ztex) {
|
||||
int cnt, fpgacnt = libztex_numberOfFpgas(ztex->root);
|
||||
int number = ztex->fpgaNum;
|
||||
if (number < 0 || number >= fpgacnt) {
|
||||
applog(LOG_WARNING, "%s: Trying to select wrong fpga (%d in %d)", ztex->repr, number, fpgacnt);
|
||||
return 1;
|
||||
}
|
||||
if (ztex->selectedFpga != number && libztex_checkCapability(ztex, CAPABILITY_MULTI_FPGA)) {
|
||||
cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x51, number, 0, NULL, 0, 500);
|
||||
if (ztex->root->selectedFpga != number && libztex_checkCapability(ztex->root, CAPABILITY_MULTI_FPGA)) {
|
||||
cnt = libusb_control_transfer(ztex->root->hndl, 0x40, 0x51, number, 0, NULL, 0, 500);
|
||||
if (unlikely(cnt < 0)) {
|
||||
applog(LOG_ERR, "Ztex check device: Failed to set fpga with err %d", cnt);
|
||||
return cnt;
|
||||
}
|
||||
ztex->selectedFpga = number;
|
||||
ztex->root->selectedFpga = number;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -276,8 +381,12 @@ int libztex_setFreq(struct libztex_device *ztex, uint16_t freq) {
|
||||
return cnt;
|
||||
}
|
||||
ztex->freqM = freq;
|
||||
applog(LOG_WARNING, "%s: Frequency change from %0.2f to %0.2f Mhz",
|
||||
ztex->repr, ztex->freqM1 * (oldfreq + 1), ztex->freqM1 * (ztex->freqM + 1));
|
||||
if (oldfreq > ztex->freqMaxM)
|
||||
applog(LOG_WARNING, "%s: Frequency set to %0.2f Mhz",
|
||||
ztex->repr, ztex->freqM1 * (ztex->freqM + 1));
|
||||
else
|
||||
applog(LOG_WARNING, "%s: Frequency change from %0.2f to %0.2f Mhz",
|
||||
ztex->repr, ztex->freqM1 * (oldfreq + 1), ztex->freqM1 * (ztex->freqM + 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -426,7 +535,7 @@ int libztex_prepare_device(struct libusb_device *dev, struct libztex_device** zt
|
||||
|
||||
newdev->usbbus = libusb_get_bus_number(dev);
|
||||
newdev->usbaddress = libusb_get_device_address(dev);
|
||||
sprintf(newdev->repr, "ZTEX %.3d:%.3d-%s", newdev->usbbus, newdev->usbaddress, newdev->snString);
|
||||
sprintf(newdev->repr, "ZTEX %s-1", newdev->snString);
|
||||
newdev->valid = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ struct libztex_fpgastate {
|
||||
};
|
||||
|
||||
struct libztex_device {
|
||||
pthread_mutex_t mutex;
|
||||
struct libztex_device *root;
|
||||
int fpgaNum;
|
||||
bool valid;
|
||||
struct libusb_device_descriptor descriptor;
|
||||
libusb_device_handle *hndl;
|
||||
@ -75,7 +78,7 @@ struct libztex_device {
|
||||
int selectedFpga;
|
||||
bool parallelConfigSupport;
|
||||
|
||||
char repr[64];
|
||||
char repr[20];
|
||||
};
|
||||
|
||||
struct libztex_dev_list {
|
||||
@ -98,6 +101,7 @@ extern int libztex_setFreq (struct libztex_device *ztex, uint16_t freq);
|
||||
extern int libztex_sendHashData (struct libztex_device *ztex, unsigned char *sendbuf);
|
||||
extern int libztex_readHashData (struct libztex_device *ztex, struct libztex_hash_data nonces[]);
|
||||
extern int libztex_resetFpga (struct libztex_device *ztex);
|
||||
extern int libztex_selectFpga(struct libztex_device *ztex, int number);
|
||||
extern int libztex_selectFpga(struct libztex_device *ztex);
|
||||
extern int libztex_numberOfFpgas(struct libztex_device *ztex);
|
||||
|
||||
#endif /* __LIBZTEX_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user