From d49261172e289b37d69bba439450d1e8c9e4181a Mon Sep 17 00:00:00 2001 From: Emma Turner Date: Mon, 23 Sep 2024 14:19:17 +0100 Subject: [PATCH] RISC-V: bump rust-toolchain to 1.78.0; bump ocaml-rs --- images/rust-toolchain/Dockerfile | 14 +- scripts/lint.sh | 2 +- .../entrypoint/src/kernel_entrypoint.rs | 2 + src/kernel_sdk/entrypoint/src/lib.rs | 2 + src/riscv/Cargo.lock | 47 +- src/riscv/Cargo.toml | 4 +- src/riscv/dummy_kernel/rust-toolchain.toml | 2 +- src/riscv/jstz/bench/src/generate.rs | 2 +- src/riscv/jstz/bench/src/results.rs | 4 +- src/riscv/jstz/rust-toolchain.toml | 2 +- .../lib/src/machine_state/block_cache.rs | 521 ++++++++++++++++++ .../lib/src/machine_state/csregisters/bits.rs | 10 +- src/riscv/lib/src/machine_state/mode.rs | 4 +- src/riscv/lib/src/ocaml_api.rs | 2 +- src/riscv/lib/src/pvm/common.rs | 4 +- src/riscv/rust-toolchain.toml | 2 +- .../tests/inline_asm/rust-toolchain.toml | 2 +- 17 files changed, 565 insertions(+), 61 deletions(-) create mode 100644 src/riscv/lib/src/machine_state/block_cache.rs diff --git a/images/rust-toolchain/Dockerfile b/images/rust-toolchain/Dockerfile index 90ad79a43320..1235b9447d23 100644 --- a/images/rust-toolchain/Dockerfile +++ b/images/rust-toolchain/Dockerfile @@ -34,7 +34,7 @@ RUN curl https://sh.rustup.rs --silent --show-error --fail | \ ENV PATH=/root/.cargo/bin:$PATH # install rust toolchains and compilation targets -RUN rustup update 1.66.0 1.73.0 1.74.0 1.76.0 1.78.0 && \ +RUN rustup update 1.66.0 1.73.0 1.76.0 1.78.0 && \ for tc in $(rustup toolchain list | awk '{print $1}'); do \ rustup target add --toolchain="$tc" \ wasm32-unknown-unknown \ @@ -50,12 +50,12 @@ RUN curl -L "https://github.com/hermit-os/rust-std-hermit/releases/download/1.73 && rust-std-1.73.0-riscv64gc-unknown-hermit/install.sh \ && rm -r rust-std-1.73.0-riscv64gc-unknown-hermit rust-std-1.73.0-riscv64gc-unknown-hermit.tar.gz -# Install Rust 1.74.0 standard library for riscv64gc-unknown-hermit -RUN curl -L "https://github.com/hermit-os/rust-std-hermit/releases/download/1.74.0/rust-std-1.74.0-riscv64gc-unknown-hermit.tar.gz" -o rust-std-1.74.0-riscv64gc-unknown-hermit.tar.gz \ - && (echo f0c330eb957dc1acf9a0f0acd6a0b7d97a475e924c2d8eaa85294b66d1156b62 rust-std-1.74.0-riscv64gc-unknown-hermit.tar.gz | sha256sum -c) \ - && tar xf rust-std-1.74.0-riscv64gc-unknown-hermit.tar.gz \ - && rust-std-1.74.0-riscv64gc-unknown-hermit/install.sh \ - && rm -r rust-std-1.74.0-riscv64gc-unknown-hermit rust-std-1.74.0-riscv64gc-unknown-hermit.tar.gz +# Install Rust 1.78.0 standard library for riscv64gc-unknown-hermit +RUN curl -L "https://github.com/hermit-os/rust-std-hermit/releases/download/1.78.0/rust-std-1.78.0-riscv64gc-unknown-hermit.tar.gz" -o rust-std-1.78.0-riscv64gc-unknown-hermit.tar.gz \ + && (echo a4454f71a021b7af62f00b527cd6da28832e93728b606f6c4964c6c2c04789f0 rust-std-1.78.0-riscv64gc-unknown-hermit.tar.gz | sha256sum -c) \ + && tar xf rust-std-1.78.0-riscv64gc-unknown-hermit.tar.gz \ + && rust-std-1.78.0-riscv64gc-unknown-hermit/install.sh \ + && rm -r rust-std-1.78.0-riscv64gc-unknown-hermit rust-std-1.78.0-riscv64gc-unknown-hermit.tar.gz # Install Taplo RUN cargo +1.78.0 install taplo-cli --version 0.8.1 && \ diff --git a/scripts/lint.sh b/scripts/lint.sh index 76802ac39513..834298c04606 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -183,7 +183,7 @@ check_redirects() { } check_rust_toolchain_files() { - authorized_version=("1.66.0" "1.73.0" "1.74.0" "1.76.0" "1.78.0") + authorized_version=("1.66.0" "1.73.0" "1.76.0" "1.78.0") declare -a rust_toolchain_files mapfile -t rust_toolchain_files <<< "$(find src/ -name rust-toolchain)" diff --git a/src/kernel_sdk/entrypoint/src/kernel_entrypoint.rs b/src/kernel_sdk/entrypoint/src/kernel_entrypoint.rs index 1d917af46fee..06f507ae279b 100644 --- a/src/kernel_sdk/entrypoint/src/kernel_entrypoint.rs +++ b/src/kernel_sdk/entrypoint/src/kernel_entrypoint.rs @@ -2,6 +2,8 @@ // // SPDX-License-Identifier: MIT +#![allow(unused_imports)] + cfg_if::cfg_if! { if #[cfg(target_arch = "wasm32")] { mod wasm; diff --git a/src/kernel_sdk/entrypoint/src/lib.rs b/src/kernel_sdk/entrypoint/src/lib.rs index 9685187c071d..cae5074833b5 100644 --- a/src/kernel_sdk/entrypoint/src/lib.rs +++ b/src/kernel_sdk/entrypoint/src/lib.rs @@ -71,4 +71,6 @@ pub use host::RollupHostWithInMemoryStorage as RollupHost; mod kernel_entrypoint; mod panic_protection; +#[doc(hidden)] +#[allow(unused_imports)] pub use kernel_entrypoint::*; diff --git a/src/riscv/Cargo.lock b/src/riscv/Cargo.lock index 2d8c43966385..871f7b08bf47 100644 --- a/src/riscv/Cargo.lock +++ b/src/riscv/Cargo.lock @@ -1256,71 +1256,50 @@ dependencies = [ [[package]] name = "ocaml" -version = "1.0.0-beta.5" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871da589fac01351dda8c8b26a5132b90d8accd5382424cd072902584ffe0c02" +checksum = "4d8d4c8f085edfe98a1edf883c560019626194814237b12138ac160caa6c776c" dependencies = [ "ocaml-boxroot-sys", "ocaml-derive", - "ocaml-interop", - "ocaml-sys 0.23.0", + "ocaml-sys", ] [[package]] name = "ocaml-boxroot-sys" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5186393bfbee4ce2bc5bbb82beafb77e85c1d0a557e3cfc8c8a0d63d7845fed5" +checksum = "541b4c121093aa5bfb1b0e0d6f8ca00c807b156445bc4f4e19683421f6d26208" dependencies = [ "cc", ] [[package]] name = "ocaml-build" -version = "1.0.0-beta.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae2b0b155a81c2f3f9e71cb1f47e84d705d852e9ea7c10955d8bce1fa2d26aa0" +checksum = "1d51b05aa0083eaec54b22a3f2a3d49175e04b4fb77ca7abb5a85731736239c3" dependencies = [ "proc-macro2", - "syn 1.0.109", + "syn 2.0.65", ] [[package]] name = "ocaml-derive" -version = "1.0.0-beta.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdffd393e5e346c52509608ac6c3be178523931bf9f50c18d23836474521d17" +checksum = "3de4a0decff0fd3ee0928dfa15dac08651157f8f814e93b34fdf962190354035" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", -] - -[[package]] -name = "ocaml-interop" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e01e08412a7e072a90a225d2ae49a2860aeea853ce673bc63891dbf86aed063" -dependencies = [ - "ocaml-boxroot-sys", - "ocaml-sys 0.22.3", - "static_assertions", -] - -[[package]] -name = "ocaml-sys" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ec6ca7d41458442627435afb8f4671e83fd642e8a560171d671a1f679aa3cf" -dependencies = [ - "cty", + "syn 2.0.65", ] [[package]] name = "ocaml-sys" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc814766094de5f0f1c7e027027eb05c603cd7e235cc04ae195185fddecc1285" +checksum = "ff95caad36996cfaa425f1469bf0c132afac668e2654d5d1d89d1cc64001be02" dependencies = [ "cc", "cty", diff --git a/src/riscv/Cargo.toml b/src/riscv/Cargo.toml index 5021903e34a8..037a1b452011 100644 --- a/src/riscv/Cargo.toml +++ b/src/riscv/Cargo.toml @@ -18,8 +18,8 @@ lazy_static = "1.4.0" meansd = "2.1.0" num_enum = "0.7.2" numfmt = "1.1.1" -ocaml = "^1.0.0-beta" -ocaml-build = "^1.0.0-beta" +ocaml = "1.0.1" +ocaml-build = "1.0.0" paste = "1.0.14" proptest = "1.4.0" quanta = "0.12.3" diff --git a/src/riscv/dummy_kernel/rust-toolchain.toml b/src/riscv/dummy_kernel/rust-toolchain.toml index 9fbbaa759768..750a96967c14 100644 --- a/src/riscv/dummy_kernel/rust-toolchain.toml +++ b/src/riscv/dummy_kernel/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.74.0" +channel = "1.78.0" components = ["rustfmt", "clippy"] targets = ["riscv64gc-unknown-hermit"] diff --git a/src/riscv/jstz/bench/src/generate.rs b/src/riscv/jstz/bench/src/generate.rs index ea1f227e4207..ac6097aa883f 100644 --- a/src/riscv/jstz/bench/src/generate.rs +++ b/src/riscv/jstz/bench/src/generate.rs @@ -149,7 +149,7 @@ fn transfer_op( ) -> Result { let transfer = [TransferToken { from: &account.address, - transfers: &[&transfer], + transfers: &[transfer], }]; let body = serde_json::ser::to_vec(&transfer)?; diff --git a/src/riscv/jstz/bench/src/results.rs b/src/riscv/jstz/bench/src/results.rs index caba311a11e4..861d539a9acb 100644 --- a/src/riscv/jstz/bench/src/results.rs +++ b/src/riscv/jstz/bench/src/results.rs @@ -206,10 +206,10 @@ impl LogLine { #[derive(Debug)] enum LogType { - StartOfLevel(LogLine), + StartOfLevel(#[allow(unused)] LogLine), Deploy(LogLine), Success(LogLine), - EndOfLevel(LogLine), + EndOfLevel(#[allow(unused)] LogLine), SmartFunctionLog(LogLine), } diff --git a/src/riscv/jstz/rust-toolchain.toml b/src/riscv/jstz/rust-toolchain.toml index 9fbbaa759768..750a96967c14 100644 --- a/src/riscv/jstz/rust-toolchain.toml +++ b/src/riscv/jstz/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.74.0" +channel = "1.78.0" components = ["rustfmt", "clippy"] targets = ["riscv64gc-unknown-hermit"] diff --git a/src/riscv/lib/src/machine_state/block_cache.rs b/src/riscv/lib/src/machine_state/block_cache.rs new file mode 100644 index 000000000000..5750d003a192 --- /dev/null +++ b/src/riscv/lib/src/machine_state/block_cache.rs @@ -0,0 +1,521 @@ +// SPDX-FileCopyrightText: 2024 TriliTech +// +// SPDX-License-Identifier: MIT + +use crate::state_backend::{self, CellWrite}; +use crate::{ + cache_utils::FenceCounter, + parser::instruction::InstrCacheable, + state_backend::{ + AllocatedOf, Atom, Cell, LazyCell, ManagerBase, ManagerRead, ManagerReadWrite, + ManagerWrite, Ref, + }, + traps::Exception, +}; + +use super::address_translation::PAGE_SIZE; +use super::instruction_cache::ValidatedCacheEntry; +use super::MachineCoreState; +use super::{ + bus::{main_memory, Address}, + ProgramCounterUpdate, +}; +use crate::cache_utils::{Sizes, Unparsed}; + +const CACHE_INSTR: usize = 20; + +pub type CachedLayout = ( + Atom
, + Atom, + Atom, + [Atom; CACHE_INSTR], +); + +pub struct Cached { + address: Cell, + fence_counter: Cell, + len_instr: Cell, + instr: [LazyCell; CACHE_INSTR], +} + +impl Cached { + fn bind(space: AllocatedOf) -> Self { + Self { + address: space.0, + fence_counter: space.1, + len_instr: space.2, + instr: space + .3 + .into_iter() + .map(|p| LazyCell::wrap(p)) + .collect::>() + .try_into() + .ok() + .unwrap(), + } + } + + fn invalidate(&mut self) + where + M: ManagerWrite, + { + self.address.write(0); + self.len_instr.write(0); + } + + fn reset(&mut self) + where + M: ManagerWrite, + { + self.address.write(0); + self.fence_counter.write(FenceCounter::INITIAL); + self.len_instr.write(0); + self.instr.iter_mut().for_each(|lc| lc.reset(Unparsed(0))); + } + + fn block(&mut self) -> Block + where + M: ManagerRead, + { + Block { + instr: &mut self.instr[..self.len_instr.read() as usize], + } + } + + fn struct_ref(&self) -> AllocatedOf> { + ( + self.address.struct_ref(), + self.fence_counter.struct_ref(), + self.len_instr.struct_ref(), + self.instr + .iter() + .map(LazyCell::struct_ref) + .collect::>() + .try_into() + .map_err(|_| "mismatching lengths for block instructions") + .unwrap(), + ) + } +} + +/// The default instruction cache index bits. +pub const DEFAULT_CACHE_BITS: usize = 16; + +/// The default instruction cache size. +pub const DEFAULT_CACHE_SIZE: usize = 1 << DEFAULT_CACHE_BITS; + +/// The default instruction cache index bits for tests. +pub const TEST_CACHE_BITS: usize = 12; + +/// The default instruction cache for tests. +pub const TEST_CACHE_SIZE: usize = 1 << TEST_CACHE_BITS; + +/// Trait for capturing the different possible layouts of the instruction cache (i.e. +/// controlling the number of cache entries present). +pub trait BlockCacheLayout: state_backend::Layout { + type Entries; + type Sizes; + + fn refl( + space: state_backend::AllocatedOf, + ) -> BlockCache + where + Self: Sized; + + fn entry(entries: &Self::Entries, phys_addr: Address) -> &Cached; + + fn entry_mut( + entries: &mut Self::Entries, + phys_addr: Address, + ) -> &mut Cached; + + fn entries_reset(entries: &mut Self::Entries); + + fn struct_ref(cache: &BlockCache) -> AllocatedOf> + where + Self: Sized; +} + +pub type Layout = + (Atom
, Atom, Sizes); + +impl BlockCacheLayout for Layout { + type Entries = Box<[Cached; SIZE]>; + type Sizes = Sizes; + + fn refl(space: AllocatedOf) -> BlockCache { + BlockCache { + phys_addr: space.0, + offset: space.1, + fence_counter: space.2 .0, + entries: space + .2 + .1 + .into_iter() + .map(Cached::bind) + .collect::>() + .into_boxed_slice() + .try_into() + .map_err(|_| "mismatching vector lengths for instruction cache") + .unwrap(), + } + } + + fn entry(entries: &Self::Entries, phys_addr: Address) -> &Cached { + &entries[Self::Sizes::cache_index(phys_addr)] + } + + fn entry_mut( + entries: &mut Self::Entries, + phys_addr: Address, + ) -> &mut Cached { + &mut entries[Self::Sizes::cache_index(phys_addr)] + } + + fn entries_reset(entries: &mut Self::Entries) { + entries.iter_mut().for_each(Cached::reset) + } + + fn struct_ref(cache: &BlockCache) -> AllocatedOf> { + ( + cache.phys_addr.struct_ref(), + cache.offset.struct_ref(), + ( + cache.fence_counter.struct_ref(), + cache.entries.iter().map(Cached::struct_ref).collect(), + ), + ) + } +} + +pub struct BlockCache { + phys_addr: Cell, + fence_counter: Cell, + offset: Cell, + entries: BCL::Entries, +} + +impl BlockCache { + pub fn bind(space: AllocatedOf) -> Self { + BCL::refl(space) + } + + pub fn invalidate(&mut self) + where + M: ManagerReadWrite, + { + let counter = self.fence_counter.read(); + self.fence_counter.write(counter.next()); + self.reset_to(0); + BCL::entry_mut(&mut self.entries, counter.0 as Address).invalidate(); + } + + pub fn reset(&mut self) + where + M: ManagerWrite, + { + self.fence_counter.write(FenceCounter::INITIAL); + self.reset_to(0); + BCL::entries_reset(&mut self.entries); + } + + pub fn struct_ref(&self) -> AllocatedOf> { + BCL::struct_ref(self) + } + + pub fn push_instr(&mut self, entry: ValidatedCacheEntry) + where + M: ManagerReadWrite, + { + let (phys_addr, instr, unparsed) = entry.unwrap(); + + let mut current_start = self.phys_addr.read(); + let mut offset = self.offset.read(); + + if phys_addr % PAGE_SIZE == 0 || phys_addr != current_start + offset as Address { + self.reset_to(phys_addr); + current_start = phys_addr; + offset = 0; + } + + let next = offset + WIDTH; + if self.cache_inner(current_start, phys_addr, instr, unparsed) { + self.reset_to(next as u64) + } else { + self.offset.write(offset + WIDTH); + } + } + + fn reset_to(&mut self, pa: Address) + where + M: ManagerWrite, + { + self.phys_addr.write(pa); + self.offset.write(0); + } + + fn cache_inner( + &mut self, + block_addr: Address, + phys_addr: Address, + instr: InstrCacheable, + bytes: Unparsed, + ) -> bool + where + M: ManagerReadWrite, + { + let entry = BCL::entry_mut(&mut self.entries, block_addr); + + let start = entry.address.read(); + if start != block_addr || entry.address.read() == phys_addr { + entry.address.write(block_addr); + entry.len_instr.write(0); + entry.fence_counter.write(self.fence_counter.read()); + } + + let len_instr = entry.len_instr.read(); + + entry.instr[len_instr as usize].write((instr, bytes)); + + let new_len = len_instr + 1; + entry.len_instr.write(new_len); + + new_len == CACHE_INSTR as u8 + } + + pub fn get_block(&mut self, phys_addr: Address) -> Option> + where + M: ManagerReadWrite, + { + let entry = BCL::entry_mut(&mut self.entries, phys_addr); + + if entry.address.read() == phys_addr + && self.fence_counter.read() == entry.fence_counter.read() + { + let block = entry.block(); + Some(block) + } else { + None + } + } +} + +pub struct Block<'a, M: ManagerBase> { + instr: &'a mut [LazyCell], +} + +impl<'a, M: ManagerRead> Block<'a, M> { + pub fn num_instr(&self) -> usize { + self.instr.len() + } + + pub(super) fn run_block( + &mut self, + core: &mut MachineCoreState, + instr_pc: &mut Address, + _phys_addr: Address, + steps: &mut usize, + ) -> Result + where + ML: main_memory::MainMemoryLayout, + M: ManagerReadWrite, + { + for i in self.instr.iter_mut().map(|i| &i.read_ref().0) { + match core.run_instr_cacheable(i) { + Err(e) => return Err(e), + Ok(r @ ProgramCounterUpdate::Set(_)) => { + return Ok(r); + } + Ok(ProgramCounterUpdate::Add(width)) => { + *instr_pc += width; + } + } + core.hart.pc.write(*instr_pc); + *steps += 1; + } + Ok(ProgramCounterUpdate::Set(*instr_pc)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + backend_test, create_backend, create_state, + machine_state::registers::{a0, t0, t1}, + parser::instruction::{CIBTypeArgs, SBTypeArgs}, + }; + + pub type TestLayout = Layout; + + // writing CACHE_INSTR to the block cache creates new block + backend_test!(test_writing_full_block_fetchable_uncompressed, F, { + let mut backend = create_backend!(TestLayout, F); + let mut state = create_state!(BlockCache, TestLayout, F, backend, TestLayout); + + let uncompressed_bytes = 0x00533423; + let uncompressed = InstrCacheable::Sd(SBTypeArgs { + rs1: t1, + rs2: t0, + imm: 8, + }); + + let phys_addr = 10; + + for offset in 0..(CACHE_INSTR as u64) { + let entry = ValidatedCacheEntry::from_unchecked( + phys_addr + (offset * 4), + uncompressed, + Unparsed(uncompressed_bytes), + ); + state.push_instr::<4>(entry); + } + + let block = state.get_block(phys_addr); + assert!(block.is_some()); + assert_eq!(CACHE_INSTR, block.unwrap().num_instr()); + }); + + backend_test!(test_writing_full_block_fetchable_compressed, F, { + let mut backend = create_backend!(TestLayout, F); + let mut state = create_state!(BlockCache, TestLayout, F, backend, TestLayout); + + let compressed_bytes = 0x4505; + let compressed = InstrCacheable::CLi(CIBTypeArgs { rd_rs1: a0, imm: 1 }); + + let phys_addr = 10; + + for offset in 0..(CACHE_INSTR as u64) { + let entry = ValidatedCacheEntry::from_unchecked( + phys_addr + (offset * 2), + compressed, + Unparsed(compressed_bytes), + ); + state.push_instr::<2>(entry); + } + + let block = state.get_block(phys_addr); + assert!(block.is_some()); + assert_eq!(CACHE_INSTR, block.unwrap().num_instr()); + }); + + // writing instructions immediately creates block + backend_test!(test_writing_half_block_fetchable_compressed, F, { + let mut backend = create_backend!(TestLayout, F); + let mut state = create_state!(BlockCache, TestLayout, F, backend, TestLayout); + + let compressed_bytes = 0x4505; + let compressed = InstrCacheable::CLi(CIBTypeArgs { rd_rs1: a0, imm: 1 }); + + let phys_addr = 10; + + for offset in 0..((CACHE_INSTR / 2) as u64) { + let entry = ValidatedCacheEntry::from_unchecked( + phys_addr + (offset * 2), + compressed, + Unparsed(compressed_bytes), + ); + state.push_instr::<2>(entry); + } + + let block = state.get_block(phys_addr); + assert!(block.is_some()); + assert_eq!(CACHE_INSTR / 2, block.unwrap().num_instr()); + }); + + backend_test!(test_writing_two_blocks_fetchable_compressed, F, { + let mut backend = create_backend!(TestLayout, F); + let mut state = create_state!(BlockCache, TestLayout, F, backend, TestLayout); + + let compressed_bytes = 0x4505; + let compressed = InstrCacheable::CLi(CIBTypeArgs { rd_rs1: a0, imm: 1 }); + + let phys_addr = 10; + + for offset in 0..((CACHE_INSTR * 2) as u64) { + let entry = ValidatedCacheEntry::from_unchecked( + phys_addr + (offset * 2), + compressed, + Unparsed(compressed_bytes), + ); + state.push_instr::<2>(entry); + } + + let block = state.get_block(phys_addr); + assert!(block.is_some()); + assert_eq!(CACHE_INSTR, block.unwrap().num_instr()); + + let block = state.get_block(50); + assert!(block.is_some()); + assert_eq!(CACHE_INSTR, block.unwrap().num_instr()); + }); + + // writing across pages offset two blocks next to each other + backend_test!(test_crossing_page_exactly_creates_new_block, F, { + let mut backend = create_backend!(TestLayout, F); + let mut state = create_state!(BlockCache, TestLayout, F, backend, TestLayout); + + let compressed_bytes = 0x4505; + let compressed = InstrCacheable::CLi(CIBTypeArgs { rd_rs1: a0, imm: 1 }); + + let phys_addr = PAGE_SIZE - 10; + + for offset in 0..10 { + let entry = ValidatedCacheEntry::from_unchecked( + phys_addr + (offset * 2), + compressed, + Unparsed(compressed_bytes), + ); + state.push_instr::<2>(entry); + } + + let block = state.get_block(phys_addr); + assert!(block.is_some()); + assert_eq!(5, block.unwrap().num_instr()); + + let block = state.get_block(phys_addr + 10); + assert!(block.is_some()); + assert_eq!(5, block.unwrap().num_instr()); + }); + + // writing across pages offset creates two blocks with a gap + // TODO: needs to be done at the machine state level + backend_test!( + #[ignore] + test_crossing_page_offset_creates_new_block, + F, + { + let mut backend = create_backend!(TestLayout, F); + let mut state = create_state!(BlockCache, TestLayout, F, backend, TestLayout); + + let uncompressed_bytes = 0x00533423; + let uncompressed = InstrCacheable::Sd(SBTypeArgs { + rs1: t1, + rs2: t0, + imm: 8, + }); + + let phys_addr = PAGE_SIZE - 6; + + for offset in 0..3 { + let entry = ValidatedCacheEntry::from_unchecked( + phys_addr + (offset * 4), + uncompressed, + Unparsed(uncompressed_bytes), + ); + state.push_instr::<4>(entry); + } + + let block = state.get_block(phys_addr); + assert!(block.is_some()); + assert_eq!(1, block.unwrap().num_instr()); + + let block = state.get_block(phys_addr + 4); + assert!(block.is_none()); + + let block = state.get_block(phys_addr + 8); + assert!(block.is_some()); + assert_eq!(1, block.unwrap().num_instr()); + } + ); +} diff --git a/src/riscv/lib/src/machine_state/csregisters/bits.rs b/src/riscv/lib/src/machine_state/csregisters/bits.rs index b43562aff45f..60dec11f1ebb 100644 --- a/src/riscv/lib/src/machine_state/csregisters/bits.rs +++ b/src/riscv/lib/src/machine_state/csregisters/bits.rs @@ -164,6 +164,11 @@ macro_rules! csr_new { }; } +/// Normalise the fields for a Control or State register using WARL/WPRI +pub trait NormaliseFields { + fn normalise(self) -> Self; +} + #[cfg(test)] mod tests { use crate::bits::{Bits64, ConstantBits}; @@ -185,8 +190,3 @@ mod tests { assert_eq!(test.to_bits(), 0b011); } } - -/// Normalise the fields for a Control or State register using WARL/WPRI -pub trait NormaliseFields { - fn normalise(self) -> Self; -} diff --git a/src/riscv/lib/src/machine_state/mode.rs b/src/riscv/lib/src/machine_state/mode.rs index 22065825e9f6..0e977cdb44b1 100644 --- a/src/riscv/lib/src/machine_state/mode.rs +++ b/src/riscv/lib/src/machine_state/mode.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 TriliTech +// SPDX-FileCopyrightText: 2023-2024 TriliTech // // SPDX-License-Identifier: MIT @@ -107,7 +107,7 @@ mod tests { assert_eq!(inst.read(), first_value); let value_read = bincode::serialize(&inst.struct_ref()).unwrap()[0]; - assert_eq!(Mode::try_from(value_read), Ok(first_value)); + assert_eq!(Mode::from(value_read), first_value); }); assert_eq!(Mode::from(42), Mode::default()); diff --git a/src/riscv/lib/src/ocaml_api.rs b/src/riscv/lib/src/ocaml_api.rs index 988a0310ea6a..e5d25be593a9 100644 --- a/src/riscv/lib/src/ocaml_api.rs +++ b/src/riscv/lib/src/ocaml_api.rs @@ -66,7 +66,7 @@ impl From for Status { impl From for PvmStatus { fn from(item: Status) -> Self { - PvmStatus::try_from(item as u8).expect("Invalid conversion") + PvmStatus::from(item as u8) } } diff --git a/src/riscv/lib/src/pvm/common.rs b/src/riscv/lib/src/pvm/common.rs index f42dc7874d0f..2e2e90235454 100644 --- a/src/riscv/lib/src/pvm/common.rs +++ b/src/riscv/lib/src/pvm/common.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 TriliTech +// SPDX-FileCopyrightText: 2023-2024 TriliTech // // SPDX-License-Identifier: MIT @@ -318,7 +318,7 @@ mod tests { // Handle the ECALL successfully let outcome = pvm.handle_exception(&mut Default::default(), EnvironException::EnvCallFromUMode); - assert!(matches!(outcome, false)); + assert!(!outcome); // After the ECALL we should be waiting for input assert_eq!(pvm.status(), PvmStatus::WaitingForInput); diff --git a/src/riscv/rust-toolchain.toml b/src/riscv/rust-toolchain.toml index 9e137c1e6f37..2535b0131da6 100644 --- a/src/riscv/rust-toolchain.toml +++ b/src/riscv/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.74.0" +channel = "1.78.0" components = ["rustfmt", "clippy"] diff --git a/src/riscv/tests/inline_asm/rust-toolchain.toml b/src/riscv/tests/inline_asm/rust-toolchain.toml index b806088e1676..58f1d8fc05a9 100644 --- a/src/riscv/tests/inline_asm/rust-toolchain.toml +++ b/src/riscv/tests/inline_asm/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.74.0" +channel = "1.78.0" targets = ["riscv64gc-unknown-none-elf"] -- GitLab