Giter Site home page Giter Site logo

takahirox / riscv-rust Goto Github PK

View Code? Open in Web Editor NEW
585.0 24.0 46.0 36.47 MB

RISC-V processor emulator written in Rust+WASM

Home Page: https://takahirox.github.io/riscv-rust/wasm/web/index.html

License: MIT License

Rust 74.99% Shell 0.21% HTML 2.58% JavaScript 20.80% CSS 1.41%
rust riscv risc-v emulator cpu processor webassembly wasm

riscv-rust's Introduction

riscv-rust

Build Status Crate npm version

riscv-rust is a RISC-V processor and peripheral devices emulator project written in Rust and compiled to WebAssembly. You can import RISC-V emulator into your Rust or JavaScript project. Refer to the Slides for more detail.

Online Demo

You can run Linux or xv6 on the emulator in your browser. Online demo is here

Screenshots

animation debugger

Documents

Features

  • Emulate RISC-V processor and peripheral devices
  • Stable as Linux and xv6-riscv run on it
  • Linux OpenSBI and legacy BBL boot support
  • Runnable locally
  • Also runnable in browser with WebAssembly
  • Debugger
  • You can import RISC-V emulator into your Rust or JavaScript project

Instructions/Features support status

  • RV32/64I
  • RV32/64M
  • RV32/64F (almost)
  • RV32/64D (almost)
  • RV32/64Q
  • RV32/64A (almost)
  • RV64C/32C (almost)
  • RV32/64Zifencei (almost)
  • RV32/64Zicsr (almost)
  • CSR (almost)
  • SV32/39
  • SV48
  • Privileged instructions (almost)
  • PMP

etc...

The emulator supports almost all instructions listed above but some instructions which are not used in Linux or xv6 are not implemented yet. Your contribution is very welcome.

How to import into your Rust project

The emulator module is released at crates.io. Add the following line into Cargo.toml of your Rust project.

[dependencies]
riscv_emu_rust = "0.2.0"

Refer to Document for the API.

How to build core library locally

$ git clone https://github.com/takahirox/riscv-rust.git
$ cd riscv-rust
$ cargo build --release

How to run Linux or xv6 as desktop application

$ cd riscv-rust/cli
# Run Linux
$ cargo run --release ../resources/linux/opensbi/fw_payload.elf -f ../resources/linux/rootfs.img
# Run xv6
$ cargo run --release ../resources/xv6/kernel -f ../resources/xv6/fs.img

How to run riscv-tests

Prerequirements

$ cd riscv-rust/cli
$ cargo run $path_to_riscv_tets/isa/rv32ui-p-add -n

How to import and use WebAssembly RISC-V emulator in a web browser

See wasm/web

How to install and use WebAssembly RISC-V emulator npm package

See wasm/npm

Links

Linux RISC-V port

Running 64- and 32-bit RISC-V Linux on QEMU

xv6-riscv

xv6-riscv is the RISC-V port of xv6 which is UNIX V6 rewritten by MIT for x86 in the current C language.

Specifications

riscv-rust's People

Contributors

atul9 avatar fuulish avatar kurun-pan avatar takahirox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

riscv-rust's Issues

Simpler decoding

We may simplify decoding with the sets of mask and data. For example decoding ADDI instruction can be written as

if (word & 0x0000707f) == 0x00000013 {
  return Instruction::ADDI;
}

then we may rewrite decode function with loop

// pseudo-code
for d in decoding_sets {
  if (word & d.mask) == d.data {
    return d.instruction;
  }
}

Run peripheral devices in another thread

It'd be good to run peripheral devices in another thread for the performance. For example currently terminal emulator handling input (and output) runs in the same thread so that main thread needs to periodically check input event but it seems to have an impact to the performance. If it runs in another thread it can improve the performance.

This is also important for Web. For not only catching input but also rendering the output the main thread periodically needs to sleep with setTimeout(). It can have a big performance impact. Maybe we can load off riscv emulator to workers thread and share UART registers between main and worker threads.

Enable accessing memory wider than a byte at a time

Currently the emulator accesses memory one byte at a time. For examples it access memory four times to get 32-bit instruction.

It would be a good optimization to enable accessing memory wider than a byte at a time (in case where it is ensured that all the accessed bytes are in the same page and they all are not mapped to other devices).

Investigate the performance of Rust exception handling

I'm not really sure about if it is changed but it is used be said that try-catch is slow in most (or all) languages even if it goes on non-exception flow.

We need to investigate Rust exception handling performance using

fn foo() -> Result<u64, Error> {
    ...
}

match foo() {
    Ok(result) => result,
    Err(e) => return Err(e)
};

because it's used a lot in the emulator. For example it is used to notify and catch page fault.

If it's slow we may need to think of other options.

Run modern Operating System

I'd like to try to run more modern Operating System on the emulator, for example Linux, OpenBSD, or FreeBSD.

Handle csr *ip properly

Currently the emulator takes an interrupt by seeing the device interrupt signal. But the interrupt signal should rise csr *ip register bit and the emulator should take an interrupt if csr *ip register bit is risen.

And csr *ip register can be writable. If it's writable software should be able to cause an interrupt by writing.

stressfs of xv6 doesn't end

stressfs of xv6 doesn't end. I guess that's because virtio block disk emulation is something wrong.

$ usertests
stressfs starting
write 0
write 1
write 2
write 3
write 4

Emulate peripheral devices more properly

The currently peripheral device emulation is a bit too specific to xv6-riscv device drivers, for example ignoring some peripheral device accesses which may not have an effect to xv6-riscv.

We should emulate more properly because it can be broken if they update xv6-riscv device drivers, or other programs may fail.

Consider to rename repository

I realized the name riscv-rust is already used as a project name by official risc-v. So my repository name riscv-rust may be confusing and it would be better to rename.

Enable to run test again without second argument

Currently cli application takes two arguments kernel image file and filesystem image file. But the second argument filesystem image file is xv6 specific and shouldn't be necessary for running tests. We should enable run (test) without second argument.

Skip redundant address tranlation

The emulator accesses memory one byte at a time. For example it accesses memory four times to get a 32-bit instruction.

It can have a big performance impact especially if virtual-physical memory address translation is on because the translation can be one of the slowest operation in the emulator.

So it would be a good optimization to skip redundant address translation. For example we can have translation table cache.

Write note about how to build xv6-riscv for riscv-rust

I should write a note about the files in xv6 directory.

  • xv6-riscv kernel file in xv6 directory (xv6/kernel) is built without C extension because the emulator doesn't support C extension yet. I added -march=rv64imafd compile/assemble option in Makefile of xv6-riscv. And also I edited initcode in kernel/proc.c to convert to non-C extension instructions. Plus, I added -O3 compile option to get better performance.
  • xv6-riscv filesystem image file (xv6/fs.img) is made by make qemu of xv6-riscv

Send feedback to riscv-tests

While working on Linux support I found some bugs in the CPU instruction implementations although I already passed riscv-tests. I think better to send feedback to riscv-tests for better coverage.

Cache decode

Caching decode result would be a good optimization. Especially it would work well in loop.

// pseudo code
let instruction = match decode_cache.has(word) {
  true => {
    decode_cache.get(word)
  },
  false => {
    let instruction = self.decode_internal(word);
    decode_cache.set(word, instruction);
    decode_cache.remove_lru();
    instruction
  }
};

pipe fails in xv6

How to reproduce in xv6.

$ cat README | wc

Error message.

Unknown Instruction type.
Pc:00000000000004f0, Opcode:0000000, Word:0000000000000000
thread 'main' panicked at 'explicit panic', src\cpu.rs:1022:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\release\standalone.exe xv6/kernel -f xv6/fs.img` (exit code: 101)

Rename project name

I may want to rename the project name from rust-riscv to riscv-rust at some point. (I don't remember why I named rust-riscv...)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.