Bootloader

class squishy.gateware.bootloader.SquishyBootloader(*args, src_loc_at: int = 0, **kwargs)

Squishy DFU Bootloader

This is the “top” module representing a Squishy DFU capable bootloader.

It provides DFU alt-modes for each flash slot, including the bootloader, as well as dispatch to the appropriate programming interface for the given platform.

For SquishyRev1 platforms, the method of programming is direct SPI flash, followed by an SB_WARMBOOT trigger.

For SquishyRev2 this is more complicated, as we have the supervisor MCU in the mix. First the image is written to the SPI PSRAM, a signal is then sent to the supervisor to reboot us and re-program us with the new bitstream.

Note

There needs to be some consideration for hardware platforms that support ephemeral programming, any transfers to that slot must be distinguished from a normal slot transfer, for Rev1 platforms this is not an issue, as there is no way of doing an ephemeral applet, however for Rev2, in order to try to tide wearing out flash with write cycles (even though they’re good for like, 100k cycles) we have an (optional?) onboard PSRAM that acts as both a cache for doing flash updates as well as doing hot-loading without actually touching flash.

This can be done mostly opaquely from the root of the bootloader module itself, other than having to properly name the ephemeral DFU slot, as all the machinery for updating the platform is within the target module for that anyway.

Warning

Currently there is no flash protection for the bootloader slot (slot 0), it is exposed by default, and treated like any other applet slot.

We also don’t have any checksums, which might be a bit problematic, but due to some platform limitations specifically due to Rev1 where we write directly into flash and don’t have a buffer that can be used and discarded, we write-over the slot as we update. This is particularly dangerous for the bootloader.

Parameters:
  • serial_number (str) – The device serial number to use.

  • revision (tuple[int, int]) – The device revision.

Variables:

serial_number (str) – The device serial number assigned.

class squishy.gateware.bootloader.rev1.Rev1(*args, src_loc_at: int = 0, **kwargs)
Parameters:

fifo (AsyncFIFO | None) – The storage FIFO.

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

  • slot_selection (Signal(2)) – Input: 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_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.

class squishy.gateware.bootloader.rev2.Rev2(*args, src_loc_at: int = 0, **kwargs)
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.