diff --git a/src/riscv/lib/src/cache_utils.rs b/src/riscv/lib/src/cache_utils.rs index a15c8aba0a485ba5eee5079acb2af0f513abd772..cc4dbb692f926483389cbdce4ced127f9cf0105e 100644 --- a/src/riscv/lib/src/cache_utils.rs +++ b/src/riscv/lib/src/cache_utils.rs @@ -7,7 +7,7 @@ use std::{convert::Infallible, marker::PhantomData}; use crate::{ default::ConstDefault, - machine_state::main_memory::Address, + machine_state::memory::Address, state_backend::{ AllocatedOf, CommitmentLayout, FromProofResult, Layout, ManagerAlloc, ManagerBase, ManagerSerialise, Many, ProofLayout, ProofTree, diff --git a/src/riscv/lib/src/devicetree.rs b/src/riscv/lib/src/devicetree.rs index c5f02656d980f984912b086e3792d68c6f894351..6b8a16e844c83113fad625c802f38bbfe2c62554 100644 --- a/src/riscv/lib/src/devicetree.rs +++ b/src/riscv/lib/src/devicetree.rs @@ -8,7 +8,7 @@ use vm_fdt::FdtWriter; -use crate::machine_state::main_memory; +use crate::machine_state::memory; /// Information about the initial ramdisk. pub struct InitialRamDisk { @@ -110,8 +110,8 @@ pub fn generate_custom( } /// Generate a Flattened Device Tree for the given hardware configuration. -pub fn generate( +pub fn generate( initrd: Option, ) -> Result, vm_fdt::Error> { - generate_custom(main_memory::FIRST_ADDRESS, ML::BYTES as u64, initrd) + generate_custom(memory::FIRST_ADDRESS, MC::TOTAL_BYTES as u64, initrd) } diff --git a/src/riscv/lib/src/instruction_context.rs b/src/riscv/lib/src/instruction_context.rs index 9808048b7a9d16315d5a73284dfdb96640c2ae96..c5c4a54d8fd649f621a843bf5b58641de83825ba 100644 --- a/src/riscv/lib/src/instruction_context.rs +++ b/src/riscv/lib/src/instruction_context.rs @@ -11,7 +11,7 @@ use crate::{ machine_state::{ MachineCoreState, ProgramCounterUpdate, instruction::Args, - main_memory::MainMemoryLayout, + memory::MemoryConfig, registers::{NonZeroXRegister, XValue}, }, state_backend::ManagerReadWrite, @@ -66,7 +66,7 @@ pub trait ICB { F: FnOnce(Value) -> Self::IResult; } -impl ICB for MachineCoreState { +impl ICB for MachineCoreState { type XValue = XValue; #[inline(always)] diff --git a/src/riscv/lib/src/interpreter/atomics.rs b/src/riscv/lib/src/interpreter/atomics.rs index 5f82629a9196364d4a7b269f4fa31e87e3e254f6..b2b61c15d32b9572bd48b0d123105fedbce87034 100644 --- a/src/riscv/lib/src/interpreter/atomics.rs +++ b/src/riscv/lib/src/interpreter/atomics.rs @@ -7,7 +7,7 @@ use std::mem; use crate::{ - machine_state::{MachineCoreState, main_memory::MainMemoryLayout, registers::XRegister}, + machine_state::{MachineCoreState, memory, registers::XRegister}, state_backend as backend, traps::Exception, }; @@ -15,9 +15,9 @@ use crate::{ pub const SC_SUCCESS: u64 = 0; pub const SC_FAILURE: u64 = 1; -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// Loads a word or a double from the address in `rs1`, places the diff --git a/src/riscv/lib/src/interpreter/c.rs b/src/riscv/lib/src/interpreter/c.rs index bafbee537373e81287c411d146ee3913d8fedc3e..20d9608457d6c8fc01b03925910b5456c93e5b51 100644 --- a/src/riscv/lib/src/interpreter/c.rs +++ b/src/riscv/lib/src/interpreter/c.rs @@ -44,11 +44,11 @@ pub fn run_nop(_icb: &mut impl ICB) {} #[cfg(test)] mod tests { use super::*; - use crate::machine_state::MachineCoreState; + use crate::machine_state::{MachineCoreState, memory::M1K}; use crate::{ backend_test, create_state, interpreter::i::run_add, - machine_state::{MachineCoreStateLayout, main_memory::tests::T1K, registers::nz}, + machine_state::{MachineCoreStateLayout, registers::nz}, }; backend_test!(test_add_mv, F, { @@ -62,7 +62,7 @@ mod tests { ]; for (imm, rs1, res) in imm_rs1_res { - let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); state.hart.xregisters.write_nz(nz::a3, rs1); state.hart.xregisters.write_nz(nz::a4, imm as u64); diff --git a/src/riscv/lib/src/interpreter/common_memory.rs b/src/riscv/lib/src/interpreter/common_memory.rs index 30d04e5fd69622125755b26a57316b9fd30f3408..baf49b1d75db566b338d22c848157215b4f7c068 100644 --- a/src/riscv/lib/src/interpreter/common_memory.rs +++ b/src/riscv/lib/src/interpreter/common_memory.rs @@ -6,16 +6,16 @@ use crate::{ machine_state::{ AccessType, MachineCoreState, - main_memory::{MainMemoryLayout, OutOfBounds}, + memory::{self, Memory, OutOfBounds}, registers::XRegister, }, state_backend as backend, traps::Exception, }; -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// Generic read function for loading `mem::size_of` bytes from `address` diff --git a/src/riscv/lib/src/interpreter/i.rs b/src/riscv/lib/src/interpreter/i.rs index 56f2e7b1e12c588282b3d756f12306d155bb64a8..850542132996b6caf672876dc2381025c3360718 100644 --- a/src/riscv/lib/src/interpreter/i.rs +++ b/src/riscv/lib/src/interpreter/i.rs @@ -29,10 +29,10 @@ pub fn run_add( #[cfg(test)] mod tests { use super::*; - use crate::machine_state::MachineCoreState; + use crate::machine_state::{MachineCoreState, memory::M1K}; use crate::{ backend_test, create_state, - machine_state::{MachineCoreStateLayout, main_memory::tests::T1K, registers::nz}, + machine_state::{MachineCoreStateLayout, registers::nz}, }; backend_test!(test_add, F, { let imm_rs1_res = [ @@ -45,7 +45,7 @@ mod tests { ]; for (imm, rs1, res) in imm_rs1_res { - let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); state.hart.xregisters.write_nz(nz::a0, rs1); state.hart.xregisters.write_nz(nz::t0, imm as u64); diff --git a/src/riscv/lib/src/interpreter/integer.rs b/src/riscv/lib/src/interpreter/integer.rs index e7e29548803fb2af5414b4bab2240cf7c5e6cb14..9f073c09f47416da3d024bd551689b7939fd7cac 100644 --- a/src/riscv/lib/src/interpreter/integer.rs +++ b/src/riscv/lib/src/interpreter/integer.rs @@ -29,7 +29,7 @@ mod tests { backend_test, create_state, machine_state::{ MachineCoreState, MachineCoreStateLayout, - main_memory::tests::T1K, + memory::M1K, registers::nz::{self, a0}, }, }; @@ -42,7 +42,7 @@ mod tests { ]; for (rs2, rd, res) in rs2val_rd_res { - let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); state.hart.xregisters.write_nz(a0, rs2); state.hart.xregisters.run_neg(rd, nz::a0); diff --git a/src/riscv/lib/src/interpreter/load_store.rs b/src/riscv/lib/src/interpreter/load_store.rs index 001d807da72e89568c552c8d199d4c3d87fdf77e..9ae025bf385a9d7f1769881ea53fc67f5c6e3916 100644 --- a/src/riscv/lib/src/interpreter/load_store.rs +++ b/src/riscv/lib/src/interpreter/load_store.rs @@ -34,7 +34,7 @@ mod test { backend_test, create_state, machine_state::{ MachineCoreState, MachineCoreStateLayout, - main_memory::tests::T1K, + memory::M1K, registers::{a2, a3, a4, nz}, }, }; @@ -47,7 +47,7 @@ mod test { ]; for (imm, rd_rs1, res) in imm_rdrs1_res { - let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); super::run_li(&mut state, imm, rd_rs1); assert_eq!(state.hart.xregisters.read_nz(rd_rs1), res); } @@ -55,7 +55,7 @@ mod test { backend_test!(test_lui, F, { proptest!(|(imm in any::())| { - let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); state.hart.xregisters.write(a2, 0); state.hart.xregisters.write(a4, 0); diff --git a/src/riscv/lib/src/interpreter/rv32a.rs b/src/riscv/lib/src/interpreter/rv32a.rs index 410765059287a4daa9262c6cbb70f43660451687..5e6ef61404c6e24b4e2d368fb73194680aa197da 100644 --- a/src/riscv/lib/src/interpreter/rv32a.rs +++ b/src/riscv/lib/src/interpreter/rv32a.rs @@ -10,14 +10,14 @@ use std::ops::{BitAnd, BitOr, BitXor}; use crate::{ - machine_state::{MachineCoreState, main_memory::MainMemoryLayout, registers::XRegister}, + machine_state::{MachineCoreState, memory, registers::XRegister}, state_backend as backend, traps::Exception, }; -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `LR.W` R-type instruction @@ -228,7 +228,6 @@ mod test { interpreter::atomics::{SC_FAILURE, SC_SUCCESS}, machine_state::{ MachineCoreState, MachineCoreStateLayout, - main_memory::tests::T1K, registers::{a0, a1, a2}, }, }; @@ -238,7 +237,9 @@ mod test { ($name:ident, $lr: ident, $sc: ident, $align: expr, $t: ident) => { backend_test!($name, F, { use $crate::machine_state::registers::nz; - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + use $crate::machine_state::memory::M1K; + + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -280,7 +281,9 @@ mod test { macro_rules! test_amo { ($instr: ident, $f: expr, $align: expr, $t: ident) => { backend_test!($instr, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + use $crate::machine_state::memory::M1K; + + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv32c.rs b/src/riscv/lib/src/interpreter/rv32c.rs index b0830e73ce6327a3d1d108690f5c493faa590609..247602e27868188144d4449693b8c6cfbd0390cf 100644 --- a/src/riscv/lib/src/interpreter/rv32c.rs +++ b/src/riscv/lib/src/interpreter/rv32c.rs @@ -11,7 +11,7 @@ use crate::{ machine_state::{ MachineCoreState, ProgramCounterUpdate, hart_state::HartState, - main_memory::{Address, MainMemoryLayout}, + memory::{self, Address}, registers::{NonZeroXRegister, XRegister, sp}, }, parser::instruction::InstrWidth, @@ -115,9 +115,9 @@ where } } -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `C.LW` CL-type compressed instruction @@ -179,7 +179,7 @@ mod tests { machine_state::{ MachineCoreState, MachineCoreStateLayout, ProgramCounterUpdate, hart_state::{HartState, HartStateLayout}, - main_memory::tests::T1K, + memory::M1K, registers::{ nz::{self, a0}, t1, @@ -197,7 +197,7 @@ mod tests { (u64::MAX - 1, 100, 98_i64 as u64), ]; for (init_pc, imm, res_pc) in test_case { - let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); state.hart.pc.write(init_pc); let new_pc = state.hart.run_j(imm); diff --git a/src/riscv/lib/src/interpreter/rv32i.rs b/src/riscv/lib/src/interpreter/rv32i.rs index 72303884fdfb81e91feb1d73a495c21aa793512a..3fc8f112e9e7c513df3ba7f697efb2ecd684116f 100644 --- a/src/riscv/lib/src/interpreter/rv32i.rs +++ b/src/riscv/lib/src/interpreter/rv32i.rs @@ -10,7 +10,7 @@ use crate::{ machine_state::{ MachineCoreState, ProgramCounterUpdate, hart_state::HartState, - main_memory::{Address, MainMemoryLayout}, + memory::{self, Address}, mode::Mode, registers::{NonZeroXRegister, XRegister, XRegisters}, }, @@ -349,9 +349,9 @@ where } } -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerBase, { /// `FENCE` I-Type instruction @@ -381,7 +381,7 @@ mod tests { xstatus::{MPPValue, MStatus, SPPValue}, }, hart_state::{HartState, HartStateLayout}, - main_memory::{Address, tests::T1K}, + memory::{Address, M1K}, mode::Mode, registers::{XRegisters, XRegistersLayout, a0, a1, a2, fa0, nz, t0, t1, t2, t3}, }, @@ -410,7 +410,7 @@ mod tests { ]; for (imm, rs1, rd, res) in imm_rs1_rd_res { - let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); state.hart.xregisters.write(a0, rs1); state.hart.xregisters.write(t0, imm as u64); @@ -693,14 +693,14 @@ mod tests { }); backend_test!(test_ebreak, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let ret_val = state.hart.run_ebreak(); assert_eq!(ret_val, Exception::Breakpoint); }); backend_test!(test_fence, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64a.rs b/src/riscv/lib/src/interpreter/rv64a.rs index 2e282c6f81eb16b9c2a0195863fb7129361fae37..097b370a13273f403743b4e775aea306113dad69 100644 --- a/src/riscv/lib/src/interpreter/rv64a.rs +++ b/src/riscv/lib/src/interpreter/rv64a.rs @@ -10,14 +10,14 @@ use std::ops::{BitAnd, BitOr, BitXor}; use crate::{ - machine_state::{MachineCoreState, main_memory::MainMemoryLayout, registers::XRegister}, + machine_state::{MachineCoreState, memory, registers::XRegister}, state_backend as backend, traps::Exception, }; -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `LR.D` R-type instruction @@ -228,7 +228,6 @@ mod test { interpreter::atomics::{SC_FAILURE, SC_SUCCESS}, machine_state::{ MachineCoreState, MachineCoreStateLayout, - main_memory::tests::T1K, registers::{a0, a1, a2}, }, test_amo, test_lrsc, diff --git a/src/riscv/lib/src/interpreter/rv64c.rs b/src/riscv/lib/src/interpreter/rv64c.rs index e36ca988e6e09107f5b405c7d93c8b430a271dc1..333312d8a1a19aaaee5f2b45f90a06807ed02904 100644 --- a/src/riscv/lib/src/interpreter/rv64c.rs +++ b/src/riscv/lib/src/interpreter/rv64c.rs @@ -9,8 +9,7 @@ use crate::{ machine_state::{ - MachineCoreState, - main_memory::MainMemoryLayout, + MachineCoreState, memory, registers::{NonZeroXRegister, XRegister, XRegisters, sp}, }, state_backend as backend, @@ -66,9 +65,9 @@ where } } -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `C.LD` CL-type compressed instruction @@ -131,7 +130,7 @@ mod tests { machine_state::{ MachineCoreState, MachineCoreStateLayout, hart_state::{HartState, HartStateLayout}, - main_memory::tests::T1K, + memory::M1K, registers::{a3, a4, nz, t0}, }, traps::Exception, @@ -157,7 +156,7 @@ mod tests { }); backend_test!(test_run_cldsp_clwsp, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64d.rs b/src/riscv/lib/src/interpreter/rv64d.rs index 947929a81f13f2e58d66e24c005755b7124bb864..0073d2aa6078e7155268c9adba8aa3e39589aa07 100644 --- a/src/riscv/lib/src/interpreter/rv64d.rs +++ b/src/riscv/lib/src/interpreter/rv64d.rs @@ -16,7 +16,7 @@ use crate::{ machine_state::{ MachineCoreState, hart_state::HartState, - main_memory::MainMemoryLayout, + memory, registers::{FRegister, FValue, XRegister}, }, parser::instruction::InstrRoundingMode, @@ -515,9 +515,9 @@ where } } -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `FLD` I-type instruction. @@ -561,7 +561,7 @@ mod tests { xstatus::{ExtensionValue, MStatus}, }, hart_state::{HartState, HartStateLayout}, - main_memory::tests::T1K, + memory::M1K, registers::{fa2, fa3, parse_fregister, parse_xregister, t0}, }, traps::Exception, @@ -596,7 +596,7 @@ mod tests { }); backend_test!(test_load_store, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64dc.rs b/src/riscv/lib/src/interpreter/rv64dc.rs index 2e003b83d57832e8c3c85197b0df4f3bd9f1f559..5cb6d169049f329bf73016206e983a20fdc001e1 100644 --- a/src/riscv/lib/src/interpreter/rv64dc.rs +++ b/src/riscv/lib/src/interpreter/rv64dc.rs @@ -9,17 +9,16 @@ use crate::{ machine_state::{ - MachineCoreState, - main_memory::MainMemoryLayout, + MachineCoreState, memory, registers::{FRegister, XRegister, sp}, }, state_backend as backend, traps::Exception, }; -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `C.FLD` CL-type compressed instruction @@ -86,7 +85,7 @@ mod test { CSRegister, xstatus::{ExtensionValue, MStatus}, }, - main_memory::tests::T1K, + memory::M1K, registers::{fa2, fa3, parse_xregister, sp}, }, traps::Exception, @@ -96,7 +95,7 @@ mod test { const OUT_OF_BOUNDS_OFFSET: i64 = 1024; backend_test!(test_cfsd_cfld, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -135,7 +134,7 @@ mod test { }); backend_test!(test_cfsdsp_cfldsp, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64f.rs b/src/riscv/lib/src/interpreter/rv64f.rs index 81d846ac9898578f2ebd6a5d56b684e43c0a8b87..4196f12ee731c966c24d410ee03539408974e19d 100644 --- a/src/riscv/lib/src/interpreter/rv64f.rs +++ b/src/riscv/lib/src/interpreter/rv64f.rs @@ -13,7 +13,7 @@ use crate::{ machine_state::{ MachineCoreState, hart_state::HartState, - main_memory::MainMemoryLayout, + memory, registers::{FRegister, FValue, XRegister}, }, parser::instruction::InstrRoundingMode, @@ -501,9 +501,9 @@ where } } -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `FLW` I-type instruction. @@ -568,7 +568,7 @@ mod tests { xstatus::{ExtensionValue, MStatus}, }, hart_state::{HartState, HartStateLayout}, - main_memory::tests::T1K, + memory::M1K, registers::{fa1, fa4, parse_fregister, parse_xregister, t0}, }, traps::Exception, @@ -612,7 +612,7 @@ mod tests { }); backend_test!(test_load_store, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64i.rs b/src/riscv/lib/src/interpreter/rv64i.rs index 7bcaa7a387025a55044320f2993f30544b85ee31..99b3c3528dd9ad28881c3fa31353ecf7d0abf525 100644 --- a/src/riscv/lib/src/interpreter/rv64i.rs +++ b/src/riscv/lib/src/interpreter/rv64i.rs @@ -8,8 +8,7 @@ use crate::{ machine_state::{ - MachineCoreState, - main_memory::MainMemoryLayout, + MachineCoreState, memory, registers::{NonZeroXRegister, XRegister, XRegisters}, }, state_backend as backend, @@ -238,9 +237,9 @@ where } } -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `LD` I-type instruction @@ -364,7 +363,7 @@ mod tests { machine_state::{ MachineCoreState, MachineCoreStateLayout, hart_state::{HartState, HartStateLayout}, - main_memory::tests::T1K, + memory::M1K, registers::{a0, a1, a2, a3, a4, nz, t0, t1, t2, t3, t4}, }, traps::Exception, @@ -834,7 +833,7 @@ mod tests { }); backend_test!(test_load_store, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64priv.rs b/src/riscv/lib/src/interpreter/rv64priv.rs index 6d75b1de54f8794f5d1c058f15fdb154bab546d2..a0d1347bfc62bdd80ac13441346e6e721386c72f 100644 --- a/src/riscv/lib/src/interpreter/rv64priv.rs +++ b/src/riscv/lib/src/interpreter/rv64priv.rs @@ -13,7 +13,7 @@ use crate::{ xstatus::{MPPValue, SPPValue}, }, hart_state::HartState, - main_memory::{Address, MainMemoryLayout}, + memory::{self, Address}, mode::Mode, registers::XRegister, }, @@ -102,9 +102,9 @@ where } } -impl MachineCoreState +impl MachineCoreState where - ML: MainMemoryLayout, + MC: memory::MemoryConfig, M: backend::ManagerReadWrite, { /// `WFI` instruction @@ -142,7 +142,7 @@ mod tests { machine_state::{ MachineCoreState, MachineCoreStateLayout, csregisters::{CSRRepr, CSRegister, xstatus}, - main_memory::tests::T1K, + memory::M1K, mode::Mode, registers::{a0, t0}, }, @@ -150,8 +150,8 @@ mod tests { }; backend_test!(test_sfence, F, { - type L = MachineCoreStateLayout; - let mut state = create_state!(MachineCoreState, L, F, T1K); + type L = MachineCoreStateLayout; + let mut state = create_state!(MachineCoreState, L, F, M1K); let run_test = |state: &mut MachineCoreState<_, _>, mode: Mode, diff --git a/src/riscv/lib/src/interpreter/rv64zifencei.rs b/src/riscv/lib/src/interpreter/rv64zifencei.rs index d02d7e0a54109f9e6e332199062c74f6197d2e63..80b5e57d913c95193eec29f80b86fd15ee561afd 100644 --- a/src/riscv/lib/src/interpreter/rv64zifencei.rs +++ b/src/riscv/lib/src/interpreter/rv64zifencei.rs @@ -6,17 +6,16 @@ use crate::{ machine_state::{ - AccessType, CacheLayouts, MachineState, block_cache::bcall::Block, - main_memory::MainMemoryLayout, + AccessType, CacheLayouts, MachineState, block_cache::bcall::Block, memory::MemoryConfig, }, state_backend, }; -impl MachineState +impl MachineState where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: state_backend::ManagerReadWrite, { /// Execute a `fence.i` instruction. diff --git a/src/riscv/lib/src/jit.rs b/src/riscv/lib/src/jit.rs index 030696fa1e466edde6e9c42d85d0ee3c63a234f9..5240833ef70d7e47d46a41791aa7276b942ce1c0 100644 --- a/src/riscv/lib/src/jit.rs +++ b/src/riscv/lib/src/jit.rs @@ -24,23 +24,22 @@ use self::builder::Builder; use self::state_access::JsaCalls; use self::state_access::JsaImports; use self::state_access::register_jsa_symbols; -use crate::machine_state::MachineCoreState; use crate::machine_state::ProgramCounterUpdate; use crate::machine_state::instruction::Instruction; -use crate::machine_state::main_memory::MainMemoryLayout; +use crate::machine_state::{MachineCoreState, memory::MemoryConfig}; use crate::traps::EnvironException; /// Alias for the function signature produced by the JIT compilation. -type JitFn = unsafe extern "C" fn(&mut MachineCoreState, u64, &mut usize); +type JitFn = unsafe extern "C" fn(&mut MachineCoreState, u64, &mut usize); /// A jit-compiled function that can be [called] over [`MachineCoreState`]. /// /// [called]: Self::call -pub struct JCall { - fun: JitFn, +pub struct JCall { + fun: JitFn, } -impl JCall { +impl JCall { /// Run the jit-compiled function over the state. /// /// # Safety @@ -49,7 +48,7 @@ impl JCall { /// still be alive. pub unsafe fn call( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, pc: u64, steps: &mut usize, ) -> Result<(), EnvironException> { @@ -77,7 +76,7 @@ pub enum JitError { /// The JIT is responsible for compiling blocks of instructions to machine code, /// returning a function that can be run over the [`MachineCoreState`]. -pub struct JIT { +pub struct JIT { /// The function builder context, which is reused across multiple /// [`FunctionBuilder`] instances. builder_context: FunctionBuilderContext, @@ -92,16 +91,16 @@ pub struct JIT { module: JITModule, /// Imported [JitStateAccess] functions. - jsa_imports: JsaImports, + jsa_imports: JsaImports, /// Counter for naming of functions next_id: usize, } -impl JIT { +impl JIT { /// Create a new instance of the JIT, which will be able to /// produce functions that can be run over the current - /// memory layout & manager. + /// memory configuration and manager. pub fn new() -> Result { let mut flag_builder = settings::builder(); flag_builder.set("use_colocated_libcalls", "false")?; @@ -111,7 +110,7 @@ impl JIT { let isa = isa_builder.finish(settings::Flags::new(flag_builder))?; let mut builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names()); - register_jsa_symbols::(&mut builder); + register_jsa_symbols::(&mut builder); let mut module = JITModule::new(builder); let jsa_imports = JsaImports::declare_in_module(&mut module)?; @@ -132,7 +131,7 @@ impl JIT { pub fn compile<'a>( &mut self, instr: impl IntoIterator, - ) -> Option> { + ) -> Option> { let mut builder = self.start(); for i in instr { @@ -174,7 +173,7 @@ impl JIT { /// # Return /// /// | `steps: usize` | `int` | - fn start(&mut self) -> Builder<'_, ML, JSA> { + fn start(&mut self) -> Builder<'_, MC, JSA> { let ptr = self.module.target_config().pointer_type(); self.ctx.func.signature.params.push(AbiParam::new(ptr)); @@ -195,7 +194,7 @@ impl JIT { let jsa_call = JsaCalls::func_calls(&mut self.module, &self.jsa_imports); - Builder::<'_, ML, JSA> { + Builder::<'_, MC, JSA> { builder, ptr, core_ptr_val, @@ -215,7 +214,7 @@ impl JIT { } /// Finalise the function currently under construction. - fn finalise(&mut self) -> JitFn { + fn finalise(&mut self) -> JitFn { let name = self.name(); let id = self .module @@ -247,7 +246,7 @@ impl JIT { // TODO: https://linear.app/tezos/issue/RV-496 // `Block::BlockBuilder` should not require Default, as it // does not allow for potential fallilibility -impl Default for JIT { +impl Default for JIT { fn default() -> Self { Self::new().expect("JIT is supported on all octez-riscv supported platforms") } @@ -256,17 +255,17 @@ impl Default for JIT { #[cfg(test)] mod tests { use super::*; - use crate::machine_state::block_cache::bcall::{ - BCall, Block, BlockLayout, Interpreted, InterpretedBlockBuilder, + use crate::machine_state::{MachineCoreState, MachineCoreStateLayout, memory::M1K}; + use crate::machine_state::{ + block_cache::bcall::{BCall, Block, BlockLayout, Interpreted, InterpretedBlockBuilder}, + memory::MemoryConfig, }; - use crate::machine_state::main_memory::tests::T1K; - use crate::machine_state::{MachineCoreState, MachineCoreStateLayout}; use crate::parser::instruction::InstrWidth::*; use crate::state_backend::test_helpers::assert_eq_struct; use crate::state_backend::{FnManagerIdent, ManagerRead}; use crate::{backend_test, create_state}; - fn instructions(block: &Interpreted) -> Vec + fn instructions(block: &Interpreted) -> Vec where M: ManagerRead, { @@ -289,14 +288,14 @@ mod tests { ], ]; - let mut jit = JIT::::new().unwrap(); + let mut jit = JIT::::new().unwrap(); let interpreted_bb = InterpretedBlockBuilder; for scenario in scenarios { let mut interpreted = - create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut block = create_state!(Interpreted, BlockLayout, F, T1K); + create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut block = create_state!(Interpreted, BlockLayout, F, M1K); block.start_block(); for instr in scenario.iter() { @@ -362,14 +361,14 @@ mod tests { ], ]; - let mut jit = JIT::::new().unwrap(); + let mut jit = JIT::::new().unwrap(); let interpreted_bb = InterpretedBlockBuilder; for scenario in scenarios { let mut interpreted = - create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut block = create_state!(Interpreted, BlockLayout, F, T1K); + create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut block = create_state!(Interpreted, BlockLayout, F, M1K); block.start_block(); for instr in scenario.iter() { @@ -436,12 +435,12 @@ mod tests { I::new_add(x1, x1, x2, Compressed), ]; - let mut jit = JIT::::new().unwrap(); + let mut jit = JIT::::new().unwrap(); let interpreted_bb = InterpretedBlockBuilder; - let mut interpreted = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut block = create_state!(Interpreted, BlockLayout, F, T1K); + let mut interpreted = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut block = create_state!(Interpreted, BlockLayout, F, M1K); block.start_block(); for instr in scenario.iter() { @@ -512,10 +511,10 @@ mod tests { let success: &[I] = &[I::new_nop(Compressed)]; for failure in failure_scenarios.iter() { - let mut jit = JIT::::new().unwrap(); + let mut jit = JIT::::new().unwrap(); - let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut block = create_state!(Interpreted, BlockLayout, F, T1K); + let mut jitted = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut block = create_state!(Interpreted, BlockLayout, F, M1K); block.start_block(); for instr in failure.iter() { diff --git a/src/riscv/lib/src/jit/builder.rs b/src/riscv/lib/src/jit/builder.rs index 16637e4a5b24dfb6f5eba98de8cf48e65b82a1ef..44661e0057e7403888901e44464f5e319308d7eb 100644 --- a/src/riscv/lib/src/jit/builder.rs +++ b/src/riscv/lib/src/jit/builder.rs @@ -15,23 +15,23 @@ use super::state_access::{JitStateAccess, JsaCalls}; use crate::{ instruction_context::ICB, machine_state::{ - main_memory::{Address, MainMemoryLayout}, + memory::{Address, MemoryConfig}, registers::NonZeroXRegister as XRegister, }, }; /// Builder context used when lowering individual instructions within a block. -pub(super) struct Builder<'a, ML: MainMemoryLayout, JSA: JitStateAccess> { +pub(super) struct Builder<'a, MC: MemoryConfig, JSA: JitStateAccess> { /// Cranelift function builder pub builder: FunctionBuilder<'a>, /// Helpers for calling locally imported [JitStateAccess] methods. - pub jsa_call: JsaCalls<'a, ML, JSA>, + pub jsa_call: JsaCalls<'a, MC, JSA>, /// The IR-type of pointers on the current native platform pub ptr: Type, - /// Value representing a pointer to `MachineCoreState` + /// Value representing a pointer to `MachineCoreState` pub core_ptr_val: Value, /// Value representing a pointer to `steps: usize` @@ -47,7 +47,7 @@ pub(super) struct Builder<'a, ML: MainMemoryLayout, JSA: JitStateAccess> { pub pc_offset: Address, } -impl<'a, ML: MainMemoryLayout, JSA: JitStateAccess> Builder<'a, ML, JSA> { +impl<'a, MC: MemoryConfig, JSA: JitStateAccess> Builder<'a, MC, JSA> { /// Consume the builder, allowing for the function under construction to be [`finalised`]. /// /// [`finalised`]: super::JIT::finalise @@ -92,7 +92,7 @@ impl<'a, ML: MainMemoryLayout, JSA: JitStateAccess> Builder<'a, ML, JSA> { } } -impl<'a, ML: MainMemoryLayout, JSA: JitStateAccess> ICB for Builder<'a, ML, JSA> { +impl<'a, MC: MemoryConfig, JSA: JitStateAccess> ICB for Builder<'a, MC, JSA> { type XValue = Value; type IResult = Value; diff --git a/src/riscv/lib/src/jit/state_access.rs b/src/riscv/lib/src/jit/state_access.rs index 6ec871d3dfa365412809bdbd849baeff951fe137..b921e399ceac1a8d8d4299a0dafcb8fbd589fb0a 100644 --- a/src/riscv/lib/src/jit/state_access.rs +++ b/src/riscv/lib/src/jit/state_access.rs @@ -35,7 +35,7 @@ use cranelift_module::{FuncId, Linkage, Module, ModuleResult}; use crate::{ machine_state::{ MachineCoreState, - main_memory::MainMemoryLayout, + memory::MemoryConfig, registers::{NonZeroXRegister, XValue}, }, state_backend::{ManagerReadWrite, owned_backend::Owned}, @@ -54,36 +54,36 @@ const XREG_WRITE_SYMBOL: &str = "JSA::xreg_write"; /// - a way of calling those functions from within JIT-compiled code pub trait JitStateAccess: ManagerReadWrite { /// Update the instruction pc in the state. - extern "C" fn pc_write(core: &mut MachineCoreState, pc: u64); + extern "C" fn pc_write(core: &mut MachineCoreState, pc: u64); /// Read the value of the given [`NonZeroXRegister`]. - extern "C" fn xregister_read( - core: &mut MachineCoreState, + extern "C" fn xregister_read( + core: &mut MachineCoreState, reg: NonZeroXRegister, ) -> XValue; /// Write the given value to the given [`NonZeroXRegister`]. - extern "C" fn xregister_write( - core: &mut MachineCoreState, + extern "C" fn xregister_write( + core: &mut MachineCoreState, reg: NonZeroXRegister, val: XValue, ); } impl JitStateAccess for Owned { - extern "C" fn pc_write(core: &mut MachineCoreState, pc: u64) { + extern "C" fn pc_write(core: &mut MachineCoreState, pc: u64) { core.hart.pc.write(pc) } - extern "C" fn xregister_read( - core: &mut MachineCoreState, + extern "C" fn xregister_read( + core: &mut MachineCoreState, reg: NonZeroXRegister, ) -> XValue { core.hart.xregisters.read_nz(reg) } - extern "C" fn xregister_write( - core: &mut MachineCoreState, + extern "C" fn xregister_write( + core: &mut MachineCoreState, reg: NonZeroXRegister, val: XValue, ) { @@ -92,34 +92,34 @@ impl JitStateAccess for Owned { } /// Register state access symbols in the builder. -pub(super) fn register_jsa_symbols( +pub(super) fn register_jsa_symbols( builder: &mut JITBuilder, ) { builder.symbol( PC_WRITE_SYMBOL, - ::pc_write:: as *const u8, + ::pc_write:: as *const u8, ); builder.symbol( XREG_READ_SYMBOL, - ::xregister_read:: as *const u8, + ::xregister_read:: as *const u8, ); builder.symbol( XREG_WRITE_SYMBOL, - ::xregister_write:: as *const u8, + ::xregister_write:: as *const u8, ); } /// Identifications of globally imported [`JitStateAccess`] methods. -pub(super) struct JsaImports { +pub(super) struct JsaImports { pc_write: FuncId, xreg_read: FuncId, xreg_write: FuncId, - _pd: PhantomData<(ML, JSA)>, + _pd: PhantomData<(MC, JSA)>, } -impl JsaImports { +impl JsaImports { /// Register external functions within the JIT Module. pub(super) fn declare_in_module(module: &mut JITModule) -> ModuleResult { let call_conv = module.target_config().default_call_conv; @@ -168,18 +168,18 @@ impl JsaImports { /// References to locally imported [`JitStateAccess`] methods, used to directly call /// these accessor methods in the JIT-compilation context. -pub(super) struct JsaCalls<'a, ML: MainMemoryLayout, JSA: JitStateAccess> { +pub(super) struct JsaCalls<'a, MC: MemoryConfig, JSA: JitStateAccess> { module: &'a mut JITModule, - imports: &'a JsaImports, + imports: &'a JsaImports, pc_write: Option, xreg_read: Option, xreg_write: Option, - _pd: PhantomData<(ML, JSA)>, + _pd: PhantomData<(MC, JSA)>, } -impl<'a, ML: MainMemoryLayout, JSA: JitStateAccess> JsaCalls<'a, ML, JSA> { +impl<'a, MC: MemoryConfig, JSA: JitStateAccess> JsaCalls<'a, MC, JSA> { /// Wrapper to simplify calling JSA methods from within the function under construction. - pub(super) fn func_calls(module: &'a mut JITModule, imports: &'a JsaImports) -> Self { + pub(super) fn func_calls(module: &'a mut JITModule, imports: &'a JsaImports) -> Self { Self { module, imports, diff --git a/src/riscv/lib/src/machine_state.rs b/src/riscv/lib/src/machine_state.rs index 537849bccaf3c3997570cccfca712ebd9006ddbc..fe6b7615f9307e5b2526ced31319541ada2618f7 100644 --- a/src/riscv/lib/src/machine_state.rs +++ b/src/riscv/lib/src/machine_state.rs @@ -9,7 +9,7 @@ mod cache_layouts; pub mod csregisters; pub mod hart_state; pub mod instruction; -pub mod main_memory; +pub mod memory; pub mod mode; pub mod registers; pub mod reservation_set; @@ -33,7 +33,7 @@ use csregisters::CSRegister; use csregisters::{CSRRepr, values::CSRValue}; use hart_state::{HartState, HartStateLayout}; use instruction::Instruction; -use main_memory::{Address, MainMemory, OutOfBounds}; +use memory::{Address, Memory, MemoryConfig, OutOfBounds}; use mode::Mode; use crate::{ @@ -51,7 +51,11 @@ use crate::{ /// Layout for the machine 'run state' - which contains everything required for the running of /// instructions. -pub type MachineCoreStateLayout = (HartStateLayout, ML, TranslationCacheLayout); +pub type MachineCoreStateLayout = ( + HartStateLayout, + ::Layout, + TranslationCacheLayout, +); /// The part of the machine state required to run (almost all) instructions. /// @@ -60,15 +64,13 @@ pub type MachineCoreStateLayout = (HartStateLayout, ML, TranslationCacheLayo /// /// Certain instructions (e.g. `FENCE.I` may invalidate other parts of the state, but this are /// small in number). -pub struct MachineCoreState { +pub struct MachineCoreState { pub hart: HartState, - pub main_memory: MainMemory, + pub main_memory: MC::State, pub translation_cache: TranslationCache, } -impl Clone - for MachineCoreState -{ +impl Clone for MachineCoreState { fn clone(&self) -> Self { Self { hart: self.hart.clone(), @@ -79,28 +81,24 @@ impl Clone } /// Layout for the machine state - everything required to fetch & run instructions. -pub type MachineStateLayout = ( - MachineCoreStateLayout, - ::BlockCacheLayout, +pub type MachineStateLayout = ( + MachineCoreStateLayout, + ::BlockCacheLayout, ); /// The machine state contains everything required to fetch & run instructions. pub struct MachineState< - ML: main_memory::MainMemoryLayout, + MC: memory::MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: backend::ManagerBase, > { - pub core: MachineCoreState, - pub block_cache: BlockCache, B, ML, M>, + pub core: MachineCoreState, + pub block_cache: BlockCache, B, MC, M>, } -impl< - ML: main_memory::MainMemoryLayout, - CL: CacheLayouts, - B: Block + Clone, - M: backend::ManagerClone, -> Clone for MachineState +impl + Clone, M: backend::ManagerClone> + Clone for MachineState { fn clone(&self) -> Self { Self { @@ -144,7 +142,7 @@ macro_rules! run_no_args_instr { }}; } -impl MachineCoreState { +impl MachineCoreState { /// Handle an [`Exception`] if one was risen during execution /// of an instruction (also known as synchronous exception) by taking a trap. /// @@ -195,10 +193,10 @@ impl MachineCoreStat } /// Bind the machine state to the given allocated space. - pub fn bind(space: backend::AllocatedOf, M>) -> Self { + pub fn bind(space: backend::AllocatedOf, M>) -> Self { Self { hart: HartState::bind(space.0), - main_memory: MainMemory::bind(space.1), + main_memory: MC::bind(space.1), translation_cache: TranslationCache::bind(space.2), } } @@ -207,10 +205,10 @@ impl MachineCoreStat /// the constituents of `N` that were produced from the constituents of `&M`. pub fn struct_ref<'a, F: backend::FnManager>>( &'a self, - ) -> backend::AllocatedOf, F::Output> { + ) -> backend::AllocatedOf, F::Output> { ( self.hart.struct_ref::(), - self.main_memory.struct_ref::(), + MC::struct_ref::<_, F>(&self.main_memory), self.translation_cache.struct_ref::(), ) } @@ -220,7 +218,7 @@ impl MachineCoreStat where M: backend::ManagerReadWrite, { - self.hart.reset(main_memory::FIRST_ADDRESS); + self.hart.reset(memory::FIRST_ADDRESS); self.main_memory.reset(); self.translation_cache.reset(); } @@ -237,14 +235,14 @@ impl MachineCoreStat } } -impl, M: backend::ManagerBase> - MachineState +impl, M: backend::ManagerBase> + MachineState { /// Bind the block cache to the given allocated state and the given [block builder]. /// /// [block builder]: Block::BlockBuilder pub fn bind( - space: backend::AllocatedOf, M>, + space: backend::AllocatedOf, M>, block_builder: B::BlockBuilder, ) -> Self { Self { @@ -257,7 +255,7 @@ impl, M: ba /// the constituents of `N` that were produced from the constituents of `&M`. pub fn struct_ref<'a, F: backend::FnManager>>( &'a self, - ) -> backend::AllocatedOf, F::Output> { + ) -> backend::AllocatedOf, F::Output> { ( self.core.struct_ref::(), self.block_cache.struct_ref::(), @@ -591,7 +589,7 @@ impl, M: ba /// Install a program and set the program counter to its start. pub fn setup_boot( &mut self, - program: &Program, + program: &Program, initrd: Option<&[u8]>, mode: mode::Mode, ) -> Result<(), MachineError> @@ -614,7 +612,7 @@ impl, M: ba .iter() .map(|(base, data)| base + data.len() as Address) .max() - .unwrap_or(main_memory::FIRST_ADDRESS); + .unwrap_or(memory::FIRST_ADDRESS); // Write initial ramdisk, if any let (dtb_addr, initrd) = if let Some(initrd) = initrd { @@ -631,7 +629,7 @@ impl, M: ba }; // Write device tree to memory - let fdt = devicetree::generate::(initrd)?; + let fdt = devicetree::generate::(initrd)?; self.core.main_memory.write_all(dtb_addr, fdt.as_slice())?; // Point DTB boot argument (a1) at the written device tree @@ -677,7 +675,6 @@ mod tests { Instruction, OpCode, tagged_instruction::{TaggedArgs, TaggedInstruction, TaggedRegister}, }, - main_memory::tests::T1K, registers::XRegister, }; use crate::{ @@ -696,7 +693,7 @@ mod tests { satp::{Satp, TranslationAlgorithm}, xstatus::{self, MStatus}, }, - main_memory::{self, M1M, M8K}, + memory::{self, M1K, M1M, M8K, Memory}, mode::Mode, registers::{a0, a1, a2, nz, t0, t1, t2, zero}, }, @@ -713,16 +710,15 @@ mod tests { }, traps::{EnvironException, Exception, TrapContext}, }; - use crate::{bits::u64, machine_state::main_memory::M1K}; backend_test!(test_step, F, { let state = create_state!( MachineState, - MachineStateLayout, + MachineStateLayout, F, - T1K, + M1K, DefaultCacheLayouts, - Interpreted, || InterpretedBlockBuilder); + Interpreted, || InterpretedBlockBuilder); let state_cell = std::cell::RefCell::new(state); @@ -733,8 +729,8 @@ mod tests { let mut state = state_cell.borrow_mut(); state.reset(); - let init_pc_addr = main_memory::FIRST_ADDRESS + pc_addr_offset * 4; - let jump_addr = main_memory::FIRST_ADDRESS + jump_addr * 4; + let init_pc_addr = memory::FIRST_ADDRESS + pc_addr_offset * 4; + let jump_addr = memory::FIRST_ADDRESS + jump_addr * 4; // Instruction which performs a unit op (AUIPC with t0) const T2_ENC: u64 = 0b0_0111; // x7 @@ -772,11 +768,11 @@ mod tests { backend_test!(test_step_env_exc, F, { let state = create_state!( MachineState, - MachineStateLayout, + MachineStateLayout, F, - T1K, + M1K, DefaultCacheLayouts, - Interpreted, || InterpretedBlockBuilder); + Interpreted, || InterpretedBlockBuilder); let state_cell = std::cell::RefCell::new(state); @@ -788,7 +784,7 @@ mod tests { let mut state = state_cell.borrow_mut(); state.reset(); - let init_pc_addr = main_memory::FIRST_ADDRESS + pc_addr_offset * 4; + let init_pc_addr = memory::FIRST_ADDRESS + pc_addr_offset * 4; let stvec_addr = init_pc_addr + 4 * stvec_offset; let mtvec_addr = init_pc_addr + 4 * mtvec_offset; @@ -815,11 +811,11 @@ mod tests { backend_test!(test_step_exc_mm, F, { let state = create_state!( MachineState, - MachineStateLayout, + MachineStateLayout, F, - T1K, + M1K, DefaultCacheLayouts, - Interpreted, || InterpretedBlockBuilder); + Interpreted, || InterpretedBlockBuilder); let state_cell = std::cell::RefCell::new(state); @@ -830,7 +826,7 @@ mod tests { let mut state = state_cell.borrow_mut(); state.reset(); - let init_pc_addr = main_memory::FIRST_ADDRESS + pc_addr_offset * 4; + let init_pc_addr = memory::FIRST_ADDRESS + pc_addr_offset * 4; let mtvec_addr = init_pc_addr + 4 * mtvec_offset; const EBREAK: u64 = 1 << 20 | 0b111_0011; @@ -865,11 +861,11 @@ mod tests { backend_test!(test_step_exc_us, F, { let state = create_state!( MachineState, - MachineStateLayout, + MachineStateLayout, F, - T1K, + M1K, DefaultCacheLayouts, - Interpreted, || InterpretedBlockBuilder); + Interpreted, || InterpretedBlockBuilder); let state_cell = std::cell::RefCell::new(state); @@ -881,13 +877,13 @@ mod tests { let mut state = state_cell.borrow_mut(); state.reset(); - let init_pc_addr = main_memory::FIRST_ADDRESS + pc_addr_offset * 4; + let init_pc_addr = memory::FIRST_ADDRESS + pc_addr_offset * 4; let stvec_addr = init_pc_addr + 4 * stvec_offset; // stvec is in VECTORED mode state.core.hart.csregisters.write(CSRegister::stvec, stvec_addr | 1); - let bad_address = main_memory::FIRST_ADDRESS.wrapping_sub((pc_addr_offset + 10) * 4); + let bad_address = memory::FIRST_ADDRESS.wrapping_sub((pc_addr_offset + 10) * 4); let medeleg_val = 1 << Exception::IllegalInstruction.exception_code() | 1 << Exception::EnvCallFromSMode.exception_code() | 1 << Exception::EnvCallFromMMode.exception_code() | @@ -961,7 +957,7 @@ mod tests { ); state.reset(); - let start_ram = main_memory::FIRST_ADDRESS; + let start_ram = memory::FIRST_ADDRESS; // Write the instructions to the beginning of the main memory and point the program // counter at the first instruction. @@ -1040,8 +1036,8 @@ mod tests { // Test that the machine state does not behave differently when potential ephermeral state is // reset that may impact instruction address translation caching. backend_test!(test_instruction_address_cache, F, { - // Specify the physcal memory layout. - let main_mem_addr = main_memory::FIRST_ADDRESS; + // Specify the layout in physcal memory. + let main_mem_addr = memory::FIRST_ADDRESS; let code0_addr = main_mem_addr; let code1_addr = code0_addr + 4096; let root_page_table_addr = main_mem_addr + 16384; @@ -1327,7 +1323,7 @@ mod tests { }) .unwrap(); - let start_ram = main_memory::FIRST_ADDRESS; + let start_ram = memory::FIRST_ADDRESS; // Write the instructions to the beginning of the main memory and point the program // counter at the first instruction. @@ -1466,7 +1462,7 @@ mod tests { .unwrap(), ]; - let phys_addr = main_memory::FIRST_ADDRESS; + let phys_addr = memory::FIRST_ADDRESS; let block_b_addr = phys_addr + 128; diff --git a/src/riscv/lib/src/machine_state/address_translation.rs b/src/riscv/lib/src/machine_state/address_translation.rs index 2e6960633f27e1c061d08b32a4a747d69827fdc7..db86342fd9932a91d8ae1a9dd7340e83fcd3afb6 100644 --- a/src/riscv/lib/src/machine_state/address_translation.rs +++ b/src/riscv/lib/src/machine_state/address_translation.rs @@ -10,12 +10,12 @@ use super::{ CSRRepr, CSRegister, satp::{Satp, SvLength, TranslationAlgorithm}, }, - main_memory::{self, Address}, + memory::{self, Address, OutOfBounds}, mode::Mode, }; use crate::{ bits::Bits64, - machine_state::{address_translation::pte::PageTableEntry, main_memory::OutOfBounds}, + machine_state::{address_translation::pte::PageTableEntry, memory::Memory}, state_backend::{self as backend}, traps::Exception, }; @@ -74,15 +74,14 @@ impl SvLength { } /// Implementation of the virtual address translation as explained in section 5.3.2. -fn sv_translate_impl( - bus: &main_memory::MainMemory, +fn sv_translate_impl( + bus: &impl Memory, v_addr: Address, satp: Satp, sv_length: SvLength, access_type: AccessType, ) -> Result where - ML: main_memory::MainMemoryLayout, M: backend::ManagerRead, { use physical_address as p_addr; @@ -190,7 +189,7 @@ where p_addr.ok_or(access_type.exception(v_addr)) } -impl MachineCoreState { +impl MachineCoreState { /// Get the effective hart mode when addressing memory. /// Section P:M-ISA-1.6.3 /// The MPRV (Modify PRiVilege) bit modifies the effective privilege mode, i.e., diff --git a/src/riscv/lib/src/machine_state/address_translation/physical_address.rs b/src/riscv/lib/src/machine_state/address_translation/physical_address.rs index 6b00d2d456203a34d3f08af4bb3b86e5a6c60ab7..92c1db7546eb8845e14be366615a804b30ef163c 100644 --- a/src/riscv/lib/src/machine_state/address_translation/physical_address.rs +++ b/src/riscv/lib/src/machine_state/address_translation/physical_address.rs @@ -14,7 +14,7 @@ use super::PAGE_OFFSET_WIDTH; use crate::{ bits::{ones, u64}, - machine_state::{csregisters::satp::SvLength, main_memory::Address}, + machine_state::{csregisters::satp::SvLength, memory::Address}, }; /// Obtain `PPN[index]` from a PPN field specified by `sv_length` Standard. diff --git a/src/riscv/lib/src/machine_state/address_translation/translation_cache.rs b/src/riscv/lib/src/machine_state/address_translation/translation_cache.rs index a1412725bff17ca7419f008d3af92e1cccd670d9..21c0d2b9ad4e93b9905e882b8c592b51adeb2959 100644 --- a/src/riscv/lib/src/machine_state/address_translation/translation_cache.rs +++ b/src/riscv/lib/src/machine_state/address_translation/translation_cache.rs @@ -39,7 +39,7 @@ use super::{AccessType, PAGE_OFFSET_WIDTH}; use crate::{ bits::ones, cache_utils::FenceCounter, - machine_state::{csregisters::CSRRepr, main_memory::Address, mode::Mode}, + machine_state::{csregisters::CSRRepr, memory::Address, mode::Mode}, state_backend::{ AllocatedOf, Atom, Cell, FnManager, ManagerBase, ManagerClone, ManagerRead, ManagerReadWrite, ManagerWrite, Many, Ref, diff --git a/src/riscv/lib/src/machine_state/address_translation/virtual_address.rs b/src/riscv/lib/src/machine_state/address_translation/virtual_address.rs index 124cfe52a487470de49e5e502b326f136b33f604..627416bdc9576b0e5cfef554c02bdc699b770a35 100644 --- a/src/riscv/lib/src/machine_state/address_translation/virtual_address.rs +++ b/src/riscv/lib/src/machine_state/address_translation/virtual_address.rs @@ -16,7 +16,7 @@ use crate::{ bits::{ones, u64}, machine_state::{ csregisters::{CSRRepr, satp::SvLength}, - main_memory::Address, + memory::Address, }, }; diff --git a/src/riscv/lib/src/machine_state/block_cache.rs b/src/riscv/lib/src/machine_state/block_cache.rs index 6e37b39fe7b5b45c1dd98ba4230e24ea323a41c7..11396a04fd5b8756e0fa0de39e3e5de18aaa072e 100644 --- a/src/riscv/lib/src/machine_state/block_cache.rs +++ b/src/riscv/lib/src/machine_state/block_cache.rs @@ -86,11 +86,10 @@ use std::u64; use bcall::{BCall, Block}; -use super::MachineCoreState; use super::address_translation::PAGE_OFFSET_WIDTH; use super::instruction::Instruction; -use super::main_memory::MainMemoryLayout; -use super::{ProgramCounterUpdate, main_memory::Address}; +use super::{MachineCoreState, memory::MemoryConfig}; +use super::{ProgramCounterUpdate, memory::Address}; use crate::machine_state::address_translation::PAGE_SIZE; use crate::parser::instruction::InstrWidth; use crate::state_backend::{ @@ -113,12 +112,12 @@ const PAGE_OFFSET_MASK: usize = (1 << PAGE_OFFSET_WIDTH) - 1; pub const CACHE_INSTR: usize = 20; /// Layout for an [`ICallPlaced`]. -pub struct ICallLayout { - _pd: PhantomData, +pub struct ICallLayout { + _pd: PhantomData, } -impl state_backend::Layout for ICallLayout { - type Allocated = EnrichedCell, M>; +impl state_backend::Layout for ICallLayout { + type Allocated = EnrichedCell, M>; fn allocate(backend: &mut M) -> Self::Allocated { let value = backend.allocate_enriched_cell(Instruction::DEFAULT); @@ -126,13 +125,13 @@ impl state_backend::Layout for ICallLayout { } } -impl state_backend::CommitmentLayout for ICallLayout { +impl state_backend::CommitmentLayout for ICallLayout { fn state_hash(state: AllocatedOf) -> Result { Hash::blake2b_hash(state) } } -impl state_backend::ProofLayout for ICallLayout { +impl state_backend::ProofLayout for ICallLayout { fn to_merkle_tree( state: state_backend::RefProofGenOwnedAlloc, ) -> Result { @@ -159,14 +158,14 @@ impl state_backend::ProofLayout for ICallLayout { } /// Bindings for deriving an [`ICall`] from an [`Instruction`] via the [`EnrichedCell`] mechanism. -pub struct ICallPlaced { - _pd: PhantomData, +pub struct ICallPlaced { + _pd: PhantomData, } -impl EnrichedValue for ICallPlaced { +impl EnrichedValue for ICallPlaced { type E = Instruction; - type D = ICall; + type D = ICall; } /// A function derived from an [OpCode] that can be directly run over the [MachineCoreState]. @@ -175,37 +174,37 @@ impl EnrichedValue for ICallPlaced { /// rather than for each instruction, during each block execution. /// /// [OpCode]: super::instruction::OpCode -pub struct ICall { +pub struct ICall { /// SAFETY: This function must be called with an `Args` belonging to the same `OpCode` as /// the one used to dispatch this function. run_instr: - unsafe fn(&Args, &mut MachineCoreState) -> Result, + unsafe fn(&Args, &mut MachineCoreState) -> Result, } -impl Clone for ICall { +impl Clone for ICall { fn clone(&self) -> Self { *self } } -impl Copy for ICall {} +impl Copy for ICall {} -impl ICall { +impl ICall { // SAFETY: This function must be called with an `Args` belonging to the same `OpCode` as // the one used to dispatch this function. #[inline(always)] unsafe fn run( &self, args: &Args, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { (self.run_instr)(args, core) } } -impl<'a, ML: MainMemoryLayout, M: ManagerReadWrite> From<&'a Instruction> for ICall { +impl<'a, MC: MemoryConfig, M: ManagerReadWrite> From<&'a Instruction> for ICall { fn from(value: &'a Instruction) -> Self { - let run_instr = value.opcode.to_run::(); + let run_instr = value.opcode.to_run::(); Self { run_instr } } } @@ -240,26 +239,26 @@ impl state_backend::ProofLayout for AddressCellLayout { } /// The layout of block cache entries, see [`Cached`] for more information. -pub type CachedLayout = ( +pub type CachedLayout = ( AddressCellLayout, Atom, Atom, - [ICallLayout; CACHE_INSTR], + [ICallLayout; CACHE_INSTR], ); /// Block cache entry. /// /// Contains the physical address & fence counter for validity checks, the /// underlying [`Block`] state. -pub struct Cached, M: ManagerBase> { +pub struct Cached, M: ManagerBase> { block: B, address: Cell, fence_counter: Cell, - _pd: PhantomData, + _pd: PhantomData, } -impl, M: ManagerBase> Cached { - fn bind(space: AllocatedOf, M>) -> Self { +impl, M: ManagerBase> Cached { + fn bind(space: AllocatedOf, M>) -> Self { Self { address: space.0, fence_counter: space.1, @@ -296,7 +295,7 @@ impl, M: ManagerBase> Cached { fn struct_ref<'a, F: FnManager>>( &'a self, - ) -> AllocatedOf, F::Output> { + ) -> AllocatedOf, F::Output> { let (len_instr, instr) = self.block.struct_ref::<'a, F>(); ( self.address.struct_ref::(), @@ -307,7 +306,7 @@ impl, M: ManagerBase> Cached { } } -impl + Clone, M: ManagerClone> Clone for Cached { +impl + Clone, M: ManagerClone> Clone for Cached { fn clone(&self) -> Self { Self { address: self.address.clone(), @@ -389,70 +388,66 @@ impl PartialBlock { /// 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::CommitmentLayout + state_backend::ProofLayout { - type MainMemoryLayout: MainMemoryLayout; - type Entries, M: ManagerBase>; + type MemoryConfig: MemoryConfig; + + type Entries, M: ManagerBase>; + type Sizes; - fn bind, M: state_backend::ManagerBase>( + fn bind, M: state_backend::ManagerBase>( space: state_backend::AllocatedOf, block_builder: B::BlockBuilder, - ) -> BlockCache + ) -> BlockCache where Self: Sized; - fn entry, M: ManagerBase>( + fn entry, M: ManagerBase>( entries: &Self::Entries, phys_addr: Address, - ) -> &Cached; + ) -> &Cached; - fn entry_mut, M: ManagerBase>( + fn entry_mut, M: ManagerBase>( entries: &mut Self::Entries, phys_addr: Address, - ) -> &mut Cached; + ) -> &mut Cached; - fn entries_reset, M: ManagerReadWrite>( + fn entries_reset, M: ManagerReadWrite>( entries: &mut Self::Entries, ); - fn struct_ref< - 'a, - B: Block, - M: ManagerBase, - F: FnManager>, - >( - cache: &'a BlockCache, + fn struct_ref<'a, B: Block, M: ManagerBase, F: FnManager>>( + cache: &'a BlockCache, ) -> AllocatedOf where Self: Sized; - fn clone_entries + Clone, M: ManagerClone>( + fn clone_entries + Clone, M: ManagerClone>( entries: &Self::Entries, ) -> Self::Entries; } /// The layout of the block cache. -pub type Layout = ( +pub type Layout = ( AddressCellLayout, AddressCellLayout, Atom, PartialBlockLayout, - Sizes>, + Sizes>, ); -impl BlockCacheLayout - for Layout +impl BlockCacheLayout + for Layout { - type MainMemoryLayout = ML; + type MemoryConfig = MC; - type Entries, M: ManagerBase> = - Box<[Cached; SIZE]>; + type Entries, M: ManagerBase> = Box<[Cached; SIZE]>; - type Sizes = Sizes>; + type Sizes = Sizes>; - fn bind, M: ManagerBase>( + fn bind, M: ManagerBase>( space: AllocatedOf, block_builder: B::BlockBuilder, - ) -> BlockCache { + ) -> BlockCache { BlockCache { current_block_addr: space.0, next_instr_addr: space.1, @@ -470,33 +465,28 @@ impl BlockCacheLayou } } - fn entry, M: ManagerBase>( + fn entry, M: ManagerBase>( entries: &Self::Entries, phys_addr: Address, - ) -> &Cached { + ) -> &Cached { &entries[Self::Sizes::cache_index(phys_addr)] } - fn entry_mut, M: ManagerBase>( + fn entry_mut, M: ManagerBase>( entries: &mut Self::Entries, phys_addr: Address, - ) -> &mut Cached { + ) -> &mut Cached { &mut entries[Self::Sizes::cache_index(phys_addr)] } - fn entries_reset, M: ManagerReadWrite>( + fn entries_reset, M: ManagerReadWrite>( entries: &mut Self::Entries, ) { entries.iter_mut().for_each(Cached::reset) } - fn struct_ref< - 'a, - B: Block, - M: ManagerBase, - F: FnManager>, - >( - cache: &'a BlockCache, + fn struct_ref<'a, B: Block, M: ManagerBase, F: FnManager>>( + cache: &'a BlockCache, ) -> AllocatedOf { ( cache.current_block_addr.struct_ref::(), @@ -511,7 +501,7 @@ impl BlockCacheLayou ) } - fn clone_entries + Clone, M: ManagerClone>( + fn clone_entries + Clone, M: ManagerClone>( entries: &Self::Entries, ) -> Self::Entries { entries @@ -526,9 +516,9 @@ impl BlockCacheLayou /// /// The number of entries is controlled by the `BCL` layout parameter. pub struct BlockCache< - BCL: BlockCacheLayout, - B: Block, - ML: MainMemoryLayout, + BCL: BlockCacheLayout, + B: Block, + MC: MemoryConfig, M: ManagerBase, > { current_block_addr: Cell, @@ -539,12 +529,8 @@ pub struct BlockCache< block_builder: B::BlockBuilder, } -impl< - BCL: BlockCacheLayout, - B: Block, - ML: MainMemoryLayout, - M: ManagerBase, -> BlockCache +impl, B: Block, MC: MemoryConfig, M: ManagerBase> + BlockCache { /// Bind the block cache to the given allocated state and the given [block builder]. /// @@ -724,7 +710,7 @@ impl< pub fn get_block( &mut self, phys_addr: Address, - ) -> Option<&mut (impl BCall + ?Sized + '_)> + ) -> Option<&mut (impl BCall + ?Sized + '_)> where M: ManagerRead, { @@ -754,7 +740,7 @@ impl< /// which case we only executed instructions until `steps == steps_max`. pub fn complete_current_block( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, steps: &mut usize, max_steps: usize, ) -> Result<(), EnvironException> @@ -775,7 +761,7 @@ impl< /// and running a new block. pub fn run_block_partial( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, block_addr: Address, steps: &mut usize, max_steps: usize, @@ -793,7 +779,7 @@ impl< fn run_partial_inner( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, steps: &mut usize, max_steps: usize, ) -> Result<(), EnvironException> @@ -872,11 +858,11 @@ impl< } impl< - BCL: BlockCacheLayout, - B: Block + Clone, - ML: MainMemoryLayout, + BCL: BlockCacheLayout, + B: Block + Clone, + MC: MemoryConfig, M: ManagerClone, -> Clone for BlockCache +> Clone for BlockCache { fn clone(&self) -> Self { Self { @@ -891,9 +877,9 @@ impl< } #[inline(always)] -fn run_instr( - instr: &EnrichedCell, M>, - core: &mut MachineCoreState, +fn run_instr( + instr: &EnrichedCell, M>, + core: &mut MachineCoreState, ) -> Result { let args = instr.read_ref_stored().args(); let icall = instr.read_derived(); @@ -918,18 +904,18 @@ mod tests { Instruction, OpCode, tagged_instruction::{TaggedArgs, TaggedInstruction, TaggedRegister}, }, - main_memory::{self, tests::T1K}, + memory::{self, M1K, Memory}, mode::Mode, registers::{XRegister, a1, nz, t0, t1}, }, state_backend::{CommitmentLayout, owned_backend::Owned}, }; - pub type TestLayout = Layout; + 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 state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let uncompressed = Instruction::try_from(TaggedInstruction { opcode: OpCode::Sd, @@ -955,7 +941,7 @@ mod tests { }); backend_test!(test_writing_full_block_fetchable_compressed, F, { - let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let compressed = Instruction::try_from(TaggedInstruction { opcode: OpCode::Li, @@ -983,7 +969,7 @@ mod tests { // writing instructions immediately creates block backend_test!(test_writing_half_block_fetchable_compressed, F, { - let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let compressed = Instruction::try_from(TaggedInstruction { opcode: OpCode::Li, @@ -1010,7 +996,7 @@ mod tests { }); backend_test!(test_writing_two_blocks_fetchable_compressed, F, { - let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let compressed = Instruction::try_from(TaggedInstruction { opcode: OpCode::Li, @@ -1042,7 +1028,7 @@ mod tests { // writing across pages offset two blocks next to each other backend_test!(test_crossing_page_exactly_creates_new_block, F, { - let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let compressed = Instruction::try_from(TaggedInstruction { opcode: OpCode::Li, @@ -1073,8 +1059,8 @@ mod tests { }); backend_test!(test_partial_block_executes, F, { - let mut core_state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let mut block_state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut core_state = create_state!(MachineCoreState, MachineCoreStateLayout, F, M1K); + let mut block_state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let addiw = Instruction::try_from(TaggedInstruction { opcode: OpCode::Addiw, @@ -1088,7 +1074,7 @@ mod tests { }) .unwrap(); - let block_addr = main_memory::FIRST_ADDRESS; + let block_addr = memory::FIRST_ADDRESS; for offset in 0..10 { block_state.push_instr_uncompressed(block_addr + offset * 4, addiw); @@ -1146,7 +1132,7 @@ mod tests { }); backend_test!(test_concat_blocks_suitable, F, { - let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let uncompressed = Instruction::try_from(TaggedInstruction { opcode: OpCode::Sd, @@ -1184,7 +1170,7 @@ mod tests { }); backend_test!(test_concat_blocks_too_big, F, { - let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, T1K, || InterpretedBlockBuilder); + let mut state = create_state!(BlockCache, TestLayout, F, TestLayout, Interpreted, M1K, || InterpretedBlockBuilder); let uncompressed = Instruction::try_from(TaggedInstruction { opcode: OpCode::Sd, @@ -1230,9 +1216,9 @@ mod tests { fn test_enriched_cell_hashing() { let instr = Instruction::DEFAULT; - let ec_value = (instr, ICall::::from(&instr)); - let ec: EnrichedCell, Ref<'_, Owned>> = EnrichedCell::bind(&ec_value); - let ec_hash = as CommitmentLayout>::state_hash(ec).unwrap(); + let ec_value = (instr, ICall::::from(&instr)); + let ec: EnrichedCell, Ref<'_, Owned>> = EnrichedCell::bind(&ec_value); + let ec_hash = as CommitmentLayout>::state_hash(ec).unwrap(); let c_value = [instr; 1]; let c: Cell> = Cell::bind(&c_value); @@ -1244,20 +1230,20 @@ mod tests { /// blocks at address 0 which at one point were accidentally valid but empty which caused loops. #[test] fn test_init_block() { - type Layout = super::Layout; + type Layout = super::Layout; // This test only makes sense if the test cache size isn't 0. if TEST_CACHE_SIZE < 1 { panic!("Test cache size must be at least 1"); } - let check_block = |block: &mut BlockCache| { + let check_block = |block: &mut BlockCache| { for i in 0..TEST_CACHE_SIZE { assert!(block.get_block(i as Address).is_none()); } }; - let populate_block = |block: &mut BlockCache| { + let populate_block = |block: &mut BlockCache| { for i in 0..TEST_CACHE_SIZE { block.push_instr_uncompressed( i as Address, @@ -1275,7 +1261,7 @@ mod tests { } }; - let mut block: BlockCache, T1K, Owned> = + let mut block: BlockCache, M1K, Owned> = BlockCache::bind(Owned::allocate::(), InterpretedBlockBuilder); // The initial block cache should not return any blocks. @@ -1302,9 +1288,9 @@ mod tests { /// be empty, which causes the step function to loop indefinitely when it runs the block. #[test] fn test_run_addr_zero() { - type StateLayout = MachineStateLayout; + type StateLayout = MachineStateLayout; - let mut state: MachineState, Owned> = + let mut state: MachineState, Owned> = MachineState::bind(Owned::allocate::(), InterpretedBlockBuilder); // Encoding of ECALL instruction diff --git a/src/riscv/lib/src/machine_state/block_cache/bcall.rs b/src/riscv/lib/src/machine_state/block_cache/bcall.rs index bbad104730b28595952b32cb4a2fce02737b7884..4418b66059629a6f7f7d3b2be1a849d1c3a11f26 100644 --- a/src/riscv/lib/src/machine_state/block_cache/bcall.rs +++ b/src/riscv/lib/src/machine_state/block_cache/bcall.rs @@ -14,7 +14,7 @@ use crate::{ machine_state::{ MachineCoreState, ProgramCounterUpdate, instruction::Instruction, - main_memory::{Address, MainMemoryLayout}, + memory::{Address, MemoryConfig}, }, state_backend::{ AllocatedOf, Atom, Cell, EnrichedCell, FnManager, ManagerBase, ManagerClone, ManagerRead, @@ -28,7 +28,7 @@ use crate::{ /// /// This allows static dispatch of this block, via different strategies. Namely: /// interpretation and Just-In-Time compilation. -pub trait BCall { +pub trait BCall { /// The number of instructions contained in the block. /// /// Executing a block will consume up to `num_instr` steps. @@ -45,7 +45,7 @@ pub trait BCall { /// There _must_ also be sufficient steps remaining, to execute the block in full. fn run_block( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, instr_pc: Address, steps: &mut usize, ) -> Result<(), EnvironException> @@ -54,25 +54,25 @@ pub trait BCall { } /// State Layout for Blocks -pub type BlockLayout = (Atom, [ICallLayout; CACHE_INSTR]); +pub type BlockLayout = (Atom, [ICallLayout; CACHE_INSTR]); /// Functionality required to construct & execute blocks. /// /// A block is a sequence of at least one instruction, which may be executed sequentially. /// Blocks will never contain more than [`CACHE_INSTR`] instructions. -pub trait Block { +pub trait Block { /// Block construction may require additional state not kept in storage, /// this is then passed as a parameter to [`Block::complete_block`]. type BlockBuilder: Default; /// Bind the block to the given allocated state. - fn bind(allocated: AllocatedOf, M>) -> Self; + fn bind(allocated: AllocatedOf, M>) -> Self; /// Given a manager morphism `f : &M -> N`, return the layout's allocated structure containing /// the constituents of `N` that were produced from the constituents of `&M`. fn struct_ref<'a, F: FnManager>>( &'a self, - ) -> AllocatedOf, F::Output>; + ) -> AllocatedOf, F::Output>; /// Ready a block for construction. /// @@ -108,7 +108,7 @@ pub trait Block { M: ManagerReadWrite; /// Returns the underlying slice of instructions stored in the block. - fn instr(&self) -> &[EnrichedCell, M>] + fn instr(&self) -> &[EnrichedCell, M>] where M: ManagerRead; @@ -125,7 +125,7 @@ pub trait Block { unsafe fn callable<'a>( &mut self, block_builder: &'a Self::BlockBuilder, - ) -> Option<&mut (impl BCall + ?Sized + 'a)> + ) -> Option<&mut (impl BCall + ?Sized + 'a)> where M: ManagerRead + 'a; } @@ -141,12 +141,12 @@ pub struct InterpretedBlockBuilder; /// dispatching on every 'instruction run'. See [`ICall`] for more information. /// /// [`ICall`]: super::ICall -pub struct Interpreted { - instr: [EnrichedCell, M>; CACHE_INSTR], +pub struct Interpreted { + instr: [EnrichedCell, M>; CACHE_INSTR], len_instr: Cell, } -impl BCall for [EnrichedCell, M>] { +impl BCall for [EnrichedCell, M>] { #[inline] fn num_instr(&self) -> usize where @@ -157,7 +157,7 @@ impl BCall for [EnrichedCell, + core: &mut MachineCoreState, mut instr_pc: Address, steps: &mut usize, ) -> Result<(), EnvironException> @@ -174,7 +174,7 @@ impl BCall for [EnrichedCell Block for Interpreted { +impl Block for Interpreted { type BlockBuilder = InterpretedBlockBuilder; fn num_instr(&self) -> usize @@ -193,7 +193,7 @@ impl Block for Interpreted { } #[inline] - fn instr(&self) -> &[EnrichedCell, M>] + fn instr(&self) -> &[EnrichedCell, M>] where M: ManagerRead, { @@ -233,13 +233,13 @@ impl Block for Interpreted { self.len_instr.write(0); } - fn bind((len_instr, instr): AllocatedOf, M>) -> Self { + fn bind((len_instr, instr): AllocatedOf, M>) -> Self { Self { len_instr, instr } } fn struct_ref<'a, F: FnManager>>( &'a self, - ) -> AllocatedOf, F::Output> { + ) -> AllocatedOf, F::Output> { ( self.len_instr.struct_ref::(), self.instr.each_ref().map(|entry| entry.struct_ref::()), @@ -253,7 +253,7 @@ impl Block for Interpreted { unsafe fn callable<'a>( &mut self, _bb: &'a Self::BlockBuilder, - ) -> Option<&mut (impl BCall + ?Sized + 'a)> + ) -> Option<&mut (impl BCall + ?Sized + 'a)> where M: ManagerRead + 'a, { @@ -266,7 +266,7 @@ impl Block for Interpreted { } } -impl Clone for Interpreted { +impl Clone for Interpreted { fn clone(&self) -> Self { Self { len_instr: self.len_instr.clone(), @@ -281,13 +281,13 @@ impl Clone for Interpreted { /// unsupported instructions, a fallback to [`Interpreted`] mode occurs. /// /// Blocks are compiled upon calling [`Block::complete_block`], in a *stop the world* fashion. -pub struct InlineJit { - fallback: Interpreted, - jit_fn: Option>, +pub struct InlineJit { + fallback: Interpreted, + jit_fn: Option>, } -impl Block for InlineJit { - type BlockBuilder = (JIT, InterpretedBlockBuilder); +impl Block for InlineJit { + type BlockBuilder = (JIT, InterpretedBlockBuilder); fn start_block(&mut self) where @@ -321,14 +321,14 @@ impl Block for InlineJit self.fallback.push_instr(instr) } - fn instr(&self) -> &[EnrichedCell, M>] + fn instr(&self) -> &[EnrichedCell, M>] where M: ManagerRead, { self.fallback.instr() } - fn bind(allocated: AllocatedOf, M>) -> Self { + fn bind(allocated: AllocatedOf, M>) -> Self { Self { fallback: Interpreted::bind(allocated), jit_fn: None, @@ -337,19 +337,19 @@ impl Block for InlineJit fn struct_ref<'a, F: FnManager>>( &'a self, - ) -> AllocatedOf, F::Output> { + ) -> AllocatedOf, F::Output> { self.fallback.struct_ref::() } fn complete_block(&mut self, jit: &mut Self::BlockBuilder) { self.fallback.complete_block(&mut jit.1); - if >::num_instr(self) > 0 { + if >::num_instr(self) > 0 { let instr = self .fallback .instr .iter() - .take(>::num_instr(self)) + .take(>::num_instr(self)) .map(|i| i.read_ref_stored()); let jitfn = jit.0.compile(instr); @@ -368,7 +368,7 @@ impl Block for InlineJit unsafe fn callable<'a>( &mut self, block_builder: &'a Self::BlockBuilder, - ) -> Option<&mut (impl BCall + ?Sized + 'a)> + ) -> Option<&mut (impl BCall + ?Sized + 'a)> where M: ManagerRead + 'a, { @@ -387,7 +387,7 @@ impl Block for InlineJit } } -impl BCall for InlineJit { +impl BCall for InlineJit { fn num_instr(&self) -> usize where M: ManagerRead, @@ -397,7 +397,7 @@ impl BCall for InlineJit fn run_block( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, instr_pc: Address, steps: &mut usize, ) -> Result<(), EnvironException> @@ -417,9 +417,9 @@ impl BCall for InlineJit } } -fn run_block_inner( - instr: &[EnrichedCell, M>], - core: &mut MachineCoreState, +fn run_block_inner( + instr: &[EnrichedCell, M>], + core: &mut MachineCoreState, instr_pc: &mut Address, steps: &mut usize, ) -> Result<(), Exception> diff --git a/src/riscv/lib/src/machine_state/cache_layouts.rs b/src/riscv/lib/src/machine_state/cache_layouts.rs index a7f5281654bfead978d4689824181c129981ab5c..bfa91fbe3c96a34e3fc5554277031f29f7668ff9 100644 --- a/src/riscv/lib/src/machine_state/cache_layouts.rs +++ b/src/riscv/lib/src/machine_state/cache_layouts.rs @@ -10,7 +10,7 @@ use super::{ block_cache::{self, BlockCacheLayout}, - main_memory::MainMemoryLayout, + memory::MemoryConfig, }; /// Configuration bucket for the size of caches. @@ -19,14 +19,14 @@ pub enum Sizes {} /// Wrapping trait for a bucket containing layouts for various caches used by the machine state. pub trait CacheLayouts { /// Layout for the block cache - controlling the number of entries. - type BlockCacheLayout: BlockCacheLayout; + type BlockCacheLayout: BlockCacheLayout; } impl CacheLayouts for Sizes { - type BlockCacheLayout = - block_cache::Layout; + type BlockCacheLayout = + block_cache::Layout; } /// The default configuration of cache layouts. diff --git a/src/riscv/lib/src/machine_state/csregisters.rs b/src/riscv/lib/src/machine_state/csregisters.rs index 43f869242940d40f680146952518f530433b71d1..9e41975878ed6c5311cb3c49dbad52009471d76f 100644 --- a/src/riscv/lib/src/machine_state/csregisters.rs +++ b/src/riscv/lib/src/machine_state/csregisters.rs @@ -22,7 +22,7 @@ use self::{ values::CSRValue, xstatus::{ExtensionValue, MNStatus, MStatus, SStatus}, }; -use super::{hart_state::HartState, main_memory::Address, mode::TrapMode}; +use super::{hart_state::HartState, memory::Address, mode::TrapMode}; use crate::{ bits::{Bits64, ones, u64}, machine_state::mode::Mode, diff --git a/src/riscv/lib/src/machine_state/hart_state.rs b/src/riscv/lib/src/machine_state/hart_state.rs index 06dbea007f3b46b381f1be4edd7ff1f4467eb2a6..09bf0ee5ee9847750a588d22d71f473888904486 100644 --- a/src/riscv/lib/src/machine_state/hart_state.rs +++ b/src/riscv/lib/src/machine_state/hart_state.rs @@ -9,7 +9,7 @@ use crate::{ default::ConstDefault, machine_state::{ csregisters::{self, CSRegister, xstatus}, - main_memory::Address, + memory::Address, mode::{Mode, TrapMode}, registers, reservation_set::{self, ReservationSet}, diff --git a/src/riscv/lib/src/machine_state/instruction.rs b/src/riscv/lib/src/machine_state/instruction.rs index 535283b5bf2ff8681cc7f93d77456bcbd2474dc1..5a039103b8c08a3555348eed950538a21ceb37cb 100644 --- a/src/riscv/lib/src/machine_state/instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction.rs @@ -23,7 +23,7 @@ use tagged_instruction::{ArgsShape, TaggedInstruction, opcode_to_argsshape}; use super::{ MachineCoreState, ProgramCounterUpdate, csregisters::CSRegister, - main_memory::MainMemoryLayout, + memory::MemoryConfig, registers::{FRegister, NonZeroXRegister, XRegister}, }; use crate::{ @@ -368,9 +368,9 @@ impl OpCode { /// Calling the returned function **must** correspond to an `Args` belonging to an /// instruction where the `OpCode` is the same as the `OpCode` of the current instruction. #[inline(always)] - pub(super) fn to_run( + pub(super) fn to_run( self, - ) -> unsafe fn(&Args, &mut MachineCoreState) -> Result + ) -> unsafe fn(&Args, &mut MachineCoreState) -> Result { match self { Self::Add => Args::run_add, @@ -578,9 +578,9 @@ impl OpCode { impl Instruction { /// Run an instruction over the machine core state. - pub(super) fn run( + pub(super) fn run( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { // SAFETY: Unsafe accesses in this function are due to using the [Register] union, // which is safe as the registers used are validated against the opcode. @@ -665,9 +665,9 @@ macro_rules! impl_r_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart.xregisters.$fn(self.rs1.x, self.rs2.x, self.rd.x); Ok(Next(self.width)) @@ -677,9 +677,9 @@ macro_rules! impl_r_type { ($fn: ident, non_zero) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .xregisters @@ -691,9 +691,9 @@ macro_rules! impl_r_type { ($fn: ident, non_zero_rd) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .xregisters @@ -716,9 +716,9 @@ macro_rules! impl_i_type { ($fn: ident, non_zero) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .xregisters @@ -730,9 +730,9 @@ macro_rules! impl_i_type { ($fn: ident, non_zero_rd) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart.xregisters.$fn(self.imm, self.rs1.x, self.rd.nzx); Ok(Next(self.width)) @@ -744,9 +744,9 @@ macro_rules! impl_fload_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rs1.x, self.rd.f) .map(|_| Next(self.width)) @@ -757,9 +757,9 @@ macro_rules! impl_load_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rs1.x, self.rd.x) .map(|_| Next(self.width)) @@ -770,9 +770,9 @@ macro_rules! impl_cload_sp_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rd.nzx).map(|_| Next(self.width)) } @@ -782,9 +782,9 @@ macro_rules! impl_cfload_sp_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rd.f).map(|_| Next(self.width)) } @@ -795,9 +795,9 @@ macro_rules! impl_store_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rs1.x, self.rs2.x) .map(|_| Next(self.width)) @@ -808,9 +808,9 @@ macro_rules! impl_fstore_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rs1.x, self.rs2.f) .map(|_| Next(self.width)) @@ -822,9 +822,9 @@ macro_rules! impl_b_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(core.hart.$fn(self.imm, self.rs1.x, self.rs2.x, self.width)) } @@ -833,9 +833,9 @@ macro_rules! impl_b_type { ($fn: ident, non_zero) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(core .hart @@ -848,9 +848,9 @@ macro_rules! impl_amo_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.rs1.x, self.rs2.x, self.rd.x, self.rl, self.aq) .map(|_| Next(self.width)) @@ -862,9 +862,9 @@ macro_rules! impl_ci_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart.xregisters.$fn(self.imm, self.rd.x); Ok(ProgramCounterUpdate::Next(self.width)) @@ -874,9 +874,9 @@ macro_rules! impl_ci_type { ($fn: ident, non_zero) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart.xregisters.$fn(self.imm, self.rd.nzx); Ok(ProgramCounterUpdate::Next(self.width)) @@ -897,9 +897,9 @@ macro_rules! impl_cr_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart.xregisters.$fn(self.rd.x, self.rs2.x); Ok(ProgramCounterUpdate::Next(self.width)) @@ -909,9 +909,9 @@ macro_rules! impl_cr_type { ($fn: ident, non_zero) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart.xregisters.$fn(self.rd.nzx, self.rs2.nzx); Ok(ProgramCounterUpdate::Next(self.width)) @@ -934,9 +934,9 @@ macro_rules! impl_cb_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(core.hart.$fn(self.imm, self.rs1.nzx, self.width)) } @@ -947,9 +947,9 @@ macro_rules! impl_css_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rs2.x).map(|_| Next(self.width)) } @@ -960,9 +960,9 @@ macro_rules! impl_fcss_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.$fn(self.imm, self.rs2.f).map(|_| Next(self.width)) } @@ -973,9 +973,9 @@ macro_rules! impl_csr_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.csr, self.rs1.x, self.rd.x) @@ -988,9 +988,9 @@ macro_rules! impl_csr_imm_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.csr, self.imm as u64, self.rd.x) @@ -1003,9 +1003,9 @@ macro_rules! impl_f_x_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.x, self.rd.f) @@ -1016,9 +1016,9 @@ macro_rules! impl_f_x_type { ($fn:ident, rm) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.x, self.rm, self.rd.f) @@ -1031,9 +1031,9 @@ macro_rules! impl_x_f_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.f, self.rd.x) @@ -1044,9 +1044,9 @@ macro_rules! impl_x_f_type { ($fn:ident, rm) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.f, self.rm, self.rd.x) @@ -1059,9 +1059,9 @@ macro_rules! impl_f_r_type { ($fn: ident) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.f, self.rs2.f, self.rd.f) @@ -1072,9 +1072,9 @@ macro_rules! impl_f_r_type { ($fn: ident, (rd, x)) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.f, self.rs2.f, self.rd.x) @@ -1085,9 +1085,9 @@ macro_rules! impl_f_r_type { ($fn: ident, rm) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.f, self.rm, self.rd.f) @@ -1098,9 +1098,9 @@ macro_rules! impl_f_r_type { ($fn: ident, (rs2, f), $($field: ident),+) => { /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn $fn( + unsafe fn $fn( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart .$fn(self.rs1.f, self.rs2.f, $(self.$field,)* self.rd.f) @@ -1166,9 +1166,9 @@ impl Args { // RV64I U-type instructions /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn run_auipc( + unsafe fn run_auipc( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { core.hart.run_auipc(self.imm, self.rd.nzx); Ok(Next(self.width)) @@ -1178,18 +1178,18 @@ impl Args { // /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn run_jal( + unsafe fn run_jal( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(Set(core.hart.run_jal(self.imm, self.rd.nzx, self.width))) } /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn run_jalr( + unsafe fn run_jalr( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(Set(core.hart.run_jalr(self.imm, self.rs1.x, self.rd.x))) } @@ -1318,27 +1318,27 @@ impl Args { impl_cr_type!(run_neg, non_zero); impl_css_type!(run_cswsp); - fn run_j( + fn run_j( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(Set(core.hart.run_j(self.imm))) } /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn run_cjr( + unsafe fn run_cjr( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(Set(core.hart.run_cjr(self.rs1.nzx))) } /// SAFETY: This function must only be called on an `Args` belonging /// to the same OpCode as the OpCode used to derive this function. - unsafe fn run_cjalr( + unsafe fn run_cjalr( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> Result { Ok(Set(core.hart.run_cjalr(self.rs1.nzx))) } @@ -1364,9 +1364,9 @@ impl Args { impl_fcss_type!(run_cfsdsp); // Unknown - fn run_illegal( + fn run_illegal( &self, - _core: &mut MachineCoreState, + _core: &mut MachineCoreState, ) -> Result { Err(Exception::IllegalInstruction) } diff --git a/src/riscv/lib/src/machine_state/main_memory.rs b/src/riscv/lib/src/machine_state/main_memory.rs deleted file mode 100644 index 8c7498495d359de1cd10aeaf64902e0080ef4fe4..0000000000000000000000000000000000000000 --- a/src/riscv/lib/src/machine_state/main_memory.rs +++ /dev/null @@ -1,348 +0,0 @@ -// SPDX-FileCopyrightText: 2023 TriliTech -// SPDX-FileCopyrightText: 2024-2025 Nomadic Labs -// -// SPDX-License-Identifier: MIT - -use std::mem; - -use serde::{Deserialize, Serialize}; -use tezos_smart_rollup_constants::riscv::SbiError; -use thiserror::Error; - -use crate::{ - machine_state::registers::XValue, - state_backend::{self as backend, ManagerDeserialise, ManagerSerialise}, -}; - -/// Bus address -pub type Address = XValue; - -/// An address is out of bounds. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Error, derive_more::Display)] -pub struct OutOfBounds; - -impl From for SbiError { - fn from(_value: OutOfBounds) -> Self { - SbiError::InvalidAddress - } -} - -/// The first valid memory address. -pub const FIRST_ADDRESS: Address = 0; - -/// Generates a [`backend::DynArray`] layout type given a memory size. -macro_rules! gen_memory_layout { - ($name:ident = $size_in_g:literal GiB) => { - pub type $name = crate::state_backend::DynArray<{ $size_in_g * 1024 * 1024 * 1024 }>; - }; - - ($name:ident = $size_in_m:literal MiB) => { - pub type $name = crate::state_backend::DynArray<{ $size_in_m * 1024 * 1024 }>; - }; - - ($name:ident = $size_in_k:literal KiB) => { - pub type $name = crate::state_backend::DynArray<{ $size_in_k * 1024 }>; - }; -} - -gen_memory_layout!(M1K = 1 KiB); -gen_memory_layout!(M8K = 8 KiB); -gen_memory_layout!(M1M = 1 MiB); -gen_memory_layout!(M64M = 64 MiB); -gen_memory_layout!(M1G = 1 GiB); -gen_memory_layout!(M4G = 4 GiB); - -/// Main memory layout, i.e. specifies how much memory there is -// XXX: We can't associate these layout types directly with [`backend::DynArray`] because -// inherent associated types are unstable. Hence we must go through a dummy -// trait. -pub trait MainMemoryLayout: backend::ProofLayout + backend::CommitmentLayout + 'static { - const BYTES: usize; - - /// Given a manager morphism `f : &M -> N`, return the layout's allocated structure containing - /// the constituents of `N` that were produced from the constituents of `&M`. - fn data_struct_ref< - 'a, - M: backend::ManagerBase + 'a, - F: backend::FnManager>, - >( - data: &'a Self::Allocated, - ) -> backend::AllocatedOf; - - /// Read an element in the region. `address` is in bytes. - fn data_read( - data: &Self::Allocated, - address: usize, - ) -> E; - - /// Read elements from the region. `address` is in bytes. - fn data_read_all( - data: &Self::Allocated, - address: usize, - values: &mut [E], - ); - - /// Update an element in the region. `address` is in bytes. - fn data_write( - data: &mut Self::Allocated, - address: usize, - value: E, - ); - - /// Update multiple elements in the region. `address` is in bytes. - fn data_write_all( - data: &mut Self::Allocated, - address: usize, - values: &[E], - ); - - /// Serialise main memory's dynamic region. - fn serialise_data( - data: &Self::Allocated, - serializer: S, - ) -> Result; - - /// Deserialise main memory's dynamic region. - fn deserialise_data<'de, M: ManagerDeserialise, D: serde::Deserializer<'de>>( - deserializer: D, - ) -> Result, D::Error>; - - /// Clone the dynamic region. - fn clone_data(data: &Self::Allocated) -> Self::Allocated; -} - -impl MainMemoryLayout for backend::DynArray { - const BYTES: usize = BYTES; - - fn data_struct_ref<'a, M: backend::ManagerBase, F: backend::FnManager>>( - data: &'a Self::Allocated, - ) -> backend::AllocatedOf { - data.struct_ref::() - } - - fn data_read( - data: &Self::Allocated, - address: usize, - ) -> E { - data.read(address) - } - - fn data_read_all( - data: &Self::Allocated, - address: usize, - values: &mut [E], - ) { - data.read_all(address, values); - } - - fn data_write( - data: &mut Self::Allocated, - address: usize, - value: E, - ) { - data.write(address, value); - } - - fn data_write_all( - data: &mut Self::Allocated, - address: usize, - values: &[E], - ) { - data.write_all(address, values); - } - - fn serialise_data( - data: &Self::Allocated, - serializer: S, - ) -> Result { - data.serialize(serializer) - } - - fn deserialise_data<'de, M: ManagerDeserialise, D: serde::Deserializer<'de>>( - deserializer: D, - ) -> Result, D::Error> { - serde::Deserialize::deserialize(deserializer) - } - - fn clone_data(data: &Self::Allocated) -> Self::Allocated { - data.clone() - } -} - -/// Main memory state for the given layout -pub struct MainMemory { - pub data: backend::AllocatedOf, -} - -impl MainMemory { - /// Bind the main memory state to the given allocated space. - pub fn bind(space: backend::AllocatedOf) -> Self { - MainMemory { data: space } - } - - /// Given a manager morphism `f : &M -> N`, return the layout's allocated structure containing - /// the constituents of `N` that were produced from the constituents of `&M`. - pub fn struct_ref<'a, F: backend::FnManager>>( - &'a self, - ) -> backend::AllocatedOf - where - M: 'a, - { - L::data_struct_ref::<_, F>(&self.data) - } - - /// Reset to the initial state. - pub fn reset(&mut self) - where - M: backend::ManagerWrite, - { - for i in 0..L::BYTES { - L::data_write(&mut self.data, i, 0u8); - } - } - - /// Read a value from memory. - #[inline(always)] - pub fn read(&self, addr: Address) -> Result - where - M: backend::ManagerRead, - { - if addr as usize + mem::size_of::() > L::BYTES { - return Err(OutOfBounds); - } - - Ok(L::data_read(&self.data, addr as usize)) - } - - /// Read multiple values from memory. - #[inline(always)] - pub fn read_all( - &self, - addr: Address, - values: &mut [E], - ) -> Result<(), OutOfBounds> - where - M: backend::ManagerRead, - { - if addr as usize + mem::size_of_val(values) > L::BYTES { - return Err(OutOfBounds); - } - - L::data_read_all(&self.data, addr as usize, values); - - Ok(()) - } - - /// Write a value to memory. - pub fn write(&mut self, addr: Address, value: E) -> Result<(), OutOfBounds> - where - M: backend::ManagerWrite, - { - if addr as usize + mem::size_of::() > L::BYTES { - return Err(OutOfBounds); - } - - L::data_write(&mut self.data, addr as usize, value); - - Ok(()) - } - - /// Write multiple values to memory. - pub fn write_all( - &mut self, - addr: Address, - values: &[E], - ) -> Result<(), OutOfBounds> - where - M: backend::ManagerWrite, - { - let addr = addr as usize; - - if addr + mem::size_of_val(values) > L::BYTES { - return Err(OutOfBounds); - } - - L::data_write_all(&mut self.data, addr, values); - - Ok(()) - } -} - -impl Serialize for MainMemory { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - L::serialise_data(&self.data, serializer) - } -} - -impl<'de, L, M> Deserialize<'de> for MainMemory -where - L: MainMemoryLayout, - M: ManagerDeserialise, -{ - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let data = L::deserialise_data(deserializer)?; - Ok(Self { data }) - } -} - -impl Clone for MainMemory { - fn clone(&self) -> Self { - Self { - data: L::clone_data(&self.data), - } - } -} - -impl - PartialEq> for MainMemory -{ - fn eq(&self, other: &MainMemory) -> bool { - (0..L::BYTES) - .all(|i| L::data_read::(&self.data, i) == L::data_read::(&other.data, i)) - } -} - -#[cfg(test)] -pub mod tests { - use super::*; - use crate::{backend_test, create_state}; - - gen_memory_layout!(T1K = 1 KiB); - - backend_test!(test_endianess, F, { - let mut memory = create_state!(MainMemory, T1K, F, T1K); - - memory.write(0, 0x1122334455667788u64).unwrap(); - - macro_rules! check_address { - ($ty:ty, $addr:expr, $value:expr) => { - assert_eq!(memory.read::<$ty>($addr), Ok($value)); - }; - } - - check_address!(u64, 0, 0x1122334455667788); - - check_address!(u32, 0, 0x55667788); - check_address!(u32, 4, 0x11223344); - - check_address!(u16, 0, 0x7788); - check_address!(u16, 2, 0x5566); - check_address!(u16, 4, 0x3344); - check_address!(u16, 6, 0x1122); - - check_address!(u8, 0, 0x88); - check_address!(u8, 1, 0x77); - check_address!(u8, 2, 0x66); - check_address!(u8, 3, 0x55); - check_address!(u8, 4, 0x44); - check_address!(u8, 5, 0x33); - check_address!(u8, 6, 0x22); - check_address!(u8, 7, 0x11); - }); -} diff --git a/src/riscv/lib/src/machine_state/memory.rs b/src/riscv/lib/src/machine_state/memory.rs new file mode 100644 index 0000000000000000000000000000000000000000..07e9e5d8a72592a8945f7db6a0d15e3b340d8dc8 --- /dev/null +++ b/src/riscv/lib/src/machine_state/memory.rs @@ -0,0 +1,106 @@ +// SPDX-FileCopyrightText: 2025 TriliTech +// +// SPDX-License-Identifier: MIT + +mod config; +mod state; + +use tezos_smart_rollup_constants::riscv::SbiError; +use thiserror::Error; + +use super::registers::XValue; +use crate::state_backend::{ + AllocatedOf, CommitmentLayout, Elem, FnManager, ManagerBase, ManagerClone, ManagerDeserialise, + ManagerRead, ManagerSerialise, ManagerWrite, ProofLayout, Ref, +}; + +/// Memory address +pub type Address = XValue; + +/// Lowest address +pub const FIRST_ADDRESS: Address = 0; + +/// Address out of bounds error +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Error, derive_more::Display)] +pub struct OutOfBounds; + +impl From for SbiError { + fn from(_value: OutOfBounds) -> Self { + SbiError::InvalidAddress + } +} + +/// Instance of memory +pub trait Memory: Sized { + /// Read an element in the region. `address` is in bytes. + fn read(&self, address: Address) -> Result + where + E: Elem, + M: ManagerRead; + + /// Read elements from the region. `address` is in bytes. + fn read_all(&self, address: Address, values: &mut [E]) -> Result<(), OutOfBounds> + where + E: Elem, + M: ManagerRead; + + /// Update an element in the region. `address` is in bytes. + fn write(&mut self, address: Address, value: E) -> Result<(), OutOfBounds> + where + E: Elem, + M: ManagerWrite; + + /// Update multiple elements in the region. `address` is in bytes. + fn write_all(&mut self, address: Address, values: &[E]) -> Result<(), OutOfBounds> + where + E: Elem, + M: ManagerWrite; + + /// Serialise memory. + fn serialise(&self, serializer: S) -> Result + where + M: ManagerSerialise, + S: serde::Serializer; + + /// Deserialise memory. + fn deserialise<'de, D>(deserializer: D) -> Result + where + M: ManagerDeserialise, + D: serde::Deserializer<'de>; + + /// Clone all memory. + fn clone(&self) -> Self + where + M: ManagerClone; + + /// Zero-out all memory. + fn reset(&mut self) + where + M: ManagerWrite; +} + +/// Memory configuration +pub trait MemoryConfig: 'static { + /// Number of bytes in the memory + const TOTAL_BYTES: usize; + + /// Layout for memory instance's state + type Layout: CommitmentLayout + ProofLayout; + + /// Memory instance + type State: Memory; + + /// Bind the allocated regions to produce a memory instance. + fn bind(space: AllocatedOf) -> Self::State; + + /// Given a manager morphism `f : &M -> N`, return the memory instance layout's allocated + /// structure containing the constituents of `N` that were produced from the constituents of + /// `&M`. + fn struct_ref<'a, M, F>(instance: &'a Self::State) -> AllocatedOf + where + M: ManagerBase, + F: FnManager>; +} + +// Re-export memory configurations +pub use config::{M1G, M1K, M1M, M4G, M8K, M64M}; diff --git a/src/riscv/lib/src/machine_state/memory/config.rs b/src/riscv/lib/src/machine_state/memory/config.rs new file mode 100644 index 0000000000000000000000000000000000000000..a212c1995719846c960aea15846f3f0e63832584 --- /dev/null +++ b/src/riscv/lib/src/machine_state/memory/config.rs @@ -0,0 +1,55 @@ +// SPDX-FileCopyrightText: 2025 TriliTech +// +// SPDX-License-Identifier: MIT + +use super::state::MemoryImpl; +use crate::state_backend::{AllocatedOf, DynArray, FnManager, ManagerBase, Ref}; + +/// State layout for the memory component +pub struct MemoryConfig(DynArray); + +impl super::MemoryConfig for MemoryConfig { + const TOTAL_BYTES: usize = TOTAL_BYTES; + + type Layout = DynArray; + + type State = MemoryImpl; + + fn bind(space: AllocatedOf) -> Self::State { + if TOTAL_BYTES == 0 { + panic!("Memory size must be positive"); + } + + MemoryImpl { data: space } + } + + fn struct_ref<'a, M, F>(instance: &'a Self::State) -> AllocatedOf + where + M: ManagerBase, + F: FnManager>, + { + instance.data.struct_ref::() + } +} + +/// Generates a valid memory configuration. +macro_rules! gen_memory_layout { + ($name:ident = $size_in_g:literal GiB) => { + pub type $name = MemoryConfig<{ $size_in_g * 1024 * 1024 * 1024 }>; + }; + + ($name:ident = $size_in_m:literal MiB) => { + pub type $name = MemoryConfig<{ $size_in_m * 1024 * 1024 }>; + }; + + ($name:ident = $size_in_k:literal KiB) => { + pub type $name = MemoryConfig<{ $size_in_k * 1024 }>; + }; +} + +gen_memory_layout!(M1K = 1 KiB); +gen_memory_layout!(M8K = 8 KiB); +gen_memory_layout!(M1M = 1 MiB); +gen_memory_layout!(M64M = 64 MiB); +gen_memory_layout!(M1G = 1 GiB); +gen_memory_layout!(M4G = 4 GiB); diff --git a/src/riscv/lib/src/machine_state/memory/state.rs b/src/riscv/lib/src/machine_state/memory/state.rs new file mode 100644 index 0000000000000000000000000000000000000000..69259e52a8bf0ddf697be2ba59a401fb602c87db --- /dev/null +++ b/src/riscv/lib/src/machine_state/memory/state.rs @@ -0,0 +1,182 @@ +// SPDX-FileCopyrightText: 2025 TriliTech +// +// SPDX-License-Identifier: MIT + +use std::mem; + +use serde::{Deserialize, Serialize}; + +use super::{Address, Memory, OutOfBounds}; +use crate::state_backend::{ + DynCells, Elem, ManagerBase, ManagerClone, ManagerDeserialise, ManagerRead, ManagerSerialise, + ManagerWrite, +}; + +/// Machine's memory +pub struct MemoryImpl { + pub(super) data: DynCells, +} + +impl MemoryImpl { + /// Ensure the access is within bounds. + #[inline] + fn check_bounds(address: Address, length: usize) -> Result<(), OutOfBounds> { + if length > TOTAL_BYTES.saturating_sub(address as usize) { + return Err(OutOfBounds); + } + + Ok(()) + } +} + +impl Memory for MemoryImpl +where + M: ManagerBase, +{ + #[inline] + fn read(&self, address: Address) -> Result + where + E: Elem, + M: ManagerRead, + { + Self::check_bounds(address, mem::size_of::())?; + Ok(self.data.read(address as usize)) + } + + fn read_all(&self, address: Address, values: &mut [E]) -> Result<(), OutOfBounds> + where + E: Elem, + M: ManagerRead, + { + Self::check_bounds(address, mem::size_of_val(values))?; + self.data.read_all(address as usize, values); + Ok(()) + } + + #[inline] + fn write(&mut self, address: Address, value: E) -> Result<(), OutOfBounds> + where + E: Elem, + M: ManagerWrite, + { + Self::check_bounds(address, mem::size_of::())?; + self.data.write(address as usize, value); + Ok(()) + } + + fn write_all(&mut self, address: Address, values: &[E]) -> Result<(), OutOfBounds> + where + E: Elem, + M: ManagerWrite, + { + Self::check_bounds(address, mem::size_of_val(values))?; + self.data.write_all(address as usize, values); + Ok(()) + } + + fn serialise(&self, serializer: S) -> Result + where + M: ManagerSerialise, + S: serde::Serializer, + { + self.data.serialize(serializer) + } + + fn deserialise<'de, D>(deserializer: D) -> Result + where + M: ManagerDeserialise, + D: serde::Deserializer<'de>, + { + let data = DynCells::deserialize(deserializer)?; + Ok(Self { data }) + } + + fn clone(&self) -> Self + where + M: ManagerClone, + { + Self { + data: self.data.clone(), + } + } + + fn reset(&mut self) + where + M: ManagerWrite, + { + const SIZE_OF_U64: usize = mem::size_of::(); + + let mut address = 0; + let mut outstanding = TOTAL_BYTES; + + // Write 64-bit chunks + while outstanding >= SIZE_OF_U64 { + self.data.write(address, 0u64); + address += SIZE_OF_U64; + outstanding -= SIZE_OF_U64; + } + + // Write remaining bytes + for i in 0..outstanding { + self.data.write(address.saturating_add(i), 0u8); + } + } +} + +#[cfg(test)] +pub mod tests { + use super::*; + use crate::{ + backend_test, + machine_state::memory::{M1K, Memory, MemoryConfig}, + state_backend::owned_backend::Owned, + }; + + #[test] + fn bounds_check() { + // Zero-sized reads or writes are always valid + assert!(MemoryImpl::<0, Owned>::check_bounds(0, 0).is_ok()); + assert!(MemoryImpl::<0, Owned>::check_bounds(1, 0).is_ok()); + assert!(MemoryImpl::<32, Owned>::check_bounds(0, 0).is_ok()); + assert!(MemoryImpl::<32, Owned>::check_bounds(32, 0).is_ok()); + assert!(MemoryImpl::<32, Owned>::check_bounds(64, 0).is_ok()); + + // Bounds checks + assert!(MemoryImpl::<0, Owned>::check_bounds(0, 1).is_err()); + assert!(MemoryImpl::<0, Owned>::check_bounds(1, 1).is_err()); + assert!(MemoryImpl::<32, Owned>::check_bounds(32, 1).is_err()); + assert!(MemoryImpl::<32, Owned>::check_bounds(64, 1).is_err()); + } + + backend_test!(test_endianess, F, { + let space = F::allocate::<::Layout>(); + let mut memory = M1K::bind(space); + + memory.write(0, 0x1122334455667788u64).unwrap(); + + macro_rules! check_address { + ($ty:ty, $addr:expr, $value:expr) => { + assert_eq!(memory.read::<$ty>($addr), Ok($value)); + }; + } + + check_address!(u64, 0, 0x1122334455667788); + + check_address!(u32, 0, 0x55667788); + check_address!(u32, 4, 0x11223344); + + check_address!(u16, 0, 0x7788); + check_address!(u16, 2, 0x5566); + check_address!(u16, 4, 0x3344); + check_address!(u16, 6, 0x1122); + + check_address!(u8, 0, 0x88); + check_address!(u8, 1, 0x77); + check_address!(u8, 2, 0x66); + check_address!(u8, 3, 0x55); + check_address!(u8, 4, 0x44); + check_address!(u8, 5, 0x33); + check_address!(u8, 6, 0x22); + check_address!(u8, 7, 0x11); + }); +} diff --git a/src/riscv/lib/src/program.rs b/src/riscv/lib/src/program.rs index 7ce639616a444d25332dacc2fb3fe8045b9a9108..4675b1bcc73d3bb934bc65dd577fe7483144f980 100644 --- a/src/riscv/lib/src/program.rs +++ b/src/riscv/lib/src/program.rs @@ -4,14 +4,14 @@ use std::{borrow::Cow, collections::BTreeMap, marker::PhantomData}; -use crate::{kernel_loader, machine_state::main_memory, parser::parse_block}; +use crate::{kernel_loader, machine_state::memory, parser::parse_block}; /// RISC-V program -pub struct Program<'a, ML> { - _pd: PhantomData, +pub struct Program<'a, MC> { + _pd: PhantomData, /// Address of the program's entrypoint - pub entrypoint: main_memory::Address, + pub entrypoint: memory::Address, /// Segments to be written to the main memory // Note: `[u8]` owned is `Vec`. The segment is either re-using an @@ -20,13 +20,13 @@ pub struct Program<'a, ML> { // Invariant: `segments[index]` corresponds to an array // representing bytes at `index..index+length` and // all the arrays are non-overlapping - pub segments: BTreeMap>, + pub segments: BTreeMap>, /// Raw program headers pub program_headers: Option>, } -impl<'a, ML> kernel_loader::Memory for Program<'a, ML> { +impl<'a, MC> kernel_loader::Memory for Program<'a, MC> { fn write_bytes( &mut self, mut paddr: u64, @@ -94,12 +94,12 @@ impl<'a, ML> kernel_loader::Memory for Program<'a, ML> { } } -impl<'a, ML: main_memory::MainMemoryLayout> Program<'a, ML> { +impl<'a, MC: memory::MemoryConfig> Program<'a, MC> { /// Parse the given ELF executable and convert it into our program - /// representation. The main memory layout `ML` is used to compute the + /// representation. The main memory configuration `MC` is used to compute the /// correct addresses pub fn from_elf(elf: &'a [u8]) -> Result { - let start_if_reloc = main_memory::FIRST_ADDRESS; + let start_if_reloc = memory::FIRST_ADDRESS; let mut myself = Self { _pd: PhantomData, @@ -135,7 +135,7 @@ mod tests { use crate::{ kernel_loader::{self, Memory}, - machine_state::main_memory::{self, M1M}, + machine_state::memory::{self, M1M}, program::Program, }; @@ -174,7 +174,7 @@ mod tests { fs::read(PATH).expect("Failed read dummy RISC-V kernel (try: make -C src/riscv build)"); let mut buffer = Cursor::new(Vec::new()); - kernel_loader::load_elf(&mut buffer, main_memory::FIRST_ADDRESS, &contents).unwrap(); + kernel_loader::load_elf(&mut buffer, memory::FIRST_ADDRESS, &contents).unwrap(); let buffer = buffer.into_inner(); let program = Program::::from_elf(&contents).unwrap(); diff --git a/src/riscv/lib/src/pvm/common.rs b/src/riscv/lib/src/pvm/common.rs index 83f82ed849d59b2a8df1c5bddbca2d81af2fe01a..ff491d92f54222dcdb54e9e70671a056a332d1ea 100644 --- a/src/riscv/lib/src/pvm/common.rs +++ b/src/riscv/lib/src/pvm/common.rs @@ -14,11 +14,7 @@ use super::linux; use super::reveals::{RevealRequest, RevealRequestLayout}; use crate::{ default::ConstDefault, - machine_state::{ - self, - block_cache::bcall, - main_memory::{self}, - }, + machine_state::{self, block_cache::bcall, memory}, pvm::sbi, state_backend::{ self, Atom, Cell, @@ -64,9 +60,9 @@ impl<'a> Default for PvmHooks<'a> { /// PVM state layout #[cfg(feature = "supervisor")] -pub type PvmLayout = ( +pub type PvmLayout = ( state_backend::Atom, - machine_state::MachineStateLayout, + machine_state::MachineStateLayout, Atom, RevealRequestLayout, linux::SupervisorStateLayout, @@ -74,9 +70,9 @@ pub type PvmLayout = ( /// PVM state layout #[cfg(not(feature = "supervisor"))] -pub type PvmLayout = ( +pub type PvmLayout = ( state_backend::Atom, - machine_state::MachineStateLayout, + machine_state::MachineStateLayout, Atom, RevealRequestLayout, ); @@ -124,21 +120,21 @@ const INITIAL_VERSION: u64 = 0; /// Proof generator for the PVM. /// /// Uses the interpreted block backend by default. -type PvmProofGen<'a, ML, CL, M> = Pvm< - ML, +type PvmProofGen<'a, MC, CL, M> = Pvm< + MC, CL, - bcall::Interpreted>>, + bcall::Interpreted>>, ProofGen>, >; /// Proof-generating virtual machine pub struct Pvm< - ML: main_memory::MainMemoryLayout, + MC: memory::MemoryConfig, CL: machine_state::CacheLayouts, - B: bcall::Block, + B: bcall::Block, M: state_backend::ManagerBase, > { - pub(crate) machine_state: machine_state::MachineState, + pub(crate) machine_state: machine_state::MachineState, reveal_request: RevealRequest, #[cfg(feature = "supervisor")] pub(super) system_state: linux::SupervisorState, @@ -147,17 +143,17 @@ pub struct Pvm< } impl< - ML: main_memory::MainMemoryLayout, + MC: memory::MemoryConfig, CL: machine_state::CacheLayouts, - B: bcall::Block, + B: bcall::Block, M: state_backend::ManagerBase, -> Pvm +> Pvm { /// Bind the block cache to the given allocated state and the given [block builder]. /// /// [block builder]: bcall::Block::BlockBuilder pub fn bind( - space: state_backend::AllocatedOf, M>, + space: state_backend::AllocatedOf, M>, block_builder: B::BlockBuilder, ) -> Self { Self { @@ -174,7 +170,7 @@ impl< /// the constituents of `N` that were produced from the constituents of `&M`. pub fn struct_ref<'a, F: state_backend::FnManager>>( &'a self, - ) -> state_backend::AllocatedOf, F::Output> { + ) -> state_backend::AllocatedOf, F::Output> { ( self.version.struct_ref::(), self.machine_state.struct_ref::(), @@ -186,7 +182,7 @@ impl< } /// Generate a proof-generating version of this PVM. - pub fn start_proof(&self) -> PvmProofGen<'_, ML, CL, M> { + pub fn start_proof(&self) -> PvmProofGen<'_, MC, CL, M> { enum ProofWrapper {} impl state_backend::FnManager for ProofWrapper { @@ -365,11 +361,11 @@ impl< } impl< - ML: main_memory::MainMemoryLayout, + MC: memory::MemoryConfig, CL: machine_state::CacheLayouts, - B: bcall::Block + Clone, + B: bcall::Block + Clone, M: state_backend::ManagerClone, -> Clone for Pvm +> Clone for Pvm { fn clone(&self) -> Self { Self { @@ -394,30 +390,30 @@ mod tests { }; use super::*; - use crate::state_backend::test_helpers::TestBackendFactory; use crate::{ backend_test, create_state, machine_state::{ TestCacheLayouts, block_cache::bcall::InterpretedBlockBuilder, - main_memory::M1M, + memory::Memory, registers::{a0, a1, a2, a3, a6, a7}, }, state_backend::owned_backend::Owned, }; + use crate::{machine_state::memory::M1M, state_backend::test_helpers::TestBackendFactory}; #[test] fn test_read_input() { - type ML = M1M; - type L = PvmLayout; - type B = bcall::Interpreted; + type MC = M1M; + type L = PvmLayout; + type B = bcall::Interpreted; // Setup PVM let space = Owned::allocate::(); - let mut pvm = Pvm::::bind(space, InterpretedBlockBuilder); + let mut pvm = Pvm::::bind(space, InterpretedBlockBuilder); pvm.reset(); - let level_addr = main_memory::FIRST_ADDRESS; + let level_addr = memory::FIRST_ADDRESS; let counter_addr = level_addr + 4; let buffer_addr = counter_addr + 4; @@ -509,16 +505,16 @@ mod tests { #[test] fn test_write_debug() { - type ML = M1M; - type L = PvmLayout; - type B = bcall::Interpreted; + type MC = M1M; + type L = PvmLayout; + type B = bcall::Interpreted; let mut buffer = Vec::new(); let mut hooks = PvmHooks::new(|c| buffer.push(c)); // Setup PVM let space = Owned::allocate::(); - let mut pvm = Pvm::::bind(space, InterpretedBlockBuilder); + let mut pvm = Pvm::::bind(space, InterpretedBlockBuilder); pvm.reset(); // Prepare subsequent ECALLs to use the SBI_CONSOLE_PUTCHAR extension @@ -552,17 +548,17 @@ mod tests { } backend_test!(test_reveal, F, { - type ML = M1M; - type L = PvmLayout; - type B = bcall::Interpreted::Manager>; + type MC = M1M; + type L = PvmLayout; + type B = bcall::Interpreted::Manager>; // Setup PVM - let mut pvm = create_state!(Pvm, L, F, ML, TestCacheLayouts, B, || { + let mut pvm = create_state!(Pvm, L, F, MC, TestCacheLayouts, B, || { InterpretedBlockBuilder }); pvm.reset(); - let input_address = main_memory::FIRST_ADDRESS; + let input_address = memory::FIRST_ADDRESS; let buffer = [1u8, 2, 3, 4]; let output_address = input_address + buffer.len() as u64; let xregisters = &mut pvm.machine_state.core.hart.xregisters; @@ -625,18 +621,18 @@ mod tests { }); backend_test!(test_reveal_insufficient_buffer_size, F, { - type ML = M1M; - type L = PvmLayout; - type B = bcall::Interpreted::Manager>; + type MC = M1M; + type L = PvmLayout; + type B = bcall::Interpreted::Manager>; // Setup PVM - let mut pvm = create_state!(Pvm, L, F, ML, TestCacheLayouts, B, || { + let mut pvm = create_state!(Pvm, L, F, MC, TestCacheLayouts, B, || { InterpretedBlockBuilder }); pvm.reset(); const OUTPUT_BUFFER_SIZE: usize = 10; - let input_address = main_memory::FIRST_ADDRESS; + let input_address = memory::FIRST_ADDRESS; let buffer = [1u8, 2, 3, 4]; let output_address = input_address + buffer.len() as u64; diff --git a/src/riscv/lib/src/pvm/linux.rs b/src/riscv/lib/src/pvm/linux.rs index ee4ece7ab5ae1b5e1a55eb84416afc6ff9b58102..c6be9dc7ed09c285d8c9326a1d3ce178f3dd24cb 100644 --- a/src/riscv/lib/src/pvm/linux.rs +++ b/src/riscv/lib/src/pvm/linux.rs @@ -15,7 +15,7 @@ use crate::{ machine_state::{ CacheLayouts, MachineCoreState, MachineError, MachineState, block_cache::bcall::Block, - main_memory::{Address, MainMemoryLayout}, + memory::{Address, Memory, MemoryConfig}, mode::Mode, registers, }, @@ -90,8 +90,8 @@ enum AuxVectorKey { ProgramHeadersPtr = 3, } -impl, M: ManagerBase> - MachineState +impl, M: ManagerBase> + MachineState { /// Add data to the stack, returning the updated stack pointer. fn push_stack(&mut self, align: u64, data: impl AsRef<[u8]>) -> Result @@ -116,7 +116,7 @@ impl, M: ManagerBase> where M: ManagerWrite, { - let mem_size = ML::BYTES as u64; + let mem_size = MC::TOTAL_BYTES as u64; let init_stack_ptr = mem_size.saturating_sub(mem_size % PAGE_SIZE); self.core .hart @@ -180,7 +180,7 @@ impl, M: ManagerBase> } /// Load the program into memory and set the PC to its entrypoint. - fn load_program(&mut self, program: &Program) -> Result<(), MachineError> + fn load_program(&mut self, program: &Program) -> Result<(), MachineError> where M: ManagerWrite, { @@ -196,7 +196,7 @@ impl, M: ManagerBase> } /// Install a Linux program and configure the Hart to start it. - pub fn setup_linux_process(&mut self, program: &Program) -> Result<(), MachineError> + pub fn setup_linux_process(&mut self, program: &Program) -> Result<(), MachineError> where M: ManagerReadWrite, { @@ -228,7 +228,7 @@ impl, M: ManagerBase> } } -impl, M: ManagerBase> Pvm { +impl, M: ManagerBase> Pvm { /// Check if the supervised process has requested an exit. pub fn has_exited(&self) -> Option where @@ -278,7 +278,7 @@ impl SupervisorState { /// Handle a Linux system call. pub fn handle_system_call( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, hooks: &mut PvmHooks, ) -> bool where @@ -329,10 +329,7 @@ impl SupervisorState { /// Handle `set_tid_address` system call. /// /// See: - fn handle_set_tid_address( - &mut self, - core: &mut MachineCoreState, - ) -> bool + fn handle_set_tid_address(&mut self, core: &mut MachineCoreState) -> bool where M: ManagerRead + ManagerWrite, { @@ -351,7 +348,7 @@ impl SupervisorState { true } - fn handle_exit(&mut self, core: &mut MachineCoreState) -> bool + fn handle_exit(&mut self, core: &mut MachineCoreState) -> bool where M: ManagerReadWrite, { @@ -364,7 +361,7 @@ impl SupervisorState { /// Handle `sigaltstack` system call. The new signal stack configuration is discarded. If the /// old signal stack configuration is requested, it will be zeroed out. - fn handle_sigaltstack(&mut self, core: &mut MachineCoreState) -> bool + fn handle_sigaltstack(&mut self, core: &mut MachineCoreState) -> bool where M: ManagerRead + ManagerWrite, { @@ -390,7 +387,7 @@ impl SupervisorState { /// retrieving the previous handler for a signal - it just zeroes out the memory. /// /// See: - fn handle_rt_sigaction(&mut self, core: &mut MachineCoreState) -> bool + fn handle_rt_sigaction(&mut self, core: &mut MachineCoreState) -> bool where M: ManagerRead + ManagerWrite, { @@ -428,10 +425,7 @@ impl SupervisorState { /// Handle `rt_sigprocmask` system call. This does nothing effectively. If the previous mask is /// requested, it will simply be zeroed out. - fn handle_rt_sigprocmask( - &mut self, - core: &mut MachineCoreState, - ) -> bool + fn handle_rt_sigprocmask(&mut self, core: &mut MachineCoreState) -> bool where M: ManagerRead + ManagerWrite, { @@ -466,7 +460,7 @@ impl SupervisorState { /// Handle `tkill` system call. As there is only one thread at the moment, this system call /// will return an error if the thread ID is not the main thread ID. - fn handle_tkill(&mut self, core: &mut MachineCoreState) -> bool + fn handle_tkill(&mut self, core: &mut MachineCoreState) -> bool where M: ManagerReadWrite, { @@ -516,13 +510,14 @@ mod tests { use super::*; use crate::{ - backend_test, create_state, machine_state::MachineCoreStateLayout, state_backend::DynArray, + backend_test, create_state, + machine_state::{MachineCoreStateLayout, memory::M1K}, }; // Check that the `set_tid_address` system call is working correctly. backend_test!(set_tid_address, F, { - const MEM_BYTES: usize = 1024; - type MemLayout = DynArray; + type MemLayout = M1K; + const MEM_BYTES: usize = MemLayout::TOTAL_BYTES; let mut machine_state = create_state!( MachineCoreState, @@ -553,8 +548,7 @@ mod tests { // Check `ppoll` system call the way it is used in Musl and Rust's initialisation code. backend_test!(ppoll_init_fds, F, { - const MEM_BYTES: usize = 1024; - type MemLayout = DynArray; + type MemLayout = M1K; let mut machine_state = create_state!( MachineCoreState, @@ -603,8 +597,7 @@ mod tests { // Check that the `rt_sigaction` system call is working correctly for a basic case. backend_test!(rt_sigaction_no_handler, F, { - const MEM_BYTES: usize = 1024; - type MemLayout = DynArray; + type MemLayout = M1K; let mut machine_state = create_state!( MachineCoreState, diff --git a/src/riscv/lib/src/pvm/linux/fds.rs b/src/riscv/lib/src/pvm/linux/fds.rs index 142d918c9cd171d0c56917df9896fa933ea77424..3be23aaba3122b05be638a80d1d6c56888bb273a 100644 --- a/src/riscv/lib/src/pvm/linux/fds.rs +++ b/src/riscv/lib/src/pvm/linux/fds.rs @@ -6,7 +6,11 @@ use super::{SupervisorState, error::Error}; use crate::{ - machine_state::{MachineCoreState, main_memory::MainMemoryLayout, registers}, + machine_state::{ + MachineCoreState, + memory::{Memory, MemoryConfig}, + registers, + }, pvm::{PvmHooks, linux::PAGE_SIZE}, state_backend::{ManagerBase, ManagerRead, ManagerReadWrite}, }; @@ -23,7 +27,7 @@ impl SupervisorState { /// Write to a file descriptor. fn write_to_fd( &self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, hooks: &mut PvmHooks, fd: i32, addr: u64, @@ -65,7 +69,7 @@ impl SupervisorState { /// See pub(super) fn handle_write( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, hooks: &mut PvmHooks, ) -> bool where @@ -89,7 +93,7 @@ impl SupervisorState { /// See pub(super) fn handle_writev( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, hooks: &mut PvmHooks, ) -> bool where @@ -169,10 +173,7 @@ impl SupervisorState { /// example, the `timeout` parameter is ignored entirely. /// /// See: - pub(super) fn handle_ppoll( - &mut self, - core: &mut MachineCoreState, - ) -> bool + pub(super) fn handle_ppoll(&mut self, core: &mut MachineCoreState) -> bool where M: ManagerReadWrite, { diff --git a/src/riscv/lib/src/pvm/linux/fs.rs b/src/riscv/lib/src/pvm/linux/fs.rs index fedd51c158aafa645632c9578a76ac654f76af92..94ff4eb48b15295a52d39f009dd77ffb8680dd46 100644 --- a/src/riscv/lib/src/pvm/linux/fs.rs +++ b/src/riscv/lib/src/pvm/linux/fs.rs @@ -6,7 +6,7 @@ use super::{SupervisorState, error::Error}; use crate::{ - machine_state::{MachineCoreState, main_memory::MainMemoryLayout}, + machine_state::{MachineCoreState, memory::MemoryConfig}, state_backend::{ManagerBase, ManagerReadWrite}, }; @@ -16,7 +16,7 @@ impl SupervisorState { /// See: pub(super) fn handle_openat( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> bool where M: ManagerReadWrite, @@ -30,7 +30,7 @@ impl SupervisorState { /// See: pub(super) fn handle_readlinkat( &mut self, - core: &mut MachineCoreState, + core: &mut MachineCoreState, ) -> bool where M: ManagerReadWrite, diff --git a/src/riscv/lib/src/pvm/node_pvm.rs b/src/riscv/lib/src/pvm/node_pvm.rs index 62b8e44ef129d2c7879a96572a3fcfa28662f307..829eb38cb2c71769e624b960b94c0204463ebc41 100644 --- a/src/riscv/lib/src/pvm/node_pvm.rs +++ b/src/riscv/lib/src/pvm/node_pvm.rs @@ -11,7 +11,7 @@ use crate::{ machine_state::{ TestCacheLayouts, block_cache::bcall::{Interpreted, InterpretedBlockBuilder}, - main_memory::M64M, + memory::M64M, mode::Mode, }, program::Program, diff --git a/src/riscv/lib/src/pvm/sbi.rs b/src/riscv/lib/src/pvm/sbi.rs index 721519974e237d53e6a783d659e2932924aa45fc..d8a34cadb2bf5299ef1f45f6df24318d97068b61 100644 --- a/src/riscv/lib/src/pvm/sbi.rs +++ b/src/riscv/lib/src/pvm/sbi.rs @@ -24,23 +24,18 @@ use crate::{ machine_state::{ AccessType, CacheLayouts, MachineState, block_cache::bcall::Block, - main_memory::MainMemoryLayout, + memory::{Memory, MemoryConfig}, registers::{XValue, a0, a1, a2, a3, a6, a7}, }, parser::instruction::InstrUncacheable, - state_backend::{CellRead, CellReadWrite, CellWrite, ManagerReadWrite}, + state_backend::{Cell, CellRead, CellReadWrite, CellWrite, ManagerReadWrite}, traps::EnvironException, }; /// Write the SBI error code as the return value. #[inline(always)] -fn sbi_return_error< - ML: MainMemoryLayout, - CL: CacheLayouts, - B: Block, - M: ManagerReadWrite, ->( - machine: &mut MachineState, +fn sbi_return_error, M: ManagerReadWrite>( + machine: &mut MachineState, code: SbiError, ) { machine.core.hart.xregisters.write(a0, code as i64 as u64); @@ -48,8 +43,8 @@ fn sbi_return_error< /// Write an arbitrary value as single return value. #[inline(always)] -fn sbi_return1, M: ManagerReadWrite>( - machine: &mut MachineState, +fn sbi_return1, M: ManagerReadWrite>( + machine: &mut MachineState, value: XValue, ) { // The SBI caller interprets the return value as a [i64]. We don't want the value to be @@ -63,13 +58,8 @@ fn sbi_return1, M: Manag /// Write an `sbiret` return struct. #[inline(always)] -fn sbi_return_sbiret< - ML: MainMemoryLayout, - CL: CacheLayouts, - B: Block, - M: ManagerReadWrite, ->( - machine: &mut MachineState, +fn sbi_return_sbiret, M: ManagerReadWrite>( + machine: &mut MachineState, error: Option, value: XValue, ) { @@ -83,13 +73,13 @@ fn sbi_return_sbiret< /// Run the given closure `inner` and write the corresponding SBI results to `machine`. #[inline(always)] -fn sbi_wrap(machine: &mut MachineState, inner: F) +fn sbi_wrap(machine: &mut MachineState, inner: F) where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, - F: FnOnce(&mut MachineState) -> Result, + F: FnOnce(&mut MachineState) -> Result, { match inner(machine) { Ok(value) => sbi_return1(machine, value), @@ -99,15 +89,15 @@ where /// Respond to a request for input with no input. Returns `false` in case the /// machine wasn't expecting any input, otherwise returns `true`. -pub fn provide_no_input( +pub fn provide_no_input( status: &mut S, - machine: &mut MachineState, + machine: &mut MachineState, ) -> bool where S: CellReadWrite, CL: CacheLayouts, - ML: MainMemoryLayout, - B: Block, + MC: MemoryConfig, + B: Block, M: ManagerReadWrite, { // This method should only do something when we're waiting for input. @@ -126,9 +116,9 @@ where /// Provide input information to the machine. Returns `false` in case the /// machine wasn't expecting any input, otherwise returns `true`. -pub fn provide_input( +pub fn provide_input( status: &mut S, - machine: &mut MachineState, + machine: &mut MachineState, level: u32, counter: u32, payload: &[u8], @@ -136,8 +126,8 @@ pub fn provide_input( where S: CellReadWrite, CL: CacheLayouts, - ML: MainMemoryLayout, - B: Block, + MC: MemoryConfig, + B: Block, M: ManagerReadWrite, { // This method should only do something when we're waiting for input. @@ -189,17 +179,17 @@ where /// Provide metadata in response to a metadata request. Returns `false` /// if the machine is not expecting metadata. -pub fn provide_metadata( +pub fn provide_metadata( status: &mut S, - machine: &mut MachineState, + machine: &mut MachineState, rollup_address: &[u8; 20], origination_level: u32, ) -> bool where S: CellReadWrite, CL: CacheLayouts, - ML: MainMemoryLayout, - B: Block, + MC: MemoryConfig, + B: Block, M: ManagerReadWrite, { // This method should only do something when we're waiting for metadata. @@ -233,16 +223,16 @@ where /// Provide reveal data in response to a reveal request. Returns `false` /// if the machine is not expecting reveal. -pub fn provide_reveal_response( +pub fn provide_reveal_response( status: &mut S, - machine: &mut MachineState, + machine: &mut MachineState, reveal_data: &[u8], ) -> bool where S: CellReadWrite, CL: CacheLayouts, - ML: MainMemoryLayout, - B: Block, + MC: MemoryConfig, + B: Block, M: ManagerReadWrite, { // This method should only do something when we're waiting for reveal. @@ -301,13 +291,13 @@ where /// Produce a Ed25519 signature. #[inline] -fn handle_tezos_ed25519_sign( - machine: &mut MachineState, +fn handle_tezos_ed25519_sign( + machine: &mut MachineState, ) -> Result where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { let arg_sk_addr = machine.core.hart.xregisters.read(a0); @@ -339,13 +329,13 @@ where /// Verify a Ed25519 signature. #[inline] -fn handle_tezos_ed25519_verify( - machine: &mut MachineState, +fn handle_tezos_ed25519_verify( + machine: &mut MachineState, ) -> Result where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { let arg_pk_addr = machine.core.hart.xregisters.read(a0); @@ -381,13 +371,13 @@ where /// Compute a BLAKE2B 256-bit digest. #[inline] -fn handle_tezos_blake2b_hash256( - machine: &mut MachineState, +fn handle_tezos_blake2b_hash256( + machine: &mut MachineState, ) -> Result where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { let arg_out_addr = machine.core.hart.xregisters.read(a0); @@ -414,15 +404,15 @@ where /// Handle a [SBI_TEZOS_REVEAL] call. #[inline] -fn handle_tezos_reveal( - machine: &mut MachineState, +fn handle_tezos_reveal( + machine: &mut MachineState, reveal_request: &mut RevealRequest, status: &mut S, ) where S: CellReadWrite, - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { let request_address = machine.core.hart.xregisters.read(a0); @@ -450,11 +440,11 @@ fn handle_tezos_reveal( /// Handle a [SBI_SHUTDOWN] call. #[inline(always)] -fn handle_legacy_shutdown(machine: &mut MachineState) +fn handle_legacy_shutdown(machine: &mut MachineState) where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { // This call always fails. @@ -463,13 +453,13 @@ where /// Handle a [SBI_CONSOLE_PUTCHAR] call. #[inline(always)] -fn handle_legacy_console_putchar( - machine: &mut MachineState, +fn handle_legacy_console_putchar( + machine: &mut MachineState, hooks: &mut PvmHooks, ) where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { let char = machine.core.hart.xregisters.read(a0) as u8; @@ -481,13 +471,13 @@ fn handle_legacy_console_putchar( /// Handle a [SBI_DBCN_CONSOLE_WRITE_BYTE] call. #[inline(always)] -fn handle_debug_console_write_byte( - machine: &mut MachineState, +fn handle_debug_console_write_byte( + machine: &mut MachineState, hooks: &mut PvmHooks, ) where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { let char = machine.core.hart.xregisters.read(a0) as u8; @@ -499,11 +489,11 @@ fn handle_debug_console_write_byte( /// Handle a [SBI_SRST_SYSTEM_RESET] call. #[inline(always)] -fn handle_system_reset(machine: &mut MachineState) +fn handle_system_reset(machine: &mut MachineState) where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { sbi_return_sbiret(machine, Some(SbiError::NotSupported), 0); @@ -511,11 +501,11 @@ where /// Handle unsupported SBI calls. #[inline(always)] -fn handle_not_supported(machine: &mut MachineState) +fn handle_not_supported(machine: &mut MachineState) where - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { // SBI requires us to indicate that we don't support this function by returning @@ -525,18 +515,17 @@ where /// Handle a PVM SBI call. Returns `true` if it makes sense to continue evaluation. #[inline] -pub fn handle_call( - status: &mut S, +pub fn handle_call( + status: &mut Cell, reveal_request: &mut RevealRequest, - machine: &mut MachineState, + machine: &mut MachineState, hooks: &mut PvmHooks, env_exception: EnvironException, ) -> bool where - S: CellReadWrite, - ML: MainMemoryLayout, + MC: MemoryConfig, CL: CacheLayouts, - B: Block, + B: Block, M: ManagerReadWrite, { if let EnvironException::EnvCallFromMMode = env_exception { diff --git a/src/riscv/lib/src/stepper.rs b/src/riscv/lib/src/stepper.rs index 5f04237369ee6c5c3ff9014f457efd1dd3d594d3..c99a3d5c99a03125d46803dc2a895df55d3ce7b7 100644 --- a/src/riscv/lib/src/stepper.rs +++ b/src/riscv/lib/src/stepper.rs @@ -5,7 +5,7 @@ use std::ops::{AddAssign, Bound}; use crate::{ - machine_state::{CacheLayouts, MachineCoreState, main_memory::MainMemoryLayout}, + machine_state::{CacheLayouts, MachineCoreState, memory::MemoryConfig}, state_backend::{ManagerBase, ManagerRead}, }; @@ -83,8 +83,8 @@ impl StepResult for StepperStatus { /// Interface for a debuggable stepper pub trait Stepper { - /// Memory layout of the underlying machine state - type MainMemoryLayout: MainMemoryLayout; + /// Memory config of the underlying machine state + type MemoryConfig: MemoryConfig; /// Layout of the instruction cache type CacheLayouts: CacheLayouts; @@ -93,7 +93,7 @@ pub trait Stepper { type Manager: ManagerBase + ManagerRead; /// Obtain a reference to the underlying machine state. - fn machine_state(&self) -> &MachineCoreState; + fn machine_state(&self) -> &MachineCoreState; /// Result of one or more steps type StepResult: StepResult; diff --git a/src/riscv/lib/src/stepper/pvm.rs b/src/riscv/lib/src/stepper/pvm.rs index 36e02b96d7cd2abd5144d482422d32248eb1fc5b..ed1d58912208f7a7da628a8b8ff9ac22f535931e 100644 --- a/src/riscv/lib/src/stepper/pvm.rs +++ b/src/riscv/lib/src/stepper/pvm.rs @@ -12,14 +12,14 @@ use serde::{Serialize, de::DeserializeOwned}; use tezos_smart_rollup_utils::inbox::Inbox; use super::{Stepper, StepperStatus}; -use crate::machine_state::block_cache::bcall::{Block, Interpreted, InterpretedBlockBuilder}; +use crate::machine_state::{ + block_cache::bcall::{Block, Interpreted, InterpretedBlockBuilder}, + memory::{M1G, MemoryConfig}, +}; use crate::state_backend::{ManagerBase, ManagerReadWrite}; use crate::{ kernel_loader, - machine_state::{ - CacheLayouts, DefaultCacheLayouts, MachineCoreState, MachineError, - main_memory::{M1G, MainMemoryLayout}, - }, + machine_state::{CacheLayouts, DefaultCacheLayouts, MachineCoreState, MachineError}, program::Program, pvm::{Pvm, PvmHooks, PvmLayout, PvmStatus}, range_utils::bound_saturating_sub, @@ -46,12 +46,12 @@ pub enum PvmStepperError { /// Wrapper over a PVM that lets you step through it pub struct PvmStepper< 'hooks, - ML: MainMemoryLayout = M1G, + MC: MemoryConfig = M1G, CL: CacheLayouts = DefaultCacheLayouts, M: ManagerBase = Owned, - B: Block = Interpreted, + B: Block = Interpreted, > { - pvm: Pvm, + pvm: Pvm, hooks: PvmHooks<'hooks>, inbox: Inbox, rollup_address: [u8; 20], @@ -59,8 +59,8 @@ pub struct PvmStepper< reveal_request_response_map: RevealRequestResponseMap, } -impl<'hooks, ML: MainMemoryLayout, B: Block, CL: CacheLayouts> - PvmStepper<'hooks, ML, CL, Owned, B> +impl<'hooks, MC: MemoryConfig, B: Block, CL: CacheLayouts> + PvmStepper<'hooks, MC, CL, Owned, B> { /// Create a new PVM stepper. pub fn new( @@ -72,10 +72,10 @@ impl<'hooks, ML: MainMemoryLayout, B: Block, CL: CacheLayouts> origination_level: u32, block_builder: B::BlockBuilder, ) -> Result { - let space = Owned::allocate::>(); + let space = Owned::allocate::>(); let mut pvm = Pvm::bind(space, block_builder); - let program = Program::::from_elf(program)?; + let program = Program::::from_elf(program)?; #[cfg(feature = "supervisor")] { @@ -108,11 +108,11 @@ impl<'hooks, ML: MainMemoryLayout, B: Block, CL: CacheLayouts> /// Obtain the root hash for the PVM state. pub fn hash(&self) -> Hash { let refs = self.pvm.struct_ref::(); - PvmLayout::::state_hash(refs).unwrap() + PvmLayout::::state_hash(refs).unwrap() } } -impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts> PvmStepper<'hooks, ML, CL, Owned> { +impl<'hooks, MC: MemoryConfig, CL: CacheLayouts> PvmStepper<'hooks, MC, CL, Owned> { /// Produce the Merkle proof for evaluating one step on the given PVM state. /// The given stepper takes one step. pub fn produce_proof(&mut self) -> Option { @@ -123,21 +123,21 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts> PvmStepper<'hooks, ML, CL, let refs = proof_stepper .pvm .struct_ref::(); - let merkle_proof = PvmLayout::::to_merkle_tree(refs) + let merkle_proof = PvmLayout::::to_merkle_tree(refs) .expect("Obtaining the Merkle tree of a proof-gen state should not fail") .to_merkle_proof() .expect("Converting a Merkle tree to a compressed Merkle proof should not fail"); let refs = proof_stepper.struct_ref(); - let final_hash = PvmLayout::::state_hash(refs) + let final_hash = PvmLayout::::state_hash(refs) .expect("Obtaining the final hash of the proof-gen state should not fail"); Proof::new(merkle_proof, final_hash) }) } } -impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, B: Block, M: ManagerReadWrite> - PvmStepper<'hooks, ML, CL, M, B> +impl<'hooks, MC: MemoryConfig, CL: CacheLayouts, B: Block, M: ManagerReadWrite> + PvmStepper<'hooks, MC, CL, M, B> { /// Non-continuing variant of [`Stepper::step_max`] fn step_max_once(&mut self, steps: Bound) -> StepperStatus { @@ -260,7 +260,7 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, B: Block, M: Manager /// Given a manager morphism `f : &M -> N`, return the layout's allocated structure containing /// the constituents of `N` that were produced from the constituents of `&M`. - pub fn struct_ref(&self) -> AllocatedOf, Ref<'_, M>> { + pub fn struct_ref(&self) -> AllocatedOf, Ref<'_, M>> { self.pvm.struct_ref::() } @@ -273,8 +273,8 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, B: Block, M: Manager /// [`BlockBuilder`]: Block::BlockBuilder pub fn rebind_via_serde(&mut self, block_builder: B::BlockBuilder) where - for<'a> AllocatedOf, Ref<'a, M>>: Serialize, - AllocatedOf, M>: DeserializeOwned, + for<'a> AllocatedOf, Ref<'a, M>>: Serialize, + AllocatedOf, M>: DeserializeOwned, { let space = { let refs = self.pvm.struct_ref::(); @@ -286,13 +286,13 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, B: Block, M: Manager } } -impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, M: ManagerReadWrite> - PvmStepper<'hooks, ML, CL, M> +impl<'hooks, MC: MemoryConfig, CL: CacheLayouts, M: ManagerReadWrite> + PvmStepper<'hooks, MC, CL, M> { /// Create a new stepper in which the existing PVM is managed by /// the proof-generating backend. - pub fn start_proof_mode<'a>(&'a self) -> PvmStepper<'hooks, ML, CL, ProofGen>> { - PvmStepper::<'hooks, ML, CL, ProofGen>> { + pub fn start_proof_mode<'a>(&'a self) -> PvmStepper<'hooks, MC, CL, ProofGen>> { + PvmStepper::<'hooks, MC, CL, ProofGen>> { pvm: self.pvm.start_proof(), rollup_address: self.rollup_address, origination_level: self.origination_level, @@ -316,11 +316,11 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, M: ManagerReadWrite> #![allow(unreachable_code, unused_variables, clippy::diverging_sub_expression)] let proof_tree = ProofTree::Present(proof.tree()); - let Some(space) = PvmLayout::::from_proof(proof_tree).ok() else { + let Some(space) = PvmLayout::::from_proof(proof_tree).ok() else { return false; }; - let pvm = Pvm::, Verifier>::bind(space, InterpretedBlockBuilder); + let pvm = Pvm::, Verifier>::bind(space, InterpretedBlockBuilder); let mut stepper = PvmStepper { pvm, rollup_address: self.rollup_address, @@ -346,8 +346,8 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, M: ManagerReadWrite> } } -impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, M: ManagerReadWrite> - PvmStepper<'hooks, ML, CL, M> +impl<'hooks, MC: MemoryConfig, CL: CacheLayouts, M: ManagerReadWrite> + PvmStepper<'hooks, MC, CL, M> { /// Perform one evaluation step. pub fn eval_one(&mut self) { @@ -355,16 +355,16 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts, M: ManagerReadWrite> } } -impl<'hooks, ML: MainMemoryLayout, B: Block, CL: CacheLayouts> Stepper - for PvmStepper<'hooks, ML, CL, Owned, B> +impl<'hooks, MC: MemoryConfig, B: Block, CL: CacheLayouts> Stepper + for PvmStepper<'hooks, MC, CL, Owned, B> { - type MainMemoryLayout = ML; + type MemoryConfig = MC; type CacheLayouts = CL; type Manager = Owned; - fn machine_state(&self) -> &MachineCoreState { + fn machine_state(&self) -> &MachineCoreState { &self.pvm.machine_state.core } diff --git a/src/riscv/lib/src/stepper/test.rs b/src/riscv/lib/src/stepper/test.rs index b2adad7b98088fc5fba0d5c17712cb1a1de79ce7..2c44e79f1db484ba3f34bde5cd4515a007ef5490 100644 --- a/src/riscv/lib/src/stepper/test.rs +++ b/src/riscv/lib/src/stepper/test.rs @@ -16,7 +16,7 @@ use crate::{ CacheLayouts, MachineCoreState, MachineError, MachineState, MachineStateLayout, StepManyResult, TestCacheLayouts, block_cache::bcall::{Block, Interpreted}, - main_memory::{M1G, MainMemoryLayout}, + memory::{M1G, MemoryConfig}, mode, }, program::Program, @@ -75,19 +75,19 @@ pub enum TestStepperError { MachineError(MachineError), } -pub type TestStepperLayout = - (PosixStateLayout, MachineStateLayout); +pub type TestStepperLayout = + (PosixStateLayout, MachineStateLayout); pub struct TestStepper< - ML: MainMemoryLayout = M1G, + MC: MemoryConfig = M1G, CL: CacheLayouts = TestCacheLayouts, - B: Block = Interpreted, + B: Block = Interpreted, > { - machine_state: MachineState, + machine_state: MachineState, posix_state: PosixState, } -impl> TestStepper { +impl> TestStepper { /// Initialise an interpreter with a given `program`, starting execution in [mode]. /// An initial ramdisk can also optionally be passed. #[inline] @@ -110,7 +110,7 @@ impl> TestStepper Result<(Self, BTreeMap), TestStepperError> { - let (posix_space, machine_state_space) = Owned::allocate::>(); + let (posix_space, machine_state_space) = Owned::allocate::>(); let posix_state = PosixState::bind(posix_space); let machine_state = MachineState::bind(machine_state_space, block_builder); let mut stepper = Self { @@ -122,7 +122,7 @@ impl> TestStepper::from_elf(program)?; + let elf_program = Program::::from_elf(program)?; stepper .machine_state .setup_boot(&elf_program, initrd, mode::Mode::Machine)?; @@ -160,15 +160,15 @@ impl> TestStepper> Stepper for TestStepper { - type MainMemoryLayout = ML; +impl> Stepper for TestStepper { + type MemoryConfig = MC; type CacheLayouts = TestCacheLayouts; type Manager = Owned; #[inline(always)] - fn machine_state(&self) -> &MachineCoreState { + fn machine_state(&self) -> &MachineCoreState { &self.machine_state.core } diff --git a/src/riscv/lib/src/stepper/test/posix.rs b/src/riscv/lib/src/stepper/test/posix.rs index 1ba07e0e0a80c72d59350ed75794d57b7e58d075..fbcc185736fead24ed4c7b00767ab0e371876f95 100644 --- a/src/riscv/lib/src/stepper/test/posix.rs +++ b/src/riscv/lib/src/stepper/test/posix.rs @@ -6,7 +6,7 @@ use crate::{ machine_state::{ CacheLayouts, MachineState, block_cache::bcall::Block, - main_memory::MainMemoryLayout, + memory::MemoryConfig, mode::Mode, registers::{a0, a7}, }, @@ -62,9 +62,9 @@ impl PosixState { } /// Handle a POSIX system call. Returns `Ok(true)` if it makes sense to continue execution. - pub fn handle_call>( + pub fn handle_call>( &mut self, - machine: &mut MachineState, + machine: &mut MachineState, env_exception: EnvironException, ) -> Result where diff --git a/src/riscv/lib/src/traps.rs b/src/riscv/lib/src/traps.rs index 46d47185c8fb0bd856cbec9d0f8635b60c4ca7e7..419d3f88bbf350269726f1dced50c866fe5d6823 100644 --- a/src/riscv/lib/src/traps.rs +++ b/src/riscv/lib/src/traps.rs @@ -25,7 +25,7 @@ use std::fmt::Formatter; use tezos_smart_rollup_constants::riscv::SbiError; -use crate::machine_state::{csregisters::CSRRepr, main_memory::Address}; +use crate::machine_state::{csregisters::CSRRepr, memory::Address}; /// RISC-V Exceptions (also known as synchronous exceptions) #[derive(PartialEq, Eq, thiserror::Error, strum::Display, Debug, Clone, Copy)] diff --git a/src/riscv/lib/tests/common/mod.rs b/src/riscv/lib/tests/common/mod.rs index 923ddc2b5715466fc3122f3b5fb62383d749945d..6718b07543eb2047640ced95f2fb31c570410782 100644 --- a/src/riscv/lib/tests/common/mod.rs +++ b/src/riscv/lib/tests/common/mod.rs @@ -6,7 +6,7 @@ use std::fs; use octez_riscv::{ machine_state::{ - DefaultCacheLayouts, block_cache::bcall::InterpretedBlockBuilder, main_memory::M64M, + DefaultCacheLayouts, block_cache::bcall::InterpretedBlockBuilder, memory::M64M, }, pvm::PvmHooks, stepper::pvm::PvmStepper, diff --git a/src/riscv/lib/tests/test_determinism.rs b/src/riscv/lib/tests/test_determinism.rs index 1f95ea1a9914915ff02fa8b2a17c90d52a6bd7cb..17709d4d96621de7a1ec206c8f33e041edcb346e 100644 --- a/src/riscv/lib/tests/test_determinism.rs +++ b/src/riscv/lib/tests/test_determinism.rs @@ -9,7 +9,7 @@ use std::ops::Bound; use common::*; use octez_riscv::{ machine_state::{ - DefaultCacheLayouts, block_cache::bcall::InterpretedBlockBuilder, main_memory::M64M, + DefaultCacheLayouts, block_cache::bcall::InterpretedBlockBuilder, memory::M64M, }, pvm::PvmLayout, state_backend::{RefOwnedAlloc, hash}, diff --git a/src/riscv/lib/tests/test_proofs.rs b/src/riscv/lib/tests/test_proofs.rs index 6665e0efdf5ab4818479979cf58a6f36694f7571..3189348c8c8a37be0bd8900990e41266786d5b12 100644 --- a/src/riscv/lib/tests/test_proofs.rs +++ b/src/riscv/lib/tests/test_proofs.rs @@ -9,7 +9,7 @@ use std::ops::Bound; use common::*; use octez_riscv::{ - machine_state::{DefaultCacheLayouts, main_memory::M64M}, + machine_state::{DefaultCacheLayouts, memory::M64M}, state_backend::hash, stepper::{Stepper, StepperStatus, pvm::PvmStepper}, }; diff --git a/src/riscv/lib/tests/test_regression.rs b/src/riscv/lib/tests/test_regression.rs index a7f68e508c4c26b766916ca080e927ef4b97affb..b7bc1e6bef5333e2e33d58f0308dccf0a84eea05 100644 --- a/src/riscv/lib/tests/test_regression.rs +++ b/src/riscv/lib/tests/test_regression.rs @@ -9,7 +9,7 @@ use octez_riscv::{ machine_state::{ DefaultCacheLayouts, block_cache::bcall::{Block, InlineJit, Interpreted, InterpretedBlockBuilder}, - main_memory::M64M, + memory::M64M, }, pvm::PvmHooks, state_backend::owned_backend::Owned, diff --git a/src/riscv/lib/tests/test_suite_interpreter.rs b/src/riscv/lib/tests/test_suite_interpreter.rs index 6781887fcf87d391454dfed565b0a0cb99e7bc1e..631be226506a74254671a49e2386978e2905d206 100644 --- a/src/riscv/lib/tests/test_suite_interpreter.rs +++ b/src/riscv/lib/tests/test_suite_interpreter.rs @@ -9,7 +9,7 @@ use goldenfile::Mint; use octez_riscv::{ machine_state::{ block_cache::bcall::InterpretedBlockBuilder, - main_memory::M1M, + memory::M1M, mode::Mode, registers::{XRegister, XValue, gp}, }, diff --git a/src/riscv/sandbox/src/commands/bench/commands/run.rs b/src/riscv/sandbox/src/commands/bench/commands/run.rs index 91ce40ecd30b32f98aca07ec41aad20e938ffe93..14b657256fd50401bb0b1db47eb5849b9446b26d 100644 --- a/src/riscv/sandbox/src/commands/bench/commands/run.rs +++ b/src/riscv/sandbox/src/commands/bench/commands/run.rs @@ -12,7 +12,10 @@ use std::{ use enum_tag::EnumTag; use octez_riscv::{ - machine_state::{AccessType, main_memory::Address}, + machine_state::{ + AccessType, + memory::{Address, Memory}, + }, parser::{instruction::Instr, parse}, state_backend::ManagerRead, stepper::{StepResult, Stepper, StepperStatus}, diff --git a/src/riscv/sandbox/src/commands/debug.rs b/src/riscv/sandbox/src/commands/debug.rs index aaf5028f798c4b3fec43e905b69543568dd00479..187b17d5331929702ca930d5c5cabbf424db0d24 100644 --- a/src/riscv/sandbox/src/commands/debug.rs +++ b/src/riscv/sandbox/src/commands/debug.rs @@ -6,7 +6,7 @@ use std::{error::Error, fs}; use octez_riscv::{ - machine_state::main_memory::M1G, + machine_state::memory::M1G, stepper::{pvm::PvmStepper, test::TestStepper}, }; use tezos_smart_rollup::utils::inbox::InboxBuilder; diff --git a/src/riscv/sandbox/src/commands/debug/debugger_app.rs b/src/riscv/sandbox/src/commands/debug/debugger_app.rs index 935deb21219fb4b7e57708365d411b30b664ae62..c1a20a25aeaf0287b0864485465600c275da1db7 100644 --- a/src/riscv/sandbox/src/commands/debug/debugger_app.rs +++ b/src/riscv/sandbox/src/commands/debug/debugger_app.rs @@ -19,7 +19,7 @@ use octez_riscv::{ AccessType, CacheLayouts, MachineCoreState, block_cache::bcall::InterpretedBlockBuilder, csregisters::satp::{Satp, SvLength, TranslationAlgorithm}, - main_memory::{self, Address, MainMemoryLayout}, + memory::{self, Address}, mode::Mode, }, program::Program, @@ -173,7 +173,7 @@ fn get_elf_symbols( let offset = if elf.header.e_type == ET_DYN { // Symbol addresses in relocatable executables are relative addresses. We need to offset // them by the start address of the main memory where the executable is loaded. - main_memory::FIRST_ADDRESS + memory::FIRST_ADDRESS } else { 0 }; @@ -195,7 +195,7 @@ fn get_elf_symbols( Ok(symbols) } -impl<'a, ML: MainMemoryLayout> DebuggerApp<'a, TestStepper> { +impl<'a, MC: memory::MemoryConfig> DebuggerApp<'a, TestStepper> { pub fn launch( fname: &str, program: &[u8], @@ -207,7 +207,7 @@ impl<'a, ML: MainMemoryLayout> DebuggerApp<'a, TestStepper> { let block_builder = InterpretedBlockBuilder; let (mut interpreter, prog) = - TestStepper::::new_with_parsed_program(program, initrd, exit_mode, block_builder)?; + TestStepper::::new_with_parsed_program(program, initrd, exit_mode, block_builder)?; let symbols = get_elf_symbols(program, demangle_sybols)?; errors::install_hooks()?; let terminal = tui::init()?; @@ -218,7 +218,9 @@ impl<'a, ML: MainMemoryLayout> DebuggerApp<'a, TestStepper> { } } -impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts> DebuggerApp<'_, PvmStepper<'hooks, ML, CL>> { +impl<'hooks, MC: memory::MemoryConfig, CL: CacheLayouts> + DebuggerApp<'_, PvmStepper<'hooks, MC, CL>> +{ /// Launch the Debugger app for a PVM. pub fn launch( fname: &str, @@ -231,7 +233,7 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts> DebuggerApp<'_, PvmStepper< let hooks = PvmHooks::new(|_| {}); let block_builder = InterpretedBlockBuilder; - let mut stepper = PvmStepper::<'_, ML, CL>::new( + let mut stepper = PvmStepper::<'_, MC, CL>::new( program, initrd, inbox, @@ -242,7 +244,7 @@ impl<'hooks, ML: MainMemoryLayout, CL: CacheLayouts> DebuggerApp<'_, PvmStepper< )?; let symbols = get_elf_symbols(program, opts.demangle)?; - let program = Program::::from_elf(program)?.parsed(); + let program = Program::::from_elf(program)?.parsed(); errors::install_hooks()?; let terminal = tui::init()?; @@ -495,7 +497,7 @@ impl<'a> ProgramView<'a> { mod test { use std::fs; - use octez_riscv::machine_state::main_memory::M1G; + use octez_riscv::machine_state::memory::M1G; use super::*; use crate::{ExitMode, posix_exit_mode}; diff --git a/src/riscv/sandbox/src/commands/debug/debugger_app/updates.rs b/src/riscv/sandbox/src/commands/debug/debugger_app/updates.rs index 4a6e6032dc794270a3d6b2688f54c6a0a2f53c2a..16fb5d41b9a07b5e30e28322becf8a24222933e9 100644 --- a/src/riscv/sandbox/src/commands/debug/debugger_app/updates.rs +++ b/src/riscv/sandbox/src/commands/debug/debugger_app/updates.rs @@ -10,7 +10,7 @@ use octez_riscv::{ machine_state::{ AccessType, csregisters::{CSRegister, satp::Satp}, - main_memory::Address, + memory::{Address, Memory}, }, parser::{instruction::Instr, parse}, state_backend::{ManagerRead, ManagerReadWrite}, diff --git a/src/riscv/sandbox/src/commands/gdb.rs b/src/riscv/sandbox/src/commands/gdb.rs index 572107b8089411a79d0906c266bfb1779fb3584c..79afbeaeecd1fcca61f58b5e6642781fd198101c 100644 --- a/src/riscv/sandbox/src/commands/gdb.rs +++ b/src/riscv/sandbox/src/commands/gdb.rs @@ -28,14 +28,14 @@ use gdbstub::target::ext::breakpoints::{ use gdbstub::target::ext::exec_file::ExecFile; use gdbstub::target::{Target, TargetError, TargetResult}; use gdbstub_arch::riscv::reg::RiscvCoreRegs; -use octez_riscv::machine_state::block_cache::bcall::InterpretedBlockBuilder; +use octez_riscv::machine_state::{ + block_cache::bcall::InterpretedBlockBuilder, + memory::{M1G, Memory, OutOfBounds}, +}; use octez_riscv::pvm::PvmHooks; +use octez_riscv::state_backend::FnManagerIdent; use octez_riscv::stepper::pvm::PvmStepper; use octez_riscv::stepper::{StepResult, Stepper, StepperStatus}; -use octez_riscv::{ - machine_state::main_memory::{M1G, OutOfBounds}, - state_backend::FnManagerIdent, -}; use tezos_smart_rollup::utils::inbox::InboxBuilder; use crate::cli::GdbServerOptions; diff --git a/src/riscv/sandbox/src/commands/run.rs b/src/riscv/sandbox/src/commands/run.rs index 6910801dcfb15ac0361f4022c7e50346899635c9..fff74683768dcda7e0c23e28a91e075a3caf37e0 100644 --- a/src/riscv/sandbox/src/commands/run.rs +++ b/src/riscv/sandbox/src/commands/run.rs @@ -6,10 +6,11 @@ use std::{error::Error, fs, io::Write, ops::Bound}; use octez_riscv::{ - machine_state::{DefaultCacheLayouts, main_memory::M1G}, + machine_state::DefaultCacheLayouts, machine_state::{ TestCacheLayouts, block_cache::bcall::{self, Block}, + memory::M1G, }, pvm::PvmHooks, state_backend::owned_backend::Owned,