Browse Source

Firmware 15d4 support

Not yet using suspend and while we have fpga counting implemented it isn't being used yet, thus only the groundwork for quad board support is done, not actually working yet.
nfactor-troky
nelisky 13 years ago
parent
commit
5f5e1063f4
  1. BIN
      bitstreams/ztex_ufm1_15d4.bit
  2. BIN
      bitstreams/ztex_ufm1_15y1.bit
  3. 99
      driver-ztex.c
  4. 135
      libztex.c
  5. 11
      libztex.h

BIN
bitstreams/ztex_ufm1_15d4.bit

Binary file not shown.

BIN
bitstreams/ztex_ufm1_15y1.bit

Binary file not shown.

99
driver-ztex.c

@ -87,13 +87,16 @@ static bool ztex_updateFreq(struct libztex_device* ztex)
} }
} }
if (bestM != ztex->freqM) if (bestM != ztex->freqM) {
libztex_selectFpga(ztex, 0);
libztex_setFreq(ztex, bestM); libztex_setFreq(ztex, bestM);
}
maxM = ztex->freqMDefault; maxM = ztex->freqMDefault;
while (maxM < ztex->freqMaxM && ztex->errorWeight[maxM + 1] > 100) while (maxM < ztex->freqMaxM && ztex->errorWeight[maxM + 1] > 100)
maxM++; maxM++;
if ((bestM < (1.0 - LIBZTEX_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) { if ((bestM < (1.0 - LIBZTEX_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) {
libztex_selectFpga(ztex, 0);
libztex_resetFpga(ztex); libztex_resetFpga(ztex);
applog(LOG_ERR, "%s: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.", 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); ztex->repr, (1.0 - 1.0 * bestM / maxM) * 100);
@ -147,10 +150,11 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
{ {
struct libztex_device *ztex; struct libztex_device *ztex;
unsigned char sendbuf[44]; unsigned char sendbuf[44];
int i, j; int i, j, k;
uint32_t backlog[GOLDEN_BACKLOG]; uint32_t *backlog;
int backlog_p = 0; int backlog_p = 0, backlog_max;
uint32_t lastnonce[GOLDEN_BACKLOG], nonce, noncecnt = 0; uint32_t *lastnonce;
uint32_t nonce, noncecnt = 0;
bool overflow, found, rv; bool overflow, found, rv;
struct libztex_hash_data hdata[GOLDEN_BACKLOG]; struct libztex_hash_data hdata[GOLDEN_BACKLOG];
@ -158,7 +162,8 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
memcpy(sendbuf, work->data + 64, 12); memcpy(sendbuf, work->data + 64, 12);
memcpy(sendbuf + 12, work->midstate, 32); memcpy(sendbuf + 12, work->midstate, 32);
memset(backlog, 0, sizeof(backlog));
libztex_selectFpga(ztex, 0);
i = libztex_sendHashData(ztex, sendbuf); i = libztex_sendHashData(ztex, sendbuf);
if (i < 0) { if (i < 0) {
// Something wrong happened in send // Something wrong happened in send
@ -173,19 +178,40 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
} }
} }
applog(LOG_DEBUG, "sent hashdata"); applog(LOG_DEBUG, "%s: sent hashdata", ztex->repr);
for (i = 0; i < ztex->numNonces; i++)
lastnonce[i] = 0;
lastnonce = malloc(sizeof(uint32_t)*ztex->numNonces);
if (lastnonce == NULL) {
applog(LOG_ERR, "%s: failed to allocate lastnonce[%d]", ztex->repr, ztex->numNonces);
return 0;
}
memset(lastnonce, 0, sizeof(uint32_t)*ztex->numNonces);
backlog_max = ztex->numNonces * (1+ztex->extraSolutions);
backlog = malloc(sizeof(uint32_t)*backlog_max);
if (backlog == NULL) {
applog(LOG_ERR, "%s: failed to allocate backlog[%d]", ztex->repr, backlog_max);
return 0;
}
memset(backlog, 0, sizeof(uint32_t)*backlog_max);
overflow = false; overflow = false;
// Because we may have more than one solution on 1.15y boards, lets allocate space for these
for (i=0; i<GOLDEN_BACKLOG; i++)
hdata[i].goldenNonce = (uint32_t*)malloc((sizeof(uint32_t))*(ztex->extraSolutions+1));
if (hdata[i].goldenNonce == NULL) {
applog(LOG_ERR, "%s: failed to allocate hash_data.goldenNonce[%d]", ztex->repr, ztex->extraSolutions+1);
return 0;
}
applog(LOG_DEBUG, "%s: entering poll loop", ztex->repr);
while (!(overflow || work_restart[thr->id].restart)) { while (!(overflow || work_restart[thr->id].restart)) {
usleep(250000); usleep(250000);
if (work_restart[thr->id].restart) { if (work_restart[thr->id].restart) {
applog(LOG_DEBUG, "%s: New work detected", ztex->repr); applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
break; break;
} }
libztex_selectFpga(ztex, 0);
i = libztex_readHashData(ztex, &hdata[0]); i = libztex_readHashData(ztex, &hdata[0]);
if (i < 0) { if (i < 0) {
// Something wrong happened in read // Something wrong happened in read
@ -196,6 +222,10 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
// And there's nothing we can do about it // And there's nothing we can do about it
ztex_disable(thr); ztex_disable(thr);
applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i); applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i);
for (j=0; j<GOLDEN_BACKLOG; j++)
free(hdata[j].goldenNonce);
free(lastnonce);
free(backlog);
return 0; return 0;
} }
} }
@ -227,26 +257,28 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
thr->cgpu->hw_errors++; thr->cgpu->hw_errors++;
continue; continue;
} }
nonce = hdata[i].goldenNonce; for (j=0; j<=ztex->extraSolutions; j++) {
if (nonce > 0) { nonce = hdata[i].goldenNonce[j];
found = false; if (nonce > 0) {
for (j = 0; j < GOLDEN_BACKLOG; j++) { found = false;
if (backlog[j] == nonce) { for (k = 0; k < backlog_max; k++) {
found = true; if (backlog[k] == nonce) {
break; found = true;
break;
}
} }
} if (!found) {
if (!found) { applog(LOG_DEBUG, "%s: Share found N%dE%d", ztex->repr, i, j);
applog(LOG_DEBUG, "%s: Share found", ztex->repr); backlog[backlog_p++] = nonce;
backlog[backlog_p++] = nonce; if (backlog_p >= backlog_max)
if (backlog_p >= GOLDEN_BACKLOG) backlog_p = 0;
backlog_p = 0;
#if defined(__BIGENDIAN__) || defined(MIPSEB) #if defined(__BIGENDIAN__) || defined(MIPSEB)
nonce = swab32(nonce); nonce = swab32(nonce);
#endif #endif
work->blk.nonce = 0xffffffff; work->blk.nonce = 0xffffffff;
rv = submit_nonce(thr, work, nonce); rv = submit_nonce(thr, work, nonce);
applog(LOG_DEBUG, "%s: submitted %0.8x %d", ztex->repr, nonce, rv); applog(LOG_DEBUG, "%s: submitted %0.8x %d", ztex->repr, nonce, rv);
}
} }
} }
@ -258,14 +290,25 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
if (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM]) if (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM])
ztex->maxErrorRate[ztex->freqM] = ztex->errorRate[ztex->freqM]; ztex->maxErrorRate[ztex->freqM] = ztex->errorRate[ztex->freqM];
if (!ztex_updateFreq(ztex)) if (!ztex_updateFreq(ztex)) {
// Something really serious happened, so mark this thread as dead! // Something really serious happened, so mark this thread as dead!
for (i=0; i<GOLDEN_BACKLOG; i++)
free(hdata[i].goldenNonce);
free(lastnonce);
free(backlog);
return 0; return 0;
}
applog(LOG_DEBUG, "%s: exit %1.8X", ztex->repr, noncecnt); applog(LOG_DEBUG, "%s: exit %1.8X", ztex->repr, noncecnt);
work->blk.nonce = 0xffffffff; work->blk.nonce = 0xffffffff;
for (i=0; i<GOLDEN_BACKLOG; i++)
free(hdata[i].goldenNonce);
free(lastnonce);
free(backlog);
return noncecnt > 0? noncecnt: 1; return noncecnt > 0? noncecnt: 1;
} }

135
libztex.c

@ -41,7 +41,8 @@
#define CAPABILITY_HS_FPGA 0,5 #define CAPABILITY_HS_FPGA 0,5
//* Capability index for AVR XMEGA support. //* Capability index for AVR XMEGA support.
#define CAPABILITY_MAC_EEPROM 0,6 #define CAPABILITY_MAC_EEPROM 0,6
//* Capability index for multi FPGA support.
#define CAPABILITY_MULTI_FPGA 0,7
static bool libztex_checkDevice(struct libusb_device *dev) static bool libztex_checkDevice(struct libusb_device *dev)
@ -65,7 +66,7 @@ static bool libztex_checkCapability(struct libztex_device *ztex, int i, int j)
{ {
if (!((i >= 0) && (i <= 5) && (j >= 0) && (j < 8) && if (!((i >= 0) && (i <= 5) && (j >= 0) && (j < 8) &&
(((ztex->interfaceCapabilities[i] & 255) & (1 << j)) != 0))) { (((ztex->interfaceCapabilities[i] & 255) & (1 << j)) != 0))) {
applog(LOG_ERR, "%s: capability missing: %d %d", ztex->repr, i, i); applog(LOG_ERR, "%s: capability missing: %d %d", ztex->repr, i, j);
return false; return false;
} }
return true; return true;
@ -223,8 +224,46 @@ int libztex_configureFpga(struct libztex_device *ztex)
return libztex_configureFpgaLS(ztex, buf, true, 2); return libztex_configureFpgaLS(ztex, buf, true, 2);
} }
int libztex_setFreq(struct libztex_device *ztex, uint16_t freq) int libztex_numberOfFpgas(struct libztex_device *ztex) {
{ int cnt;
unsigned char buf[3];
if ( ztex->numberOfFpgas < 0 ) {
if (libztex_checkCapability(ztex, CAPABILITY_MULTI_FPGA)) {
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x50, 0, 0, buf, 3, 1000);
if (unlikely(cnt < 0)) {
applog(LOG_ERR, "%s: Failed getMultiFpgaInfo with err %d", ztex->repr, cnt);
return cnt;
}
ztex->numberOfFpgas = buf[0]+1;
ztex->selectedFpga = buf[1];
ztex->parallelConfigSupport = (buf[2] == 1);
} else {
ztex->numberOfFpgas = 1;
ztex->selectedFpga = 0;
ztex->parallelConfigSupport = false;
}
}
return ztex->numberOfFpgas;
}
int libztex_selectFpga(struct libztex_device *ztex, int number) {
int cnt, fpgacnt = libztex_numberOfFpgas(ztex);
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 (unlikely(cnt < 0)) {
applog(LOG_ERR, "Ztex check device: Failed to set fpga with err %d", cnt);
return cnt;
}
ztex->selectedFpga = number;
}
return 0;
}
int libztex_setFreq(struct libztex_device *ztex, uint16_t freq) {
int cnt; int cnt;
if (freq > ztex->freqMaxM) if (freq > ztex->freqMaxM)
@ -246,14 +285,22 @@ int libztex_resetFpga(struct libztex_device *ztex)
return libusb_control_transfer(ztex->hndl, 0x40, 0x31, 0, 0, NULL, 0, 1000); return libusb_control_transfer(ztex->hndl, 0x40, 0x31, 0, 0, NULL, 0, 1000);
} }
int libztex_prepare_device(struct libusb_device *dev, struct libztex_device** ztex) int libztex_suspend(struct libztex_device *ztex) {
{ if (ztex->suspendSupported) {
return libusb_control_transfer(ztex->hndl, 0x40, 0x84, 0, 0, NULL, 0, 1000);
} else {
return 0;
}
}
int libztex_prepare_device(struct libusb_device *dev, struct libztex_device** ztex) {
struct libztex_device *newdev; struct libztex_device *newdev;
int i, cnt, err;
unsigned char buf[64]; unsigned char buf[64];
int cnt, err;
newdev = malloc(sizeof(struct libztex_device)); newdev = malloc(sizeof(struct libztex_device));
newdev->bitFileName = NULL; newdev->bitFileName = NULL;
newdev->numberOfFpgas = -1;
newdev->valid = false; newdev->valid = false;
newdev->hndl = NULL; newdev->hndl = NULL;
*ztex = newdev; *ztex = newdev;
@ -327,20 +374,46 @@ int libztex_prepare_device(struct libusb_device *dev, struct libztex_device** zt
return cnt; return cnt;
} }
if (unlikely(buf[0] != 4)) { if (unlikely(buf[0] != 5)) {
if (unlikely(buf[0] != 2)) { if (unlikely(buf[0] != 2 && buf[0] != 4)) {
applog(LOG_ERR, "Invalid BTCMiner descriptor version. Firmware must be updated (%d).", buf[0]); applog(LOG_ERR, "Invalid BTCMiner descriptor version. Firmware must be updated (%d).", buf[0]);
return 3; return 3;
} }
applog(LOG_WARNING, "Firmware out of date"); applog(LOG_WARNING, "Firmware out of date (%d).", buf[0]);
} }
i = buf[0] > 4 ? 11 : (buf[0] > 2 ? 10 : 8);
while (cnt < 64 && buf[cnt] != 0)
cnt++;
if (cnt < i+1) {
applog(LOG_ERR, "Invalid bitstream file name .");
return 4;
}
newdev->bitFileName = malloc(sizeof(char)*(cnt+1));
memcpy(newdev->bitFileName, &buf[i], cnt);
newdev->bitFileName[cnt] = 0;
newdev->numNonces = buf[1] + 1; newdev->numNonces = buf[1] + 1;
newdev->offsNonces = ((buf[2] & 255) | ((buf[3] & 255) << 8)) - 10000; newdev->offsNonces = ((buf[2] & 255) | ((buf[3] & 255) << 8)) - 10000;
newdev->freqM1 = ((buf[4] & 255) | ((buf[5] & 255) << 8) ) * 0.01; newdev->freqM1 = ((buf[4] & 255) | ((buf[5] & 255) << 8) ) * 0.01;
newdev->freqMaxM = (buf[7] & 255); newdev->freqMaxM = (buf[7] & 255);
newdev->freqM = (buf[6] & 255); newdev->freqM = (buf[6] & 255);
newdev->freqMDefault = newdev->freqM; newdev->freqMDefault = newdev->freqM;
newdev->suspendSupported = (buf[0] == 5);
newdev->hashesPerClock = buf[0] > 2 ? ((buf[8] & 255) | ((buf[9] & 255) << 8) + 1) / 128.0 : 1.0;
newdev->extraSolutions = buf[0] > 4 ? buf[10] : 0;
applog(LOG_DEBUG, "PID: %d numNonces: %d offsNonces: %d freqM1: %f freqMaxM: %d freqM: %d suspendSupported: %s hashesPerClock: %f extraSolutions: %d",
buf[0], newdev->numNonces, newdev->offsNonces, newdev->freqM1, newdev->freqMaxM, newdev->freqM, newdev->suspendSupported ? "T": "F",
newdev->hashesPerClock, newdev->extraSolutions);
if (buf[0] < 4) {
if (strncmp(newdev->bitFileName, "ztex_ufm1_15b", 13) != 0)
newdev->hashesPerClock = 0.5;
applog(LOG_WARNING, "HASHES_PER_CLOCK not defined, assuming %0.2f", newdev->hashesPerClock);
}
for (cnt=0; cnt < 255; cnt++) { for (cnt=0; cnt < 255; cnt++) {
newdev->errorCount[cnt] = 0; newdev->errorCount[cnt] = 0;
@ -349,10 +422,6 @@ int libztex_prepare_device(struct libusb_device *dev, struct libztex_device** zt
newdev->maxErrorRate[cnt] = 0; newdev->maxErrorRate[cnt] = 0;
} }
cnt = strlen((char *)&buf[buf[0] == 4? 10: 8]);
newdev->bitFileName = malloc(sizeof(char) * (cnt + 1));
memcpy(newdev->bitFileName, &buf[buf[0] == 4? 10: 8], cnt + 1);
newdev->usbbus = libusb_get_bus_number(dev); newdev->usbbus = libusb_get_bus_number(dev);
newdev->usbaddress = libusb_get_device_address(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 %.3d:%.3d-%s", newdev->usbbus, newdev->usbaddress, newdev->snString);
@ -437,29 +506,43 @@ int libztex_sendHashData(struct libztex_device *ztex, unsigned char *sendbuf)
return cnt; return cnt;
} }
int libztex_readHashData(struct libztex_device *ztex, struct libztex_hash_data nonces[]) int libztex_readHashData(struct libztex_device *ztex, struct libztex_hash_data nonces[]) {
{ int bufsize = 12 + ztex->extraSolutions * 4;
// length of buf must be 8 * (numNonces + 1) unsigned char *rbuf;
unsigned char rbuf[12 * 8]; int cnt, i, j;
int cnt, i;
if (ztex->hndl == NULL) if (ztex->hndl == NULL)
return 0; return 0;
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x81, 0, 0, rbuf, 12 * ztex->numNonces, 1000); rbuf = malloc(sizeof(unsigned char) * (ztex->numNonces * bufsize));
if (rbuf == NULL) {
applog(LOG_ERR, "%s: Failed to allocate memory for reading nonces", ztex->repr);
return 0;
}
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x81, 0, 0, rbuf, bufsize * ztex->numNonces, 1000);
if (unlikely(cnt < 0)) { if (unlikely(cnt < 0)) {
applog(LOG_ERR, "%s: Failed readHashData with err %d", ztex->repr, cnt); applog(LOG_ERR, "%s: Failed readHashData with err %d", ztex->repr, cnt);
free(rbuf);
return cnt; return cnt;
} }
for (i = 0; i < ztex->numNonces; i++) { for (i=0; i<ztex->numNonces; i++) {
memcpy((char*)&nonces[i].goldenNonce, &rbuf[i * 12], 4); memcpy((char*)&nonces[i].goldenNonce[0], &rbuf[i*bufsize], 4);
nonces[i].goldenNonce -= ztex->offsNonces; nonces[i].goldenNonce[0] -= ztex->offsNonces;
memcpy((char*)&nonces[i].nonce, &rbuf[(i * 12) + 4], 4); //applog(LOG_DEBUG, "W %d:0 %0.8x", i, nonces[i].goldenNonce[0]);
memcpy((char*)&nonces[i].nonce, &rbuf[(i*bufsize)+4], 4);
nonces[i].nonce -= ztex->offsNonces; nonces[i].nonce -= ztex->offsNonces;
memcpy((char*)&nonces[i].hash7, &rbuf[(i * 12) + 8], 4); memcpy((char*)&nonces[i].hash7, &rbuf[(i*bufsize)+8], 4);
for (j=0; j<ztex->extraSolutions; j++) {
memcpy((char*)&nonces[i].goldenNonce[j+1], &rbuf[(i*bufsize)+12+(j*4)], 4);
nonces[i].goldenNonce[j+1] -= ztex->offsNonces;
//applog(LOG_DEBUG, "W %d:%d %0.8x", i, j+1, nonces[i].goldenNonce[j+1]);
}
} }
free(rbuf);
return cnt; return cnt;
} }

11
libztex.h

@ -32,7 +32,7 @@
#define LIBZTEX_MAXMAXERRORRATE 0.05 #define LIBZTEX_MAXMAXERRORRATE 0.05
#define LIBZTEX_ERRORHYSTERESIS 0.1 #define LIBZTEX_ERRORHYSTERESIS 0.1
#define LIBZTEX_OVERHEATTHRESHOLD 0.5 #define LIBZTEX_OVERHEATTHRESHOLD 0.4
struct libztex_fpgastate { struct libztex_fpgastate {
bool fpgaConfigured; bool fpgaConfigured;
@ -62,12 +62,19 @@ struct libztex_device {
uint8_t freqMaxM; uint8_t freqMaxM;
uint8_t freqMDefault; uint8_t freqMDefault;
char* bitFileName; char* bitFileName;
bool suspendSupported;
double hashesPerClock;
uint8_t extraSolutions;
double errorCount[256]; double errorCount[256];
double errorWeight[256]; double errorWeight[256];
double errorRate[256]; double errorRate[256];
double maxErrorRate[256]; double maxErrorRate[256];
int numberOfFpgas;
int selectedFpga;
bool parallelConfigSupport;
char repr[64]; char repr[64];
}; };
@ -77,7 +84,7 @@ struct libztex_dev_list {
}; };
struct libztex_hash_data { struct libztex_hash_data {
uint32_t goldenNonce; uint32_t *goldenNonce;
uint32_t nonce; uint32_t nonce;
uint32_t hash7; uint32_t hash7;
}; };

Loading…
Cancel
Save