diff --git a/Makefile.am b/Makefile.am index 02ee6f06..f94eae30 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,7 +13,7 @@ EXTRA_DIST = example.conf m4/gnulib-cache.m4 linux-usb-cgminer \ SUBDIRS = lib compat ccan -INCLUDES = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_INCLUDES) +INCLUDES = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_INCLUDES) $(USB_FLAGS) bin_PROGRAMS = cgminer @@ -22,7 +22,7 @@ bin_SCRIPTS = *.cl cgminer_LDFLAGS = $(PTHREAD_FLAGS) cgminer_LDADD = $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \ @OPENCL_LIBS@ @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ \ - @UDEV_LIBS@ \ + @UDEV_LIBS@ @USB_LIBS@ \ @MATH_LIBS@ lib/libgnu.a ccan/libccan.a cgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib @OPENCL_FLAGS@ @@ -74,3 +74,7 @@ endif if HAS_ICARUS cgminer_SOURCES += icarus.c endif + +if HAS_ZTEX +cgminer_SOURCES += ztex.c libztex.c +endif diff --git a/cgminer.c b/cgminer.c index 70f3e5e9..4f55e7f8 100644 --- a/cgminer.c +++ b/cgminer.c @@ -54,6 +54,9 @@ #include #endif +#ifdef HAVE_LIBUSB + #include +#endif enum workio_commands { WC_GET_WORK, @@ -1016,6 +1019,9 @@ static char *opt_verusage_and_exit(const char *extra) #endif #ifdef USE_ICARUS "icarus " +#endif +#ifdef USE_ZTEX + "ztex " #endif "mining support.\n" , packagename); @@ -4130,6 +4136,9 @@ static void clean_up(void) #ifdef HAVE_OPENCL clear_adl(nDevs); #endif +#ifdef HAVE_LIBUSB + libusb_exit(NULL); +#endif gettimeofday(&total_tv_end, NULL); #ifdef HAVE_CURSES @@ -4385,6 +4394,10 @@ extern struct device_api bitforce_api; extern struct device_api icarus_api; #endif +#ifdef USE_ZTEX +extern struct device_api ztex_api; +#endif + static int cgminer_id_count = 0; @@ -4409,6 +4422,9 @@ int main(int argc, char *argv[]) struct thr_info *thr; unsigned int k; int i, j; +#ifdef HAVE_LIBUSB + struct libusb_context *context; +#endif /* This dangerous functions tramples random dynamically allocated * variables so do it before anything at all */ @@ -4419,6 +4435,9 @@ int main(int argc, char *argv[]) for (i = 0; i < argc; i++) initial_args[i] = strdup(argv[i]); initial_args[argc] = NULL; +#ifdef HAVE_LIBUSB + libusb_init(NULL); +#endif mutex_init(&hash_lock); mutex_init(&qd_lock); @@ -4572,6 +4591,10 @@ int main(int argc, char *argv[]) icarus_api.api_detect(); #endif +#ifdef USE_ZTEX + ztex_api.api_detect(); +#endif + #ifdef WANT_CPUMINE cpu_api.api_detect(); #endif diff --git a/configure.ac b/configure.ac index 4f7ed9ac..ab243b9b 100644 --- a/configure.ac +++ b/configure.ac @@ -62,6 +62,8 @@ AC_FUNC_ALLOCA have_win32=false PTHREAD_FLAGS="-lpthread" +USB_LIBS="" +USB_FLAGS="" DLOPEN_FLAGS="-ldl" OPENCL_LIBS="-lOpenCL" WS2_LIBS="" @@ -207,6 +209,16 @@ if test "x$icarus" = xyes; then fi AM_CONDITIONAL([HAS_ICARUS], [test x$icarus = xyes]) +ztex="no" + +AC_ARG_ENABLE([ztex], + [AC_HELP_STRING([--enable-ztex],[Compile support for Ztex (default disabled)])], + [ztex=$enableval] + ) +if test "x$ztex" = xyes; then + AC_DEFINE([USE_ZTEX], [1], [Defined to 1 if Ztex support is wanted]) +fi +AM_CONDITIONAL([HAS_ZTEX], [test x$ztex = xyes]) curses="auto" @@ -301,6 +313,14 @@ if test "x$bitforce" != xno; then fi AM_CONDITIONAL([HAVE_LIBUDEV], [test x$libudev != xno]) +if test "x$ztex" != xno; then + AC_CHECK_LIB(usb-1.0, libusb_init, , + AC_MSG_ERROR([Could not find usb library - please install libusb])) + AC_DEFINE([HAVE_LIBUSB], [1], [Defined to 1 if libusb is wanted]) + USB_LIBS="-lusb-1.0" + USB_FLAGS="-I/usr/include/libusb-1.0" +fi + PKG_PROG_PKG_CONFIG() PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.15.6], [AC_DEFINE([CURL_HAS_SOCKOPT], [1], [Defined if version of curl supports sockopts.])], @@ -362,6 +382,8 @@ AC_SUBST(PDCURSES_LIBS) AC_SUBST(WS2_LIBS) AC_SUBST(MATH_LIBS) AC_SUBST(UDEV_LIBS) +AC_SUBST(USB_LIBS) +AC_SUBST(USB_FLAGS) AC_CONFIG_FILES([ Makefile @@ -393,13 +415,13 @@ if test "x$opencl" != xno; then echo " OpenCL...............: FOUND. GPU mining support enabled" else echo " OpenCL...............: NOT FOUND. GPU mining support DISABLED" - if test "x$cpumining$bitforce$icarus" = xnonono; then + if test "x$cpumining$bitforce$icarus$ztex" = xnononono; then AC_MSG_ERROR([No mining configured in]) fi fi else echo " OpenCL...............: Detection overrided. GPU mining support DISABLED" - if test "x$cpumining$bitforce$icarus" = xnonono; then + if test "x$cpumining$bitforce$icarus$ztex" = xnononono; then AC_MSG_ERROR([No mining configured in]) fi fi @@ -427,6 +449,12 @@ else echo " Icarus.FPGAs.........: Disabled" fi +if test "x$ztex" = xyes; then + echo " Ztex.FPGAs...........: Enabled" +else + echo " Ztex.FPGAs...........: Disabled" +fi + if test "x$bitforce" != xno; then echo " libudev.detection....: $libudev" fi @@ -441,8 +469,8 @@ echo echo "Compilation............: make (or gmake)" echo " CPPFLAGS.............: $CPPFLAGS" echo " CFLAGS...............: $CFLAGS" -echo " LDFLAGS..............: $LDFLAGS $PTHREAD_FLAGS" -echo " LDADD................: $DLOPEN_FLAGS $LIBCURL_LIBS $JANSSON_LIBS $PTHREAD_LIBS $OPENCL_LIBS $NCURSES_LIBS $PDCURSES_LIBS $WS2_LIBS $MATH_LIBS $UDEV_LIBS" +echo " LDFLAGS..............: $LDFLAGS $PTHREAD_FLAGS $USB_FLAGS" +echo " LDADD................: $DLOPEN_FLAGS $LIBCURL_LIBS $JANSSON_LIBS $PTHREAD_LIBS $OPENCL_LIBS $NCURSES_LIBS $PDCURSES_LIBS $WS2_LIBS $MATH_LIBS $UDEV_LIBS $USB_LIBS" echo echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" echo " prefix...............: $prefix" diff --git a/libztex.c b/libztex.c new file mode 100644 index 00000000..6d2c9bf7 --- /dev/null +++ b/libztex.c @@ -0,0 +1,404 @@ +#include +#include +#include "miner.h" +#include "libztex.h" + +#define BUFSIZE 256 + +//* Capability index for EEPROM support. +#define CAPABILITY_EEPROM 0,0 +//* Capability index for FPGA configuration support. +#define CAPABILITY_FPGA 0,1 +//* Capability index for FLASH memory support. +#define CAPABILITY_FLASH 0,2 +//* Capability index for DEBUG helper support. +#define CAPABILITY_DEBUG 0,3 +//* Capability index for AVR XMEGA support. +#define CAPABILITY_XMEGA 0,4 +//* Capability index for AVR XMEGA support. +#define CAPABILITY_HS_FPGA 0,5 +//* Capability index for AVR XMEGA support. +#define CAPABILITY_MAC_EEPROM 0,6 + + + +static bool libztex_checkDevice (struct libusb_device *dev) { + int err; + + struct libusb_device_descriptor desc; + err = libusb_get_device_descriptor(dev, &desc); + if (unlikely(err != 0)) { + applog(LOG_ERR, "Ztex check device: Failed to open read descriptor with error %d", err); + return false; + } + if (!(desc.idVendor == 0x221A && desc.idProduct == 0x0100)) { + return false; + } + return true; +} + +static bool libztex_checkCapability (struct libztex_device *ztex, int i, int j) { + if (!((i>=0) && (i<=5) && (j>=0) && (j<8) && + (((ztex->interfaceCapabilities[i] & 255) & (1 << j)) != 0))) { + applog(LOG_ERR, "%s: capability missing: %d %d", ztex->repr, i, i); + } + return true; +} + +static int libztex_detectBitstreamBitOrder (const unsigned char *buf, int size) { + int i; + size -= 4; + for (i=0; i> 7) | + ((c & 64) >> 5) | + ((c & 32) >> 3) | + ((c & 16) >> 1) | + ((c & 8) << 1) | + ((c & 4) << 3) | + ((c & 2) << 5) | + ((c & 1) << 7); + } +} + +static int libztex_getFpgaState (struct libztex_device *ztex, struct libztex_fpgastate *state) { + int cnt; + unsigned char buf[9]; + if (!libztex_checkCapability(ztex, CAPABILITY_FPGA)) { + return -1; + } + cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x30, 0, 0, buf, 9, 1000); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "%s: Failed getFpgaState with err %d", ztex->repr, cnt); + return cnt; + } + state->fpgaConfigured = buf[0] == 0; + state->fpgaChecksum = buf[1] & 0xff; + state->fpgaBytes = ((buf[5] & 0xff)<<24) | ((buf[4] & 0xff)<<16) | ((buf[3] & 0xff)<<8) | (buf[2] & 0xff); + state->fpgaInitB = buf[6] & 0xff; + state->fpgaFlashResult = buf[7]; + state->fpgaFlashBitSwap = buf[8] != 0; + return 0; +} + +static int libztex_configureFpgaLS (struct libztex_device *ztex, const char* firmware, bool force, char bs) { + struct libztex_fpgastate state; + unsigned char buf[8*1024*1024], cs; + ssize_t pos=0; + int transactionBytes = 2048; + int tries, cnt, i, j; + FILE *fp; + + if (!libztex_checkCapability(ztex, CAPABILITY_FPGA)) { + return -1; + } + + libztex_getFpgaState(ztex, &state); + if (!force) { + if (state.fpgaConfigured) { + return 1; + } + } + + fp = fopen(firmware, "rb"); + if (!fp) { + applog(LOG_ERR, "%s: failed to read firmware '%s'", ztex->repr, firmware); + return -2; + } + + while (!feof(fp)) { + buf[pos++] = getc(fp); + }; + pos--; + applog(LOG_ERR, "%s: read firmware, %d bytes", ztex->repr, pos); + + fclose(fp); + + if ( bs<0 || bs>1 ) + bs = libztex_detectBitstreamBitOrder(buf, transactionBytes0; tries--) { + //* Reset fpga + cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x31, 0, 0, NULL, 0, 1000); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "%s: Failed reset fpga with err %d", ztex->repr, cnt); + continue; + } + cs = 0; + i = 0; + while (i < pos) { + j = (i+transactionBytes) > pos ? pos-i : transactionBytes; + cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x32, 0, 0, &buf[i], j, 5000); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "%s: Failed send fpga data with err %d", ztex->repr, cnt); + break; + } + for (j=0; jrepr); + return 3; + } + } + sleep(0.2); + applog(LOG_ERR, "%s: FPGA configuration done", ztex->repr); + return 0; +} + +int libztex_configureFpga (struct libztex_device *ztex) { + int rv; + rv = libztex_configureFpgaLS(ztex, "bitstreams/ztex_ufm1_15d3.bit", true, 2); + if (rv == 0) { + libztex_setFreq(ztex, ztex->freqMDefault); + } + return rv; +} + +int libztex_setFreq (struct libztex_device *ztex, uint16_t freq) { + int cnt; + if (freq > ztex->freqMaxM) { + freq = ztex->freqMaxM; + } + + cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x83, freq, 0, NULL, 0, 500); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "Ztex check device: Failed to set frequency with err %d", cnt); + return cnt; + } + ztex->freqM = freq; + applog(LOG_WARNING, "%s: Frequency change to %d Mhz", ztex->repr, ztex->freqM1 * (ztex->freqM + 1)); + + return 0; +} + +int libztex_prepare_device (struct libusb_device *dev, struct libztex_device** ztex) { + struct libztex_device *newdev; + int cnt, err; + unsigned char buf[64]; + + newdev = malloc(sizeof(struct libztex_device)); + newdev->valid = false; + newdev->hndl = NULL; + *ztex = newdev; + + err = libusb_get_device_descriptor(dev, &newdev->descriptor); + if (unlikely(err != 0)) { + applog(LOG_ERR, "Ztex check device: Failed to open read descriptor with error %d", err); + return err; + } + + // Check vendorId and productId + if (!(newdev->descriptor.idVendor == LIBZTEX_IDVENDOR && + newdev->descriptor.idProduct == LIBZTEX_IDPRODUCT)) { + applog(LOG_ERR, "Not a ztex device? %0.4X, %0.4X", newdev->descriptor.idVendor, newdev->descriptor.idProduct); + return 1; + } + + libusb_open(dev, &newdev->hndl); + cnt = libusb_get_string_descriptor_ascii (newdev->hndl, newdev->descriptor.iSerialNumber, newdev->snString, + LIBZTEX_SNSTRING_LEN+1); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "Ztex check device: Failed to read device snString with err %d", cnt); + return cnt; + } + applog(LOG_WARNING, "-- %s", newdev->snString); + + cnt = libusb_control_transfer(newdev->hndl, 0xc0, 0x22, 0, 0, buf, 40, 500); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "Ztex check device: Failed to read ztex descriptor with err %d", cnt); + return cnt; + } + + if ( buf[0]!=40 || buf[1]!=1 || buf[2]!='Z' || buf[3]!='T' || buf[4]!='E' || buf[5]!='X' ) { + applog(LOG_ERR, "Ztex check device: Error reading ztex descriptor"); + return 2; + } + + newdev->productId[0] = buf[6]; + newdev->productId[1] = buf[7]; + newdev->productId[2] = buf[8]; + newdev->productId[3] = buf[9]; + newdev->fwVersion = buf[10]; + newdev->interfaceVersion = buf[11]; + newdev->interfaceCapabilities[0] = buf[12]; + newdev->interfaceCapabilities[1] = buf[13]; + newdev->interfaceCapabilities[2] = buf[14]; + newdev->interfaceCapabilities[3] = buf[15]; + newdev->interfaceCapabilities[4] = buf[16]; + newdev->interfaceCapabilities[5] = buf[17]; + newdev->moduleReserved[0] = buf[18]; + newdev->moduleReserved[1] = buf[19]; + newdev->moduleReserved[2] = buf[20]; + newdev->moduleReserved[3] = buf[21]; + newdev->moduleReserved[4] = buf[22]; + newdev->moduleReserved[5] = buf[23]; + newdev->moduleReserved[6] = buf[24]; + newdev->moduleReserved[7] = buf[25]; + newdev->moduleReserved[8] = buf[26]; + newdev->moduleReserved[9] = buf[27]; + newdev->moduleReserved[10] = buf[28]; + newdev->moduleReserved[11] = buf[29]; + + + cnt = libusb_control_transfer(newdev->hndl, 0xc0, 0x82, 0, 0, buf, 64, 500); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "Ztex check device: Failed to read ztex descriptor with err %d", cnt); + return cnt; + } + + if (unlikely(buf[0]) != 4) { + if (unlikely(buf[0]) != 2) { + applog(LOG_ERR, "Invalid BTCMiner descriptor version. Firmware must be updated."); + return 3; + } + applog(LOG_WARNING, "Firmware out of date"); + } + + newdev->numNonces = buf[1] + 1; + newdev->offsNonces = ((buf[2] & 255) | ((buf[3] & 255) << 8)) - 10000; + newdev->freqM1 = ( (buf[4] & 255) | ((buf[5] & 255) << 8) ) * 0.01; + newdev->freqMaxM = (buf[7] & 255); + newdev->freqM = (buf[6] & 255); + newdev->freqMDefault = newdev->freqM; + + 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); + newdev->valid = true; + return 0; +} + +void libztex_destroy_device (struct libztex_device* ztex) { + if (ztex->hndl != NULL) { + libusb_close(ztex->hndl); + } + free(ztex); +} + +int libztex_scanDevices (struct libztex_dev_list*** devs_p) { + libusb_device **list; + struct libztex_device *ztex; + ssize_t cnt = libusb_get_device_list(NULL, &list); + ssize_t i = 0; + int found = 0, pos = 0, err; + + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "Ztex scan devices: Failed to list usb devices with err %d", cnt); + return 0; + } + + int usbdevices[LIBZTEX_MAX_DESCRIPTORS]; + + for (i = 0; i < cnt; i++) { + if (libztex_checkDevice(list[i])) { + // Got one! + usbdevices[found] = i; + found++; + } + } + + struct libztex_dev_list **devs; + devs = malloc(sizeof(struct libztex_dev_list *) * found); + if (devs == NULL) { + applog(LOG_ERR, "Ztex scan devices: Failed to allocate memory"); + return 0; + } + + for (i = 0; i < found; i++) { + err = libztex_prepare_device(list[usbdevices[i]], &ztex); + if (unlikely(err != 0)) { + applog(LOG_ERR, "prepare device: %d", err); + } + // check if valid + if (!ztex->valid) { + libztex_destroy_device(ztex); + continue; + } + devs[pos] = malloc(sizeof(struct libztex_dev_list)); + devs[pos]->dev = ztex; + devs[pos]->next = NULL; + //libusb_open(list[usbdevices[i]], &devs[i]->hndl); + //libusb_close(devs[cnt]->dev->hndl); + if (pos > 0) { + devs[pos]->next = devs[pos]; + } + pos++; + } + + libusb_free_device_list(list, 1); + *devs_p = devs; + return pos; +} + +int libztex_sendHashData (struct libztex_device *ztex, unsigned char *sendbuf) { + int cnt; + + cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x80, 0, 0, sendbuf, 44, 1000); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "%s: Failed sendHashData with err %d", ztex->repr, cnt); + } + + return cnt; +} + +int libztex_readHashData (struct libztex_device *ztex, struct libztex_hash_data nonces[]) { + // length of buf must be 8 * (numNonces + 1) + unsigned char rbuf[12*8]; + int cnt, i; + + cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x81, 0, 0, rbuf, 12*ztex->numNonces, 1000); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "%s: Failed readHashData with err %d", ztex->repr, cnt); + return cnt; + } + + for (i=0; inumNonces; i++) { + memcpy((char*)&nonces[i].goldenNonce, &rbuf[i*12], 4); + nonces[i].goldenNonce -= ztex->offsNonces; + memcpy((char*)&nonces[i].nonce, &rbuf[(i*12)+4], 4); + nonces[i].nonce -= ztex->offsNonces; + memcpy((char*)&nonces[i].hash7, &rbuf[(i*12)+8], 4); + } + + return cnt; +} + +void libztex_freeDevList (struct libztex_dev_list **devs) { + ssize_t cnt = 0; + bool done = false; + while (!done) { + if (devs[cnt]->next == NULL) { + done = true; + } + free(devs[cnt++]); + } + free(devs); +} + +int libztex_configreFpga (struct libztex_dev_list* dev) { + return 0; +} + diff --git a/libztex.h b/libztex.h new file mode 100644 index 00000000..44e598b1 --- /dev/null +++ b/libztex.h @@ -0,0 +1,62 @@ +#ifndef __LIBZTEX_H__ +#define __LIBZTEX_H__ + +#include + +#define LIBZTEX_MAX_DESCRIPTORS 512 +#define LIBZTEX_SNSTRING_LEN 10 + +#define LIBZTEX_IDVENDOR 0x221A +#define LIBZTEX_IDPRODUCT 0x0100 + +struct libztex_fpgastate { + bool fpgaConfigured; + unsigned char fpgaChecksum; + uint16_t fpgaBytes; + unsigned char fpgaInitB; + unsigned char fpgaFlashResult; + bool fpgaFlashBitSwap; +}; + +struct libztex_device { + bool valid; + struct libusb_device_descriptor descriptor; + libusb_device_handle *hndl; + unsigned char usbbus; + unsigned char usbaddress; + unsigned char snString[LIBZTEX_SNSTRING_LEN+1]; + unsigned char productId[4]; + unsigned char fwVersion; + unsigned char interfaceVersion; + unsigned char interfaceCapabilities[6]; + unsigned char moduleReserved[12]; + uint8_t numNonces; + uint16_t offsNonces; + uint16_t freqM1; + uint8_t freqM; + uint8_t freqMaxM; + uint8_t freqMDefault; + + char repr[64]; +}; + +struct libztex_dev_list { + struct libztex_device *dev; + struct libztex_dev_list *next; +}; + +struct libztex_hash_data { + uint32_t goldenNonce; + uint32_t nonce; + uint32_t hash7; +}; + +extern int libztex_scanDevices (struct libztex_dev_list ***devs); +extern void libztex_freeDevList (struct libztex_dev_list **devs); +extern void libztex_destroy_device (struct libztex_device* ztex); +extern int libztex_configureFpga (struct libztex_device *dev); +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[]); + +#endif /* __LIBZTEX_H__ */ diff --git a/miner.h b/miner.h index 24a6ef36..12ae8a02 100644 --- a/miner.h +++ b/miner.h @@ -61,6 +61,14 @@ void *alloca (size_t); #include "ADL_SDK/adl_sdk.h" #endif +#ifdef HAVE_LIBUSB + #include +#endif + +#ifdef USE_ZTEX + #include "libztex.h" +#endif + #if !defined(WIN32) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) #define bswap_16 __builtin_bswap16 #define bswap_32 __builtin_bswap32 @@ -249,6 +257,9 @@ struct cgpu_info { int device_id; char *device_path; FILE *device_file; +#ifdef USE_ZTEX + struct libztex_device *device; +#endif int device_fd; enum dev_enable deven; diff --git a/todo_ztex.txt b/todo_ztex.txt new file mode 100644 index 00000000..411744c1 --- /dev/null +++ b/todo_ztex.txt @@ -0,0 +1,5 @@ +- make it compile on osx / windows +- read actual bitstream +- nonce errors from fpga +- clock scaling +- HS fpga config diff --git a/ztex.c b/ztex.c new file mode 100644 index 00000000..2cf7ae22 --- /dev/null +++ b/ztex.c @@ -0,0 +1,168 @@ +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#ifndef WIN32 +// #include +// #include +// #include +// #ifndef O_CLOEXEC +// #define O_CLOEXEC 0 +// #endif +//#else +// #include +// #include +//#endif + +//#include "elist.h" +#include + +#include "miner.h" +#include "libztex.h" +//#include + +#define GOLDEN_BACKLOG 5 + +struct device_api ztex_api; + + +static void ztex_detect() +{ + int cnt; + int i; + struct libztex_dev_list **ztex_devices; + + cnt = libztex_scanDevices(&ztex_devices); + applog(LOG_WARNING, "Found %d ztex board(s)", cnt); + + for (i=0; iapi = &ztex_api; + ztex->device_id = total_devices; + ztex->device = ztex_devices[i]->dev; + //ztex->device_path = strdup(devpath); + ztex->threads = 1; + devices[total_devices++] = ztex; + + applog(LOG_WARNING,"%s: Found Ztex, mark as %d", ztex->device->repr, ztex->device_id); + } + + if (cnt > 0) { + libztex_freeDevList(ztex_devices); + } + +} + +static bool ztex_prepare(struct thr_info *thr) +{ + struct timeval now; + struct cgpu_info *ztex = thr->cgpu; + + gettimeofday(&now, NULL); + get_datestamp(ztex->init, &now); + + if (libztex_configureFpga(ztex->device) != 0) { + return false; + } + return true; +} + +static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, + __maybe_unused uint64_t max_nonce) +{ + struct libztex_device *ztex; + unsigned char sendbuf[44]; + int i, j; + uint32_t backlog[GOLDEN_BACKLOG]; + int backlog_p = 0; + uint32_t lastnonce[GOLDEN_BACKLOG], nonce, noncecnt = 0; + bool overflow, found, rv; + struct libztex_hash_data hdata[GOLDEN_BACKLOG]; + + ztex = thr->cgpu->device; + + memcpy(sendbuf, work->data + 64, 12); + memcpy(sendbuf+12, work->midstate, 32); + memset(backlog, 0, sizeof(backlog)); + libztex_sendHashData(ztex, sendbuf); + //applog(LOG_WARNING, "sent hashdata"); + + //hdata = malloc(sizeof(struct libztex_hash_data*)*ztex->numNonces); + for (i=0; inumNonces; i++) { + //hdata[i] = malloc(sizeof(struct libztex_hash_data)); + lastnonce[i] = 0; + } + //sleep(1.00); + overflow = false; + while (!(overflow || work_restart[thr->id].restart)) { + //sleep(0.5); + libztex_readHashData(ztex, &hdata[0]); + + for (i=0; inumNonces; i++) { + nonce = hdata[i].nonce; + if (nonce > noncecnt) + noncecnt = nonce; + if ((nonce >> 4) < (lastnonce[i] >> 4)) + overflow = true; + else + lastnonce[i] = nonce; + nonce = hdata[i].goldenNonce; + if (nonce > 0) { + found = false; + for (j=0; j= GOLDEN_BACKLOG) { + backlog_p = 0; + } +#ifdef __BIG_ENDIAN__ + nonce = swab32(nonce); +#endif + work->blk.nonce = 0xffffffff; + rv = submit_nonce(thr, work, nonce); + applog(LOG_WARNING, "submitted %0.8X %d", nonce, rv); + } + } + +// +// //applog(LOG_WARNING, "%0.8X %0.8X %d", hdata[i]->nonce, hdata[i]->goldenNonce, work_restart[thr->id].restart); + } + + } + + //for (i=0; inumNonces; i++) { + // free(hdata[i]); + // } + // free(hdata); + + applog(LOG_WARNING, "exit %0.8X", noncecnt); + return noncecnt; +} + +static void ztex_shutdown(struct thr_info *thr) +{ + if (thr->cgpu) { + libztex_destroy_device(thr->cgpu->device); + thr->cgpu = NULL; + } +} + +struct device_api ztex_api = { + .name = "ZTX", + .api_detect = ztex_detect, + .thread_prepare = ztex_prepare, + .scanhash = ztex_scanhash, + .thread_shutdown = ztex_shutdown, +};