Skip to content

Commit

Permalink
bootl: refactor; add uartboot
Browse files Browse the repository at this point in the history
  • Loading branch information
saursin committed Dec 26, 2023
1 parent 0b2d02a commit 15da939
Show file tree
Hide file tree
Showing 8 changed files with 430 additions and 136 deletions.
6 changes: 4 additions & 2 deletions sw/bootloader/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ include ../../common.mk
##############################################################################

EXEC:= bootloader
SRCS:= main.c crt0.S target/$(soctarget)/boot.c
SRCS:= crt0.S main.c
SRCS+= $(wildcard target/$(soctarget)/*.c)
SRCS+= $(wildcard target/$(soctarget)/*.S)

RVPREFIX:= riscv64-unknown-elf
CFLAGS:= -march=$(shell cfgparse.py $(RVATOM)/rtl/config/$(soctarget).json -a isa)
CFLAGS+= -mabi=$(shell cfgparse.py $(RVATOM)/rtl/config/$(soctarget).json -a abi)
CFLAGS+= -Wall -nostartfiles -ffreestanding -g -Os
CFLAGS+= -I $(RVATOM_LIB)/include -I include
CFLAGS+= -I $(RVATOM_LIB)/include -I include -I target/$(soctarget)
CFLAGS+= $(shell cfgparse.py $(RVATOM)/rtl/config/$(soctarget).json -d)
CFLAGS+= -DTARGET_$(shell echo $(soctarget) | tr 'a-z' 'A-Z')
ifeq ($(sim), 1)
Expand Down
20 changes: 16 additions & 4 deletions sw/bootloader/include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,26 @@
#define P(x)
#endif

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

///////////////////////////////////////////////////////////////////////////////
// Return codes

// General
#define RCODE_OK 0
#define RCODE_EXCEPTION 1
#define RCODE_UNREACHABLE 2
#define RCODE_INIT_FAIL 3
#define RCODE_FLASHBOOT_INVALID_DEVICE 4
#define RCODE_FLASHBOOT_COPY_FAIL 5
#define RCODE_PLATFORM_INIT_FAIL 3

// Flashboot
#define RCODE_FLASHBOOT_NOSPI 10
#define RCODE_FLASHBOOT_INVALID_DEVICE 11

// UARTBOOT
#define RCODE_UARTBOOT_NOUART 20
#define RCODE_UARTBOOT_FAILED 21

void puthex(unsigned val);
void __attribute__((noreturn)) boot_panic(int code);
void __attribute__((noreturn)) boot_panic(int code, char *msg);
void * platform_init();
34 changes: 9 additions & 25 deletions sw/bootloader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,17 @@ void puthex(unsigned val) {
}

void boot_panic_handler(){
boot_panic(RCODE_EXCEPTION);
#ifdef __EN_PRINTS
puts("Exception: cause=0x"); puthex(CSR_read(CSR_MCAUSE));
puts(", addr=0x"); puthex(CSR_read(CSR_MEPC));
#endif
exit(RCODE_EXCEPTION);
}

void boot_panic(int code){
void boot_panic(int code, char * msg){
#ifdef __EN_PRINTS
puts("boot-panic: ");
switch (code) {
case RCODE_EXCEPTION:
puts("exception: cause=0x"); puthex(CSR_read(CSR_MCAUSE));
puts(", addr=0x"); puthex(CSR_read(CSR_MEPC));
break;
case RCODE_UNREACHABLE:
puts("unreachable");
break;
case RCODE_INIT_FAIL:
puts("init fail");
break;
case RCODE_FLASHBOOT_INVALID_DEVICE:
puts("flashboot: invalid device");
break;
case RCODE_FLASHBOOT_COPY_FAIL:
puts("flashboot: no spi IP");
break;
default:
puts("unknown");
};
puts(msg ? msg : "?");
putchar('\n');
#endif
exit(code);
Expand All @@ -63,8 +48,7 @@ int main(){
// ********** Platform specific initialization **********
void * jump_addr = platform_init();
if(jump_addr == NULL) {

boot_panic(RCODE_INIT_FAIL);
boot_panic(RCODE_PLATFORM_INIT_FAIL, "Platform init failure");
}

// Jump to target
Expand All @@ -73,5 +57,5 @@ int main(){
app_main();

// Unreachable
boot_panic(RCODE_UNREACHABLE);
boot_panic(RCODE_UNREACHABLE, "Unreachable");
}
66 changes: 42 additions & 24 deletions sw/bootloader/target/hydrogensoc/boot.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
#include <stdint.h>

#include "common.h"

#include <platform.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <gpio.h>
#include <spi.h>
#include "flashboot.h"

#define STRINGIFY(s) #s
#define EXPAND_AND_STRINGIFY(s) STRINGIFY(s)
#include "common.h"
#include "flashboot.h"
#include "uartboot.h"

extern uint32_t __approm_start;
extern uint32_t __approm_size;
Expand All @@ -23,19 +19,20 @@ extern uint32_t __approm_size;
// 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

// Time period of LED flashes
#define LED_FLASH_TIMEPERIOD 100

// Bootmodes
#define BOOTMODE_FLASHBOOT 0
#define BOOTMODE_JUMP_TO_RAM 1
#define BOOTMODE_INF_LOOP 2
#define BOOTMODE_UARTBOOT 2
#define BOOTMODE_INF_LOOP 3
#define BOOTMODE_DEFAULT BOOTMODE_JUMP_TO_RAM

//-------------------------------------------------------
Expand All @@ -45,11 +42,11 @@ extern uint32_t __approm_size;
*
* @param pin led pin
* @param count number of times to blink
* @param time_period time_period in of one ON & OFF
* @param period_ms time_period in of one ON & OFF
*/
void led_blink(int pin, int count, int time_period)
void led_blink(int pin, int count, int period_ms)
{
int halfperiod = time_period >> 1;
int halfperiod = period_ms >> 1;
#ifdef SIM
halfperiod = 0;
#endif
Expand All @@ -73,46 +70,67 @@ void * platform_init(){
gpio_setmode(BOOTMODE_PIN1, INPUT);

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

// get bootmode
uint8_t pin0_val = (uint8_t)gpio_read(BOOTMODE_PIN0);
uint8_t pin1_val = (uint8_t)gpio_read(BOOTMODE_PIN1);
bootmode = pin0_val | pin1_val << 1;
#else
P(puts("nogpio: using default bootmode\n");)
P(puts("no gpio: using default bootmode\n");)
#endif

// Print Bootmode
P(puts("bootmode: ");)
P(puts("bootmode: 0x");)
P(putchar('0'+bootmode);)
P(puts(": ");)
P(putchar('\n');)

// Perform action according to bootmode
bool wait_for_keypress = false;
switch (bootmode)
{
case BOOTMODE_FLASHBOOT:
#ifdef SOC_EN_SPI
flashboot((uint8_t *)&__approm_start, FLASH_IMG_OFFSET, FLASH_IMG_SIZE);
flashboot((uint8_t *)&__approm_start, FLASH_IMG_OFFSET, (unsigned)&__approm_size);
#else
boot_panic(RCODE_FLASHBOOT_COPY_FAIL);
boot_panic(RCODE_FLASHBOOT_NOSPI, "No SPI IP");
#endif
break;

case BOOTMODE_JUMP_TO_RAM:
P(puts("jmptoram\n");)
P(puts("Jumping to RAM\n");)
break;

case BOOTMODE_UARTBOOT:
wait_for_keypress = true;
#ifdef SOC_EN_UART
uartboot((uint8_t *)&__approm_start, (unsigned)&__approm_size);
#else
boot_panic(RCODE_UARTBOOT_NOUART, "No UART IP"); // TODO: fixme
#endif
break;

case BOOTMODE_INF_LOOP:
default:
P(puts("infloop\n");)
P(puts("Infinite loop\n");)
while(1){
asm volatile("");
}
}

#ifdef SIM
wait_for_keypress = false;
#endif

if(wait_for_keypress){
puts("\nPress ENTER to continue...\n");
while(serial_read()!='\r')
asm volatile ("");
}

#ifdef SOC_EN_GPIO
// Blink single (signal jump to user code)
led_blink(BOOTLED_PIN, END_LED_FLASHES, 50);
led_blink(BOOTLED_PIN, END_LED_FLASHES, LED_FLASH_TIMEPERIOD);
#endif

// return start address of approm
Expand Down
85 changes: 85 additions & 0 deletions sw/bootloader/target/hydrogensoc/flashboot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include <platform.h>
#include <stdio.h>
#include <spi.h>
#include <utils.h>
#include <mmio.h>

#include "flashboot.h"
#include "common.h"

// Flash definitions
#define FLASH_CMD_READ 0x03
#define FLASH_CMD_READID 0X9f

#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

static char flashgetid(struct SPI_Config *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_READID);
char id = spi_transfer(cfg, 0x0);
// deselect
REG32(cfg->base_addr, SPI_REG_CSCTRL_OFFSET) = bitclear(REG32(cfg->base_addr, SPI_REG_CSCTRL_OFFSET), 24+cfg->device_num);
return id;
}

static int flashcpy(struct SPI_Config *cfg, uint8_t *dest, uint32_t src_addr, uint32_t len) {
// 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);
return 0;
}

void flashboot(uint8_t *dest, uint32_t src_addr, uint32_t len) {
// Init
struct SPI_Config cfg = {
cfg.base_addr = SPI_ADDR,
cfg.enable = true,
cfg.pha = false,
cfg.pol = false,
cfg.lsb_first = false,
cfg.baudrate = 1000000,
cfg.device_num = 0,
cfg.cs_mode = CSMODE_DISABLE,
cfg.post_cs_low_delay = 1,
cfg.pre_cs_high_delay = 1,
cfg.loopback_enable=false
};
spi_init(&cfg);

// Check ID
uint8_t manufacturer_id = flashgetid(&cfg);
P(puts("flashboot: manuf id = 0x");)
P(puthex(manufacturer_id);)
P(putchar('\n');)
if(manufacturer_id == 0x00 || manufacturer_id == 0xff){
boot_panic(RCODE_FLASHBOOT_INVALID_DEVICE, "Invalid FLASH Device");
}

// Copy
P(puts("\nflashboot: copying from " EXPAND_AND_STRINGIFY(FLASH_IMG_OFFSET));)
flashcpy(&cfg, dest, src_addr, len);
P(puts(" - OK\n");)

// Deinit
cfg.cs_mode = CSMODE_AUTO;
spi_init(&cfg);
}
Loading

0 comments on commit 15da939

Please sign in to comment.