#![expect(
unsafe_code,
reason = "`Processor::map` hands the processor host memory by raw pointer, which only its caller can keep in place"
)]
use super::{Access, DataModel, Error, HostCall, InterruptLine};
use crate::device::Level;
use crate::soc::{Endian, Width};
use crate::time::VirtualNanos;
pub trait CoreBus {
fn access(&mut self, access: Access, from_code: bool) -> Option<u64>;
fn time(&self, instructions: u64) -> VirtualNanos;
fn queued(&mut self) -> Vec<Queued>;
fn carry_on(&mut self, instructions: u64, event: Option<VirtualNanos>) -> Option<u32> {
let _ = (instructions, event);
None
}
fn stops_before(&mut self, access: &Access) -> bool {
let _ = access;
false
}
fn send_trace(&mut self, bytes: &[u8]) {
let _ = bytes;
}
}
pub trait Processor: Send + std::fmt::Debug {
fn run(&mut self, budget: u32, bus: &mut dyn CoreBus) -> (Exit, u64);
fn retired(&self) -> u64;
fn ask(&mut self, queued: Queued);
fn maps(&self, start: u64, length: u64) -> bool {
let _ = (start, length);
true
}
fn page_size(&self) -> u64 {
1
}
unsafe fn map(&mut self, start: u64, length: u64, host: *mut u8, writable: bool) {
let _ = (start, length, host, writable);
}
fn boot(&mut self, table: u64, read: &dyn Fn(u64, Width) -> Option<u64>);
fn reset(&mut self);
fn take_reset_request(&mut self) -> bool;
fn next_event(&self) -> Option<VirtualNanos>;
fn on_event(&mut self, now: VirtualNanos);
fn waiting(&self) -> bool;
fn pc(&self) -> u64;
fn add_breakpoint(&mut self, address: u64) -> bool {
let _ = address;
false
}
fn remove_breakpoint(&mut self, address: u64) {
let _ = address;
}
fn pass_breakpoint(&mut self, address: u64) {
let _ = address;
}
fn attach_debugger(&mut self, attached: bool);
fn hold_interrupts(&mut self, held: bool);
fn gdb_register(&self, number: usize) -> Option<Vec<u8>>;
fn set_gdb_register(&mut self, number: usize, bytes: &[u8]) -> bool;
fn debugger_access(
&mut self,
write: Option<u64>,
address: u64,
width: Width,
now: VirtualNanos,
) -> Option<u64>;
fn take_debugger_trace(&mut self) -> Vec<u8> {
Vec::new()
}
fn target_xml(&self) -> &'static str;
fn data_model(&self) -> DataModel;
fn byte_order(&self, address: u64) -> Endian;
fn save(&self) -> Vec<u8>;
fn load(&mut self, bytes: &[u8]) -> Result<(), Error>;
fn monitor_command(&mut self, command: &str) -> Option<String> {
let _ = command;
None
}
fn debugger_halted(&mut self, why: HaltReason) -> bool {
let _ = why;
false
}
fn bit_alias(&self, address: u64, width: Width) -> Option<BitAlias> {
let _ = (address, width);
None
}
fn own_ranges(&self) -> Vec<std::ops::Range<u64>> {
Vec::new()
}
fn host_call(&self, _read: &mut dyn FnMut(u64, Width) -> Option<u64>) -> Option<HostCall> {
None
}
fn answer_host_call(&mut self, _answer: Option<u64>) {}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Queued {
Line(InterruptLine, Level),
Invalidate(u64, u64),
Route(u64),
Unroute(u64),
Return,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BitAlias {
pub unit: u64,
pub bit: u32,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum HaltReason {
Requested,
Breakpoint,
Watchpoint,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Exit {
Budget,
Breakpoint,
Waiting,
Lockup,
Halted,
HostCall,
Returned,
}