diff options
| author | taitep <taitep@taitep.se> | 2025-12-27 21:33:39 +0100 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-12-27 21:33:39 +0100 |
| commit | 5c008bfc0446e4631dbab64be61159af04f78dd1 (patch) | |
| tree | 852f7ee883f675b4c67cf424b8f7d17357e7742d /src/mem.rs | |
| parent | b5d36b7969f2759147d58a80e0e5b62c215d2998 (diff) | |
Add exception values (what will go in mtval/stval)
Diffstat (limited to 'src/mem.rs')
| -rw-r--r-- | src/mem.rs | 253 |
1 files changed, 167 insertions, 86 deletions
@@ -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<DWord, MemoryExceptionType> { + pub fn read_dword(&self, addr: Addr) -> Result<DWord, MemoryException> { 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<Word, MemoryExceptionType> { + pub fn read_word(&self, addr: Addr) -> Result<Word, MemoryException> { 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<HWord, MemoryExceptionType> { + pub fn read_hword(&self, addr: Addr) -> Result<HWord, MemoryException> { 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<Byte, MemoryExceptionType> { + pub fn read_byte(&self, addr: Addr) -> Result<Byte, MemoryException> { 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::<AtomicU64>() .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::<AtomicU32>() .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<DWord, MemoryExceptionType> { + pub fn read_dword(&self, addr: Addr) -> Result<DWord, MemoryException> { 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::<AtomicU64>() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .load(Relaxed)) } #[inline] - pub fn read_word(&self, addr: Addr) -> Result<Word, MemoryExceptionType> { + pub fn read_word(&self, addr: Addr) -> Result<Word, MemoryException> { 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::<AtomicU32>() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .load(Relaxed)) } #[inline] - pub fn read_hword(&self, addr: Addr) -> Result<HWord, MemoryExceptionType> { + pub fn read_hword(&self, addr: Addr) -> Result<HWord, MemoryException> { 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::<AtomicU16>() .get(index) - .ok_or(MemoryExceptionType::AccessFault) + .ok_or(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) }? .load(Relaxed)) } #[inline] - pub fn read_byte(&self, addr: Addr) -> Result<Byte, MemoryExceptionType> { + pub fn read_byte(&self, addr: Addr) -> Result<Byte, MemoryException> { 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::<AtomicU64>() .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::<AtomicU32>() .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::<AtomicU16>() .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<DWord, MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn read_dword(&self, addr: Addr) -> Result<DWord, MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn read_word(&self, addr: Addr) -> Result<Word, MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn read_word(&self, addr: Addr) -> Result<Word, MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn read_hword(&self, addr: Addr) -> Result<HWord, MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn read_hword(&self, addr: Addr) -> Result<HWord, MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } - fn read_byte(&self, addr: Addr) -> Result<Byte, MemoryExceptionType> { - Err(MemoryExceptionType::AccessFault) + fn read_byte(&self, addr: Addr) -> Result<Byte, MemoryException> { + Err(MemoryException { + type_: MemoryExceptionType::AccessFault, + addr, + }) } } |
