Browse Source

Bitfury BF1 source files added

Andreas Auer 12 years ago
parent
commit
d0c26c80a7
5 changed files with 356 additions and 0 deletions
  1. 4 0
      Makefile.am
  2. 17 0
      configure.ac
  3. 284 0
      driver-bf1.c
  4. 42 0
      driver-bf1.h
  5. 9 0
      miner.c

+ 4 - 0
Makefile.am

@@ -134,6 +134,10 @@ bitforce_firmware_flash_SOURCES = bitforce-firmware-flash.c
 endif
 endif
 endif
 endif
 
 
+if HAS_BF1
+bfgminer_SOURCES += driver-bf1.c
+endif
+
 if HAS_ICARUS
 if HAS_ICARUS
 bfgminer_SOURCES += driver-icarus.c icarus-common.h
 bfgminer_SOURCES += driver-icarus.c icarus-common.h
 bfgminer_SOURCES += driver-cairnsmore.c
 bfgminer_SOURCES += driver-cairnsmore.c

+ 17 - 0
configure.ac

@@ -293,6 +293,17 @@ else
 	adl="no"
 	adl="no"
 fi
 fi
 
 
+################################################################################
+AC_ARG_ENABLE([bf1],
+	[AC_HELP_STRING([--disable-bf1],[Compile support for Bitfury BF1 (default enabled)])],
+	[bf1=$enableval],
+	[bf1=yes]
+	)
+if test "x$bf1" = xyes; then
+	AC_DEFINE([USE_BF1], [1], [Defined to 1 if Bitfury BF1 support is wanted])
+fi
+AM_CONDITIONAL([HAS_BF1], [test x$bf11 = xyes])
+
 AC_ARG_ENABLE([bitforce],
 AC_ARG_ENABLE([bitforce],
 	[AC_HELP_STRING([--disable-bitforce],[Compile support for BitForce (default enabled)])],
 	[AC_HELP_STRING([--disable-bitforce],[Compile support for BitForce (default enabled)])],
 	[bitforce=$enableval],
 	[bitforce=$enableval],
@@ -894,6 +905,12 @@ else
 	echo "  Avalon.ASICs.........: Disabled"
 	echo "  Avalon.ASICs.........: Disabled"
 fi
 fi
 
 
+if test "x$bf1" = xyes; then
+	echo "  Bitfury BF1.ASICs....: Enabled"
+else
+	echo "  Bitfury BF1.ASICs....: Disabled"
+fi
+
 if test "x$bitforce" = xyes; then
 if test "x$bitforce" = xyes; then
 	echo "  BitForce.devices.....: Enabled"
 	echo "  BitForce.devices.....: Enabled"
 else
 else

+ 284 - 0
driver-bf1.c

@@ -0,0 +1,284 @@
+/*
+ * Copyright 2013 Andreas Auer
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.  See COPYING for more details.
+ */
+
+/*
+ * MiniMiner One with Avalon ASIC
+ */
+
+#include "config.h"
+#include "miner.h"
+#include "fpgautils.h"
+#include "logging.h"
+
+#include "deviceapi.h"
+#include "sha2.h"
+
+#include "driver-bf1.h"
+
+#include <stdio.h>
+
+struct device_drv bf1_drv;
+
+//------------------------------------------------------------------------------
+static bool bf1_checkNonce(struct cgpu_info *cgpu,
+                            struct work *work,
+                            int nonce)
+{
+	uint32_t *data32 = (uint32_t *)(work->data);
+	unsigned char swap[80];
+	uint32_t *swap32 = (uint32_t *)swap;
+	unsigned char hash1[32];
+	unsigned char hash2[32];
+	uint32_t *hash2_32 = (uint32_t *)hash2;
+
+	swap32[76/4] = htobe32(nonce);
+
+	swap32yes(swap32, data32, 76 / 4);
+
+	sha2(swap, 80, hash1);
+	sha2(hash1, 32, hash2);
+
+	if(hash2_32[7] == 0)
+		return true;
+
+	return false;
+}
+
+
+//------------------------------------------------------------------------------
+static bool bf1_detect_custom(const char *devpath, struct device_drv *api, struct BF1Info *info)
+{
+	int fd = serial_open(devpath, info->baud, 1, true);
+
+	if(fd < 0)
+	{
+		return false;
+	}
+
+	char buf[sizeof(struct BF1Identity)+1];
+	int len;
+
+	write(fd, "I", 1);
+	len = serial_read(fd, buf, sizeof(buf));
+	if(len != sizeof(buf))
+	{
+		serial_close(fd);
+		return false;
+	}
+
+	struct BF1Identity *id = (struct BF1Identity *)&buf[1];
+	info->id = *id;
+	applog(LOG_DEBUG, "%d, %s %08x", info->id.version, info->id.product, info->id.serial);
+
+	char buf_state[sizeof(struct BF1State)+1];
+	write(fd, "R", 1);
+	len = serial_read(fd, buf, sizeof(buf_state));
+	serial_close(fd);
+
+	if(len != sizeof(buf_state))
+	{
+		return false;
+	}
+
+	serial_close(fd);
+
+
+	if(serial_claim(devpath, api))
+	{
+		const char *claimedby = serial_claim(devpath, api)->dname;
+		applog(LOG_DEBUG, "Bitfury BF1 device %s already claimed by other driver: %s", devpath, claimedby);
+		return false;
+	}
+
+	/* We have a real MiniMiner ONE! */
+	struct cgpu_info *bf1;
+	bf1 = calloc(1, sizeof(struct cgpu_info));
+	bf1->drv = api;
+	bf1->device_path = strdup(devpath);
+	bf1->device_fd = -1;
+	bf1->threads = 1;
+	add_cgpu(bf1);
+
+	applog(LOG_INFO, "Found %"PRIpreprv" at %s", bf1->proc_repr, devpath);
+
+	applog(LOG_DEBUG, "%"PRIpreprv": Init: baud=%d",
+		bf1->proc_repr, info->baud);
+
+	bf1->device_data = info;
+
+	return true;
+}
+
+//------------------------------------------------------------------------------
+static bool bf1_detect_one(const char *devpath)
+{
+	struct BF1Info *info = calloc(1, sizeof(struct BF1Info));
+	if (unlikely(!info))
+		quit(1, "Failed to malloc bf1Info");
+
+	info->baud = BF1_BAUD;
+
+	if (!bf1_detect_custom(devpath, &bf1_drv, info))
+	{
+		free(info);
+		return false;
+	}
+	return true;
+}
+
+//------------------------------------------------------------------------------
+static void bf1_detect()
+{
+	applog(LOG_WARNING, "Searching for Bitfury BF1 devices");
+	serial_detect(&bf1_drv, bf1_detect_one);
+}
+
+//------------------------------------------------------------------------------
+static bool bf1_init(struct thr_info *thr)
+{
+	applog(LOG_INFO, "Bitfury BF1 init");
+
+	struct cgpu_info *bf1 = thr->cgpu;
+	struct BF1Info *info = (struct BF1Info *)bf1->device_data;
+
+	int fd = serial_open(bf1->device_path, info->baud, 1, true);
+	if (unlikely(-1 == fd))
+	{
+		applog(LOG_ERR, "Failed to open Bitfury BF1 on %s", bf1->device_path);
+		return false;
+	}
+
+	bf1->device_fd = fd;
+	//notifier_init(thr->work_restart_notifier);
+
+	applog(LOG_INFO, "Opened Bitfury BF1 on %s", bf1->device_path);
+
+	return true;
+}
+
+//------------------------------------------------------------------------------
+static int64_t bf1_scanwork(struct thr_info *thr)
+{
+	struct cgpu_info *board = thr->cgpu;
+	struct BF1Info *info = (struct BF1Info *)board->device_data;
+
+	struct BF1HashData hash_data;
+	uint32_t hashes = 0;
+
+	if(!info->work)
+	{
+		info->work = get_queued(board);
+		if(info->work == NULL)
+		{
+			return 0;
+		}
+	}
+
+	uint8_t sendbuf[45];
+	sendbuf[0] = 'W';
+	memcpy(sendbuf + 1, work->midstate, 32);
+	memcpy(sendbuf + 33, work->data + 64, 12);
+	write(board->device_fd, sendbuf, sizeof(sendbuf));
+
+	applog(LOG_DEBUG, "%"PRIpreprv": sent hashdata", board->proc_repr);
+
+	char rxbuffer[1024];
+	int len;
+	len = serial_read(board->device_fd, rxbuffer, sizeof(rxbuffer));
+	for(int i=0; i<len; i+=7)
+	{
+		applog(LOG_INFO, "Cmd: %c State: %c Valid: %d Nonce: %08X", rxbuffer[0], rxbuffer[1], rxbuffer[2], *((uint32_t *)&rxbuffer[3]));
+		hashes = 0xFFFFFFFFUL;
+	}
+
+	return hashes;
+/*
+
+	bool overflow = false;
+	int count = 0;
+	uint32_t nonce_count = 0;
+
+	uint8_t buffer[128];
+	while (!(overflow || thr->work_restart))
+	{
+		if (!restart_wait(thr, 250))
+		{
+			applog(LOG_DEBUG, "%"PRIpreprv": New work detected", board->proc_repr);
+			break;
+		}
+
+		int len = serial_read(board->device_fd, buffer, sizeof(struct bf1State)+1);
+		if(len == (sizeof(struct bf1State)+1))
+		{
+			struct bf1State *state = (struct bf1State *)(buffer+1);
+			applog(LOG_DEBUG, "State: %c, %d, %08x", state->state, state->nonce_valid, state->nonce);
+
+			if(state->nonce_valid == 1)
+			{
+				nonce_count = state->nonce;
+				if(bf1_checkNonce(board, work, state->nonce))
+				{
+					applog(LOG_INFO, "Golden nonce found: %08X", state->nonce);
+					submit_nonce(thr, work, state->nonce);
+				}
+				break;
+			}
+			else if(state->state == 'R')
+			{
+				nonce_count = 0xFFFFFFFFUL;
+				break;
+			}
+		}
+
+		if (thr->work_restart)
+		{
+			applog(LOG_DEBUG, "%"PRIpreprv": New work detected", board->proc_repr);
+			break;
+		}
+	}
+
+	work->blk.nonce = 0xffffffff;
+	return nonce_count;
+*/
+}
+
+//------------------------------------------------------------------------------
+static void bf1_statline_before(char *buf, struct cgpu_info *cgpu)
+{
+	char before[] = "                    ";
+	if(cgpu->device_data)
+	{
+		struct BF1Info *info = (struct BF1Info *)cgpu->device_data;
+
+		int len = strlen(info->id.product);
+		memcpy(before, info->id.product, len);
+
+		sprintf(before + len + 1, "%08X", info->id.serial);
+	}
+	tailsprintf(buf, "%s | ", &before[0]);
+}
+
+//------------------------------------------------------------------------------
+static void bf1_shutdown(struct thr_info *thr)
+{
+	struct cgpu_info *cgpu = thr->cgpu;
+
+	serial_close(cgpu->device_fd);
+}
+
+//------------------------------------------------------------------------------
+struct device_drv bf1_drv = {
+	.dname = "Bitfury BF1",
+	.name = "BF1",
+	.drv_detect = bf1_detect,
+	.get_statline_before = bf1_statline_before,
+	.scanwork = bf1_scanwork,
+	.thread_init = bf1_init,
+	.thread_shutdown = bf1_shutdown,
+};

+ 42 - 0
driver-bf1.h

@@ -0,0 +1,42 @@
+/*
+ * driver-s6lx75.h
+ *
+ *  Created on: 09.06.2013
+ *      Author: andreas
+ */
+
+#ifndef DRIVER_BF1_H_
+#define DRIVER_BF1_H_
+
+#define BF1_BAUD	115200
+
+struct BF1Identity
+{
+	uint8_t version;
+	char    product[8];
+	uint32_t serial;
+} __attribute__((packed));
+
+struct BF1State
+{
+    uint8_t state;
+    uint8_t nonce_valid;
+    uint32_t nonce;
+} __attribute__((packed));
+
+struct BF1HashData
+{
+	uint32_t golden_nonce;
+	uint32_t nonce;
+};
+
+struct BF1Info
+{
+	uint32_t baud;
+
+	struct BF1Identity id;
+
+	struct work *work;
+};
+
+#endif /* DRIVER_S6LX75_H_ */

+ 9 - 0
miner.c

@@ -8383,6 +8383,10 @@ struct device_drv cpu_drv = {
 extern struct device_drv bitforce_drv;
 extern struct device_drv bitforce_drv;
 #endif
 #endif
 
 
+#ifdef USE_BF1
+extern struct device_drv bf1_drv;
+#endif
+
 #ifdef USE_ICARUS
 #ifdef USE_ICARUS
 extern struct device_drv cairnsmore_drv;
 extern struct device_drv cairnsmore_drv;
 extern struct device_drv icarus_drv;
 extern struct device_drv icarus_drv;
@@ -8755,6 +8759,11 @@ int main(int argc, char *argv[])
 		bitforce_drv.drv_detect();
 		bitforce_drv.drv_detect();
 #endif
 #endif
 
 
+#ifdef USE_BF1
+	if (!opt_scrypt)
+		bf1_drv.drv_detect();
+#endif
+
 #ifdef USE_MODMINER
 #ifdef USE_MODMINER
 	if (!opt_scrypt)
 	if (!opt_scrypt)
 		modminer_drv.drv_detect();
 		modminer_drv.drv_detect();