diff --git a/machine/emulator b/machine/emulator index b7efb64a..4cad7553 160000 --- a/machine/emulator +++ b/machine/emulator @@ -1 +1 @@ -Subproject commit b7efb64a92c552d9307d3c7581f1de4de94ababb +Subproject commit 4cad755346822b1d7349b18502983ce22e412a60 diff --git a/machine/rust-bindings/cartesi-machine-sys/Cargo.toml b/machine/rust-bindings/cartesi-machine-sys/Cargo.toml index 363ded2b..f3278d0a 100644 --- a/machine/rust-bindings/cartesi-machine-sys/Cargo.toml +++ b/machine/rust-bindings/cartesi-machine-sys/Cargo.toml @@ -26,7 +26,8 @@ copy_uarch = [] # requires setting env vars LIBCARTESI_PATH and INCLUDECARTESI_PATH external_cartesi = [] -default = ["download_uarch"] +# default = ["download_uarch"] +default = ["build_uarch"] [dependencies] diff --git a/machine/rust-bindings/cartesi-machine-sys/build.rs b/machine/rust-bindings/cartesi-machine-sys/build.rs index 3e898a0f..4fbec00b 100644 --- a/machine/rust-bindings/cartesi-machine-sys/build.rs +++ b/machine/rust-bindings/cartesi-machine-sys/build.rs @@ -1,27 +1,7 @@ // (c) Cartesi and individual authors (see AUTHORS) // SPDX-License-Identifier: Apache-2.0 (see LICENSE) - use std::{env, path::PathBuf, process::Command}; -mod feature_checks { - #[cfg(all(feature = "build_uarch", feature = "copy_uarch",))] - compile_error!("Features `build_uarch` and `copy_uarch` are mutually exclusive"); - - #[cfg(all(feature = "build_uarch", feature = "download_uarch"))] - compile_error!("Features `build_uarch` and `download_uarch` are mutually exclusive"); - - #[cfg(all(feature = "copy_uarch", feature = "download_uarch"))] - compile_error!("Features `copy_uarch`, and `download_uarch` are mutually exclusive"); - - #[cfg(not(any( - feature = "copy_uarch", - feature = "download_uarch", - feature = "build_uarch", - feature = "external_cartesi", - )))] - compile_error!("At least one of `build_uarch`, `copy_uarch`, `download_uarch`, and `external_cartesi` must be set"); -} - fn main() { let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); @@ -78,29 +58,33 @@ fn main() { // machine api let machine_bindings = bindgen::Builder::default() .header(include_path.join("machine-c-api.h").to_str().unwrap()) + .merge_extern_blocks(true) + .generate_comments(false) + .prepend_enum_name(false) + .translate_enum_integer_types(true) .generate() .expect("Unable to generate machine bindings"); - // htif constants - let htif = bindgen::Builder::default() - .header(include_path.join("htif-defines.h").to_str().unwrap()) - .generate() - .expect("Unable to generate htif bindings"); + // // htif constants + // let htif = bindgen::Builder::default() + // .header(libdir_path.join("htif-defines.h").to_str().unwrap()) + // .generate() + // .expect("Unable to generate htif bindings"); - // pma constants - let pma = bindgen::Builder::default() - .header(include_path.join("pma-defines.h").to_str().unwrap()) - .generate() - .expect("Unable to generate pma bindings"); + // // pma constants + // let pma = bindgen::Builder::default() + // .header(libdir_path.join("pma-defines.h").to_str().unwrap()) + // .generate() + // .expect("Unable to generate pma bindings"); // Write the bindings to the `$OUT_DIR/bindings.rs` and `$OUT_DIR/htif.rs` files. machine_bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write machine bindings"); - htif.write_to_file(out_path.join("htif.rs")) - .expect("Couldn't write htif defines"); - pma.write_to_file(out_path.join("pma.rs")) - .expect("Couldn't write pma defines"); + // htif.write_to_file(out_path.join("htif.rs")) + // .expect("Couldn't write htif defines"); + // pma.write_to_file(out_path.join("pma.rs")) + // .expect("Couldn't write pma defines"); // Setup reruns println!("cargo:rerun-if-changed=build.rs"); @@ -131,7 +115,9 @@ mod build_cm { } } + // // Build and link emulator + // // build dependencies Command::new("make") @@ -282,7 +268,106 @@ mod build_cm { } } -#[allow(dead_code)] +#[cfg(feature = "download_uarch")] +mod download { + use bytes::Bytes; + use std::fs::OpenOptions; + use std::{ + io::{self, Read, Write}, + path::Path, + process::{Command, Stdio}, + }; + + fn download_uarch(machine_dir_path: &PathBuf) { + // apply git patche for 0.18.1 + let patch_file = machine_dir_path.join("add-generated-files.diff"); + + download_git_patch(&patch_file, "v0.18.1"); + apply_git_patch(&patch_file, machine_dir_path); + } + + fn download_git_patch(patch_file: &PathBuf, target_tag: &str) { + let emulator_git_url = "https://github.com/cartesi/machine-emulator"; + + let patch_url = format!( + "{}/releases/download/{}/add-generated-files.diff", + emulator_git_url, target_tag, + ); + + // get + let diff_data = reqwest::blocking::get(patch_url) + .expect("error downloading diff of generated files") + .bytes() + .expect("error getting diff request body"); + + // write to file + write_bytes_to_file(patch_file.to_str().unwrap(), diff_data) + .expect("failed to write `add-generated-files.diff`"); + } + + fn apply_git_patch(patch_file: &Path, target_dir: &Path) { + // Open the patch file + let mut patch = fs::File::open(patch_file).expect("fail to open patch file"); + + // Create a command to run `patch -Np0` + let mut cmd = Command::new("patch") + .arg("-Np0") + .stdin(Stdio::piped()) + .current_dir(target_dir) + .spawn() + .expect("fail to spawn patch command"); + + // Write the contents of the patch file to the command's stdin + if let Some(ref mut stdin) = cmd.stdin { + let mut buffer = Vec::new(); + patch + .read_to_end(&mut buffer) + .expect("fail to read patch content"); + stdin + .write_all(&buffer) + .expect("fail to write patch to pipe"); + } + + // Wait for the command to complete + let status = cmd.wait().expect("fail to wait for patch command"); + + if !status.success() { + eprintln!("Patch command failed with status: {:?}", status); + } + } + + fn write_bytes_to_file(path: &str, data: Bytes) -> io::Result<()> { + let mut file = OpenOptions::new() + .write(true) + .create(true) + .open(path) + .expect(&format!("failed to open file {}", path)); + + file.write_all(&data)?; + file.flush() // Ensure all data is written to disk + } +} + +mod feature_checks { + #[cfg(all(feature = "build_uarch", feature = "copy_uarch",))] + compile_error!("Features `build_uarch` and `copy_uarch` are mutually exclusive"); + + #[cfg(all(feature = "build_uarch", feature = "download_uarch"))] + compile_error!("Features `build_uarch` and `download_uarch` are mutually exclusive"); + + #[cfg(all(feature = "copy_uarch", feature = "download_uarch"))] + compile_error!("Features `copy_uarch`, and `download_uarch` are mutually exclusive"); + + #[cfg(not(any( + feature = "copy_uarch", + feature = "download_uarch", + feature = "build_uarch", + feature = "external_cartesi", + )))] + compile_error!("At least one of `build_uarch`, `copy_uarch`, `download_uarch`, and `external_cartesi` must be set"); +} + +#[allow(unused)] fn clean(path: &PathBuf) { // clean build artifacts Command::new("make") diff --git a/machine/rust-bindings/cartesi-machine-sys/src/lib.rs b/machine/rust-bindings/cartesi-machine-sys/src/lib.rs index 133a4417..04af9171 100644 --- a/machine/rust-bindings/cartesi-machine-sys/src/lib.rs +++ b/machine/rust-bindings/cartesi-machine-sys/src/lib.rs @@ -5,5 +5,5 @@ extern crate link_cplusplus; include!(concat!(env!("OUT_DIR"), "/bindings.rs")); -include!(concat!(env!("OUT_DIR"), "/htif.rs")); -include!(concat!(env!("OUT_DIR"), "/pma.rs")); +// include!(concat!(env!("OUT_DIR"), "/htif.rs")); +// include!(concat!(env!("OUT_DIR"), "/pma.rs")); diff --git a/machine/rust-bindings/cartesi-machine/src/constants.rs b/machine/rust-bindings/cartesi-machine/src/constants.rs index 859e56cc..09c469cf 100644 --- a/machine/rust-bindings/cartesi-machine/src/constants.rs +++ b/machine/rust-bindings/cartesi-machine/src/constants.rs @@ -3,132 +3,114 @@ //! Constants definitions from Cartesi Machine -/// +pub mod machine { + use cartesi_machine_sys::*; + pub const CYCLE_MAX: u64 = CM_MCYCLE_MAX as u64; + pub const HASH_SIZE: u32 = CM_HASH_SIZE; + pub const TREE_LOG2_WORD_SIZE: u32 = CM_TREE_LOG2_WORD_SIZE; + pub const TREE_LOG2_PAGE_SIZE: u32 = CM_TREE_LOG2_PAGE_SIZE; + pub const TREE_LOG2_ROOT_SIZE: u32 = CM_TREE_LOG2_ROOT_SIZE; +} + +pub mod pma { + use cartesi_machine_sys::*; + pub const RX_START: u64 = CM_PMA_CMIO_RX_BUFFER_START as u64; + pub const RX_LOG2_SIZE: u64 = CM_PMA_CMIO_RX_BUFFER_LOG2_SIZE as u64; + pub const TX_START: u64 = CM_PMA_CMIO_TX_BUFFER_START as u64; + pub const TX_LOG2_SIZE: u64 = CM_PMA_CMIO_TX_BUFFER_LOG2_SIZE as u64; + pub const RAM_START: u64 = CM_PMA_RAM_START as u64; +} + pub mod break_reason { use cartesi_machine_sys::*; - pub const FAILED: u32 = CM_BREAK_REASON_CM_BREAK_REASON_FAILED; - pub const HALTED: u32 = CM_BREAK_REASON_CM_BREAK_REASON_HALTED; - pub const YIELDED_MANUALLY: u32 = CM_BREAK_REASON_CM_BREAK_REASON_YIELDED_MANUALLY; - pub const YIELDED_AUTOMATICALLY: u32 = CM_BREAK_REASON_CM_BREAK_REASON_YIELDED_AUTOMATICALLY; - pub const YIELDED_SOFTLY: u32 = CM_BREAK_REASON_CM_BREAK_REASON_YIELDED_SOFTLY; - pub const REACHED_TARGET_MCYCLE: u32 = CM_BREAK_REASON_CM_BREAK_REASON_REACHED_TARGET_MCYCLE; + pub const FAILED: u32 = CM_BREAK_REASON_FAILED; + pub const HALTED: u32 = CM_BREAK_REASON_HALTED; + pub const YIELDED_MANUALLY: u32 = CM_BREAK_REASON_YIELDED_MANUALLY; + pub const YIELDED_AUTOMATICALLY: u32 = CM_BREAK_REASON_YIELDED_AUTOMATICALLY; + pub const YIELDED_SOFTLY: u32 = CM_BREAK_REASON_YIELDED_SOFTLY; + pub const REACHED_TARGET_MCYCLE: u32 = CM_BREAK_REASON_REACHED_TARGET_MCYCLE; } -/// pub mod uarch_break_reason { use cartesi_machine_sys::*; - pub const REACHED_TARGET_CYCLE: u32 = - CM_UARCH_BREAK_REASON_CM_UARCH_BREAK_REASON_REACHED_TARGET_CYCLE; - pub const UARCH_HALTED: u32 = CM_UARCH_BREAK_REASON_CM_UARCH_BREAK_REASON_UARCH_HALTED; + pub const REACHED_TARGET_CYCLE: u32 = CM_UARCH_BREAK_REASON_REACHED_TARGET_CYCLE; + pub const UARCH_HALTED: u32 = CM_UARCH_BREAK_REASON_UARCH_HALTED; } -/// -pub mod htif { - pub mod masks { - use cartesi_machine_sys::*; - pub const DEVICE_SHIFT: u32 = HTIF_DEV_SHIFT_DEF; - pub const COMMAND_SHIFT: u32 = HTIF_CMD_SHIFT_DEF; - pub const DATA_SHIFT: u32 = HTIF_DATA_SHIFT_DEF; - pub const DEVICE_MASK: u64 = HTIF_DEV_MASK_DEF as u64; - pub const COMMAND_MASK: u64 = HTIF_CMD_MASK_DEF as u64; - pub const DATA_MASK: u64 = HTIF_DATA_MASK_DEF as u64; - } - - /// HTIF devices - pub mod devices { - use cartesi_machine_sys::*; - pub const HALT: u32 = HTIF_DEV_HALT_DEF; - pub const CONSOLE: u32 = HTIF_DEV_CONSOLE_DEF; - pub const YIELD: u32 = HTIF_DEV_YIELD_DEF; - } +pub mod access_log_type { + use cartesi_machine_sys::*; + pub const ANNOTATIONS: u32 = CM_ACCESS_LOG_TYPE_ANNOTATIONS; + pub const LARGE_DATA: u32 = CM_ACCESS_LOG_TYPE_LARGE_DATA; +} - /// HTIF commands +pub mod cmio { + /// CMIO commands pub mod commands { use cartesi_machine_sys::*; - pub const HALT_HALT: u32 = HTIF_HALT_CMD_HALT_DEF; - pub const CONSOLE_GETCHAR: u32 = HTIF_CONSOLE_CMD_GETCHAR_DEF; - pub const CONSOLE_PUTCHAR: u32 = HTIF_CONSOLE_CMD_PUTCHAR_DEF; - pub const YIELD_AUTOMATIC: u32 = HTIF_YIELD_CMD_AUTOMATIC_DEF; - pub const YIELD_MANUAL: u32 = HTIF_YIELD_CMD_MANUAL_DEF; + pub const YIELD_AUTOMATIC: u32 = CM_CMIO_YIELD_COMMAND_AUTOMATIC; + pub const YIELD_MANUAL: u32 = CM_CMIO_YIELD_COMMAND_MANUAL; } - /// HTIF request + /// CMIO request pub mod tohost { pub mod automatic { use cartesi_machine_sys::*; - pub const PROGRESS: u32 = HTIF_YIELD_AUTOMATIC_REASON_PROGRESS_DEF; - pub const TX_OUTPUT: u32 = HTIF_YIELD_AUTOMATIC_REASON_TX_OUTPUT_DEF; - pub const TX_REPORT: u32 = HTIF_YIELD_AUTOMATIC_REASON_TX_REPORT_DEF; + pub const PROGRESS: u32 = CM_CMIO_YIELD_AUTOMATIC_REASON_PROGRESS; + pub const TX_OUTPUT: u32 = CM_CMIO_YIELD_AUTOMATIC_REASON_TX_OUTPUT; + pub const TX_REPORT: u32 = CM_CMIO_YIELD_AUTOMATIC_REASON_TX_REPORT; } pub mod manual { use cartesi_machine_sys::*; - pub const RX_ACCEPTED: u32 = HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED_DEF; - pub const RX_REJECTED: u32 = HTIF_YIELD_MANUAL_REASON_RX_REJECTED_DEF; - pub const TX_EXCEPTION: u32 = HTIF_YIELD_MANUAL_REASON_TX_EXCEPTION_DEF; + pub const RX_ACCEPTED: u32 = CM_CMIO_YIELD_MANUAL_REASON_RX_ACCEPTED; + pub const RX_REJECTED: u32 = CM_CMIO_YIELD_MANUAL_REASON_RX_REJECTED; + pub const TX_EXCEPTION: u32 = CM_CMIO_YIELD_MANUAL_REASON_TX_EXCEPTION; } } - /// HTIF reply + /// CMIO reply pub mod fromhost { use cartesi_machine_sys::*; - pub const ADVANCE_STATE: u16 = HTIF_YIELD_REASON_ADVANCE_STATE_DEF as u16; - pub const INSPECT_STATE: u16 = HTIF_YIELD_REASON_INSPECT_STATE_DEF as u16; + pub const ADVANCE_STATE: u16 = CM_CMIO_YIELD_REASON_ADVANCE_STATE as u16; + pub const INSPECT_STATE: u16 = CM_CMIO_YIELD_REASON_INSPECT_STATE as u16; } } -/// -pub mod pma { - use cartesi_machine_sys::*; - pub const CMIO_RX_BUFFER_START: u64 = PMA_CMIO_RX_BUFFER_START_DEF as u64; - pub const CMIO_RX_BUFFER_LOG2_SIZE: u64 = PMA_CMIO_RX_BUFFER_LOG2_SIZE_DEF as u64; - pub const CMIO_TX_BUFFER_START: u64 = PMA_CMIO_TX_BUFFER_START_DEF as u64; - pub const CMIO_TX_BUFFER_LOG2_SIZE: u64 = PMA_CMIO_TX_BUFFER_LOG2_SIZE_DEF as u64; -} - -pub mod error { +pub mod errors { use cartesi_machine_sys::*; - pub const OK: u32 = CM_ERROR_CM_ERROR_OK; + pub const OK: i32 = CM_ERROR_OK; // Logic errors - pub const INVALID_ARGUMENT: u32 = CM_ERROR_CM_ERROR_INVALID_ARGUMENT; - pub const DOMAIN_ERROR: u32 = CM_ERROR_CM_ERROR_DOMAIN_ERROR; - pub const LENGTH_ERROR: u32 = CM_ERROR_CM_ERROR_LENGTH_ERROR; - pub const OUT_OF_RANGE: u32 = CM_ERROR_CM_ERROR_OUT_OF_RANGE; - pub const LOGIC_ERROR: u32 = CM_ERROR_CM_ERROR_LOGIC_ERROR; - pub const LOGIC_ERROR_END: u32 = CM_ERROR_CM_LOGIC_ERROR_END; + pub const INVALID_ARGUMENT: i32 = CM_ERROR_INVALID_ARGUMENT; + pub const DOMAIN_ERROR: i32 = CM_ERROR_DOMAIN_ERROR; + pub const LENGTH_ERROR: i32 = CM_ERROR_LENGTH_ERROR; + pub const OUT_OF_RANGE: i32 = CM_ERROR_OUT_OF_RANGE; + pub const LOGIC_ERROR: i32 = CM_ERROR_LOGIC_ERROR; // Bad optional access error - pub const BAD_OPTIONAL_ACCESS: u32 = CM_ERROR_CM_ERROR_BAD_OPTIONAL_ACCESS; + pub const BAD_OPTIONAL_ACCESS: i32 = CM_ERROR_BAD_OPTIONAL_ACCESS; // Runtime errors - pub const RUNTIME_ERROR: u32 = CM_ERROR_CM_ERROR_RUNTIME_ERROR; - pub const RANGE_ERROR: u32 = CM_ERROR_CM_ERROR_RANGE_ERROR; - pub const OVERFLOW_ERROR: u32 = CM_ERROR_CM_ERROR_OVERFLOW_ERROR; - pub const UNDERFLOW_ERROR: u32 = CM_ERROR_CM_ERROR_UNDERFLOW_ERROR; - pub const REGEX_ERROR: u32 = CM_ERROR_CM_ERROR_REGEX_ERROR; - pub const SYSTEM_IOS_BASE_FAILURE: u32 = CM_ERROR_CM_ERROR_SYSTEM_IOS_BASE_FAILURE; - pub const FILESYSTEM_ERROR: u32 = CM_ERROR_CM_ERROR_FILESYSTEM_ERROR; - pub const ATOMIC_TX_ERROR: u32 = CM_ERROR_CM_ERROR_ATOMIC_TX_ERROR; - pub const NONEXISTING_LOCAL_TIME: u32 = CM_ERROR_CM_ERROR_NONEXISTING_LOCAL_TIME; - pub const AMBIGOUS_LOCAL_TIME: u32 = CM_ERROR_CM_ERROR_AMBIGUOUS_LOCAL_TIME; - pub const FORMAT_ERROR: u32 = CM_ERROR_CM_ERROR_FORMAT_ERROR; - pub const RUNTIME_ERROR_END: u32 = CM_ERROR_CM_RUNTIME_ERROR_END; + pub const RUNTIME_ERROR: i32 = CM_ERROR_RUNTIME_ERROR; + pub const RANGE_ERROR: i32 = CM_ERROR_RANGE_ERROR; + pub const OVERFLOW_ERROR: i32 = CM_ERROR_OVERFLOW_ERROR; + pub const UNDERFLOW_ERROR: i32 = CM_ERROR_UNDERFLOW_ERROR; + pub const REGEX_ERROR: i32 = CM_ERROR_REGEX_ERROR; + pub const SYSTEM_ERROR: i32 = CM_ERROR_SYSTEM_ERROR; // Other errors - pub const BAD_TYPEID: u32 = CM_ERROR_CM_ERROR_BAD_TYPEID; - pub const BAD_CAST: u32 = CM_ERROR_CM_ERROR_BAD_CAST; - pub const BAD_ANY_CAST: u32 = CM_ERROR_CM_ERROR_BAD_ANY_CAST; - pub const BAD_WEAK_PTR: u32 = CM_ERROR_CM_ERROR_BAD_WEAK_PTR; - pub const BAD_FUNCTION_CALL: u32 = CM_ERROR_CM_ERROR_BAD_FUNCTION_CALL; - pub const BAD_ALLOC: u32 = CM_ERROR_CM_ERROR_BAD_ALLOC; - pub const BAD_ARRAY_NEW_LENGTH: u32 = CM_ERROR_CM_ERROR_BAD_ARRAY_NEW_LENGTH; - pub const BAD_EXCEPTION: u32 = CM_ERROR_CM_ERROR_BAD_EXCEPTION; - pub const BAD_VARIANT_ACCESS: u32 = CM_ERROR_CM_ERROR_BAD_VARIANT_ACCESS; - pub const EXCEPTION: u32 = CM_ERROR_CM_ERROR_EXCEPTION; - pub const OTHER_ERROR_END: u32 = CM_ERROR_CM_OTHER_ERROR_END; + pub const BAD_TYPEID: i32 = CM_ERROR_BAD_TYPEID; + pub const BAD_CAST: i32 = CM_ERROR_BAD_CAST; + pub const BAD_ANY_CAST: i32 = CM_ERROR_BAD_ANY_CAST; + pub const BAD_WEAK_PTR: i32 = CM_ERROR_BAD_WEAK_PTR; + pub const BAD_FUNCTION_CALL: i32 = CM_ERROR_BAD_FUNCTION_CALL; + pub const BAD_ALLOC: i32 = CM_ERROR_BAD_ALLOC; + pub const BAD_ARRAY_NEW_LENGTH: i32 = CM_ERROR_BAD_ARRAY_NEW_LENGTH; + pub const BAD_EXCEPTION: i32 = CM_ERROR_BAD_EXCEPTION; + pub const BAD_VARIANT_ACCESS: i32 = CM_ERROR_BAD_VARIANT_ACCESS; + pub const EXCEPTION: i32 = CM_ERROR_EXCEPTION; // C API Errors - pub const UNKNOWN: u32 = CM_ERROR_CM_ERROR_UNKNOWN; + pub const UNKNOWN: i32 = CM_ERROR_UNKNOWN; } diff --git a/machine/rust-bindings/cartesi-machine/src/lib.rs b/machine/rust-bindings/cartesi-machine/src/lib.rs index 39848d0a..847c5aea 100644 --- a/machine/rust-bindings/cartesi-machine/src/lib.rs +++ b/machine/rust-bindings/cartesi-machine/src/lib.rs @@ -3,21 +3,22 @@ #![doc = include_str!("../README.md")] -pub mod configuration; -pub mod errors; +// pub mod configuration; -pub mod hash; -pub mod machine; +mod constants; +pub use constants::*; +pub mod machine2; + +pub mod errors; // TODO: review -pub mod log; -pub mod proof; +// pub mod log; +// pub mod hash; +// pub mod proof; -mod constants; mod utils; -pub use constants::*; -pub use machine::Machine; +// pub use machine::Machine; // Reexport inner cartesi-machine-sys pub use cartesi_machine_sys; diff --git a/machine/rust-bindings/cartesi-machine/src/machine2.rs b/machine/rust-bindings/cartesi-machine/src/machine2.rs new file mode 100644 index 00000000..39ccf6ae --- /dev/null +++ b/machine/rust-bindings/cartesi-machine/src/machine2.rs @@ -0,0 +1,18 @@ +use std::path::Path; + +/// Machine instance handle +pub struct Machine { + pub machine: *mut cartesi_machine_sys::cm_machine, +} + +impl Drop for Machine { + fn drop(&mut self) { + unsafe { + cartesi_machine_sys::cm_delete(self.machine); + } + } +} + +impl Machine { + fn x() {} +}