-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
emul-trace-mem: Keep track of previous memory op (#184)
_Issue #111, part 2._ - Extend the trace with links from each step to the previous steps that last touched the same memory addresses. - A lot of refactoring to avoid having `(u32, u32, u32)` everywhere. - **[See Documentation](https://github.com/scroll-tech/ceno/pull/184/files#diff-1068ec7481772ce29c055d915f4ff8449817856b0bec6229b7c30db3be593593R10)** --------- Co-authored-by: Aurélien Nicolas <[email protected]>
- Loading branch information
Showing
7 changed files
with
407 additions
and
198 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
mod addr; | ||
pub use addr::{ByteAddr, RegIdx, WordAddr}; | ||
pub use addr::*; | ||
|
||
mod platform; | ||
pub use platform::{Platform, CENO_PLATFORM}; | ||
|
||
mod tracer; | ||
pub use tracer::{Change, StepRecord}; | ||
pub use tracer::{Change, MemOp, ReadOp, StepRecord, Tracer, WriteOp}; | ||
|
||
mod vm_state; | ||
pub use vm_state::VMState; | ||
|
||
mod rv32im; | ||
pub use rv32im::{DecodedInstruction, InsnCategory, InsnKind}; | ||
pub use rv32im::{DecodedInstruction, EmuContext, InsnCategory, InsnKind}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,112 @@ | ||
use crate::addr::{Addr, RegIdx}; | ||
|
||
/// The Platform struct holds the parameters of the VM. | ||
/// It defines: | ||
/// - the layout of virtual memory, | ||
/// - special addresses, such as the initial PC, | ||
/// - codes of environment calls. | ||
pub struct Platform; | ||
|
||
pub const CENO_PLATFORM: Platform = Platform; | ||
|
||
impl Platform { | ||
// Virtual memory layout. | ||
|
||
pub fn rom_start(&self) -> u32 { | ||
pub const fn rom_start(&self) -> Addr { | ||
0x2000_0000 | ||
} | ||
|
||
pub fn rom_end(&self) -> u32 { | ||
pub const fn rom_end(&self) -> Addr { | ||
0x3000_0000 - 1 | ||
} | ||
|
||
pub fn is_rom(&self, addr: u32) -> bool { | ||
pub fn is_rom(&self, addr: Addr) -> bool { | ||
(self.rom_start()..=self.rom_end()).contains(&addr) | ||
} | ||
|
||
pub fn ram_start(&self) -> u32 { | ||
pub const fn ram_start(&self) -> Addr { | ||
0x8000_0000 | ||
} | ||
|
||
pub fn ram_end(&self) -> u32 { | ||
pub const fn ram_end(&self) -> Addr { | ||
0xFFFF_FFFF | ||
} | ||
|
||
pub fn is_ram(&self, addr: u32) -> bool { | ||
pub fn is_ram(&self, addr: Addr) -> bool { | ||
(self.ram_start()..=self.ram_end()).contains(&addr) | ||
} | ||
|
||
/// Virtual address of a register. | ||
pub const fn register_vma(&self, index: RegIdx) -> Addr { | ||
// Register VMAs are aligned, cannot be confused with indices, and readable in hex. | ||
(index << 8) as Addr | ||
} | ||
|
||
/// Virtual address of the program counter. | ||
pub const fn pc_vma(&self) -> Addr { | ||
self.register_vma(32) | ||
} | ||
|
||
// Startup. | ||
|
||
pub fn pc_start(&self) -> u32 { | ||
pub const fn pc_start(&self) -> Addr { | ||
self.rom_start() | ||
} | ||
|
||
// Permissions. | ||
|
||
pub fn can_read(&self, addr: u32) -> bool { | ||
pub fn can_read(&self, addr: Addr) -> bool { | ||
self.is_rom(addr) || self.is_ram(addr) | ||
} | ||
|
||
pub fn can_write(&self, addr: u32) -> bool { | ||
pub fn can_write(&self, addr: Addr) -> bool { | ||
self.is_ram(addr) | ||
} | ||
|
||
pub fn can_execute(&self, addr: u32) -> bool { | ||
pub fn can_execute(&self, addr: Addr) -> bool { | ||
self.is_rom(addr) | ||
} | ||
|
||
// Environment calls. | ||
|
||
/// Register containing the ecall function code. (x5, t0) | ||
pub fn reg_ecall(&self) -> usize { | ||
pub const fn reg_ecall(&self) -> RegIdx { | ||
5 | ||
} | ||
|
||
/// Register containing the first function argument. (x10, a0) | ||
pub fn reg_arg0(&self) -> usize { | ||
pub const fn reg_arg0(&self) -> RegIdx { | ||
10 | ||
} | ||
|
||
/// The code of ecall HALT. | ||
pub fn ecall_halt(&self) -> u32 { | ||
pub const fn ecall_halt(&self) -> u32 { | ||
0 | ||
} | ||
|
||
/// The code of success. | ||
pub fn code_success(&self) -> u32 { | ||
pub const fn code_success(&self) -> u32 { | ||
0 | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_no_overlap() { | ||
let p = CENO_PLATFORM; | ||
assert!(p.can_execute(p.pc_start())); | ||
// ROM and RAM do not overlap. | ||
assert!(!p.is_rom(p.ram_start())); | ||
assert!(!p.is_rom(p.ram_end())); | ||
assert!(!p.is_ram(p.rom_start())); | ||
assert!(!p.is_ram(p.rom_end())); | ||
// Registers do not overlap with ROM or RAM. | ||
for reg in [p.pc_vma(), p.register_vma(0), p.register_vma(31)] { | ||
assert!(!p.is_rom(reg)); | ||
assert!(!p.is_ram(reg)); | ||
} | ||
} | ||
} |
Oops, something went wrong.