diff options
author | Tim Newsome <tim@sifive.com> | 2019-01-01 12:37:34 -0800 |
---|---|---|
committer | Tomas Vanek <vanekt@fbl.cz> | 2019-01-11 19:50:09 +0000 |
commit | 31ea7037b3df7e567a9eb34d28947d118c4cada1 (patch) | |
tree | 5230e15a186f1915f3e1d5dd729c11b8c3f3c519 /contrib | |
parent | 42d8fa899c6a6f136daa761e7718003f08f723e7 (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/Makefile | 28 | ||||
-rw-r--r-- | contrib/loaders/flash/fespi/fespi.S | 99 | ||||
-rw-r--r-- | contrib/loaders/flash/fespi/fespi.inc | 15 |
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, |