diff --git a/machine-bindings/cartesi-machine-sys/src/headers/machine-c-api.h b/machine-bindings/cartesi-machine-sys/src/headers/machine-c-api.h index c3775425..91c41bbd 100644 --- a/machine-bindings/cartesi-machine-sys/src/headers/machine-c-api.h +++ b/machine-bindings/cartesi-machine-sys/src/headers/machine-c-api.h @@ -23,7 +23,6 @@ #include #include #else -#include #include #include #endif @@ -69,7 +68,7 @@ typedef enum { // NOLINT(modernize-use-using) CM_ERROR_FILESYSTEM_ERROR, CM_ERROR_ATOMIC_TX_ERROR, CM_ERROR_NONEXISTING_LOCAL_TIME, - CM_ERROR_AMBIGOUS_LOCAL_TIME, + CM_ERROR_AMBIGUOUS_LOCAL_TIME, CM_ERROR_FORMAT_ERROR, CM_RUNTIME_ERROR_END, // Other errors @@ -94,6 +93,7 @@ typedef enum { // NOLINT(modernize-use-using) CM_BREAK_REASON_HALTED, CM_BREAK_REASON_YIELDED_MANUALLY, CM_BREAK_REASON_YIELDED_AUTOMATICALLY, + CM_BREAK_REASON_YIELDED_SOFTLY, CM_BREAK_REASON_REACHED_TARGET_MCYCLE } CM_BREAK_REASON; @@ -129,7 +129,10 @@ typedef enum { // NOLINT(modernize-use-using) CM_PROC_SENVCFG, CM_PROC_ILRSC, CM_PROC_IFLAGS, + CM_PROC_IUNREP, CM_PROC_CLINT_MTIMECMP, + CM_PROC_PLIC_GIRQPEND, + CM_PROC_PLIC_GIRQSRVD, CM_PROC_HTIF_TOHOST, CM_PROC_HTIF_FROMHOST, CM_PROC_HTIF_IHALT, @@ -181,6 +184,7 @@ typedef struct { // NOLINT(modernize-use-using) uint64_t senvcfg; ///< Value of senvcfg CSR uint64_t ilrsc; ///< Value of ilrsc CSR uint64_t iflags; ///< Value of iflags CSR + uint64_t iunrep; ///< Value of iunrep CSR } cm_processor_config; /// \brief RAM state configuration @@ -221,6 +225,12 @@ typedef struct { // NOLINT(modernize-use-using) uint64_t mtimecmp; ///< Value of mtimecmp CSR } cm_clint_config; +/// \brief PLIC device state configuration +typedef struct { // NOLINT(modernize-use-using) + uint64_t girqpend; ///< Value of girqpend CSR + uint64_t girqsrvd; ///< Value of girqsrvd CSR +} cm_plic_config; + /// \brief HTIF device state configuration typedef struct { // NOLINT(modernize-use-using) uint64_t fromhost; ///< Value of fromhost CSR @@ -230,11 +240,74 @@ typedef struct { // NOLINT(modernize-use-using) bool yield_automatic; ///< Make yield automatic available? } cm_htif_config; +/// \brief VirtIO device type +typedef enum { // NOLINT(modernize-use-using) + CM_VIRTIO_DEVICE_CONSOLE, + CM_VIRTIO_DEVICE_P9FS, + CM_VIRTIO_DEVICE_NET_USER, + CM_VIRTIO_DEVICE_NET_TUNTAP +} CM_VIRTIO_DEVICE_TYPE; + +/// \brief VirtIO Plan 9 filesystem device state configuration +typedef struct { // NOLINT(modernize-use-using) + const char *tag; ///< Guest mount tag + const char *host_directory; ///< Path to the host shared directory +} cm_virtio_p9fs_config; + +/// \brief VirtIO host forward state config +typedef struct cm_virtio_hostfwd_config { // NOLINT(modernize-use-using) + bool is_udp; + uint64_t host_ip; + uint64_t guest_ip; + uint16_t host_port; + uint16_t guest_port; +} cm_virtio_hostfwd_config; + +/// \brief VirtIO host forward configuration array +typedef struct { // NOLINT(modernize-use-using) + cm_virtio_hostfwd_config *entry; + size_t count; +} cm_virtio_hostfwd_config_array; + +/// \brief VirtIO user network device state configuration +typedef struct { // NOLINT(modernize-use-using) + cm_virtio_hostfwd_config_array hostfwd; +} cm_virtio_net_user_config; + +/// \brief VirtIO TUN/TAP network device state configuration +typedef struct { // NOLINT(modernize-use-using) + const char *iface; ///< Host's tap network interface (e.g "tap0") +} cm_virtio_net_tuntap_config; + +/// \brief VirtIO device union +typedef union { // NOLINT(modernize-use-using) + cm_virtio_p9fs_config p9fs; ///< Plan 9 filesystem + cm_virtio_net_user_config net_user; ///< User-mode networking + cm_virtio_net_tuntap_config net_tuntap; ///< TUN/TAP networking +} cm_virtio_device_config_union; + +/// \brief VirtIO device state configuration +typedef struct { // NOLINT(modernize-use-using) + CM_VIRTIO_DEVICE_TYPE type; ///< VirtIO device type + cm_virtio_device_config_union device; ///< VirtIO device config +} cm_virtio_device_config; + +/// \brief VirtIO device configuration array +typedef struct { // NOLINT(modernize-use-using) + cm_virtio_device_config *entry; + size_t count; +} cm_virtio_config_array; + +/// \brief CMIO buffer configuration +typedef struct { // NOLINT(modernize-use-using) + bool shared; ///< Target changes to range affect image file? + const char *image_filename; ///< Memory range image file name +} cm_cmio_buffer_config; + /// \brief Cmio state configuration -typedef struct { // NOLINT(modernize-use-using) - bool has_value; ///< Represents whether the rest of the struct have been filled - cm_memory_range_config rx_buffer; ///< RX buffer memory range - cm_memory_range_config tx_buffer; ///< TX buffer memory range +typedef struct { // NOLINT(modernize-use-using) + cm_cmio_buffer_config rx_buffer; ///< RX buffer configuration + cm_cmio_buffer_config tx_buffer; ///< TX buffer configuration } cm_cmio_config; /// \brief microarchitecture RAM configuration @@ -264,7 +337,9 @@ typedef struct { // NOLINT(modernize-use-using) cm_memory_range_config_array flash_drive; cm_tlb_config tlb; cm_clint_config clint; + cm_plic_config plic; cm_htif_config htif; + cm_virtio_config_array virtio; cm_cmio_config cmio; cm_uarch_config uarch; } cm_machine_config; @@ -363,7 +438,9 @@ typedef struct { // NOLINT(modernize-use-using) cm_concurrency_runtime_config concurrency; cm_htif_runtime_config htif; bool skip_root_hash_check; + bool skip_root_hash_store; bool skip_version_check; + bool soft_yield; } cm_machine_runtime_config; /// \brief Machine instance handle @@ -664,6 +741,17 @@ CM_API int cm_read_virtual_memory(const cm_machine *m, uint64_t address, unsigne CM_API int cm_write_virtual_memory(cm_machine *m, uint64_t address, const unsigned char *data, size_t length, char **err_msg); +/// \brief Translates a virtual memory address to its corresponding physical memory address. +/// \param m Pointer to valid machine instance +/// \param vaddr Virtual address to translate. +/// \param paddr Receives the physical memory address. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_translate_virtual_address(cm_machine *m, uint64_t vaddr, uint64_t *paddr, char **err_msg); + /// \brief Reads the value of a general-purpose register. /// \param m Pointer to valid machine instance /// \param i Register index. Between 0 and X_REG_COUNT-1, inclusive. @@ -1297,6 +1385,26 @@ CM_API uint64_t cm_packed_iflags(int PRV, int X, int Y, int H); /// \returns 0 for success, non zero code for error CM_API int cm_write_iflags(cm_machine *m, uint64_t val, char **err_msg); +/// \brief Reads the value of the iunrep register. +/// \param m Pointer to valid machine instance +/// \param val Receives value of the register. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_read_iunrep(const cm_machine *m, uint64_t *val, char **err_msg); + +/// \brief Writes the value of the iunrep register. +/// \param m Pointer to valid machine instance +/// \param val New register value. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_write_iunrep(cm_machine *m, uint64_t val, char **err_msg); + /// \brief Reads the value of HTIF's tohost register. /// \param m Pointer to valid machine instance /// \param val Receives value of the register. @@ -1457,6 +1565,46 @@ CM_API int cm_read_clint_mtimecmp(const cm_machine *m, uint64_t *val, char **err /// \returns 0 for success, non zero code for error CM_API int cm_write_clint_mtimecmp(cm_machine *m, uint64_t val, char **err_msg); +/// \brief Reads the value of PLIC's girqpend register. +/// \param m Pointer to valid machine instance +/// \param val Receives value of the register. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_error_message. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_read_plic_girqpend(const cm_machine *m, uint64_t *val, char **err_msg); + +/// \brief Writes the value of PLIC's girqpend register. +/// \param m Pointer to valid machine instance +/// \param val New register value. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_error_message. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_write_plic_girqpend(cm_machine *m, uint64_t val, char **err_msg); + +/// \brief Reads the value of PLIC's girqsrvd register. +/// \param m Pointer to valid machine instance +/// \param val Receives value of the register. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_error_message. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_read_plic_girqsrvd(const cm_machine *m, uint64_t *val, char **err_msg); + +/// \brief Writes the value of PLIC's girqsrvd register. +/// \param m Pointer to valid machine instance +/// \param val New register value. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_error_message. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_write_plic_girqsrvd(cm_machine *m, uint64_t val, char **err_msg); + /// \brief Checks the value of the iflags_X flag. /// \param m Pointer to valid machine instance /// \param val Receives the flag value @@ -1621,7 +1769,15 @@ CM_API int cm_destroy(cm_machine *m, char **err_msg); /// \returns 0 for success, non zero code for error CM_API int cm_snapshot(cm_machine *m, char **err_msg); -/// \brief Performs rollback +/// \brief Performs commit of the machine, discarding last snapshot. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successful function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring. +/// err_msg can be NULL, meaning the error message won't be received. +/// \returns 0 for success, non zero code for error +CM_API int cm_commit(cm_machine *m, char **err_msg); + +/// \brief Performs rollback of the machine, restoring last snapshot. /// \param err_msg Receives the error message if function execution fails /// or NULL in case of successful function execution. In case of failure error_msg /// must be deleted by the function caller using cm_delete_cstring. @@ -1695,7 +1851,7 @@ CM_API int cm_write_uarch_cycle(cm_machine *m, uint64_t val, char **err_msg); /// \param m Pointer to valid machine instance /// \param val Receives value of the halt flag. /// \param err_msg Receives the error message if function execution fails -/// or NULL in case of successfull function execution. In case of failure error_msg +/// or NULL in case of successful function execution. In case of failure error_msg /// must be deleted by the function caller using cm_delete_cstring /// \returns 0 for success, non zero code for error CM_API int cm_read_uarch_halt_flag(const cm_machine *m, bool *val, char **err_msg); @@ -1703,15 +1859,15 @@ CM_API int cm_read_uarch_halt_flag(const cm_machine *m, bool *val, char **err_ms /// \brief Sets the value of the microarchitecture halt flag. /// \param m Pointer to valid machine instance /// \param err_msg Receives the error message if function execution fails -/// or NULL in case of successfull function execution. In case of failure error_msg +/// or NULL in case of successful function execution. In case of failure error_msg /// must be deleted by the function caller using cm_delete_cstring /// \returns 0 for success, non zero code for error CM_API int cm_set_uarch_halt_flag(cm_machine *m, char **err_msg); -/// \brief Resets the value of the microarchitecture halt flag. +/// \brief Resets the entire uarch state to pristine values. /// \param m Pointer to valid machine instance /// \param err_msg Receives the error message if function execution fails -/// or NULL in case of successfull function execution. In case of failure error_msg +/// or NULL in case of successful function execution. In case of failure error_msg /// must be deleted by the function caller using cm_delete_cstring /// \returns 0 for success, non zero code for error CM_API int cm_reset_uarch(cm_machine *m, char **err_msg); @@ -1722,7 +1878,7 @@ CM_API int cm_reset_uarch(cm_machine *m, char **err_msg); /// \param one_based Use 1-based indices when reporting errors. /// \param access_log Receives the state access log. /// \param err_msg Receives the error message if function execution fails -/// or NULL in case of successfull function execution. In case of failure error_msg +/// or NULL in case of successful function execution. In case of failure error_msg /// must be deleted by the function caller using cm_delete_cstring /// \returns 0 for success, non zero code for error CM_API int cm_log_uarch_reset(cm_machine *m, cm_access_log_type log_type, bool one_based, cm_access_log **access_log, @@ -1757,6 +1913,64 @@ CM_API int cm_get_memory_ranges(cm_machine *m, cm_memory_range_descr_array **mrd /// \returns void CM_API void cm_delete_memory_range_descr_array(cm_memory_range_descr_array *mrda); +/// \brief Sends cmio response +/// \param m Pointer to valid machine instance +/// \param reason Reason for sending the response. +/// \param data Response data to send +/// \param length Length of response data. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successfull function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring +/// \returns 0 for success, non zero code for error +CM_API int cm_send_cmio_response(cm_machine *m, uint16_t reason, const unsigned char *data, size_t length, + char **err_msg); + +/// \brief Send cmio response and returns an access log +/// \param m Pointer to valid machine instance +/// \param reason Reason for sending the response. +/// \param data Response data to send. +/// \param length Length of response data. +/// \param log_type Type of access log to generate. +/// \param one_based Use 1-based indices when reporting errors. +/// \param access_log Receives the state access log. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successfull function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring +/// \returns 0 for success, non zero code for error +CM_API int cm_log_send_cmio_response(cm_machine *m, uint16_t reason, const unsigned char *data, size_t length, + cm_access_log_type log_type, bool one_based, cm_access_log **access_log, char **err_msg); + +/// \brief Checks the internal consistency of an access log produced by cm_send_cmio_response +/// \param reason Reason for sending the response. +/// \param data The response sent when the log was generated. +/// \param length Length of response. +/// \param log State access log to be verified. +/// \param runtime_config Runtime configuration of the machine. +/// \param one_based Use 1-based indices when reporting errors. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successfull function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring +/// \returns 0 for success, non zero code for error +CM_API int cm_verify_send_cmio_response_log(uint16_t reason, const unsigned char *data, size_t length, + const cm_access_log *log, const cm_machine_runtime_config *runtime_config, bool one_based, char **err_msg); + +/// \brief Checks the validity of state transitions caused by cm_send_cmio_response +/// \param reason Reason for sending the response. +/// \param data The response sent when the log was generated. +/// \param length Length of response +/// \param root_hash_before State hash before load. +/// \param log State access log to be verified. +/// \param root_hash_after State hash after load. +/// \param runtime_config Runtime configuration of the machine. +/// \param one_based Use 1-based indices when reporting errors. +/// \param err_msg Receives the error message if function execution fails +/// or NULL in case of successfull function execution. In case of failure error_msg +/// must be deleted by the function caller using cm_delete_cstring +/// \returns 0 for success, non zero code for error +CM_API int cm_verify_send_cmio_response_state_transition(uint16_t reason, const unsigned char *data, size_t length, + const cm_hash *root_hash_before, const cm_access_log *log, const cm_hash *root_hash_after, + const cm_machine_runtime_config *runtime_config, bool one_based, char **err_msg); + #ifdef __cplusplus } #endif diff --git a/machine-bindings/cartesi-machine-sys/src/headers/machine-c-defines.h b/machine-bindings/cartesi-machine-sys/src/headers/machine-c-defines.h index bbb9820d..b899e1b3 100644 --- a/machine-bindings/cartesi-machine-sys/src/headers/machine-c-defines.h +++ b/machine-bindings/cartesi-machine-sys/src/headers/machine-c-defines.h @@ -27,10 +27,12 @@ #define CM_MACHINE_F_REG_COUNT 32 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) #define CM_MACHINE_UARCH_X_REG_COUNT 32 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) -#define CM_TREE_LOG2_WORD_SIZE 3 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) -#define CM_TREE_LOG2_PAGE_SIZE 12 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) -#define CM_TREE_LOG2_ROOT_SIZE 64 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) -#define CM_FLASH_DRIVE_CONFIGS_MAX_SIZE 8 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) +#define CM_TREE_LOG2_WORD_SIZE 3 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) +#define CM_TREE_LOG2_PAGE_SIZE 12 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) +#define CM_TREE_LOG2_ROOT_SIZE 64 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) +#define CM_FLASH_DRIVE_CONFIGS_MAX_SIZE 8 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) +#define CM_VIRTIO_CONFIGS_MAX_SIZE 16 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) +#define CM_VIRTIO_HOSTFWD_CONFIGS_MAX_SIZE 16 // NOLINT(cppcoreguidelines-macro-usage, modernize-macro-to-enum) #include "machine-c-version.h" diff --git a/machine-bindings/cartesi-machine-sys/src/headers/machine-c-version.h b/machine-bindings/cartesi-machine-sys/src/headers/machine-c-version.h index 54a843b4..96dff037 100644 --- a/machine-bindings/cartesi-machine-sys/src/headers/machine-c-version.h +++ b/machine-bindings/cartesi-machine-sys/src/headers/machine-c-version.h @@ -18,11 +18,11 @@ #define MACHINE_EMULATOR_SDK_MACHINE_C_VERSION_H // NOLINTBEGIN -#define CM_MARCHID 15 +#define CM_MARCHID 17 #define CM_VERSION_MAJOR 0 -#define CM_VERSION_MINOR 15 -#define CM_VERSION_PATCH 2 +#define CM_VERSION_MINOR 17 +#define CM_VERSION_PATCH 0 #define CM_VERSION_LABEL "" #define _CM_STR_HELPER(x) #x diff --git a/machine-bindings/cartesi-machine/src/configuration.rs b/machine-bindings/cartesi-machine/src/configuration.rs index 7ec01f4b..28cf38cc 100644 --- a/machine-bindings/cartesi-machine/src/configuration.rs +++ b/machine-bindings/cartesi-machine/src/configuration.rs @@ -2,150 +2,6 @@ use crate::ffi::{free_cstr, from_cstr, to_cstr}; -#[repr(C)] -#[derive(Debug, Clone)] -/// Processor state configuration -pub struct ProcessorConfig { - /// General purpose registers - pub x: [u64; 32usize], - /// Floating point registers - pub f: [u64; 32usize], - /// Program counter - pub pc: u64, - /// Floating point control and status register - pub fcsr: u64, - /// Vendor ID - pub mvendorid: u64, - /// Architecture ID - pub marchid: u64, - /// Implementation ID - pub mimpid: u64, - /// Machine cycle - pub mcycle: u64, - /// Machine instruction cycle - pub icycleinstret: u64, - /// Machine status - pub mstatus: u64, - /// Machine Trap Vector - pub mtvec: u64, - /// Machine Scratch - pub mscratch: u64, - /// Machine Exception Program Counter - pub mepc: u64, - /// Machine Cause - pub mcause: u64, - /// Machine Trap Value - pub mtval: u64, - /// Machine ISA - pub misa: u64, - /// Machine Interrupt Enable - pub mie: u64, - /// Machine Interrupt Pending - pub mip: u64, - /// Machine Exception Delegation - pub medeleg: u64, - /// Machine Interrupt Delegation - pub mideleg: u64, - /// Machine Counter Enable - pub mcounteren: u64, - /// Machine Environment Configuration - pub menvcfg: u64, - /// Supervisor Trap Vector - pub stvec: u64, - /// Supervisor Scratch - pub sscratch: u64, - /// Supervisor Exception Program Counter - pub sepc: u64, - /// Supervisor Cause - pub scause: u64, - /// Supervisor Trap Value - pub stval: u64, - /// Supervisor Address Translation and Protection - pub satp: u64, - /// Supervisor Interrupt Enable - pub scounteren: u64, - /// Supervisor Environment Configuration - pub senvcfg: u64, - /// Illegal Load Reserved Status - pub ilrsc: u64, - /// Interrupt Flags - pub iflags: u64, -} - -impl From for cartesi_machine_sys::cm_processor_config { - fn from(config: ProcessorConfig) -> Self { - unsafe { std::mem::transmute(config) } - } -} - -impl From for ProcessorConfig { - fn from(config: cartesi_machine_sys::cm_processor_config) -> Self { - unsafe { std::mem::transmute(config) } - } -} - -/// RAM state configuration -#[derive(Debug, Clone)] -pub struct RamConfig { - /// RAM length - pub length: u64, - /// RAM image file name - pub image_filename: Option, -} - -impl From for cartesi_machine_sys::cm_ram_config { - fn from(config: RamConfig) -> Self { - Self { - length: config.length, - image_filename: to_cstr(config.image_filename), - } - } -} - -impl From for RamConfig { - fn from(config: cartesi_machine_sys::cm_ram_config) -> Self { - Self { - length: config.length, - image_filename: from_cstr(config.image_filename), - } - } -} - -/// DTB state configuration -#[derive(Debug, Clone)] -pub struct DtbConfig { - /// Bootargs to pass to kernel - pub bootargs: Option, - /// Initialization commands to be executed as root on boot - pub init: Option, - /// Commands to execute the main application - pub entrypoint: Option, - /// ROM image file - pub image_filename: Option, -} - -impl From for cartesi_machine_sys::cm_dtb_config { - fn from(config: DtbConfig) -> Self { - Self { - bootargs: to_cstr(config.bootargs), - init: to_cstr(config.init), - entrypoint: to_cstr(config.entrypoint), - image_filename: to_cstr(config.image_filename), - } - } -} - -impl From for DtbConfig { - fn from(config: cartesi_machine_sys::cm_dtb_config) -> Self { - Self { - bootargs: from_cstr(config.bootargs), - init: from_cstr(config.init), - entrypoint: from_cstr(config.entrypoint), - image_filename: from_cstr(config.image_filename), - } - } -} - /// Memory range configuration #[derive(Debug, Clone)] pub struct MemoryRangeConfig { @@ -181,49 +37,6 @@ impl From for MemoryRangeConfig { } } -/// TLB configuration -#[derive(Debug, Clone)] -pub struct TlbConfig { - /// TLB image file name - pub image_filename: Option, -} - -impl From for cartesi_machine_sys::cm_tlb_config { - fn from(config: TlbConfig) -> Self { - Self { - image_filename: to_cstr(config.image_filename), - } - } -} - -impl From for TlbConfig { - fn from(config: cartesi_machine_sys::cm_tlb_config) -> Self { - Self { - image_filename: from_cstr(config.image_filename), - } - } -} - -/// CLint configuration -#[derive(Debug, Clone)] -#[repr(C)] -pub struct ClintConfig { - /// Value of mtimecmp CSR - pub mtimecmp: u64, -} - -impl From for cartesi_machine_sys::cm_clint_config { - fn from(config: ClintConfig) -> Self { - unsafe { std::mem::transmute(config) } - } -} - -impl From for ClintConfig { - fn from(config: cartesi_machine_sys::cm_clint_config) -> Self { - unsafe { std::mem::transmute(config) } - } -} - /// Htif configuration #[derive(Debug, Clone)] #[repr(C)] @@ -252,231 +65,6 @@ impl From for HtifConfig { } } -/// Rollup configuration -#[derive(Debug, Clone)] -pub struct RollupConfig { - /// Represents whether the rest of the struct have been filled - pub has_value: bool, - /// RX buffer memory range - pub rx_buffer: MemoryRangeConfig, - /// TX buffer memory range - pub tx_buffer: MemoryRangeConfig, -} - -impl From for cartesi_machine_sys::cm_cmio_config { - fn from(config: RollupConfig) -> Self { - Self { - has_value: config.has_value, - rx_buffer: config.rx_buffer.into(), - tx_buffer: config.tx_buffer.into(), - } - } -} - -impl From for RollupConfig { - fn from(config: cartesi_machine_sys::cm_cmio_config) -> Self { - Self { - has_value: config.has_value, - rx_buffer: config.rx_buffer.into(), - tx_buffer: config.tx_buffer.into(), - } - } -} - -/// Uarch RAM configuration -#[derive(Debug, Clone)] -pub struct UarchRamConfig { - /// RAM image file name - pub image_filename: Option, -} - -impl From for cartesi_machine_sys::cm_uarch_ram_config { - fn from(config: UarchRamConfig) -> Self { - Self { - image_filename: to_cstr(config.image_filename), - } - } -} - -impl From for UarchRamConfig { - fn from(config: cartesi_machine_sys::cm_uarch_ram_config) -> Self { - Self { - image_filename: from_cstr(config.image_filename), - } - } -} - -/// Uarch Processor configuration -#[derive(Debug, Clone)] -#[repr(C)] -pub struct UarchProcessorConfig { - /// General purpose registers - pub x: [u64; 32usize], - /// Program counter - pub pc: u64, - /// Machine cycle - pub cycle: u64, - /// Halt flag - pub halt_flag: bool, -} - -impl From for cartesi_machine_sys::cm_uarch_processor_config { - fn from(config: UarchProcessorConfig) -> Self { - unsafe { std::mem::transmute(config) } - } -} - -impl From for UarchProcessorConfig { - fn from(config: cartesi_machine_sys::cm_uarch_processor_config) -> Self { - unsafe { std::mem::transmute(config) } - } -} - -/// Uarch configuration -#[derive(Debug, Clone)] -pub struct UarchConfig { - /// Processor configuration - pub processor: UarchProcessorConfig, - /// RAM configuration - pub ram: UarchRamConfig, -} - -impl From for cartesi_machine_sys::cm_uarch_config { - fn from(config: UarchConfig) -> Self { - Self { - processor: config.processor.into(), - ram: config.ram.into(), - } - } -} - -impl From for UarchConfig { - fn from(config: cartesi_machine_sys::cm_uarch_config) -> Self { - Self { - processor: config.processor.into(), - ram: config.ram.into(), - } - } -} - -/// Machine configuration -#[derive(Debug, Clone)] -pub struct MachineConfig { - /// Processor configuration - pub processor: ProcessorConfig, - /// RAM configuration - pub ram: RamConfig, - /// DTB configuration - pub dtb: DtbConfig, - /// Flash drive configuration - pub flash_drive: Vec, - /// TLB configuration - pub tlb: TlbConfig, - /// CLint configuration - pub clint: ClintConfig, - /// Htif configuration - pub htif: HtifConfig, - /// Rollup configuration - pub rollup: RollupConfig, - /// Uarch configuration - pub uarch: UarchConfig, -} - -impl From for OwnedMachineConfig { - fn from(config: MachineConfig) -> Self { - let count = config.flash_drive.len(); - let leaked_entry = Box::leak( - config - .flash_drive - .into_iter() - .map(|x| x.into()) - .collect::>() - .into_boxed_slice(), - ); - let entry: *mut cartesi_machine_sys::cm_memory_range_config = leaked_entry.as_mut_ptr(); - let flash_drive = cartesi_machine_sys::cm_memory_range_config_array { entry, count }; - - let config = cartesi_machine_sys::cm_machine_config { - processor: config.processor.into(), - ram: config.ram.into(), - dtb: config.dtb.into(), - flash_drive, - tlb: config.tlb.into(), - clint: config.clint.into(), - htif: config.htif.into(), - cmio: config.rollup.into(), - uarch: config.uarch.into(), - }; - - Self(config) - } -} - -impl From for MachineConfig { - fn from(value: cartesi_machine_sys::cm_machine_config) -> Self { - Self { - processor: value.processor.into(), - ram: value.ram.into(), - dtb: value.dtb.into(), - flash_drive: unsafe { - std::slice::from_raw_parts( - value.flash_drive.entry, - value.flash_drive.count as usize, - ) - .into_iter() - .map(|x| x.clone().into()) - .collect() - }, - tlb: value.tlb.into(), - clint: value.clint.into(), - htif: value.htif.into(), - rollup: value.cmio.into(), - uarch: value.uarch.into(), - } - } -} - -impl Default for MachineConfig { - fn default() -> Self { - unsafe { - let raw_config = cartesi_machine_sys::cm_new_default_machine_config(); - let config = MachineConfig::from(*raw_config); - cartesi_machine_sys::cm_delete_machine_config(raw_config); - config - } - } -} - -/// A machine configuration that is owned by Rust and should be dropped in another way. -pub struct OwnedMachineConfig(cartesi_machine_sys::cm_machine_config); - -impl AsRef for OwnedMachineConfig { - fn as_ref(&self) -> &cartesi_machine_sys::cm_machine_config { - &self.0 - } -} - -impl Drop for OwnedMachineConfig { - fn drop(&mut self) { - free_cstr(self.0.ram.image_filename); - free_cstr(self.0.dtb.bootargs); - free_cstr(self.0.dtb.init); - free_cstr(self.0.dtb.entrypoint); - free_cstr(self.0.dtb.image_filename); - free_cstr(self.0.tlb.image_filename); - free_cstr(self.0.cmio.rx_buffer.image_filename); - free_cstr(self.0.cmio.tx_buffer.image_filename); - free_cstr(self.0.uarch.ram.image_filename); - - unsafe { - drop(Box::from_raw(std::slice::from_raw_parts_mut( - self.0.flash_drive.entry, - self.0.flash_drive.count as usize, - ))) - } - } -} - #[derive(Debug, Default, Clone)] #[repr(C)] pub struct ConcurrencyRuntimeConfig { @@ -519,7 +107,9 @@ pub struct RuntimeConfig { pub concurrency: ConcurrencyRuntimeConfig, pub htif: HtifRuntimeConfig, pub skip_root_hash_check: bool, + pub skip_root_hash_store: bool, pub skip_version_check: bool, + pub soft_yield: bool, } impl From for cartesi_machine_sys::cm_machine_runtime_config { diff --git a/machine-bindings/cartesi-machine/src/errors.rs b/machine-bindings/cartesi-machine/src/errors.rs index 6b61389c..9ca13f80 100644 --- a/machine-bindings/cartesi-machine/src/errors.rs +++ b/machine-bindings/cartesi-machine/src/errors.rs @@ -26,7 +26,7 @@ pub enum ErrorCode { FilesystemError = CM_ERROR_CM_ERROR_FILESYSTEM_ERROR as isize, AtomicTxError = CM_ERROR_CM_ERROR_ATOMIC_TX_ERROR as isize, NonexistingLocalTime = CM_ERROR_CM_ERROR_NONEXISTING_LOCAL_TIME as isize, - AmbigousLocalTime = CM_ERROR_CM_ERROR_AMBIGOUS_LOCAL_TIME as isize, + AmbigousLocalTime = CM_ERROR_CM_ERROR_AMBIGUOUS_LOCAL_TIME as isize, FormatError = CM_ERROR_CM_ERROR_FORMAT_ERROR as isize, RuntimeErrorEnd = CM_ERROR_CM_RUNTIME_ERROR_END as isize, BadTypeid = CM_ERROR_CM_ERROR_BAD_TYPEID as isize, diff --git a/machine-bindings/cartesi-machine/src/lib.rs b/machine-bindings/cartesi-machine/src/lib.rs index 46d8248a..0f0685f2 100644 --- a/machine-bindings/cartesi-machine/src/lib.rs +++ b/machine-bindings/cartesi-machine/src/lib.rs @@ -13,8 +13,8 @@ pub mod log; pub mod proof; use cartesi_machine_sys::{cm_machine_runtime_config, cm_memory_range_config}; -use configuration::{free_cm_memory_range_config_cstr, OwnedMachineConfig}; -use configuration::{MachineConfig, RuntimeConfig}; +use configuration::{free_cm_memory_range_config_cstr}; +use configuration::{RuntimeConfig}; use errors::{ErrorCollector, MachineError}; macro_rules! read_csr { @@ -169,33 +169,6 @@ impl Drop for Machine { } impl Machine { - /// Create new machine instance from configuration - pub fn create( - machine_config: MachineConfig, - runtime: RuntimeConfig, - ) -> Result { - let mut error_collector = ErrorCollector::new(); - let mut machine = Machine { - machine: std::ptr::null_mut(), - }; - - unsafe { - let config = OwnedMachineConfig::from(machine_config); - let runtime = cm_machine_runtime_config::from(runtime); - - let result = cartesi_machine_sys::cm_create_machine( - config.as_ref(), - &runtime, - &mut machine.machine, - &mut error_collector.as_mut_ptr(), - ); - - error_collector.collect(result)?; - } - - Ok(machine) - } - /// Create machine instance from previously serialized directory pub fn load(path: &Path, runtime: RuntimeConfig) -> Result { let mut error_collector = ErrorCollector::new(); @@ -552,6 +525,25 @@ impl Machine { Ok(data) } + /// Write a CMIO response + pub fn send_cmio_response(&mut self, reason: u16, data: &[u8]) -> Result<(), MachineError> { + let mut error_collector = ErrorCollector::new(); + + unsafe { + let result = cartesi_machine_sys::cm_send_cmio_response( + self.machine, + reason, + data.as_ptr(), + data.len(), + &mut error_collector.as_mut_ptr(), + ); + + error_collector.collect(result)?; + } + + Ok(()) + } + /// Write a chunk of data to the machine memory. pub fn write_memory(&mut self, address: u64, data: &[u8]) -> Result<(), MachineError> { let mut error_collector = ErrorCollector::new(); @@ -703,53 +695,6 @@ impl Machine { unsafe { cartesi_machine_sys::cm_get_f_address(i as i32) } } - /// Returns copy of initialization config. - pub fn get_initial_config(&mut self) -> Result { - let mut error_collector = ErrorCollector::new(); - let mut config = std::ptr::null(); - - unsafe { - let result = cartesi_machine_sys::cm_get_initial_config( - self.machine, - &mut config, - &mut error_collector.as_mut_ptr(), - ); - - error_collector.collect(result)?; - } - - let new_config: MachineConfig = unsafe { (*config).into() }; - - unsafe { - cartesi_machine_sys::cm_delete_machine_config(config); - } - - Ok(new_config) - } - - /// Returns copy of default system config. - pub fn get_default_config() -> Result { - let mut error_collector = ErrorCollector::new(); - let mut config = std::ptr::null(); - - unsafe { - let result = cartesi_machine_sys::cm_get_default_config( - &mut config, - &mut error_collector.as_mut_ptr(), - ); - - error_collector.collect(result)?; - } - - let new_config: MachineConfig = unsafe { (*config).into() }; - - unsafe { - cartesi_machine_sys::cm_delete_machine_config(config); - } - - Ok(new_config) - } - /// Replaces a memory range pub fn replace_memory_range( &mut self, diff --git a/machine-emulator-sdk b/machine-emulator-sdk index 3219664e..58b6d860 160000 --- a/machine-emulator-sdk +++ b/machine-emulator-sdk @@ -1 +1 @@ -Subproject commit 3219664e92f262b7e03d7251dfb5b27d349a9ca1 +Subproject commit 58b6d8601f6537f5ac505c1a782c8892b146961d diff --git a/offchain/Dockerfile.compute.test b/offchain/Dockerfile.compute.test index 4824b956..52023e17 100644 --- a/offchain/Dockerfile.compute.test +++ b/offchain/Dockerfile.compute.test @@ -4,7 +4,7 @@ ENV CARGO_REGISTRIES_CARTESI_INDEX=https://github.com/cartesi/crates-index RUN rustup component add rustfmt RUN cargo install cargo-chef RUN apt-get update && \ - apt-get install -y clang + apt-get install -y clang libslirp0 FROM chef AS planner WORKDIR /app @@ -25,14 +25,14 @@ RUN cargo chef cook --release --recipe-path recipe.json # Build application COPY --from=ethereum/solc:0.8.23 /usr/bin/solc /usr/bin/solc RUN chmod u+x /usr/bin/solc -COPY --from=cartesi/machine-emulator:0.16.0 /lib/libcartesi* /lib +COPY --from=cartesi/machine-emulator:0.17.0 /lib/libcartesi* /lib COPY ./offchain /app/offchain COPY ./machine-emulator-sdk /app/machine-emulator-sdk COPY ./permissionless-arbitration /app/permissionless-arbitration RUN cargo build --release --bin dave-compute -FROM --platform=linux/amd64 cartesi/machine-emulator:0.16.0 +FROM --platform=linux/amd64 cartesi/machine-emulator:0.17.0 USER root RUN apt-get update && \ diff --git a/permissionless-arbitration/contracts/src/tournament/abstracts/LeafTournament.sol b/permissionless-arbitration/contracts/src/tournament/abstracts/LeafTournament.sol index fdcb6f8c..5b6d71c7 100644 --- a/permissionless-arbitration/contracts/src/tournament/abstracts/LeafTournament.sol +++ b/permissionless-arbitration/contracts/src/tournament/abstracts/LeafTournament.sol @@ -7,8 +7,8 @@ import "./Tournament.sol"; import "../../CanonicalConstants.sol"; import "../../Commitment.sol"; -import "step/ready_src/UArchStep.sol"; -import "step/ready_src/UArchReset.sol"; +import "step/src/UArchStep.sol"; +import "step/src/UArchReset.sol"; /// @notice Leaf tournament is the one that seals leaf match abstract contract LeafTournament is Tournament { diff --git a/permissionless-arbitration/lua_node/Dockerfile b/permissionless-arbitration/lua_node/Dockerfile index 003a3ddd..816ab46d 100644 --- a/permissionless-arbitration/lua_node/Dockerfile +++ b/permissionless-arbitration/lua_node/Dockerfile @@ -1,4 +1,4 @@ -FROM cartesi/machine-emulator:0.16.0 +FROM cartesi/machine-emulator:0.17.0 USER 0 RUN apt-get -y update; apt-get -y install curl git; apt-get install -y procps xxd diff --git a/permissionless-arbitration/measure_constants/Dockerfile b/permissionless-arbitration/measure_constants/Dockerfile index e5406c6b..87e37450 100644 --- a/permissionless-arbitration/measure_constants/Dockerfile +++ b/permissionless-arbitration/measure_constants/Dockerfile @@ -1,4 +1,4 @@ -FROM cartesi/machine-emulator:0.16.0 +FROM cartesi/machine-emulator:0.17.0 USER root RUN apt-get update && \ diff --git a/permissionless-arbitration/measure_constants/program/Dockerfile-bootstrap b/permissionless-arbitration/measure_constants/program/Dockerfile-bootstrap index 23824338..6bc6a0a4 100644 --- a/permissionless-arbitration/measure_constants/program/Dockerfile-bootstrap +++ b/permissionless-arbitration/measure_constants/program/Dockerfile-bootstrap @@ -39,9 +39,9 @@ RUN HOSTNAME=linux SOURCE_DATE_EPOCH=1695938400 genext2fs -z -v -v -f -a /replic RUN ls -al /replicate/source.ext2 RUN rm -rf /replicate/release /replicate/release.tar -COPY --from=cartesi/linux-kernel:0.19.1 /opt/riscv/kernel/artifacts/linux-6.5.9-ctsi-1-v0.19.1.bin /usr/share/cartesi-machine/images/linux.bin +COPY --from=cartesi/linux-kernel:0.20.0 /opt/riscv/kernel/artifacts/linux-6.5.13-ctsi-1-v0.20.0.bin /usr/share/cartesi-machine/images/linux.bin #20231201T000000Z -FROM cartesi/machine-emulator:0.16.0 AS cartesi-base +FROM cartesi/machine-emulator:0.17.0 AS cartesi-base COPY --from=build /replicate/source.ext2 /source.ext2 COPY --from=build /usr/share/cartesi-machine/images /usr/share/cartesi-machine/images USER root