Skip to content

Commit

Permalink
Vm support for continuation (#57)
Browse files Browse the repository at this point in the history
* add support for vm continuation

* open mips may access memory > 0x80000000

* write image to json file

* add support for load segment

* initialize registers when load segment

* add register page to rtrace at the begining

* fix register page

* add end pc for segment

* ignore slot instruction in mips-emulator and add check for end pc

* fix syscall

* fix rtrace image

* fix fmt

* ignore vm execute minigeth

* change println to log::debug

* fix cargo fmt
  • Loading branch information
weilzkm authored Dec 18, 2023
1 parent ffdac22 commit e0bef35
Show file tree
Hide file tree
Showing 133 changed files with 5,121 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
/Cargo.lock
/output
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static_assertions = "1.1.0"
keccak-hash = "0.10.0"
byteorder = "1.5.0"
hex = "0.4"
lazy_static = "1.4.0"

elf = { version = "0.7", default-features = false }

Expand Down
1 change: 1 addition & 0 deletions output/segment0

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions output/segment1

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions src/cpu/kernel/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,29 @@ pub(crate) fn combined_kernel() -> Kernel {
}
}

pub(crate) fn segment_kernel() -> Kernel {
let code = Vec::new();

let p: Program = Program::load_segment(0).unwrap();

let code_hash_bytes = keccak(&code).0;
let code_hash_be = core::array::from_fn(|i| {
u32::from_le_bytes(core::array::from_fn(|j| code_hash_bytes[i * 4 + j]))
});
let code_hash = code_hash_be.map(u32::from_be);
log::debug!("code_hash: {:?}", code_hash);
let blockpath = Program::get_block_path("13284491", "");

Kernel {
program: p,
code,
code_hash,
ordered_labels: vec![],
global_labels: HashMap::new(),
blockpath,
}
}

impl Kernel {
/// Get a string representation of the current offset for debugging purposes.
pub(crate) fn offset_name(&self, offset: usize) -> String {
Expand All @@ -81,3 +104,4 @@ impl Kernel {
pub(crate) const BYTES_PER_OFFSET: u8 = 3;

pub static KERNEL: Lazy<Kernel> = Lazy::new(combined_kernel);
//pub static KERNEL: Lazy<Kernel> = Lazy::new(segment_kernel);
78 changes: 75 additions & 3 deletions src/cpu/kernel/elf.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
extern crate alloc;
use crate::mips_emulator::state::Segment;
use alloc::collections::BTreeMap;
use serde::{Deserialize, Serialize};

use anyhow::{anyhow, bail, Context, Result};
use elf::{endian::BigEndian, file::Class, ElfBytes};
use serde::{Deserialize, Serialize};
use std::env;
use std::fs;
use std::fs::File;
use std::io::BufReader;

pub const WORD_SIZE: usize = core::mem::size_of::<u32>();
pub const INIT_SP: u32 = 0x7fffd000;
pub const PAGE_SIZE: u32 = 4096;
Expand All @@ -18,6 +21,12 @@ pub struct Program {

/// The initial memory image
pub image: BTreeMap<u32, u32>,

pub gprs: [usize; 32],
pub lo: usize,
pub hi: usize,
pub heap: usize,
pub end_pc: usize,
}

impl Program {
Expand Down Expand Up @@ -196,7 +205,70 @@ impl Program {
image.insert(sp + 4 * 11, 0x44572234u32.to_be());
image.insert(sp + 4 * 12, 0x90032dd2u32.to_be());

Ok(Program { entry, image })
let mut gprs = [0; 32];
gprs[29] = INIT_SP as usize;

let lo = 0;
let hi = 0;
let heap = 0x20000000;
let end_pc = 0;

Ok(Program {
entry,
image,
gprs,
lo,
hi,
heap,
end_pc,
})
}

pub fn load_segment(segment_id: u32) -> Result<Program> {
let mut name = String::from("output/segment");
name.push_str(&segment_id.to_string());
log::debug!("file {}", name);
let f = File::open(name).unwrap();
let reader = BufReader::new(f);

let segment: Segment = serde_json::from_reader(reader).unwrap();

let entry = segment.pc;
let image = segment.mem_image;
let end_pc = segment.end_pc as usize;

let mut gprs: [usize; 32] = [0; 32];

for i in 0..32 {
let data = image.get(&((i << 2) as u32)).unwrap();
gprs[i] = data.to_be() as usize;
}

let lo: usize = image.get(&((32 << 2) as u32)).unwrap().to_be() as usize;
let hi: usize = image.get(&((33 << 2) as u32)).unwrap().to_be() as usize;
let heap: usize = image.get(&((34 << 2) as u32)).unwrap().to_be() as usize;
let pc: usize = image.get(&((35 << 2) as u32)).unwrap().to_be() as usize;

log::debug!(
"load segment pc: {} image: {:?} gprs: {:?} lo: {} hi: {} heap:{} range: ({} -> {})",
segment.pc,
segment.image_id,
gprs,
lo,
hi,
heap,
pc,
end_pc
);
Ok(Program {
entry,
image,
gprs,
lo,
hi,
heap,
end_pc,
})
}
}

Expand Down
13 changes: 11 additions & 2 deletions src/generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use crate::cpu::columns::CpuColumnsView;
use crate::cpu::kernel::KERNEL;
use crate::generation::outputs::{get_outputs, GenerationOutputs};
use crate::generation::state::GenerationState;
use crate::mips_emulator::state::SEGMENT_STEPS;
use crate::witness::transition::transition;

/// Inputs needed for trace generation. Wrap the trace record.
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
pub struct GenerationInputs {
Expand All @@ -41,7 +41,7 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
// Decode the trace record
// 1. Decode instruction and fill in cpu columns
// 2. Decode memory and fill in memory columns
let mut state = GenerationState::<F>::new(inputs.clone(), &KERNEL.code, 400000).unwrap();
let mut state = GenerationState::<F>::new(inputs.clone(), &KERNEL.code, SEGMENT_STEPS).unwrap();
generate_bootstrap_kernel::<F>(&mut state);

timed!(timing, "simulate CPU", simulate_cpu(&mut state)?);
Expand Down Expand Up @@ -90,6 +90,15 @@ pub(crate) fn simulate_cpu<F: RichField + Extendable<D>, const D: usize>(
row.program_counter = F::from_canonical_usize(pc);
row.is_kernel_mode = F::ONE;

if step == state.step && pc != KERNEL.program.end_pc {
log::error!(
"Segment split {} error at {:X} expected: {:X}",
step,
pc,
KERNEL.program.end_pc
)
}

loop {
state.traces.push_cpu(row);
row.clock += F::ONE;
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub(crate) mod keccak_sponge;
pub(crate) mod logic;
pub(crate) mod lookup;
pub(crate) mod memory;
pub(crate) mod mips_emulator;
pub(crate) mod proof;
pub(crate) mod prover;
pub(crate) mod stark;
Expand Down
Loading

0 comments on commit e0bef35

Please sign in to comment.