2021-10-06 23:14:56 +00:00
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
use std::rc::Rc;
|
2023-06-10 22:28:21 +00:00
|
|
|
use std::cell::{RefCell, RefMut};
|
2021-10-30 03:06:15 +00:00
|
|
|
use std::collections::HashMap;
|
2021-10-06 23:14:56 +00:00
|
|
|
|
2023-06-11 02:29:54 +00:00
|
|
|
use crate::{Bus, EdgeSignal, Error, InterruptController, ClockTime, ClockDuration, Address, Device};
|
2021-10-06 23:14:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
pub struct System {
|
2023-04-23 22:46:47 +00:00
|
|
|
pub clock: ClockTime,
|
2023-06-08 03:44:14 +00:00
|
|
|
pub devices: HashMap<String, Device>,
|
2021-11-23 19:45:11 +00:00
|
|
|
pub event_queue: Vec<NextStep>,
|
2021-11-01 23:51:45 +00:00
|
|
|
|
2023-06-08 04:08:28 +00:00
|
|
|
pub debuggables: Vec<Device>,
|
2021-11-03 22:33:22 +00:00
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
pub bus: Rc<RefCell<Bus>>,
|
2023-05-13 21:47:27 +00:00
|
|
|
pub buses: HashMap<String, Rc<RefCell<Bus>>>,
|
2021-10-09 18:00:32 +00:00
|
|
|
pub interrupt_controller: RefCell<InterruptController>,
|
2021-12-09 03:07:27 +00:00
|
|
|
|
|
|
|
pub break_signal: Option<EdgeSignal>,
|
2021-10-06 23:14:56 +00:00
|
|
|
}
|
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
impl Default for System {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
2023-04-23 22:46:47 +00:00
|
|
|
clock: ClockTime::START,
|
2021-11-01 23:51:45 +00:00
|
|
|
devices: HashMap::new(),
|
2021-10-30 03:06:15 +00:00
|
|
|
event_queue: vec![],
|
2021-11-01 23:51:45 +00:00
|
|
|
|
2023-06-08 04:08:28 +00:00
|
|
|
debuggables: Vec::new(),
|
2021-11-03 22:33:22 +00:00
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
bus: Rc::new(RefCell::new(Bus::default())),
|
2023-05-13 21:47:27 +00:00
|
|
|
buses: HashMap::new(),
|
2023-03-06 04:19:49 +00:00
|
|
|
interrupt_controller: RefCell::new(InterruptController::default()),
|
2021-12-09 03:07:27 +00:00
|
|
|
|
|
|
|
break_signal: None,
|
2021-10-06 23:14:56 +00:00
|
|
|
}
|
|
|
|
}
|
2023-03-06 04:19:49 +00:00
|
|
|
}
|
2021-10-06 23:14:56 +00:00
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
impl System {
|
2021-10-07 16:41:01 +00:00
|
|
|
pub fn get_bus(&self) -> RefMut<'_, Bus> {
|
|
|
|
self.bus.borrow_mut()
|
2021-10-06 23:14:56 +00:00
|
|
|
}
|
|
|
|
|
2021-10-09 18:00:32 +00:00
|
|
|
pub fn get_interrupt_controller(&self) -> RefMut<'_, InterruptController> {
|
|
|
|
self.interrupt_controller.borrow_mut()
|
|
|
|
}
|
|
|
|
|
2023-06-08 03:44:14 +00:00
|
|
|
pub fn get_device(&self, name: &str) -> Result<Device, Error> {
|
2023-06-11 00:39:20 +00:00
|
|
|
self.devices.get(name).cloned().ok_or_else(|| Error::new(format!("system: no device named {}", name)))
|
2021-12-26 00:30:07 +00:00
|
|
|
}
|
|
|
|
|
2023-06-08 03:44:14 +00:00
|
|
|
pub fn add_device(&mut self, name: &str, device: Device) -> Result<(), Error> {
|
2023-06-08 04:08:28 +00:00
|
|
|
self.try_add_debuggable(device.clone());
|
2021-11-13 19:39:20 +00:00
|
|
|
self.try_queue_device(device.clone());
|
|
|
|
self.devices.insert(name.to_string(), device);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-06-08 03:44:14 +00:00
|
|
|
pub fn add_addressable_device(&mut self, addr: Address, device: Device) -> Result<(), Error> {
|
2021-11-29 19:11:32 +00:00
|
|
|
self.add_peripheral(&format!("mem{:x}", addr), addr, device)
|
|
|
|
}
|
|
|
|
|
2023-06-08 03:44:14 +00:00
|
|
|
pub fn add_peripheral(&mut self, name: &str, addr: Address, device: Device) -> Result<(), Error> {
|
2021-12-06 22:51:57 +00:00
|
|
|
self.bus.borrow_mut().insert(addr, device.clone());
|
2023-06-08 04:08:28 +00:00
|
|
|
self.try_add_debuggable(device.clone());
|
2021-10-30 03:06:15 +00:00
|
|
|
self.try_queue_device(device.clone());
|
2021-11-29 19:11:32 +00:00
|
|
|
self.devices.insert(name.to_string(), device);
|
2021-10-07 18:35:15 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-06-08 03:44:14 +00:00
|
|
|
pub fn add_interruptable_device(&mut self, name: &str, device: Device) -> Result<(), Error> {
|
2023-06-08 04:08:28 +00:00
|
|
|
self.try_add_debuggable(device.clone());
|
2021-10-30 03:06:15 +00:00
|
|
|
self.try_queue_device(device.clone());
|
2021-11-01 23:51:45 +00:00
|
|
|
self.devices.insert(name.to_string(), device);
|
2021-10-07 16:41:01 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
2021-10-06 23:14:56 +00:00
|
|
|
|
2021-12-09 03:07:27 +00:00
|
|
|
fn process_one_event(&mut self) -> Result<(), Error> {
|
2021-10-24 05:22:02 +00:00
|
|
|
let mut event_device = self.event_queue.pop().unwrap();
|
|
|
|
self.clock = event_device.next_clock;
|
2023-03-06 04:19:49 +00:00
|
|
|
let result = match event_device.device.borrow_mut().as_steppable().unwrap().step(self) {
|
2021-11-03 22:33:22 +00:00
|
|
|
Ok(diff) => {
|
2023-04-23 23:17:07 +00:00
|
|
|
event_device.next_clock = self.clock.checked_add(diff).unwrap();
|
2021-11-03 22:33:22 +00:00
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
Err(err) => Err(err),
|
|
|
|
};
|
2021-10-30 03:06:15 +00:00
|
|
|
self.queue_device(event_device);
|
2021-11-03 22:33:22 +00:00
|
|
|
result
|
2021-10-24 05:22:02 +00:00
|
|
|
}
|
|
|
|
|
2023-06-11 02:29:54 +00:00
|
|
|
/// Step the simulation one event exactly
|
2021-12-09 03:07:27 +00:00
|
|
|
pub fn step(&mut self) -> Result<(), Error> {
|
|
|
|
match self.process_one_event() {
|
2023-06-10 22:28:21 +00:00
|
|
|
Ok(()) => {},
|
2023-06-11 02:29:54 +00:00
|
|
|
Err(err @ Error::Breakpoint(_)) => {
|
2023-06-10 22:28:21 +00:00
|
|
|
return Err(err);
|
2021-12-09 03:07:27 +00:00
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
self.exit_error();
|
2023-06-10 22:28:21 +00:00
|
|
|
log::error!("{:?}", err);
|
2021-12-09 03:07:27 +00:00
|
|
|
return Err(err);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-06-11 02:29:54 +00:00
|
|
|
/// Step through the simulation until the next event is for the given device
|
2023-06-10 22:28:21 +00:00
|
|
|
pub fn step_until_device(&mut self, device: Device) -> Result<(), Error> {
|
|
|
|
loop {
|
|
|
|
self.step()?;
|
|
|
|
|
|
|
|
if self.get_next_event_device().id() == device.id() {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-06-11 02:29:54 +00:00
|
|
|
/// Step through the simulation until the next event scheduled is for a debuggable device
|
2023-06-10 22:28:21 +00:00
|
|
|
pub fn step_until_debuggable(&mut self) -> Result<(), Error> {
|
|
|
|
loop {
|
|
|
|
self.step()?;
|
|
|
|
|
|
|
|
if self.get_next_event_device().borrow_mut().as_debuggable().is_some() {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-06-11 02:29:54 +00:00
|
|
|
/// Run the simulation until the given simulation clock time has been reached
|
2023-06-10 22:28:21 +00:00
|
|
|
pub fn run_until_clock(&mut self, clock: ClockTime) -> Result<(), Error> {
|
|
|
|
while self.clock < clock {
|
|
|
|
self.step()?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-06-11 02:29:54 +00:00
|
|
|
/// Run the simulation for `elapsed` amount of simulation time
|
2023-06-10 22:28:21 +00:00
|
|
|
pub fn run_for_duration(&mut self, elapsed: ClockDuration) -> Result<(), Error> {
|
2021-11-23 19:45:11 +00:00
|
|
|
let target = self.clock + elapsed;
|
2021-10-24 05:22:02 +00:00
|
|
|
|
|
|
|
while self.clock < target {
|
2021-12-09 03:07:27 +00:00
|
|
|
self.step()?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-06-11 02:29:54 +00:00
|
|
|
/// Run the simulation forever, or until there is an error
|
2023-06-10 22:28:21 +00:00
|
|
|
pub fn run_forever(&mut self) -> Result<(), Error> {
|
|
|
|
self.run_until_clock(ClockTime::FOREVER)
|
|
|
|
}
|
|
|
|
|
2021-10-07 18:35:15 +00:00
|
|
|
pub fn exit_error(&mut self) {
|
2021-11-01 23:51:45 +00:00
|
|
|
for (_, dev) in self.devices.iter() {
|
2023-03-06 04:34:30 +00:00
|
|
|
if let Some(dev) = dev.borrow_mut().as_steppable() {
|
|
|
|
dev.on_error(self);
|
2021-10-07 18:35:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-10-15 04:16:31 +00:00
|
|
|
|
2023-06-10 22:28:21 +00:00
|
|
|
pub fn get_next_event_device(&self) -> Device {
|
|
|
|
self.event_queue[self.event_queue.len() - 1].device.clone()
|
2023-06-08 04:08:28 +00:00
|
|
|
}
|
|
|
|
|
2023-06-10 22:28:21 +00:00
|
|
|
pub fn get_next_debuggable_device(&self) -> Option<Device> {
|
|
|
|
for event in self.event_queue.iter().rev() {
|
|
|
|
if event.device.borrow_mut().as_debuggable().is_some() {
|
|
|
|
return Some(event.device.clone());
|
2021-12-21 03:53:12 +00:00
|
|
|
}
|
|
|
|
}
|
2023-06-10 22:28:21 +00:00
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn try_add_debuggable(&mut self, device: Device) {
|
|
|
|
if device.borrow_mut().as_debuggable().is_some() {
|
|
|
|
self.debuggables.push(device);
|
|
|
|
}
|
2021-12-21 03:53:12 +00:00
|
|
|
}
|
2021-10-30 03:06:15 +00:00
|
|
|
|
2023-06-08 03:44:14 +00:00
|
|
|
fn try_queue_device(&mut self, device: Device) {
|
2021-10-30 03:06:15 +00:00
|
|
|
if device.borrow_mut().as_steppable().is_some() {
|
2021-11-23 19:45:11 +00:00
|
|
|
self.queue_device(NextStep::new(device));
|
2021-10-30 03:06:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-23 19:45:11 +00:00
|
|
|
fn queue_device(&mut self, device_step: NextStep) {
|
2023-03-25 17:51:46 +00:00
|
|
|
for (i, event) in self.event_queue.iter().enumerate().rev() {
|
|
|
|
if event.next_clock > device_step.next_clock {
|
2021-11-01 23:51:45 +00:00
|
|
|
self.event_queue.insert(i + 1, device_step);
|
2021-10-30 03:06:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-11-01 23:51:45 +00:00
|
|
|
self.event_queue.insert(0, device_step);
|
2021-10-30 03:06:15 +00:00
|
|
|
}
|
2021-10-24 05:22:02 +00:00
|
|
|
}
|
2021-10-19 18:33:51 +00:00
|
|
|
|
2021-10-24 05:22:02 +00:00
|
|
|
|
2021-11-23 19:45:11 +00:00
|
|
|
pub struct NextStep {
|
2023-04-23 22:46:47 +00:00
|
|
|
pub next_clock: ClockTime,
|
2023-06-08 03:44:14 +00:00
|
|
|
pub device: Device,
|
2021-10-24 05:22:02 +00:00
|
|
|
}
|
|
|
|
|
2021-11-23 19:45:11 +00:00
|
|
|
impl NextStep {
|
2023-06-08 03:44:14 +00:00
|
|
|
pub fn new(device: Device) -> Self {
|
2021-10-24 05:22:02 +00:00
|
|
|
Self {
|
2023-04-23 22:46:47 +00:00
|
|
|
next_clock: ClockTime::START,
|
2021-10-24 05:22:02 +00:00
|
|
|
device,
|
2021-10-19 18:33:51 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-24 05:22:02 +00:00
|
|
|
}
|
2021-10-22 04:55:27 +00:00
|
|
|
|