diff --git a/manifest/product_octez.ml b/manifest/product_octez.ml index f2e2634dae360b1ea3781ad7636910cb6b06fa69..e1fb50696b6bf45d9286fc76579c47c0abfcd033 100644 --- a/manifest/product_octez.ml +++ b/manifest/product_octez.ml @@ -5023,10 +5023,15 @@ let _octez_embedded_protocol_packer = let _octez_riscv_pvm_test = tezt - ["test_main"; "test_storage"] + ["test_main"; "test_backend"; "test_storage"; "utils"] ~path:"src/lib_riscv/pvm/test" ~opam:"octez-riscv-pvm-test" ~synopsis:"Tests for RISC-V OCaml API" + ~dep_globs: + [ + "../../../riscv/assets/riscv-dummy.elf"; + "../../../riscv/assets/riscv-dummy.elf.checksum"; + ] ~deps: [ octez_rust_deps; diff --git a/src/lib_riscv/pvm/test/dune b/src/lib_riscv/pvm/test/dune index 8b9bc36a3cbe73cbf80d816686471bfecda579f5..f2661927dbafda3302da2a19294146b00e4ace96 100644 --- a/src/lib_riscv/pvm/test/dune +++ b/src/lib_riscv/pvm/test/dune @@ -22,7 +22,7 @@ -open Tezos_stdlib_unix -open Tezos_base_test_helpers -open Octez_alcotezt) - (modules test_main test_storage)) + (modules test_main test_backend test_storage utils)) (executable (name main) @@ -35,6 +35,9 @@ (rule (alias runtest) (package octez-riscv-pvm-test) + (deps + (glob_files ../../../riscv/assets/riscv-dummy.elf) + (glob_files ../../../riscv/assets/riscv-dummy.elf.checksum)) (enabled_if (<> false %{env:RUNTEZTALIAS=true})) (action (run %{dep:./main.exe} /flaky /ci_disabled))) diff --git a/src/lib_riscv/pvm/test/test_backend.ml b/src/lib_riscv/pvm/test/test_backend.ml new file mode 100644 index 0000000000000000000000000000000000000000..59a1bdad90cab378a0e23bbb1ed0f2b115184cfa --- /dev/null +++ b/src/lib_riscv/pvm/test/test_backend.ml @@ -0,0 +1,25 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Nomadic Labs *) +(* *) +(*****************************************************************************) + +open Octez_riscv_pvm + +let test_advance_dummy_kernel () = + let open Lwt_syntax in + let state = Storage.empty () in + let* kernel = Utils.read_riscv_dummy_kernel () in + let* state = Backend.install_boot_sector state kernel in + let state = Backend.Mutable_state.from_imm state in + + (* This relies on the kernel being able to step at least `sum(step_count)` steps + * without requiring input *) + let step_counts = [1L; 2L; 10L; 100L; 1000L] in + Lwt_list.iter_s + (fun max_steps -> + let* steps = Backend.Mutable_state.compute_step_many ~max_steps state in + assert (steps = max_steps) ; + return_unit) + step_counts diff --git a/src/lib_riscv/pvm/test/test_main.ml b/src/lib_riscv/pvm/test/test_main.ml index c3bbda132722262135e304178804a756ac24b7ff..0675b7e0269508d3da8d3ea8043373bc506eeed2 100644 --- a/src/lib_riscv/pvm/test/test_main.ml +++ b/src/lib_riscv/pvm/test/test_main.ml @@ -1,13 +1,19 @@ (*****************************************************************************) (* *) (* SPDX-License-Identifier: MIT *) -(* Copyright (c) 2023-2024 Nomadic Labs *) +(* Copyright (c) 2023-2025 Nomadic Labs *) (* Copyright (c) 2024 TriliTech *) (* *) (*****************************************************************************) let tests = [ + ( "Backend", + [ + ( "PVM advances the expected number of steps", + `Quick, + Test_backend.test_advance_dummy_kernel ); + ] ); ( "Storage", [ ("Simple test", `Quick, Test_storage.test_simple); diff --git a/src/lib_riscv/pvm/test/utils.ml b/src/lib_riscv/pvm/test/utils.ml new file mode 100644 index 0000000000000000000000000000000000000000..0e666880fc7e4de4ac72e3bb735bea107b7e7cec --- /dev/null +++ b/src/lib_riscv/pvm/test/utils.ml @@ -0,0 +1,20 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(* Get a string pointing to the path of a RISC-V kernel which the RISC-V PVM + * can interpret as an initial boot sector. The PVM will then load the kernel + * directly. This is to bypass origination of large kernels, which is not + * currently supported (RV-109) *) +let read_riscv_kernel (kernel_path : string) (checksum_path : string) = + match String.split_on_char ' ' (read_file checksum_path) with + | checksum :: _ -> Lwt.return ("kernel:" ^ kernel_path ^ ":" ^ checksum) + | _ -> Lwt.fail_with "Kernel found" + +let read_riscv_dummy_kernel () = + read_riscv_kernel + (project_root // "src/riscv/assets/riscv-dummy.elf") + (project_root // "src/riscv/assets/riscv-dummy.elf.checksum") diff --git a/src/riscv/lib/src/ocaml_api.rs b/src/riscv/lib/src/ocaml_api.rs index 051bd1ee5773981441f33b103e81ef4a55e3e9e3..3addf4afd812e8d1d93bbafb537b1621a2d9ee19 100644 --- a/src/riscv/lib/src/ocaml_api.rs +++ b/src/riscv/lib/src/ocaml_api.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023-2024 Nomadic Labs +// SPDX-FileCopyrightText: 2023-2025 Nomadic Labs // SPDX-FileCopyrightText: 2024-2025 TriliTech // // SPDX-License-Identifier: MIT @@ -304,44 +304,48 @@ pub fn octez_riscv_compute_step_with_debug( #[ocaml::func] #[ocaml::sig("int64 -> state -> (state * int64)")] pub fn octez_riscv_compute_step_many( - max_steps: usize, + max_steps: u64, state: Pointer, ) -> (Pointer, i64) { apply_imm(state, |pvm| { - pvm.compute_step_many(&mut PvmHooks::default(), max_steps) + pvm.compute_step_many(&mut PvmHooks::default(), max_steps as usize) }) } #[ocaml::func] #[ocaml::sig("int64 -> mut_state -> int64")] -pub fn octez_riscv_mut_compute_step_many(max_steps: usize, state: Pointer) -> i64 { +pub fn octez_riscv_mut_compute_step_many(max_steps: u64, state: Pointer) -> i64 { apply_mut(state, |pvm| { - pvm.compute_step_many(&mut PvmHooks::default(), max_steps) + pvm.compute_step_many(&mut PvmHooks::default(), max_steps as usize) }) } #[ocaml::func] #[ocaml::sig("int64 -> state -> (int -> unit) -> (state * int64)")] pub fn octez_riscv_compute_step_many_with_debug( - max_steps: usize, + max_steps: u64, state: Pointer, printer: ocaml::Value, ) -> (Pointer, i64) { let mut hooks = PvmHooks::from_printer(printer, gc); - apply_imm(state, |pvm| pvm.compute_step_many(&mut hooks, max_steps)) + apply_imm(state, |pvm| { + pvm.compute_step_many(&mut hooks, max_steps as usize) + }) } #[ocaml::func] #[ocaml::sig("int64 -> mut_state -> (int -> unit) -> int64")] pub fn octez_riscv_mut_compute_step_many_with_debug( - max_steps: usize, + max_steps: u64, state: Pointer, printer: ocaml::Value, ) -> i64 { let mut hooks = PvmHooks::from_printer(printer, gc); - apply_mut(state, |pvm| pvm.compute_step_many(&mut hooks, max_steps)) + apply_mut(state, |pvm| { + pvm.compute_step_many(&mut hooks, max_steps as usize) + }) } #[ocaml::func]