From df6873eff9f6ea216ac1d3e34f0eba2c4e6f88fa Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 13 Oct 2013 17:23:51 +1100 Subject: [PATCH] Remove old initialisation code from hashfast, use hf protocol library where possible and prepare for new driver model. --- driver-hashfast.c | 117 ++------------------------ driver-hashfast.h | 208 +--------------------------------------------- hf_protocol.h | 1 + 3 files changed, 10 insertions(+), 316 deletions(-) diff --git a/driver-hashfast.c b/driver-hashfast.c index 3af61d63..f835289a 100644 --- a/driver-hashfast.c +++ b/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, diff --git a/driver-hashfast.h b/driver-hashfast.h index 7daea2a7..f9defdfd 100644 --- a/driver-hashfast.h +++ b/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 ) 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 */ diff --git a/hf_protocol.h b/hf_protocol.h index 3cccd52a..d862c76b 100644 --- a/hf_protocol.h +++ b/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