From 5c008bfc0446e4631dbab64be61159af04f78dd1 Mon Sep 17 00:00:00 2001 From: taitep Date: Sat, 27 Dec 2025 21:33:39 +0100 Subject: Add exception values (what will go in mtval/stval) --- src/mem.rs | 253 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 167 insertions(+), 86 deletions(-) (limited to 'src/mem.rs') diff --git a/src/mem.rs b/src/mem.rs index 6aae337..95a0eb2 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -13,7 +13,7 @@ use memmap2::MmapMut; use crate::{ consts::{Addr, Byte, DWord, HWord, Word}, - exceptions::MemoryExceptionType, + exceptions::{MemoryException, MemoryExceptionType}, }; pub type PageNum = usize; @@ -37,119 +37,140 @@ impl MemConfig { } } - pub fn read_dword(&self, addr: Addr) -> Result { + pub fn read_dword(&self, addr: Addr) -> Result { if addr >= RAM_START { self.ram.read_dword(addr - RAM_START) } else { if !addr.is_multiple_of(8) && self.mmio_root.crosses_boundary(addr, 8) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.read_dword(addr) } } - pub fn read_word(&self, addr: Addr) -> Result { + pub fn read_word(&self, addr: Addr) -> Result { if addr >= RAM_START { self.ram.read_word(addr - RAM_START) } else { if !addr.is_multiple_of(4) && self.mmio_root.crosses_boundary(addr, 4) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.read_word(addr) } } - pub fn read_hword(&self, addr: Addr) -> Result { + pub fn read_hword(&self, addr: Addr) -> Result { if addr >= RAM_START { self.ram.read_hword(addr - RAM_START) } else { if !addr.is_multiple_of(2) && self.mmio_root.crosses_boundary(addr, 2) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.read_hword(addr) } } - pub fn read_byte(&self, addr: Addr) -> Result { + pub fn read_byte(&self, addr: Addr) -> Result { if addr >= RAM_START { self.ram.read_byte(addr - RAM_START) } else { - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.read_byte(addr) } } - pub fn write_dword(&self, addr: Addr, value: DWord) -> Result<(), MemoryExceptionType> { + pub fn write_dword(&self, addr: Addr, value: DWord) -> Result<(), MemoryException> { if addr >= RAM_START { self.ram.write_dword(addr - RAM_START, value) } else { if !addr.is_multiple_of(8) && self.mmio_root.crosses_boundary(addr, 8) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.write_dword(addr, value) } } - pub fn write_word(&self, addr: Addr, value: Word) -> Result<(), MemoryExceptionType> { + pub fn write_word(&self, addr: Addr, value: Word) -> Result<(), MemoryException> { if addr >= RAM_START { self.ram.write_word(addr - RAM_START, value) } else { if !addr.is_multiple_of(4) && self.mmio_root.crosses_boundary(addr, 4) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.write_word(addr, value) } } - pub fn write_hword(&self, addr: Addr, value: HWord) -> Result<(), MemoryExceptionType> { + pub fn write_hword(&self, addr: Addr, value: HWord) -> Result<(), MemoryException> { if addr >= RAM_START { self.ram.write_hword(addr - RAM_START, value) } else { if !addr.is_multiple_of(2) && self.mmio_root.crosses_boundary(addr, 2) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.write_hword(addr, value) } } - pub fn write_byte(&self, addr: Addr, value: Byte) -> Result<(), MemoryExceptionType> { + pub fn write_byte(&self, addr: Addr, value: Byte) -> Result<(), MemoryException> { if addr >= RAM_START { self.ram.write_byte(addr - RAM_START, value) } else { - let (interface, addr) = self - .mmio_root - .get_device(addr) - .ok_or(MemoryExceptionType::AccessFault)?; + let (interface, addr) = self.mmio_root.get_device(addr).ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })?; interface.write_byte(addr, value) } } - pub fn get_atomic_dword(&self, addr: Addr) -> Result<&AtomicU64, MemoryExceptionType> { + pub fn get_atomic_dword(&self, addr: Addr) -> Result<&AtomicU64, MemoryException> { if !addr.is_multiple_of(8) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } let index = ((addr - RAM_START) / 8) as usize; @@ -157,16 +178,25 @@ impl MemConfig { self.ram .buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } } - pub fn get_atomic_word(&self, addr: Addr) -> Result<&AtomicU32, MemoryExceptionType> { + pub fn get_atomic_word(&self, addr: Addr) -> Result<&AtomicU32, MemoryException> { if !addr.is_multiple_of(4) { - return Err(MemoryExceptionType::AddressMisaligned); + return Err(MemoryException { + type_: MemoryExceptionType::AddressMisaligned, + addr, + }); } if addr < RAM_START { - return Err(MemoryExceptionType::AccessFault); + return Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }); } let index = ((addr - RAM_START) / 4) as usize; @@ -174,7 +204,10 @@ impl MemConfig { self.ram .buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } } } @@ -229,7 +262,7 @@ impl Ram { } #[inline] - pub fn read_dword(&self, addr: Addr) -> Result { + pub fn read_dword(&self, addr: Addr) -> Result { if !addr.is_multiple_of(8) { let high_word_addr = addr.wrapping_add(4); @@ -243,12 +276,15 @@ impl Ram { Ok(unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .load(Relaxed)) } #[inline] - pub fn read_word(&self, addr: Addr) -> Result { + pub fn read_word(&self, addr: Addr) -> Result { if !addr.is_multiple_of(4) { let high_hword_addr = addr.wrapping_add(2); @@ -262,12 +298,15 @@ impl Ram { Ok(unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .load(Relaxed)) } #[inline] - pub fn read_hword(&self, addr: Addr) -> Result { + pub fn read_hword(&self, addr: Addr) -> Result { if !addr.is_multiple_of(2) { let high_byte_addr = addr.wrapping_add(1); @@ -281,21 +320,27 @@ impl Ram { Ok(unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .load(Relaxed)) } #[inline] - pub fn read_byte(&self, addr: Addr) -> Result { + pub fn read_byte(&self, addr: Addr) -> Result { Ok(self .buf_atomic() .get(addr as usize) - .ok_or(MemoryExceptionType::AccessFault)? + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })? .load(Relaxed)) } #[inline] - pub fn write_dword(&self, addr: Addr, value: DWord) -> Result<(), MemoryExceptionType> { + pub fn write_dword(&self, addr: Addr, value: DWord) -> Result<(), MemoryException> { if !addr.is_multiple_of(8) { let low_word = value as Word; let high_word = (value >> 32) as Word; @@ -311,13 +356,16 @@ impl Ram { unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .store(value, Relaxed); Ok(()) } #[inline] - pub fn write_word(&self, addr: Addr, value: Word) -> Result<(), MemoryExceptionType> { + pub fn write_word(&self, addr: Addr, value: Word) -> Result<(), MemoryException> { if !addr.is_multiple_of(4) { let low_hword = value as HWord; let high_hword = (value >> 16) as HWord; @@ -333,13 +381,16 @@ impl Ram { unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .store(value, Relaxed); Ok(()) } #[inline] - pub fn write_hword(&self, addr: Addr, value: HWord) -> Result<(), MemoryExceptionType> { + pub fn write_hword(&self, addr: Addr, value: HWord) -> Result<(), MemoryException> { if !addr.is_multiple_of(2) { let low_byte = value as Byte; let high_byte = (value >> 8) as Byte; @@ -355,16 +406,22 @@ impl Ram { unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .store(value, Relaxed); Ok(()) } #[inline] - pub fn write_byte(&self, addr: Addr, value: Byte) -> Result<(), MemoryExceptionType> { + pub fn write_byte(&self, addr: Addr, value: Byte) -> Result<(), MemoryException> { self.buf_atomic() .get(addr as usize) - .ok_or(MemoryExceptionType::AccessFault)? + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + })? .store(value, Relaxed); Ok(()) } @@ -477,29 +534,53 @@ impl Default for MmioSecondLevel { #[allow(unused_variables)] pub trait MemDeviceInterface { - fn write_dword(&self, addr: Addr, value: DWord) -> Result<(), MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn write_dword(&self, addr: Addr, value: DWord) -> Result<(), MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn write_word(&self, addr: Addr, value: Word) -> Result<(), MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn write_word(&self, addr: Addr, value: Word) -> Result<(), MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn write_hword(&self, addr: Addr, value: HWord) -> Result<(), MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn write_hword(&self, addr: Addr, value: HWord) -> Result<(), MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn write_byte(&self, addr: Addr, value: Byte) -> Result<(), MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn write_byte(&self, addr: Addr, value: Byte) -> Result<(), MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn read_dword(&self, addr: Addr) -> Result { - Err(MemoryExceptionType::AccessFault) + fn read_dword(&self, addr: Addr) -> Result { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn read_word(&self, addr: Addr) -> Result { - Err(MemoryExceptionType::AccessFault) + fn read_word(&self, addr: Addr) -> Result { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn read_hword(&self, addr: Addr) -> Result { - Err(MemoryExceptionType::AccessFault) + fn read_hword(&self, addr: Addr) -> Result { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn read_byte(&self, addr: Addr) -> Result { - Err(MemoryExceptionType::AccessFault) + fn read_byte(&self, addr: Addr) -> Result { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } } -- cgit v1.2.3