Revert "Rework MMU trait to allow for full control of MMU issued memory cycles"
This commit breaks accesses to the MMU IO space because since the MMU card is borrowed during accesses to memory, when it calls into the backplane to do the physical access, the backplane will attemp to borrow the MMU card again, causing a panic
This commit is contained in:
parent
3a4d2b0c9d
commit
8f91a1aa3e
@ -148,51 +148,43 @@ impl Backplane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word(&self, address: u32) -> Result<u16, BusError> {
|
pub fn read_word(&self, address: u32) -> Result<u16, BusError> {
|
||||||
if let Some(mmu) = self.mmu {
|
self.mem_helper(
|
||||||
self.cards[mmu]
|
address,
|
||||||
.borrow_mut()
|
|mut card| card.read_word(address),
|
||||||
.try_as_mmu()
|
|mut card| card.read_word_io(address as u8),
|
||||||
.unwrap()
|
false,
|
||||||
.read_word(address, self)
|
false,
|
||||||
} else {
|
)
|
||||||
self.read_word_phys(address)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_byte(&self, address: u32) -> Result<u8, BusError> {
|
pub fn read_byte(&self, address: u32) -> Result<u8, BusError> {
|
||||||
if let Some(mmu) = self.mmu {
|
self.mem_helper(
|
||||||
self.cards[mmu]
|
address,
|
||||||
.borrow_mut()
|
|mut card| card.read_byte(address),
|
||||||
.try_as_mmu()
|
|mut card| card.read_byte_io(address as u8),
|
||||||
.unwrap()
|
false,
|
||||||
.read_byte(address, self)
|
false,
|
||||||
} else {
|
)
|
||||||
self.read_byte_phys(address)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_word(&self, address: u32, data: u16) -> Result<(), BusError> {
|
pub fn write_word(&self, address: u32, data: u16) -> Result<(), BusError> {
|
||||||
if let Some(mmu) = self.mmu {
|
self.mem_helper(
|
||||||
self.cards[mmu]
|
address,
|
||||||
.borrow_mut()
|
|mut card| card.write_word(address, data),
|
||||||
.try_as_mmu()
|
|mut card| card.write_word_io(address as u8, data),
|
||||||
.unwrap()
|
false,
|
||||||
.write_word(address, data, self)
|
true,
|
||||||
} else {
|
)
|
||||||
self.write_word_phys(address, data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&self, address: u32, data: u8) -> Result<(), BusError> {
|
pub fn write_byte(&self, address: u32, data: u8) -> Result<(), BusError> {
|
||||||
if let Some(mmu) = self.mmu {
|
self.mem_helper(
|
||||||
self.cards[mmu]
|
address,
|
||||||
.borrow_mut()
|
|mut card| card.write_byte(address, data),
|
||||||
.try_as_mmu()
|
|mut card| card.write_byte_io(address as u8, data),
|
||||||
.unwrap()
|
false,
|
||||||
.write_byte(address, data, self)
|
true,
|
||||||
} else {
|
)
|
||||||
self.write_byte_phys(address, data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word_phys(&self, address: u32) -> Result<u16, BusError> {
|
pub fn read_word_phys(&self, address: u32) -> Result<u16, BusError> {
|
||||||
@ -200,30 +192,41 @@ impl Backplane {
|
|||||||
address,
|
address,
|
||||||
|mut card| card.read_word(address),
|
|mut card| card.read_word(address),
|
||||||
|mut card| card.read_word_io(address as u8),
|
|mut card| card.read_word_io(address as u8),
|
||||||
|
true,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn read_byte_phys(&self, address: u32) -> Result<u8, BusError> {
|
pub fn read_byte_phys(&self, address: u32) -> Result<u8, BusError> {
|
||||||
self.mem_helper(
|
self.mem_helper(
|
||||||
address,
|
address,
|
||||||
|mut card| card.read_byte(address),
|
|mut card| card.read_byte(address),
|
||||||
|mut card| card.read_byte_io(address as u8),
|
|mut card| card.read_byte_io(address as u8),
|
||||||
|
true,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn write_word_phys(&self, address: u32, data: u16) -> Result<(), BusError> {
|
pub fn write_word_phys(&self, address: u32, data: u16) -> Result<(), BusError> {
|
||||||
self.mem_helper(
|
self.mem_helper(
|
||||||
address,
|
address,
|
||||||
|mut card| card.write_word(address, data),
|
|mut card| card.write_word(address, data),
|
||||||
|mut card| card.write_word_io(address as u8, data),
|
|mut card| card.write_word_io(address as u8, data),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn write_byte_phys(&self, address: u32, data: u8) -> Result<(), BusError> {
|
pub fn write_byte_phys(&self, address: u32, data: u8) -> Result<(), BusError> {
|
||||||
self.mem_helper(
|
self.mem_helper(
|
||||||
address,
|
address,
|
||||||
|mut card| card.write_byte(address, data),
|
|mut card| card.write_byte(address, data),
|
||||||
|mut card| card.write_byte_io(address as u8, data),
|
|mut card| card.write_byte_io(address as u8, data),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,11 +235,29 @@ impl Backplane {
|
|||||||
address: u32,
|
address: u32,
|
||||||
mut mem_func: M,
|
mut mem_func: M,
|
||||||
mut io_func: I,
|
mut io_func: I,
|
||||||
|
bypass_mmu: bool,
|
||||||
|
write: bool,
|
||||||
) -> Result<T, BusError>
|
) -> Result<T, BusError>
|
||||||
where
|
where
|
||||||
M: FnMut(RefMut<'_, dyn Card>) -> NullableResult<T, BusError>,
|
M: FnMut(RefMut<'_, dyn Card>) -> NullableResult<T, BusError>,
|
||||||
I: FnMut(RefMut<'_, dyn Card>) -> NullableResult<T, BusError>,
|
I: FnMut(RefMut<'_, dyn Card>) -> NullableResult<T, BusError>,
|
||||||
{
|
{
|
||||||
|
let address = if bypass_mmu {
|
||||||
|
address
|
||||||
|
} else if let Some(card_no) = self.mmu {
|
||||||
|
match self.cards[card_no]
|
||||||
|
.borrow_mut()
|
||||||
|
.try_as_mmu()
|
||||||
|
.unwrap()
|
||||||
|
.translate_address(self, address, write)
|
||||||
|
{
|
||||||
|
NullableResult::Ok(address) => address,
|
||||||
|
NullableResult::Err(e) => return Err(e),
|
||||||
|
NullableResult::Null => return Err(BusError),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
address
|
||||||
|
};
|
||||||
let res = match address {
|
let res = match address {
|
||||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self
|
(0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self
|
||||||
.cards
|
.cards
|
||||||
|
15
src/card.rs
15
src/card.rs
@ -141,20 +141,15 @@ pub trait Card: Debug + Display + mopa::Any {
|
|||||||
mopafy!(Card);
|
mopafy!(Card);
|
||||||
|
|
||||||
pub trait Mmu: Debug {
|
pub trait Mmu: Debug {
|
||||||
fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result<u16, BusError>;
|
fn translate_address(
|
||||||
fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result<u8, BusError>;
|
|
||||||
|
|
||||||
fn write_word(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
address: u32,
|
|
||||||
data: u16,
|
|
||||||
backplane: &Backplane,
|
backplane: &Backplane,
|
||||||
) -> Result<(), BusError>;
|
address: u32,
|
||||||
|
write: bool,
|
||||||
fn write_byte(&mut self, address: u32, data: u8, backplane: &Backplane)
|
) -> NullableResult<u32, BusError>;
|
||||||
-> Result<(), BusError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const fn u64_set_be_byte(val: u64, idx: u8, byte: u8) -> u64 {
|
pub const fn u64_set_be_byte(val: u64, idx: u8, byte: u8) -> u64 {
|
||||||
let mut bytes = val.to_be_bytes();
|
let mut bytes = val.to_be_bytes();
|
||||||
|
48
src/mmu.rs
48
src/mmu.rs
@ -173,13 +173,13 @@ impl Display for MmuCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MmuCard {
|
impl Mmu for MmuCard {
|
||||||
fn translate_address(
|
fn translate_address(
|
||||||
&mut self,
|
&mut self,
|
||||||
address: u32,
|
|
||||||
backplane: &Backplane,
|
backplane: &Backplane,
|
||||||
|
address: u32,
|
||||||
write: bool,
|
write: bool,
|
||||||
) -> Result<u32, BusError> {
|
) -> NullableResult<u32, BusError> {
|
||||||
let print_debug = self.print_debug;
|
let print_debug = self.print_debug;
|
||||||
if self.enabled {
|
if self.enabled {
|
||||||
let page = address >> 12;
|
let page = address >> 12;
|
||||||
@ -197,7 +197,7 @@ impl MmuCard {
|
|||||||
if print_debug {
|
if print_debug {
|
||||||
println!("No mapping frame for this quarter");
|
println!("No mapping frame for this quarter");
|
||||||
}
|
}
|
||||||
return Err(BusError);
|
return NullableResult::Null;
|
||||||
}
|
}
|
||||||
let map_frame = self.map_frames[(page >> 10) as usize];
|
let map_frame = self.map_frames[(page >> 10) as usize];
|
||||||
let entry_address = (map_frame) | ((page & 0x3FF) << 2);
|
let entry_address = (map_frame) | ((page & 0x3FF) << 2);
|
||||||
@ -218,7 +218,7 @@ impl MmuCard {
|
|||||||
if print_debug {
|
if print_debug {
|
||||||
println!("Entry not writable");
|
println!("Entry not writable");
|
||||||
}
|
}
|
||||||
return Err(BusError);
|
return NullableResult::Err(BusError);
|
||||||
}
|
}
|
||||||
if print_debug {
|
if print_debug {
|
||||||
println!(
|
println!(
|
||||||
@ -226,49 +226,17 @@ impl MmuCard {
|
|||||||
(entry.frame << 12) | offset
|
(entry.frame << 12) | offset
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok((entry.frame << 12) | offset)
|
NullableResult::Ok((entry.frame << 12) | offset)
|
||||||
} else {
|
} else {
|
||||||
if print_debug {
|
if print_debug {
|
||||||
println!("Entry not present");
|
println!("Entry not present");
|
||||||
}
|
}
|
||||||
Err(BusError)
|
NullableResult::Null
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(address)
|
NullableResult::Ok(address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mmu for MmuCard {
|
|
||||||
fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result<u16, BusError> {
|
|
||||||
let address = self.translate_address(address, backplane, false)?;
|
|
||||||
backplane.read_word_phys(address)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result<u8, BusError> {
|
|
||||||
let address = self.translate_address(address, backplane, false)?;
|
|
||||||
backplane.read_byte_phys(address)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_word(
|
|
||||||
&mut self,
|
|
||||||
address: u32,
|
|
||||||
data: u16,
|
|
||||||
backplane: &Backplane,
|
|
||||||
) -> Result<(), BusError> {
|
|
||||||
let address = self.translate_address(address, backplane, true)?;
|
|
||||||
backplane.write_word_phys(address, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_byte(
|
|
||||||
&mut self,
|
|
||||||
address: u32,
|
|
||||||
data: u8,
|
|
||||||
backplane: &Backplane,
|
|
||||||
) -> Result<(), BusError> {
|
|
||||||
let address = self.translate_address(address, backplane, true)?;
|
|
||||||
backplane.write_byte_phys(address, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register!(MmuCard, "mmu");
|
register!(MmuCard, "mmu");
|
||||||
|
Loading…
Reference in New Issue
Block a user