• Stars
    star
    339
  • Rank 124,632 (Top 3 %)
  • Language Verilog
  • Created over 5 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An open source SPI flash emulator and monitor

ULX3S connected to SPI flash with a 8-SOIC clip and debugged with oscilloscope probes

SPI Spy: Flash emulation

The SPI Spy is an open source (both hardware and software) SPI flash emulation tool. It can store a flash image in the SDRAM connected to the FPGA and serve the image to a host CPU over the SPI bus. This allows you to avoid the lengthy SPI flash erase/write cycles during firmware development as well as to more easily explore early boot time security against TOCTOU attacks.

Platform

The design is currently based on the ULX3S which has an Lattice ECP5-12F FPGA and a 16-bit wide 32 MB SDRAM. It might be portable to the TinyFPGA-EX or other open source ECP5 boards, although it uses a custom SDRAM controller to be able to meet the difficult timing requirements of the SPI flash protocol (described below).

It has been tested on the Thinkpad x230 (no SFDP) and the Supermicro X11SSH-F (with SFDP). Write support is very flaky; the entire state machine needs to be redone (issue #17).

Supported features

  • Single SPI up to 20 MHz clock
  • 3-byte addressing (up to 16 MB of flash image)
  • High-speed (1 MB/s) /dev/ttyACM0 interface
  • Serial port updates to the SDRAM (could have a better interface issue #3)
  • Logging flash access patterns (could be longer, issue #5)
  • SFDP pages (with some caveats)
  • TOCTOU changes to the flash image based on read patterns

Not yet supported

  • Dual- and Quad-SPI (issue #1)
  • Multiple !CS pins (issue #7)
  • Fast read command (issue #1)
  • Erase/Write emulation (issue #12)
  • Status registers (partially supported, could be better)
  • Block protection bits (maybe worth it, probably not)
  • Linux RISC-V core in the FPGA

Wiring

8-SOIC chip clip and !CS pin mod

Typical 8-SOIC and 8-DIP flash chips (!RST and Vcc are optional):

                    +------+
   J1 7     !CS 1---| o    |---8  Vcc   J1 + (for low voltage)
   J1 10     SO 2---|      |---7 !RST   J1 11 (optional)
            !WP 3---|      |---6  SCK   J1 8
   J1 GND   GND 4---|      |---5  SI    J1 9
                    +------+

Typical 16-SOIC flash chips (!RST and Vcc are optional):

                   +--------+
           IO3 1---| o      |--16 CLK      J1 8
   J1 +    Vcc 2---|        |--15 SI/IO1   J1 9
   J1 11  !RST 3---|        |--14
               4---|        |--13
               5---|        |--12
               6---|        |--11
   J1 7    !CS 7---|        |--10 GND      J1 GND
   J1 10    SO 8---|        |---9 !WP/IO2
                   +--------+

If there is a series resistor on the !CS pin, it might be possible to clip directly to the chip with a Pomona 8-SOIC "chip clip" and use TOCTOU mode to override the signal from the PCH. However, this doesn't always work so sometimes it is necessary to desolder pin 1 from the board, bend the leg upwards and solder a jumper wire to the pad on the maiboard as shown in the above photo.

If the board has a "Dediprog" or programming header it might be possible to attach directly to the header and also override the chip select pin, although more testing is necessary.

IMPORTANT NOTE the system defaults to using 3.3v signalling for the SPI bus. If you have more modern system, it might use 1.8v and driving it at the higher voltage can cause problems. It is possible to remove the RV3 resistor from the board and provide power to the FPGA GPIO bank through the + pin on the left side connector (J1, pin labeled "2.5/3.3V"); you can connect this pin to the Vcc pin on the SPI flash, which will allow the FPGA to output the same voltage. More details are in issue #10.

Usage

spispy connected to a Supermicro X11SSH-F mainboard

If using the spispy with a 3.3V chip and a clip you can leave the Vcc pin disconnected; otherwise be sure to see the important note above about hardware changes to support lower voltage flash chips. Be sure to set the TOCTOU flag in the spispy.v file so that the spispy will prevent the real flash from responding (or use the #RESET pin; need to document when this works).

When you plug in the spispy it should show up as a USB-CDC-ACM device with a device file like /dev/ttyACM0. You might have to start minicom or some other terminal program to configure the control lines correctly (and to prevent ModemManager from screwing with it).

Install the sfdp.bin image into the top of DRAM to tell the PCH that the flash only supports single read commands at the slowest speed:

write-ram 0x1000000 sfdp.bin > /dev/ttyACM0

Install the ROM image into the bottom of DRAM (pv is optional to provide a bargraph and bandwidth measurement):

write-ram 0x0 coreboot.bin | pv > /dev/ttyACM0

If you want to update part of the ROM image, such as the top 8 MB of the coreboot image, you can use dd to extract that part:

dd < coreboot.bin bs=1024 skip=8192 | write-ram 0x800000 | pv > /dev/ttyACM0

Protocol

SPI data

The SPI protocol is difficult to emulate without specialized hardware since it has very demanding timing requirements. The flash device has no control over the clock and must be able to respond to a random read request on the very next clock. At 20 MHz, the slowest SPI bus on some Intel PCH chipsets, this is 50ns from receiving the last bit of the address to having to supply the first bit of the data.

Unfortunately, most microcontroller CPUs aren't able to respond to an incoming SPI byte on the next SPI cycle due to internal muxes and buses, so they aren't able to reply in time. Even if the CPU could do it, most DRAM memory has a 100ns or longer latency for a random read, so it won't be able to answer quickly enough. Additionally, DRAM requires a refresh cycle that takes it offline during the refresh, which adds a random latency.

SDRAM read waveform

These difficulties can be overcome with an FPGA using a custom DRAM controller. The FPGA is able to inhibit refresh cycles during the SPI critical sections, which reduces the latency jitter, and it can split the DRAM access into two parts: the "row activation" once 16 of the 24 address bits are known, and then a "column read" of two bytes worth of data once 7 of the last 8 bits are known. The correct byte is selected once the last bit of the address has been received.

The row activation command requires at least four DRAM clock cycles, but can be stretched arbitrarily long with a special control signal wired into the FPGA's sdram controller from the SPI bus interface. This allows the FPGA to overlap the activation with the reception of the last bits, and the final column read requires only two clock cycles when the DRAM is configured with a CAS latency of two.

Subsequent bytes are "easy" at 20 MHz for single SPI since the full SDRAM read cycle (7 FPGA clocks) fits into the 8 clocks of the SPI bus (roughly 24 FPGA clocks). For dual or quad-SPI it will be necessary to configure a burst mode on the SDRAM controller or allow new column addresses to be provided dynamically.

More Repositories

1

LEDscape

Beagle Bone Black cape and firmware for driving a large number of WS281x LED strips.
C
280
star
2

safeboot

Scripts to slightly improve the security of the Linux boot process with UEFI Secure Boot and TPM support
Shell
270
star
3

hcpy

Python tool to talk to Home Connect appliances over the local network (no cloud required)
Python
261
star
4

papercraft

Unfolding STL models to make laser cut patterns
C
260
star
5

airbreak

CPAP jailbreak to allow it to be used as a temporary ventilator
Assembly
258
star
6

esp32-ttgo

Code for the TT GO ESP32 module
156
star
7

rwmem

Read and write physical memory on OS X
C
136
star
8

pixel-wrangler

HDMI to whatever adapter
Verilog
104
star
9

plotter-vision

Hidden Wireframe removal demo in p5.js
JavaScript
87
star
10

eink-pricetags

Reverse engineering cheap e-ink price tags
C
87
star
11

up5k

Upduino v2 with the ice40 up5k FPGA demos
Verilog
78
star
12

charliewatch

An "analog" version of Travis Goodspeed's Goodwatch
C
77
star
13

vst

Software for the v.st vector boards
Processing
76
star
14

safeboot-loader

Linux kernel module to use UEFI Block IO Protocol devices. Probably not a good idea.
C
72
star
15

lighthouse

Arduino and Processng library to interface with the HTC Vive Lighthouse beacons
Eagle
69
star
16

disassembly

Reverse engineering and disassembly examples
C
51
star
17

ZbPy

MicroPython IEEE802.15.4 / Zigbee parser
Python
44
star
18

mdt9100

Motorolla Mobile Data Terminal MDT9100 interface for the BeagleBone Black
C++
41
star
19

classicmac

Mac 128/Plus/SE hardware interface using the BeagleBone Black PRU.
C
33
star
20

risc8

Mostly AVR compatible FPGA soft-core
Verilog
25
star
21

cosign

Cooperative RSA signing
Python
25
star
22

jumphost

ssh jump host appliance
Makefile
25
star
23

DynamicTemplates

Import of the DIY Dynamic Template v2, retrieved from the Internet Archive
C++
22
star
24

linux-builder

Scripts to build the Linux kernel from a config file and initrd from a list of programs
Python
19
star
25

flashtools

Simplified version of flashrom for installing new system firmware
C
18
star
26

soft-ssb

PSK31 over SSB for the teensy 3.1 implemented entirely in software
Arduino
17
star
27

psionpi

Raspberry Pi board to fit in a Psion PDA
Verilog
14
star
28

unicodedots

Draws pictures with Unicode Braille characters
Perl
13
star
29

bioswrite

Command line tool to write to x86 boot flash chips via the PCH
C
12
star
30

p5.projection

p5js library for projection mapping
JavaScript
12
star
31

polargraph

A hackish polargraph plotting tool
C
11
star
32

advent

The original Colossal Cave adventure in FORTRAN IV
Fortran
11
star
33

modelf

USB interface for the IBM Model F AT keyboard
Arduino
11
star
34

servostep

Closed loop servo control for stepper motors
Arduino
10
star
35

sneekbot

Snake robot built with the LX16A servos
C++
10
star
36

uxen

Clone of Bromium's public release of uxen-4.0 and uxen-4.1
C
10
star
37

rotary

Rotary phone interface for the Adafruit FONA boards
Eagle
9
star
38

rgblaser

RGB laser projector controller built on a teensy 3
Eagle
8
star
39

gamebadge

Gameboy emulator for the SHA2017 e-ink badge
C
8
star
40

sbsigntools

Clone of https://git.kernel.org/pub/scm/linux/kernel/git/jejb/sbsigntools.git/ with patches for yubikey support
C
8
star
41

neyes

ASCII art version of xeyes, implemented with ncurses and xterm mouse mode
C
8
star
42

prom

PROM reader
C
7
star
43

overtime

When is the next GVB ferry, bus or tram arriving
C
7
star
44

safeboot-attest

Remote attestation for the safeboot system
Python
7
star
45

enigma

3D Printable Pocket Enigma machine
OpenSCAD
7
star
46

moon-watch

Moon phase and solar time watch face for the Skagen Hybrid
JavaScript
7
star
47

flora

FLORA and Pixel class examples
Arduino
7
star
48

teensyv

Vector display for the Teensy 3
C
7
star
49

hackerspace-zone

Self-hosted, single-sign-on community server
Shell
7
star
50

slackwrap

Wrap the slack API around stdin/stdout
Perl
6
star
51

barcode

Generating barcodes with Unicode characters
Perl
6
star
52

xkeyscore

Twitter notification filter
JavaScript
6
star
53

spiflash

Teensy based SPI flash programmer
C++
6
star
54

ArduinoVoice

Port of the SAM c64 software to the Arduino
C
6
star
55

iomonitor

Trace IO calls in a process
Perl
5
star
56

fpga-class

Intro to FPGA class projects
Verilog
5
star
57

ssss

Shamir's Secret Sharing Scheme
C
5
star
58

ft817

Yaesu FT-817nd serial port interface
C
5
star
59

voyager

Signal processing of the images on the Voyager Golden Record
Perl
5
star
60

model100

TRS-80 Model 100 FPGA board
C
5
star
61

ncube

nCube supercomputer documentation
5
star
62

gcc-0.9

gcc-0.9 from 1987
C
5
star
63

train-display

NS train display LED matrix
Verilog
4
star
64

bx3-sdk

Import of BX3 SDK for RF03 BlueX SoC
C
4
star
65

litefestival

Guerilla projection art for the Amsterdam "Lite" Festival
JavaScript
4
star
66

soldertime

Firmware for the Spikenzie Labs Solder:Time DeskClock
Arduino
4
star
67

sparktime

Spark Core demo
C
4
star
68

orrery

3D printable orrery with six planets and one moon. VERY DRAFT!
OpenSCAD
4
star
69

safeboot-hcp

Host Certificate tools
Shell
3
star
70

symbolics

Symbolics keyboard interface
Arduino
3
star
71

pdfcal

Page-per-day calendar generator for Remarkable tablet
Python
3
star
72

openscad

OpenSCAD tutorial
3
star
73

secret-cards

JavaScript
3
star
74

kexec-load

Wrapper around the kexec_load system call
C
2
star
75

mondriaan

Mondriaan Art project
JavaScript
2
star
76

fft-doodle

Doodle some lines and see the FFT of them
JavaScript
2
star
77

orion

Constellation PCB art
2
star
78

hushcon

Hushcon 2016 pagers
C++
2
star
79

curves

Fractal curves
Perl
2
star
80

gnomon

3D printed or laser cut digital sundial
OpenSCAD
2
star
81

october-first

The October First committee notes
2
star
82

SketchSaver

Saves your Arduino sketches into the flash so that you can recover them later
C++
2
star
83

avr-video

AVR NTSC video generator and character overlay using two resistors and a LM1881 video sync separator.
C
2
star
84

vectorscope

Import of bitbucket.com/hudson/vectorscope
C
2
star
85

cyclops

Attempt to build a cyclops camera with RAM chips
C++
2
star
86

laserchess

Port of the 1987 Compute! magazine LaserChess game (Amiga BASIC version)
JavaScript
2
star
87

epilog

Command line laser cutting tool for Epilog cutters
C
2
star
88

gcc-1.21

Ancient version of gcc
C
1
star
89

markovtrek

Markov generated Startrek episodes
Perl
1
star
90

spacerocks2000

Spacerocks 2000, an updated version of the Arduino spacerocks game
JavaScript
1
star
91

gemma-bootloader

An Adafruit GEMMA/Trinket compatible bootloader
C
1
star
92

augustine

Augustine's 16th Law
R
1
star
93

pario

Parallel IO using the BeagleBone Black PRU
C
1
star
94

nbody

A p5js n-body simulation
JavaScript
1
star
95

rowblue

ESP32 BLE interface for generic rowing machines to Zwift and other services
C
1
star
96

pendant

Holly's Burning Man pendant
Arduino
1
star
97

ikwilcoronabooster

Static site for finding the current year of Netherlands corona boosters
HTML
1
star
98

diceroll-games

Multiparty cryptographic dice
JavaScript
1
star
99

intercom-kiosk

Intercom front end for the house using mqtt and reolink
JavaScript
1
star
100

truchet

Truchet Tile svg generator for plotting
HTML
1
star