forth-riscv

My forth
git clone git://git.electrosoup.com/forth-riscv
Log | Files | Refs

commit eeed52bda2fcae84582cf9e0f9f9df77bf34e7c0
parent 1a25d3f2c0add6533834e5581d531feefe892069
Author: Christian Ermann <christianermann@gmail.com>
Date:   Mon, 16 Sep 2024 15:51:26 -0600

Hello, World!

Diffstat:
ADockerfile | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AMakefile | 4++++
Aforth.s | 35+++++++++++++++++++++++++++++++++++
Ans16550a.s | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Ariscv32-virt.ld | 9+++++++++
5 files changed, 165 insertions(+), 0 deletions(-)

diff --git a/Dockerfile b/Dockerfile @@ -0,0 +1,68 @@ +FROM debian:stable-slim as build-tools + +RUN apt-get update && apt-get -y upgrade && \ + apt-get --no-install-recommends -y install \ + autoconf \ + automake \ + autotools-dev \ + curl \ + python3 \ + python3-pip \ + libmpc-dev \ + libmpfr-dev \ + libgmp-dev \ + gawk \ + build-essential \ + bison \ + flex \ + texinfo \ + gperf \ + libtool \ + patchutils \ + bc \ + zlib1g-dev \ + libexpat-dev \ + ninja-build \ + git \ + cmake \ + libglib2.0-dev \ + libslirp-dev + +RUN git clone https://github.com/riscv/riscv-gnu-toolchain + +WORKDIR "/riscv-gnu-toolchain" +RUN ./configure --prefix=/opt/riscv +RUN make + +FROM debian:stable-slim as build + +COPY --from=build-tools /opt/riscv /opt/riscv +ENV PATH="$PATH:/opt/riscv/bin" +COPY ns16550a.s . +COPY forth.s . +COPY riscv32-virt.ld . +RUN riscv64-unknown-elf-as -march=rv32i -o ns16550a.o ns16550a.s +RUN riscv64-unknown-elf-as -march=rv32i -o forth.o forth.s +RUN riscv64-unknown-elf-ld -T riscv32-virt.ld -o forth.elf forth.o ns16550a.o +RUN riscv64-unknown-elf-objcopy -O binary forth.elf forth.bin + +FROM debian:stable-slim as run-base + +RUN apt-get update && apt-get -y upgrade && \ + apt-get --no-install-recommends -y install \ + device-tree-compiler \ + qemu-system-misc + +FROM run-base as run +COPY --from=build forth.bin forth.bin +#RUN qemu-system-riscv32 -machine virt -machine dumpdtb=riscv32-virt.dtb -bios none +#RUN dtc -I dtb -O dts -o riscv32-virt.dts riscv32-virt.dtb + +CMD ["qemu-system-riscv32", "-nographic", "-bios", "none", "-machine", "virt", "-kernel", "forth.bin"] + + +#CMD ["/bin/sh"] + +#FROM build +#COPY --from=build-tools /opt/riscv/... / + diff --git a/Makefile b/Makefile @@ -0,0 +1,4 @@ +all: + docker build . --tag forth-riscv32 + docker image prune -f + docker run --interactive --rm forth-riscv32 diff --git a/forth.s b/forth.s @@ -0,0 +1,35 @@ +.extern uart_put_char +.extern uart_get_char + +.section ".text" + +start: + li a0, 'H + jal uart_put_char + li a0, 'e + jal uart_put_char + li a0, 'l + jal uart_put_char + li a0, 'l + jal uart_put_char + li a0, 'o + jal uart_put_char + li a0, ', + jal uart_put_char + li a0, ' + jal uart_put_char + li a0, 'W + jal uart_put_char + li a0, 'o + jal uart_put_char + li a0, 'r + jal uart_put_char + li a0, 'l + jal uart_put_char + li a0, 'd + jal uart_put_char + li a0, '! + jal uart_put_char + li a0, '\n + jal uart_put_char + diff --git a/ns16550a.s b/ns16550a.s @@ -0,0 +1,49 @@ +.global uart_init +.global uart_put_char +.global uart_get_char + +.equ UART_ADDR, 0x10000000 + +.equ INTERRUPT_ENABLE_REGISTER, 0x1 +.equ FIFO_CONTROL_REGISTER, 0x2 +.equ LINE_CONTROL_REGISTER, 0x3 +.equ LINE_STATUS_REGISTER, 0x5 + +.equ LINE_STATUS_DATA_READY, 0x1 +.equ LINE_STATUS_TRANSMIT_EMPTY, 0x20 + +.section ".text" + +uart_init: + li t0, UART_ADDR + # Disable interrupts (for now) + li t1, 0x0 + sb t1, INTERRUPT_ENABLE_REGISTER(t0) + # 8 data bits, 1 stop bit, no parity + li t1, 0x3 + sb t1, LINE_CONTROL_REGISTER(t0) + # Enable FIFOs, clear rx and tx + li t1, 0x7 + sb t1, FIFO_CONTROL_REGISTER(t0) + ret + +uart_get_char: + li t0, UART_ADDR +_wait_for_rx: + lbu t1, LINE_STATUS_REGISTER(t0) + andi t1, t1, LINE_STATUS_DATA_READY + beqz t1, _wait_for_rx +_get_char: + lbu a0, (t0) + ret + +uart_put_char: + li t0, UART_ADDR +_wait_for_tx: + lbu t1, LINE_STATUS_REGISTER(t0) + andi t1, t1, LINE_STATUS_TRANSMIT_EMPTY + beqz t1, _wait_for_tx +_put_char: + sb a0, (t0) + ret + diff --git a/riscv32-virt.ld b/riscv32-virt.ld @@ -0,0 +1,9 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) +ENTRY(start) + +SECTIONS { + .text 0x80000000 : { *(.text); *(.text.*) } +} +