1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use crate::{
instructions::Instruction, MEMORY_FRAMES, RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY,
RISCV_PAGES,
};
use std::alloc::{alloc, Layout};
pub const TRACE_SIZE: usize = 8192;
pub const TRACE_ITEM_LENGTH: usize = 16;
pub const RET_DECODE_TRACE: u8 = 1;
pub const RET_ECALL: u8 = 2;
pub const RET_EBREAK: u8 = 3;
pub const RET_DYNAMIC_JUMP: u8 = 4;
pub const RET_MAX_CYCLES_EXCEEDED: u8 = 5;
pub const RET_CYCLES_OVERFLOW: u8 = 6;
pub const RET_OUT_OF_BOUND: u8 = 7;
pub const RET_INVALID_PERMISSION: u8 = 8;
pub const RET_SLOWPATH: u8 = 9;
#[inline(always)]
pub fn calculate_slot(addr: u64) -> usize {
(addr as usize >> 2) & (TRACE_SIZE - 1)
}
#[derive(Default)]
#[repr(C)]
pub struct Trace {
pub address: u64,
pub length: u8,
pub cycles: u64,
pub instructions: [Instruction; TRACE_ITEM_LENGTH + 1],
pub thread: [u64; TRACE_ITEM_LENGTH + 1],
}
#[repr(C)]
pub struct AsmCoreMachine {
pub registers: [u64; RISCV_GENERAL_REGISTER_NUMBER],
pub pc: u64,
pub next_pc: u64,
pub running: u8,
pub cycles: u64,
pub max_cycles: u64,
pub chaos_mode: u8,
pub chaos_seed: u32,
pub reset_signal: u8,
pub isa: u8,
pub version: u32,
pub flags: [u8; RISCV_PAGES],
pub memory: [u8; RISCV_MAX_MEMORY],
pub frames: [u8; MEMORY_FRAMES],
pub traces: [Trace; TRACE_SIZE],
}
impl AsmCoreMachine {
pub fn new(isa: u8, version: u32, max_cycles: u64) -> Box<AsmCoreMachine> {
let mut machine = unsafe {
let layout = Layout::new::<AsmCoreMachine>();
#[allow(clippy::cast_ptr_alignment)]
let raw_allocation = alloc(layout) as *mut AsmCoreMachine;
Box::from_raw(raw_allocation)
};
machine.registers = [0; RISCV_GENERAL_REGISTER_NUMBER];
machine.pc = 0;
machine.next_pc = 0;
machine.running = 0;
machine.cycles = 0;
machine.max_cycles = max_cycles;
if cfg!(feature = "enable-chaos-mode-by-default") {
machine.chaos_mode = 1;
} else {
machine.chaos_mode = 0;
}
machine.chaos_seed = 0;
machine.reset_signal = 0;
machine.version = version;
machine.isa = isa;
machine.flags = [0; RISCV_PAGES];
for i in 0..TRACE_SIZE {
machine.traces[i] = Trace::default();
}
machine.frames = [0; MEMORY_FRAMES];
machine
}
}