Tell MMU whether memory accesses are user or supervisor

This commit is contained in:
pjht 2024-03-09 12:25:54 -06:00
parent f3cec9c9a3
commit d05eb249bb
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
6 changed files with 33 additions and 16 deletions

View File

@ -151,7 +151,7 @@ impl Backplane {
.cmd(cmd)
}
pub fn read_word(&self, address: u32) -> Result<u16, BusError> {
pub fn read_word(&self, address: u32, supervisor: bool) -> Result<u16, BusError> {
self.mem_helper(
address,
|address, mut card| card.read_word(address),
@ -159,10 +159,11 @@ impl Backplane {
|address| self.read_word_io(address as u8),
false,
false,
supervisor,
)
}
pub fn read_byte(&self, address: u32) -> Result<u8, BusError> {
pub fn read_byte(&self, address: u32, supervisor: bool) -> Result<u8, BusError> {
self.mem_helper(
address,
|address, mut card| card.read_byte(address),
@ -170,10 +171,11 @@ impl Backplane {
|address| self.read_byte_io(address as u8),
false,
false,
supervisor,
)
}
pub fn write_word(&self, address: u32, data: u16) -> Result<(), BusError> {
pub fn write_word(&self, address: u32, data: u16, supervisor: bool) -> Result<(), BusError> {
self.mem_helper(
address,
|address, mut card| card.write_word(address, data),
@ -181,10 +183,11 @@ impl Backplane {
|address| self.write_word_io(address as u8, data),
false,
true,
supervisor,
)
}
pub fn write_byte(&self, address: u32, data: u8) -> Result<(), BusError> {
pub fn write_byte(&self, address: u32, data: u8, supervisor: bool) -> Result<(), BusError> {
self.mem_helper(
address,
|address, mut card| card.write_byte(address, data),
@ -192,6 +195,7 @@ impl Backplane {
|address| self.write_byte_io(address as u8, data),
false,
true,
supervisor,
)
}
@ -203,6 +207,7 @@ impl Backplane {
|address| self.read_word_io(address as u8),
true,
false,
true,
)
}
@ -215,6 +220,7 @@ impl Backplane {
|address| self.read_byte_io(address as u8),
true,
false,
true,
)
}
@ -227,6 +233,7 @@ impl Backplane {
|address| self.write_word_io(address as u8, data),
true,
true,
true,
)
}
@ -239,6 +246,7 @@ impl Backplane {
|address| self.write_byte_io(address as u8, data),
true,
true,
true,
)
}
@ -250,6 +258,7 @@ impl Backplane {
mut backplane_io_func: B,
bypass_mmu: bool,
write: bool,
supervisor: bool,
) -> Result<T, BusError>
where
M: FnMut(u32, RefMut<'_, dyn Card>) -> NullableResult<T, BusError>,
@ -263,7 +272,7 @@ impl Backplane {
.borrow_mut()
.try_as_mmu()
.unwrap()
.translate_address(self, address, write)
.translate_address(self, address, write, supervisor)
{
NullableResult::Ok(address) => address,
NullableResult::Err(e) => return Err(e),

View File

@ -146,6 +146,7 @@ pub trait Mmu: Debug {
backplane: &Backplane,
address: u32,
write: bool,
supervisor: bool,
) -> NullableResult<u32, BusError>;
}

View File

@ -1483,7 +1483,7 @@ impl M68K {
self.store_mem_cycles = true;
}
}
let result = self.bus.read_byte(address).map_err(|_| DetailedBusError {
let result = self.bus.read_byte(address, self.is_supervisor()).map_err(|_| DetailedBusError {
address,
cause: BusErrorCause::ReadingByte,
});
@ -1518,7 +1518,7 @@ impl M68K {
}
let result = self
.bus
.write_byte(address, data)
.write_byte(address, data, self.is_supervisor())
.map_err(|_| DetailedBusError {
address,
cause: BusErrorCause::WritingByte,
@ -1553,7 +1553,7 @@ impl M68K {
self.store_mem_cycles = true;
}
}
let result = self.bus.read_word(address).map_err(|_| DetailedBusError {
let result = self.bus.read_word(address, self.is_supervisor()).map_err(|_| DetailedBusError {
address,
cause: BusErrorCause::ReadingWord,
});
@ -1592,7 +1592,7 @@ impl M68K {
}
let result = self
.bus
.write_word(address, data)
.write_word(address, data, self.is_supervisor())
.map_err(|_| DetailedBusError {
address,
cause: BusErrorCause::WritingWord,

View File

@ -294,11 +294,11 @@ fn main() -> Result<(), anyhow::Error> {
} else {
for i in 0..count {
match size {
peek::Size::Byte => data.push(u32::from(bus.read_byte(addr + i)?)),
peek::Size::Word => data.push(u32::from(bus.read_word(addr + (i * 2))?)),
peek::Size::Byte => data.push(u32::from(bus.read_byte(addr + i, true)?)),
peek::Size::Word => data.push(u32::from(bus.read_word(addr + (i * 2), true)?)),
peek::Size::LongWord => data.push(
u32::from(bus.read_word(addr + (i * 4))?) << 16
| u32::from(bus.read_word(addr + (i * 4) + 2)?),
u32::from(bus.read_word(addr + (i * 4), true)?) << 16
| u32::from(bus.read_word(addr + (i * 4) + 2, true)?),
),
}
}
@ -335,10 +335,10 @@ fn main() -> Result<(), anyhow::Error> {
return Err(anyhow!("Cannot poke a word to a non-aligned address"));
}
let data = parse::<u16>(args.get_one::<String>("data").unwrap())?;
state.cpu.bus_mut().write_word(address, data)?;
state.cpu.bus_mut().write_word(address, data, true)?;
} else {
let data = parse::<u8>(args.get_one::<String>("data").unwrap())?;
state.cpu.bus_mut().write_byte(address, data)?;
state.cpu.bus_mut().write_byte(address, data, true)?;
}
Ok(None)
}

View File

@ -161,6 +161,7 @@ impl Mmu for MmuCard {
backplane: &Backplane,
address: u32,
write: bool,
supervisor: bool,
) -> NullableResult<u32, BusError> {
let print_debug = self.print_debug;
if self.enabled {
@ -198,6 +199,12 @@ impl Mmu for MmuCard {
mapping
};
if mapping & MAPPING_FLAG_PRESENT > 0 {
if !supervisor && (mapping & MAPPING_FLAG_USER == 0) {
if print_debug {
println!("Page not user accessible");
}
return NullableResult::Err(BusError);
}
if write && (mapping & MAPPING_FLAG_WRITABLE == 0) {
if print_debug {
println!("Page not writable");

View File

@ -156,7 +156,7 @@ impl Card for Storage {
// Closure is used to drop the mutex guard
// between pop calls to prevent deadlock
while let Some(data) = (|| self.read_data.pop_front())() {
backplane.write_byte(address, data).unwrap();
backplane.write_byte(address, data, true).unwrap();
address += 1;
}
self.transfer = false;