bm1397.md 5.4 KB

BM1397

Prelude

Many registers described below are common with other BM13xx chips. Here we focus mainly on BM1397 as this register map has been reverse engineered from the 'bmminer' of T17 original Firmware from Bitmain.

Full process step by step

  1. Download the official T17 Firmware from Bitmain website.
  2. Run these commands one by one:
tar -xvzf ANTMINER-T17-user-OM-202004231629-sig_5828.tar.gz
tar -xvzf fw.tar.gz
tail -c+65 < uramdisk.image.gz > uramdisk.image.cut.gz
gunzip -c -d uramdisk.image.cut.gz > uramdisk.image
mkdir uramdisk
sudo mount -ro loop uramdisk.image uramdisk
  1. Mess with Ghidra onto the bmminer ELF file.

Registers Map

Core Registers Map

Communication Protocol

Write Core Register

In order to write values to a Core Register, a Write Register Command shall be done to the Core Register Control Register with the RD#_WR fields = 1.

Read Core Register

In order to read the value of a Core Register, a Write Register Command shall be done to the Core Register Control Register with the RD#_WR fields = 0.

Then the chip will reply a Register Value Response for the Core Register Value Register.

Enumerate Chips on the Chain

With the original firmware of the control board, an enumeration of all chips on the chain (physically on a hash board) is done at the beginning. It is a Read Register Command on Chip Address Register with ALL = 1. Then all chips on the chain reply a Register Value Response.

During this enumeration, we see that all chips on the chain have a ADDR = 0. So the FW affect new Chip Address by first sending a Chain Inactive Command, so chips stop relaying command to the chain, then using the Set Chip Address Command which sill be accepted only by the first chip on the chain. Then the next Set Chip Address Command will be ignored by the first chip and relayed to the second chip on the chain, which will accept this Command and set it's own Chip Address. And so on up to the last chip on the chain.

On S9k (BM1393), FW also perform a Write Regsiter Command to Chip Address Register with the wanted ADDR in addition to the Set Chip Address Command. I am not sure if it is usefull on BM1393, but on BM1397 the full Chip Address Register seems to be Read Only.

The ADDR given don't have to be contiguous on a chain, for instance they are given with increment of 8 on T17 original FW and 4 on S9k original FW. It is used to divide evenly the total nonce space between chips on the chain. Indeed, all chips will add their own ADDR to the Nonce they are hashing.

For instance a T17 hash board has 30 chips on a chain, so with an increment of 8, the last Chip Address will be 232 (actually the FW send 32 Set Chip Address Command, so the last 2 Commands should be useless).

Same for S9k hash board with physically 60 chip on the chain, FW send 64 Set Chip Address Command.

This should be the reason why the full 32 bits Nonce space is never fully hashed by miners with chip number on chain not aligned to a power of 2. See The Mystery Of The Bitcoin Nonce Pattern

Set Baudrate

In order to get a higher hash rate, we need to increase the communication Baudrate because at 115200bps (default baudrate) a Send Job Command with 4 midstate would take 15.2ms which could be longer than the time the full chain would take to Hash the complete Nonce space of the previous job.

BaudRate = fBase / ((BT8D + 1) * 8)

At chip reset, in Misc Control Register :

So the default BaudRate = fCLKI / ((BT8D + 1) * 8) = 115740 bps with reset values (0.47% error with target 115200 bps).

This is possible up to 3.125Mbps BaudRate with BT8D = 0.

For higher baud rates, here are the necessary steps (numeric example below is for 6.25 Mbps BaudRate):

  1. enabling and configuring PLL3 using PLL3 Parameter for example writing 0xC0700111 will result of a PLL3 with frequency equal to fPLL3 = fCLKI * FBDIV / (REFDIV * POSTDIV1 * POSTDIV2) = 25MHz*112/(1*1*1) = 2.8 GHz
  2. setting PLL3_DIV4 in Fast UART Configuration for example writing 0x0600000F give a PLL3_DIV4 = 6
  3. setting BCLK_SEL to 1 fBase = fPLL3 / (PLL3_DIV4 + 1) = 2.8 GHz / (6 + 1) = 400 MHz
  4. setting BT8D to 7 BaudRate = fBase / ((BT8D + 1)*8) = 400 MHz / ((7+1)*8) = 6.25 MBps