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:
pjht 2023-03-23 09:02:57 -05:00
parent 3a4d2b0c9d
commit 8f91a1aa3e
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
3 changed files with 70 additions and 86 deletions

View File

@ -148,51 +148,43 @@ impl Backplane {
}
pub fn read_word(&self, address: u32) -> Result<u16, BusError> {
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<u8, BusError> {
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<u16, BusError> {
@ -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<u8, BusError> {
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<T, BusError>
where
M: 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 {
(0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self
.cards

View File

@ -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<u16, BusError>;
fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result<u8, BusError>;
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<u32, BusError>;
}
#[allow(dead_code)]
pub const fn u64_set_be_byte(val: u64, idx: u8, byte: u8) -> u64 {
let mut bytes = val.to_be_bytes();

View File

@ -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<u32, BusError> {
) -> NullableResult<u32, BusError> {
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<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");