aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2019-01-01 12:37:34 -0800
committerTomas Vanek <vanekt@fbl.cz>2019-01-11 19:50:09 +0000
commit31ea7037b3df7e567a9eb34d28947d118c4cada1 (patch)
tree5230e15a186f1915f3e1d5dd729c11b8c3f3c519 /contrib
parent42d8fa899c6a6f136daa761e7718003f08f723e7 (diff)
Add flash support for SiFive's Freedom E platforms
Valgrind and Clang Static Analyzer have no complaints about this change. Change-Id: I7757615ec52448372bdc57729cdf97c7016d97e8 Signed-off-by: Tim Newsome <tim@sifive.com> Reviewed-on: http://openocd.zylin.com/4656 Tested-by: jenkins Reviewed-by: Philipp Guehring <pg@futureware.at> Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Diffstat (limited to 'contrib')
-rw-r--r--contrib/loaders/flash/fespi/Makefile28
-rw-r--r--contrib/loaders/flash/fespi/fespi.S99
-rw-r--r--contrib/loaders/flash/fespi/fespi.inc15
3 files changed, 142 insertions, 0 deletions
diff --git a/contrib/loaders/flash/fespi/Makefile b/contrib/loaders/flash/fespi/Makefile
new file mode 100644
index 00000000..4d2ab51d
--- /dev/null
+++ b/contrib/loaders/flash/fespi/Makefile
@@ -0,0 +1,28 @@
+BIN2C = ../../../../src/helper/bin2char.sh
+
+CROSS_COMPILE ?= riscv64-unknown-elf-
+
+CC=$(CROSS_COMPILE)gcc
+OBJCOPY=$(CROSS_COMPILE)objcopy
+OBJDUMP=$(CROSS_COMPILE)objdump
+
+CFLAGS = -march=rv32i -mabi=ilp32 -x assembler-with-cpp -nostdlib -nostartfiles
+
+all: fespi.inc
+
+.PHONY: clean
+
+%.elf: %.S
+ $(CC) $(CFLAGS) $< -o $@
+
+%.lst: %.elf
+ $(OBJDUMP) -S $< > $@
+
+%.bin: %.elf
+ $(OBJCOPY) -Obinary $< $@
+
+%.inc: %.bin
+ $(BIN2C) < $< > $@
+
+clean:
+ -rm -f *.elf *.lst *.bin *.inc
diff --git a/contrib/loaders/flash/fespi/fespi.S b/contrib/loaders/flash/fespi/fespi.S
new file mode 100644
index 00000000..d68e65ef
--- /dev/null
+++ b/contrib/loaders/flash/fespi/fespi.S
@@ -0,0 +1,99 @@
+#define SPIFLASH_READ_STATUS 0x05 // Read Status Register
+#define SPIFLASH_BSY_BIT 0x00000001 // WIP Bit of SPI SR on SMI SR
+
+// Register offsets
+#define FESPI_REG_FMT 0x40
+#define FESPI_REG_TXFIFO 0x48
+#define FESPI_REG_RXFIFO 0x4c
+#define FESPI_REG_IP 0x74
+
+// Fields
+#define FESPI_IP_TXWM 0x1
+#define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
+
+// To enter, jump to the start of command_table (ie. offset 0).
+// a0 - FESPI base address
+// a1 - start address of buffer
+
+// The buffer contains a "program" in byte sequences. The first byte in a
+// sequence determines the operation. Some operation will read more data from
+// the program, while some will not. The operation byte is the offset into
+// command_table, so eg. 4 means exit, 8 means transmit, and so on.
+
+ .global _start
+_start:
+command_table:
+ j main // 0
+ ebreak // 4
+ j tx // 8
+ j txwm_wait // 12
+ j write_reg // 16
+ j wip_wait // 20
+ j set_dir // 24
+
+// Execute the program.
+main:
+ lbu t0, 0(a1)
+ addi a1, a1, 1
+ la t1, command_table
+ add t0, t0, t1
+ jr t0
+
+// Read 1 byte the contains the number of bytes to transmit. Then read those
+// bytes from the program and transmit them one by one.
+tx:
+ lbu t1, 0(a1) // read number of bytes to transmit
+ addi a1, a1, 1
+1: lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
+ bltz t0, 1b
+ lbu t0, 0(a1) // Load byte to write
+ sw t0, FESPI_REG_TXFIFO(a0)
+ addi a1, a1, 1
+ addi t1, t1, -1
+ bgtz t1, 1b
+ j main
+
+// Wait until TXWM is set.
+txwm_wait:
+1: lw t0, FESPI_REG_IP(a0)
+ andi t0, t0, FESPI_IP_TXWM
+ beqz t0, 1b
+ j main
+
+// Read 1 byte that contains the offset of the register to write, and 1 byte
+// that contains the data to write.
+write_reg:
+ lbu t0, 0(a1) // read register to write
+ add t0, t0, a0
+ lbu t1, 1(a1) // read value to write
+ addi a1, a1, 2
+ sw t1, 0(t0)
+ j main
+
+wip_wait:
+ li a2, SPIFLASH_READ_STATUS
+ jal txrx_byte
+ // discard first result
+1: li a2, 0
+ jal txrx_byte
+ andi t0, a2, SPIFLASH_BSY_BIT
+ bnez t0, 1b
+ j main
+
+txrx_byte: // transmit the byte in a2, receive a bit into a2
+ lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
+ bltz t0, txrx_byte
+ sw a2, FESPI_REG_TXFIFO(a0)
+1: lw a2, FESPI_REG_RXFIFO(a0)
+ bltz a2, 1b
+ ret
+
+set_dir:
+ lw t0, FESPI_REG_FMT(a0)
+ li t1, ~(FESPI_FMT_DIR(0xFFFFFFFF))
+ and t0, t0, t1
+ lbu t1, 0(a1) // read value to OR in
+ addi a1, a1, 1
+ or t0, t0, t1
+ sw t0, FESPI_REG_FMT(a0)
+ j main
diff --git a/contrib/loaders/flash/fespi/fespi.inc b/contrib/loaders/flash/fespi/fespi.inc
new file mode 100644
index 00000000..768bdc59
--- /dev/null
+++ b/contrib/loaders/flash/fespi/fespi.inc
@@ -0,0 +1,15 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x6f,0x00,0xc0,0x01,0x73,0x00,0x10,0x00,0x6f,0x00,0xc0,0x02,0x6f,0x00,0x00,0x05,
+0x6f,0x00,0xc0,0x05,0x6f,0x00,0x00,0x07,0x6f,0x00,0x00,0x0a,0x83,0xc2,0x05,0x00,
+0x93,0x85,0x15,0x00,0x17,0x03,0x00,0x00,0x13,0x03,0xc3,0xfd,0xb3,0x82,0x62,0x00,
+0x67,0x80,0x02,0x00,0x03,0xc3,0x05,0x00,0x93,0x85,0x15,0x00,0x83,0x22,0x85,0x04,
+0xe3,0xce,0x02,0xfe,0x83,0xc2,0x05,0x00,0x23,0x24,0x55,0x04,0x93,0x85,0x15,0x00,
+0x13,0x03,0xf3,0xff,0xe3,0x44,0x60,0xfe,0x6f,0xf0,0x5f,0xfc,0x83,0x22,0x45,0x07,
+0x93,0xf2,0x12,0x00,0xe3,0x8c,0x02,0xfe,0x6f,0xf0,0x5f,0xfb,0x83,0xc2,0x05,0x00,
+0xb3,0x82,0xa2,0x00,0x03,0xc3,0x15,0x00,0x93,0x85,0x25,0x00,0x23,0xa0,0x62,0x00,
+0x6f,0xf0,0xdf,0xf9,0x13,0x06,0x50,0x00,0xef,0x00,0x80,0x01,0x13,0x06,0x00,0x00,
+0xef,0x00,0x00,0x01,0x93,0x72,0x16,0x00,0xe3,0x9a,0x02,0xfe,0x6f,0xf0,0x1f,0xf8,
+0x83,0x22,0x85,0x04,0xe3,0xce,0x02,0xfe,0x23,0x24,0xc5,0x04,0x03,0x26,0xc5,0x04,
+0xe3,0x4e,0x06,0xfe,0x67,0x80,0x00,0x00,0x83,0x22,0x05,0x04,0x13,0x03,0x70,0xff,
+0xb3,0xf2,0x62,0x00,0x03,0xc3,0x05,0x00,0x93,0x85,0x15,0x00,0xb3,0xe2,0x62,0x00,
+0x23,0x20,0x55,0x04,0x6f,0xf0,0x9f,0xf4,