commit eeed52bda2fcae84582cf9e0f9f9df77bf34e7c0
parent 1a25d3f2c0add6533834e5581d531feefe892069
Author: Christian Ermann <christianermann@gmail.com>
Date: Mon, 16 Sep 2024 15:51:26 -0600
Hello, World!
Diffstat:
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.*) }
+}
+