Browse Source

Add in first draft for a serialised work model sending/receiving data for BF1 devices.

nfactor-troky
Con Kolivas 11 years ago
parent
commit
759e82bb98
  1. 17
      cgminer.c
  2. 149
      driver-bitfury.c
  3. 3
      driver-bitfury.h
  4. 1
      miner.h
  5. 2
      usbutils.c

17
cgminer.c

@ -6016,6 +6016,23 @@ void inc_hw_errors(struct thr_info *thr)
thr->cgpu->drv->hw_error(thr); thr->cgpu->drv->hw_error(thr);
} }
bool test_nonce(struct work *work, uint32_t nonce)
{
uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12);
unsigned char hash2[32];
uint32_t *hash2_32 = (uint32_t *)hash2;
uint32_t diff1targ;
*work_nonce = htole32(nonce);
/* Do one last check before attempting to submit the work */
rebuild_hash(work);
flip32(hash2_32, work->hash);
diff1targ = opt_scrypt ? 0x0000ffffUL : 0;
return (be32toh(hash2_32[7] <= diff1targ));
}
/* Returns true if nonce for work was a valid share */ /* Returns true if nonce for work was a valid share */
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
{ {

149
driver-bitfury.c

@ -11,6 +11,7 @@
#include "miner.h" #include "miner.h"
#include "driver-bitfury.h" #include "driver-bitfury.h"
#include "sha2.h"
struct device_drv bitfury_drv; struct device_drv bitfury_drv;
@ -100,7 +101,13 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device
bitfury_identify(bitfury); bitfury_identify(bitfury);
bitfury_empty_buffer(bitfury); bitfury_empty_buffer(bitfury);
//return true;
if (!add_cgpu(bitfury))
goto out_close;
update_usb_stats(bitfury);
applog(LOG_INFO, "%s%d: Found at %s",
bitfury->drv->name, bitfury->device_id, bitfury->device_path);
return true;
out_close: out_close:
bitfury_close(bitfury); bitfury_close(bitfury);
out: out:
@ -114,7 +121,7 @@ static void bitfury_detect(void)
static bool bitfury_prepare(struct thr_info __maybe_unused *thr) static bool bitfury_prepare(struct thr_info __maybe_unused *thr)
{ {
return false; return true;
} }
static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury) static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury)
@ -122,9 +129,137 @@ static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury)
return true; return true;
} }
static int64_t bitfury_scanhash(struct thr_info __maybe_unused *thr) static bool rehash(unsigned char *midstate, unsigned m7, unsigned ntime, unsigned nbits, unsigned nnonce)
{
uint8_t in[16];
uint32_t *in32 = (uint32_t *)in;
uint32_t *mid32 = (uint32_t *)midstate;
uint32_t out32[8];
uint8_t *out = (uint8_t *) out32;
sha256_ctx ctx;
memset( &ctx, 0, sizeof(sha256_ctx));
memcpy(ctx.h, mid32, 8*4);
ctx.tot_len = 64;
nnonce = bswap_32(nnonce);
in32[0] = bswap_32(m7);
in32[1] = bswap_32(ntime);
in32[2] = bswap_32(nbits);
in32[3] = nnonce;
sha256_update(&ctx, in, 16);
sha256_final(&ctx, out);
sha256(out, 32, out);
if (out32[7] == 0)
return true;
return false;
}
static uint32_t decnonce(uint32_t in)
{
uint32_t out;
/* First part load */
out = (in & 0xFF) << 24; in >>= 8;
/* Byte reversal */
in = (((in & 0xaaaaaaaa) >> 1) | ((in & 0x55555555) << 1));
in = (((in & 0xcccccccc) >> 2) | ((in & 0x33333333) << 2));
in = (((in & 0xf0f0f0f0) >> 4) | ((in & 0x0f0f0f0f) << 4));
out |= (in >> 2)&0x3FFFFF;
/* Extraction */
if (in & 1) out |= (1 << 23);
if (in & 2) out |= (1 << 22);
out -= 0x800004;
return out;
}
static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32_t nonce)
{
uint32_t nonceoff;
if (test_nonce(work, nonce)) {
submit_nonce(thr, work, nonce);
return true;
}
nonceoff = nonce - 0x400000;
if (test_nonce(work, nonceoff)) {
submit_nonce(thr, work, nonceoff);
return true;
}
nonceoff = nonce - 0x800000;
if (test_nonce(work, nonceoff)) {
submit_nonce(thr, work, nonceoff);
return true;
}
nonceoff = nonce + 0x2800000;
if (test_nonce(work, nonceoff)) {
submit_nonce(thr, work, nonceoff);
return true;
}
nonceoff = nonce + 0x2C800000;
if (test_nonce(work, nonceoff)) {
submit_nonce(thr, work, nonceoff);
return true;
}
nonceoff = nonce + 0x400000;
if (test_nonce(work, nonceoff)) {
submit_nonce(thr, work, nonceoff);
return true;
}
return false;
}
static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
int64_t __maybe_unused max_nonce)
{ {
return 0; struct cgpu_info *bitfury = thr->cgpu;
struct bitfury_info *info = bitfury->device_data;
char sendbuf[45], buf[512];
int64_t hashes = 0;
int amount, i, tot;
sendbuf[0] = 'W';
memcpy(sendbuf + 1, work->midstate, 32);
memcpy(sendbuf + 33, work->data + 64, 12);
usb_write(bitfury, sendbuf, 45, &amount, C_PING);
usb_read(bitfury, buf, 7, &amount, C_PING);
if (unlikely(!info->prevwork)) {
info->prevwork = copy_work(work);
return 0;
}
usb_read_once_timeout(bitfury, buf, 7, &amount, 2000, C_PING);
tot = amount;
while (amount) {
usb_read_once_timeout(bitfury, buf + tot, 512, &amount, 10, C_PING);
tot += amount;
}
for (i = 0; i < tot; i += 7) {
uint32_t nonce;
/* Ignore state & switched data in results for now. */
memcpy(&nonce, buf + i + 3, 4);
nonce = decnonce(nonce);
if (bitfury_checkresults(thr, work, nonce)) {
hashes += 0xffffffff;
continue;
}
if (bitfury_checkresults(thr, info->prevwork, nonce))
hashes += 0xffffffff;
}
free_work(info->prevwork);
info->prevwork = copy_work(work);
work->blk.nonce = 0xffffffff;
return hashes;
} }
static void bitfury_flush_work(struct cgpu_info __maybe_unused *bitfury) static void bitfury_flush_work(struct cgpu_info __maybe_unused *bitfury)
@ -158,12 +293,10 @@ struct device_drv bitfury_drv = {
.dname = "bitfury", .dname = "bitfury",
.name = "BFO", .name = "BFO",
.drv_detect = bitfury_detect, .drv_detect = bitfury_detect,
.thread_prepare = bitfury_prepare, .scanhash = bitfury_scanhash,
.hash_work = hash_queued_work,
.queue_full = bitfury_fill,
.scanwork = bitfury_scanhash,
.flush_work = bitfury_flush_work, .flush_work = bitfury_flush_work,
.get_api_stats = bitfury_api_stats, .get_api_stats = bitfury_api_stats,
.thread_prepare = bitfury_prepare,
.get_statline_before = get_bitfury_statline_before, .get_statline_before = get_bitfury_statline_before,
.reinit_device = bitfury_init, .reinit_device = bitfury_init,
.thread_shutdown = bitfury_shutdown, .thread_shutdown = bitfury_shutdown,

3
driver-bitfury.h

@ -10,12 +10,15 @@
#ifndef BITFURY_H #ifndef BITFURY_H
#define BITFURY_H #define BITFURY_H
#include "miner.h"
#include "usbutils.h" #include "usbutils.h"
struct bitfury_info { struct bitfury_info {
uint8_t version; uint8_t version;
char product[8]; char product[8];
uint32_t serial; uint32_t serial;
struct work *prevwork;
char readbuf[512];
}; };
#endif /* BITFURY_H */ #endif /* BITFURY_H */

1
miner.h

@ -1356,6 +1356,7 @@ struct modminer_fpga_state {
extern void get_datestamp(char *, size_t, struct timeval *); extern void get_datestamp(char *, size_t, struct timeval *);
extern void inc_hw_errors(struct thr_info *thr); extern void inc_hw_errors(struct thr_info *thr);
extern bool test_nonce(struct work *work, uint32_t nonce);
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
extern struct work *get_queued(struct cgpu_info *cgpu); extern struct work *get_queued(struct cgpu_info *cgpu);
extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);

2
usbutils.c

@ -84,7 +84,7 @@
#else #else
#define BFLSC_TIMEOUT_MS 300 #define BFLSC_TIMEOUT_MS 300
#define BITFORCE_TIMEOUT_MS 200 #define BITFORCE_TIMEOUT_MS 200
#define BITFURY_TIMEOUT_MS 200 #define BITFURY_TIMEOUT_MS 100
#define MODMINER_TIMEOUT_MS 100 #define MODMINER_TIMEOUT_MS 100
#define AVALON_TIMEOUT_MS 200 #define AVALON_TIMEOUT_MS 200
#define ICARUS_TIMEOUT_MS 200 #define ICARUS_TIMEOUT_MS 200

Loading…
Cancel
Save