From 9de4fa1524f41637dc44175627ea0dff25e59db6 Mon Sep 17 00:00:00 2001 From: Avimitin Date: Tue, 8 Oct 2024 21:32:10 +0800 Subject: [PATCH] [sail-riscv] add sail-riscv Rust binder Disambiguation: * sail: the official sail language, library, API, headers that belongs to rem-project. * sail-riscv: the riscv spec definition describe using sail. Build step: 1. Use rust-bindgen to create Rust FFI to the sail header, so that we can always keep integrity of the sail library. 2. Extern declare all necessary C function define in generated model from sail and sail-riscv. 3. Define or override necessary functions from our Rust side. Current issues: * Implement our Rust emulator using above strategy inevitably create a programming model that functions will be called back and forth from both C and Rust side. This will also make the code hard to read. Hope this situation could be improved in upcomming rational documents. * Although sail support using different prefix for its model declaration when generating C sources, I am still afraid that these global machine state in sail-riscv model will cause problem in our future development. Signed-off-by: Avimitin --- sail-riscv/default.nix | 4 + sail-riscv/sail-riscv-sys/Cargo.lock | 286 ++++++++++++++++++ sail-riscv/sail-riscv-sys/Cargo.toml | 9 + sail-riscv/sail-riscv-sys/build.rs | 19 ++ sail-riscv/sail-riscv-sys/default.nix | 45 +++ .../sail-riscv-sys/sail_include/wrapper.h | 1 + sail-riscv/sail-riscv-sys/src/lib.rs | 96 ++++++ 7 files changed, 460 insertions(+) create mode 100644 sail-riscv/default.nix create mode 100644 sail-riscv/sail-riscv-sys/Cargo.lock create mode 100644 sail-riscv/sail-riscv-sys/Cargo.toml create mode 100644 sail-riscv/sail-riscv-sys/build.rs create mode 100644 sail-riscv/sail-riscv-sys/default.nix create mode 100644 sail-riscv/sail-riscv-sys/sail_include/wrapper.h create mode 100644 sail-riscv/sail-riscv-sys/src/lib.rs diff --git a/sail-riscv/default.nix b/sail-riscv/default.nix new file mode 100644 index 000000000..642e11a78 --- /dev/null +++ b/sail-riscv/default.nix @@ -0,0 +1,4 @@ +{ lib, newScope }: +lib.makeScope newScope (scope: { + sail-riscv-sys = scope.callPackage ./sail-riscv-sys { }; +}) diff --git a/sail-riscv/sail-riscv-sys/Cargo.lock b/sail-riscv/sail-riscv-sys/Cargo.lock new file mode 100644 index 000000000..44a59a360 --- /dev/null +++ b/sail-riscv/sail-riscv-sys/Cargo.lock @@ -0,0 +1,286 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "prettyplease" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "sail-riscv-sys" +version = "0.1.0" +dependencies = [ + "bindgen", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/sail-riscv/sail-riscv-sys/Cargo.toml b/sail-riscv/sail-riscv-sys/Cargo.toml new file mode 100644 index 000000000..6221ea018 --- /dev/null +++ b/sail-riscv/sail-riscv-sys/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "sail-riscv-sys" +version = "0.1.0" +edition = "2021" + +[dependencies] + +[build-dependencies] +bindgen = "0.70.1" diff --git a/sail-riscv/sail-riscv-sys/build.rs b/sail-riscv/sail-riscv-sys/build.rs new file mode 100644 index 000000000..abf126d08 --- /dev/null +++ b/sail-riscv/sail-riscv-sys/build.rs @@ -0,0 +1,19 @@ +use std::env; +use std::path::PathBuf; + +fn main() { + let sail_install_path = env::var("SAIL_INSTALL_PATH").expect("$SAIL_INSTALL_PATH not set"); + + let bindings = bindgen::Builder::default() + .header("sail_include/wrapper.h") + .clang_arg(format!("-I{sail_install_path}/share/sail/lib")) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .generate() + .expect("Unable to generate bindings"); + + // Write the bindings to the $OUT_DIR/bindings.rs file. + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("sail_h.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/sail-riscv/sail-riscv-sys/default.nix b/sail-riscv/sail-riscv-sys/default.nix new file mode 100644 index 000000000..e2e6f3aef --- /dev/null +++ b/sail-riscv/sail-riscv-sys/default.nix @@ -0,0 +1,45 @@ +{ lib +, rustPlatform +, sail-riscv-c-model +, rustfmt +, rust-analyzer +, llvmPackages_18 +}: + +let + finalPkg = rustPlatform.buildRustPackage { + name = "sail-riscv-rs-emulator"; + src = with lib.fileset; toSource { + root = ./.; + fileset = unions [ + ./src + ./build.rs + ./sail_include + ./Cargo.lock + ./Cargo.toml + ]; + }; + + nativeBuildInputs = [ + rustPlatform.bindgenHook + ]; + + env = { + SAIL_INSTALL_PATH = toString sail-riscv-c-model.sail; + }; + + cargoLock = { + lockFile = ./Cargo.lock; + }; + + passthru = { + devShell = finalPkg.overrideAttrs (prev: { + nativeBuildInputs = prev.nativeBuildInputs ++ [ + rustfmt + rust-analyzer + ]; + }); + }; + }; +in +finalPkg diff --git a/sail-riscv/sail-riscv-sys/sail_include/wrapper.h b/sail-riscv/sail-riscv-sys/sail_include/wrapper.h new file mode 100644 index 000000000..b866f9e2c --- /dev/null +++ b/sail-riscv/sail-riscv-sys/sail_include/wrapper.h @@ -0,0 +1 @@ +#include diff --git a/sail-riscv/sail-riscv-sys/src/lib.rs b/sail-riscv/sail-riscv-sys/src/lib.rs new file mode 100644 index 000000000..8a23b30af --- /dev/null +++ b/sail-riscv/sail-riscv-sys/src/lib.rs @@ -0,0 +1,96 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +// This disable warning of `u128` type usage. +// The `u128` type is not ABI stable, and is considered not FFI safe. +#![allow(improper_ctypes)] + +include!(concat!(env!("OUT_DIR"), "/sail_h.rs")); + +#[repr(C)] +pub(crate) struct zMisa { + zMisa_chunk_0: mach_bits, +} + +#[repr(C)] +pub(crate) struct zMcause { + zMcause_chunk_0: mach_bits, +} + +// ---------------------------------------------------------------------------- +// Defined in sail model +// ---------------------------------------------------------------------------- +extern "C" { + fn model_init(); + fn model_fini(); + + fn z_set_Misa_C(_: *mut zMisa, _: mach_bits) -> unit; + fn z_set_Misa_D(_: *mut zMisa, _: mach_bits) -> unit; + fn z_set_Misa_F(_: *mut zMisa, _: mach_bits) -> unit; +} + +// ---------------------------------------------------------------------------- +// Defined in sail-riscv model +// ---------------------------------------------------------------------------- +extern "C" { + fn zinit_model(_: unit) -> unit; + fn zstep(_: sail_int) -> bool; + fn ztick_clock(_: unit) -> unit; + fn ztick_platform(_: unit) -> unit; + + pub static mut zxlen_val: mach_bits; + pub static mut zhtif_done: bool; + pub static mut zhtif_exit_code: mach_bits; + pub static mut have_exception: bool; + + /* machine state */ + pub static mut zcur_privilege: u32; + pub static mut zPC: mach_bits; + pub static mut zx1: mach_bits; + pub static mut zx2: mach_bits; + pub static mut zx3: mach_bits; + pub static mut zx4: mach_bits; + pub static mut zx5: mach_bits; + pub static mut zx6: mach_bits; + pub static mut zx7: mach_bits; + pub static mut zx8: mach_bits; + pub static mut zx9: mach_bits; + pub static mut zx10: mach_bits; + pub static mut zx11: mach_bits; + pub static mut zx12: mach_bits; + pub static mut zx13: mach_bits; + pub static mut zx14: mach_bits; + pub static mut zx15: mach_bits; + pub static mut zx16: mach_bits; + pub static mut zx17: mach_bits; + pub static mut zx18: mach_bits; + pub static mut zx19: mach_bits; + pub static mut zx20: mach_bits; + pub static mut zx21: mach_bits; + pub static mut zx22: mach_bits; + pub static mut zx23: mach_bits; + pub static mut zx24: mach_bits; + pub static mut zx25: mach_bits; + pub static mut zx26: mach_bits; + pub static mut zx27: mach_bits; + pub static mut zx28: mach_bits; + pub static mut zx29: mach_bits; + pub static mut zx30: mach_bits; + pub static mut zx31: mach_bits; + + pub static mut zmstatus: mach_bits; + pub static mut zmepc: mach_bits; + pub static mut zmtval: mach_bits; + pub static mut zsepc: mach_bits; + pub static mut zstval: mach_bits; + + pub static mut zfloat_result: mach_bits; + pub static mut zfloat_fflags: mach_bits; + + pub static mut zmcause: zMcause; + pub static mut zscause: zMcause; + + pub static mut zminstret: mach_bits; + + pub static mut zmisa: zMisa; +}