/ bf16-bitfury16.c
bf16-bitfury16.c
1 #include <arpa/inet.h> 2 3 #include "miner.h" 4 5 #include "bf16-bitfury16.h" 6 #include "bf16-communication.h" 7 #include "bf16-ctrldevice.h" 8 9 #include "math.h" 10 #include "sha2.h" 11 #include "driver-bitfury16.h" 12 13 //#define FLIP_BITS 14 15 bf_cmd_description_t cmd_description[CHIP_CMD_NUM] = { 16 { 17 .cmd_code = CHIP_CMD_TASK_STATUS, 18 .cmd_description = "CHIP_CMD_TASK_STATUS" 19 }, 20 { 21 .cmd_code = CHIP_CMD_TASK_WRITE, 22 .cmd_description = "CHIP_CMD_TASK_WRITE" 23 }, 24 { 25 .cmd_code = CHIP_CMD_TASK_SWITCH, 26 .cmd_description = "CHIP_CMD_TASK_SWITCH" 27 }, 28 { 29 .cmd_code = CHIP_CMD_READ_NONCE, 30 .cmd_description = "CHIP_CMD_READ_NONCE" 31 }, 32 { 33 .cmd_code = CHIP_CMD_SET_CLOCK, 34 .cmd_description = "CHIP_CMD_SET_CLOCK" 35 }, 36 { 37 .cmd_code = CHIP_CMD_TOGGLE, 38 .cmd_description = "CHIP_CMD_TOGGLE" 39 }, 40 { 41 .cmd_code = CHIP_CMD_SET_MASK, 42 .cmd_description = "CHIP_CMD_SET_MASK" 43 }, 44 { 45 .cmd_code = CHIP_CMD_CREATE_CHANNEL, 46 .cmd_description = "CHIP_CMD_CREATE_CHANNEL" 47 } 48 }; 49 50 char* get_cmd_description(bf_cmd_code_t cmd_code) 51 { 52 uint8_t i; 53 54 for (i = 0; i < CHIP_CMD_NUM; i++) 55 if (cmd_description[i].cmd_code == cmd_code) 56 return cmd_description[i].cmd_description; 57 58 return NULL; 59 } 60 61 static void shift_bits(uint8_t* data, uint8_t size, uint8_t nbits) 62 { 63 uint8_t i; 64 uint8_t bytes = nbits / 8; 65 uint8_t bits = nbits % 8; 66 67 for (i = 0; i < size; i++) { 68 data[i] = (data[i + bytes] << bits); 69 uint8_t minor = (data[i + bytes + 1] >> (8 - bits)); 70 data[i] |= minor; 71 } 72 } 73 74 static uint8_t extra_bytes(uint8_t depth) 75 { 76 return (depth * 3) / 8 + 1; 77 } 78 79 static uint8_t analyze_rx_data(bf_command_t* command, bf_cmd_status_t* cmd_status, uint32_t* nonces) 80 { 81 uint8_t i; 82 uint8_t res = 0; 83 84 if (command->cmd_code & CHIP_CMD_READ_NONCE) { 85 shift_bits(command->rx, 49 + 2 + extra_bytes(command->depth), command->depth * 3); 86 87 command->status = command->rx[0]; 88 cmd_status->status = command->rx[0]; 89 command->checksum = command->rx[1]; 90 cmd_status->checksum_expected = command->checksum; 91 92 if (nonces == NULL) 93 return 1; 94 95 uint32_t nonce = 0x00000000; 96 97 /* fill nonces buffer */ 98 for (i = 0; i <= 48; i++) { 99 if ((i % 4 == 0) && (i != 0)) { 100 if ((nonce & 0x0fffffff) != 0x0fffffff) 101 nonce ^= 0xaaaaaaaa; 102 nonces[i/4 - 1] = nonce; 103 104 if (i == 48) 105 break; 106 107 nonce = 0x00000000; 108 } 109 110 nonce |= (command->rx[i + 2] << 8*(4 - (i%4) - 1)); 111 } 112 113 #if 0 114 char data[128]; 115 memset(data, 0, sizeof(data)); 116 for (i = 0; i < 49 + 2 + extra_bytes(command->depth); i++) 117 sprintf(data, "%s%02x", data, command->rx[i]); 118 applog(LOG_DEBUG, "BF16: RX <- [%s]", data); 119 #endif 120 121 for (i = 0; i < 48; i ++) 122 command->nonce_checksum += command->rx[i + 2]; 123 command->nonce_checksum += command->rx[1]; 124 125 cmd_status->nonce_checksum_expected = command->nonce_checksum; 126 127 if (command->checksum != command->rx[1]) { 128 command->checksum_error = true; 129 cmd_status->checksum_error = true; 130 cmd_status->checksum_received = command->rx[50]; 131 res = 1; 132 #if 0 133 applog(LOG_ERR, "Checksum mismatch: received [%02x] expected [%02x]", command->rx[1], 0x04); 134 #endif 135 } else { 136 command->checksum_error = false; 137 cmd_status->checksum_error = false; 138 } 139 140 if ((command->nonce_checksum != command->rx[50]) && 141 (command->nonce_checksum != command->rx[50] + 1)) { 142 command->nonce_checksum_error = true; 143 cmd_status->nonce_checksum_error = true; 144 cmd_status->nonce_checksum_received = command->rx[50]; 145 146 res += 2; 147 #if 0 148 applog(LOG_ERR, "Nonce checksum mismatch: received [%02x] expected [%02x]", command->rx[50], checksum); 149 #endif 150 } else { 151 command->nonce_checksum_error = false; 152 cmd_status->nonce_checksum_error = false; 153 } 154 } else { 155 shift_bits(command->rx, 2 + extra_bytes(command->depth), command->depth * 3); 156 157 if (opt_bf16_test_chip != NULL) { 158 char data[16]; 159 memset(data, 0, sizeof(data)); 160 for (i = 0; i < 2 + extra_bytes(command->depth); i++) 161 sprintf(data, "%s%02x", data, command->rx[i]); 162 applog(LOG_NOTICE, "BF16: RX <- [%s]", data); 163 } 164 165 command->status = command->rx[0]; 166 cmd_status->status = command->rx[0]; 167 uint8_t cmd_checksum = command->rx[1]; 168 cmd_status->checksum_expected = command->checksum; 169 170 #if 0 171 applog(LOG_DEBUG, "Command checksum: [%02x]", cmd_checksum); 172 applog(LOG_DEBUG, "Command status: [%02x]", command->status); 173 #endif 174 175 if ((command->checksum != cmd_checksum) && 176 (command->checksum != cmd_checksum + 1)) { 177 command->checksum_error = true; 178 cmd_status->checksum_error = true; 179 cmd_status->checksum_received = cmd_checksum; 180 res = 1; 181 182 if (opt_bf16_test_chip != NULL) { 183 applog(LOG_ERR, "BF16: checksum mismatch: received [%02x] expected [%02x]", 184 cmd_checksum, command->checksum); 185 } 186 } else { 187 command->checksum_error = false; 188 cmd_status->checksum_error = false; 189 } 190 } 191 192 return res; 193 } 194 195 /* SPI BTC250 primitives */ 196 uint8_t create_channel(spi_channel_id_t spi_channel, uint8_t* channel_path, uint8_t channel_length) 197 { 198 int res = 0; 199 200 uint8_t* channel_path_buff = cgcalloc(channel_length, sizeof(uint8_t)); 201 cg_memcpy(channel_path_buff, channel_path, channel_length); 202 203 res = device_spi_transfer(spi_channel, channel_path_buff, channel_length); 204 205 free(channel_path_buff); 206 207 return res; 208 } 209 210 uint8_t destroy_channel(spi_channel_id_t spi_channel, uint8_t depth) 211 { 212 bf_command_t chip_command; 213 bf_chip_address_t chip_address = { 0x00, 0x00, 0x0f }; 214 215 /* send command to 0x0f address */ 216 spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_TASK_SWITCH, 0, NULL); 217 return spi_command_exec(spi_channel, &chip_command, NULL); 218 } 219 220 /* SPI BTC16 primitives */ 221 void spi_emit_reset(spi_channel_id_t spi_channel) 222 { 223 device_ctrl_transfer(spi_channel, 1, F_RST); 224 225 uint8_t data[2] = { 0x00, 0x00 }; 226 device_spi_transfer(spi_channel, data, sizeof(data)); 227 228 device_ctrl_transfer(spi_channel, 0, F_RST); 229 } 230 231 uint8_t send_toggle(spi_channel_id_t spi_channel, uint8_t depth, bf_chip_address_t chip_address) 232 { 233 bf_command_t chip_command; 234 uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 }; 235 236 spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_TOGGLE, 3, toggle); 237 return spi_command_exec(spi_channel, &chip_command, NULL); 238 } 239 240 uint8_t set_clock(spi_channel_id_t spi_channel, uint8_t depth, 241 bf_chip_address_t chip_address, uint8_t clock) 242 { 243 bf_command_t chip_command; 244 uint8_t clock_buf[4]; 245 246 memset(clock_buf, 0, 4); 247 gen_clock_data(clock, 1, clock_buf); 248 spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_SET_CLOCK, 3, clock_buf); 249 return spi_command_exec(spi_channel, &chip_command, NULL); 250 } 251 252 /* cmd buffer primitives */ 253 int8_t cmd_buffer_init(bf_cmd_buffer_t* cmd_buffer) 254 { 255 if (cmd_buffer == NULL) 256 return -1; 257 258 cmd_buffer->cmd_list = cgmalloc(sizeof(bf_list_t)); 259 cmd_buffer->cmd_list->head = NULL; 260 cmd_buffer->cmd_list->tail = NULL; 261 cmd_buffer->cmd_list->count = 0; 262 263 cmd_buffer->tx_buffer = cgcalloc(CMD_BUFFER_LEN, sizeof(uint8_t)); 264 cmd_buffer->rx_buffer = cgcalloc(CMD_BUFFER_LEN, sizeof(uint8_t)); 265 266 memset(cmd_buffer->tx_buffer, 0, CMD_BUFFER_LEN); 267 memset(cmd_buffer->rx_buffer, 0, CMD_BUFFER_LEN); 268 269 cmd_buffer->free_bytes = CMD_BUFFER_LEN; 270 cmd_buffer->tx_offset = 0; 271 cmd_buffer->rx_offset = 0; 272 cmd_buffer->status = EMPTY; 273 274 return 0; 275 } 276 277 int8_t cmd_buffer_deinit(bf_cmd_buffer_t* cmd_buffer) 278 { 279 if (cmd_buffer == NULL) 280 return -1; 281 282 /* free cmd buffer */ 283 while (cmd_buffer->cmd_list->head != NULL) { 284 bf_data_t* cdata = cmd_buffer->cmd_list->head; 285 LIST_POP_HEAD(cmd_buffer->cmd_list); 286 free(cdata->data); 287 free(cdata); 288 } 289 290 free(cmd_buffer->cmd_list); 291 292 /* free RX/TX buffer */ 293 free(cmd_buffer->tx_buffer); 294 free(cmd_buffer->rx_buffer); 295 296 cmd_buffer->free_bytes = CMD_BUFFER_LEN; 297 cmd_buffer->tx_offset = 0; 298 cmd_buffer->rx_offset = 0; 299 cmd_buffer->status = EMPTY; 300 301 return 0; 302 } 303 304 int8_t cmd_buffer_clear(bf_cmd_buffer_t* cmd_buffer) 305 { 306 if (cmd_buffer == NULL) 307 return -1; 308 309 /* release cmd buffer data memory */ 310 while (cmd_buffer->cmd_list->head != NULL) { 311 bf_data_t* cdata = cmd_buffer->cmd_list->head; 312 LIST_POP_HEAD(cmd_buffer->cmd_list); 313 free(cdata->data); 314 free(cdata); 315 } 316 317 cmd_buffer->cmd_list->count = 0; 318 319 /* clear RX/TX buffer */ 320 memset(cmd_buffer->tx_buffer, 0, CMD_BUFFER_LEN); 321 memset(cmd_buffer->rx_buffer, 0, CMD_BUFFER_LEN); 322 323 cmd_buffer->free_bytes = CMD_BUFFER_LEN; 324 cmd_buffer->tx_offset = 0; 325 cmd_buffer->rx_offset = 0; 326 cmd_buffer->status = EMPTY; 327 328 return 0; 329 } 330 331 int8_t cmd_buffer_push(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth, 332 const bf_chip_address_t chip_address, const bf_chip_address_t src_address, 333 const bf_works_t work, const uint32_t id, 334 const bf_cmd_code_t cmd_code, const uint8_t data_length, const uint8_t* tx) 335 { 336 uint8_t res = 0; 337 338 if (cmd_buffer == NULL) 339 return -1; 340 341 if (cmd_buffer->status == EXECUTED) 342 return -2; 343 344 bf_command_t command; 345 memset(&command, 0, sizeof(bf_command_t)); 346 347 uint8_t buff[192]; 348 memset(buff, 0, sizeof(buff)); 349 350 if (cmd_code != CHIP_CMD_CREATE_CHANNEL) { 351 res = spi_command_init(&command, depth, chip_address, cmd_code, data_length, tx); 352 if (res != 0) 353 return res; 354 } 355 356 /* init structure */ 357 bf_data_t* cdata = cgmalloc(sizeof(bf_data_t)); 358 cdata->data = cgmalloc(sizeof(bf_cmd_t)); 359 cdata->next = NULL; 360 cdata->prev = NULL; 361 362 cg_memcpy(&CMD(cdata)->chip_address, &chip_address, sizeof(bf_chip_address_t)); 363 cg_memcpy(&CMD(cdata)->src_address, &src_address, sizeof(bf_chip_address_t)); 364 cg_memcpy(&CMD(cdata)->work, &work, sizeof(bf_works_t)); 365 CMD(cdata)->id = id; 366 CMD(cdata)->depth = command.depth; 367 CMD(cdata)->checksum = command.checksum; 368 CMD(cdata)->cmd_code = cmd_code; 369 370 if (CMD(cdata)->cmd_code & CHIP_CMD_READ_NONCE) 371 CMD(cdata)->data_length = command.data_length + 49 + 2 + extra_bytes(command.depth); 372 else if (CMD(cdata)->cmd_code == CHIP_CMD_CREATE_CHANNEL) 373 CMD(cdata)->data_length = data_length; 374 else 375 CMD(cdata)->data_length = command.data_length + 2 + extra_bytes(command.depth); 376 377 if (cmd_buffer->free_bytes < CMD(cdata)->data_length) { 378 /* not enough TX/RX buffer space available */ 379 free(cdata->data); 380 free(cdata); 381 return -3; 382 } 383 384 /* init send buffer */ 385 if (cmd_code != CHIP_CMD_CREATE_CHANNEL) { 386 cg_memcpy(buff, command.tx, command.data_length); 387 cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, buff, CMD(cdata)->data_length); 388 } else 389 cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, tx, CMD(cdata)->data_length); 390 391 #if 0 392 uint16_t i; 393 char data[384]; 394 memset(data, 0, sizeof(data)); 395 for (i = 0; i < command.data_length; i++) 396 sprintf(data, "%s%02x", data, command.tx[i]); 397 applog(LOG_DEBUG, "BF16: TX -> [%s]", data); 398 #endif 399 400 cmd_buffer->tx_offset += CMD(cdata)->data_length; 401 cmd_buffer->free_bytes -= CMD(cdata)->data_length; 402 403 /* add cmd to buffer */ 404 LIST_PUSH_TAIL(cmd_buffer->cmd_list, cdata); 405 cmd_buffer->cmd_list->count++; 406 407 return 0; 408 } 409 410 int8_t cmd_buffer_push_send_toggle(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth, 411 const bf_chip_address_t chip_address) 412 { 413 bf_works_t work; 414 uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 }; 415 416 return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address, 417 work, 0, CHIP_CMD_TOGGLE, 3, toggle); 418 } 419 420 int8_t cmd_buffer_push_set_clock(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth, 421 const bf_chip_address_t chip_address, uint8_t clock) 422 { 423 bf_works_t work; 424 uint8_t clock_buf[4]; 425 426 memset(clock_buf, 0, 4); 427 gen_clock_data(clock, 1, clock_buf); 428 429 return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address, 430 work, 0, CHIP_CMD_SET_CLOCK, 3, clock_buf); 431 } 432 433 int8_t cmd_buffer_push_set_mask(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth, 434 const bf_chip_address_t chip_address, uint8_t mask) 435 { 436 uint8_t i; 437 bf_works_t work; 438 uint8_t noncemask[4]; 439 440 for (i = 0; i < 4; i++) 441 noncemask[i] = (mask >> (8*(4 - i - 1))) & 0xff; 442 443 return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address, 444 work, 0, CHIP_CMD_SET_MASK, 3, noncemask); 445 } 446 447 int8_t cmd_buffer_push_create_channel(bf_cmd_buffer_t* cmd_buffer, 448 uint8_t* channel_path, uint8_t channel_length) 449 { 450 bf_works_t work; 451 bf_chip_address_t chip_address = { 0x00, 0x00, 0x00 }; 452 453 return cmd_buffer_push(cmd_buffer, 0, chip_address, chip_address, 454 work, 0, CHIP_CMD_CREATE_CHANNEL, channel_length, channel_path); 455 } 456 457 int8_t cmd_buffer_push_destroy_channel(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth) 458 { 459 bf_works_t work; 460 bf_chip_address_t chip_address = { 0x00, 0x00, 0x0f }; 461 462 return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address, 463 work, 0, CHIP_CMD_TASK_SWITCH, 0, NULL); 464 } 465 466 bool match_nonce(uint32_t nonce, uint32_t mask, uint8_t nbits) 467 { 468 uint32_t fixed_mask = (uint32_t)(pow(2, nbits) - 1); 469 return ((nonce & fixed_mask) == (mask & fixed_mask)); 470 } 471 472 uint8_t find_nonces(uint32_t* curr_nonces, uint32_t* prev_nonces, uint32_t* valid_nonces) 473 { 474 uint8_t i, j; 475 uint8_t found = 0; 476 uint8_t nonces = 0; 477 uint8_t diff = 0; 478 479 uint32_t found_nonces[12]; 480 memset(found_nonces, 0, sizeof(found_nonces)); 481 482 for (i = 0; i < 12; i++) { 483 if (((curr_nonces[i] & 0x0fffffff) != 0x0fffffff) && 484 (curr_nonces[i] != prev_nonces[i])) { 485 found_nonces[found++] = curr_nonces[i]; 486 } 487 488 if (((curr_nonces[i] & 0x0fffffff) == 0x0fffffff) && 489 (curr_nonces[i] != prev_nonces[i])) 490 diff++; 491 } 492 493 for (i = 0; i < found; i++) { 494 if (found_nonces[i] == 0x00000000) 495 continue; 496 497 for (j = i; j < found; j++) { 498 if ((j != i) && (found_nonces[i] == found_nonces[j])) 499 found_nonces[j] = 0x00000000; 500 } 501 502 valid_nonces[nonces++] = found_nonces[i]; 503 } 504 505 return nonces; 506 } 507 508 int8_t cmd_buffer_pop(bf_cmd_buffer_t* cmd_buffer, bf_cmd_status_t* cmd_status, uint32_t* nonces) 509 { 510 if (cmd_buffer == NULL) 511 return -1; 512 513 if (cmd_buffer->status != EXECUTED) 514 return -2; 515 516 if (cmd_buffer->cmd_list->head == NULL) 517 return -3; 518 519 uint8_t buff[192]; 520 bf_command_t chip_command; 521 memset(buff, 0, sizeof(buff)); 522 memset(chip_command.rx, 0, sizeof(chip_command.rx)); 523 524 /* extract command from list */ 525 bf_data_t* cdata = cmd_buffer->cmd_list->head; 526 527 chip_command.cmd_code = CMD(cdata)->cmd_code; 528 chip_command.depth = CMD(cdata)->depth; 529 chip_command.data_length = CMD(cdata)->data_length; 530 chip_command.status = 0; 531 chip_command.checksum = CMD(cdata)->checksum; 532 chip_command.nonce_checksum = 0; 533 chip_command.checksum_error = false; 534 chip_command.nonce_checksum_error = false; 535 536 /* extract chip return data */ 537 cg_memcpy(buff, cmd_buffer->rx_buffer + cmd_buffer->rx_offset, CMD(cdata)->data_length); 538 cmd_buffer->rx_offset += CMD(cdata)->data_length; 539 if (CMD(cdata)->cmd_code & CHIP_CMD_READ_NONCE) { 540 cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (49 + 2 + extra_bytes(chip_command.depth)), 541 49 + 2 + extra_bytes(chip_command.depth)); 542 memset(nonces, 0, 12 * sizeof(uint32_t)); 543 analyze_rx_data(&chip_command, cmd_status, nonces); 544 } else if (CMD(cdata)->cmd_code == CHIP_CMD_CREATE_CHANNEL) { 545 cg_memcpy(chip_command.rx, buff, CMD(cdata)->data_length); 546 } else { 547 cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (2 + extra_bytes(chip_command.depth)), 548 2 + extra_bytes(chip_command.depth)); 549 analyze_rx_data(&chip_command, cmd_status, NULL); 550 } 551 552 /* prepare cmd_status */ 553 cg_memcpy(&cmd_status->chip_address, &CMD(cdata)->chip_address, sizeof(bf_chip_address_t)); 554 cg_memcpy(&cmd_status->src_address, &CMD(cdata)->src_address, sizeof(bf_chip_address_t)); 555 cg_memcpy(&cmd_status->work, &CMD(cdata)->work, sizeof(bf_works_t)); 556 cmd_status->id = CMD(cdata)->id; 557 cmd_status->cmd_code = CMD(cdata)->cmd_code; 558 559 /* push memory back to free cmd list */ 560 LIST_POP_HEAD(cmd_buffer->cmd_list); 561 cmd_buffer->cmd_list->count--; 562 free(cdata->data); 563 free(cdata); 564 565 return 0; 566 } 567 568 int8_t cmd_buffer_exec(spi_channel_id_t spi_channel, bf_cmd_buffer_t* cmd_buffer) 569 { 570 if (cmd_buffer == NULL) 571 return -1; 572 573 if (cmd_buffer->status == TX_READY) { 574 device_spi_txrx(spi_channel, cmd_buffer->tx_buffer, cmd_buffer->rx_buffer, cmd_buffer->tx_offset); 575 cmd_buffer->status = EXECUTED; 576 } else 577 return -2; 578 579 return 0; 580 } 581 582 /* BF16 command primitives */ 583 uint8_t gen_clock_data(uint8_t clock, uint8_t prescaler, uint8_t data[4]) 584 { 585 uint8_t i; 586 uint32_t data32 = 0x00000000; 587 588 if (clock > 0x3f) 589 return -1; 590 591 if ((prescaler != 0) && (prescaler != 1)) 592 return -1; 593 594 uint32_t magic_const = 0x38; 595 uint32_t prescaler1 = prescaler; 596 uint32_t clock1 = clock; 597 uint32_t prescaler2 = prescaler; 598 uint32_t clock2 = clock; 599 600 magic_const <<= 20; 601 602 if (prescaler == 1) { 603 prescaler1 <<= 19; 604 prescaler2 <<= 12; 605 } 606 607 clock1 <<= 13; 608 clock2 <<= 6; 609 610 data32 = magic_const | prescaler1 | clock1 | prescaler2 | clock2; 611 for (i = 0; i < 4; i++) 612 data[i] = (data32 >> (8*(4 - i - 1))) & 0xff; 613 614 return 0; 615 } 616 617 #ifdef FLIP_BITS 618 static uint32_t flip_bits(uint32_t data, uint8_t nbits) 619 { 620 uint32_t ret = 0x00000000; 621 uint8_t i; 622 623 for (i = 0; i < nbits; i++) 624 ret |= (((data >> i) & 0x1) << (nbits - (i + 1))); 625 626 return ret; 627 } 628 #endif 629 630 uint32_t gen_mask(uint32_t nonce, uint8_t nbits) 631 { 632 uint32_t mask = 0x00000000; 633 634 uint32_t mask_code = (nbits << 16); 635 636 /* highest 16 bits of nonce counter */ 637 uint32_t nonce_code = (nonce & 0x0007ffff); 638 #ifdef FLIP_BITS 639 uint32_t nonce_cntr = flip_bits(nonce_code, 19); 640 nonce_code = (flip_bits(nonce_cntr - 2, 19) ^ 0xaaaaaaaa); 641 mask = (mask_code | (nonce_code & (uint32_t)(pow(2, nbits) - 1))); 642 #else 643 nonce_code = ((nonce_code ^ 0xaaaaaaaa) & (uint32_t)(pow(2, nbits) - 1)); 644 mask = (mask_code | nonce_code); 645 #endif 646 647 return mask; 648 } 649 650 void ms3steps16(uint32_t* p, uint32_t* w, uint32_t* task) 651 { 652 uint32_t a, b, c, d, e, f, g, h, new_e, new_a; 653 uint8_t i; 654 655 a = p[0]; 656 b = p[1]; 657 c = p[2]; 658 d = p[3]; 659 e = p[4]; 660 f = p[5]; 661 g = p[6]; 662 h = p[7]; 663 for (i = 0; i < 3; i++) { 664 new_e = w[i] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) + d; 665 new_a = w[i] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) + 666 SHA256_F1(a) + MAJ(a,b,c); 667 d = c; 668 c = b; 669 b = a; 670 a = new_a; 671 h = g; 672 g = f; 673 f = e; 674 e = new_e; 675 } 676 677 task[18] = ntohl(a ^ 0xaaaaaaaa); 678 task[17] = ntohl(b ^ 0xaaaaaaaa); 679 task[16] = ntohl(c ^ 0xaaaaaaaa); 680 task[15] = ntohl(d ^ 0xaaaaaaaa); 681 task[11] = ntohl(e ^ 0xaaaaaaaa); 682 task[10] = ntohl(f ^ 0xaaaaaaaa); 683 task[9] = ntohl(g ^ 0xaaaaaaaa); 684 task[8] = ntohl(h ^ 0xaaaaaaaa); 685 } 686 687 uint8_t gen_task_data(uint32_t* midstate, uint32_t merkle, uint32_t ntime, 688 uint32_t nbits, uint32_t mask, uint8_t* task) 689 { 690 uint8_t i; 691 uint32_t tmp; 692 uint32_t w[3]; 693 694 w[0] = merkle; 695 w[1] = ntime; 696 w[2] = nbits; 697 698 for (i = 0; i < 8; i++) { 699 tmp = midstate[i]; 700 tmp ^= 0xaaaaaaaa; 701 tmp = ntohl(tmp); 702 cg_memcpy(task + i*4, &tmp, sizeof(tmp)); 703 } 704 705 ms3steps16(midstate, w, (uint32_t*)task); 706 707 for (i = 0; i < 3; i++) { 708 tmp = w[i]; 709 tmp ^= 0xaaaaaaaa; 710 tmp = ntohl(tmp); 711 cg_memcpy(task + (12 + i)*4, &tmp, sizeof(tmp)); 712 } 713 714 mask = ntohl(mask); 715 cg_memcpy(task + 19*4, &mask, sizeof(mask)); 716 717 return 0; 718 } 719 720 uint8_t spi_command_init(bf_command_t* command, const uint8_t depth, 721 const bf_chip_address_t chip_address, const bf_cmd_code_t cmd_code, 722 const uint8_t data_length, const uint8_t* tx) 723 { 724 uint8_t i; 725 726 memset(command->tx, 0, sizeof(command->tx)); 727 memset(command->rx, 0, sizeof(command->rx)); 728 729 command->tx[0] = 0x01; 730 command->data_length = 1; 731 732 if ((chip_address.chip_id > 10) && (chip_address.chip_id != 0x0f)) 733 return 1; 734 else { 735 cg_memcpy(&command->chip_address, &chip_address, sizeof(bf_chip_address_t)); 736 command->tx[1] = (command->chip_address.chip_id << 4); 737 command->data_length++; 738 } 739 740 command->depth = depth; 741 742 command->cmd_code = cmd_code; 743 command->tx[2] = command->cmd_code; 744 command->data_length++; 745 746 if (data_length <= 79) { 747 command->tx[3] = data_length; 748 command->data_length++; 749 } else 750 return 1; 751 752 /* fill TX data */ 753 if (data_length == 0) { 754 command->tx[4] = 0x00; 755 command->data_length++; 756 } else if (tx != NULL) { 757 cg_memcpy(command->tx + 4, tx, data_length + 1); 758 command->data_length += (data_length + 1); 759 } else 760 return 1; 761 762 /* calculate checksum */ 763 command->checksum = 0; 764 command->nonce_checksum = 0; 765 for (i = 2; i < command->data_length; i++) 766 command->checksum += command->tx[i]; 767 768 command->checksum_error = false; 769 command->nonce_checksum_error = false; 770 771 return 0; 772 } 773 774 uint8_t spi_command_exec(spi_channel_id_t spi_channel, bf_command_t* command, uint32_t* nonces) 775 { 776 uint8_t buff[192]; 777 uint8_t res = 0; 778 bf_cmd_status_t cmd_status; 779 780 if (command->cmd_code & CHIP_CMD_READ_NONCE) { 781 memset(buff, 0x00, command->data_length + 49 + 2 + extra_bytes(command->depth)); 782 cg_memcpy(buff, command->tx, command->data_length); 783 device_spi_transfer(spi_channel, buff, command->data_length + 49 + 2 + extra_bytes(command->depth)); 784 cg_memcpy(command->rx, buff + command->data_length, 49 + 2 + extra_bytes(command->depth)); 785 786 #if 0 787 uint16_t i; 788 char data[256]; 789 memset(data, 0, sizeof(data)); 790 for (i = 0; i < command->data_length; i++) 791 sprintf(data, "%s%02x", data, command->tx[i]); 792 applog(LOG_DEBUG, "BF16: TX -> [%s]", data); 793 #endif 794 795 return analyze_rx_data(command, &cmd_status, nonces); 796 } else { 797 memset(buff, 0x00, command->data_length + 2 + extra_bytes(command->depth)); 798 cg_memcpy(buff, command->tx, command->data_length); 799 device_spi_transfer(spi_channel, buff, command->data_length + 2 + extra_bytes(command->depth)); 800 cg_memcpy(command->rx, buff + command->data_length, 2 + extra_bytes(command->depth)); 801 802 if (opt_bf16_test_chip != NULL) { 803 uint16_t i; 804 char data[256]; 805 memset(data, 0, sizeof(data)); 806 for (i = 0; i < command->data_length; i++) 807 sprintf(data, "%s%02x", data, command->tx[i]); 808 applog(LOG_NOTICE, "BF16: TX -> [%s]", data); 809 } 810 811 return analyze_rx_data(command, &cmd_status, nonces); 812 } 813 814 return res; 815 } 816 817 /* dynamic work list primitives */ 818 bf_list_t* workd_list_init(void) 819 { 820 bf_list_t* list = cgmalloc(sizeof(bf_list_t)); 821 list->head = NULL; 822 list->tail = NULL; 823 list->count = 0; 824 pthread_mutex_init(&list->lock, NULL); 825 826 return list; 827 } 828 829 int8_t workd_list_deinit(bf_list_t* list, struct cgpu_info *bitfury) 830 { 831 if (list == NULL) 832 return -1; 833 834 /* free work list */ 835 L_LOCK(list); 836 while (list->head != NULL) { 837 bf_data_t* wdata = list->head; 838 LIST_POP_HEAD(list); 839 840 if (WORKD(wdata)->rolled) 841 free_work(WORKD(wdata)->work); 842 else 843 work_completed(bitfury, WORKD(wdata)->work); 844 845 free(wdata); 846 } 847 L_UNLOCK(list); 848 849 pthread_mutex_destroy(&list->lock); 850 list->count = 0; 851 free(list); 852 853 return 0; 854 } 855 856 int8_t workd_list_push(bf_list_t* list, bf_workd_t* work) 857 { 858 if ((list == NULL) || (work == NULL)) 859 return -1; 860 861 bf_data_t* wdata = cgmalloc(sizeof(bf_data_t)); 862 wdata->data = work; 863 wdata->next = NULL; 864 wdata->prev = NULL; 865 866 LIST_PUSH_TAIL(list, wdata); 867 list->count++; 868 869 return 0; 870 } 871 872 int8_t workd_list_pop(bf_list_t* list, struct cgpu_info *bitfury) 873 { 874 if (list == NULL) 875 return -1; 876 877 bf_data_t* wdata = list->head; 878 if (wdata != NULL) { 879 LIST_POP_HEAD(list); 880 881 if (WORKD(wdata)->rolled) 882 free_work(WORKD(wdata)->work); 883 else 884 work_completed(bitfury, WORKD(wdata)->work); 885 886 list->count--; 887 free(wdata->data); 888 free(wdata); 889 } else 890 return -1; 891 892 return 0; 893 } 894 895 int8_t workd_list_remove(bf_list_t* list, bf_works_t* works) 896 { 897 if (list == NULL) 898 return -1; 899 900 bf_data_t* wdata = list->head; 901 if (wdata != NULL) { 902 LIST_POP_HEAD(list); 903 904 cg_memcpy(&works->work, WORKD(wdata)->work, sizeof(struct work)); 905 cg_memcpy(&works->payload, &WORKD(wdata)->payload, sizeof(bf_payload_t)); 906 907 list->count--; 908 free(wdata); 909 } else 910 return -1; 911 912 return 0; 913 } 914 915 /* nonces list primitives */ 916 bf_list_t* nonce_list_init(void) 917 { 918 bf_list_t* list = cgmalloc(sizeof(bf_list_t)); 919 list->head = NULL; 920 list->tail = NULL; 921 list->count = 0; 922 pthread_mutex_init(&list->lock, NULL); 923 924 return list; 925 } 926 927 int8_t nonce_list_deinit(bf_list_t* list) 928 { 929 if (list == NULL) 930 return -1; 931 932 /* free nonce list */ 933 L_LOCK(list); 934 while (list->head != NULL) { 935 bf_data_t* ndata = list->head; 936 LIST_POP_HEAD(list); 937 free(ndata->data); 938 free(ndata); 939 } 940 L_UNLOCK(list); 941 942 pthread_mutex_destroy(&list->lock); 943 list->count = 0; 944 free(list); 945 946 return 0; 947 } 948 949 int8_t nonce_list_push(bf_list_t* list, uint32_t nonce) 950 { 951 if (list == NULL) 952 return -1; 953 954 /* find nonce duplicates */ 955 bf_data_t* ndata = list->head; 956 while (ndata != NULL) { 957 if (NONCE(ndata)->nonce == nonce) 958 return -1; 959 ndata = ndata->next; 960 } 961 962 ndata = cgmalloc(sizeof(bf_data_t)); 963 ndata->data = cgmalloc(sizeof(bf_nonce_t)); 964 NONCE(ndata)->nonce = nonce; 965 ndata->next = NULL; 966 ndata->prev = NULL; 967 968 LIST_PUSH_TAIL(list, ndata); 969 list->count++; 970 971 return 0; 972 } 973 974 uint32_t nonce_list_pop(bf_list_t* list) 975 { 976 uint32_t nonce = 0; 977 978 bf_data_t* ndata = list->head; 979 if (ndata != NULL) { 980 nonce = NONCE(ndata)->nonce; 981 LIST_POP_HEAD(list); 982 list->count--; 983 free(ndata->data); 984 free(ndata); 985 } else 986 return -1; 987 988 return nonce; 989 } 990 991 /* renoncework list primitives */ 992 bf_list_t* renoncework_list_init(void) 993 { 994 bf_list_t* list = cgmalloc(sizeof(bf_list_t)); 995 list->head = NULL; 996 list->tail = NULL; 997 list->count = 0; 998 pthread_mutex_init(&list->lock, NULL); 999 1000 return list; 1001 } 1002 1003 int8_t renoncework_list_deinit(bf_list_t* list) 1004 { 1005 if (list == NULL) 1006 return -1; 1007 1008 /* free renoncework list */ 1009 L_LOCK(list); 1010 while (list->head != NULL) { 1011 bf_data_t* rnwdata = list->head; 1012 LIST_POP_HEAD(list); 1013 1014 free(rnwdata->data); 1015 free(rnwdata); 1016 } 1017 L_UNLOCK(list); 1018 1019 pthread_mutex_destroy(&list->lock); 1020 list->count = 0; 1021 free(list); 1022 1023 return 0; 1024 } 1025 1026 int8_t renoncework_list_push(bf_list_t* list, bf_chip_address_t src_address, uint32_t nonce) 1027 { 1028 if (list == NULL) 1029 return -1; 1030 1031 bf_data_t* rnwdata = cgmalloc(sizeof(bf_data_t)); 1032 rnwdata->data = cgmalloc(sizeof(bf_renoncework_t)); 1033 rnwdata->next = NULL; 1034 rnwdata->prev = NULL; 1035 1036 cg_memcpy(&RENONCEWORK(rnwdata)->src_address, &src_address, sizeof(bf_chip_address_t)); 1037 RENONCEWORK(rnwdata)->nonce = nonce; 1038 1039 LIST_PUSH_TAIL(list, rnwdata); 1040 list->count++; 1041 1042 return 0; 1043 } 1044 1045 int8_t renoncework_list_pop(bf_list_t* list) 1046 { 1047 if (list == NULL) 1048 return -1; 1049 1050 bf_data_t* rnwdata = list->head; 1051 if (rnwdata != NULL) { 1052 LIST_POP_HEAD(list); 1053 list->count--; 1054 free(rnwdata->data); 1055 free(rnwdata); 1056 } else 1057 return -1; 1058 1059 return 0; 1060 } 1061 1062 /* noncework list primitives */ 1063 bf_list_t* noncework_list_init(void) 1064 { 1065 bf_list_t* list = cgmalloc(sizeof(bf_list_t)); 1066 list->head = NULL; 1067 list->tail = NULL; 1068 list->count = 0; 1069 pthread_mutex_init(&list->lock, NULL); 1070 1071 return list; 1072 } 1073 1074 int8_t noncework_list_deinit(bf_list_t* list) 1075 { 1076 if (list == NULL) 1077 return -1; 1078 1079 /* free noncework list */ 1080 L_LOCK(list); 1081 while (list->head != NULL) { 1082 bf_data_t* nwdata = list->head; 1083 LIST_POP_HEAD(list); 1084 1085 free(nwdata->data); 1086 free(nwdata); 1087 } 1088 L_UNLOCK(list); 1089 1090 pthread_mutex_destroy(&list->lock); 1091 list->count = 0; 1092 free(list); 1093 1094 return 0; 1095 } 1096 1097 int8_t noncework_list_push(bf_list_t* list, bf_chip_address_t chip_address, 1098 bf_chip_address_t src_address, bf_works_t cwork, bf_works_t owork, uint32_t nonce) 1099 { 1100 if (list == NULL) 1101 return -1; 1102 1103 bf_data_t* nwdata = cgmalloc(sizeof(bf_data_t)); 1104 nwdata->data = cgmalloc(sizeof(bf_noncework_t)); 1105 nwdata->next = NULL; 1106 nwdata->prev = NULL; 1107 1108 cg_memcpy(&NONCEWORK(nwdata)->cwork, &cwork, sizeof(bf_works_t)); 1109 cg_memcpy(&NONCEWORK(nwdata)->owork, &owork, sizeof(bf_works_t)); 1110 cg_memcpy(&NONCEWORK(nwdata)->chip_address, &chip_address, sizeof(bf_chip_address_t)); 1111 cg_memcpy(&NONCEWORK(nwdata)->src_address, &src_address, sizeof(bf_chip_address_t)); 1112 NONCEWORK(nwdata)->nonce = nonce; 1113 1114 LIST_PUSH_TAIL(list, nwdata); 1115 list->count++; 1116 1117 return 0; 1118 } 1119 1120 int8_t noncework_list_pop(bf_list_t* list) 1121 { 1122 if (list == NULL) 1123 return -1; 1124 1125 bf_data_t* nwdata = list->head; 1126 if (nwdata != NULL) { 1127 LIST_POP_HEAD(list); 1128 list->count--; 1129 free(nwdata->data); 1130 free(nwdata); 1131 } else 1132 return -1; 1133 1134 return 0; 1135 } 1136 1137 /* renonce list primitives */ 1138 bf_list_t* renonce_list_init(void) 1139 { 1140 bf_list_t* list = cgmalloc(sizeof(bf_list_t)); 1141 list->head = NULL; 1142 list->tail = NULL; 1143 list->count = 0; 1144 pthread_mutex_init(&list->lock, NULL); 1145 1146 return list; 1147 } 1148 1149 int8_t renonce_list_deinit(bf_list_t* list) 1150 { 1151 if (list == NULL) 1152 return -1; 1153 1154 /* free renonce list */ 1155 L_LOCK(list); 1156 while (list->head != NULL) { 1157 bf_data_t* rdata = list->head; 1158 LIST_POP_HEAD(list); 1159 1160 free(rdata->data); 1161 free(rdata); 1162 } 1163 L_UNLOCK(list); 1164 1165 pthread_mutex_destroy(&list->lock); 1166 list->count = 0; 1167 free(list); 1168 1169 return 0; 1170 } 1171 1172 int8_t renonce_list_push(bf_list_t* list, uint32_t id, uint32_t nonce, bf_chip_address_t src_address, 1173 bf_works_t cwork, bf_works_t owork) 1174 { 1175 if (list == NULL) 1176 return -1; 1177 1178 bf_data_t* rdata = cgmalloc(sizeof(bf_data_t)); 1179 rdata->data = cgmalloc(sizeof(bf_renonce_t)); 1180 rdata->next = NULL; 1181 rdata->prev = NULL; 1182 1183 cg_memcpy(&RENONCE(rdata)->cwork, &cwork, sizeof(bf_works_t)); 1184 cg_memcpy(&RENONCE(rdata)->owork, &owork, sizeof(bf_works_t)); 1185 cg_memcpy(&RENONCE(rdata)->src_address, &src_address, sizeof(bf_chip_address_t)); 1186 RENONCE(rdata)->id = id; 1187 RENONCE(rdata)->nonce = nonce; 1188 RENONCE(rdata)->stage = RENONCE_STAGE0; 1189 RENONCE(rdata)->sent = false; 1190 RENONCE(rdata)->received = false; 1191 RENONCE(rdata)->match = false; 1192 1193 LIST_PUSH_TAIL(list, rdata); 1194 list->count++; 1195 1196 return 0; 1197 } 1198 1199 int8_t renonce_list_pop(bf_list_t* list) 1200 { 1201 if (list == NULL) 1202 return -1; 1203 1204 bf_data_t* rdata = list->head; 1205 if (rdata != NULL) { 1206 LIST_POP_HEAD(list); 1207 list->count--; 1208 free(rdata->data); 1209 free(rdata); 1210 } else 1211 return -1; 1212 1213 return 0; 1214 } 1215 1216 int8_t renonce_list_remove(bf_list_t* list, bf_data_t* rdata) 1217 { 1218 if (list == NULL) 1219 return -1; 1220 1221 if (rdata != NULL) { 1222 LIST_REMOVE(list, rdata); 1223 list->count--; 1224 free(rdata->data); 1225 free(rdata); 1226 } else 1227 return -1; 1228 1229 return 0; 1230 }