diff options
| author | taitep <taitep@taitep.se> | 2025-12-24 13:56:41 +0100 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-12-24 13:56:41 +0100 |
| commit | 09d90643726d2a86952473e27b6e5d64543e41a0 (patch) | |
| tree | 52d0ebf404675e1ae359dd77af406131a0623111 /src/mem.rs | |
| parent | 3f789442c0be7d0222209d98dde21efcff7602d0 (diff) | |
EXCEPTION SYSTEM (initial version - may change later)
Diffstat (limited to 'src/mem.rs')
| -rw-r--r-- | src/mem.rs | 154 |
1 files changed, 74 insertions, 80 deletions
@@ -11,7 +11,10 @@ use std::sync::{ use memmap2::MmapMut; -use crate::consts::{Byte, DWord, HWord, Word}; +use crate::{ + consts::{Byte, DWord, HWord, Word}, + exceptions::ExceptionType, +}; pub type PageNum = usize; @@ -45,38 +48,46 @@ impl MemConfig { } } - pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, MemAccessFault> { + pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.read_dword(page - self.ram_start, offset) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::LoadAccessFault)?; entry.interface.read_dword(page - entry.base, offset) } } - pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault> { + pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.read_word(page - self.ram_start, offset) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::LoadAccessFault)?; entry.interface.read_word(page - entry.base, offset) } } - pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault> { + pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.read_hword(page - self.ram_start, offset) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::LoadAccessFault)?; entry.interface.read_hword(page - entry.base, offset) } } - pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault> { + pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.read_byte(page - self.ram_start, offset) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::LoadAccessFault)?; entry.interface.read_byte(page - entry.base, offset) } @@ -87,26 +98,25 @@ impl MemConfig { page: PageNum, offset: u16, value: DWord, - ) -> Result<(), MemAccessFault> { + ) -> Result<(), ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.write_dword(page - self.ram_start, offset, value) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::StoreAmoAccessFault)?; entry .interface .write_dword(page - entry.base, offset, value) } } - pub fn write_word( - &self, - page: PageNum, - offset: u16, - value: Word, - ) -> Result<(), MemAccessFault> { + pub fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.write_word(page - self.ram_start, offset, value) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::StoreAmoAccessFault)?; entry.interface.write_word(page - entry.base, offset, value) } } @@ -115,26 +125,25 @@ impl MemConfig { page: PageNum, offset: u16, value: HWord, - ) -> Result<(), MemAccessFault> { + ) -> Result<(), ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.write_hword(page - self.ram_start, offset, value) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::StoreAmoAccessFault)?; entry .interface .write_hword(page - entry.base, offset, value) } } - pub fn write_byte( - &self, - page: PageNum, - offset: u16, - value: Byte, - ) -> Result<(), MemAccessFault> { + pub fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { self.ram.write_byte(page - self.ram_start, offset, value) } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::StoreAmoAccessFault)?; entry.interface.write_byte(page - entry.base, offset, value) } } @@ -143,7 +152,7 @@ impl MemConfig { &self, page: PageNum, offset: u16, - ) -> Result<&AtomicU64, MemAccessFault> { + ) -> Result<&AtomicU64, ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { debug_assert!(((offset * 8) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 8) + (offset as usize); @@ -151,18 +160,16 @@ impl MemConfig { self.ram .buf_transmuted::<AtomicU64>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::HardwareError) } } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::StoreAmoAccessFault)?; entry.interface.get_atomic_dword(page - entry.base, offset) } } - pub fn get_atomic_word( - &self, - page: PageNum, - offset: u16, - ) -> Result<&AtomicU32, MemAccessFault> { + pub fn get_atomic_word(&self, page: PageNum, offset: u16) -> Result<&AtomicU32, ExceptionType> { if page_in_range(page, self.ram_start, self.ram.pages) { debug_assert!(((offset * 4) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 4) + (offset as usize); @@ -170,10 +177,12 @@ impl MemConfig { self.ram .buf_transmuted::<AtomicU32>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::HardwareError) } } else { - let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?; + let entry = self + .find_device_by_page(page) + .ok_or(ExceptionType::StoreAmoAccessFault)?; entry.interface.get_atomic_word(page - entry.base, offset) } } @@ -232,46 +241,46 @@ impl Ram { } #[inline] - pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, MemAccessFault> { + pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, ExceptionType> { debug_assert!(((offset * 8) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 8) + (offset as usize); Ok(unsafe { self.buf_transmuted::<AtomicU64>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::LoadAccessFault) }? .load(Relaxed)) } #[inline] - pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault> { + pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, ExceptionType> { debug_assert!(((offset * 4) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 4) + (offset as usize); Ok(unsafe { self.buf_transmuted::<AtomicU32>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::LoadAccessFault) }? .load(Relaxed)) } #[inline] - pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault> { + pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, ExceptionType> { debug_assert!(((offset * 2) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 2) + (offset as usize); Ok(unsafe { self.buf_transmuted::<AtomicU16>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::LoadAccessFault) }? .load(Relaxed)) } #[inline] - pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault> { + pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, ExceptionType> { debug_assert!((offset as usize) < PAGE_SIZE); let index = page * PAGE_SIZE + (offset as usize); Ok(self .buf_atomic() .get(index) - .ok_or(MemAccessFault)? + .ok_or(ExceptionType::LoadAccessFault)? .load(Relaxed)) } @@ -281,30 +290,25 @@ impl Ram { page: PageNum, offset: u16, value: DWord, - ) -> Result<(), MemAccessFault> { + ) -> Result<(), ExceptionType> { debug_assert!(((offset * 8) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 8) + (offset as usize); unsafe { self.buf_transmuted::<AtomicU64>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::StoreAmoAccessFault) }? .store(value, Relaxed); Ok(()) } #[inline] - pub fn write_word( - &self, - page: PageNum, - offset: u16, - value: Word, - ) -> Result<(), MemAccessFault> { + pub fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), ExceptionType> { debug_assert!(((offset * 4) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 4) + (offset as usize); unsafe { self.buf_transmuted::<AtomicU32>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::StoreAmoAccessFault) }? .store(value, Relaxed); Ok(()) @@ -315,29 +319,24 @@ impl Ram { page: PageNum, offset: u16, value: HWord, - ) -> Result<(), MemAccessFault> { + ) -> Result<(), ExceptionType> { debug_assert!(((offset * 2) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 2) + (offset as usize); unsafe { self.buf_transmuted::<AtomicU16>() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::StoreAmoAccessFault) }? .store(value, Relaxed); Ok(()) } #[inline] - pub fn write_byte( - &self, - page: PageNum, - offset: u16, - value: Byte, - ) -> Result<(), MemAccessFault> { + pub fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType> { debug_assert!((offset as usize) < PAGE_SIZE); let index = page * PAGE_SIZE + (offset as usize); self.buf_atomic() .get(index) - .ok_or(MemAccessFault)? + .ok_or(ExceptionType::StoreAmoAccessFault)? .store(value, Relaxed); Ok(()) } @@ -351,21 +350,16 @@ pub struct DeviceEntry { } pub trait MemDeviceInterface { - fn write_dword(&self, page: PageNum, offset: u16, value: DWord) -> Result<(), MemAccessFault>; - fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), MemAccessFault>; - fn write_hword(&self, page: PageNum, offset: u16, value: HWord) -> Result<(), MemAccessFault>; - fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), MemAccessFault>; - - fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, MemAccessFault>; - fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault>; - fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault>; - fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault>; - - fn get_atomic_word(&self, page: PageNum, offset: u16) -> Result<&AtomicU32, MemAccessFault>; - fn get_atomic_dword(&self, page: PageNum, offset: u16) -> Result<&AtomicU64, MemAccessFault>; + fn write_dword(&self, page: PageNum, offset: u16, value: DWord) -> Result<(), ExceptionType>; + fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), ExceptionType>; + fn write_hword(&self, page: PageNum, offset: u16, value: HWord) -> Result<(), ExceptionType>; + fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType>; + + fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, ExceptionType>; + fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, ExceptionType>; + fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, ExceptionType>; + fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, ExceptionType>; + + fn get_atomic_word(&self, page: PageNum, offset: u16) -> Result<&AtomicU32, ExceptionType>; + fn get_atomic_dword(&self, page: PageNum, offset: u16) -> Result<&AtomicU64, ExceptionType>; } - -/// Error that means something has gone wrong accessing memory -/// Examples are: Accessing unmapped memory, accessing an MMIO register at the wrong size -#[derive(Debug)] -pub struct MemAccessFault; |
