Browse Source

Remove old initialisation code from hashfast, use hf protocol library where possible and prepare for new driver model.

Con Kolivas 12 years ago
parent
commit
df6873eff9
3 changed files with 10 additions and 316 deletions
  1. 7 110
      driver-hashfast.c
  2. 2 206
      driver-hashfast.h
  3. 1 0
      hf_protocol.h

+ 7 - 110
driver-hashfast.c

@@ -25,7 +25,7 @@
 
 static unsigned char crc8_table[256];	/* CRC-8 table */
 
-void hf_init_crc8(void)
+static void hf_init_crc8(void)
 {
 	int i,j;
 	unsigned char crc;
@@ -50,8 +50,6 @@ static unsigned char __maybe_unused hf_crc8(unsigned char *h)
 	return crc;
 }
 
-static hf_info_t **hashfast_infos;
-
 struct hf_cmd {
 	int cmd;
 	char *cmd_name;
@@ -115,106 +113,13 @@ static int __maybe_unused hashfast_send_frame(struct cgpu_info *hashfast, uint8_
 	return 0;
 }
 
-static int hashfast_reset(struct cgpu_info __maybe_unused *hashfast)
+static int __maybe_unused hashfast_reset(struct cgpu_info __maybe_unused *hashfast)
 {
 	return 0;
 }
 
-static bool hashfast_detect_common(struct cgpu_info *hashfast, int baud)
+static bool hashfast_detect_common(struct cgpu_info __maybe_unused *hashfast)
 {
-	hf_core_t **c, *core;
-	hf_info_t *info;
-	hf_job_t *j;
-	int i, k, ret;
-
-	hashfast_infos = realloc(hashfast_infos, sizeof(hf_info_t *) * (total_devices + 1));
-	if (unlikely(!hashfast_infos))
-		quit(1, "Failed to realloc hashfast_infos in hashfast_detect_common");
-	// Assume success, allocate info ahead of reset, so reset can fill fields in
-	info = calloc(sizeof(hf_info_t), 1);
-	if (unlikely(!info))
-		quit(1, "Failed to calloc info in hashfast_detect_common");
-	hashfast_infos[hashfast->device_id] = info;
-	info->tacho_enable = 1;
-	info->miner_count = 1;
-	info->max_search_difficulty = 12;
-	info->baud_rate = baud;
-
-	ret = hashfast_reset(hashfast);
-	if (unlikely(ret)) {
-		free(info);
-		hashfast_infos[hashfast->device_id] = NULL;
-		return false;
-	}
-
-	/* 1 Pending, 1 active for each */
-	info->inflight_target = info->asic_count * info->core_count *2;
-
-	switch (info->device_type) {
-		default:
-		case HFD_G1:
-			/* Implies hash_loops = 0 for full nonce range */
-			break;
-		case HFD_ExpressAGX:
-			/* ExpressAGX */
-			info->hash_loops = 1 << 26;
-			break;
-		case HFD_VC709:
-			/* Virtex 7
-			 * Adjust according to fast or slow configuration */
-			if (info->core_count > 5)
-				info->hash_loops = 1 << 26;
-			else
-				info->hash_loops = 1 << 30;
-			break;
-	}
-	applog(LOG_INFO, "Hashfast Detect: chips %d cores %d inflight_target %d entries",
-	       info->asic_count, info->core_count, info->inflight_target);
-
-	/* Initialize list heads */
-	info->active.next = &info->active;
-	info->active.prev = &info->active;
-	info->inactive.next = &info->inactive;
-	info->inactive.prev = &info->inactive;
-
-	/* Allocate core data structures */
-	info->cores = calloc(info->asic_count, sizeof(hf_core_t  *));
-	if (unlikely(!info->cores))
-		quit(1, "Failed to calloc info cores in hashfast_detect_common");
-	c = info->cores;
-
-	for (i = 0; i < info->asic_count; i++) {
-		*c = calloc(info->core_count, sizeof(hf_core_t));
-		if (unlikely(!*c))
-			quit(1, "Failed to calloc hf_core_t in hashfast_detect_common");
-		for (k = 0, core = *c; k < info->core_count; k++, core++)
-			core->enabled = 1;
-		c++;
-	}
-
-	/* Now allocate enough structures to hold all the in-flight work
-	 * 2 per core - one active and one pending. These go on the inactive
-	 * queue, and get used/recycled as required. */
-	for (i = 0; i < info->asic_count * info->core_count * 2; i++) {
-		j = calloc(sizeof(hf_job_t), 1);
-		if (unlikely(!j))
-			quit(1, "Failed to calloc hf_job_t in hashfast_detect_common");
-		list_add(&info->inactive, &j->l);
-	}
-
-	info->inactive_count = info->asic_count * info->core_count * 2;
-	applog(LOG_INFO, "Hashfast Detect: Allocated %d job entries",
-	       info->inflight_target);
-
-		// Finally, allocate enough space to hold the work array.
-	info->max_work = info->inflight_target;
-	info->num_sequence = 1024;
-
-	info->work = calloc(info->max_work, sizeof(hf_work_t));
-	if (unlikely(!info->work))
-		quit(1, "Failed to calloc info work in hashfast_detect_common");
-	applog(LOG_INFO, "Hashfast Detect: Allocated space for %d work entries", info->inflight_target);
-
 	return true;
 }
 
@@ -228,7 +133,6 @@ static void hashfast_usb_initialise(struct cgpu_info *hashfast)
 static bool hashfast_detect_one_usb(libusb_device *dev, struct usb_find_devices *found)
 {
 	struct cgpu_info *hashfast;
-	int baud = DEFAULT_BAUD_RATE;
 
 	hashfast = usb_alloc_cgpu(&hashfast_drv, HASHFAST_MINER_THREADS);
 	if (!hashfast)
@@ -242,12 +146,11 @@ static bool hashfast_detect_one_usb(libusb_device *dev, struct usb_find_devices
 	}
 
 	hashfast->usbdev->usb_type = USB_TYPE_STD;
-	usb_set_pps(hashfast, HASHFAST_USB_PACKETSIZE);
 
 	hashfast_usb_initialise(hashfast);
 
 	add_cgpu(hashfast);
-	return hashfast_detect_common(hashfast, baud);
+	return hashfast_detect_common(hashfast);
 }
 
 static void hashfast_detect(bool hotplug)
@@ -263,12 +166,7 @@ static bool hashfast_prepare(struct thr_info __maybe_unused *thr)
 	return true;
 }
 
-static bool hashfast_fill(struct cgpu_info __maybe_unused *hashfast)
-{
-	return true;
-}
-
-static int64_t hashfast_scanhash(struct thr_info __maybe_unused *thr)
+static int64_t hashfast_scanwork(struct thr_info __maybe_unused *thr)
 {
 	return 0;
 }
@@ -293,9 +191,8 @@ struct device_drv hashfast_drv = {
 	.name = "HFA",
 	.drv_detect = hashfast_detect,
 	.thread_prepare = hashfast_prepare,
-	.hash_work = hash_queued_work,
-	.queue_full = hashfast_fill,
-	.scanwork = hashfast_scanhash,
+	.hash_work = &hash_driver_work,
+	.scanwork = hashfast_scanwork,
 	.get_api_stats = hashfast_api_stats,
 	.reinit_device = hashfast_init,
 	.thread_shutdown = hashfast_shutdown,

+ 2 - 206
driver-hashfast.h

@@ -14,213 +14,9 @@
 #ifdef USE_HASHFAST
 #include "miner.h"
 #include "elist.h"
+#include "hf_protocol.h"
 
-#define HASHFAST_MINER_THREADS      1
-
-// Some serial protocol definitions
-#define DEFAULT_BAUD_RATE	    115200
-
-#define HF_PREAMBLE             (uint8_t) 0xaa
-#define HF_BROADCAST_ADDRESS    (uint8_t) 0xff
-
-// Operation codes (Second header byte)
-#define OP_NULL		0
-#define OP_ROOT         1
-#define OP_RESET        2
-#define OP_PLL_CONFIG   3
-#define OP_ADDRESS      4
-#define OP_READDRESS    5
-#define OP_HIGHEST      6
-#define OP_BAUD         7
-#define OP_UNROOT       8
-
-#define OP_HASH         9
-#define OP_NONCE        10
-#define OP_ABORT        11
-#define OP_STATUS       12
-#define OP_GPIO         13
-#define OP_CONFIG       14
-#define OP_STATISTICS   15
-#define OP_GROUP        16
-#define OP_CLOCKGATE    17
-
-// All packets begin with a standard 8 byte header
-struct hf_header {
-	uint8_t  preamble;                      // Always 0xaa
-	uint8_t  operation_code;
-	uint8_t  chip_address;
-	uint8_t  core_address;
-	uint16_t hdata;                         // Header specific data
-	uint8_t  data_length;                   // .. of data frame to follow, in 4 byte blocks, 0=no data
-	uint8_t  crc8;                          // Computed across bytes 1-6 inclusive
-} __attribute__((packed,aligned(4)));   	// 8 bytes total
-
-// Body of packet for an OP_HASH operation
-struct hf_hash {
-	uint8_t  midstate[32];                  // Computed from first half of block header
-	uint8_t  merkle_residual[4];            // From block header
-	uint32_t timestamp;                     // From block header
-	uint32_t bits;                          // Actual difficulty target for block header
-	uint32_t starting_nonce;                // Usually set to 0
-	uint32_t nonce_loops;                   // How many nonces to search, or 0 for 2^32
-	uint16_t ntime_loops:12;                // How many times to roll timestamp, or 0
-	uint16_t spare1:4;
-	uint8_t  search_difficulty;             // Search difficulty to use, number of leading '0' bits required
-	uint8_t  spare2;
-	uint32_t spare3;
-	uint32_t crc32;                         // Computed across all preceding data fields
-} __attribute__((packed,aligned(4)));           // 64 bytes total, including CRC
-
-// How nonces are returned in OP_NONCE packets
-struct hf_candidate_nonce {
-	uint32_t nonce;                         // Candidate nonce
-	uint16_t sequence;                      // Sequence number from corresponding OP_HASH
-	uint16_t ntime:12;                      // ntime offset, if ntime roll occurred
-	uint16_t search:1;                      // Search forward next 128 nonces to find solution
-	uint16_t spare:3;
-} __attribute__((packed,aligned(4)));
-
-// Body of packet for an OP_CONFIG operation
-struct hf_config_data {
-	uint16_t status_period:11;                  // Periodic status time, msec
-	uint16_t enable_periodic_status:1;          // Send periodic status
-	uint16_t send_status_on_core_idle:1;        // Schedule status whenever core goes idle
-	uint16_t send_status_on_pending_empty:1;    // Schedule status whenever core pending goes idle
-	uint16_t pwm_active_level:1;                // Active level of PWM outputs, if used
-	uint16_t forward_all_privileged_packets:1;  // Forward priv pkts -- diagnostic
-	uint8_t  status_batch_delay;                // Batching delay, time to wait before actually sending status
-	uint8_t  watchdog:7;                        // Watchdog timeout, seconds
-	uint8_t  disable_sensors:1;                 // Diagnostic
-
-        uint8_t  rx_header_timeout:7;               // Header timeout in char times
-	uint8_t  rx_ignore_header_crc:1;            // Ignore rx header crc's (diagnostic)
-	uint8_t  rx_data_timeout:7;                 // Data timeout in char times / 16
-	uint8_t  rx_ignore_data_crc:1;              // Ignore rx data crc's (diagnostic)
-	uint8_t  stats_interval:7;                  // Minimum interval to report statistics (seconds)
-	uint8_t  stat_diagnostic:1;                 // Never set this
-	uint8_t  measure_interval;                  // Die temperature measurment interval (msec)
-
-        uint32_t one_usec:12;                       // How many LF clocks per usec.
-	uint32_t max_nonces_per_frame:4;            // Maximum # of nonces to combine in a single frame
-	uint32_t voltage_sample_points:8;           // Bit mask for sample points (up to 5 bits set)
-	uint32_t pwm_phases:2;                      // phases - 1
-	uint32_t trim:4;                            // Trim value for temperature measurements
-	uint32_t clock_diagnostic:1;                // Never set this
-	uint32_t forward_all_packets:1;             // Forward everything - diagnostic.
-
-        uint16_t pwm_period;                        // Period of PWM outputs, in reference clock cycles
-	uint16_t pwm_pulse_period;                  // Initial count, phase 0
-} __attribute__((packed,aligned(4)));
-
-// What comes back in the body of an OP_STATISTICS frame
-struct hf_statistics {
-	uint8_t rx_header_crc;                      // Header CRC's
-	uint8_t rx_body_crc;                        // Data CRC's
-	uint8_t rx_header_timeouts;                 // Header timeouts
-	uint8_t rx_body_timeouts;                   // Data timeouts
-	uint8_t core_nonce_fifo_full;               // Core nonce Q overrun events
-	uint8_t array_nonce_fifo_full;              // System nonce Q overrun events
-	uint8_t stats_overrun;                      // Overrun in statistics reporting
-	uint8_t spare;
-} __attribute__((packed,aligned(4)));
-
-
-// Not really necessary (could just link directly to CGMiner's work structures), but these are
-// here as an internal place to stage split jobs in the future, e.g. ntime rolling across
-// multiple cores.
-typedef struct hf_work_t {
-	struct work     *work;                      // Finally out to cgminer's work
-
-	uint8_t         data[128];                  // XXX These are only replicated here to help de-couple the
-	uint8_t         midstate[32];               // XXX driver code from cgminer's specifics, since this is
-	uint8_t         target[32];                 // XXX a sample driver. There's no other reason.
-
-	int             split_count;                // How many cores this is split between
-} hf_work_t;
-
-// Internal representation of a "job". Each core should normally have one active job and one pending job queued to it.
-// This is where the ALL IMPORTANT sequence number is kept. When jobs are created, this structure is put in the "active"
-// list (unique to the asic/core), and an incrementing sequence number is assigned to the job. Only when a sequence number
-// that matches or exceeds (modulo <max sequence>) this number in a returned OP_STATUS, do we know that the "busy" bits
-// associated with this same core represent the job status, i.e. the associated OP_HASH is no longer in flight.
-typedef struct hf_job_t {
-	struct list_head l;
-
-	uint8_t chip;                               // Chip address
-	uint8_t core;                               // Core address
-	uint16_t sequence;                          // Copy of the active sequence number
-
-	hf_work_t *work;                            // Pointer to the work block
-
-} hf_job_t;
-
-// Per-core structure
-typedef struct hf_core_t {
-	hf_job_t *active;                           // Active job on this core, NULL if none
-	hf_job_t *pending;                          // Pending job on this core, NULL if none
-	uint8_t enabled;                            // 1 = enabled, 0 = disabled
-	uint8_t inflight;                           // How many jobs are "inflight": 0, 1 or 2
-	uint8_t seen_allbusy;                       // We've seen both active and pending queues busy
-} hf_core_t;                                        // since the last OP_HASH was queued
-
-// Per device structure. This is found by looking up an array, which is indexed
-// by CGMiner's cgpu_info.device_id field.
-typedef struct hf_info_t {
-	int miner_count;
-	int timeout;
-	int baud_rate;                          // Baud rate, if applicable
-	int ref_frequency;                      // Reference clock rate
-	int asic_count;                         // # of chips in the chain
-	int core_count;                         // # of cores per chip
-	int device_type;                        // What sort of device this is
-	int max_search_difficulty;              // # of bits set to 0 in hash
-	int inflight_target;                    // Set to chips * cores * 2 (1 active, 1 pending each core)
-	int hash_sequence;                      // The last hash sequence #
-	int num_sequence;                       // A power of 2. What the sequence number range is.
-	int num_work;                           // Number of "work" entries in work queue
-	int max_work;                           // Target maximum number of "work" entries in work queue
-						// If work is split between cores, then max_work < inflight_target.
-	int last_log;                           // Last OP_STATUS log time in seconds
-
-	float thermal_trip_temperature;         // Thermal trip temperature in degrees C
-	int thermal_trip_limit;                 // Thermal trip limit in raw device adc counts (derived from above)
-	int tacho_enable;                       // Set if there is a tacho to be read
-
-	uint64_t hash_loops;                    // XXX Temp. How many nonces to cycle through (range limited for FPGA emulation)
-
-	int no_matching_work;
-
-	struct list_head active;                  // Double linked list through all ACTIVE in-flight jobs (hf_job_t's)
-	struct list_head inactive;                // Double linked list through all INACTIVE job blocks (hf_job_t's)
-
-	int active_count;                       // How many active hf_job_t's are out there
-	int inactive_count;                     // How many inactive hf_job_t's are out there
-
-	hf_core_t **cores;                      // Points to array of chips, which each point to array of cores
-	hf_work_t *work;                        // Points to array of work
-} hf_info_t;
-
-// The sequence distance between a sent and received sequence number.
-#define SEQUENCE_DISTANCE(tx,rx)        ((tx)>=(rx)?((tx)-(rx)):(info->num_sequence+(tx)-(rx)))
-
-// Values info->device_type can take, comes from a completed OP_ADDRESS cycle
-#define HFD_G1                          1       /* A real G-1 ASIC */
-#define HFD_VC709                       128     /* FPGA Emulation */
-#define HFD_ExpressAGX                  129     /* FPGA Emulation */
-
-// Some USB defines
-#define HASHFAST_USB_PACKETSIZE         512     /* XXX Fix this. */
-
-// Some low level serial defines
-#define HASHFAST_READ_TIME(baud) ((double)HASHFAST_READ_SIZE * (double)8.0 / (double)(baud))
-
-#define ASSERT1(condition) __maybe_unused static char sizeof_uint32_t_must_be_4[(condition)?1:-1]
-ASSERT1(sizeof(uint32_t) == 4);
-
-hf_info_t **hashfast_info;
-
-void hf_init_crc8(void);
-void hf_init_crc32(void);
+#define HASHFAST_MINER_THREADS 1
 
 #endif /* USE_HASHFAST */
 #endif	/* HASHFAST_H */

+ 1 - 0
hf_protocol.h

@@ -22,6 +22,7 @@
 #define HF_GWQ_ADDRESS          (uint8_t) 254
 
 // Serial protocol operation codes (Second header byte)
+#define OP_NULL         0
 #define OP_ROOT         1
 #define OP_RESET        2
 #define OP_PLL_CONFIG   3