123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230 |
- #include <arpa/inet.h>
- #include "miner.h"
- #include "bf16-bitfury16.h"
- #include "bf16-communication.h"
- #include "bf16-ctrldevice.h"
- #include "math.h"
- #include "sha2.h"
- #include "driver-bitfury16.h"
- //#define FLIP_BITS
- bf_cmd_description_t cmd_description[CHIP_CMD_NUM] = {
- {
- .cmd_code = CHIP_CMD_TASK_STATUS,
- .cmd_description = "CHIP_CMD_TASK_STATUS"
- },
- {
- .cmd_code = CHIP_CMD_TASK_WRITE,
- .cmd_description = "CHIP_CMD_TASK_WRITE"
- },
- {
- .cmd_code = CHIP_CMD_TASK_SWITCH,
- .cmd_description = "CHIP_CMD_TASK_SWITCH"
- },
- {
- .cmd_code = CHIP_CMD_READ_NONCE,
- .cmd_description = "CHIP_CMD_READ_NONCE"
- },
- {
- .cmd_code = CHIP_CMD_SET_CLOCK,
- .cmd_description = "CHIP_CMD_SET_CLOCK"
- },
- {
- .cmd_code = CHIP_CMD_TOGGLE,
- .cmd_description = "CHIP_CMD_TOGGLE"
- },
- {
- .cmd_code = CHIP_CMD_SET_MASK,
- .cmd_description = "CHIP_CMD_SET_MASK"
- },
- {
- .cmd_code = CHIP_CMD_CREATE_CHANNEL,
- .cmd_description = "CHIP_CMD_CREATE_CHANNEL"
- }
- };
- char* get_cmd_description(bf_cmd_code_t cmd_code)
- {
- uint8_t i;
- for (i = 0; i < CHIP_CMD_NUM; i++)
- if (cmd_description[i].cmd_code == cmd_code)
- return cmd_description[i].cmd_description;
- return NULL;
- }
- static void shift_bits(uint8_t* data, uint8_t size, uint8_t nbits)
- {
- uint8_t i;
- uint8_t bytes = nbits / 8;
- uint8_t bits = nbits % 8;
- for (i = 0; i < size; i++) {
- data[i] = (data[i + bytes] << bits);
- uint8_t minor = (data[i + bytes + 1] >> (8 - bits));
- data[i] |= minor;
- }
- }
- static uint8_t extra_bytes(uint8_t depth)
- {
- return (depth * 3) / 8 + 1;
- }
- static uint8_t analyze_rx_data(bf_command_t* command, bf_cmd_status_t* cmd_status, uint32_t* nonces)
- {
- uint8_t i;
- uint8_t res = 0;
- if (command->cmd_code & CHIP_CMD_READ_NONCE) {
- shift_bits(command->rx, 49 + 2 + extra_bytes(command->depth), command->depth * 3);
- command->status = command->rx[0];
- cmd_status->status = command->rx[0];
- command->checksum = command->rx[1];
- cmd_status->checksum_expected = command->checksum;
- if (nonces == NULL)
- return 1;
- uint32_t nonce = 0x00000000;
- /* fill nonces buffer */
- for (i = 0; i <= 48; i++) {
- if ((i % 4 == 0) && (i != 0)) {
- if ((nonce & 0x0fffffff) != 0x0fffffff)
- nonce ^= 0xaaaaaaaa;
- nonces[i/4 - 1] = nonce;
- if (i == 48)
- break;
- nonce = 0x00000000;
- }
- nonce |= (command->rx[i + 2] << 8*(4 - (i%4) - 1));
- }
- #if 0
- char data[128];
- memset(data, 0, sizeof(data));
- for (i = 0; i < 49 + 2 + extra_bytes(command->depth); i++)
- sprintf(data, "%s%02x", data, command->rx[i]);
- applog(LOG_DEBUG, "BF16: RX <- [%s]", data);
- #endif
- for (i = 0; i < 48; i ++)
- command->nonce_checksum += command->rx[i + 2];
- command->nonce_checksum += command->rx[1];
- cmd_status->nonce_checksum_expected = command->nonce_checksum;
- if (command->checksum != command->rx[1]) {
- command->checksum_error = true;
- cmd_status->checksum_error = true;
- cmd_status->checksum_received = command->rx[50];
- res = 1;
- #if 0
- applog(LOG_ERR, "Checksum mismatch: received [%02x] expected [%02x]", command->rx[1], 0x04);
- #endif
- } else {
- command->checksum_error = false;
- cmd_status->checksum_error = false;
- }
- if ((command->nonce_checksum != command->rx[50]) &&
- (command->nonce_checksum != command->rx[50] + 1)) {
- command->nonce_checksum_error = true;
- cmd_status->nonce_checksum_error = true;
- cmd_status->nonce_checksum_received = command->rx[50];
- res += 2;
- #if 0
- applog(LOG_ERR, "Nonce checksum mismatch: received [%02x] expected [%02x]", command->rx[50], checksum);
- #endif
- } else {
- command->nonce_checksum_error = false;
- cmd_status->nonce_checksum_error = false;
- }
- } else {
- shift_bits(command->rx, 2 + extra_bytes(command->depth), command->depth * 3);
- if (opt_bf16_test_chip != NULL) {
- char data[16];
- memset(data, 0, sizeof(data));
- for (i = 0; i < 2 + extra_bytes(command->depth); i++)
- sprintf(data, "%s%02x", data, command->rx[i]);
- applog(LOG_NOTICE, "BF16: RX <- [%s]", data);
- }
- command->status = command->rx[0];
- cmd_status->status = command->rx[0];
- uint8_t cmd_checksum = command->rx[1];
- cmd_status->checksum_expected = command->checksum;
- #if 0
- applog(LOG_DEBUG, "Command checksum: [%02x]", cmd_checksum);
- applog(LOG_DEBUG, "Command status: [%02x]", command->status);
- #endif
- if ((command->checksum != cmd_checksum) &&
- (command->checksum != cmd_checksum + 1)) {
- command->checksum_error = true;
- cmd_status->checksum_error = true;
- cmd_status->checksum_received = cmd_checksum;
- res = 1;
- if (opt_bf16_test_chip != NULL) {
- applog(LOG_ERR, "BF16: checksum mismatch: received [%02x] expected [%02x]",
- cmd_checksum, command->checksum);
- }
- } else {
- command->checksum_error = false;
- cmd_status->checksum_error = false;
- }
- }
- return res;
- }
- /* SPI BTC250 primitives */
- uint8_t create_channel(spi_channel_id_t spi_channel, uint8_t* channel_path, uint8_t channel_length)
- {
- int res = 0;
- uint8_t* channel_path_buff = cgcalloc(channel_length, sizeof(uint8_t));
- cg_memcpy(channel_path_buff, channel_path, channel_length);
- res = device_spi_transfer(spi_channel, channel_path_buff, channel_length);
- free(channel_path_buff);
- return res;
- }
- uint8_t destroy_channel(spi_channel_id_t spi_channel, uint8_t depth)
- {
- bf_command_t chip_command;
- bf_chip_address_t chip_address = { 0x00, 0x00, 0x0f };
- /* send command to 0x0f address */
- spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_TASK_SWITCH, 0, NULL);
- return spi_command_exec(spi_channel, &chip_command, NULL);
- }
- /* SPI BTC16 primitives */
- void spi_emit_reset(spi_channel_id_t spi_channel)
- {
- device_ctrl_transfer(spi_channel, 1, F_RST);
- uint8_t data[2] = { 0x00, 0x00 };
- device_spi_transfer(spi_channel, data, sizeof(data));
- device_ctrl_transfer(spi_channel, 0, F_RST);
- }
- uint8_t send_toggle(spi_channel_id_t spi_channel, uint8_t depth, bf_chip_address_t chip_address)
- {
- bf_command_t chip_command;
- uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 };
- spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_TOGGLE, 3, toggle);
- return spi_command_exec(spi_channel, &chip_command, NULL);
- }
- uint8_t set_clock(spi_channel_id_t spi_channel, uint8_t depth,
- bf_chip_address_t chip_address, uint8_t clock)
- {
- bf_command_t chip_command;
- uint8_t clock_buf[4];
- memset(clock_buf, 0, 4);
- gen_clock_data(clock, 1, clock_buf);
- spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_SET_CLOCK, 3, clock_buf);
- return spi_command_exec(spi_channel, &chip_command, NULL);
- }
- /* cmd buffer primitives */
- int8_t cmd_buffer_init(bf_cmd_buffer_t* cmd_buffer)
- {
- if (cmd_buffer == NULL)
- return -1;
- cmd_buffer->cmd_list = cgmalloc(sizeof(bf_list_t));
- cmd_buffer->cmd_list->head = NULL;
- cmd_buffer->cmd_list->tail = NULL;
- cmd_buffer->cmd_list->count = 0;
- cmd_buffer->tx_buffer = cgcalloc(CMD_BUFFER_LEN, sizeof(uint8_t));
- cmd_buffer->rx_buffer = cgcalloc(CMD_BUFFER_LEN, sizeof(uint8_t));
- memset(cmd_buffer->tx_buffer, 0, CMD_BUFFER_LEN);
- memset(cmd_buffer->rx_buffer, 0, CMD_BUFFER_LEN);
- cmd_buffer->free_bytes = CMD_BUFFER_LEN;
- cmd_buffer->tx_offset = 0;
- cmd_buffer->rx_offset = 0;
- cmd_buffer->status = EMPTY;
- return 0;
- }
- int8_t cmd_buffer_deinit(bf_cmd_buffer_t* cmd_buffer)
- {
- if (cmd_buffer == NULL)
- return -1;
- /* free cmd buffer */
- while (cmd_buffer->cmd_list->head != NULL) {
- bf_data_t* cdata = cmd_buffer->cmd_list->head;
- LIST_POP_HEAD(cmd_buffer->cmd_list);
- free(cdata->data);
- free(cdata);
- }
- free(cmd_buffer->cmd_list);
- /* free RX/TX buffer */
- free(cmd_buffer->tx_buffer);
- free(cmd_buffer->rx_buffer);
- cmd_buffer->free_bytes = CMD_BUFFER_LEN;
- cmd_buffer->tx_offset = 0;
- cmd_buffer->rx_offset = 0;
- cmd_buffer->status = EMPTY;
- return 0;
- }
- int8_t cmd_buffer_clear(bf_cmd_buffer_t* cmd_buffer)
- {
- if (cmd_buffer == NULL)
- return -1;
- /* release cmd buffer data memory */
- while (cmd_buffer->cmd_list->head != NULL) {
- bf_data_t* cdata = cmd_buffer->cmd_list->head;
- LIST_POP_HEAD(cmd_buffer->cmd_list);
- free(cdata->data);
- free(cdata);
- }
- cmd_buffer->cmd_list->count = 0;
- /* clear RX/TX buffer */
- memset(cmd_buffer->tx_buffer, 0, CMD_BUFFER_LEN);
- memset(cmd_buffer->rx_buffer, 0, CMD_BUFFER_LEN);
- cmd_buffer->free_bytes = CMD_BUFFER_LEN;
- cmd_buffer->tx_offset = 0;
- cmd_buffer->rx_offset = 0;
- cmd_buffer->status = EMPTY;
- return 0;
- }
- int8_t cmd_buffer_push(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
- const bf_chip_address_t chip_address, const bf_chip_address_t src_address,
- const bf_works_t work, const uint32_t id,
- const bf_cmd_code_t cmd_code, const uint8_t data_length, const uint8_t* tx)
- {
- uint8_t res = 0;
- if (cmd_buffer == NULL)
- return -1;
- if (cmd_buffer->status == EXECUTED)
- return -2;
- bf_command_t command;
- memset(&command, 0, sizeof(bf_command_t));
- uint8_t buff[192];
- memset(buff, 0, sizeof(buff));
- if (cmd_code != CHIP_CMD_CREATE_CHANNEL) {
- res = spi_command_init(&command, depth, chip_address, cmd_code, data_length, tx);
- if (res != 0)
- return res;
- }
- /* init structure */
- bf_data_t* cdata = cgmalloc(sizeof(bf_data_t));
- cdata->data = cgmalloc(sizeof(bf_cmd_t));
- cdata->next = NULL;
- cdata->prev = NULL;
- cg_memcpy(&CMD(cdata)->chip_address, &chip_address, sizeof(bf_chip_address_t));
- cg_memcpy(&CMD(cdata)->src_address, &src_address, sizeof(bf_chip_address_t));
- cg_memcpy(&CMD(cdata)->work, &work, sizeof(bf_works_t));
- CMD(cdata)->id = id;
- CMD(cdata)->depth = command.depth;
- CMD(cdata)->checksum = command.checksum;
- CMD(cdata)->cmd_code = cmd_code;
- if (CMD(cdata)->cmd_code & CHIP_CMD_READ_NONCE)
- CMD(cdata)->data_length = command.data_length + 49 + 2 + extra_bytes(command.depth);
- else if (CMD(cdata)->cmd_code == CHIP_CMD_CREATE_CHANNEL)
- CMD(cdata)->data_length = data_length;
- else
- CMD(cdata)->data_length = command.data_length + 2 + extra_bytes(command.depth);
- if (cmd_buffer->free_bytes < CMD(cdata)->data_length) {
- /* not enough TX/RX buffer space available */
- free(cdata->data);
- free(cdata);
- return -3;
- }
- /* init send buffer */
- if (cmd_code != CHIP_CMD_CREATE_CHANNEL) {
- cg_memcpy(buff, command.tx, command.data_length);
- cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, buff, CMD(cdata)->data_length);
- } else
- cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, tx, CMD(cdata)->data_length);
- #if 0
- uint16_t i;
- char data[384];
- memset(data, 0, sizeof(data));
- for (i = 0; i < command.data_length; i++)
- sprintf(data, "%s%02x", data, command.tx[i]);
- applog(LOG_DEBUG, "BF16: TX -> [%s]", data);
- #endif
- cmd_buffer->tx_offset += CMD(cdata)->data_length;
- cmd_buffer->free_bytes -= CMD(cdata)->data_length;
- /* add cmd to buffer */
- LIST_PUSH_TAIL(cmd_buffer->cmd_list, cdata);
- cmd_buffer->cmd_list->count++;
- return 0;
- }
- int8_t cmd_buffer_push_send_toggle(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
- const bf_chip_address_t chip_address)
- {
- bf_works_t work;
- uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 };
- return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
- work, 0, CHIP_CMD_TOGGLE, 3, toggle);
- }
- int8_t cmd_buffer_push_set_clock(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
- const bf_chip_address_t chip_address, uint8_t clock)
- {
- bf_works_t work;
- uint8_t clock_buf[4];
- memset(clock_buf, 0, 4);
- gen_clock_data(clock, 1, clock_buf);
- return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
- work, 0, CHIP_CMD_SET_CLOCK, 3, clock_buf);
- }
- int8_t cmd_buffer_push_set_mask(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
- const bf_chip_address_t chip_address, uint8_t mask)
- {
- uint8_t i;
- bf_works_t work;
- uint8_t noncemask[4];
- for (i = 0; i < 4; i++)
- noncemask[i] = (mask >> (8*(4 - i - 1))) & 0xff;
- return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
- work, 0, CHIP_CMD_SET_MASK, 3, noncemask);
- }
- int8_t cmd_buffer_push_create_channel(bf_cmd_buffer_t* cmd_buffer,
- uint8_t* channel_path, uint8_t channel_length)
- {
- bf_works_t work;
- bf_chip_address_t chip_address = { 0x00, 0x00, 0x00 };
- return cmd_buffer_push(cmd_buffer, 0, chip_address, chip_address,
- work, 0, CHIP_CMD_CREATE_CHANNEL, channel_length, channel_path);
- }
- int8_t cmd_buffer_push_destroy_channel(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth)
- {
- bf_works_t work;
- bf_chip_address_t chip_address = { 0x00, 0x00, 0x0f };
- return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
- work, 0, CHIP_CMD_TASK_SWITCH, 0, NULL);
- }
- bool match_nonce(uint32_t nonce, uint32_t mask, uint8_t nbits)
- {
- uint32_t fixed_mask = (uint32_t)(pow(2, nbits) - 1);
- return ((nonce & fixed_mask) == (mask & fixed_mask));
- }
- uint8_t find_nonces(uint32_t* curr_nonces, uint32_t* prev_nonces, uint32_t* valid_nonces)
- {
- uint8_t i, j;
- uint8_t found = 0;
- uint8_t nonces = 0;
- uint8_t diff = 0;
- uint32_t found_nonces[12];
- memset(found_nonces, 0, sizeof(found_nonces));
- for (i = 0; i < 12; i++) {
- if (((curr_nonces[i] & 0x0fffffff) != 0x0fffffff) &&
- (curr_nonces[i] != prev_nonces[i])) {
- found_nonces[found++] = curr_nonces[i];
- }
- if (((curr_nonces[i] & 0x0fffffff) == 0x0fffffff) &&
- (curr_nonces[i] != prev_nonces[i]))
- diff++;
- }
- for (i = 0; i < found; i++) {
- if (found_nonces[i] == 0x00000000)
- continue;
- for (j = i; j < found; j++) {
- if ((j != i) && (found_nonces[i] == found_nonces[j]))
- found_nonces[j] = 0x00000000;
- }
- valid_nonces[nonces++] = found_nonces[i];
- }
- return nonces;
- }
- int8_t cmd_buffer_pop(bf_cmd_buffer_t* cmd_buffer, bf_cmd_status_t* cmd_status, uint32_t* nonces)
- {
- if (cmd_buffer == NULL)
- return -1;
- if (cmd_buffer->status != EXECUTED)
- return -2;
- if (cmd_buffer->cmd_list->head == NULL)
- return -3;
- uint8_t buff[192];
- bf_command_t chip_command;
- memset(buff, 0, sizeof(buff));
- memset(chip_command.rx, 0, sizeof(chip_command.rx));
- /* extract command from list */
- bf_data_t* cdata = cmd_buffer->cmd_list->head;
- chip_command.cmd_code = CMD(cdata)->cmd_code;
- chip_command.depth = CMD(cdata)->depth;
- chip_command.data_length = CMD(cdata)->data_length;
- chip_command.status = 0;
- chip_command.checksum = CMD(cdata)->checksum;
- chip_command.nonce_checksum = 0;
- chip_command.checksum_error = false;
- chip_command.nonce_checksum_error = false;
- /* extract chip return data */
- cg_memcpy(buff, cmd_buffer->rx_buffer + cmd_buffer->rx_offset, CMD(cdata)->data_length);
- cmd_buffer->rx_offset += CMD(cdata)->data_length;
- if (CMD(cdata)->cmd_code & CHIP_CMD_READ_NONCE) {
- cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (49 + 2 + extra_bytes(chip_command.depth)),
- 49 + 2 + extra_bytes(chip_command.depth));
- memset(nonces, 0, 12 * sizeof(uint32_t));
- analyze_rx_data(&chip_command, cmd_status, nonces);
- } else if (CMD(cdata)->cmd_code == CHIP_CMD_CREATE_CHANNEL) {
- cg_memcpy(chip_command.rx, buff, CMD(cdata)->data_length);
- } else {
- cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (2 + extra_bytes(chip_command.depth)),
- 2 + extra_bytes(chip_command.depth));
- analyze_rx_data(&chip_command, cmd_status, NULL);
- }
- /* prepare cmd_status */
- cg_memcpy(&cmd_status->chip_address, &CMD(cdata)->chip_address, sizeof(bf_chip_address_t));
- cg_memcpy(&cmd_status->src_address, &CMD(cdata)->src_address, sizeof(bf_chip_address_t));
- cg_memcpy(&cmd_status->work, &CMD(cdata)->work, sizeof(bf_works_t));
- cmd_status->id = CMD(cdata)->id;
- cmd_status->cmd_code = CMD(cdata)->cmd_code;
- /* push memory back to free cmd list */
- LIST_POP_HEAD(cmd_buffer->cmd_list);
- cmd_buffer->cmd_list->count--;
- free(cdata->data);
- free(cdata);
- return 0;
- }
- int8_t cmd_buffer_exec(spi_channel_id_t spi_channel, bf_cmd_buffer_t* cmd_buffer)
- {
- if (cmd_buffer == NULL)
- return -1;
- if (cmd_buffer->status == TX_READY) {
- device_spi_txrx(spi_channel, cmd_buffer->tx_buffer, cmd_buffer->rx_buffer, cmd_buffer->tx_offset);
- cmd_buffer->status = EXECUTED;
- } else
- return -2;
- return 0;
- }
- /* BF16 command primitives */
- uint8_t gen_clock_data(uint8_t clock, uint8_t prescaler, uint8_t data[4])
- {
- uint8_t i;
- uint32_t data32 = 0x00000000;
- if (clock > 0x3f)
- return -1;
- if ((prescaler != 0) && (prescaler != 1))
- return -1;
- uint32_t magic_const = 0x38;
- uint32_t prescaler1 = prescaler;
- uint32_t clock1 = clock;
- uint32_t prescaler2 = prescaler;
- uint32_t clock2 = clock;
- magic_const <<= 20;
- if (prescaler == 1) {
- prescaler1 <<= 19;
- prescaler2 <<= 12;
- }
- clock1 <<= 13;
- clock2 <<= 6;
- data32 = magic_const | prescaler1 | clock1 | prescaler2 | clock2;
- for (i = 0; i < 4; i++)
- data[i] = (data32 >> (8*(4 - i - 1))) & 0xff;
- return 0;
- }
- #ifdef FLIP_BITS
- static uint32_t flip_bits(uint32_t data, uint8_t nbits)
- {
- uint32_t ret = 0x00000000;
- uint8_t i;
- for (i = 0; i < nbits; i++)
- ret |= (((data >> i) & 0x1) << (nbits - (i + 1)));
- return ret;
- }
- #endif
- uint32_t gen_mask(uint32_t nonce, uint8_t nbits)
- {
- uint32_t mask = 0x00000000;
- uint32_t mask_code = (nbits << 16);
- /* highest 16 bits of nonce counter */
- uint32_t nonce_code = (nonce & 0x0007ffff);
- #ifdef FLIP_BITS
- uint32_t nonce_cntr = flip_bits(nonce_code, 19);
- nonce_code = (flip_bits(nonce_cntr - 2, 19) ^ 0xaaaaaaaa);
- mask = (mask_code | (nonce_code & (uint32_t)(pow(2, nbits) - 1)));
- #else
- nonce_code = ((nonce_code ^ 0xaaaaaaaa) & (uint32_t)(pow(2, nbits) - 1));
- mask = (mask_code | nonce_code);
- #endif
- return mask;
- }
- void ms3steps16(uint32_t* p, uint32_t* w, uint32_t* task)
- {
- uint32_t a, b, c, d, e, f, g, h, new_e, new_a;
- uint8_t 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 = w[i] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) + d;
- new_a = w[i] + 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;
- }
- task[18] = ntohl(a ^ 0xaaaaaaaa);
- task[17] = ntohl(b ^ 0xaaaaaaaa);
- task[16] = ntohl(c ^ 0xaaaaaaaa);
- task[15] = ntohl(d ^ 0xaaaaaaaa);
- task[11] = ntohl(e ^ 0xaaaaaaaa);
- task[10] = ntohl(f ^ 0xaaaaaaaa);
- task[9] = ntohl(g ^ 0xaaaaaaaa);
- task[8] = ntohl(h ^ 0xaaaaaaaa);
- }
- uint8_t gen_task_data(uint32_t* midstate, uint32_t merkle, uint32_t ntime,
- uint32_t nbits, uint32_t mask, uint8_t* task)
- {
- uint8_t i;
- uint32_t tmp;
- uint32_t w[3];
- w[0] = merkle;
- w[1] = ntime;
- w[2] = nbits;
- for (i = 0; i < 8; i++) {
- tmp = midstate[i];
- tmp ^= 0xaaaaaaaa;
- tmp = ntohl(tmp);
- cg_memcpy(task + i*4, &tmp, sizeof(tmp));
- }
- ms3steps16(midstate, w, (uint32_t*)task);
- for (i = 0; i < 3; i++) {
- tmp = w[i];
- tmp ^= 0xaaaaaaaa;
- tmp = ntohl(tmp);
- cg_memcpy(task + (12 + i)*4, &tmp, sizeof(tmp));
- }
- mask = ntohl(mask);
- cg_memcpy(task + 19*4, &mask, sizeof(mask));
- return 0;
- }
- uint8_t spi_command_init(bf_command_t* command, const uint8_t depth,
- const bf_chip_address_t chip_address, const bf_cmd_code_t cmd_code,
- const uint8_t data_length, const uint8_t* tx)
- {
- uint8_t i;
- memset(command->tx, 0, sizeof(command->tx));
- memset(command->rx, 0, sizeof(command->rx));
- command->tx[0] = 0x01;
- command->data_length = 1;
- if ((chip_address.chip_id > 10) && (chip_address.chip_id != 0x0f))
- return 1;
- else {
- cg_memcpy(&command->chip_address, &chip_address, sizeof(bf_chip_address_t));
- command->tx[1] = (command->chip_address.chip_id << 4);
- command->data_length++;
- }
- command->depth = depth;
- command->cmd_code = cmd_code;
- command->tx[2] = command->cmd_code;
- command->data_length++;
- if (data_length <= 79) {
- command->tx[3] = data_length;
- command->data_length++;
- } else
- return 1;
- /* fill TX data */
- if (data_length == 0) {
- command->tx[4] = 0x00;
- command->data_length++;
- } else if (tx != NULL) {
- cg_memcpy(command->tx + 4, tx, data_length + 1);
- command->data_length += (data_length + 1);
- } else
- return 1;
- /* calculate checksum */
- command->checksum = 0;
- command->nonce_checksum = 0;
- for (i = 2; i < command->data_length; i++)
- command->checksum += command->tx[i];
- command->checksum_error = false;
- command->nonce_checksum_error = false;
- return 0;
- }
- uint8_t spi_command_exec(spi_channel_id_t spi_channel, bf_command_t* command, uint32_t* nonces)
- {
- uint8_t buff[192];
- uint8_t res = 0;
- bf_cmd_status_t cmd_status;
- if (command->cmd_code & CHIP_CMD_READ_NONCE) {
- memset(buff, 0x00, command->data_length + 49 + 2 + extra_bytes(command->depth));
- cg_memcpy(buff, command->tx, command->data_length);
- device_spi_transfer(spi_channel, buff, command->data_length + 49 + 2 + extra_bytes(command->depth));
- cg_memcpy(command->rx, buff + command->data_length, 49 + 2 + extra_bytes(command->depth));
- #if 0
- uint16_t i;
- char data[256];
- memset(data, 0, sizeof(data));
- for (i = 0; i < command->data_length; i++)
- sprintf(data, "%s%02x", data, command->tx[i]);
- applog(LOG_DEBUG, "BF16: TX -> [%s]", data);
- #endif
- return analyze_rx_data(command, &cmd_status, nonces);
- } else {
- memset(buff, 0x00, command->data_length + 2 + extra_bytes(command->depth));
- cg_memcpy(buff, command->tx, command->data_length);
- device_spi_transfer(spi_channel, buff, command->data_length + 2 + extra_bytes(command->depth));
- cg_memcpy(command->rx, buff + command->data_length, 2 + extra_bytes(command->depth));
- if (opt_bf16_test_chip != NULL) {
- uint16_t i;
- char data[256];
- memset(data, 0, sizeof(data));
- for (i = 0; i < command->data_length; i++)
- sprintf(data, "%s%02x", data, command->tx[i]);
- applog(LOG_NOTICE, "BF16: TX -> [%s]", data);
- }
- return analyze_rx_data(command, &cmd_status, nonces);
- }
- return res;
- }
- /* dynamic work list primitives */
- bf_list_t* workd_list_init(void)
- {
- bf_list_t* list = cgmalloc(sizeof(bf_list_t));
- list->head = NULL;
- list->tail = NULL;
- list->count = 0;
- pthread_mutex_init(&list->lock, NULL);
- return list;
- }
- int8_t workd_list_deinit(bf_list_t* list, struct cgpu_info *bitfury)
- {
- if (list == NULL)
- return -1;
- /* free work list */
- L_LOCK(list);
- while (list->head != NULL) {
- bf_data_t* wdata = list->head;
- LIST_POP_HEAD(list);
- if (WORKD(wdata)->rolled)
- free_work(WORKD(wdata)->work);
- else
- work_completed(bitfury, WORKD(wdata)->work);
- free(wdata);
- }
- L_UNLOCK(list);
- pthread_mutex_destroy(&list->lock);
- list->count = 0;
- free(list);
- return 0;
- }
- int8_t workd_list_push(bf_list_t* list, bf_workd_t* work)
- {
- if ((list == NULL) || (work == NULL))
- return -1;
- bf_data_t* wdata = cgmalloc(sizeof(bf_data_t));
- wdata->data = work;
- wdata->next = NULL;
- wdata->prev = NULL;
- LIST_PUSH_TAIL(list, wdata);
- list->count++;
- return 0;
- }
- int8_t workd_list_pop(bf_list_t* list, struct cgpu_info *bitfury)
- {
- if (list == NULL)
- return -1;
- bf_data_t* wdata = list->head;
- if (wdata != NULL) {
- LIST_POP_HEAD(list);
- if (WORKD(wdata)->rolled)
- free_work(WORKD(wdata)->work);
- else
- work_completed(bitfury, WORKD(wdata)->work);
- list->count--;
- free(wdata->data);
- free(wdata);
- } else
- return -1;
- return 0;
- }
- int8_t workd_list_remove(bf_list_t* list, bf_works_t* works)
- {
- if (list == NULL)
- return -1;
- bf_data_t* wdata = list->head;
- if (wdata != NULL) {
- LIST_POP_HEAD(list);
- cg_memcpy(&works->work, WORKD(wdata)->work, sizeof(struct work));
- cg_memcpy(&works->payload, &WORKD(wdata)->payload, sizeof(bf_payload_t));
- list->count--;
- free(wdata);
- } else
- return -1;
- return 0;
- }
- /* nonces list primitives */
- bf_list_t* nonce_list_init(void)
- {
- bf_list_t* list = cgmalloc(sizeof(bf_list_t));
- list->head = NULL;
- list->tail = NULL;
- list->count = 0;
- pthread_mutex_init(&list->lock, NULL);
- return list;
- }
- int8_t nonce_list_deinit(bf_list_t* list)
- {
- if (list == NULL)
- return -1;
- /* free nonce list */
- L_LOCK(list);
- while (list->head != NULL) {
- bf_data_t* ndata = list->head;
- LIST_POP_HEAD(list);
- free(ndata->data);
- free(ndata);
- }
- L_UNLOCK(list);
- pthread_mutex_destroy(&list->lock);
- list->count = 0;
- free(list);
-
- return 0;
- }
- int8_t nonce_list_push(bf_list_t* list, uint32_t nonce)
- {
- if (list == NULL)
- return -1;
- /* find nonce duplicates */
- bf_data_t* ndata = list->head;
- while (ndata != NULL) {
- if (NONCE(ndata)->nonce == nonce)
- return -1;
- ndata = ndata->next;
- }
- ndata = cgmalloc(sizeof(bf_data_t));
- ndata->data = cgmalloc(sizeof(bf_nonce_t));
- NONCE(ndata)->nonce = nonce;
- ndata->next = NULL;
- ndata->prev = NULL;
- LIST_PUSH_TAIL(list, ndata);
- list->count++;
- return 0;
- }
- uint32_t nonce_list_pop(bf_list_t* list)
- {
- uint32_t nonce = 0;
- bf_data_t* ndata = list->head;
- if (ndata != NULL) {
- nonce = NONCE(ndata)->nonce;
- LIST_POP_HEAD(list);
- list->count--;
- free(ndata->data);
- free(ndata);
- } else
- return -1;
- return nonce;
- }
- /* renoncework list primitives */
- bf_list_t* renoncework_list_init(void)
- {
- bf_list_t* list = cgmalloc(sizeof(bf_list_t));
- list->head = NULL;
- list->tail = NULL;
- list->count = 0;
- pthread_mutex_init(&list->lock, NULL);
- return list;
- }
- int8_t renoncework_list_deinit(bf_list_t* list)
- {
- if (list == NULL)
- return -1;
- /* free renoncework list */
- L_LOCK(list);
- while (list->head != NULL) {
- bf_data_t* rnwdata = list->head;
- LIST_POP_HEAD(list);
- free(rnwdata->data);
- free(rnwdata);
- }
- L_UNLOCK(list);
- pthread_mutex_destroy(&list->lock);
- list->count = 0;
- free(list);
- return 0;
- }
- int8_t renoncework_list_push(bf_list_t* list, bf_chip_address_t src_address, uint32_t nonce)
- {
- if (list == NULL)
- return -1;
- bf_data_t* rnwdata = cgmalloc(sizeof(bf_data_t));
- rnwdata->data = cgmalloc(sizeof(bf_renoncework_t));
- rnwdata->next = NULL;
- rnwdata->prev = NULL;
- cg_memcpy(&RENONCEWORK(rnwdata)->src_address, &src_address, sizeof(bf_chip_address_t));
- RENONCEWORK(rnwdata)->nonce = nonce;
- LIST_PUSH_TAIL(list, rnwdata);
- list->count++;
- return 0;
- }
- int8_t renoncework_list_pop(bf_list_t* list)
- {
- if (list == NULL)
- return -1;
- bf_data_t* rnwdata = list->head;
- if (rnwdata != NULL) {
- LIST_POP_HEAD(list);
- list->count--;
- free(rnwdata->data);
- free(rnwdata);
- } else
- return -1;
- return 0;
- }
- /* noncework list primitives */
- bf_list_t* noncework_list_init(void)
- {
- bf_list_t* list = cgmalloc(sizeof(bf_list_t));
- list->head = NULL;
- list->tail = NULL;
- list->count = 0;
- pthread_mutex_init(&list->lock, NULL);
- return list;
- }
- int8_t noncework_list_deinit(bf_list_t* list)
- {
- if (list == NULL)
- return -1;
- /* free noncework list */
- L_LOCK(list);
- while (list->head != NULL) {
- bf_data_t* nwdata = list->head;
- LIST_POP_HEAD(list);
- free(nwdata->data);
- free(nwdata);
- }
- L_UNLOCK(list);
- pthread_mutex_destroy(&list->lock);
- list->count = 0;
- free(list);
- return 0;
- }
- int8_t noncework_list_push(bf_list_t* list, bf_chip_address_t chip_address,
- bf_chip_address_t src_address, bf_works_t cwork, bf_works_t owork, uint32_t nonce)
- {
- if (list == NULL)
- return -1;
- bf_data_t* nwdata = cgmalloc(sizeof(bf_data_t));
- nwdata->data = cgmalloc(sizeof(bf_noncework_t));
- nwdata->next = NULL;
- nwdata->prev = NULL;
- cg_memcpy(&NONCEWORK(nwdata)->cwork, &cwork, sizeof(bf_works_t));
- cg_memcpy(&NONCEWORK(nwdata)->owork, &owork, sizeof(bf_works_t));
- cg_memcpy(&NONCEWORK(nwdata)->chip_address, &chip_address, sizeof(bf_chip_address_t));
- cg_memcpy(&NONCEWORK(nwdata)->src_address, &src_address, sizeof(bf_chip_address_t));
- NONCEWORK(nwdata)->nonce = nonce;
- LIST_PUSH_TAIL(list, nwdata);
- list->count++;
- return 0;
- }
- int8_t noncework_list_pop(bf_list_t* list)
- {
- if (list == NULL)
- return -1;
- bf_data_t* nwdata = list->head;
- if (nwdata != NULL) {
- LIST_POP_HEAD(list);
- list->count--;
- free(nwdata->data);
- free(nwdata);
- } else
- return -1;
- return 0;
- }
- /* renonce list primitives */
- bf_list_t* renonce_list_init(void)
- {
- bf_list_t* list = cgmalloc(sizeof(bf_list_t));
- list->head = NULL;
- list->tail = NULL;
- list->count = 0;
- pthread_mutex_init(&list->lock, NULL);
- return list;
- }
- int8_t renonce_list_deinit(bf_list_t* list)
- {
- if (list == NULL)
- return -1;
- /* free renonce list */
- L_LOCK(list);
- while (list->head != NULL) {
- bf_data_t* rdata = list->head;
- LIST_POP_HEAD(list);
- free(rdata->data);
- free(rdata);
- }
- L_UNLOCK(list);
- pthread_mutex_destroy(&list->lock);
- list->count = 0;
- free(list);
- return 0;
- }
- int8_t renonce_list_push(bf_list_t* list, uint32_t id, uint32_t nonce, bf_chip_address_t src_address,
- bf_works_t cwork, bf_works_t owork)
- {
- if (list == NULL)
- return -1;
- bf_data_t* rdata = cgmalloc(sizeof(bf_data_t));
- rdata->data = cgmalloc(sizeof(bf_renonce_t));
- rdata->next = NULL;
- rdata->prev = NULL;
- cg_memcpy(&RENONCE(rdata)->cwork, &cwork, sizeof(bf_works_t));
- cg_memcpy(&RENONCE(rdata)->owork, &owork, sizeof(bf_works_t));
- cg_memcpy(&RENONCE(rdata)->src_address, &src_address, sizeof(bf_chip_address_t));
- RENONCE(rdata)->id = id;
- RENONCE(rdata)->nonce = nonce;
- RENONCE(rdata)->stage = RENONCE_STAGE0;
- RENONCE(rdata)->sent = false;
- RENONCE(rdata)->received = false;
- RENONCE(rdata)->match = false;
- LIST_PUSH_TAIL(list, rdata);
- list->count++;
- return 0;
- }
- int8_t renonce_list_pop(bf_list_t* list)
- {
- if (list == NULL)
- return -1;
- bf_data_t* rdata = list->head;
- if (rdata != NULL) {
- LIST_POP_HEAD(list);
- list->count--;
- free(rdata->data);
- free(rdata);
- } else
- return -1;
- return 0;
- }
- int8_t renonce_list_remove(bf_list_t* list, bf_data_t* rdata)
- {
- if (list == NULL)
- return -1;
- if (rdata != NULL) {
- LIST_REMOVE(list, rdata);
- list->count--;
- free(rdata->data);
- free(rdata);
- } else
- return -1;
- return 0;
- }
|