Browse Source

titan: Setup_core command implemented

Vitalii Demianets 11 years ago
parent
commit
5f3cc33230
2 changed files with 261 additions and 0 deletions
  1. 246 0
      titan-asic.c
  2. 15 0
      titan-asic.h

+ 246 - 0
titan-asic.c

@@ -21,6 +21,7 @@
 #define	KNC_ASIC_CMD_REPORT		0x82
 #define	KNC_ASIC_CMD_REPORT		0x82
 #define	KNC_ASIC_CMD_SETWORK		0x81
 #define	KNC_ASIC_CMD_SETWORK		0x81
 #define	KNC_ASIC_CMD_SETWORK_URGENT	0x83
 #define	KNC_ASIC_CMD_SETWORK_URGENT	0x83
+#define	KNC_ASIC_CMD_SETUP_CORE		0x87
 
 
 /* Error bits */
 /* Error bits */
 #define	ERR_SEND_CRC_FAIL	(1 << 0)
 #define	ERR_SEND_CRC_FAIL	(1 << 0)
@@ -80,6 +81,23 @@ exit_other_error:
 			*errors |= ERR_RCV_CRC_FAIL;
 			*errors |= ERR_RCV_CRC_FAIL;
 	}
 	}
 
 
+#if 0
+	{
+		uint8_t *txbuf = spi_gettxbuf(spi);
+		char str[8192];
+		int i, n;
+		n = 0;
+		for (i = 0; i < transfer_size; ++i)
+			n += sprintf(&str[n], i ? ",0x%02hhX" : "0x%02hhX", txbuf[i]);
+		applog(LOG_NOTICE, "TX: %s", str);
+		n = 0;
+		for (i = 0; i < transfer_size; ++i)
+			n += sprintf(&str[n], i ? ",0x%02hhX" : "0x%02hhX", rxbuf[i]);
+		applog(LOG_NOTICE, "RX: %s", str);
+		if (0 < rcv_crc_data_len)
+			applog(LOG_NOTICE, "RX-CRC: 0x%08X", crc);
+	}
+#endif
 	return rxbuf;
 	return rxbuf;
 }
 }
 
 
@@ -247,3 +265,231 @@ bool knc_titan_get_report(const char *repr, struct spi_port * const spi, struct
 	knc_titan_parse_get_report(&rxbuf[4], report);
 	knc_titan_parse_get_report(&rxbuf[4], report);
 	return true;
 	return true;
 }
 }
+
+bool knc_titan_setup_core(const char *repr, struct spi_port * const spi, struct titan_setup_core_params *params, int die, int core)
+{
+	/* The size of command is the same as for set_work */
+	uint8_t setup_core_cmd[SETWORK_CMD_SIZE] = {
+		KNC_ASIC_CMD_SETUP_CORE,
+		die,
+		(core >> 8) & 0xFF,
+		core & 0xFF,
+		/* next follows padding and data */
+	};
+	const int send_size = sizeof(setup_core_cmd);
+	const int transfer_size = send_size + CRC32_SIZE + SPI_RESPONSE_TRAILER_SIZE;
+	uint8_t *rxbuf;
+	uint32_t errors;
+	uint32_t *src, *dst;
+	int i;
+	struct titan_packed_core_params {
+		/* WORD [0] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t padding			:26;
+		uint32_t bad_address_mask_0_6msb	:6;
+#else
+		uint32_t bad_address_mask_0_6msb	:6;
+		uint32_t padding			:26;
+#endif
+		/* WORD [1] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t bad_address_mask_0_4lsb	:4;
+		uint32_t bad_address_mask_1		:10;
+		uint32_t bad_address_match_0		:10;
+		uint32_t bad_address_match_1_8msb	:8;
+#else
+		uint32_t bad_address_match_1_8msb	:8;
+		uint32_t bad_address_match_0		:10;
+		uint32_t bad_address_mask_1		:10;
+		uint32_t bad_address_mask_0_4lsb	:4;
+#endif
+		/* WORD [2] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t bad_address_match_1_2lsb	:2;
+		uint32_t difficulty			:6;
+		uint32_t thread_enable			:8;
+		uint32_t thread_base_address_0		:10;
+		uint32_t thread_base_address_1_6msb	:6;
+#else
+		uint32_t thread_base_address_1_6msb	:6;
+		uint32_t thread_base_address_0		:10;
+		uint32_t thread_enable			:8;
+		uint32_t difficulty			:6;
+		uint32_t bad_address_match_1_2lsb	:2;
+#endif
+		/* WORD [3] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t thread_base_address_1_4lsb	:4;
+		uint32_t thread_base_address_2		:10;
+		uint32_t thread_base_address_3		:10;
+		uint32_t thread_base_address_4_8msb	:8;
+#else
+		uint32_t thread_base_address_4_8msb	:8;
+		uint32_t thread_base_address_3		:10;
+		uint32_t thread_base_address_2		:10;
+		uint32_t thread_base_address_1_4lsb	:4;
+#endif
+		/* WORD [4] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t thread_base_address_4_2lsb	:2;
+		uint32_t thread_base_address_5		:10;
+		uint32_t thread_base_address_6		:10;
+		uint32_t thread_base_address_7		:10;
+#else
+		uint32_t thread_base_address_7		:10;
+		uint32_t thread_base_address_6		:10;
+		uint32_t thread_base_address_5		:10;
+		uint32_t thread_base_address_4_2lsb	:2;
+#endif
+		/* WORD [5] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t lookup_gap_mask_0		:10;
+		uint32_t lookup_gap_mask_1		:10;
+		uint32_t lookup_gap_mask_2		:10;
+		uint32_t lookup_gap_mask_3_2msb		:2;
+#else
+		uint32_t lookup_gap_mask_3_2msb		:2;
+		uint32_t lookup_gap_mask_2		:10;
+		uint32_t lookup_gap_mask_1		:10;
+		uint32_t lookup_gap_mask_0		:10;
+#endif
+		/* WORD [6] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t lookup_gap_mask_3_8lsb		:8;
+		uint32_t lookup_gap_mask_4		:10;
+		uint32_t lookup_gap_mask_5		:10;
+		uint32_t lookup_gap_mask_6_4msb		:4;
+#else
+		uint32_t lookup_gap_mask_6_4msb		:4;
+		uint32_t lookup_gap_mask_5		:10;
+		uint32_t lookup_gap_mask_4		:10;
+		uint32_t lookup_gap_mask_3_8lsb		:8;
+#endif
+		/* WORD [7] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t lookup_gap_mask_6_6lsb		:6;
+		uint32_t lookup_gap_mask_7		:10;
+		uint32_t N_mask_0			:10;
+		uint32_t N_mask_1_6msb			:6;
+#else
+		uint32_t N_mask_1_6msb			:6;
+		uint32_t N_mask_0			:10;
+		uint32_t lookup_gap_mask_7		:10;
+		uint32_t lookup_gap_mask_6_6lsb		:6;
+#endif
+		/* WORD [8] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t N_mask_1_4lsb			:4;
+		uint32_t N_mask_2			:10;
+		uint32_t N_mask_3			:10;
+		uint32_t N_mask_4_8msb			:8;
+#else
+		uint32_t N_mask_4_8msb			:8;
+		uint32_t N_mask_3			:10;
+		uint32_t N_mask_2			:10;
+		uint32_t N_mask_1_4lsb			:4;
+#endif
+		/* WORD [9] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t N_mask_4_2lsb			:2;
+		uint32_t N_mask_5			:10;
+		uint32_t N_mask_6			:10;
+		uint32_t N_mask_7			:10;
+#else
+		uint32_t N_mask_7			:10;
+		uint32_t N_mask_6			:10;
+		uint32_t N_mask_5			:10;
+		uint32_t N_mask_4_2lsb			:2;
+#endif
+		/* WORD [10] */
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+		uint32_t N_shift_0			:4;
+		uint32_t N_shift_1			:4;
+		uint32_t N_shift_2			:4;
+		uint32_t N_shift_3			:4;
+		uint32_t N_shift_4			:4;
+		uint32_t N_shift_5			:4;
+		uint32_t N_shift_6			:4;
+		uint32_t N_shift_7			:4;
+#else
+		uint32_t N_shift_7			:4;
+		uint32_t N_shift_6			:4;
+		uint32_t N_shift_5			:4;
+		uint32_t N_shift_4			:4;
+		uint32_t N_shift_3			:4;
+		uint32_t N_shift_2			:4;
+		uint32_t N_shift_1			:4;
+		uint32_t N_shift_0			:4;
+#endif
+		/* WORD [11] */
+		uint32_t nonce_top;
+		/* WORD [12] */
+		uint32_t nonce_bottom;
+	} __attribute__((packed)) packed_params;
+
+	packed_params.padding = 0;
+	packed_params.bad_address_mask_0_6msb = (params->bad_address_mask[0] >> 4) & 0x03F;
+	packed_params.bad_address_mask_0_4lsb = params->bad_address_mask[0] & 0x00F;
+	packed_params.bad_address_mask_1 = params->bad_address_mask[1];
+	packed_params.bad_address_match_0 = params->bad_address_match[0];
+	packed_params.bad_address_match_1_8msb = (params->bad_address_match[1] >> 2) & 0x0FF;
+	packed_params.bad_address_match_1_2lsb = params->bad_address_match[1] & 0x003;
+	packed_params.difficulty = params->difficulty;
+	packed_params.thread_enable = params->thread_enable;
+	packed_params.thread_base_address_0 = params->thread_base_address[0];
+	packed_params.thread_base_address_1_6msb = (params->thread_base_address[1] >> 4) & 0x03F;
+	packed_params.thread_base_address_1_4lsb = params->thread_base_address[1] & 0x00F;
+	packed_params.thread_base_address_2 = params->thread_base_address[2];
+	packed_params.thread_base_address_3 = params->thread_base_address[3];
+	packed_params.thread_base_address_4_8msb = (params->thread_base_address[4] >> 2) & 0x0FF;
+	packed_params.thread_base_address_4_2lsb = params->thread_base_address[4] & 0x003;
+	packed_params.thread_base_address_5 = params->thread_base_address[5];
+	packed_params.thread_base_address_6 = params->thread_base_address[6];
+	packed_params.thread_base_address_7 = params->thread_base_address[7];
+	packed_params.lookup_gap_mask_0 = params->lookup_gap_mask[0];
+	packed_params.lookup_gap_mask_1 = params->lookup_gap_mask[1];
+	packed_params.lookup_gap_mask_2 = params->lookup_gap_mask[2];
+	packed_params.lookup_gap_mask_3_2msb = (params->lookup_gap_mask[3] >> 8) & 0x003;
+	packed_params.lookup_gap_mask_3_8lsb = params->lookup_gap_mask[3] & 0x0FF;
+	packed_params.lookup_gap_mask_4 = params->lookup_gap_mask[4];
+	packed_params.lookup_gap_mask_5 = params->lookup_gap_mask[5];
+	packed_params.lookup_gap_mask_6_4msb = (params->lookup_gap_mask[6] >> 6) & 0x00F;
+	packed_params.lookup_gap_mask_6_6lsb = params->lookup_gap_mask[6] & 0x03F;
+	packed_params.lookup_gap_mask_7 = params->lookup_gap_mask[7];
+	packed_params.N_mask_0 = params->N_mask[0];
+	packed_params.N_mask_1_6msb = (params->N_mask[1] >> 4) & 0x03F;
+	packed_params.N_mask_1_4lsb = params->N_mask[1] & 0x00F;
+	packed_params.N_mask_2 = params->N_mask[2];
+	packed_params.N_mask_3 = params->N_mask[3];
+	packed_params.N_mask_4_8msb = (params->N_mask[4] >> 2) & 0x0FF;
+	packed_params.N_mask_4_2lsb = params->N_mask[4] & 0x003;
+	packed_params.N_mask_5 = params->N_mask[5];
+	packed_params.N_mask_6 = params->N_mask[6];
+	packed_params.N_mask_7 = params->N_mask[7];
+	packed_params.N_shift_0 = params->N_shift[0];
+	packed_params.N_shift_1 = params->N_shift[1];
+	packed_params.N_shift_2 = params->N_shift[2];
+	packed_params.N_shift_3 = params->N_shift[3];
+	packed_params.N_shift_4 = params->N_shift[4];
+	packed_params.N_shift_5 = params->N_shift[5];
+	packed_params.N_shift_6 = params->N_shift[6];
+	packed_params.N_shift_7 = params->N_shift[7];
+	packed_params.nonce_top = params->nonce_top;
+	packed_params.nonce_bottom = params->nonce_bottom;
+
+	src = (uint32_t *)&packed_params;
+	dst = (uint32_t *)(&setup_core_cmd[send_size - sizeof(packed_params)]);
+	for (i = 0; i < (sizeof(packed_params) / 4); ++i)
+		dst[i] = htobe32(src[i]);
+
+	rxbuf = spi_transfer(spi, setup_core_cmd, send_size, transfer_size, 0, &errors);
+	if (NULL == rxbuf) {
+		applog(LOG_ERR, "%s[%d:%d] knc_titan_setup_core: Unrecognized error", repr, die, core);
+		return false;
+	}
+	if (0 != errors) {
+		applog(LOG_ERR, "%s[%d:%d] knc_titan_setup_core: Communication failed, errors = 0x%X", repr, die, core, errors);
+		return false;
+	}
+	return true;
+}

+ 15 - 0
titan-asic.h

@@ -8,6 +8,7 @@
 #define	KNC_TITAN_DIES_PER_ASIC		4
 #define	KNC_TITAN_DIES_PER_ASIC		4
 #define	KNC_TITAN_CORES_PER_DIE		48
 #define	KNC_TITAN_CORES_PER_DIE		48
 #define	KNC_TITAN_CORES_PER_ASIC	(KNC_TITAN_CORES_PER_DIE * KNC_TITAN_DIES_PER_ASIC)
 #define	KNC_TITAN_CORES_PER_ASIC	(KNC_TITAN_CORES_PER_DIE * KNC_TITAN_DIES_PER_ASIC)
+#define	KNC_TITAN_THREADS_PER_CORE	8
 #define	KNC_TITAN_NONCES_PER_REPORT	5
 #define	KNC_TITAN_NONCES_PER_REPORT	5
 
 
 #define	KNC_TITAN_ASIC_REVISION		0xA102
 #define	KNC_TITAN_ASIC_REVISION		0xA102
@@ -29,8 +30,22 @@ struct titan_report {
 	} nonces[KNC_TITAN_NONCES_PER_REPORT];
 	} nonces[KNC_TITAN_NONCES_PER_REPORT];
 };
 };
 
 
+struct titan_setup_core_params {
+	uint16_t bad_address_mask[2];
+	uint16_t bad_address_match[2];
+	uint8_t difficulty;
+	uint8_t thread_enable;
+	uint16_t thread_base_address[KNC_TITAN_THREADS_PER_CORE];
+	uint16_t lookup_gap_mask[KNC_TITAN_THREADS_PER_CORE];
+	uint16_t N_mask[KNC_TITAN_THREADS_PER_CORE];
+	uint8_t N_shift[KNC_TITAN_THREADS_PER_CORE];
+	uint32_t nonce_top;
+	uint32_t nonce_bottom;
+};
+
 bool knc_titan_spi_get_info(const char *repr, struct spi_port * const spi, struct titan_info_response *resp, int die, int core_hint);
 bool knc_titan_spi_get_info(const char *repr, struct spi_port * const spi, struct titan_info_response *resp, int die, int core_hint);
 bool knc_titan_get_report(const char *repr, struct spi_port * const spi, struct titan_report *report, int die, int core);
 bool knc_titan_get_report(const char *repr, struct spi_port * const spi, struct titan_report *report, int die, int core);
 bool knc_titan_set_work(const char *repr, struct spi_port * const spi, struct titan_report *report, int die, int core, int slot, struct work *work, bool urgent);
 bool knc_titan_set_work(const char *repr, struct spi_port * const spi, struct titan_report *report, int die, int core, int slot, struct work *work, bool urgent);
+bool knc_titan_setup_core(const char *repr, struct spi_port * const spi, struct titan_setup_core_params *params, int die, int core);
 
 
 #endif /* __TITAN_ASIC_H */
 #endif /* __TITAN_ASIC_H */