Difference between revisions of "BIP MinerHardwareBinaryProtocol"

From Bitcoin Wiki
Jump to: navigation, search
(Packet Format)
 
Line 22: Line 22:
  
 
Packet length/types:
 
Packet length/types:
* 00 - Abort
+
* <tt>00</tt> -- Abort
* 01 to ef - Data packet length (1 to 239 bytes)
+
* <tt>01</tt> to <tt>ef</tt> -- Data packet length (1 to 239 bytes)
* f0 to fc - Reserved
+
* <tt>f0</tt> to <tt>fc</tt> -- Reserved
* fd - Bad packet (command aborted)
+
* <tt>fd</tt> -- Bad packet (command aborted)
* fe - ACK
+
* <tt>fe</tt> -- ACK
* ff - End of command
+
* <tt>ff</tt> -- End of command
  
 
ACK should be sent in response to each 250-byte packet. Bulk data transfers, such as bitstream uploads, should wait until ACK is received before sending more packets (maybe? or does USB handle this for us too?).
 
ACK should be sent in response to each 250-byte packet. Bulk data transfers, such as bitstream uploads, should wait until ACK is received before sending more packets (maybe? or does USB handle this for us too?).
  
CRC32 must include the string "mhbp" plus the packet length/type byte and all data; this is not used to prevent corruption (USB already guarantees that), but rather to avoid acting when something foreign sends stuff. If the CRC32 does not match, the device should send a "fd" packet back and abort the command.
+
CRC32 must include the string "mhbp" plus the packet length/type byte and all data; this is not used to prevent corruption (USB already guarantees that), but rather to avoid acting when something foreign sends stuff. If the CRC32 does not match, the device should send a "<tt>fd</tt>" packet back and abort the command.
  
Null-length commands (ie, "ff" without any valid data packets preceding it) must be ACK'd and ignored.
+
Null-length commands (ie, "<tt>ff</tt>" without any valid data packets preceding it) must be ACK'd and ignored.
  
 
Anything up to the initial FE is ignored.
 
Anything up to the initial FE is ignored.
Line 40: Line 40:
 
*1 byte: request id
 
*1 byte: request id
 
*1 byte: command id
 
*1 byte: command id
**Cx -- Modification commands (potentially dangerous)
+
**<tt>Cx</tt> -- Modification commands (potentially dangerous)
**Dx -- Replies to Modification commands
+
**<tt>Dx</tt> -- Replies to Modification commands
**Ex -- Informational commands
+
**<tt>Ex</tt> -- Informational commands
**Fx -- Replies to Informational commands
+
**<tt>Fx</tt> -- Replies to Informational commands
 
*1 byte: device number (ignored for some commands)
 
*1 byte: device number (ignored for some commands)
**00 is the MCU
+
**<tt>00</tt> is the controller
**1-fe are FPGAs
+
**<tt>01</tt> to <tt>fe</tt> are mining devices
**ff for "all FPGAs"
+
**<tt>ff</tt> for "all mining devices"
*1 byte: status (should always be 00 for requests)
+
*1 byte: status (should always be <tt>00</tt> for requests)
**00 -- success
+
**<tt>00</tt> -- success
**80 -- failure
+
**<tt>80</tt> -- failure
 
*N bytes: data
 
*N bytes: data
  
Line 57: Line 57:
  
 
===Commands===
 
===Commands===
====c1 -- program software====
+
====<tt>c1</tt> -- program software====
 
Data:
 
Data:
 
* 4 bytes: hardware version (big endian)
 
* 4 bytes: hardware version (big endian)
Line 63: Line 63:
 
* 2 bytes: hardware model number
 
* 2 bytes: hardware model number
 
* 4 bytes: hardware specific information ("ID Code")
 
* 4 bytes: hardware specific information ("ID Code")
 +
* 2 bytes: hardware component
 +
** <tt>0000</tt> -- FPGA Bitstream
 +
** <tt>0100</tt> -- JTAG abstraction interface
 
* 4 bytes: software size
 
* 4 bytes: software size
 
* N bytes: software data
 
* N bytes: software data
====c2 -- get/set clock speed====
+
====<tt>c2</tt> -- get/set clock speed====
 
Data:
 
Data:
* 1 byte: new clock speed (00 = don't change)
+
* 4 bytes: new clock speed in Hz (omit to read only)
Reply (if getting):
+
** <tt>00000000</tt> -- minimum allowed
* 1 byte: current clock speed
+
** <tt>ffffffff</tt> -- maximum allowed
====c3 -- get/set register(s)====
+
Reply (for both get and set):
 +
* 4 bytes: current/new clock speed
 +
====<tt>c3</tt> -- start new job====
 
Data:
 
Data:
* 2 bytes: first register number
+
* 1 byte: busy behaviour (what to do if there's already a job running)
* 2 bytes: number of registers to fetch/set
+
** <tt>00</tt> -- cancel it (and all pending queued jobs) and start new job immediately
* N bytes: new values for each register (omitted to read)
+
** <tt>01</tt> -- error
 +
** <tt>02</tt> -- queue to run after current job finishes
 +
* (data may end here to cancel all jobs and halt)
 +
* 1 byte: job id
 +
** <tt>00</tt> -- Unusable
 +
* N bytes: job data
 +
** For standard Bitcoin kernels (but may be different for other kernels!):
 +
*** 32 bytes: SHA256 midstate
 +
*** 4 bytes: final 32 bits of transaction merkle root
 +
*** 4 bytes: block time header
 +
*** 4 bytes: block target in compact format ("bits")
 +
*** 4 bytes (optional): first valid nonce (if omitted, <tt>00000000</tt>)
 +
*** 4 bytes (optional): last valid nonce (if omitted, <tt>ffffffff</tt>)
 +
*** 2 bytes (optional): how many times to roll the time header (if omitted, <tt>0000</tt>)
 +
====<tt>c4</tt> -- get/set register====
 +
Data:
 +
* 2 bytes: register number
 +
** <tt>ffff</tt> -- valid share nonce
 +
*** Value:
 +
**** 1 byte: job id
 +
***** <tt>00</tt> -- Unknown
 +
**** N bytes: nonce (4 bytes for standard Bitcoin kernels)
 +
* N bytes: new value (omitted to read)
 
Reply (if reading):
 
Reply (if reading):
* 1 byte: width (in bits) of each register
+
* N bytes: current value
* N bytes: value of each register
+
====<tt>c5</tt> -- watch register====
====c4 -- watch register(s)====
 
 
Data:
 
Data:
* 2 bytes: first register number
+
* 2 bytes: register number
* 2 bytes: number of registers to watch
+
* 1 byte: how long to watch, in seconds
* 1 byte: how long to watch, in seconds; 00 = cancel watch; ff = never expire
+
** <tt>00</tt> -- cancel watch
Reply (immediate):
+
** <tt>ff</tt> -- never expire
* 1 byte: width (in bits) of each register
+
Reply (immediately):
* N bytes: current value of each register
+
* N bytes: current value
Notification (DEFERRED, with command=ff and same request id):
+
Notification (when condition met, with command=<tt>ff</tt> and same request id):
* 2 bytes: number of registers changed
+
* 2 bytes: register number
* for each:
+
* N bytes: new value
** 2 bytes: register number
+
====<tt>e0</tt> -- ping====
** N bytes: value of register
 
====e0 -- ping====
 
 
Device number ignored.
 
Device number ignored.
 
Replies with same data given
 
Replies with same data given
====e1 -- get FPGA count====
+
====<tt>e1</tt> -- get mining device count====
 
Device number ignored.
 
Device number ignored.
 
Reply:
 
Reply:
* 1 byte: number of FPGAs
+
* 1 byte: number of mining devices
====e2 -- hardware version====
+
====<tt>e2</tt> -- hardware version====
 
Reply:
 
Reply:
 
* 4 bytes: hardware version (big endian)
 
* 4 bytes: hardware version (big endian)
Line 104: Line 128:
 
* 2 bytes: hardware model number
 
* 2 bytes: hardware model number
 
* 4 bytes: hardware specific information ("ID Code")
 
* 4 bytes: hardware specific information ("ID Code")
 +
* 2 bytes: number of programmable hardware components
 +
* 2*N bytes: hardware component ids
 
* 1 byte: length of hardware serial number
 
* 1 byte: length of hardware serial number
 
* N bytes: hardware serial number
 
* N bytes: hardware serial number
Line 111: Line 137:
 
* N bytes: human-readable hardware model/version string (UTF-8)
 
* N bytes: human-readable hardware model/version string (UTF-8)
  
====e3 -- software version====
+
====<tt>e3</tt> -- software version====
 
Reply:
 
Reply:
 
* 4 bytes: software version (big endian)
 
* 4 bytes: software version (big endian)
Line 118: Line 144:
 
* 1 byte: length of human-readable software name
 
* 1 byte: length of human-readable software name
 
* N bytes: human-readable hardware model/version string (UTF-8)
 
* N bytes: human-readable hardware model/version string (UTF-8)
====e4 -- get temperature====
+
* 2 byte: number of MHBP features supported
 +
* 2*N bytes: MHBP features supported
 +
** <tt>c310</tt> -- standard Bitcoin kernel interface
 +
** <tt>c311</tt> -- standard Bitcoin kernel interface: nonce range
 +
** <tt>c312</tt> -- standard Bitcoin kernel interface: roll time
 +
** <tt>c400</tt> -- general register access
 +
** <tt>c410</tt> -- "job id" tracking
 +
** <tt>c500</tt> -- general register watching
 +
** <tt>c501</tt> -- nonce register watching
 +
 
 +
====<tt>e4</tt> -- get temperature====
 
Reply:
 
Reply:
 
* 1 byte: temperature in celcius
 
* 1 byte: temperature in celcius

Latest revision as of 20:27, 14 July 2012

This page describes a BIP (Bitcoin Improvement Proposal).
Please see BIP 2 for more information about BIPs and creating them. Please do not just create a wiki page.

  BIP: ?
  Title: Protocol for Dedicated Mining Hardware
  Author: Luke Dashjr <luke+bipmhbp@dashjr.org>
  Status: Draft
  Type: Standards Track
  Created: 08-06-2012

Abstract

Specification

This protocol is designed to be spoken only over a reliable (including error correction) lower-level protocol, such as USB-Serial or USB-CDC, to a local device.

Packet Format

  • 1 byte: always FE
  • 1 byte: packet length/type
  • N bytes: packet data
  • 4 bytes: packet data CRC32 (only for data packets)

Packet length/types:

  • 00 -- Abort
  • 01 to ef -- Data packet length (1 to 239 bytes)
  • f0 to fc -- Reserved
  • fd -- Bad packet (command aborted)
  • fe -- ACK
  • ff -- End of command

ACK should be sent in response to each 250-byte packet. Bulk data transfers, such as bitstream uploads, should wait until ACK is received before sending more packets (maybe? or does USB handle this for us too?).

CRC32 must include the string "mhbp" plus the packet length/type byte and all data; this is not used to prevent corruption (USB already guarantees that), but rather to avoid acting when something foreign sends stuff. If the CRC32 does not match, the device should send a "fd" packet back and abort the command.

Null-length commands (ie, "ff" without any valid data packets preceding it) must be ACK'd and ignored.

Anything up to the initial FE is ignored.

Command Format

  • 1 byte: request id
  • 1 byte: command id
    • Cx -- Modification commands (potentially dangerous)
    • Dx -- Replies to Modification commands
    • Ex -- Informational commands
    • Fx -- Replies to Informational commands
  • 1 byte: device number (ignored for some commands)
    • 00 is the controller
    • 01 to fe are mining devices
    • ff for "all mining devices"
  • 1 byte: status (should always be 00 for requests)
    • 00 -- success
    • 80 -- failure
  • N bytes: data

Commands less than 4 bytes should be ignored. Additional data beyond what is expected should be ignored.

Commands

c1 -- program software

Data:

  • 4 bytes: hardware version (big endian)
  • 2 bytes: hardware manuf/authority
  • 2 bytes: hardware model number
  • 4 bytes: hardware specific information ("ID Code")
  • 2 bytes: hardware component
    • 0000 -- FPGA Bitstream
    • 0100 -- JTAG abstraction interface
  • 4 bytes: software size
  • N bytes: software data

c2 -- get/set clock speed

Data:

  • 4 bytes: new clock speed in Hz (omit to read only)
    • 00000000 -- minimum allowed
    • ffffffff -- maximum allowed

Reply (for both get and set):

  • 4 bytes: current/new clock speed

c3 -- start new job

Data:

  • 1 byte: busy behaviour (what to do if there's already a job running)
    • 00 -- cancel it (and all pending queued jobs) and start new job immediately
    • 01 -- error
    • 02 -- queue to run after current job finishes
  • (data may end here to cancel all jobs and halt)
  • 1 byte: job id
    • 00 -- Unusable
  • N bytes: job data
    • For standard Bitcoin kernels (but may be different for other kernels!):
      • 32 bytes: SHA256 midstate
      • 4 bytes: final 32 bits of transaction merkle root
      • 4 bytes: block time header
      • 4 bytes: block target in compact format ("bits")
      • 4 bytes (optional): first valid nonce (if omitted, 00000000)
      • 4 bytes (optional): last valid nonce (if omitted, ffffffff)
      • 2 bytes (optional): how many times to roll the time header (if omitted, 0000)

c4 -- get/set register

Data:

  • 2 bytes: register number
    • ffff -- valid share nonce
      • Value:
        • 1 byte: job id
          • 00 -- Unknown
        • N bytes: nonce (4 bytes for standard Bitcoin kernels)
  • N bytes: new value (omitted to read)

Reply (if reading):

  • N bytes: current value

c5 -- watch register

Data:

  • 2 bytes: register number
  • 1 byte: how long to watch, in seconds
    • 00 -- cancel watch
    • ff -- never expire

Reply (immediately):

  • N bytes: current value

Notification (when condition met, with command=ff and same request id):

  • 2 bytes: register number
  • N bytes: new value

e0 -- ping

Device number ignored. Replies with same data given

e1 -- get mining device count

Device number ignored. Reply:

  • 1 byte: number of mining devices

e2 -- hardware version

Reply:

  • 4 bytes: hardware version (big endian)
  • 2 bytes: hardware manuf/authority
  • 2 bytes: hardware model number
  • 4 bytes: hardware specific information ("ID Code")
  • 2 bytes: number of programmable hardware components
  • 2*N bytes: hardware component ids
  • 1 byte: length of hardware serial number
  • N bytes: hardware serial number
  • 1 byte: length of hardware model number
  • N bytes: hardware model number (EUI-64 when available)
  • 1 byte: length of human-readable hardware model
  • N bytes: human-readable hardware model/version string (UTF-8)

e3 -- software version

Reply:

  • 4 bytes: software version (big endian)
  • 1 byte: length of software-specific unique identifier (git commit?)
  • N bytes: software-specific unique identifier
  • 1 byte: length of human-readable software name
  • N bytes: human-readable hardware model/version string (UTF-8)
  • 2 byte: number of MHBP features supported
  • 2*N bytes: MHBP features supported
    • c310 -- standard Bitcoin kernel interface
    • c311 -- standard Bitcoin kernel interface: nonce range
    • c312 -- standard Bitcoin kernel interface: roll time
    • c400 -- general register access
    • c410 -- "job id" tracking
    • c500 -- general register watching
    • c501 -- nonce register watching

e4 -- get temperature

Reply:

  • 1 byte: temperature in celcius

Examples

Needs updating

Get temperature of FPGA #2

> 04  00 44 02 00  ff
< 05  00 c4 02 00 30  ff

Mine a bitcoin share (with proper bitstream, on FPGA #1)

> 34  00 03 01 00 0000 000b <32:midstate> <12:taildata>  ff  (assign job to registers)
> 09  01 04 01 00 000e 0001 ff  ff  (setup watch on nonce-found register)
< 04  00 83 01 00  ff
< 09  01 84 01 00 20 ffffffff  ff
...
< 0c  01 ff 01 00 0001 000e <4:nonce>  ff  (nonce-found got updated)
> 09  02 04 01 00 000e 0001 00  ff  (clear nonce-found watch)
< 09  02 84 01 00 20 <4:nonce>  ff

Reset the command queue

To reset the command queue, send 244 zero bytes; this will pad-out any "open" packet, and send a zero-length for the next one to abort the command.

Motivation

Rationale

Backwards Compatibility

Reference Implementation