Tell MMU whether memory accesses are user or supervisor
This commit is contained in:
parent
f3cec9c9a3
commit
d05eb249bb
@ -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),
|
||||
|
@ -146,6 +146,7 @@ pub trait Mmu: Debug {
|
||||
backplane: &Backplane,
|
||||
address: u32,
|
||||
write: bool,
|
||||
supervisor: bool,
|
||||
) -> NullableResult<u32, BusError>;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
12
src/main.rs
12
src/main.rs
@ -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)
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user