diff --git a/bootrom/.gitignore b/bootrom/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/bootrom/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/bootrom/Makefile b/bootrom/Makefile new file mode 100644 index 0000000..8ac94ef --- /dev/null +++ b/bootrom/Makefile @@ -0,0 +1,23 @@ +CC ?= riscv64-unknown-elf-gcc +OBJCOPY ?= riscv64-unknown-elf-objcopy +ROM_BASE ?= 0x00100 + +LDFLAGS=-Tlinker.ld -nostdlib -nostartfiles -nodefaultlibs -static -Wl,--no-gc-sections -Wl,--defsym=ROM_BASE=$(ROM_BASE) + +b=rbootrom + +all: $b.elf $b.bin + +$b.o: $b.S + $(CC) $(CFLAGS) -c -o $@ $< + +$b.elf: $b.o linker.ld + $(CC) $(LDFLAGS) -o $@ $< + +$b.bin: $b.elf + $(OBJCOPY) -O binary $b.elf $b.bin + +clean: + rm -f $b.elf $b.bin $b.o + +.PHONY: clean all diff --git a/bootrom/linker.ld b/bootrom/linker.ld new file mode 100644 index 0000000..9a955e7 --- /dev/null +++ b/bootrom/linker.ld @@ -0,0 +1,19 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) + +SECTIONS +{ + ROM_BASE = DEFINED(ROM_BASE) ? ROM_BASE : 0x00100; /* Default to 0x00100 if ROM_BASE is not defined */ + + . = ROM_BASE; + .text.start : { *(.text.start) } + . = ROM_BASE + 0x80; + .text.hang : { *(.text.hang) } + /* + . = ROM_BASE + 0xC0; + .rodata.dtb : { *(.rodata.dtb) } + */ + + . = ALIGN(0x100); + .text : { *(.text) } +} diff --git a/bootrom/rbootrom.S b/bootrom/rbootrom.S new file mode 100644 index 0000000..c2c0d00 --- /dev/null +++ b/bootrom/rbootrom.S @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024, Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: MIT + * + * RBOOTROM v1.0 + * Modified by Rodrigo Arias Mallo + * + * This is a custom bootrom that prints some information to the UART when + * starting, as well as when it hangs. It assumes the UART is at UART_BASE and + * it will jump to DRAM_BASE to continue the boot. + */ + +#define DRAM_BASE 0x80000000 +#define UART_BASE 0x40001000 + +.macro PUTC, ch + li a0, \ch + jal putchar +.endm + +.section .text.start, "ax", @progbits +.globl _start +_start: + jal print_hello // Print initial message on HART 0 only + csrr a0, mhartid // Load HART ID into a0 + li s0, DRAM_BASE // Load next address into s0 + jr s0 // Jump to s0 + +.section .text.hang, "ax", @progbits +.globl _hang +_hang: + + PUTC '\n' + PUTC '\r' + PUTC 'R' + PUTC 'B' + PUTC 'O' + PUTC 'O' + PUTC 'T' + PUTC 'R' + PUTC 'O' + PUTC 'M' + PUTC ' ' + PUTC 'H' + PUTC 'A' + PUTC 'N' + PUTC 'G' + PUTC '\n' + PUTC '\r' + + /* Hang */ + csrr a0, mhartid +1: + wfi + j 1b + +.section .text, "ax", @progbits + +putchar: + // Wait a bit before writing to UART + li t0, 100000 // Delay a bit +1: + addi t0, t0, -1 // Decrement + bne t0, zero, 1b // Repeat if not zero + + // Write the character now + la t0, UART_BASE // Transmitter Holding Buffer + sb a0, 0(t0) // Write a0 byte + ret + +print_hello: + csrr t0, mhartid // Load HART ID into a0 + beq t0, zero, 1f // Print message on HART 0 only + ret +1: + // Identify bootroom + PUTC '\n' + PUTC '\r' + PUTC 'R' + PUTC 'B' + PUTC 'O' + PUTC 'O' + PUTC 'T' + PUTC 'R' + PUTC 'O' + PUTC 'M' + PUTC ' ' + PUTC 'v' + PUTC '1' + PUTC '.' + PUTC '0' + PUTC '\n' + PUTC '\r' + ret diff --git a/overlay.nix b/overlay.nix index 64ad58f..8bf3fca 100644 --- a/overlay.nix +++ b/overlay.nix @@ -107,4 +107,18 @@ final: prev: hardeningDisable = [ "all" ]; }; + rbootrom = prev.pkgsStatic.stdenv.mkDerivation { + name = "sa-fpga-tests"; + src = ./bootrom; + dontConfigure = true; + buildPhase = '' + make + ''; + installPhase = '' + mkdir $out + cp rbootrom.bin rbootrom.elf $out/ + ''; + dontFixup = true; + hardeningDisable = [ "all" ]; + }; }