firmware: Import of the boot code
This is what gets embedded in the bitstream and loads the main software from flash. Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
parent
c85dc29b06
commit
f4ee67209b
|
@ -0,0 +1,24 @@
|
|||
CROSS ?= riscv-none-embed-
|
||||
|
||||
CC := $(CROSS)gcc
|
||||
OBJCOPY := $(CROSS)objcopy
|
||||
|
||||
CFLAGS=-Wall -Os -march=rv32i -mabi=ilp32 -ffreestanding -flto -nostartfiles -fomit-frame-pointer -Wl,--gc-section --specs=nano.specs
|
||||
|
||||
|
||||
all: boot.hex
|
||||
|
||||
|
||||
boot.elf: lnk-boot.lds boot.S
|
||||
$(CC) $(CFLAGS) -Wl,-Bstatic,-T,lnk-boot.lds,--strip-debug -DAPP_FLASH_ADDR=0x000a0000 -o $@ boot.S
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
%.hex: %.bin
|
||||
hexdump boot.bin -ve '1/4 "%08x\n"' $< > $@
|
||||
|
||||
clean:
|
||||
rm -f *.bin *.hex *.elf *.o
|
||||
|
||||
.PHONY: clean
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* boot.S
|
||||
*
|
||||
* SPI boot code
|
||||
*
|
||||
* Copyright (C) 2020-2023 Sylvain Munaut <tnt@246tNt.com>
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef APP_FLASH_ADDR
|
||||
#define APP_FLASH_ADDR 0x000a0000
|
||||
#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
|
||||
jal spi_wakeup
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SB_SPI driver code
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Register definitions
|
||||
|
||||
.equ SPI_BASE, 0x81000000
|
||||
|
||||
.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
|
||||
|
||||
|
||||
// Initializes te SPI hardware
|
||||
//
|
||||
// Clobbers a0, a1
|
||||
|
||||
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
|
||||
|
||||
|
||||
//
|
||||
// Wake up flash
|
||||
//
|
||||
spi_wakeup:
|
||||
|
||||
mv s2, ra
|
||||
|
||||
// Setup CS
|
||||
li t0, SPI_BASE
|
||||
li t1, 0x0e
|
||||
sw t1, SPICSR(t0)
|
||||
|
||||
// Send command
|
||||
li a0, 0xAB
|
||||
jal _spi_do_one
|
||||
|
||||
// Release CS
|
||||
li t0, SPI_BASE
|
||||
li t1, 0x0f
|
||||
sw t1, SPICSR(t0)
|
||||
|
||||
// Wait a bit
|
||||
li s1, 0x10000
|
||||
1:
|
||||
addi s1, s1, -1
|
||||
bne s1, zero, 1b
|
||||
|
||||
// Done
|
||||
jr s2
|
||||
|
||||
|
||||
// Reads a block of memory from SPI flash
|
||||
//
|
||||
// Params:
|
||||
// a0 - destination pointer
|
||||
// a1 - length (bytes)
|
||||
// a2 - flash offset
|
||||
// Clobbers t0, t1, s0, s1, s2
|
||||
|
||||
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
|
||||
|
||||
|
||||
// Performs a single 8 bit SPI xfer
|
||||
//
|
||||
// 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
|
|
@ -0,0 +1,14 @@
|
|||
MEMORY
|
||||
{
|
||||
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x0400
|
||||
}
|
||||
ENTRY(_start)
|
||||
SECTIONS {
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text.start)
|
||||
*(.text)
|
||||
*(.text*)
|
||||
} >ROM
|
||||
}
|
Loading…
Reference in New Issue