Browse Source

Structure changes for OP_NONCE, add big endian header

nfactor-troky
Adrian Port 11 years ago committed by Con Kolivas
parent
commit
065054f658
  1. 12
      driver-hashfast.c
  2. 685
      hf_protocol.h
  3. 267
      hf_protocol_be.h

12
driver-hashfast.c

@ -497,7 +497,7 @@ static void search_for_extra_nonce(struct thr_info *thr, struct work *work,
int i; int i;
/* No function to test with ntime offsets yet */ /* No function to test with ntime offsets yet */
if (n->ntime) if (n->ntime & HF_NTIME_MASK)
return; return;
for (i = 0; i < 128; i++, nonce++) { for (i = 0; i < 128; i++, nonce++) {
/* We could break out of this early if nonce wraps or if we /* We could break out of this early if nonce wraps or if we
@ -520,8 +520,8 @@ static void hfa_parse_nonce(struct thr_info *thr, struct cgpu_info *hashfast,
for (i = 0; i < num_nonces; i++, n++) { for (i = 0; i < num_nonces; i++, n++) {
struct work *work; struct work *work;
applog(LOG_DEBUG, "HFA %d: OP_NONCE: %2d: %2d: search %1d ntime %2d sequence %4d nonce 0x%08x", applog(LOG_DEBUG, "HFA %d: OP_NONCE: %2d: %2d: ntime %2d sequence %4d nonce 0x%08x",
hashfast->device_id, h->chip_address, i, n->search, n->ntime, n->sequence, n->nonce); hashfast->device_id, h->chip_address, i, n->ntime & HF_NTIME_MASK, n->sequence, n->nonce);
// Find the job from the sequence number // Find the job from the sequence number
mutex_lock(&info->lock); mutex_lock(&info->lock);
@ -533,11 +533,11 @@ static void hfa_parse_nonce(struct thr_info *thr, struct cgpu_info *hashfast,
applog(LOG_INFO, "HFA %d: No matching work!", hashfast->device_id); applog(LOG_INFO, "HFA %d: No matching work!", hashfast->device_id);
} else { } else {
applog(LOG_DEBUG, "HFA %d: OP_NONCE: sequence %d: submitting nonce 0x%08x ntime %d", applog(LOG_DEBUG, "HFA %d: OP_NONCE: sequence %d: submitting nonce 0x%08x ntime %d",
hashfast->device_id, n->sequence, n->nonce, n->ntime); hashfast->device_id, n->sequence, n->nonce, n->ntime & HF_NTIME_MASK);
if ((n->nonce & 0xffff0000) == 0x42420000) // XXX REMOVE THIS if ((n->nonce & 0xffff0000) == 0x42420000) // XXX REMOVE THIS
break; // XXX PHONEY EMULATOR NONCE break; // XXX PHONEY EMULATOR NONCE
submit_noffset_nonce(thr, work, n->nonce, n->ntime); // XXX Return value from submit_nonce is error if set submit_noffset_nonce(thr, work, n->nonce, n->ntime & HF_NTIME_MASK); // XXX Return value from submit_nonce is error if set
if (unlikely(n->search)) { if (unlikely(n->ntime & HF_NONCE_SEARCH)) {
/* This tells us there is another share in the /* This tells us there is another share in the
* next 128 nonces */ * next 128 nonces */
applog(LOG_DEBUG, "HFA %d: OP_NONCE: SEARCH PROXIMITY EVENT FOUND", applog(LOG_DEBUG, "HFA %d: OP_NONCE: SEARCH PROXIMITY EVENT FOUND",

685
hf_protocol.h

@ -1,336 +1,349 @@
// //
// Copyright 2013 HashFast LLC // Copyright 2013 HashFast LLC
// //
// This program is free software; you can redistribute it and/or modify it // This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free // under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option) // Software Foundation; either version 3 of the License, or (at your option)
// any later version. See COPYING for more details. // any later version. See COPYING for more details.
// //
// Useful data structures and values for interfacing with HashFast products // Useful data structures and values for interfacing with HashFast products
// //
// Version 1.0
//
#ifndef _HF_PROTOCOL_H_
#define _HF_PROTOCOL_H_ #ifndef _HF_PROTOCOL_H_
#define _HF_PROTOCOL_H_
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#error "This header uses bit fields and has byte ordering assumptions suitable only for Little Endian platforms" #define HF_PROTOCOL_VERSION ((0<<8)|1)
#endif
#define HF_PREAMBLE (uint8_t) 0xaa
#define HF_PREAMBLE (uint8_t) 0xaa #define HF_BROADCAST_ADDRESS (uint8_t) 0xff
#define HF_BROADCAST_ADDRESS (uint8_t) 0xff #define HF_GWQ_ADDRESS (uint8_t) 254
#define HF_GWQ_ADDRESS (uint8_t) 254
// Serial protocol operation codes (Second header byte)
// Serial protocol operation codes (Second header byte) #define OP_NULL 0
#define OP_NULL 0 #define OP_ROOT 1
#define OP_ROOT 1 #define OP_RESET 2
#define OP_RESET 2 #define OP_PLL_CONFIG 3
#define OP_PLL_CONFIG 3 #define OP_ADDRESS 4
#define OP_ADDRESS 4 #define OP_READDRESS 5
#define OP_READDRESS 5 #define OP_HIGHEST 6
#define OP_HIGHEST 6 #define OP_BAUD 7
#define OP_BAUD 7 #define OP_UNROOT 8
#define OP_UNROOT 8
#define OP_HASH 9
#define OP_HASH 9 #define OP_NONCE 10
#define OP_NONCE 10 #define OP_ABORT 11
#define OP_ABORT 11 #define OP_STATUS 12
#define OP_STATUS 12 #define OP_GPIO 13
#define OP_GPIO 13 #define OP_CONFIG 14
#define OP_CONFIG 14 #define OP_STATISTICS 15
#define OP_STATISTICS 15 #define OP_GROUP 16
#define OP_GROUP 16 #define OP_CLOCKGATE 17
#define OP_CLOCKGATE 17
// Conversions for the ADC readings from GN on-chip sensors
// Generic header #define GN_CORE_VOLTAGE(a) ((float)(a)/256*1.2)
struct hf_header { #define GN_DIE_TEMPERATURE(a) ((((float)(a)*240)/4096.0)-61.5)
uint8_t preamble; // Always 0xaa
uint8_t operation_code; // The sequence distance between a sent and received sequence number.
uint8_t chip_address; #define SEQUENCE_DISTANCE(tx,rx) ((tx)>=(rx)?((tx)-(rx)):(info->num_sequence+(tx)-(rx)))
uint8_t core_address;
uint16_t hdata; // Header specific data // Values the protocol field in the above structure may take
uint8_t data_length; // .. of data frame to follow, in 4 byte blocks, 0=no data #define PROTOCOL_USB_MAPPED_SERIAL 0
uint8_t crc8; // Computed across bytes 1-6 inclusive #define PROTOCOL_GLOBAL_WORK_QUEUE 1
} __attribute__((packed,aligned(4))); // 8 bytes total
// Conversions for the board/module level sensors
// Header specific to OP_PLL_CONFIG #define M_VOLTAGE(a) ((float)(a)*19.0734e-6)
struct hf_pll_config { #define M_PHASE_CURRENT(a) ((float)(a)*0.794728597e-3)
uint8_t preamble;
uint8_t operation_code; // Values info->device_type can take
uint8_t chip_address; #define HFD_G1 1 // HashFast G-1 GN ASIC
#define HFD_VC709 128
uint8_t pll_divr:6; #define HFD_ExpressAGX 129
uint8_t pll_bypass:1;
uint8_t pll_reset:1; // USB interface specific operation codes
#define OP_USB_INIT 128 // Initialize USB interface details
uint16_t pll_divf:8; #define OP_GET_TRACE 129 // Send back the trace buffer if present
uint16_t spare1:1; // Must always be 0 #define OP_LOOPBACK_USB 130
uint16_t pll_divq:3; #define OP_LOOPBACK_UART 131
uint16_t pll_range:3; #define OP_DFU 132 // Jump into the boot loader
uint16_t pll_fse:1; // Must always be 1 #define OP_USB_SHUTDOWN 133 // Initialize USB interface details
#define OP_DIE_STATUS 134 // Die status. There are 4 die per ASIC
uint8_t data_length; // Always 0 #define OP_GWQ_STATUS 135 // Global Work Queue protocol status
uint8_t crc8; // Computed across bytes 1-6 inclusive #define OP_WORK_RESTART 136 // Stratum work restart regime
} __attribute__((packed,aligned(4))); // 8 bytes total #define OP_USB_STATS1 137 // Statistics class 1
#define OP_USB_GWQSTATS 138 // GWQ protocol statistics
// OP_HASH serial data #define OP_USB_NOTICE 139 // Asynchronous notification event
struct hf_hash_serial { #define OP_USB_DEBUG 255
uint8_t midstate[32]; // Computed from first half of block header
uint8_t merkle_residual[4]; // From block header // HashFast vendor and product ID's
uint32_t timestamp; // From block header #define HF_USB_VENDOR_ID 0x297c
uint32_t bits; // Actual difficulty target for block header #define HF_USB_PRODUCT_ID_G1 0x0001
uint32_t starting_nonce; // Usually set to 0
uint32_t nonce_loops; // How many nonces to search, or 0 for 2^32 // If this bit is set, search forward for other nonce(s)
uint16_t ntime_loops:12; // How many times to roll timestamp, or 0 #define HF_NTIME_MASK 0xfff // Mask for for ntime
uint16_t spare1:4; #define HF_NONCE_SEARCH 0x1000 // Search bit in candidate_nonce -> ntime
uint8_t search_difficulty; // Search difficulty to use, # of '0' digits required
uint8_t option; //
uint32_t group:8; // Fault codes that can be returned in struct hf_usb_init_base.operation_status
uint32_t spare3:24; //
uint32_t crc32; // Computed across all preceding data fields #define E_RESET_TIMEOUT 1
} __attribute__((packed,aligned(4))); // 64 bytes total, including CRC #define E_ADDRESS_TIMEOUT 2
#define E_CLOCKGATE_TIMEOUT 3
// OP_HASH usb data - squashed so header+data = 64 bytes #define E_CONFIG_TIMEOUT 4
struct hf_hash_usb { #define E_EXCESS_CORE_FAILURES 5
uint8_t midstate[32]; // Computed from first half of block header
uint8_t merkle_residual[4]; // From block header #define U32SIZE(x) (sizeof(x)/sizeof(uint32_t))
uint32_t timestamp; // From block header
uint32_t bits; // Actual difficulty target for block header
uint32_t starting_nonce; // Usually set to 0 // Structure definitions, LE platforms
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 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
uint16_t spare1:4; #include "hf_protocol_be.h"
uint8_t search_difficulty; // Search difficulty to use, # of '0' digits required #else
uint8_t group; // Non-zero for valid group // Generic header
} __attribute__((packed,aligned(4))); struct hf_header {
uint8_t preamble; // Always 0xaa
// OP_NONCE data uint8_t operation_code;
struct hf_candidate_nonce { uint8_t chip_address;
uint32_t nonce; // Candidate nonce uint8_t core_address;
uint16_t sequence; // Sequence number from corresponding OP_HASH uint16_t hdata; // Header specific data
uint16_t ntime:12; // ntime offset, if ntime roll occurred uint8_t data_length; // .. of data frame to follow, in 4 byte blocks, 0=no data
uint16_t search:1; // Search forward next 128 nonces to find solution uint8_t crc8; // Computed across bytes 1-6 inclusive
uint16_t spare:3; } __attribute__((packed,aligned(4))); // 8 bytes total
} __attribute__((packed,aligned(4)));
// Header specific to OP_PLL_CONFIG
// OP_CONFIG data struct hf_pll_config {
struct hf_config_data { uint8_t preamble;
uint16_t status_period:11; // Periodic status time, msec uint8_t operation_code;
uint16_t enable_periodic_status:1; // Send periodic status uint8_t chip_address;
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 uint8_t pll_divr:6;
uint16_t pwm_active_level:1; // Active level of PWM outputs, if used uint8_t pll_bypass:1;
uint16_t forward_all_privileged_packets:1; // Forward priv pkts -- diagnostic uint8_t pll_reset:1;
uint8_t status_batch_delay; // Batching delay, time to wait before sending status
uint8_t watchdog:7; // Watchdog timeout, seconds uint8_t pll_divf;
uint8_t disable_sensors:1; // Diagnostic
uint8_t spare1:1; // Must always be 0
uint8_t rx_header_timeout:7; // Header timeout in char times uint8_t pll_divq:3;
uint8_t rx_ignore_header_crc:1; // Ignore rx header crc's (diagnostic) uint8_t pll_range:3;
uint8_t rx_data_timeout:7; // Data timeout in char times / 16 uint8_t pll_fse:1; // Must always be 1
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 data_length; // Always 0
uint8_t stat_diagnostic:1; // Never set this uint8_t crc8; // Computed across bytes 1-6 inclusive
uint8_t measure_interval; // Die temperature measurement interval (msec) } __attribute__((packed,aligned(4))); // 8 bytes total
uint32_t one_usec:12; // How many LF clocks per usec. // OP_HASH serial data
uint32_t max_nonces_per_frame:4; // Maximum # of nonces to combine in a single frame struct hf_hash_serial {
uint32_t voltage_sample_points:8; // Bit mask for sample points (up to 5 bits set) uint8_t midstate[32]; // Computed from first half of block header
uint32_t pwm_phases:2; // phases - 1 uint8_t merkle_residual[4]; // From block header
uint32_t trim:4; // Trim value for temperature measurements uint32_t timestamp; // From block header
uint32_t clock_diagnostic:1; // Never set this uint32_t bits; // Actual difficulty target for block header
uint32_t forward_all_packets:1; // Forward everything - diagnostic. uint32_t starting_nonce; // Usually set to 0
uint32_t nonce_loops; // How many nonces to search, or 0 for 2^32
uint16_t pwm_period; // Period of PWM outputs, in reference clock cycles uint16_t ntime_loops; // How many times to roll timestamp, or 0
uint16_t pwm_pulse_period; // Initial count, phase 0 uint8_t search_difficulty; // Search difficulty to use, # of '0' digits required
} __attribute__((packed,aligned(4))); uint8_t option;
uint8_t group;
// OP_GROUP data uint8_t spare3[3];
struct hf_group_data { } __attribute__((packed,aligned(4)));
uint16_t nonce_msoffset; // This value << 16 added to starting nonce
uint16_t ntime_offset:12; // This value added to timestamp // OP_HASH usb data - header+data = 64 bytes
uint16_t spare:4; struct hf_hash_usb {
} __attribute__((packed,aligned(4))); uint8_t midstate[32]; // Computed from first half of block header
uint8_t merkle_residual[4]; // From block header
// Structure of the monitor fields for G-1, returned in OP_STATUS, core bitmap follows this uint32_t timestamp; // From block header
struct hf_g1_monitor { uint32_t bits; // Actual difficulty target for block header
uint16_t die_temperature:12; // Die temperature ADC count uint32_t starting_nonce; // Usually set to 0
uint16_t spare:4; // Spare uint32_t nonce_loops; // How many nonces to search, or 0 for 2^32
uint8_t core_voltage[6]; // Core voltage uint16_t ntime_loops; // How many times to roll timestamp, or 0
// [0] = main sensor uint8_t search_difficulty; // Search difficulty to use, # of '0' digits required
// [1]-[5] = other positions uint8_t group; // Non-zero for valid group
} __attribute__((packed,aligned(4))); } __attribute__((packed,aligned(4)));
// Conversions for the ADC readings from GN on-chip sensors in the above structure // OP_NONCE data
#define GN_CORE_VOLTAGE(a) ((float)(a)/256*1.2) struct hf_candidate_nonce {
#define GN_DIE_TEMPERATURE(a) ((((float)(a)*240)/4096.0)-61.5) uint32_t nonce; // Candidate nonce
uint16_t sequence; // Sequence number from corresponding OP_HASH
// What comes back in the body of an OP_STATISTICS frame (On die statistics) uint16_t ntime; // ntime offset, if ntime roll occurred, in LS 12 bits
struct hf_statistics { // If b12 set, search forward next 128 nonces to find solution(s)
uint8_t rx_header_crc; // Header CRC error's } __attribute__((packed,aligned(4)));
uint8_t rx_body_crc; // Data CRC error's
uint8_t rx_header_timeouts; // Header timeouts // OP_CONFIG data
uint8_t rx_body_timeouts; // Data timeouts struct hf_config_data {
uint8_t core_nonce_fifo_full; // Core nonce Q overrun events uint16_t status_period:11; // Periodic status time, msec
uint8_t array_nonce_fifo_full; // System nonce Q overrun events uint16_t enable_periodic_status:1; // Send periodic status
uint8_t stats_overrun; // Overrun in statistics reporting uint16_t send_status_on_core_idle:1; // Schedule status whenever core goes idle
uint8_t spare; uint16_t send_status_on_pending_empty:1; // Schedule status whenever core pending goes idle
} __attribute__((packed,aligned(4))); 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 sending status
// The sequence distance between a sent and received sequence number. uint8_t watchdog:7; // Watchdog timeout, seconds
#define SEQUENCE_DISTANCE(tx,rx) ((tx)>=(rx)?((tx)-(rx)):(info->num_sequence+(tx)-(rx))) uint8_t disable_sensors:1; // Diagnostic
//////////////////////////////////////////////////////////////////////////////// uint8_t rx_header_timeout:7; // Header timeout in char times
// USB protocol data structures 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)
// Convenience header specific to OP_USB_INIT uint8_t stats_interval:7; // Minimum interval to report statistics (seconds)
struct hf_usb_init_header { uint8_t stat_diagnostic:1; // Never set this
uint8_t preamble; // Always 0xaa uint8_t measure_interval; // Die temperature measurement interval (msec)
uint8_t operation_code;
uint8_t spare1; 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
uint8_t protocol:3; // Which protocol to use uint32_t voltage_sample_points:8; // Bit mask for sample points (up to 5 bits set)
uint8_t user_configuration:1; // Use the following configuration data uint32_t pwm_phases:2; // phases - 1
uint8_t spare2:4; uint32_t trim:4; // Trim value for temperature measurements
uint32_t clock_diagnostic:1; // Never set this
uint16_t hash_clock:12; // Requested hash clock frequency uint32_t forward_all_packets:1; // Forward everything - diagnostic.
uint16_t pll_bypass:1; // Force PLL bypass, hash clock = ref clock
uint16_t no_asic_initialization:1; // Do not perform automatic ASIC initialization uint16_t pwm_period; // Period of PWM outputs, in reference clock cycles
uint16_t do_atspeed_core_tests:1; // Do core tests at speed, return second bitmap uint16_t pwm_pulse_period; // Initial count, phase 0
uint16_t leave_powered_down:1; // Init USB only, leave device powered down } __attribute__((packed,aligned(4)));
uint8_t data_length; // .. of data frame to follow, in 4 byte blocks // OP_GROUP data
uint8_t crc8; // Computed across bytes 1-6 inclusive struct hf_group_data {
} __attribute__((packed,aligned(4))); // 8 bytes total uint16_t nonce_msoffset; // This value << 16 added to starting nonce
uint16_t ntime_offset; // This value added to timestamp
// Values the protocol field in the above structure may take } __attribute__((packed,aligned(4)));
#define PROTOCOL_USB_MAPPED_SERIAL 0
#define PROTOCOL_GLOBAL_WORK_QUEUE 1 // Structure of the monitor fields for G-1, returned in OP_STATUS, core bitmap follows this
struct hf_g1_monitor {
// Options (only if present) that may be appended to the above header uint16_t die_temperature; // Die temperature ADC count
// Each option involving a numerical value will only be in effect if the value is non-zero uint8_t core_voltage[6]; // Core voltage
// This allows the user to select only those options desired for modification. Do not // [0] = main sensor
// use this facility unless you are an expert - loading inconsistent settings will not work. // [1]-[5] = other positions
struct hf_usb_init_options { } __attribute__((packed,aligned(4)));
uint16_t group_ntime_roll; // Total ntime roll amount per group
uint16_t core_ntime_roll; // Total core ntime roll amount // What comes back in the body of an OP_STATISTICS frame (On die statistics)
uint8_t low_operating_temp_limit; // Lowest normal operating limit struct hf_statistics {
uint8_t high_operating_temp_limit; // Highest normal operating limit uint8_t rx_header_crc; // Header CRC error's
uint16_t spare; uint8_t rx_body_crc; // Data CRC error's
} __attribute__((packed,aligned(4))); uint8_t rx_header_timeouts; // Header timeouts
uint8_t rx_body_timeouts; // Data timeouts
// Base item returned from device for OP_USB_INIT uint8_t core_nonce_fifo_full; // Core nonce Q overrun events
struct hf_usb_init_base { uint8_t array_nonce_fifo_full; // System nonce Q overrun events
uint16_t firmware_rev; // Firmware revision # uint8_t stats_overrun; // Overrun in statistics reporting
uint16_t hardware_rev; // Hardware revision # uint8_t spare;
uint32_t serial_number; // Board serial number } __attribute__((packed,aligned(4)));
uint8_t operation_status; // Reply status for OP_USB_INIT (0 = success)
uint8_t extra_status_1; // Extra reply status information, code specific
uint16_t sequence_modulus; // Sequence numbers are to be modulo this ////////////////////////////////////////////////////////////////////////////////
uint16_t hash_clockrate; // Actual hash clock rate used (nearest Mhz) // USB protocol data structures
uint16_t inflight_target; // Target inflight amount for GWQ protocol ////////////////////////////////////////////////////////////////////////////////
} __attribute__((packed,aligned(4)));
// Convenience header specific to OP_USB_INIT
// The above base item (16 bytes) is followed by the struct hf_config_data (16 bytes) actually struct hf_usb_init_header {
// used internally (so users may modify non-critical fields by doing subsequent uint8_t preamble; // Always 0xaa
// OP_CONFIG operations). This is followed by a device specific "core good" bitmap (unless the uint8_t operation_code;
// user disabled initialization), and optionally by an at-speed "core good" bitmap. uint8_t spare1;
uint8_t protocol:3; // Which protocol to use
// Information in an OP_DIE_STATUS frame. This is for one die - there are four per ASIC. uint8_t user_configuration:1; // Use the following configuration data
// Board level phase current and voltage sensors are likely to disappear in later production models. uint8_t pll_bypass:1; // Force PLL bypass, hash clock = ref clock
struct hf_g1_die_data { uint8_t no_asic_initialization:1; // Do not perform automatic ASIC initialization
struct hf_g1_monitor die; // Die sensors - 8 bytes uint8_t do_atspeed_core_tests:1; // Do core tests at speed, return second bitmap
uint16_t phase_currents[4]; // Phase currents (0 if unavailable) uint8_t leave_powered_down:1; // Init USB only, leave device powered down
uint16_t voltage; // Voltage at device boundary (0 if unavailable)
uint16_t temperature; // Regulator temp sensor uint16_t hash_clock; // Requested hash clock frequency
uint16_t tacho; // See documentation
uint16_t spare; uint8_t data_length; // .. of data frame to follow, in 4 byte blocks
} __attribute__((packed,aligned(4))); // 24 bytes total uint8_t crc8; // Computed across bytes 1-6 inclusive
} __attribute__((packed,aligned(4))); // 8 bytes total
// Conversions for the board/module level sensors
#define M_VOLTAGE(a) ((float)(a)*19.0734e-6) // Options (only if present) that may be appended to the above header
#define M_PHASE_CURRENT(a) ((float)(a)*0.794728597e-3) // Each option involving a numerical value will only be in effect if the value is non-zero
// This allows the user to select only those options desired for modification. Do not
// Information for an OP_GWQ_STATUS frame // use this facility unless you are an expert - loading inconsistent settings will not work.
// If sequence_head == sequence_tail, then there is no active work and sequence_head is invalid struct hf_usb_init_options {
struct hf_gwq_data { uint16_t group_ntime_roll; // Total ntime roll amount per group
uint64_t hash_count; // Add this to host's cumulative hash count uint16_t core_ntime_roll; // Total core ntime roll amount
uint16_t sequence_head; // The latest, internal, active sequence # uint8_t low_operating_temp_limit; // Lowest normal operating limit
uint16_t sequence_tail; // The latest, internal, inactive sequence # uint8_t high_operating_temp_limit; // Highest normal operating limit
uint16_t shed_count; // # of cores have been shedded for thermal control uint16_t spare;
uint16_t spare; } __attribute__((packed,aligned(4)));
} __attribute__((packed,aligned(4)));
// Base item returned from device for OP_USB_INIT
struct hf_usb_init_base {
// Information for an OP_USB_STATS1 frame - Communication statistics uint16_t firmware_rev; // Firmware revision #
struct hf_usb_stats1 { uint16_t hardware_rev; // Hardware revision #
// USB incoming uint32_t serial_number; // Board serial number
uint16_t usb_rx_preambles; uint8_t operation_status; // Reply status for OP_USB_INIT (0 = success)
uint16_t usb_rx_receive_byte_errors; uint8_t extra_status_1; // Extra reply status information, code specific
uint16_t usb_rx_bad_hcrc; uint16_t sequence_modulus; // Sequence numbers are to be modulo this
uint16_t hash_clockrate; // Actual hash clock rate used (nearest Mhz)
// USB outgoing uint16_t inflight_target; // Target inflight amount for GWQ protocol
uint16_t usb_tx_attempts; } __attribute__((packed,aligned(4)));
uint16_t usb_tx_packets;
uint16_t usb_tx_timeouts; // The above base item (16 bytes) is followed by the struct hf_config_data (16 bytes) actually
uint16_t usb_tx_incompletes; // used internally (so users may modify non-critical fields by doing subsequent
uint16_t usb_tx_endpointstalled; // OP_CONFIG operations). This is followed by a device specific "core good" bitmap (unless the
uint16_t usb_tx_disconnected; // user disabled initialization), and optionally by an at-speed "core good" bitmap.
uint16_t usb_tx_suspended;
// Internal UART transmit // Information in an OP_DIE_STATUS frame. This is for one die - there are four per ASIC.
uint16_t uart_tx_queue_dma; // Board level phase current and voltage sensors are likely to disappear in later production models.
uint16_t uart_tx_interrupts; struct hf_g1_die_data {
struct hf_g1_monitor die; // Die sensors - 8 bytes
// Internal UART receive uint16_t phase_currents[4]; // Phase currents (0 if unavailable)
uint16_t uart_rx_preamble_ints; uint16_t voltage; // Voltage at device boundary (0 if unavailable)
uint16_t uart_rx_missed_preamble_ints; uint16_t temperature; // Regulator temp sensor
uint16_t uart_rx_header_done; uint16_t tacho; // See documentation
uint16_t uart_rx_data_done; uint16_t spare;
uint16_t uart_rx_bad_hcrc; } __attribute__((packed,aligned(4))); // 24 bytes total
uint16_t uart_rx_bad_dma;
uint16_t uart_rx_short_dma;
uint16_t uart_rx_buffers_full; // Information for an OP_GWQ_STATUS frame
// If sequence_head == sequence_tail, then there is no active work and sequence_head is invalid
uint8_t max_tx_buffers; // Maximum # of send buffers ever used struct hf_gwq_data {
uint8_t max_rx_buffers; // Maximum # of receive buffers ever used uint64_t hash_count; // Add this to host's cumulative hash count
} __attribute__((packed,aligned(4))); uint16_t sequence_head; // The latest, internal, active sequence #
uint16_t sequence_tail; // The latest, internal, inactive sequence #
// Values info->device_type can take uint16_t shed_count; // # of cores have been shedded for thermal control
#define HFD_G1 1 // HashFast G-1 GN ASIC uint16_t spare;
#define HFD_VC709 128 } __attribute__((packed,aligned(4)));
#define HFD_ExpressAGX 129
// USB interface specific operation codes // Information for an OP_USB_STATS1 frame - Communication statistics
#define OP_USB_INIT 128 // Initialize USB interface details struct hf_usb_stats1 {
#define OP_GET_TRACE 129 // Send back the trace buffer if present // USB incoming
#define OP_LOOPBACK_USB 130 uint16_t usb_rx_preambles;
#define OP_LOOPBACK_UART 131 uint16_t usb_rx_receive_byte_errors;
#define OP_DFU 132 // Jump into the boot loader uint16_t usb_rx_bad_hcrc;
#define OP_USB_SHUTDOWN 133 // Initialize USB interface details
#define OP_DIE_STATUS 134 // Die status. There are 4 die per ASIC // USB outgoing
#define OP_GWQ_STATUS 135 // Global Work Queue protocol status uint16_t usb_tx_attempts;
#define OP_WORK_RESTART 136 // Stratum work restart regime uint16_t usb_tx_packets;
#define OP_USB_STATS1 137 uint16_t usb_tx_timeouts;
#define OP_USB_GWQSTATS 138 uint16_t usb_tx_incompletes;
#define OP_USB_DEBUG 255 uint16_t usb_tx_endpointstalled;
uint16_t usb_tx_disconnected;
// HashFast vendor and product ID's uint16_t usb_tx_suspended;
#define HF_USB_VENDOR_ID 0x297c
#define HF_USB_PRODUCT_ID_G1 0x0001 // Internal UART transmit
uint16_t uart_tx_queue_dma;
// uint16_t uart_tx_interrupts;
// Fault codes that can be returned in struct hf_usb_init_base.operation_status
// // Internal UART receive
#define E_RESET_TIMEOUT 1 uint16_t uart_rx_preamble_ints;
#define E_ADDRESS_TIMEOUT 2 uint16_t uart_rx_missed_preamble_ints;
#define E_CLOCKGATE_TIMEOUT 3 uint16_t uart_rx_header_done;
#define E_CONFIG_TIMEOUT 4 uint16_t uart_rx_data_done;
uint16_t uart_rx_bad_hcrc;
#define U32SIZE(x) (sizeof(x)/sizeof(uint32_t)) //uint16_t uart_rx_bad_crc32;
uint16_t uart_rx_bad_dma;
uint16_t uart_rx_short_dma;
#endif uint16_t uart_rx_buffers_full;
uint8_t max_tx_buffers; // Maximum # of send buffers ever used
uint8_t max_rx_buffers; // Maximum # of receive buffers ever used
} __attribute__((packed,aligned(4)));
// Information for an OP_USB_NOTICE frame
struct hf_usb_notice_data {
uint32_t extra_data; // Depends on notification code
char message[]; // NULL terminated, little endian byte order
};
#endif
#endif

267
hf_protocol_be.h

@ -0,0 +1,267 @@
//
// Copyright 2013 HashFast LLC
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version. See COPYING for more details.
//
// Big endian versions of packed structures
//
// Version 1.0
//
#ifndef _HF_PROTOCOL_BE_H_
#define _HF_PROTOCOL_BE_H_
// Generic 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
// Header specific to OP_PLL_CONFIG
struct hf_pll_config {
uint8_t preamble;
uint8_t operation_code;
uint8_t chip_address;
uint8_t pll_reset:1;
uint8_t pll_bypass:1;
uint8_t pll_divr:6;
uint8_t pll_divf;
uint8_t pll_fse:1; // Must always be 1
uint8_t pll_range:3;
uint8_t pll_divq:3;
uint8_t spare1:1; // Must always be 0
uint8_t data_length; // Always 0
uint8_t crc8; // Computed across bytes 1-6 inclusive
} __attribute__((packed,aligned(4))); // 8 bytes total
// OP_HASH serial data
struct hf_hash_serial {
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; // How many times to roll timestamp, or 0
uint8_t search_difficulty; // Search difficulty to use, # of '0' digits required
uint8_t option;
uint8_t group;
uint8_t spare3[3];
} __attribute__((packed,aligned(4)));
// OP_HASH usb data - header+data = 64 bytes
struct hf_hash_usb {
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; // How many times to roll timestamp, or 0
uint8_t search_difficulty; // Search difficulty to use, # of '0' digits required
uint8_t group; // Non-zero for valid group
} __attribute__((packed,aligned(4)));
// OP_NONCE data
struct hf_candidate_nonce {
uint32_t nonce; // Candidate nonce
uint16_t sequence; // Sequence number from corresponding OP_HASH
uint16_t ntime; // ntime offset, if ntime roll occurred, in LS 12 bits
// If b12 set, search forward next 128 nonces to find solution(s)
} __attribute__((packed,aligned(4)));
// OP_CONFIG data
// This is usually internal data only, for serial drivers only
// Users shouldn't normally need to interpret this, but in the event a Big Endian
// user requires access to this data, the following structure will get all
// the fields in the right place, but byte swaps will be required for the
// uint16_t's and the uint32_t.
struct hf_config_data {
uint16_t forward_all_privileged_packets:1; // Forward priv pkts -- diagnostic
uint16_t pwm_active_level:1; // Active level of PWM outputs, if used
uint16_t send_status_on_pending_empty:1; // Schedule status whenever core pending goes idle
uint16_t send_status_on_core_idle:1; // Schedule status whenever core goes idle
uint16_t enable_periodic_status:1; // Send periodic status
uint16_t status_period:11; // Periodic status time, msec
uint8_t status_batch_delay; // Batching delay, time to wait before sending status
uint8_t disable_sensors:1; // Diagnostic
uint8_t watchdog:7; // Watchdog timeout, seconds
uint8_t rx_ignore_header_crc:1; // Ignore rx header crc's (diagnostic)
uint8_t rx_header_timeout:7; // Header timeout in char times
uint8_t rx_ignore_data_crc:1; // Ignore rx data crc's (diagnostic)
uint8_t rx_data_timeout:7; // Data timeout in char times / 16
uint8_t stat_diagnostic:1; // Never set this
uint8_t stats_interval:7; // Minimum interval to report statistics (seconds)
uint8_t measure_interval; // Die temperature measurement interval (msec)
uint32_t forward_all_packets:1; // Forward everything - diagnostic.
uint32_t clock_diagnostic:1; // Never set this
uint32_t trim:4; // Trim value for temperature measurements
uint32_t pwm_phases:2; // phases - 1
uint32_t voltage_sample_points:8; // Bit mask for sample points (up to 5 bits set)
uint32_t max_nonces_per_frame:4; // Maximum # of nonces to combine in a single frame
uint32_t one_usec:12; // How many LF clocks per usec.
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)));
// OP_GROUP data
struct hf_group_data {
uint16_t nonce_msoffset; // This value << 16 added to starting nonce
uint16_t ntime_offset; // This value added to timestamp
} __attribute__((packed,aligned(4)));
// Structure of the monitor fields for G-1, returned in OP_STATUS, core bitmap follows this
struct hf_g1_monitor {
uint16_t die_temperature; // Die temperature ADC count
uint8_t core_voltage[6]; // Core voltage
// [0] = main sensor
// [1]-[5] = other positions
} __attribute__((packed,aligned(4)));
// What comes back in the body of an OP_STATISTICS frame (On die statistics)
struct hf_statistics {
uint8_t rx_header_crc; // Header CRC error's
uint8_t rx_body_crc; // Data CRC error'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)));
////////////////////////////////////////////////////////////////////////////////
// USB protocol data structures
////////////////////////////////////////////////////////////////////////////////
// Convenience header specific to OP_USB_INIT
struct hf_usb_init_header {
uint8_t preamble; // Always 0xaa
uint8_t operation_code;
uint8_t spare1;
uint8_t leave_powered_down:1; // Init USB only, leave device powered down
uint8_t do_atspeed_core_tests:1; // Do core tests at speed, return second bitmap
uint8_t no_asic_initialization:1; // Do not perform automatic ASIC initialization
uint8_t pll_bypass:1; // Force PLL bypass, hash clock = ref clock
uint8_t user_configuration:1; // Use the following configuration data
uint8_t protocol:3; // Which protocol to use
uint16_t hash_clock; // Requested hash clock frequency
uint8_t data_length; // .. of data frame to follow, in 4 byte blocks
uint8_t crc8; // Computed across bytes 1-6 inclusive
} __attribute__((packed,aligned(4))); // 8 bytes total
// Options (only if present) that may be appended to the above header
// Each option involving a numerical value will only be in effect if the value is non-zero
// This allows the user to select only those options desired for modification. Do not
// use this facility unless you are an expert - loading inconsistent settings will not work.
struct hf_usb_init_options {
uint16_t group_ntime_roll; // Total ntime roll amount per group
uint16_t core_ntime_roll; // Total core ntime roll amount
uint8_t low_operating_temp_limit; // Lowest normal operating limit
uint8_t high_operating_temp_limit; // Highest normal operating limit
uint16_t spare;
} __attribute__((packed,aligned(4)));
// Base item returned from device for OP_USB_INIT
struct hf_usb_init_base {
uint16_t firmware_rev; // Firmware revision #
uint16_t hardware_rev; // Hardware revision #
uint32_t serial_number; // Board serial number
uint8_t operation_status; // Reply status for OP_USB_INIT (0 = success)
uint8_t extra_status_1; // Extra reply status information, code specific
uint16_t sequence_modulus; // Sequence numbers are to be modulo this
uint16_t hash_clockrate; // Actual hash clock rate used (nearest Mhz)
uint16_t inflight_target; // Target inflight amount for GWQ protocol
} __attribute__((packed,aligned(4)));
// The above base item (16 bytes) is followed by the struct hf_config_data (16 bytes) actually
// used internally (so users may modify non-critical fields by doing subsequent
// OP_CONFIG operations). This is followed by a device specific "core good" bitmap (unless the
// user disabled initialization), and optionally by an at-speed "core good" bitmap.
// Information in an OP_DIE_STATUS frame. This is for one die - there are four per ASIC.
// Board level phase current and voltage sensors are likely to disappear in later production models.
struct hf_g1_die_data {
struct hf_g1_monitor die; // Die sensors - 8 bytes
uint16_t phase_currents[4]; // Phase currents (0 if unavailable)
uint16_t voltage; // Voltage at device boundary (0 if unavailable)
uint16_t temperature; // Regulator temp sensor
uint16_t tacho; // See documentation
uint16_t spare;
} __attribute__((packed,aligned(4))); // 24 bytes total
// Information for an OP_GWQ_STATUS frame
// If sequence_head == sequence_tail, then there is no active work and sequence_head is invalid
struct hf_gwq_data {
uint64_t hash_count; // Add this to host's cumulative hash count
uint16_t sequence_head; // The latest, internal, active sequence #
uint16_t sequence_tail; // The latest, internal, inactive sequence #
uint16_t shed_count; // # of cores have been shedded for thermal control
uint16_t spare;
} __attribute__((packed,aligned(4)));
// Information for an OP_USB_STATS1 frame - Communication statistics
struct hf_usb_stats1 {
// USB incoming
uint16_t usb_rx_preambles;
uint16_t usb_rx_receive_byte_errors;
uint16_t usb_rx_bad_hcrc;
// USB outgoing
uint16_t usb_tx_attempts;
uint16_t usb_tx_packets;
uint16_t usb_tx_timeouts;
uint16_t usb_tx_incompletes;
uint16_t usb_tx_endpointstalled;
uint16_t usb_tx_disconnected;
uint16_t usb_tx_suspended;
// Internal UART transmit
uint16_t uart_tx_queue_dma;
uint16_t uart_tx_interrupts;
// Internal UART receive
uint16_t uart_rx_preamble_ints;
uint16_t uart_rx_missed_preamble_ints;
uint16_t uart_rx_header_done;
uint16_t uart_rx_data_done;
uint16_t uart_rx_bad_hcrc;
//uint16_t uart_rx_bad_crc32;
uint16_t uart_rx_bad_dma;
uint16_t uart_rx_short_dma;
uint16_t uart_rx_buffers_full;
uint8_t max_tx_buffers; // Maximum # of send buffers ever used
uint8_t max_rx_buffers; // Maximum # of receive buffers ever used
} __attribute__((packed,aligned(4)));
// Information for an OP_USB_NOTICE frame
struct hf_usb_notice_data {
uint32_t extra_data; // Depends on notification code
char message[]; // NULL terminated, little endian byte order
};
#endif
Loading…
Cancel
Save