Squishy Rev2 Bootloader

This module contains the implementation of the rev2 hardware-specific bootloader.

The rev2 hardware has a more complex boot process due to the following reasons:
  • The addition of a supervisor MCU

  • The presence of a shared PSRAM between the supervisor and the FPGA

As such, there is a boot protocol that has to be established between the supervisor and the FPGA.

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

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 write_slot

  2. FPGA raises the ~SU_IRQ line to notify the supervisor we want to write slot data

  3. Supervisor reads the slots and txlen registers

  4. Supervisor ACK’s the IRQ

  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 III. Goto 4.b

  1. If the destination slot is ephemeral:
    1. Supervisor then writes into the FPGA control register that the erase/flash cycle is done

  1. Supervisor waits for the FPGA to tell it to reboot into a given slot with the boot IRQ

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

  3. Supervisor resets the FPGA into configuration mode

  4. Read a block into our SPI buffer from the slot backing storage

  5. While we have not written the full bitstream:

  1. Read at most buffers worth of bitstream data from backing store

  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_completed (Signal) – Input: Signal from the DFU handler when a full slot download is completed.

  • 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.