From 21a8479ce99f54012150cc948ed7e5bb066c61e0 Mon Sep 17 00:00:00 2001 From: taitep Date: Wed, 31 Dec 2025 13:16:32 +0100 Subject: [PATCH] Make MMIO devices not have control of the address of exceptions --- src/basic_uart.rs | 16 +++----- src/core.rs | 2 +- src/exceptions.rs | 12 ++++-- src/instructions/rvi/mem.rs | 22 +++++----- src/main.rs | 10 ++--- src/mem.rs | 80 +++++++++++++++---------------------- 6 files changed, 63 insertions(+), 79 deletions(-) diff --git a/src/basic_uart.rs b/src/basic_uart.rs index 8317950..0e209ba 100644 --- a/src/basic_uart.rs +++ b/src/basic_uart.rs @@ -13,7 +13,7 @@ use std::time::Duration; use nix::fcntl::fcntl; use nix::fcntl::{FcntlArg, OFlag}; -use trve::exceptions::{MemoryException, MemoryExceptionType}; +use trve::exceptions::MemoryExceptionType; use trve::mem::MemDeviceInterface; /// byte 0: rx/tx @@ -77,26 +77,20 @@ impl BasicUart { } impl MemDeviceInterface for BasicUart { - fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { + fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryExceptionType> { match addr { 0 => { self.write(value); Ok(()) } - _ => Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }), + _ => Err(MemoryExceptionType::AccessFault), } } - fn read_byte(&self, addr: u64) -> Result { + fn read_byte(&self, addr: u64) -> Result { match addr { 0 => Ok(self.read()), 1 => Ok(1 | (self.can_read() as u8) << 1), - _ => Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }), + _ => Err(MemoryExceptionType::AccessFault), } } } diff --git a/src/core.rs b/src/core.rs index e646b46..30d879a 100644 --- a/src/core.rs +++ b/src/core.rs @@ -58,7 +58,7 @@ impl Core { let instr = match self.mem.read_word(self.pc) { Ok(i) => i, Err(e) => { - return Err(e.to_exception_instr()); + return Err(e.into_exception_instr()); } }; diff --git a/src/exceptions.rs b/src/exceptions.rs index cc18839..0b92a97 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -51,6 +51,12 @@ pub enum MemoryExceptionType { PageFault, } +impl MemoryExceptionType { + pub(crate) fn with_addr(self, addr: u64) -> MemoryException { + MemoryException { type_: self, addr } + } +} + #[derive(Debug, Clone, Copy)] pub struct MemoryException { pub type_: MemoryExceptionType, @@ -58,7 +64,7 @@ pub struct MemoryException { } impl MemoryException { - pub(crate) fn to_exception_store(&self) -> Exception { + pub(crate) fn into_exception_store(self) -> Exception { Exception { type_: match self.type_ { MemoryExceptionType::AddressMisaligned => ExceptionType::StoreAmoAddressMisaligned, @@ -69,7 +75,7 @@ impl MemoryException { } } - pub(crate) fn to_exception_instr(&self) -> Exception { + pub(crate) fn into_exception_instr(self) -> Exception { Exception { type_: match self.type_ { MemoryExceptionType::AddressMisaligned => ExceptionType::InstructionAccessFault, @@ -80,7 +86,7 @@ impl MemoryException { } } - pub(crate) fn to_exception_load(&self) -> Exception { + pub(crate) fn into_exception_load(self) -> Exception { Exception { type_: match self.type_ { MemoryExceptionType::AddressMisaligned => ExceptionType::LoadAddressMisaligned, diff --git a/src/instructions/rvi/mem.rs b/src/instructions/rvi/mem.rs index caa18e1..ad08a39 100644 --- a/src/instructions/rvi/mem.rs +++ b/src/instructions/rvi/mem.rs @@ -11,7 +11,7 @@ pub fn sd(core: &mut Core, instr: Instruction) -> Result<(), Exception> { let value = core.reg_read(instr.rs2()); core.mem .write_dword(addr, value) - .map_err(|e| e.to_exception_store())?; + .map_err(|e| e.into_exception_store())?; core.advance_pc(); Ok(()) } @@ -22,7 +22,7 @@ pub fn ld(core: &mut Core, instr: Instruction) -> Result<(), Exception> { instr.rd(), core.mem .read_dword(addr) - .map_err(|e| e.to_exception_load())?, + .map_err(|e| e.into_exception_load())?, ); core.advance_pc(); Ok(()) @@ -33,7 +33,7 @@ pub fn sw(core: &mut Core, instr: Instruction) -> Result<(), Exception> { let value = core.reg_read(instr.rs2()) as u32; core.mem .write_word(addr, value) - .map_err(|e| e.to_exception_store())?; + .map_err(|e| e.into_exception_store())?; core.advance_pc(); Ok(()) } @@ -44,7 +44,7 @@ pub fn lw(core: &mut Core, instr: Instruction) -> Result<(), Exception> { instr.rd(), core.mem .read_word(addr) - .map_err(|e| e.to_exception_load())? as i32 as i64 as u64, + .map_err(|e| e.into_exception_load())? as i32 as i64 as u64, ); core.advance_pc(); Ok(()) @@ -56,7 +56,7 @@ pub fn lwu(core: &mut Core, instr: Instruction) -> Result<(), Exception> { instr.rd(), core.mem .read_word(addr) - .map_err(|e| e.to_exception_load())? as u64, + .map_err(|e| e.into_exception_load())? as u64, ); core.advance_pc(); Ok(()) @@ -67,7 +67,7 @@ pub fn sh(core: &mut Core, instr: Instruction) -> Result<(), Exception> { let value = core.reg_read(instr.rs2()) as u16; core.mem .write_hword(addr, value) - .map_err(|e| e.to_exception_store())?; + .map_err(|e| e.into_exception_store())?; core.advance_pc(); Ok(()) } @@ -78,7 +78,7 @@ pub fn lh(core: &mut Core, instr: Instruction) -> Result<(), Exception> { instr.rd(), core.mem .read_hword(addr) - .map_err(|e| e.to_exception_load())? as i16 as i64 as u64, + .map_err(|e| e.into_exception_load())? as i16 as i64 as u64, ); core.advance_pc(); Ok(()) @@ -90,7 +90,7 @@ pub fn lhu(core: &mut Core, instr: Instruction) -> Result<(), Exception> { instr.rd(), core.mem .read_hword(addr) - .map_err(|e| e.to_exception_load())? as u64, + .map_err(|e| e.into_exception_load())? as u64, ); core.advance_pc(); Ok(()) @@ -101,7 +101,7 @@ pub fn sb(core: &mut Core, instr: Instruction) -> Result<(), Exception> { let value = core.reg_read(instr.rs2()) as u8; core.mem .write_byte(addr, value) - .map_err(|e| e.to_exception_store())?; + .map_err(|e| e.into_exception_store())?; core.advance_pc(); Ok(()) } @@ -112,7 +112,7 @@ pub fn lb(core: &mut Core, instr: Instruction) -> Result<(), Exception> { instr.rd(), core.mem .read_byte(addr) - .map_err(|e| e.to_exception_load())? as i8 as i64 as u64, + .map_err(|e| e.into_exception_load())? as i8 as i64 as u64, ); core.advance_pc(); Ok(()) @@ -124,7 +124,7 @@ pub fn lbu(core: &mut Core, instr: Instruction) -> Result<(), Exception> { instr.rd(), core.mem .read_byte(addr) - .map_err(|e| e.to_exception_load())? as u64, + .map_err(|e| e.into_exception_load())? as u64, ); core.advance_pc(); Ok(()) diff --git a/src/main.rs b/src/main.rs index 11330bd..4e02745 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use clap::Parser; use trve::{ core::Core, - exceptions::MemoryException, + exceptions::MemoryExceptionType, gdb, mem::{MemConfig, MemDeviceInterface, MmioRoot, Ram}, }; @@ -69,22 +69,22 @@ mod basic_uart; struct DbgOut; impl MemDeviceInterface for DbgOut { - fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryException> { + fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryExceptionType> { eprintln!("Wrote DWord {value:016x} to Debug-Out address {addr:x}"); Ok(()) } - fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryException> { + fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryExceptionType> { eprintln!("Wrote Word {value:08x} to Debug-Out address {addr:x}"); Ok(()) } - fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryException> { + fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryExceptionType> { eprintln!("Wrote HWord {value:04x} to Debug-Out address {addr:x}"); Ok(()) } - fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { + fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryExceptionType> { eprintln!("Wrote Byte {value:02x} to Debug-Out address {addr:x}"); Ok(()) } diff --git a/src/mem.rs b/src/mem.rs index a3b087c..607f2d4 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -49,7 +49,7 @@ impl MemConfig { addr, })?; - interface.read_dword(addr) + interface.read_dword(addr).map_err(|e| e.with_addr(addr)) } } pub fn read_word(&self, addr: u64) -> Result { @@ -67,7 +67,7 @@ impl MemConfig { addr, })?; - interface.read_word(addr) + interface.read_word(addr).map_err(|e| e.with_addr(addr)) } } pub fn read_hword(&self, addr: u64) -> Result { @@ -84,7 +84,7 @@ impl MemConfig { type_: MemoryExceptionType::AccessFault, addr, })?; - interface.read_hword(addr) + interface.read_hword(addr).map_err(|e| e.with_addr(addr)) } } pub fn read_byte(&self, addr: u64) -> Result { @@ -95,7 +95,7 @@ impl MemConfig { type_: MemoryExceptionType::AccessFault, addr, })?; - interface.read_byte(addr) + interface.read_byte(addr).map_err(|e| e.with_addr(addr)) } } @@ -113,7 +113,9 @@ impl MemConfig { type_: MemoryExceptionType::AccessFault, addr, })?; - interface.write_dword(addr, value) + interface + .write_dword(addr, value) + .map_err(|e| e.with_addr(addr)) } } pub fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryException> { @@ -130,7 +132,9 @@ impl MemConfig { type_: MemoryExceptionType::AccessFault, addr, })?; - interface.write_word(addr, value) + interface + .write_word(addr, value) + .map_err(|e| e.with_addr(addr)) } } pub fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryException> { @@ -147,7 +151,9 @@ impl MemConfig { type_: MemoryExceptionType::AccessFault, addr, })?; - interface.write_hword(addr, value) + interface + .write_hword(addr, value) + .map_err(|e| e.with_addr(addr)) } } pub fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { @@ -158,7 +164,9 @@ impl MemConfig { type_: MemoryExceptionType::AccessFault, addr, })?; - interface.write_byte(addr, value) + interface + .write_byte(addr, value) + .map_err(|e| e.with_addr(addr)) } } @@ -531,53 +539,29 @@ impl Default for MmioSecondLevel { #[allow(unused_variables)] pub trait MemDeviceInterface { - fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryException> { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryExceptionType> { + Err(MemoryExceptionType::AccessFault) } - fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryException> { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryExceptionType> { + Err(MemoryExceptionType::AccessFault) } - fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryException> { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryExceptionType> { + Err(MemoryExceptionType::AccessFault) } - fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryExceptionType> { + Err(MemoryExceptionType::AccessFault) } - fn read_dword(&self, addr: u64) -> Result { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn read_dword(&self, addr: u64) -> Result { + Err(MemoryExceptionType::AccessFault) } - fn read_word(&self, addr: u64) -> Result { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn read_word(&self, addr: u64) -> Result { + Err(MemoryExceptionType::AccessFault) } - fn read_hword(&self, addr: u64) -> Result { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn read_hword(&self, addr: u64) -> Result { + Err(MemoryExceptionType::AccessFault) } - fn read_byte(&self, addr: u64) -> Result { - Err(MemoryException { - type_: MemoryExceptionType::AccessFault, - addr, - }) + fn read_byte(&self, addr: u64) -> Result { + Err(MemoryExceptionType::AccessFault) } }