123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- /*
- * Copyright 2014 Con Kolivas
- * Copyright 2013 Andrew Smith
- * Copyright 2013 bitfury
- *
- * 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.
- */
- #include "miner.h"
- #include "driver-bitfury.h"
- #include "libbitfury.h"
- #include "sha2.h"
- void ms3steps(uint32_t *p)
- {
- uint32_t a, b, c, d, e, f, g, h, new_e, new_a;
- int i;
- a = p[0];
- b = p[1];
- c = p[2];
- d = p[3];
- e = p[4];
- f = p[5];
- g = p[6];
- h = p[7];
- for (i = 0; i < 3; i++) {
- new_e = p[i+16] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) + d;
- new_a = p[i+16] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) +
- SHA256_F1(a) + MAJ(a,b,c);
- d = c;
- c = b;
- b = a;
- a = new_a;
- h = g;
- g = f;
- f = e;
- e = new_e;
- }
- p[15] = a;
- p[14] = b;
- p[13] = c;
- p[12] = d;
- p[11] = e;
- p[10] = f;
- p[9] = g;
- p[8] = h;
- }
- 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;
- }
- /* Test vectors to calculate (using address-translated loads) */
- static unsigned int atrvec[] = {
- 0xb0e72d8e, 0x1dc5b862, 0xe9e7c4a6, 0x3050f1f5, 0x8a1a6b7e, 0x7ec384e8, 0x42c1c3fc, 0x8ed158a1, /* MIDSTATE */
- 0,0,0,0,0,0,0,0,
- 0x8a0bb7b7, 0x33af304f, 0x0b290c1a, 0xf0c4e61f, /* WDATA: hashMerleRoot[7], nTime, nBits, nNonce */
- };
- static bool atrvec_set;
- void bitfury_work_to_payload(struct bitfury_payload *p, struct work *work)
- {
- memcpy(p->midstate, work->midstate, 32);
- p->m7 = *(unsigned int *)(work->data + 64);
- p->ntime = *(unsigned int *)(work->data + 68);
- p->nbits = *(unsigned int *)(work->data + 72);
- applog(LOG_INFO, "INFO nonc: %08x bitfury_scanHash MS0: %08x, ", p->nnonce,
- ((unsigned int *)work->midstate)[0]);
- applog(LOG_INFO, "INFO merkle[7]: %08x, ntime: %08x, nbits: %08x", p->m7,
- p->ntime, p->nbits);
- }
- /* Configuration registers - control oscillators and such stuff. PROGRAMMED when
- * magic number matches, UNPROGRAMMED (default) otherwise */
- void spi_config_reg(struct bitfury_info *info, int cfgreg, int ena)
- {
- static const uint8_t enaconf[4] = { 0xc1, 0x6a, 0x59, 0xe3 };
- static const uint8_t disconf[4] = { 0, 0, 0, 0 };
- if (ena)
- spi_add_data(info, 0x7000 + cfgreg * 32, enaconf, 4);
- else
- spi_add_data(info, 0x7000 + cfgreg * 32, disconf, 4);
- }
- void spi_set_freq(struct bitfury_info *info)
- {
- uint64_t freq;
- const uint8_t *osc6 = (unsigned char *)&freq;
- freq = (1ULL << info->osc6_bits) - 1ULL;
- spi_add_data(info, 0x6000, osc6, 8); /* Program internal on-die slow oscillator frequency */
- }
- #define FIRST_BASE 61
- #define SECOND_BASE 4
- void spi_send_conf(struct bitfury_info *info)
- {
- const int8_t nfu_counters[16] = { 64, 64, SECOND_BASE, SECOND_BASE+4, SECOND_BASE+2,
- SECOND_BASE+2+16, SECOND_BASE, SECOND_BASE+1, (FIRST_BASE)%65, (FIRST_BASE+1)%65,
- (FIRST_BASE+3)%65, (FIRST_BASE+3+16)%65, (FIRST_BASE+4)%65, (FIRST_BASE+4+4)%65,
- (FIRST_BASE+3+3)%65, (FIRST_BASE+3+1+3)%65 };
- int i;
- for (i = 7; i <= 11; i++)
- spi_config_reg(info, i, 0);
- spi_config_reg(info, 6, 1); /* disable OUTSLK */
- spi_config_reg(info, 4, 1); /* Enable slow oscillator */
- for (i = 1; i <= 3; ++i)
- spi_config_reg(info, i, 0);
- /* Program counters correctly for rounds processing, here it should
- * start consuming power */
- spi_add_data(info, 0x0100, nfu_counters, 16);
- }
- void spi_send_init(struct bitfury_info *info)
- {
- /* Prepare internal buffers */
- /* PREPARE BUFFERS (INITIAL PROGRAMMING) */
- unsigned int w[16];
- if (!atrvec_set) {
- atrvec_set = true;
- ms3steps(atrvec);
- }
- memset(w, 0, sizeof(w));
- w[3] = 0xffffffff;
- w[4] = 0x80000000;
- w[15] = 0x00000280;
- spi_add_data(info, 0x1000, w, 16 * 4);
- spi_add_data(info, 0x1400, w, 8 * 4);
- memset(w, 0, sizeof(w));
- w[0] = 0x80000000;
- w[7] = 0x100;
- spi_add_data(info, 0x1900, w, 8 * 4); /* Prepare MS and W buffers! */
- spi_add_data(info, 0x3000, atrvec, 19 * 4);
- }
- void spi_clear_buf(struct bitfury_info *info)
- {
- info->spibufsz = 0;
- }
- void spi_add_buf(struct bitfury_info *info, const void *buf, const int sz)
- {
- if (unlikely(info->spibufsz + sz > SPIBUF_SIZE)) {
- applog(LOG_WARNING, "SPI bufsize overflow!");
- return;
- }
- memcpy(&info->spibuf[info->spibufsz], buf, sz);
- info->spibufsz += sz;
- }
- void spi_add_break(struct bitfury_info *info)
- {
- spi_add_buf(info, "\x4", 1);
- }
- void spi_add_fasync(struct bitfury_info *info, int n)
- {
- int i;
- for (i = 0; i < n; i++)
- spi_add_buf(info, "\x5", 1);
- }
- static void spi_add_buf_reverse(struct bitfury_info *info, const char *buf, const int sz)
- {
- int i;
- for (i = 0; i < sz; i++) { // Reverse bit order in each byte!
- unsigned char p = buf[i];
- p = ((p & 0xaa) >> 1) | ((p & 0x55) << 1);
- p = ((p & 0xcc) >> 2) | ((p & 0x33) << 2);
- p = ((p & 0xf0) >> 4) | ((p & 0x0f) << 4);
- info->spibuf[info->spibufsz + i] = p;
- }
- info->spibufsz += sz;
- }
- void spi_add_data(struct bitfury_info *info, uint16_t addr, const void *buf, int len)
- {
- unsigned char otmp[3];
- if (len < 4 || len > 128) {
- applog(LOG_WARNING, "Can't add SPI data size %d", len);
- return;
- }
- len /= 4; /* Strip */
- otmp[0] = (len - 1) | 0xE0;
- otmp[1] = (addr >> 8) & 0xFF;
- otmp[2] = addr & 0xFF;
- spi_add_buf(info, otmp, 3);
- len *= 4;
- spi_add_buf_reverse(info, buf, len);
- }
- // Bit-banging reset... Each 3 reset cycles reset first chip in chain
- bool spi_reset(struct cgpu_info *bitfury, struct bitfury_info *info)
- {
- struct mcp_settings *mcp = &info->mcp;
- int r;
- // SCK_OVRRIDE
- mcp->value.pin[NFU_PIN_SCK_OVR] = MCP2210_GPIO_PIN_HIGH;
- mcp->direction.pin[NFU_PIN_SCK_OVR] = MCP2210_GPIO_OUTPUT;
- mcp->designation.pin[NFU_PIN_SCK_OVR] = MCP2210_PIN_GPIO;
- if (!mcp2210_set_gpio_settings(bitfury, mcp))
- return false;
- for (r = 0; r < 16; ++r) {
- char buf[1] = {0x81}; // will send this waveform: - _ _ _ _ _ _ -
- unsigned int length = 1;
- if (!mcp2210_spi_transfer(bitfury, &info->mcp, buf, &length))
- return false;
- }
- // Deactivate override
- mcp->direction.pin[NFU_PIN_SCK_OVR] = MCP2210_GPIO_INPUT;
- if (!mcp2210_set_gpio_settings(bitfury, mcp))
- return false;
- return true;
- }
- bool mcp_spi_txrx(struct cgpu_info *bitfury, struct bitfury_info *info)
- {
- unsigned int length, sendrcv;
- int offset = 0;
- length = info->spibufsz;
- applog(LOG_DEBUG, "%s %d: SPI sending %u bytes total", bitfury->drv->name,
- bitfury->device_id, length);
- while (length > MCP2210_TRANSFER_MAX) {
- sendrcv = MCP2210_TRANSFER_MAX;
- if (!mcp2210_spi_transfer(bitfury, &info->mcp, info->spibuf + offset, &sendrcv))
- return false;
- if (sendrcv != MCP2210_TRANSFER_MAX) {
- applog(LOG_DEBUG, "%s %d: Send/Receive size mismatch sent %d received %d",
- bitfury->drv->name, bitfury->device_id, MCP2210_TRANSFER_MAX, sendrcv);
- }
- length -= MCP2210_TRANSFER_MAX;
- offset += MCP2210_TRANSFER_MAX;
- }
- sendrcv = length;
- if (!mcp2210_spi_transfer(bitfury, &info->mcp, info->spibuf + offset, &sendrcv))
- return false;
- if (sendrcv != length) {
- applog(LOG_WARNING, "%s %d: Send/Receive size mismatch sent %d received %d",
- bitfury->drv->name, bitfury->device_id, length, sendrcv);
- return false;
- }
- return true;
- }
- #define READ_WRITE_BYTES_SPI0 0x31
- bool ftdi_spi_txrx(struct cgpu_info *bitfury, struct bitfury_info *info)
- {
- int err, amount, len;
- uint16_t length;
- char buf[1024];
- len = info->spibufsz;
- length = info->spibufsz - 1; //FTDI length is shifted by one 0x0000 = one byte
- buf[0] = READ_WRITE_BYTES_SPI0;
- buf[1] = length & 0x00FF;
- buf[2] = (length & 0xFF00) >> 8;
- memcpy(&buf[3], info->spibuf, info->spibufsz);
- info->spibufsz += 3;
- err = usb_write(bitfury, buf, info->spibufsz, &amount, C_BXM_SPITX);
- if (err || amount != (int)info->spibufsz) {
- applog(LOG_ERR, "%s %d: SPI TX error %d, sent %d of %d", bitfury->drv->name,
- bitfury->device_id, err, amount, info->spibufsz);
- return false;
- }
- info->spibufsz = len;
- /* We shouldn't even get a timeout error on reads in spi mode */
- err = usb_read(bitfury, info->spibuf, len, &amount, C_BXM_SPIRX);
- if (err || amount != len) {
- applog(LOG_ERR, "%s %d: SPI RX error %d, read %d of %d", bitfury->drv->name,
- bitfury->device_id, err, amount, info->spibufsz);
- return false;
- }
- amount = usb_buffer_size(bitfury);
- if (amount) {
- applog(LOG_ERR, "%s %d: SPI RX Extra read buffer size %d", bitfury->drv->name,
- bitfury->device_id, amount);
- usb_buffer_clear(bitfury);
- return false;
- }
- return true;
- }
- #define BT_OFFSETS 3
- bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32_t nonce)
- {
- const uint32_t bf_offsets[] = {-0x800000, 0, -0x400000};
- int i;
- for (i = 0; i < BT_OFFSETS; i++) {
- uint32_t noffset = nonce + bf_offsets[i];
- if (test_nonce(work, noffset)) {
- submit_tested_work(thr, work);
- return true;
- }
- }
- return false;
- }
- /* Currently really only supports 2 chips, so chip_n can only be 0 or 1 */
- bool libbitfury_sendHashData(struct thr_info *thr, struct cgpu_info *bitfury,
- struct bitfury_info *info, int chip_n)
- {
- unsigned newbuf[17];
- unsigned *oldbuf = &info->oldbuf[17 * chip_n];
- struct bitfury_payload *p = &info->payload[chip_n];
- unsigned int localvec[20];
- /* Programming next value */
- memcpy(localvec, p, 20 * 4);
- ms3steps(localvec);
- spi_clear_buf(info);
- spi_add_break(info);
- spi_add_fasync(info, chip_n);
- spi_add_data(info, 0x3000, (void*)localvec, 19 * 4);
- if (!info->spi_txrx(bitfury, info))
- return false;
- memcpy(newbuf, info->spibuf + 4 + chip_n, 17 * 4);
- info->job_switched[chip_n] = newbuf[16] != oldbuf[16];
- if (likely(info->second_run[chip_n])) {
- if (info->job_switched[chip_n]) {
- int i;
- for (i = 0; i < 16; i++) {
- if (oldbuf[i] != newbuf[i] && info->owork[chip_n]) {
- uint32_t nonce; //possible nonce
- nonce = decnonce(newbuf[i]);
- if (bitfury_checkresults(thr, info->owork[chip_n], nonce)) {
- info->submits[chip_n]++;
- info->nonces++;
- }
- }
- }
- memcpy(oldbuf, newbuf, 17 * 4);
- }
- } else
- info->second_run[chip_n] = true;
- cgsleep_ms(BITFURY_REFRESH_DELAY);
- return true;
- }
|