Skip to content

Commit

Permalink
boot: make bootloader multitarget
Browse files Browse the repository at this point in the history
  • Loading branch information
saursin committed Oct 14, 2023
1 parent e054162 commit b374908
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 173 deletions.
44 changes: 33 additions & 11 deletions sw/bootloader/Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
EXEC:= bootloader.elf
EXEC:= bootloader

CFLAGS:= -mabi=ilp32 -march=rv32i -nostartfiles -ffreestanding -DTARGET_HYDROGENSOC -Os
RVPREFIX:= riscv64-unknown-elf

CFLAGS:= -mabi=ilp32 -march=rv32i -nostartfiles -ffreestanding -Os
CFLAGS+= -I $(RVATOM_LIB)/include
LFLAGS:= -L $(RVATOM_LIB)/ -T $(RVATOM_LIB)/link/link_boot_hydrogensoc.ld -lcatom -Xlinker -Map $(EXEC).map -Wl,--gc-sections
LFLAGS:= -L $(RVATOM_LIB)/ -T $(RVATOM_LIB)/link/link_bootloader.ld -lcatom -Xlinker -Map $(EXEC).map -Wl,--gc-sections

CONVELF_ARGS:= -t elf -c

ifeq ($(MAKECMDGOALS),clean)
else
ifeq ($(soctarget), atombones)
CFLAGS += -DTARGET_ATOMBONES -DTARGET_HEADER='"atombones.h"'
else
ifeq ($(soctarget), hydrogensoc)
CFLAGS += -DTARGET_HYDROGENSOC -DTARGET_HEADER='"hydrogensoc.h"'
else
$(error Invalid SoC target: $(soctarget))
endif
endif
endif


default: $(EXEC).elf $(EXEC).objdump $(EXEC).bin $(EXEC).hex

$(EXEC).elf: main.c crt0.S
$(RVPREFIX)-gcc $(CFLAGS) -o $@ $^ $(LFLAGS)

default: boot
$(EXEC).objdump: $(EXEC).elf
$(RVPREFIX)-objdump -htd $< > $@

.PHONY: boot
boot: $(EXEC)
$(EXEC).bin: $(EXEC).elf
$(RVPREFIX)-objcopy -O binary $< $@

$(EXEC): main.c crt0.S
riscv64-unknown-elf-gcc $(CFLAGS) -o $@ $^ $(LFLAGS)
riscv64-unknown-elf-objdump -htd $@ > $@.objdump
python3 $$RVATOM/scripts/convelf.py -t elf -j hydrogensoc.json --keep-temp $(EXEC) -c
$(EXEC).hex: $(EXEC).elf
convelf.py $(CONVELF_ARGS) -m="BOOTROM:0x00010000:8192:h:$@" $<

.PHONY: clean
clean:
rm -f *.o *.objdump *.map *.elf *.hex
rm -f *.o *.objdump *.map *.elf *.hex *.bin
15 changes: 15 additions & 0 deletions sw/bootloader/atombones.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <stdint.h>

extern uint32_t __approm_start;

/**
* @brief Platform specific initialization
*
* @return void* address to jump to after boot
*/
void * platform_init() {
// Jump to start of approm
return (void *) &__approm_start;
}
58 changes: 58 additions & 0 deletions sw/bootloader/flashboot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once

#include <stdint.h>
#include <spi.h>

// Flash definitions
#define FLASH_CMD_READ 0x03
#define SPI_REG_SCKDIV_OFFSET 0x00
#define SPI_REG_SCTRL_OFFSET 0x04
#define SPI_REG_TDATA_OFFSET 0x08
#define SPI_REG_RDATA_OFFSET 0x0c
#define SPI_REG_CSCTRL_OFFSET 0x10
#define SPI_REG_DCTRL_OFFSET 0x14

/**
* @brief Copies Data from FLAST to dest
*
* @param dest dest buffer
* @param src_addr source address in flash
* @param len
* @return int
*/
int flashcpy(uint8_t *dest, uint32_t src_addr, uint32_t len) {
struct SPI_Config cfg = {
.base_addr = SPI_ADDR,
.enable = true,
.pha = false,
.pol = false,
.lsb_first = false,
.baudrate = 1000000,
.device_num = 0,
.cs_mode = CSMODE_DISABLE,
.post_cs_low_delay = 1,
.pre_cs_high_delay = 1,
.loopback_enable=false
};
spi_init(&cfg);

// select
REG32(cfg.base_addr, SPI_REG_CSCTRL_OFFSET) = bitset(REG32(cfg.base_addr, SPI_REG_CSCTRL_OFFSET), 24+cfg.device_num);
spi_transfer(&cfg, FLASH_CMD_READ);
spi_transfer(&cfg, src_addr >> 16);
spi_transfer(&cfg, src_addr >> 8);
spi_transfer(&cfg, src_addr);

while(len--) {
REG8(cfg.base_addr, SPI_REG_TDATA_OFFSET) = 0x0;
while(REG32(SPI_ADDR, SPI_REG_SCTRL_OFFSET) >> 31)
asm volatile("");
*(dest++) = REG8(cfg.base_addr, SPI_REG_RDATA_OFFSET);
}

// deselect
REG32(cfg.base_addr, SPI_REG_CSCTRL_OFFSET) = bitclear(REG32(cfg.base_addr, SPI_REG_CSCTRL_OFFSET), 24+cfg.device_num);
cfg.cs_mode = CSMODE_AUTO;
spi_init(&cfg);
return 0;
}
97 changes: 97 additions & 0 deletions sw/bootloader/hydrogensoc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#pragma once

#include "gpio.h"
#include "time.h"
#include "mmio.h"
#include "spi.h"

#include "flashboot.h"

#define STRINGIFY(s) #s
#define EXPAND_AND_STRINGIFY(s) STRINGIFY(s)

extern uint32_t __approm_start;
extern uint32_t __approm_size;


//-------------------- Configuration --------------------
#define BOOTLED_PIN 0
#define BOOTMODE_PIN0 8
#define BOOTMODE_PIN1 9

// Address offset at which image resides
#define FLASH_IMG_OFFSET 0x000c0000

// Size of Image
#define FLASH_IMG_SIZE 32 * 1024 // 32 KB

// number of flashes to indicate entering of bootloader
#define START_LED_FLASHES 3

// number of flashes to indicate entering of user application
#define END_LED_FLASHES 1
//-------------------------------------------------------


/**
* @brief Blink BOOTLED
*
* @param pin led pin
* @param count number of times to blink
* @param time_period time_period in of one ON & OFF
*/
void led_blink(int pin, int count, int time_period)
{
for(int i=0; i<count; i++)
{
gpio_write(pin, HIGH);
sleep_ms(time_period >> 1);
gpio_write(pin, LOW);
sleep_ms(time_period >> 1);
}
}


/**
* @brief Platform specific initialization
*
* @return void* address to jump to after boot
*/
void * platform_init() {
// Initialize GPIO
gpio_setmode(BOOTLED_PIN, OUTPUT);
gpio_setmode(BOOTMODE_PIN0, INPUT);
gpio_setmode(BOOTMODE_PIN1, INPUT);

// Blink LED START_LED_FLASHES times (signal entering of bootloader)
led_blink(BOOTLED_PIN, START_LED_FLASHES, 50);

// get bootmode
uint8_t bootmode = (uint8_t)gpio_read(BOOTMODE_PIN0)
| (((uint8_t)gpio_read(BOOTMODE_PIN1)) << 1);
/**
* Bootmode:
* 0b00: flashboot
* 0b01: jump to ram
* default: infinite loop
*/
if (bootmode == 0b00) {
// Bootmode: flash boot
P(puts("flashboot: Copying from " EXPAND_AND_STRINGIFY(FLASH_IMG_OFFSET) "\n");)
// copy from flash
flashcpy((uint8_t *)&__approm_start, FLASH_IMG_OFFSET, FLASH_IMG_SIZE);
} else if (bootmode == 0b01) {
// Bootmode: jump to ram
} else {
// Bootmode: Infinite loop
while(1){
asm volatile("");
}
}

// Blink single (signal jump to user code)
led_blink(BOOTLED_PIN, END_LED_FLASHES, 50);

// Jump to start of approm
return (void *) &__approm_start;
}
Loading

0 comments on commit b374908

Please sign in to comment.