bf16-bitfury16.c 29 KB

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