summaryrefslogtreecommitdiff
path: root/src/mem.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem.rs')
-rw-r--r--src/mem.rs253
1 files changed, 167 insertions, 86 deletions
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<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,
+ })
}
}