summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs2
-rw-r--r--src/mem.rs33
2 files changed, 27 insertions, 8 deletions
diff --git a/src/main.rs b/src/main.rs
index c276280..74515b1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -110,7 +110,7 @@ fn main() {
fn handle_instruction(state: &mut CpuState) {
let pc = state.pc;
- let word = state.memory.read_word(pc).unwrap();
+ let word = state.memory.read_instruction(pc).unwrap();
let opcode = word & 0x7f;
match opcode {
0b0110011 => {
diff --git a/src/mem.rs b/src/mem.rs
index 770659b..acf1af0 100644
--- a/src/mem.rs
+++ b/src/mem.rs
@@ -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 */