Commit 05403a7b authored by Mattia Rizzi's avatar Mattia Rizzi

Bootloader code

parent 87366418
#CROSS_COMPILE_TARGET ?= /home/mattia/riscv-toolchain/riscv/bin/riscv32-elf-
CROSS_COMPILE_TARGET ?= /home/mattia/riscv32-nanolib/gnu-mcu-eclipse/riscv-none-gcc/8.1.0-2-20181019-0952/bin/riscv-none-embed-
CFLAGS += -mabi=ilp32 -march=rv32im -Os -ffunction-sections -fdata-sections --specs=nano.specs --specs=nosys.specs -lgcc -lc -Wl,--gc-sections
CC = $(CROSS_COMPILE_TARGET)gcc
LD = $(CROSS_COMPILE_TARGET)ld
OBJDUMP = $(CROSS_COMPILE_TARGET)objdump
OBJCOPY = $(CROSS_COMPILE_TARGET)objcopy
SIZE = $(CROSS_COMPILE_TARGET)size
STRIP = $(CROSS_COMPILE_TARGET)strip
all: bootloader.hex
crt0.o: crt0.S
$(CC) -c -o $@ $(CFLAGS) $<
irq.o: irq.S
$(CC) -c -o $@ $(CFLAGS) $<
eth_config.o: eth_config.c
$(CC) -c -o $@ $(CFLAGS) $<
refresh.o: refresh.s
$(CC) -c -o $@ $(CFLAGS) $<
main: main.o crt0.o bootldr.ld
$(CC) -o $@ -nostartfiles $(CFLAGS) crt0.o main.o -T bootldr.ld
main-text.bin: main
riscv32-elf-objcopy -j .text -j .loader -O binary $< $@
bootloader.hex: main-text.bin
riscv32-elf-objcopy -I binary -O ihex $< $@
clean:
rm main
rm main-text.*
rm bootloader.*
OUTPUT_FORMAT("elf32-littleriscv")
ENTRY(_start)
MEMORY
{
iram : ORIGIN = 0x00000000, LENGTH = 512
ldr : ORIGIN = 0x00000200, LENGTH = 512
dram : ORIGIN = 0x00010000, LENGTH = 64K
}
SECTIONS
{
/* Begining of code and text segment */
. = 0x00000000;
/* text: Program code section */
.text :
{
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
} > iram
.loader :
{
*(.launcher)
*(.launcher.*)
*(.launcher_call)
} > ldr
/* rodata: Read-only data */
.data :
{
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
_edata = .;
/* Have _gp point to middle of sdata/sbss to maximize displacement range */
. = ALIGN(16);
_gp = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.srodata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
_fbss = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
_bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
_end = ALIGN(8);
} > dram
PROVIDE(_fstack = ORIGIN(dram) + LENGTH(dram) - 0x100);
}
.section .boot, "ax", @progbits
.global _start
_start:
j _entry
.org 0x8
_entry:
lui ra, 0
lui sp, 0
lui gp, 0
lui tp, 0
lui s0, 0
lui s1, 0
lui s2, 0
lui s3, 0
lui s4, 0
lui s5, 0
lui s6, 0
lui s7, 0
lui s8, 0
lui s9, 0
lui s10, 0
lui s11, 0
lui t0, 0
lui t1, 0
lui t2, 0
lui t3, 0
lui t4, 0
lui t5, 0
lui t6, 0
lui a0, 0
lui a1, 0
lui a2, 0
lui a3, 0
lui a4, 0
lui a5, 0
lui a6, 0
lui a7, 0
li t1, 0xffff
1:
sw zero, 0(t0)
addi t0, t0, 4
and t0, t0, t1
bne t0, zero, 1b
lui t0, 0
lui t1, 0
la gp, _gp /* Initialize global pointer */
la sp, _fstack
/* la t0, _fexception_stack
csrrw t0, mscratch, t0 */
/* clear the bss segment */
la t0, _fbss
la t1, _end
1:
#ifdef __riscv64
sd zero,0(t0)
addi t0, t0, 8
#else
sw zero,0(t0)
addi t0, t0, 4
#endif
bltu t0, t1, 1b
call main
1:
j 1b
.data
_recov_data: .long 0
// TO DO: check integrity of the image before executing it
#include <stdio.h>
//#include <string.h>
#include "riscv.h"
#define IRAM_SIZE 65536
#define LOADER_SIZE 512
#define APP_IMAGE_TEXT 0x60000000
#define APP_IMAGE_DATA 0x60020000
#define LOADER_IMAGE 0x60012200
#define print_line() print_char('\n');print_char('\r')
typedef struct uart_reg {
uint32_t flags;
uint32_t buffer;
} uart_reg;
void __attribute__((__section__(".launcher_call"))) print_string (char * str, unsigned char len) {
for (char i=0; i < len; i++)
print_char(str[i]);
}
void __attribute__((always_inline)) print_char (char c) {
volatile uart_reg * uart_tx = (uart_reg *) 0x82000000;
while (!uart_tx->flags);
uart_tx->buffer = c;
uart_tx->flags = 2;
}
void __attribute__((__section__(".launcher_call"))) print_word (uint32_t word) {
int8_t i;
uint8_t disp;
uint32_t temp;
char c;
for (i=7; i >= 0; i--) {
disp = ((word >> (i<<2)) & 0xf);
if (disp <= 9 )
c = '0'+ disp;
else
c = 'A' + disp - 10;
print_char (c);
}
}
uint32_t __attribute__((__section__(".launcher_call"))) envm_read (uint32_t * addr) {
volatile uint32_t * wb_envm_dev = 0x87000000;
while (wb_envm_dev[0] & 0x1);
wb_envm_dev[1] = addr;
while (*wb_envm_dev & 0x1);
return wb_envm_dev[2];
}
void __attribute__((__section__(".launcher"))) iram_write (uint32_t * addr, uint32_t data) {
volatile uint32_t * wb_iram_dev = 0x87000010;
wb_iram_dev[0] = addr;
wb_iram_dev[1] = data;
asm ("nop");
// asm("nop");
// asm("nop");
// asm("nop");
}
void load_image ();
void main(void)
{
const char boot_logo [5] = {'b','o','o','t'};
volatile char * p_wd = 0x81000000;
void (*func)(void) = IRAM_SIZE - LOADER_SIZE + (&load_image - 0x200) ;
uint32_t i, data = 0;
//print_line();
print_string (boot_logo, 4);
print_line();
for (i=1024; i < (1<<16); i=i+4)
iram_write(i, 0);
for (i=0; i < 1024; i=i+4) {
data = envm_read (LOADER_IMAGE + i);
iram_write(IRAM_SIZE-LOADER_SIZE+i, data);
}
*p_wd = 1;
(*func)(); // jump to (relocated) load_image()
while(1);
// *p_wd = 1; //watchdog
}
void __attribute__((__section__(".launcher"))) load_image () {
const char done [5] = {'D','o','n', 'e'};
uint32_t i, data = 0;
uint32_t * dram = 0;
void (*func)(void) = 0 ;
for (i=0; i < IRAM_SIZE-LOADER_SIZE; i=i+4) {
data = envm_read (APP_IMAGE_TEXT + i);
iram_write (i, data);
}
for (i=0; i < (1<<16)-1024; i=i+4) {
data = envm_read (APP_IMAGE_DATA + i);
*dram++ = data;
}
print_string(done, 4);
(*func)(); // run app
while(1);
}
#ifndef __RISCV_H
#define __RISCV_H
#ifdef __GNUC__
#define riscv_read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define riscv_write_csr(reg, val) \
asm volatile ("csrw " #reg ", %0" :: "r"(val))
#define riscv_swap_csr(reg, val) ({ long __tmp; \
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
__tmp; })
#define riscv_set_csr(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (bit) < 32) \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define riscv_clear_csr(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (bit) < 32) \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define riscv_rdtime() riscv_read_csr(time)
#define riscv_rdcycle() riscv_read_csr(cycle)
#define riscv_rdinstret() riscv_read_csr(instret)
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment