titan-asic.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. * Copyright 2014 Vitalii Demianets
  3. * Copyright 2014 KnCMiner
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the Free
  7. * Software Foundation; either version 3 of the License, or (at your option)
  8. * any later version. See COPYING for more details.
  9. */
  10. #include "miner.h"
  11. #include "logging.h"
  12. #include "titan-asic.h"
  13. bool knc_titan_get_info(const char *repr, void * const ctx, int channel, int die, struct knc_die_info *die_info)
  14. {
  15. int rc;
  16. rc = knc_detect_die(ctx, channel, die, die_info);
  17. return (0 == rc);
  18. }
  19. bool knc_titan_set_work(const char *repr, void * const ctx, int channel, int die, int core, int slot, struct work *work, bool urgent, bool *work_accepted, struct knc_report *report)
  20. {
  21. int request_length = 4 + 1 + 6*4 + 3*4 + 8*4;
  22. uint8_t request[request_length];
  23. int response_length = 1 + 1 + (1 + 4) * 5;
  24. uint8_t response[response_length];
  25. int status;
  26. request_length = knc_prepare_titan_setwork(request, die, core, slot, work, urgent);
  27. status = knc_syncronous_transfer(ctx, channel, request_length, request, response_length, response);
  28. if (status == KNC_ACCEPTED) {
  29. *work_accepted = true;
  30. } else {
  31. *work_accepted = false;
  32. if (response[0] == 0x7f) {
  33. applog(LOG_DEBUG, "%s[%d:%d]: Core disabled", repr, channel, die);
  34. return false;
  35. }
  36. if (status & KNC_ERR_MASK) {
  37. applog(LOG_ERR, "%s[%d:%d]: Failed to set work state (%x)", repr, channel, die, status);
  38. return false;
  39. }
  40. if (!(status & KNC_ERR_MASK)) {
  41. /* !KNC_ERRMASK */
  42. applog(LOG_DEBUG, "%s[%d:%d]: Core busy", repr, channel, die, status);
  43. }
  44. }
  45. knc_decode_report(response, report, KNC_VERSION_TITAN);
  46. return true;
  47. }
  48. bool knc_titan_get_report(const char *repr, void * const ctx, int channel, int die, int core, struct knc_report *report)
  49. {
  50. uint8_t request[4];
  51. int request_length;
  52. int response_length = 1 + 1 + (1 + 4) * 5;
  53. uint8_t response[response_length];
  54. int status;
  55. request_length = knc_prepare_report(request, die, core);
  56. status = knc_syncronous_transfer(ctx, channel, request_length, request, response_length, response);
  57. if (status) {
  58. applog(LOG_ERR, "%s[%d:%d]: get_report failed (%x)", repr, channel, die, status);
  59. return false;
  60. }
  61. knc_decode_report(response, report, KNC_VERSION_TITAN);
  62. return true;
  63. }
  64. bool knc_titan_setup_core(const char *repr, void * const ctx, int channel, int die, int core, struct titan_setup_core_params *params)
  65. {
  66. #define SETWORK_CMD_SIZE (5 + BLOCK_HEADER_BYTES_WITHOUT_NONCE)
  67. /* The size of command is the same as for set_work */
  68. uint8_t setup_core_cmd[SETWORK_CMD_SIZE] = {
  69. KNC_ASIC_CMD_SETUP_CORE,
  70. die,
  71. (core >> 8) & 0xFF,
  72. core & 0xFF,
  73. /* next follows padding and data */
  74. };
  75. const int send_size = sizeof(setup_core_cmd);
  76. int response_length = send_size - 4;
  77. uint8_t response[response_length];
  78. int status;
  79. uint32_t *src, *dst;
  80. int i;
  81. struct titan_packed_core_params {
  82. /* WORD [0] */
  83. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  84. uint32_t padding :26;
  85. uint32_t bad_address_mask_0_6msb :6;
  86. #else
  87. uint32_t bad_address_mask_0_6msb :6;
  88. uint32_t padding :26;
  89. #endif
  90. /* WORD [1] */
  91. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  92. uint32_t bad_address_mask_0_4lsb :4;
  93. uint32_t bad_address_mask_1 :10;
  94. uint32_t bad_address_match_0 :10;
  95. uint32_t bad_address_match_1_8msb :8;
  96. #else
  97. uint32_t bad_address_match_1_8msb :8;
  98. uint32_t bad_address_match_0 :10;
  99. uint32_t bad_address_mask_1 :10;
  100. uint32_t bad_address_mask_0_4lsb :4;
  101. #endif
  102. /* WORD [2] */
  103. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  104. uint32_t bad_address_match_1_2lsb :2;
  105. uint32_t difficulty :6;
  106. uint32_t thread_enable :8;
  107. uint32_t thread_base_address_0 :10;
  108. uint32_t thread_base_address_1_6msb :6;
  109. #else
  110. uint32_t thread_base_address_1_6msb :6;
  111. uint32_t thread_base_address_0 :10;
  112. uint32_t thread_enable :8;
  113. uint32_t difficulty :6;
  114. uint32_t bad_address_match_1_2lsb :2;
  115. #endif
  116. /* WORD [3] */
  117. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  118. uint32_t thread_base_address_1_4lsb :4;
  119. uint32_t thread_base_address_2 :10;
  120. uint32_t thread_base_address_3 :10;
  121. uint32_t thread_base_address_4_8msb :8;
  122. #else
  123. uint32_t thread_base_address_4_8msb :8;
  124. uint32_t thread_base_address_3 :10;
  125. uint32_t thread_base_address_2 :10;
  126. uint32_t thread_base_address_1_4lsb :4;
  127. #endif
  128. /* WORD [4] */
  129. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  130. uint32_t thread_base_address_4_2lsb :2;
  131. uint32_t thread_base_address_5 :10;
  132. uint32_t thread_base_address_6 :10;
  133. uint32_t thread_base_address_7 :10;
  134. #else
  135. uint32_t thread_base_address_7 :10;
  136. uint32_t thread_base_address_6 :10;
  137. uint32_t thread_base_address_5 :10;
  138. uint32_t thread_base_address_4_2lsb :2;
  139. #endif
  140. /* WORD [5] */
  141. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  142. uint32_t lookup_gap_mask_0 :10;
  143. uint32_t lookup_gap_mask_1 :10;
  144. uint32_t lookup_gap_mask_2 :10;
  145. uint32_t lookup_gap_mask_3_2msb :2;
  146. #else
  147. uint32_t lookup_gap_mask_3_2msb :2;
  148. uint32_t lookup_gap_mask_2 :10;
  149. uint32_t lookup_gap_mask_1 :10;
  150. uint32_t lookup_gap_mask_0 :10;
  151. #endif
  152. /* WORD [6] */
  153. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  154. uint32_t lookup_gap_mask_3_8lsb :8;
  155. uint32_t lookup_gap_mask_4 :10;
  156. uint32_t lookup_gap_mask_5 :10;
  157. uint32_t lookup_gap_mask_6_4msb :4;
  158. #else
  159. uint32_t lookup_gap_mask_6_4msb :4;
  160. uint32_t lookup_gap_mask_5 :10;
  161. uint32_t lookup_gap_mask_4 :10;
  162. uint32_t lookup_gap_mask_3_8lsb :8;
  163. #endif
  164. /* WORD [7] */
  165. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  166. uint32_t lookup_gap_mask_6_6lsb :6;
  167. uint32_t lookup_gap_mask_7 :10;
  168. uint32_t N_mask_0 :10;
  169. uint32_t N_mask_1_6msb :6;
  170. #else
  171. uint32_t N_mask_1_6msb :6;
  172. uint32_t N_mask_0 :10;
  173. uint32_t lookup_gap_mask_7 :10;
  174. uint32_t lookup_gap_mask_6_6lsb :6;
  175. #endif
  176. /* WORD [8] */
  177. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  178. uint32_t N_mask_1_4lsb :4;
  179. uint32_t N_mask_2 :10;
  180. uint32_t N_mask_3 :10;
  181. uint32_t N_mask_4_8msb :8;
  182. #else
  183. uint32_t N_mask_4_8msb :8;
  184. uint32_t N_mask_3 :10;
  185. uint32_t N_mask_2 :10;
  186. uint32_t N_mask_1_4lsb :4;
  187. #endif
  188. /* WORD [9] */
  189. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  190. uint32_t N_mask_4_2lsb :2;
  191. uint32_t N_mask_5 :10;
  192. uint32_t N_mask_6 :10;
  193. uint32_t N_mask_7 :10;
  194. #else
  195. uint32_t N_mask_7 :10;
  196. uint32_t N_mask_6 :10;
  197. uint32_t N_mask_5 :10;
  198. uint32_t N_mask_4_2lsb :2;
  199. #endif
  200. /* WORD [10] */
  201. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  202. uint32_t N_shift_0 :4;
  203. uint32_t N_shift_1 :4;
  204. uint32_t N_shift_2 :4;
  205. uint32_t N_shift_3 :4;
  206. uint32_t N_shift_4 :4;
  207. uint32_t N_shift_5 :4;
  208. uint32_t N_shift_6 :4;
  209. uint32_t N_shift_7 :4;
  210. #else
  211. uint32_t N_shift_7 :4;
  212. uint32_t N_shift_6 :4;
  213. uint32_t N_shift_5 :4;
  214. uint32_t N_shift_4 :4;
  215. uint32_t N_shift_3 :4;
  216. uint32_t N_shift_2 :4;
  217. uint32_t N_shift_1 :4;
  218. uint32_t N_shift_0 :4;
  219. #endif
  220. /* WORD [11] */
  221. uint32_t nonce_top;
  222. /* WORD [12] */
  223. uint32_t nonce_bottom;
  224. } __attribute__((packed)) packed_params;
  225. packed_params.padding = 0;
  226. packed_params.bad_address_mask_0_6msb = (params->bad_address_mask[0] >> 4) & 0x03F;
  227. packed_params.bad_address_mask_0_4lsb = params->bad_address_mask[0] & 0x00F;
  228. packed_params.bad_address_mask_1 = params->bad_address_mask[1];
  229. packed_params.bad_address_match_0 = params->bad_address_match[0];
  230. packed_params.bad_address_match_1_8msb = (params->bad_address_match[1] >> 2) & 0x0FF;
  231. packed_params.bad_address_match_1_2lsb = params->bad_address_match[1] & 0x003;
  232. packed_params.difficulty = params->difficulty;
  233. packed_params.thread_enable = params->thread_enable;
  234. packed_params.thread_base_address_0 = params->thread_base_address[0];
  235. packed_params.thread_base_address_1_6msb = (params->thread_base_address[1] >> 4) & 0x03F;
  236. packed_params.thread_base_address_1_4lsb = params->thread_base_address[1] & 0x00F;
  237. packed_params.thread_base_address_2 = params->thread_base_address[2];
  238. packed_params.thread_base_address_3 = params->thread_base_address[3];
  239. packed_params.thread_base_address_4_8msb = (params->thread_base_address[4] >> 2) & 0x0FF;
  240. packed_params.thread_base_address_4_2lsb = params->thread_base_address[4] & 0x003;
  241. packed_params.thread_base_address_5 = params->thread_base_address[5];
  242. packed_params.thread_base_address_6 = params->thread_base_address[6];
  243. packed_params.thread_base_address_7 = params->thread_base_address[7];
  244. packed_params.lookup_gap_mask_0 = params->lookup_gap_mask[0];
  245. packed_params.lookup_gap_mask_1 = params->lookup_gap_mask[1];
  246. packed_params.lookup_gap_mask_2 = params->lookup_gap_mask[2];
  247. packed_params.lookup_gap_mask_3_2msb = (params->lookup_gap_mask[3] >> 8) & 0x003;
  248. packed_params.lookup_gap_mask_3_8lsb = params->lookup_gap_mask[3] & 0x0FF;
  249. packed_params.lookup_gap_mask_4 = params->lookup_gap_mask[4];
  250. packed_params.lookup_gap_mask_5 = params->lookup_gap_mask[5];
  251. packed_params.lookup_gap_mask_6_4msb = (params->lookup_gap_mask[6] >> 6) & 0x00F;
  252. packed_params.lookup_gap_mask_6_6lsb = params->lookup_gap_mask[6] & 0x03F;
  253. packed_params.lookup_gap_mask_7 = params->lookup_gap_mask[7];
  254. packed_params.N_mask_0 = params->N_mask[0];
  255. packed_params.N_mask_1_6msb = (params->N_mask[1] >> 4) & 0x03F;
  256. packed_params.N_mask_1_4lsb = params->N_mask[1] & 0x00F;
  257. packed_params.N_mask_2 = params->N_mask[2];
  258. packed_params.N_mask_3 = params->N_mask[3];
  259. packed_params.N_mask_4_8msb = (params->N_mask[4] >> 2) & 0x0FF;
  260. packed_params.N_mask_4_2lsb = params->N_mask[4] & 0x003;
  261. packed_params.N_mask_5 = params->N_mask[5];
  262. packed_params.N_mask_6 = params->N_mask[6];
  263. packed_params.N_mask_7 = params->N_mask[7];
  264. packed_params.N_shift_0 = params->N_shift[0];
  265. packed_params.N_shift_1 = params->N_shift[1];
  266. packed_params.N_shift_2 = params->N_shift[2];
  267. packed_params.N_shift_3 = params->N_shift[3];
  268. packed_params.N_shift_4 = params->N_shift[4];
  269. packed_params.N_shift_5 = params->N_shift[5];
  270. packed_params.N_shift_6 = params->N_shift[6];
  271. packed_params.N_shift_7 = params->N_shift[7];
  272. packed_params.nonce_top = params->nonce_top;
  273. packed_params.nonce_bottom = params->nonce_bottom;
  274. src = (uint32_t *)&packed_params;
  275. dst = (uint32_t *)(&setup_core_cmd[send_size - sizeof(packed_params)]);
  276. for (i = 0; i < (sizeof(packed_params) / 4); ++i)
  277. dst[i] = htobe32(src[i]);
  278. status = knc_syncronous_transfer(ctx, channel, send_size, setup_core_cmd, response_length, response);
  279. /* For this command ASIC does not send CRC in response, so ignore it */
  280. status &= ~(KNC_ERR_CRC);
  281. if (status != KNC_ACCEPTED) {
  282. applog(LOG_ERR, "%s[%d:%d]: setup_core failed (%x)", repr, channel, die, status);
  283. return false;
  284. }
  285. return true;
  286. }