Home

Awesome

riscv_emufun (mini-rv32ima)

Click below for the YouTube video introducing this project:

Writing a Really Tiny RISC-V Emulator But Will It Run Doom?

What

mini-rv32ima is a single-file-header, mini-rv32ima.h, in the STB Style library that:

It has a demo wrapper that:

†: Zifence+RV32A are stubbed. So, tweaks will need to be made if you want to emulate a multiprocessor system with this emulator.

Just see the mini-rv32ima folder.

It's "fully functional" now in that I can run Linux, apps, etc. Compile flat binaries and drop them in an image.

Why

I'm working on a really really simple C Risc-V emulator. So simple it doesn't even have an MMU (Memory Management Unit). I have a few goals, they include:

How

Windows instructions (Just playing with the image)

WSL (For full toolchain and image build:

Linux instructions (both):

You can do in-depth work on Linux by:

If you want to play with the bare metal system, see below, or if you have the toolchain installed, just:

If you just want to play emdoom, and use the prebuilt image:

Questions?

Everything else: Contact us on my Discord: https://discord.com/invite/CCeyWyZ

How do I use this in my own project?

You shoud not need to modify mini-rv32ima.h, but instead, use mini-rv32ima.c as a template for what you are trying to do in your own project.

You can override all functionality by defining the following macros. Here are examples of what mini-rv32ima.c does with them. You can see the definition of the functions, or augment their definitions, by altering mini-rv32ima.c.

MacroDefinition / Comment
MINIRV32WARN( x... )printf( x ); <br> Warnings emitted from mini-rv32ima.h
MINIRV32_DECORATEstatic <br> How to decorate the functions.
MINI_RV32_RAM_SIZEram_amt <br> A variable, how big is system RAM?
MINIRV32_IMPLEMENTATIONIf using mini-rv32ima.h, need to define this.
MINIRV32_POSTEXEC( pc, ir, retval ){ if( retval > 0 ) { if( fail_on_all_faults ) { printf( "FAULT\n" ); return 3; } else retval = HandleException( ir, retval ); } } <br> If you want to execute something every time slice.
MINIRV32_HANDLE_MEM_STORE_CONTROL( addy, val )if( HandleControlStore( addy, val ) ) return val; <br> Called on non-RAM memory access.
MINIRV32_HANDLE_MEM_LOAD_CONTROL( addy, rval )rval = HandleControlLoad( addy ); <br> Called on non-RAM memory access return a value.
MINIRV32_OTHERCSR_WRITE( csrno, value )HandleOtherCSRWrite( image, csrno, value ); <br> You can use CSRs for control requests.
MINIRV32_OTHERCSR_READ( csrno, value )value = HandleOtherCSRRead( image, csrno ); <br> You can use CSRs for control requests.

Hopeful goals?

Special Thanks

More details

If you want to build the kernel yourself:

Emdoom notes

If you want to use bare metal to build your binaries so you don't need buildroot, you can use the rv64 gcc in 32-bit mode built into Ubuntu 20.04 and up.

sudo apt-get install gcc-multilib gcc-riscv64-unknown-elf make

Links

Attic

General notes:

(These things don't currently work)

Building Tests

(This does not work, now)

cd riscv-tests
export CROSS_COMPILE=riscv64-linux-gnu-
export PLATFORM_RISCV_XLEN=32
CC=riscv64-linux-gnu-gcc ./configure
make XLEN=32 RISCV_PREFIX=riscv64-unknown-elf- RISCV_GCC_OPTS="-g -O1 -march=rv32imaf -mabi=ilp32f -I/usr/include"

Building OpenSBI

(This does not currently work!)

cd opensbi
export CROSS_COMPILE=riscv64-unknown-elf-
export PLATFORM_RISCV_XLEN=32
make

Extra links

Using custom build

Where yminpatch is the patch from the mailing list.

rm -rf buildroot
git clone git://git.buildroot.net/buildroot
cd buildroot
git am < ../yminpatch.txt
make qemu_riscv32_nommu_virt_defconfig
make
# Or use our configs.

Note: For emdoom you will need to modify include/linux/mmzone.h and change MAX_ORDER to 13.

Buildroot Notes

Add this: https://github.com/cnlohr/buildroot/pull/1/commits/bc890f74354e7e2f2b1cf7715f6ef334ff6ed1b2

Use this: https://github.com/cnlohr/buildroot/commit/e97714621bfae535d947817e98956b112eb80a75