sw: Add bootrom
This commit is contained in:
parent
434a06fa70
commit
4057f5239e
4
sw/bootrom/.gitignore
vendored
Normal file
4
sw/bootrom/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*.bin
|
||||
*.elf
|
||||
*.hex
|
||||
*.vhex
|
45
sw/bootrom/boot.ld
Normal file
45
sw/bootrom/boot.ld
Normal file
@ -0,0 +1,45 @@
|
||||
__heap_size = 0x80;
|
||||
__stack_size = 0x80;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ROM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x100
|
||||
RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 0x400
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.boot)
|
||||
*(.text)
|
||||
*(.text)
|
||||
*(.rodata*)
|
||||
} > ROM
|
||||
.data :
|
||||
{
|
||||
*(.sbss)
|
||||
*(.data)
|
||||
*(.bss)
|
||||
*(.rela*)
|
||||
*(COMMON)
|
||||
} > RAM
|
||||
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE ( end = . );
|
||||
_sheap = .;
|
||||
. = . + __heap_size;
|
||||
. = ALIGN(4);
|
||||
_eheap = .;
|
||||
} >RAM
|
||||
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_estack = .;
|
||||
. = . + __stack_size;
|
||||
. = ALIGN(4);
|
||||
_sstack = .;
|
||||
} >RAM
|
||||
}
|
8
sw/bootrom/build.sh
Executable file
8
sw/bootrom/build.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
riscv64-elf-gcc -mabi=ilp32 -march=rv32i -nostdlib -nostartfiles -ffreestanding -T boot.ld -Os -o bootrom.elf main.c
|
||||
#riscv64-elf-objdump -D bootrom.elf
|
||||
riscv64-elf-objcopy -O binary bootrom.elf bootrom.bin
|
||||
od --endian=little -vtx4 -An -w4 bootrom.bin | tr -d ' ' > bootrom.vhex
|
||||
r2 -A -c 'pdf @ sym._start' -q bootrom.elf
|
87
sw/bootrom/main.c
Normal file
87
sw/bootrom/main.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#define UART0_BASE 0x81000000
|
||||
#define UART0_SR (*((volatile uint32_t *) (UART0_BASE + 0x00)))
|
||||
#define UART0_DR (*((volatile uint32_t *) (UART0_BASE + 0x04)))
|
||||
|
||||
#define UART0_SR_RX_DATA_EMPTY (1 << 0)
|
||||
#define UART0_SR_TX_FULL (1 << 1)
|
||||
|
||||
/*
|
||||
// Set up stack pointer
|
||||
asm("_start:\
|
||||
xor sp, sp, sp;\
|
||||
lui sp, 0x80100;\
|
||||
j main;\
|
||||
");
|
||||
*/
|
||||
|
||||
__attribute__((noreturn)) void _start() {
|
||||
uint8_t state = 0;
|
||||
uint8_t c;
|
||||
uint8_t opcode;
|
||||
uint8_t *ptr;
|
||||
uint32_t length;
|
||||
|
||||
/*while (1) {
|
||||
while (UART0_SR & UART0_SR_RX_DATA_EMPTY);
|
||||
c = UART0_DR;
|
||||
while (UART0_SR & UART0_SR_TX_FULL);
|
||||
UART0_DR = c;
|
||||
}*/
|
||||
|
||||
while (1) {
|
||||
while (UART0_SR & UART0_SR_RX_DATA_EMPTY);
|
||||
c = UART0_DR;
|
||||
state++;
|
||||
switch (state) {
|
||||
case 1: // Opcode
|
||||
opcode = c;
|
||||
ptr = 0;
|
||||
length = 0;
|
||||
if (c == 0) // NOP
|
||||
state = 0;
|
||||
break;
|
||||
case 2: // Address
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
ptr = (uint8_t*)(((uint32_t)ptr << 8) | c);
|
||||
if (state != 5)
|
||||
break;
|
||||
if (opcode == 3) { // Jump
|
||||
//((void (*)()) ptr)();
|
||||
asm("jalr %0" : : "r"(ptr)); // Not sure why, but the jump above causes GCC to save variables to the stack at the beginning of this function
|
||||
__builtin_unreachable();
|
||||
}
|
||||
break;
|
||||
case 6: // Length
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
length = (length << 8) | c;
|
||||
if (state != 9)
|
||||
break;
|
||||
if (opcode == 2) { // Read
|
||||
for (; length > 0; length--) {
|
||||
while (UART0_SR & UART0_SR_TX_FULL);
|
||||
UART0_DR = *(ptr);
|
||||
ptr++;
|
||||
}
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 10: // Write byte by byte
|
||||
*(ptr++) = c;
|
||||
if (--length == 0) {
|
||||
state = 0;
|
||||
} else {
|
||||
state--; // Stay in this state
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
Loading…
Reference in New Issue
Block a user