From 8f91a1aa3ec86f9d939662add57433d9c95f13e4 Mon Sep 17 00:00:00 2001 From: pjht Date: Thu, 23 Mar 2023 09:02:57 -0500 Subject: [PATCH] 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 --- src/backplane.rs | 93 +++++++++++++++++++++++++++++------------------- src/card.rs | 15 +++----- src/mmu.rs | 48 +++++-------------------- 3 files changed, 70 insertions(+), 86 deletions(-) diff --git a/src/backplane.rs b/src/backplane.rs index 1137c37..5f1baac 100644 --- a/src/backplane.rs +++ b/src/backplane.rs @@ -148,51 +148,43 @@ impl Backplane { } pub fn read_word(&self, address: u32) -> Result { - if let Some(mmu) = self.mmu { - self.cards[mmu] - .borrow_mut() - .try_as_mmu() - .unwrap() - .read_word(address, self) - } else { - self.read_word_phys(address) - } + self.mem_helper( + address, + |mut card| card.read_word(address), + |mut card| card.read_word_io(address as u8), + false, + false, + ) } pub fn read_byte(&self, address: u32) -> Result { - if let Some(mmu) = self.mmu { - self.cards[mmu] - .borrow_mut() - .try_as_mmu() - .unwrap() - .read_byte(address, self) - } else { - self.read_byte_phys(address) - } + self.mem_helper( + address, + |mut card| card.read_byte(address), + |mut card| card.read_byte_io(address as u8), + false, + false, + ) } pub fn write_word(&self, address: u32, data: u16) -> Result<(), BusError> { - if let Some(mmu) = self.mmu { - self.cards[mmu] - .borrow_mut() - .try_as_mmu() - .unwrap() - .write_word(address, data, self) - } else { - self.write_word_phys(address, data) - } + self.mem_helper( + address, + |mut card| card.write_word(address, data), + |mut card| card.write_word_io(address as u8, data), + false, + true, + ) } pub fn write_byte(&self, address: u32, data: u8) -> Result<(), BusError> { - if let Some(mmu) = self.mmu { - self.cards[mmu] - .borrow_mut() - .try_as_mmu() - .unwrap() - .write_byte(address, data, self) - } else { - self.write_byte_phys(address, data) - } + self.mem_helper( + address, + |mut card| card.write_byte(address, data), + |mut card| card.write_byte_io(address as u8, data), + false, + true, + ) } pub fn read_word_phys(&self, address: u32) -> Result { @@ -200,30 +192,41 @@ impl Backplane { address, |mut card| card.read_word(address), |mut card| card.read_word_io(address as u8), + true, + false, ) } + #[allow(dead_code)] pub fn read_byte_phys(&self, address: u32) -> Result { self.mem_helper( address, |mut card| card.read_byte(address), |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> { self.mem_helper( address, |mut card| card.write_word(address, 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> { self.mem_helper( address, |mut card| card.write_byte(address, data), |mut card| card.write_byte_io(address as u8, data), + true, + true, ) } @@ -232,11 +235,29 @@ impl Backplane { address: u32, mut mem_func: M, mut io_func: I, + bypass_mmu: bool, + write: bool, ) -> Result where M: FnMut(RefMut<'_, dyn Card>) -> NullableResult, I: FnMut(RefMut<'_, dyn Card>) -> NullableResult, { + 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 { (0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self .cards diff --git a/src/card.rs b/src/card.rs index cc25027..d58b100 100644 --- a/src/card.rs +++ b/src/card.rs @@ -141,20 +141,15 @@ pub trait Card: Debug + Display + mopa::Any { mopafy!(Card); pub trait Mmu: Debug { - fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result; - fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result; - - fn write_word( + fn translate_address( &mut self, - address: u32, - data: u16, backplane: &Backplane, - ) -> Result<(), BusError>; - - fn write_byte(&mut self, address: u32, data: u8, backplane: &Backplane) - -> Result<(), BusError>; + address: u32, + write: bool, + ) -> NullableResult; } + #[allow(dead_code)] pub const fn u64_set_be_byte(val: u64, idx: u8, byte: u8) -> u64 { let mut bytes = val.to_be_bytes(); diff --git a/src/mmu.rs b/src/mmu.rs index efb7227..1cb4e30 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -173,13 +173,13 @@ impl Display for MmuCard { } } -impl MmuCard { +impl Mmu for MmuCard { fn translate_address( &mut self, - address: u32, backplane: &Backplane, + address: u32, write: bool, - ) -> Result { + ) -> NullableResult { let print_debug = self.print_debug; if self.enabled { let page = address >> 12; @@ -197,7 +197,7 @@ impl MmuCard { if print_debug { println!("No mapping frame for this quarter"); } - return Err(BusError); + return NullableResult::Null; } let map_frame = self.map_frames[(page >> 10) as usize]; let entry_address = (map_frame) | ((page & 0x3FF) << 2); @@ -218,7 +218,7 @@ impl MmuCard { if print_debug { println!("Entry not writable"); } - return Err(BusError); + return NullableResult::Err(BusError); } if print_debug { println!( @@ -226,49 +226,17 @@ impl MmuCard { (entry.frame << 12) | offset ); } - Ok((entry.frame << 12) | offset) + NullableResult::Ok((entry.frame << 12) | offset) } else { if print_debug { println!("Entry not present"); } - Err(BusError) + NullableResult::Null } } else { - Ok(address) + NullableResult::Ok(address) } } } -impl Mmu for MmuCard { - fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result { - let address = self.translate_address(address, backplane, false)?; - backplane.read_word_phys(address) - } - - fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result { - 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");