Squishy Rev2 Bootloader

Bootloader Protocol

Squishy Rev2 has a little bit of a complicated boot protocol due to the use of a platform supervisor, the protocol between the FPGA in either the applet of bootloader state and the supervisor must be well defined to avoid any potential problems.

Applet Mode

When the FPGA is hosting an applet, we can request to drop into the bootloader as follows:

  1. FPGA raises ~SU_IRQ with the IRQ register value DFU set to 1

  2. Supervisor resets the FPGA configuration and loads the bootloader bitstream

  3. Supervisor then waits for the next IRQ event

  4. Supervisor then checks the IRQ register to make sure it is in_boot

Bootloader Mode

Upon the FPGA entering the bootloader:

  1. FPGA waits for a DFU upload, and if done stuffs it into the PSRAM

  1. FPGA Holds bus_hold high until DFU upload is complete

  2. FPGA sticks the destination slot for the DFU payload into the dest_slot half of the slots register

  3. FPGA writes the DFU payload size into the txlen register

  1. FPGA sets the IRQ Reason to in_boot

  2. FPGA raises the ~SU_IRQ line to notify the supervisor we are in the bootloader

  3. Supervisor reads the slots and txlen registers

  1. If the destination slot is not ephemeral:

  1. Supervisor erases the flash region mapped to that slot

  2. Supervisor write the contents of the PSRAM for txlen into the target flash slot

  3. Supervisor then writes into the FPGA control register that the erase/flash cycle is done

  4. Supervisor waits for the FPGA to tell it to reboot into a given slot

  5. FPGA triggers reboot on DFU detach to last written slot?

  1. If the destination slot is ephemeral:

  1. Supervisor resets the FPGA into configuration mode

  2. Read a block into our SPI buffer from the PSRAM

  3. While we have not written the full bitstream:

  1. Read at most buffers worth of bitstream data from PSRAM

  2. Dump buffer into FPGA configuration

  1. Check FPGA configuration status

  2. let the FPGA boot into new bitstream

class squishy.gateware.bootloader.rev2.Rev2(*args: Any, src_loc_at: int = 0, **kwargs: Any)
Parameters:

fifo (AsyncFIFO | None) – The storage FIFO.

Variables:
  • trigger_reboot (Signal) – FPGA reboot trigger from DFU.

  • slot_selection (Signal(2)) – Flash slot destination from DFU alt-mode.

  • dl_start (Signal) – Input: Start of a DFU transfer.

  • dl_finish (Signal) – Input: An acknowledgement of the dl_done signal

  • dl_ready (Signal) – Output: If the backing storage is ready for data.

  • dl_done (Signal) – Output: When the backing storage is done storing the data.

  • dl_reset_slot (Signal) – Input: Signals to the storage to reset the active slot.

  • dl_size (Signal(16)) – Input: The size of the DFU transfer into the the FIFO

  • slot_changed (Signal) – Input: Raised when the DFU alt-mode is changed.

  • slot_ack (Signal) – Output: When the slot_changed signal was acted on.