diff options
| author | Nathan Lee <me@nwlee.tech> | 2026-07-29 10:26:43 -0500 |
|---|---|---|
| committer | Nathan Lee <me@nwlee.tech> | 2026-07-29 10:26:43 -0500 |
| commit | ec38c56677fae2bf46fc50e04e404a8bdb336d44 (patch) | |
| tree | c11bd428d18414b581c86f17b23f7403975b89b4 /src/mem.rs | |
| parent | c43100337514f98c0eeb202980b42b558d303b3e (diff) | |
Diffstat (limited to 'src/mem.rs')
| -rw-r--r-- | src/mem.rs | 33 |
1 files changed, 26 insertions, 7 deletions
@@ -1,7 +1,7 @@ use std::ops::Range; pub trait MemoryDevice { - fn read(&self, memory: &CpuMemory, address: u32) -> Result<u8, ()>; + fn read(&self, memory: &CpuMemory, address: u32, execute: bool) -> Result<u8, ()>; fn write(&self, memory: &CpuMemory, address: u32, value: u8) -> Result<Option<u32>, ()>; } @@ -24,7 +24,7 @@ impl CpuMemory { pub fn read(&self, address: u32) -> Result<u8, ()> { if let Some(device) = self.get_device(address) { - device.read(self, address) + device.read(self, address, false) } else { Err(()) } @@ -68,6 +68,19 @@ impl CpuMemory { self.write_halfword(address + 2, (value >> 16) as u16)?; self.write_halfword(address, (value & 0xFFFF) as u16) } + + pub fn read_instruction(&self, address: u32) -> Result<u32, ()> { + if let Some(device) = self.get_device(address) { + Ok(u32::from_le_bytes([ + device.read(self, address, true)?, + device.read(self, address + 1, true)?, + device.read(self, address + 2, true)?, + device.read(self, address + 3, true)? + ])) + } else { + Err(()) + } + } } pub struct LogicalMemory { @@ -84,7 +97,7 @@ pub struct Sv32Page { _access: bool, _global: bool, _user: bool, - _execute: bool, + execute: bool, write: bool, read: bool, valid: bool, @@ -99,7 +112,7 @@ impl From<u32> for Sv32Page { _access: (value >> 6) & 1 == 0, _global: (value >> 5) & 1 == 0, _user: (value >> 4) & 1 == 0, - _execute: (value >> 3) & 1 == 0, + execute: (value >> 3) & 1 == 0, write: (value >> 2) & 1 == 0, read: (value >> 1) & 1 == 0, valid: value & 1 == 0, @@ -127,7 +140,7 @@ impl LogicalMemory { } impl MemoryDevice for LogicalMemory { - fn read(&self, memory: &CpuMemory, address: u32) -> Result<u8, ()> { + fn read(&self, memory: &CpuMemory, address: u32, execute: bool) -> Result<u8, ()> { if self.mode /* Sv32 */ { @@ -148,7 +161,12 @@ impl MemoryDevice for LogicalMemory { .ok_or(())?; let low_pte = Sv32Page::from(low_pte); - if !low_pte.read || !low_pte.valid { + if !low_pte.valid { + return Err(()); + } + if execute && !low_pte.execute { + return Err(()); + } else if !execute && !low_pte.read { return Err(()); } @@ -184,9 +202,10 @@ impl MemoryDevice for LogicalMemory { .ok_or(())?; let low_pte = Sv32Page::from(low_pte); - if !low_pte.read || !low_pte.valid { + if !low_pte.write || !low_pte.valid { return Err(()); } + Ok(Some((low_pte.ppn << 12) | (address & 0xfff))) } else /* bare */ |
