Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup/platform-range #621

Merged
merged 1 commit into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 16 additions & 53 deletions ceno_emul/src/platform.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ops::Range;

use crate::addr::{Addr, RegIdx};

/// The Platform struct holds the parameters of the VM.
Expand All @@ -7,74 +9,35 @@ use crate::addr::{Addr, RegIdx};
/// - codes of environment calls.
#[derive(Clone, Debug)]
pub struct Platform {
pub rom_start: Addr,
pub rom_end: Addr,
pub ram_start: Addr,
pub ram_end: Addr,
pub rom: Range<Addr>,
pub ram: Range<Addr>,
pub public_io: Range<Addr>,
pub stack_top: Addr,
/// If true, ecall instructions are no-op instead of trap. Testing only.
pub unsafe_ecall_nop: bool,
}

pub const CENO_PLATFORM: Platform = Platform {
rom_start: 0x2000_0000,
rom_end: 0x3000_0000,
ram_start: 0x8000_0000,
ram_end: 0xFFFF_0000,
rom: 0x2000_0000..0x3000_0000,
ram: 0x8000_0000..0xFFFF_0000,
public_io: 0x3000_1000..0x3000_2000,
stack_top: 0xC0000000,
unsafe_ecall_nop: false,
};

impl Platform {
// Virtual memory layout.

pub const fn rom_start(&self) -> Addr {
self.rom_start
}

pub const fn rom_end(&self) -> Addr {
self.rom_end
}

pub fn is_rom(&self, addr: Addr) -> bool {
(self.rom_start()..self.rom_end()).contains(&addr)
}

// TODO figure out a proper region for public io
pub const fn public_io_start(&self) -> Addr {
0x3000_1000
}

pub const fn public_io_end(&self) -> Addr {
0x3000_2000
}

pub const fn ram_start(&self) -> Addr {
if cfg!(feature = "forbid_overflow") {
// -1<<11 == 0x800 is the smallest negative 'immediate'
// offset we can have in memory instructions.
// So if we stay away from it, we are safe.
assert!(self.ram_start >= 0x800);
}
self.ram_start
}

pub const fn ram_end(&self) -> Addr {
if cfg!(feature = "forbid_overflow") {
// (1<<11) - 1 == 0x7ff is the largest positive 'immediate'
// offset we can have in memory instructions.
// So if we stay away from it, we are safe.
assert!(self.ram_end < -(1_i32 << 11) as u32)
}
self.ram_end
self.rom.contains(&addr)
}

pub fn is_ram(&self, addr: Addr) -> bool {
(self.ram_start()..self.ram_end()).contains(&addr)
self.ram.contains(&addr)
}

pub fn is_pub_io(&self, addr: Addr) -> bool {
(self.public_io_start()..self.public_io_end()).contains(&addr)
self.public_io.contains(&addr)
}

/// Virtual address of a register.
Expand All @@ -91,7 +54,7 @@ impl Platform {
// Startup.

pub const fn pc_base(&self) -> Addr {
self.rom_start()
self.rom.start
}

// Permissions.
Expand Down Expand Up @@ -146,10 +109,10 @@ mod tests {
let p = CENO_PLATFORM;
assert!(p.can_execute(p.pc_base()));
// ROM and RAM do not overlap.
assert!(!p.is_rom(p.ram_start()));
assert!(!p.is_rom(p.ram_end() - WORD_SIZE as Addr));
assert!(!p.is_ram(p.rom_start()));
assert!(!p.is_ram(p.rom_end() - WORD_SIZE as Addr));
assert!(!p.is_rom(p.ram.start));
assert!(!p.is_rom(p.ram.end - WORD_SIZE as Addr));
assert!(!p.is_ram(p.rom.start));
assert!(!p.is_ram(p.rom.end - WORD_SIZE as Addr));
// Registers do not overlap with ROM or RAM.
for reg in [
Platform::register_vma(0),
Expand Down
2 changes: 1 addition & 1 deletion ceno_emul/src/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl StepRecord {
Some(value),
Some(Change::new(value, value)),
Some(WriteOp {
addr: CENO_PLATFORM.ram_start().into(),
addr: CENO_PLATFORM.ram.start.into(),
value: Change {
before: value,
after: value,
Expand Down
2 changes: 1 addition & 1 deletion ceno_emul/src/vm_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl EmuContext for VMState {
// Read two registers, write one register, write one memory word, and branch.
tracing::warn!("ecall ignored: syscall_id={}", function);
self.store_register(DecodedInstruction::RD_NULL as RegIdx, 0)?;
let addr = self.platform.ram_start().into();
let addr = self.platform.ram.start.into();
self.store_memory(addr, self.peek_memory(addr))?;
self.set_pc(ByteAddr(self.pc) + PC_STEP_SIZE);
Ok(true)
Expand Down
2 changes: 1 addition & 1 deletion ceno_emul/tests/test_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn test_ceno_rt_mem() -> Result<()> {
let mut state = VMState::new_from_elf(CENO_PLATFORM, program_elf)?;
let _steps = run(&mut state)?;

let value = state.peek_memory(CENO_PLATFORM.ram_start().into());
let value = state.peek_memory(CENO_PLATFORM.ram.start.into());
assert_eq!(value, 6765, "Expected Fibonacci 20, got {}", value);
Ok(())
}
Expand Down
12 changes: 6 additions & 6 deletions ceno_zkvm/examples/riscv_opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ const PROGRAM_CODE: [u32; PROGRAM_SIZE] = {
let mut program: [u32; PROGRAM_SIZE] = [ECALL_HALT; PROGRAM_SIZE];
declare_program!(
program,
encode_rv32(LUI, 0, 0, 10, CENO_PLATFORM.public_io_start()), // lui x10, public_io
encode_rv32(LW, 10, 0, 1, 0), // lw x1, 0(x10)
encode_rv32(LW, 10, 0, 2, 4), // lw x2, 4(x10)
encode_rv32(LW, 10, 0, 3, 8), // lw x3, 8(x10)
encode_rv32(LUI, 0, 0, 10, CENO_PLATFORM.public_io.start), // lui x10, public_io
encode_rv32(LW, 10, 0, 1, 0), // lw x1, 0(x10)
encode_rv32(LW, 10, 0, 2, 4), // lw x2, 4(x10)
encode_rv32(LW, 10, 0, 3, 8), // lw x3, 8(x10)
// Main loop.
encode_rv32(ADD, 1, 4, 4, 0), // add x4, x1, x4
encode_rv32(ADD, 2, 3, 3, 0), // add x3, x2, x3
Expand Down Expand Up @@ -90,8 +90,8 @@ fn main() {
})
.collect(),
);
let mem_addresses = CENO_PLATFORM.ram_start()..CENO_PLATFORM.ram_end();
let io_addresses = CENO_PLATFORM.public_io_start()..CENO_PLATFORM.public_io_end();
let mem_addresses = CENO_PLATFORM.ram.clone();
let io_addresses = CENO_PLATFORM.public_io.clone();

let (flame_layer, _guard) = FlameLayer::with_file("./tracing.folded").unwrap();
let mut fmt_layer = fmt::layer()
Expand Down
9 changes: 4 additions & 5 deletions ceno_zkvm/src/bin/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,16 @@ fn main() {
Preset::Sp1 => Platform {
// The stack section is not mentioned in ELF headers, so we repeat the constant STACK_TOP here.
stack_top: 0x0020_0400,
rom_start: 0x0020_0800,
rom_end: 0x0040_0000,
ram_start: 0x0020_0000,
ram_end: 0xFFFF_0000,
rom: 0x0020_0800..0x0040_0000,
ram: 0x0020_0000..0xFFFF_0000,
unsafe_ecall_nop: true,
..CENO_PLATFORM
},
};
tracing::info!("Running on platform {:?}", args.platform);

const STACK_SIZE: u32 = 256;
let mut mem_padder = MemPadder::new(platform.ram_start()..platform.ram_end());
let mut mem_padder = MemPadder::new(platform.ram.clone());

tracing::info!("Loading ELF file: {}", args.elf);
let elf_bytes = fs::read(&args.elf).expect("read elf file");
Expand Down
8 changes: 4 additions & 4 deletions ceno_zkvm/src/tables/ram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl DynVolatileRamTable for DynMemTable {
const ZERO_INIT: bool = true;

fn offset_addr(params: &ProgramParams) -> Addr {
params.platform.ram_start()
params.platform.ram.start
}

fn end_addr(params: &ProgramParams) -> Addr {
params.platform.ram_end()
params.platform.ram.end
}

fn name() -> &'static str {
Expand All @@ -41,11 +41,11 @@ impl DynVolatileRamTable for PrivateMemTable {
const ZERO_INIT: bool = false;

fn offset_addr(params: &ProgramParams) -> Addr {
params.platform.ram_start()
params.platform.ram.start
}

fn end_addr(params: &ProgramParams) -> Addr {
params.platform.ram_end()
params.platform.ram.end
}

fn name() -> &'static str {
Expand Down