update README for public release

This commit is contained in:
Stefan 2021-08-17 10:18:01 +02:00
parent 2eea541a27
commit bfe37dee75
2 changed files with 299 additions and 3 deletions

View File

@ -1,16 +1,85 @@
# rvc - risc v in c
# rvc - risc v in c / HLSL
An experimental 32-bit [0] RISC-V emulator written in plain C [1], with a focus on porting the result to a HLSL pixel shader.
Mostly based on [takahirox/riscv-rust](https://github.com/takahirox/riscv-rust), which is a great resource for learning about RISC-V in general, aside from the [official specs](https://riscv.org/technical/specifications/) of course.
The resulting HLSL (Unity CG) can be found in `_Nix/`, read on to learn more.
A version of this shader running in VRChat can be found in this world:
https://vrchat.com/home/world/wrld_8126d9ef-eba5-4d49-9867-9e3c4f0b290d
The C version was initially based on [takahirox/riscv-rust](https://github.com/takahirox/riscv-rust) (see for example instruction decoder generation using `instructions.txt` and `parse_ins.pl`), which is a great resource for learning about RISC-V in general, aside from the [official specs](https://riscv.org/technical/specifications/) of course.
[0] GPUs only really support 32-bit integer math (in the use-case I want to put this in anyway)
[1] The elf loader ('elfy') is written in Rust, because I was too lazy to do it myself in C (Rust uses the 'elf' crate) and it doesn't need porting anyway.
# Cloning this repository
This repo makes heavy use of submodules, so make sure to use `git clone --recursive` on initial cloning (may take a long time) and run `git submodule update --recursive` after a new pull.
To build any of the code included, you will probably need the following:
* A C compiler (gcc, clang)
* A rust compiler
* Perl 5
* A device tree compiler (dtc)
# C version specifics
Pay no mind to the somewhat weird style of C please, it is mostly because of the need to port to HLSL.
To build, remove the 'rvc' binary and 'src/main.o', then run 'make rvc' from the top level directory.
To run the riscv-tests, use `test.sh`. `test.sh all --clean` can be used to run the full supported test suite.
# Shader specifics
The shader version is a direct port of the C one. It can be found as part of a Unity project in `_Nix/`.
This is *not* a drag-and-drop prefab by any means, it will require careful setup and integration into a world to be useful.
The biggest pitfall is probably the required Perl support. The shader code uses [perlpp](https://github.com/interpreters/perlpp) and a valid runtime environment (I recommend [Strawberry Perl](https://strawberryperl.com/) for Windows). See the file `AutoImport.cs` for more information, you will need to set a valid path in there. Technically, the already created \*.h files can be used as-is, but you won't be able to meaningfully change any code without it.
The approach uses a Custom Render Texture and some (really messy) VRChat Udon scripts to manage the emulator during runtime. They will probably require fixing up for use in your own world.
The `NixDebug.cs` (Udon) script needs to be placed on a camera pointing at a camera loop reading in from the 'display' shader. This provides a translation layer between the 128bit-per-pixel integer texture used in the CRT and the `Color(float, float, float, float)` struct available in Unity/C#.
`NixControl.cs` is built with support for my [Dial](https://github.com/PiMaker/VRChatUnityThings#dial) prefab in mind, but can be changed to support any other control input too of course.
# Build instructions (for the various subprojects/payloads)
### Toolchain/Initramfs
For both the target toolchain (`riscv32-gnu-linux-`) and the initramfs, [buildroot](https://buildroot.org/) is used - this is *not* a submodule, but an extracted and slightly modified version instead.
To build, run `make buildroot-2021.05/build.marker` in the top level directory. The toolchain will be made in `buildroot-2021.05/output/host` and the rootfs in `buildroot-2021.05/output/images`. This will take a long time.
### Micropython
Enter the 'mprv' subdirectory. Run 'make'. Requires the toolchain to be built.
### bare_metal_test
Enter the 'bare_metal_test' subdirectory. Run 'make'. Requires the toolchain to be built.
### toimg
This tool is responsible for converting binary images (not ELF!) into texture files you can import into Unity, which can then be run by the shader version.
Enter the 'toimg' subdirectory. Run `cargo build --release`. Use `./target/release/toimg <binary> 2048 2048` to create an image file. The second '2048' specifies the height, which may be smaller than '2048'. On the first run, the program will display the optimal size to give for running a second time. This is not necessary, but will produce smaller images.
### rust_payload
This is a test payload written in rust. It demonstrates the ability to run rust code natively on the emulator (both C and shader version). Build by running `make rust_payload.bin` in the top-level directory.
NOTE: This requires a custom rust toolchain, as the default one does not have a 'rv32ima' target, only 'rv32imac' which is not supported. A demonstrative patch for [rustc](https://github.com/rust-lang/rust) can be found in `rust-target-rv32ima.patch`.
### linux
To build the linux payload, run `make linux_payload.bin` in the top level directory. This requires the toolchain and initramfs to be built.
# Why?
Because.
# License
MIT. Take it or leave it.
MIT. See LICENSE for more.

227
rust-target-rv32ima.patch Normal file
View File

@ -0,0 +1,227 @@
From e23b4e558bd1d6bcdc63751a66af6657b21da4f5 Mon Sep 17 00:00:00 2001
From: Stefan <stefan@pimaker.at>
Date: Wed, 9 Jun 2021 15:18:26 +0200
Subject: [PATCH] rust target rv32ima
Signed-off-by: Stefan <stefan@pimaker.at>
---
compiler/rustc_target/src/spec/mod.rs | 1 +
.../src/spec/riscv32ima_unknown_none_elf.rs | 26 ++++
src/doc/rustc/src/platform-support.md | 143 ++++++++++--------
src/tools/build-manifest/src/main.rs | 1 +
4 files changed, 107 insertions(+), 64 deletions(-)
create mode 100644 compiler/rustc_target/src/spec/riscv32ima_unknown_none_elf.rs
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 0f2aaeb533a..81417fd5647 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -868,6 +868,7 @@ fn $module() {
("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
+ ("riscv32ima-unknown-none-elf", riscv32ima_unknown_none_elf),
("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu),
("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl),
("riscv64imac-unknown-none-elf", riscv64imac_unknown_none_elf),
diff --git a/compiler/rustc_target/src/spec/riscv32ima_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32ima_unknown_none_elf.rs
new file mode 100644
index 00000000000..6f0ef862582
--- /dev/null
+++ b/compiler/rustc_target/src/spec/riscv32ima_unknown_none_elf.rs
@@ -0,0 +1,26 @@
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel};
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+ Target {
+ data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
+ llvm_target: "riscv32".to_string(),
+ pointer_width: 32,
+ arch: "riscv32".to_string(),
+
+ options: TargetOptions {
+ linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+ linker: Some("rust-lld".to_string()),
+ cpu: "generic-rv32".to_string(),
+ max_atomic_width: Some(32),
+ features: "+m,+a".to_string(),
+ executables: true,
+ panic_strategy: PanicStrategy::Abort,
+ relocation_model: RelocModel::Static,
+ emit_debug_gdb_scripts: false,
+ unsupported_abis: super::riscv_base::unsupported_abis(),
+ eh_frame_header: false,
+ ..Default::default()
+ },
+ }
+}
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 3225e95941c..7a58992293a 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -107,70 +107,85 @@ policy](target-tier-policy.md#tier-2-target-policy) in the Target Tier Policy.
The `std` column in the table below has the following meanings:
-* ✓ indicates the full standard library is available.
-* \* indicates the target only supports [`no_std`] development.
-
-[`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
-
-target | std | notes
--------|:---:|-------
-`aarch64-apple-ios` | ✓ | ARM64 iOS
-`aarch64-fuchsia` | ✓ | ARM64 Fuchsia
-`aarch64-linux-android` | ✓ | ARM64 Android
-`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
-`aarch64-unknown-none` | * | Bare ARM64, hardfloat
-`arm-linux-androideabi` | ✓ | ARMv7 Android
-`arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with MUSL
-`arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with MUSL, hardfloat
-`armebv7r-none-eabi` | * | Bare ARMv7-R, Big Endian
-`armebv7r-none-eabihf` | * | Bare ARMv7-R, Big Endian, hardfloat
-`armv5te-unknown-linux-gnueabi` | ✓ | ARMv5TE Linux (kernel 4.4, glibc 2.23)
-`armv5te-unknown-linux-musleabi` | ✓ | ARMv5TE Linux with MUSL
-`armv7-linux-androideabi` | ✓ | ARMv7a Android
-`armv7-unknown-linux-gnueabi` | ✓ |ARMv7 Linux (kernel 4.15, glibc 2.27)
-`armv7-unknown-linux-musleabi` | ✓ |ARMv7 Linux, MUSL
-`armv7-unknown-linux-musleabihf` | ✓ | ARMv7 Linux with MUSL
-`armv7a-none-eabi` | * | Bare ARMv7-A
-`armv7r-none-eabi` | * | Bare ARMv7-R
-`armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat
-`asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten
-`i586-pc-windows-msvc` | ✓ | 32-bit Windows w/o SSE
-`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23)
-`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL
-`i686-linux-android` | ✓ | 32-bit x86 Android
-`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD
-`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL
-`mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL
-`mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL
-`mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL
-`mipsel-unknown-linux-musl` | ✓ | MIPS (LE) Linux with MUSL
-`nvptx64-nvidia-cuda` | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
-`riscv32i-unknown-none-elf` | * | Bare RISC-V (RV32I ISA)
-`riscv32imac-unknown-none-elf` | * | Bare RISC-V (RV32IMAC ISA)
-`riscv32imc-unknown-none-elf` | * | Bare RISC-V (RV32IMC ISA)
-`riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA)
-`riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA)
-`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23)
-`sparcv9-sun-solaris` | ✓ | SPARC Solaris 10/11, illumos
-`thumbv6m-none-eabi` | * | Bare Cortex-M0, M0+, M1
-`thumbv7em-none-eabi` | * | Bare Cortex-M4, M7
-`thumbv7em-none-eabihf` | * | Bare Cortex-M4F, M7F, FPU, hardfloat
-`thumbv7m-none-eabi` | * | Bare Cortex-M3
-`thumbv7neon-linux-androideabi` | ✓ | Thumb2-mode ARMv7a Android with NEON
-`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode ARMv7a Linux with NEON (kernel 4.4, glibc 2.23)
-`thumbv8m.base-none-eabi` | * | ARMv8-M Baseline
-`thumbv8m.main-none-eabi` | * | ARMv8-M Mainline
-`thumbv8m.main-none-eabihf` | * | ARMv8-M Mainline, hardfloat
-`wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
-`wasm32-unknown-unknown` | ✓ | WebAssembly
-`wasm32-wasi` | ✓ | WebAssembly with WASI
-`x86_64-apple-ios` | ✓ | 64-bit x86 iOS
-`x86_64-fortanix-unknown-sgx` | ✓ | [Fortanix ABI] for 64-bit Intel SGX
-`x86_64-fuchsia` | ✓ | 64-bit Fuchsia
-`x86_64-linux-android` | ✓ | 64-bit x86 Android
-`x86_64-pc-solaris` | ✓ | 64-bit Solaris 10/11, illumos
-`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
-`x86_64-unknown-redox` | ✓ | Redox OS
+target | std | host | notes
+-------|-----|------|-------
+`aarch64-apple-darwin` | ✓ | ✓ | ARM64 macOS (11.0+, Big Sur+)
+`aarch64-apple-ios` | ✓ | | ARM64 iOS
+`aarch64-fuchsia` | ✓ | | ARM64 Fuchsia
+`aarch64-linux-android` | ✓ | | ARM64 Android
+`aarch64-pc-windows-msvc` | ✓ | ✓ | ARM64 Windows MSVC
+`aarch64-unknown-linux-musl` | ✓ | ✓ | ARM64 Linux with MUSL
+`aarch64-unknown-none` | * | | Bare ARM64, hardfloat
+`aarch64-unknown-none-softfloat` | * | | Bare ARM64, softfloat
+`arm-linux-androideabi` | ✓ | | ARMv7 Android
+`arm-unknown-linux-gnueabi` | ✓ | ✓ | ARMv6 Linux (kernel 3.2, glibc 2.17)
+`arm-unknown-linux-gnueabihf` | ✓ | ✓ | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
+`arm-unknown-linux-musleabi` | ✓ | | ARMv6 Linux with MUSL
+`arm-unknown-linux-musleabihf` | ✓ | | ARMv6 Linux with MUSL, hardfloat
+`armebv7r-none-eabi` | * | | Bare ARMv7-R, Big Endian
+`armebv7r-none-eabihf` | * | | Bare ARMv7-R, Big Endian, hardfloat
+`armv5te-unknown-linux-gnueabi` | ✓ | | ARMv5TE Linux (kernel 4.4, glibc 2.23)
+`armv5te-unknown-linux-musleabi` | ✓ | | ARMv5TE Linux with MUSL
+`armv7-linux-androideabi` | ✓ | | ARMv7a Android
+`armv7a-none-eabi` | * | | Bare ARMv7-A
+`armv7r-none-eabi` | * | | Bare ARMv7-R
+`armv7r-none-eabihf` | * | | Bare ARMv7-R, hardfloat
+`armv7-unknown-linux-gnueabi` | ✓ | | ARMv7 Linux (kernel 4.15, glibc 2.27)
+`armv7-unknown-linux-gnueabihf` | ✓ | ✓ | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
+`armv7-unknown-linux-musleabi` | ✓ | | ARMv7 Linux, MUSL
+`armv7-unknown-linux-musleabihf` | ✓ | | ARMv7 Linux with MUSL
+`asmjs-unknown-emscripten` | ✓ | | asm.js via Emscripten
+`i586-pc-windows-msvc` | ✓ | | 32-bit Windows w/o SSE
+`i586-unknown-linux-gnu` | ✓ | | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23)
+`i586-unknown-linux-musl` | ✓ | | 32-bit Linux w/o SSE, MUSL
+`i686-linux-android` | ✓ | | 32-bit x86 Android
+`i686-unknown-freebsd` | ✓ | | 32-bit FreeBSD
+`i686-unknown-linux-musl` | ✓ | | 32-bit Linux with MUSL
+`mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
+`mips-unknown-linux-musl` | ✓ | | MIPS Linux with MUSL
+`mips64-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23)
+`mips64-unknown-linux-muslabi64` | ✓ | | MIPS64 Linux, n64 ABI, MUSL
+`mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23)
+`mips64el-unknown-linux-muslabi64` | ✓ | | MIPS64 (LE) Linux, n64 ABI, MUSL
+`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (LE) Linux (kernel 4.4, glibc 2.23)
+`mipsel-unknown-linux-musl` | ✓ | | MIPS (LE) Linux with MUSL
+`nvptx64-nvidia-cuda` | ✓ | | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
+`powerpc-unknown-linux-gnu` | ✓ | ✓ | PowerPC Linux (kernel 2.6.32, glibc 2.11)
+`powerpc64-unknown-linux-gnu` | ✓ | ✓ | PPC64 Linux (kernel 2.6.32, glibc 2.11)
+`powerpc64le-unknown-linux-gnu` | ✓ | ✓ | PPC64LE Linux (kernel 3.10, glibc 2.17)
+`riscv32i-unknown-none-elf` | * | | Bare RISC-V (RV32I ISA)
+`riscv32imac-unknown-none-elf` | * | | Bare RISC-V (RV32IMAC ISA)
+`riscv32ima-unknown-none-elf` | * | | Bare RISC-V (RV32IMA ISA)
+`riscv32imc-unknown-none-elf` | * | | Bare RISC-V (RV32IMC ISA)
+`riscv64gc-unknown-linux-gnu` | ✓ | ✓ | RISC-V Linux (kernel 4.20, glibc 2.29)
+`riscv64gc-unknown-none-elf` | * | | Bare RISC-V (RV64IMAFDC ISA)
+`riscv64imac-unknown-none-elf` | * | | Bare RISC-V (RV64IMAC ISA)
+`s390x-unknown-linux-gnu` | ✓ | ✓ | S390x Linux (kernel 2.6.32, glibc 2.11)
+`sparc64-unknown-linux-gnu` | ✓ | | SPARC Linux (kernel 4.4, glibc 2.23)
+`sparcv9-sun-solaris` | ✓ | | SPARC Solaris 10/11, illumos
+`thumbv6m-none-eabi` | * | | Bare Cortex-M0, M0+, M1
+`thumbv7em-none-eabi` | * | | Bare Cortex-M4, M7
+`thumbv7em-none-eabihf` | * | | Bare Cortex-M4F, M7F, FPU, hardfloat
+`thumbv7m-none-eabi` | * | | Bare Cortex-M3
+`thumbv7neon-linux-androideabi` | ✓ | | Thumb2-mode ARMv7a Android with NEON
+`thumbv7neon-unknown-linux-gnueabihf` | ✓ | | Thumb2-mode ARMv7a Linux with NEON (kernel 4.4, glibc 2.23)
+`thumbv8m.base-none-eabi` | * | | ARMv8-M Baseline
+`thumbv8m.main-none-eabi` | * | | ARMv8-M Mainline
+`thumbv8m.main-none-eabihf` | * | | ARMv8-M Mainline, hardfloat
+`wasm32-unknown-emscripten` | ✓ | | WebAssembly via Emscripten
+`wasm32-unknown-unknown` | ✓ | | WebAssembly
+`wasm32-wasi` | ✓ | | WebAssembly with WASI
+`x86_64-apple-ios` | ✓ | | 64-bit x86 iOS
+`x86_64-fortanix-unknown-sgx` | ✓ | | [Fortanix ABI] for 64-bit Intel SGX
+`x86_64-fuchsia` | ✓ | | 64-bit Fuchsia
+`x86_64-linux-android` | ✓ | | 64-bit x86 Android
+`x86_64-pc-solaris` | ✓ | | 64-bit Solaris 10/11, illumos
+`x86_64-unknown-freebsd` | ✓ | ✓ | 64-bit FreeBSD
+`x86_64-unknown-illumos` | ✓ | ✓ | illumos
+`x86_64-unknown-linux-gnux32` | ✓ | | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
+`x86_64-unknown-linux-musl` | ✓ | ✓ | 64-bit Linux with MUSL
+`x86_64-unknown-netbsd` | ✓ | ✓ | NetBSD/amd64
+`x86_64-unknown-redox` | ✓ | | Redox OS
[Fortanix ABI]: https://edp.fortanix.com/
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 1e19b7b21d8..a411320ac9e 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -116,6 +116,7 @@
"powerpc64le-unknown-linux-gnu",
"riscv32i-unknown-none-elf",
"riscv32imc-unknown-none-elf",
+ "riscv32ima-unknown-none-elf",
"riscv32imac-unknown-none-elf",
"riscv32gc-unknown-linux-gnu",
"riscv64imac-unknown-none-elf",
--
2.32.0