# rvemu: RISC-V Online Emulataor
[![Build Status](https://travis-ci.com/d0iasm/rvemu.svg?branch=master)](https://travis-ci.com/d0iasm/rvemu)
[![Actions Status](https://github.com/d0iasm/rvemu/workflows/CI/badge.svg)](https://github.com/d0iasm/rvemu/actions)
[![docs.rs](https://docs.rs/rvemu/badge.svg)](https://docs.rs/rvemu)
[![crate.io](https://img.shields.io/crates/v/rvemu.svg)](https://crates.io/crates/rvemu)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/d0iasm/rvemu/master/LICENSE)
RISC-V online emulator with WebAssembly generated by Rust. The emulator implements the standard extensions RV64G (RV64IMAFD) and cimplies with [the RISC-V specifications](https://riscv.org/specifications/).
The online emulator is available here: [**rvemu.app**](https://rvemu.app/)
Supports the following RISC-V ISAs (RV64G):
- RV64I (v2.1): supports 52/52 instructions (FENCE, ECALL, and EBREAK don't do anything for now)
- RV64M (v2.0): supports 13/13 instructions
- RV64A (v2.0): supports 22/22 instructions (No atomicity for now)
- RV64F (v2.2): supports 30/30 instructions
- RV64D (v2.2): supports 32/32 instructions
- Zifencei (v2.0): supports 1/1 instructions (FENCE.i doesn't do anything for now)
- Zicsr (v2.0): supports 6/6 instructions (no unittests and no atomicity)
__NOTE: This project is currently under intensely development. The source code might be changed dramatically.__
What to do next is:
1. devices interrupt (refers to
[memlayout.h](https://github.com/mit-pdos/xv6-riscv/blob/37df68e5dedbf2a26c2bf0bdae090b206ce78b48/kernel/memlayout.h) in xv6)
1. keyboards
2. timer
3. virtio
4. block devices
2. virtual memory
# Usage
The emulator supports the following commands:
- __upload__: Upload a local RISC-V binary/local RISC-V binaries for an execution on the emulator.
- __ls__: List the files you uploaded.
- __run [file]__: Execute a file.
- __help__: Print all commands you can use.
![Demo](https://raw.githubusercontent.com/d0iasm/rvemu/master/demo.gif)
## Build and run on the local browser
The `wasm-pack build` command generates a pkg directory and makes Rust source code into `.wasm` binary. It also generates the JavaScript API for using our Rust-generated WebAssembly. The toolchain's supported target is `wasm32-unknown-unknown`.
You need to execute this command whenever you change your Rust code.
```
$ make rvemu-wasm
// This is the alias of `wasm-pack build lib/rvemu-wasm --out-dir <path-to-rvemu>/public/pkg --target web`.
```
This command installs dependencies in the `node_modules` directory. Need `npm install --save` in the `public` directory at the first time and whenever you change dependencies in package.json.
```
$ npm install --save // at the public directory
```
You can see the website via http://localhost:8000. `npm start` is the alias of `python3 -m http.server` so you need Python3 in your environment.
```
$ npm start // at the public directory
```
## Build and run as a CLI tool
The emulator can be executed as a CLI tool too. You can build it by `make rvemu-cli` command which is the alias of `cargo build --release --manifest-path lib/rvemu-cli/Cargo.toml`.
To execute the RISC-V ELF binary, XV6 in the folloing example, you can use `--kernel` or `-k` options to specify the kernel image. Note that `xv6-kernel.text` is an ELF file without headers by the command `riscv64-unknown-elf-objcopy -O binary xv6-kernel.text kernel`
```
$ ./target/release/rvemu-cli --kernel examples/xv6-kernel.text
```
You can see the details of how to use by the `help` option.
```
$ ./target/release/rvemu-cli --help
rvemu: RISC-V emulator 0.0.1
Asami Doi <@d0iasm>
USAGE:
rvemu-cli [FLAGS] --kernel <kernel>
FLAGS:
-d, --debug Enables to output debug messages
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-k, --kernel <kernel> A kernel ELF image without headers
```
## Build RISC-V binary
This emulator starts to execute at the address 0x8000_0000, the start address of DRAM, so you need to extract .text section to execute your binary file on the emulator.
```
// Make an assembly file from a C file.
$ riscv64-unknown-elf-gcc -S -nostdlib hoge.c
// Make a binary file from an assembly file with start position 0.
$ riscv64-unknown-elf-gcc -Wl,-Ttext=0x80000000 -nostdlib -o hoge hoge.s
// Extract a text section from a binary file.
$ riscv64-unknown-elf-objcopy -O binary --only-section=.text hoge hoge.text
```
## Testing
### ISA testing
You can see the binaries for unit testings in [riscv/riscv-tests](https://github.com/riscv/riscv-tests).
The following command executes all `rv64ua/d/f/i/m-p-*` binaries.
```
$ make test-isa
```
### Testing with WebAssembly
NOTE: This is deprecated bacause I'll delete them in the future. This tests are
implemented in the `lib/rvemu-wasm/tests` directory.
You need to install a Firefox browser, a Chrome browser, or a Safari browser to run the integration testings. A browser can be specified by a `--firefox` or a `--chrome` flag.
```
$ make test-wasm
```
## Analyzing with perf
```
$ perf record -F99 --call-graph dwarf ./target/release/rvemu-cli -k ./kernel.text
$ perf report
```
## Publish
[The site](https://rvemu.app/) is hosted by a firebase.
```
$ firebase deploy
```
# Roadmap
### Supports "The RISC-V Instruction Set ManualVolume I: Unprivileged ISADocument Version 20191213"
- [x] RV64G ISA
- [ ] RV64C ISA
### Supports "The RISC-V Instruction Set ManualVolume II: Privileged ArchitectureDocument Version 20190608-Priv-MSU-Ratified"
- [ ] Privileged ISA (URET, SRET, MRET, WFI, SFENCE.VMA, HFENCE.BVMA, and HFENCE.GVMA)
- [ ] Machine-level CSRs
- [ ] Machine-Mode privileged instructions
- [ ] Supervisor-level CSRs
- [ ] Supervisor instructions
- [ ] Page-Based Virtual-Memory System
- [ ] User-level CSRs
## Dependencies
- rust toolchain (rustup/rustc/cargo/cargo-generate)
- wasm-pack
- npm
- [xterm](https://xtermjs.org/)
- xterm-addon-fit
- firebase CLI
## Resources
### Documents
- [RISC-V Specifications](https://riscv.org/specifications/)
- [Rust and WebAssembly](https://rustwasm.github.io/docs/book/introduction.html)
- [riscv/riscv-sbi-doc](https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc)
- [riscv/riscv-elf-psabi-doc](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md)
- [riscv/riscv-asm-manual](https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md)
### Implementation of other emulators
- [qemu/qemu](https://github.com/qemu/qemu)
- [riscv/riscv-isa-sim](https://github.com/riscv/riscv-isa-sim)
- [riscv/riscv-angel](https://github.com/riscv/riscv-angel)
- [riscv/riscv-ovpsim](https://github.com/riscv/riscv-ovpsim)
- [rv8-io/rv8](https://github.com/rv8-io/rv8)
- [TinyEmu](https://bellard.org/tinyemu/)
- [stephank/rvsim](https://github.com/stephank/rvsim)
### Helpful tools
- [riscv/riscv-tests](https://github.com/riscv/riscv-tests)
- [wat2wasm demo](https://webassembly.github.io/wabt/demo/wat2wasm/)
- [RISC-V Online Simulator](https://www.kvakil.me/venus/)
## Articles about this project
- [Emulate 32-Bit And 64-Bit RISC-V In Your Browser With Asami’s Open Source rvemu | Gareth Halfacree, Hackster.io](https://riscv.org/2020/01/emulate-32-bit-and-64-bit-risc-v-in-your-browser-with-asamis-open-source-rvemu-gareth-halfacree-hackster-io/)
- [Emulate 32-Bit and 64-Bit RISC-V in Your Browser with Asami's Open Source rvemu](https://www.hackster.io/news/emulate-32-bit-and-64-bit-risc-v-in-your-browser-with-asami-s-open-source-rvemu-b783f672e463)