mirror of
https://github.com/transistorfet/moa.git
synced 2024-12-12 05:29:35 +00:00
Rewrite system device storage
This commit is contained in:
parent
6e7e315808
commit
64571e45b8
@ -1,6 +1,8 @@
|
|||||||
|
use std::any::{Any, TypeId};
|
||||||
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::{RefCell, RefMut, BorrowMutError};
|
use std::cell::RefCell;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
use femtos::{Duration, Instant};
|
use femtos::{Duration, Instant};
|
||||||
|
|
||||||
use crate::{Error, System};
|
use crate::{Error, System};
|
||||||
@ -172,6 +174,13 @@ pub trait Inspectable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub type DeviceId = u32;
|
||||||
|
pub trait Resource: Any + 'static + Transmutable {}
|
||||||
|
|
||||||
|
pub type Device = Rc<RefCell<dyn Resource>>;
|
||||||
|
|
||||||
|
impl<T> Resource for T where T: Transmutable + 'static {}
|
||||||
|
|
||||||
pub trait Transmutable {
|
pub trait Transmutable {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||||
@ -199,54 +208,76 @@ pub trait Transmutable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Taken from deno_core
|
||||||
|
fn is<T: Resource>(field: &dyn Resource) -> bool {
|
||||||
|
field.type_id() == TypeId::of::<T>()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taken from deno_core
|
||||||
|
pub fn downcast_rc_refc<'a, T: Resource>(field: &'a Device) -> Option<&'a Rc<RefCell<T>>> {
|
||||||
|
if is::<T>(field.borrow().deref()) {
|
||||||
|
let ptr = field as *const Rc<RefCell<_>> as *const Rc<RefCell<T>>;
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
Some(unsafe { &*ptr })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type TransmutableBox = Rc<RefCell<Box<dyn Transmutable>>>;
|
pub type TransmutableBox = Rc<RefCell<Box<dyn Transmutable>>>;
|
||||||
|
|
||||||
pub fn wrap_transmutable<T: Transmutable + 'static>(value: T) -> TransmutableBox {
|
pub fn wrap_transmutable<T: Transmutable + 'static>(value: T) -> TransmutableBox {
|
||||||
Rc::new(RefCell::new(Box::new(value)))
|
Rc::new(RefCell::new(Box::new(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(1);
|
static NEXT_ID: AtomicU32 = AtomicU32::new(1);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
pub fn get_next_id() -> u32 {
|
||||||
pub struct DeviceId(usize);
|
let next = NEXT_ID.load(Ordering::Acquire);
|
||||||
|
NEXT_ID.store(next + 1, Ordering::Release);
|
||||||
impl DeviceId {
|
next
|
||||||
pub fn new() -> Self {
|
|
||||||
let next = NEXT_ID.load(Ordering::Acquire);
|
|
||||||
NEXT_ID.store(next + 1, Ordering::Release);
|
|
||||||
Self(next)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DeviceId {
|
// #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
fn default() -> Self {
|
// pub struct DeviceId(usize);
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
// impl DeviceId {
|
||||||
pub struct Device(DeviceId, TransmutableBox);
|
// pub fn new() -> Self {
|
||||||
|
// let next = NEXT_ID.load(Ordering::Acquire);
|
||||||
|
// NEXT_ID.store(next + 1, Ordering::Release);
|
||||||
|
// Self(next)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl Device {
|
// impl Default for DeviceId {
|
||||||
pub fn new<T>(value: T) -> Self
|
// fn default() -> Self {
|
||||||
where
|
// Self::new()
|
||||||
T: Transmutable + 'static,
|
// }
|
||||||
{
|
// }
|
||||||
Self(DeviceId::new(), wrap_transmutable(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn id(&self) -> DeviceId {
|
// #[derive(Clone)]
|
||||||
self.0
|
// pub struct Device(DeviceId, TransmutableBox);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn borrow_mut(&self) -> RefMut<'_, Box<dyn Transmutable>> {
|
// impl Device {
|
||||||
self.1.borrow_mut()
|
// pub fn new<T>(value: T) -> Self
|
||||||
}
|
// where
|
||||||
|
// T: Transmutable + 'static,
|
||||||
|
// {
|
||||||
|
// Self(DeviceId::new(), wrap_transmutable(value))
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, Box<dyn Transmutable>>, BorrowMutError> {
|
// pub fn id(&self) -> DeviceId {
|
||||||
self.1.try_borrow_mut()
|
// self.0
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
|
// pub fn borrow_mut(&self) -> RefMut<'_, Box<dyn Transmutable>> {
|
||||||
|
// self.1.borrow_mut()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn try_borrow_mut(&self) -> Result<RefMut<'_, Box<dyn Transmutable>>, BorrowMutError> {
|
||||||
|
// self.1.try_borrow_mut()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7,7 +7,7 @@ mod memory;
|
|||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
pub use crate::devices::{
|
pub use crate::devices::{
|
||||||
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, Device,
|
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, Resource
|
||||||
};
|
};
|
||||||
pub use crate::devices::{
|
pub use crate::devices::{
|
||||||
read_beu16, read_beu32, read_leu16, read_leu32, write_beu16, write_beu32, write_leu16, write_leu32, wrap_transmutable,
|
read_beu16, read_beu32, read_leu16, read_leu32, write_beu16, write_beu32, write_leu16, write_leu32, wrap_transmutable,
|
||||||
@ -15,6 +15,6 @@ pub use crate::devices::{
|
|||||||
pub use crate::error::Error;
|
pub use crate::error::Error;
|
||||||
pub use crate::interrupts::InterruptController;
|
pub use crate::interrupts::InterruptController;
|
||||||
pub use crate::memory::{MemoryBlock, AddressTranslator, AddressRepeater, Bus, BusPort, dump_slice, dump_memory};
|
pub use crate::memory::{MemoryBlock, AddressTranslator, AddressRepeater, Bus, BusPort, dump_slice, dump_memory};
|
||||||
pub use crate::system::System;
|
pub use crate::system::{System, DeviceSettings};
|
||||||
|
|
||||||
pub use emulator_hal::bus::{BusAccess};
|
pub use emulator_hal::bus::BusAccess;
|
||||||
|
@ -1,29 +1,33 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
use std::collections::HashMap;
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use femtos::{Instant, Duration};
|
use femtos::{Instant, Duration};
|
||||||
|
|
||||||
use crate::{Bus, Error, InterruptController, Address, Device};
|
use crate::devices::{downcast_rc_refc, get_next_id, Device, DeviceId, Resource};
|
||||||
|
use crate::{Address, Bus, Error, InterruptController};
|
||||||
|
|
||||||
|
|
||||||
pub struct System {
|
pub struct System {
|
||||||
pub clock: Instant,
|
pub clock: Instant,
|
||||||
pub devices: HashMap<String, Device>,
|
pub devices: BTreeMap<DeviceId, Device>,
|
||||||
pub event_queue: Vec<NextStep>,
|
pub event_queue: Vec<NextStep>,
|
||||||
|
pub id_to_name: HashMap<DeviceId, String>,
|
||||||
|
|
||||||
pub debuggables: Vec<Device>,
|
pub debuggables: Vec<DeviceId>,
|
||||||
|
|
||||||
pub bus: Rc<RefCell<Bus>>,
|
pub bus: Rc<RefCell<Bus>>,
|
||||||
pub buses: HashMap<String, Rc<RefCell<Bus>>>,
|
pub buses: HashMap<String, Rc<RefCell<Bus>>>,
|
||||||
pub interrupt_controller: RefCell<InterruptController>,
|
pub interrupt_controller: RefCell<InterruptController>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Default for System {
|
impl Default for System {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
clock: Instant::START,
|
clock: Instant::START,
|
||||||
devices: HashMap::new(),
|
devices: BTreeMap::new(),
|
||||||
event_queue: vec![],
|
event_queue: vec![],
|
||||||
|
id_to_name: HashMap::new(),
|
||||||
|
|
||||||
debuggables: Vec::new(),
|
debuggables: Vec::new(),
|
||||||
|
|
||||||
@ -34,6 +38,24 @@ impl Default for System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DeviceSettings {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub address: Option<Address>,
|
||||||
|
pub debuggable: bool,
|
||||||
|
pub queue: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DeviceSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
name: None,
|
||||||
|
address: None,
|
||||||
|
debuggable: false,
|
||||||
|
queue: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl System {
|
impl System {
|
||||||
pub fn get_bus(&self) -> RefMut<'_, Bus> {
|
pub fn get_bus(&self) -> RefMut<'_, Bus> {
|
||||||
self.bus.borrow_mut()
|
self.bus.borrow_mut()
|
||||||
@ -43,43 +65,104 @@ impl System {
|
|||||||
self.interrupt_controller.borrow_mut()
|
self.interrupt_controller.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device(&self, name: &str) -> Result<Device, Error> {
|
pub fn get_device<T: Resource>(&self, device: DeviceId) -> Result<Rc<RefCell<T>>, Error> {
|
||||||
self.devices
|
self.devices
|
||||||
.get(name)
|
.get(&device)
|
||||||
|
.and_then(|rc| downcast_rc_refc::<T>(rc))
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or_else(|| Error::new(format!("system: no device named {}", name)))
|
.ok_or_else(|| Error::new(format!("system: bad device id {}", device)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_device(&mut self, name: &str, device: Device) -> Result<(), Error> {
|
pub fn get_device_by_name<T: Resource>(&self, name: &str) -> Result<Rc<RefCell<T>>, Error> {
|
||||||
self.try_add_debuggable(device.clone());
|
let id = self.id_to_name.iter().find_map(|(key, &ref val)| if val == name { Some(key)} else { None });
|
||||||
self.try_queue_device(device.clone());
|
if let Some(id) = id {
|
||||||
self.devices.insert(name.to_string(), device);
|
self.get_device(*id)
|
||||||
Ok(())
|
} else {
|
||||||
|
Err(Error::new(format!("system: could not find device {}", name)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_addressable_device(&mut self, addr: Address, device: Device) -> Result<(), Error> {
|
pub fn get_dyn_device(&self, device: DeviceId) -> Result<Device, Error> {
|
||||||
self.add_peripheral(&format!("mem{:x}", addr), addr, device)
|
self.devices
|
||||||
|
.get(&device)
|
||||||
|
.cloned()
|
||||||
|
.ok_or_else(|| Error::new(format!("system: bad device id {}", device)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_peripheral(&mut self, name: &str, addr: Address, device: Device) -> Result<(), Error> {
|
pub fn get_dyn_device_by_name(&self, name: &str) -> Result<Device, Error> {
|
||||||
self.bus.borrow_mut().insert(addr, device.clone());
|
let id = self.id_to_name.iter().find_map(|(key, &ref val)| if val == name { Some(key)} else { None });
|
||||||
self.try_add_debuggable(device.clone());
|
if let Some(id) = id {
|
||||||
self.try_queue_device(device.clone());
|
self.get_dyn_device(*id)
|
||||||
self.devices.insert(name.to_string(), device);
|
} else {
|
||||||
Ok(())
|
Err(Error::new(format!("system: could not find device {}", name)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_interruptable_device(&mut self, name: &str, device: Device) -> Result<(), Error> {
|
pub fn add_device<T: Resource>(&mut self, device: T, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
||||||
self.try_add_debuggable(device.clone());
|
self.add_device_rc_ref(Rc::new(RefCell::new(device)), settings)
|
||||||
self.try_queue_device(device.clone());
|
}
|
||||||
self.devices.insert(name.to_string(), device);
|
|
||||||
Ok(())
|
pub fn add_device_rc_ref<T: Resource>(&mut self, device: Rc<RefCell<T>>, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
||||||
|
let device = device as Device;
|
||||||
|
self.add_device_rc_dyn(device, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_device_rc_dyn(&mut self, device: Device, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
||||||
|
let id = get_next_id();
|
||||||
|
self.id_to_name.insert(id, settings.name.unwrap_or_default());
|
||||||
|
|
||||||
|
self.devices.insert(id, device.clone());
|
||||||
|
|
||||||
|
if settings.debuggable && device.borrow_mut().as_debuggable().is_some() {
|
||||||
|
self.debuggables.push(id);
|
||||||
|
}
|
||||||
|
if settings.queue && device.borrow_mut().as_steppable().is_some() {
|
||||||
|
self.queue_device(NextStep::new(id));
|
||||||
|
}
|
||||||
|
if let Some(addr) = settings.address {
|
||||||
|
self.bus.borrow_mut().insert(addr, device.clone());
|
||||||
|
}
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_named_device<T: Resource>(&mut self, name: &str, device: T) -> Result<DeviceId, Error> {
|
||||||
|
self.add_device(device, DeviceSettings {
|
||||||
|
name: Some(name.to_owned()),
|
||||||
|
queue: true,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_addressable_device<T: Resource>(&mut self, addr: Address, device: T) -> Result<DeviceId, Error> {
|
||||||
|
self.add_device(device, DeviceSettings {
|
||||||
|
name: Some(format!("mem{:x}", addr)),
|
||||||
|
address: Some(addr),
|
||||||
|
queue: true,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_peripheral<T: Resource>(&mut self, name: &str, addr: Address, device: T) -> Result<DeviceId, Error> {
|
||||||
|
self.add_device(device, DeviceSettings {
|
||||||
|
name: Some(name.to_owned()),
|
||||||
|
address: Some(addr),
|
||||||
|
queue: true,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_interruptable_device<T: Resource>(&mut self, name: &str, device: T) -> Result<DeviceId, Error> {
|
||||||
|
self.add_device(device, DeviceSettings {
|
||||||
|
name: Some(name.to_owned()),
|
||||||
|
queue: true,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_one_event(&mut self) -> Result<(), Error> {
|
fn process_one_event(&mut self) -> Result<(), Error> {
|
||||||
let mut event_device = self.event_queue.pop().unwrap();
|
let mut event_device = self.event_queue.pop().unwrap();
|
||||||
self.clock = event_device.next_clock;
|
self.clock = event_device.next_clock;
|
||||||
let result = match event_device.device.borrow_mut().as_steppable().unwrap().step(self) {
|
let result = match self.get_dyn_device(event_device.device).unwrap().borrow_mut().as_steppable().unwrap().step(self) {
|
||||||
Ok(diff) => {
|
Ok(diff) => {
|
||||||
event_device.next_clock = self.clock.checked_add(diff).unwrap();
|
event_device.next_clock = self.clock.checked_add(diff).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -107,11 +190,11 @@ impl System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Step through the simulation until the next event is for the given device
|
/// Step through the simulation until the next event is for the given device
|
||||||
pub fn step_until_device(&mut self, device: Device) -> Result<(), Error> {
|
pub fn step_until_device(&mut self, device: DeviceId) -> Result<(), Error> {
|
||||||
loop {
|
loop {
|
||||||
self.step()?;
|
self.step()?;
|
||||||
|
|
||||||
if self.get_next_event_device().id() == device.id() {
|
if self.get_next_event_device() == device {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,7 +206,7 @@ impl System {
|
|||||||
loop {
|
loop {
|
||||||
self.step()?;
|
self.step()?;
|
||||||
|
|
||||||
if self.get_next_event_device().borrow_mut().as_debuggable().is_some() {
|
if self.get_dyn_device(self.get_next_event_device()).unwrap().borrow_mut().as_debuggable().is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,31 +244,19 @@ impl System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_next_event_device(&self) -> Device {
|
pub fn get_next_event_device(&self) -> DeviceId {
|
||||||
self.event_queue[self.event_queue.len() - 1].device.clone()
|
self.event_queue[self.event_queue.len() - 1].device
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_next_debuggable_device(&self) -> Option<Device> {
|
pub fn get_next_debuggable_device(&self) -> Option<DeviceId> {
|
||||||
for event in self.event_queue.iter().rev() {
|
for event in self.event_queue.iter().rev() {
|
||||||
if event.device.borrow_mut().as_debuggable().is_some() {
|
if self.get_dyn_device(event.device).unwrap().borrow_mut().as_debuggable().is_some() {
|
||||||
return Some(event.device.clone());
|
return Some(event.device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_add_debuggable(&mut self, device: Device) {
|
|
||||||
if device.borrow_mut().as_debuggable().is_some() {
|
|
||||||
self.debuggables.push(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_queue_device(&mut self, device: Device) {
|
|
||||||
if device.borrow_mut().as_steppable().is_some() {
|
|
||||||
self.queue_device(NextStep::new(device));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn queue_device(&mut self, device_step: NextStep) {
|
fn queue_device(&mut self, device_step: NextStep) {
|
||||||
for (i, event) in self.event_queue.iter().enumerate().rev() {
|
for (i, event) in self.event_queue.iter().enumerate().rev() {
|
||||||
if event.next_clock > device_step.next_clock {
|
if event.next_clock > device_step.next_clock {
|
||||||
@ -200,11 +271,11 @@ impl System {
|
|||||||
|
|
||||||
pub struct NextStep {
|
pub struct NextStep {
|
||||||
pub next_clock: Instant,
|
pub next_clock: Instant,
|
||||||
pub device: Device,
|
pub device: DeviceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NextStep {
|
impl NextStep {
|
||||||
pub fn new(device: Device) -> Self {
|
pub fn new(device: DeviceId) -> Self {
|
||||||
Self {
|
Self {
|
||||||
next_clock: Instant::START,
|
next_clock: Instant::START,
|
||||||
device,
|
device,
|
||||||
|
@ -27,7 +27,7 @@ impl Debugger {
|
|||||||
pub fn print_step(&mut self, system: &mut System) -> Result<(), Error> {
|
pub fn print_step(&mut self, system: &mut System) -> Result<(), Error> {
|
||||||
println!("@ {} ns", system.clock.as_duration().as_nanos());
|
println!("@ {} ns", system.clock.as_duration().as_nanos());
|
||||||
if let Some(device) = system.get_next_debuggable_device() {
|
if let Some(device) = system.get_next_debuggable_device() {
|
||||||
device.borrow_mut().as_debuggable().unwrap().print_current_step(system)?;
|
system.get_dyn_device(device).unwrap().borrow_mut().as_debuggable().unwrap().print_current_step(system)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -65,13 +65,13 @@ impl Debugger {
|
|||||||
let (name, addr) = parse_address(args[1])?;
|
let (name, addr) = parse_address(args[1])?;
|
||||||
match name {
|
match name {
|
||||||
Some(name) => {
|
Some(name) => {
|
||||||
let target = system.get_device(name)?;
|
let target = system.get_dyn_device_by_name(name)?;
|
||||||
target.borrow_mut().as_debuggable().unwrap().add_breakpoint(addr);
|
target.borrow_mut().as_debuggable().unwrap().add_breakpoint(addr);
|
||||||
println!("Breakpoint set for devices {:?} at {:08x}", name, addr);
|
println!("Breakpoint set for devices {:?} at {:08x}", name, addr);
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
if let Some(device) = system.get_next_debuggable_device() {
|
if let Some(device) = system.get_next_debuggable_device() {
|
||||||
device.borrow_mut().as_debuggable().unwrap().add_breakpoint(addr);
|
system.get_dyn_device(device).unwrap().borrow_mut().as_debuggable().unwrap().add_breakpoint(addr);
|
||||||
println!("Breakpoint set for {:08x}", addr);
|
println!("Breakpoint set for {:08x}", addr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -85,13 +85,13 @@ impl Debugger {
|
|||||||
let (name, addr) = parse_address(args[1])?;
|
let (name, addr) = parse_address(args[1])?;
|
||||||
match name {
|
match name {
|
||||||
Some(name) => {
|
Some(name) => {
|
||||||
let target = system.get_device(name)?;
|
let target = system.get_dyn_device_by_name(name)?;
|
||||||
target.borrow_mut().as_debuggable().unwrap().remove_breakpoint(addr);
|
target.borrow_mut().as_debuggable().unwrap().remove_breakpoint(addr);
|
||||||
println!("Breakpoint removed for devices {:?} at {:08x}", name, addr);
|
println!("Breakpoint removed for devices {:?} at {:08x}", name, addr);
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
if let Some(device) = system.get_next_debuggable_device() {
|
if let Some(device) = system.get_next_debuggable_device() {
|
||||||
device.borrow_mut().as_debuggable().unwrap().remove_breakpoint(addr);
|
system.get_dyn_device(device).unwrap().borrow_mut().as_debuggable().unwrap().remove_breakpoint(addr);
|
||||||
println!("Breakpoint removed for {:08x}", addr);
|
println!("Breakpoint removed for {:08x}", addr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -132,13 +132,13 @@ impl Debugger {
|
|||||||
if args.len() < 2 {
|
if args.len() < 2 {
|
||||||
println!("Usage: inspect <device_name> [<device specific arguments>]");
|
println!("Usage: inspect <device_name> [<device specific arguments>]");
|
||||||
} else {
|
} else {
|
||||||
let device = system.get_device(args[1])?;
|
// let device = system.get_dyn_device(args[1])?;
|
||||||
let subargs = if args.len() > 2 { &args[2..] } else { &[""] };
|
// let subargs = if args.len() > 2 { &args[2..] } else { &[""] };
|
||||||
device
|
// device
|
||||||
.borrow_mut()
|
// .borrow_mut()
|
||||||
.as_inspectable()
|
// .as_inspectable()
|
||||||
.ok_or_else(|| Error::new("That device is not inspectable"))?
|
// .ok_or_else(|| Error::new("That device is not inspectable"))?
|
||||||
.inspect(system, subargs)?;
|
// .inspect(system, subargs)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dis" | "disassemble" => {
|
"dis" | "disassemble" => {
|
||||||
@ -155,7 +155,7 @@ impl Debugger {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(device) = system.get_next_debuggable_device() {
|
if let Some(device) = system.get_next_debuggable_device() {
|
||||||
device
|
system.get_dyn_device(device).unwrap()
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.as_debuggable()
|
.as_debuggable()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -202,7 +202,7 @@ impl Debugger {
|
|||||||
//},
|
//},
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(device) = system.get_next_debuggable_device() {
|
if let Some(device) = system.get_next_debuggable_device() {
|
||||||
if device.borrow_mut().as_debuggable().unwrap().run_command(system, &args)? {
|
if system.get_dyn_device(device).unwrap().borrow_mut().as_debuggable().unwrap().run_command(system, &args)? {
|
||||||
println!("Error: unknown command {}", args[0]);
|
println!("Error: unknown command {}", args[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user