-
-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Chuck Benedict
committed
Jul 29, 2024
1 parent
a4c5b85
commit fa7aba4
Showing
6 changed files
with
100 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
SRCS_C3 := $(wildcard *.c3) | ||
|
||
default: hello.elf | ||
|
||
hello.a: $(SRCS_C3) | ||
c3c --use-stdlib=no --no-entry --target elf-riscv32 static-lib $(SRCS_C3) | ||
|
||
start.o: start.s | ||
riscv64-unknown-elf-as -g -march=rv32i -mabi=ilp32 -o start.o start.s | ||
|
||
hello.elf: hello.a start.o baremetal.ld | ||
riscv64-unknown-elf-ld -T baremetal.ld -m elf32lriscv -o hello.elf hello.a start.o | ||
|
||
run: hello.elf | ||
@echo "Ctrl-A C for QEMU console, then quit to exit" | ||
qemu-system-riscv32 -nographic -serial mon:stdio -machine virt -bios hello.elf | ||
|
||
debug: hello.elf | ||
@echo "Ctrl-A C for QEMU console, then quit to exit" | ||
qemu-system-riscv32 -nographic -serial mon:stdio -machine virt -s -S -bios hello.elf | ||
|
||
clean: | ||
rm -f *.o *.a hello.elf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Risc-V 32 Embedded Example With QEMU | ||
## Prereqs | ||
- QEMU | ||
- Risc-V toolchain | ||
- C3C | ||
- Make | ||
## Running | ||
`make run` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
EXTERN(main) | ||
|
||
SECTIONS | ||
{ | ||
. = 0x80000000; /* QEMU default load address to run bios */ | ||
.text : { | ||
KEEP(*(.text._start)); /* Ensure _start is placed first */ | ||
*(.text*); /* Program code here */ | ||
} | ||
. = ALIGN (CONSTANT (COMMONPAGESIZE)); /* Make sure linker does not jam data into text section, making text writable */ | ||
.data : { | ||
*(.data*) /* Stack goes here */ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import uart; | ||
|
||
const UART0_BASE = 0x10000000; | ||
|
||
fn void main() @export("main") { | ||
Uart* uart0 = (Uart*)UART0_BASE; // Create pointer to UART 0 | ||
uart0.fcr = uart::UARTFCR_FFENA; // Enable FIFO | ||
uart0.puts("Hello World!\n"); // Write the string to the UART | ||
while (1); // Loop forever to prevent program from ending | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Simple C runtime startup bootstrap | ||
# Two primary functions: | ||
# - Stack allocation and initializing stack pointer | ||
# - Jumping to main | ||
|
||
.section .text._start | ||
.global _start | ||
_start: | ||
la sp, __stack_top # Load the stack pointer | ||
add s0, sp, zero # Set the frame pointer | ||
jal zero, main # Run main entry point - no argc | ||
loop: j loop # Spin forever in case main returns | ||
|
||
.section .data | ||
.space 1024*8 # allocate 8K of memory to serve as initial stack | ||
.align 16 # Smallest stack allocation is 16 bytes, so align accordingly | ||
__stack_top: # The stack grows downward according the Risc-V ABI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
module uart; | ||
|
||
const UARTFCR_FFENA = 0x01; // UART FIFO Control Register enable bit | ||
const UARTLSR_THRE = 0x20; // UART Line Status Register Transmit Hold Register Empty bit | ||
|
||
struct Uart { | ||
char dr; // UART Data Register | ||
char filler1; | ||
char fcr; // FIFO Control Register | ||
char filler2; | ||
char filler3; | ||
char lsr; // Line Status Register | ||
} | ||
|
||
fn bool Uart.uart_ff_thr_empty(Uart* this) { | ||
return (bool)($$volatile_load(&this.lsr) & UARTLSR_THRE); | ||
} | ||
|
||
fn void Uart.putc(Uart* this, char c) { | ||
while (!this.uart_ff_thr_empty()); // Wait until the FIFO holding register is empty | ||
$$volatile_store(&this.dr, c); // Write character to transmit register | ||
} | ||
|
||
fn void Uart.puts(Uart* this, char *str) { | ||
while (*str) { // Loop until value at string pointer is zero | ||
this.putc(*str++); // Write the character and increment pointer | ||
} | ||
} |