gateware: Initial import of all common parts
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
diff --git a/gateware/common/fw/boot.S b/gateware/common/fw/boot.S
new file mode 100644
index 0000000..df4f41b
--- /dev/null
+++ b/gateware/common/fw/boot.S
@@ -0,0 +1,144 @@
+/*
+ * boot.S
+ *
+ * SPI boot code
+ *
+ * Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef APP_FLASH_ADDR
+#define APP_FLASH_ADDR 0x00100000
+#endif
+
+#ifndef APP_SRAM_ADDR
+#define APP_SRAM_ADDR 0x00020000
+#endif
+
+#ifndef APP_SIZE
+#define APP_SIZE 0x00010000
+#endif
+
+ .section .text.start
+ .global _start
+_start:
+ // SPI init
+ jal spi_init
+
+ // Read from flash to SRAM
+ li a0, APP_SRAM_ADDR
+ li a1, APP_SIZE
+ li a2, APP_FLASH_ADDR
+ jal spi_flash_read
+
+ // Setup reboot code
+ li t0, 0x0002006f
+ sw t0, 0(zero)
+
+ // Jump to main code
+ j APP_SRAM_ADDR
+
+
+ .equ SPI_BASE, 0x80000000
+ .equ SPICR0, 4 * 0x08
+ .equ SPICR1, 4 * 0x09
+ .equ SPICR2, 4 * 0x0a
+ .equ SPIBR, 4 * 0x0b
+ .equ SPISR, 4 * 0x0c
+ .equ SPITXDR, 4 * 0x0d
+ .equ SPIRXDR, 4 * 0x0e
+ .equ SPICSR, 4 * 0x0f
+
+
+spi_init:
+ li a0, SPI_BASE
+
+ li a1, 0xff
+ sw a1, SPICR0(a0)
+
+ li a1, 0x80
+ sw a1, SPICR1(a0)
+
+ li a1, 0xc0
+ sw a1, SPICR2(a0)
+
+ li a1, 0x03
+ sw a1, SPIBR(a0)
+
+ li a1, 0x0f
+ sw a1, SPICSR(a0)
+
+ ret
+
+
+// Params:
+// a0 - destination pointer
+// a1 - length (bytes)
+// a2 - flash offset
+//
+
+spi_flash_read:
+ // Save params
+ mv s0, a0
+ mv s1, a1
+ mv s2, ra
+
+ // Setup CS
+ li t0, SPI_BASE
+ li t1, 0x0e
+ sw t1, SPICSR(t0)
+
+ // Send command
+ li a0, 0x03
+ jal _spi_do_one
+
+ srli a0, a2, 16
+ and a0, a0, 0xff
+ jal _spi_do_one
+
+ srli a0, a2, 8
+ and a0, a0, 0xff
+ jal _spi_do_one
+
+ and a0, a2, 0xff
+ jal _spi_do_one
+
+ // Read loop
+_spi_loop:
+ li a0, 0x00
+ jal _spi_do_one
+ sb a0, 0(s0)
+ addi s0, s0, 1
+ addi s1, s1, -1
+ bne s1, zero, _spi_loop
+
+ // Release CS
+ li t0, SPI_BASE
+ li t1, 0x0f
+ sw t1, SPICSR(t0)
+
+ // Done
+ jr s2
+
+
+// Params: a0 - Data to TX
+// Returns: a0 - RX data
+// Clobbers t0, t1
+_spi_do_one:
+ li t0, SPI_BASE
+ li t1, 0x08
+
+ // Write TX data
+ sw a0, SPITXDR(t0)
+
+ // Wait for RXRDY
+1:
+ lw a0, SPISR(t0)
+ and a0, a0, t1
+ bne a0, t1, 1b
+
+ // Read RX data
+ lw a0, SPIRXDR(t0)
+
+ // Done
+ ret