From 09d90643726d2a86952473e27b6e5d64543e41a0 Mon Sep 17 00:00:00 2001 From: taitep Date: Wed, 24 Dec 2025 13:56:41 +0100 Subject: EXCEPTION SYSTEM (initial version - may change later) --- src/mem.rs | 154 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 74 insertions(+), 80 deletions(-) (limited to 'src/mem.rs') diff --git a/src/mem.rs b/src/mem.rs index 44e1dc7..21cabec 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -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 { + pub fn read_dword(&self, page: PageNum, offset: u16) -> Result { 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 { + pub fn read_word(&self, page: PageNum, offset: u16) -> Result { 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 { + pub fn read_hword(&self, page: PageNum, offset: u16) -> Result { 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 { + pub fn read_byte(&self, page: PageNum, offset: u16) -> Result { 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::() .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::() .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 { + pub fn read_dword(&self, page: PageNum, offset: u16) -> Result { debug_assert!(((offset * 8) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 8) + (offset as usize); Ok(unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::LoadAccessFault) }? .load(Relaxed)) } #[inline] - pub fn read_word(&self, page: PageNum, offset: u16) -> Result { + pub fn read_word(&self, page: PageNum, offset: u16) -> Result { debug_assert!(((offset * 4) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 4) + (offset as usize); Ok(unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::LoadAccessFault) }? .load(Relaxed)) } #[inline] - pub fn read_hword(&self, page: PageNum, offset: u16) -> Result { + pub fn read_hword(&self, page: PageNum, offset: u16) -> Result { debug_assert!(((offset * 2) as usize) < PAGE_SIZE); let index = page * (PAGE_SIZE / 2) + (offset as usize); Ok(unsafe { self.buf_transmuted::() .get(index) - .ok_or(MemAccessFault) + .ok_or(ExceptionType::LoadAccessFault) }? .load(Relaxed)) } #[inline] - pub fn read_byte(&self, page: PageNum, offset: u16) -> Result { + pub fn read_byte(&self, page: PageNum, offset: u16) -> Result { 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::() .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::() .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::() .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; - fn read_word(&self, page: PageNum, offset: u16) -> Result; - fn read_hword(&self, page: PageNum, offset: u16) -> Result; - fn read_byte(&self, page: PageNum, offset: u16) -> Result; - - 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; + fn read_word(&self, page: PageNum, offset: u16) -> Result; + fn read_hword(&self, page: PageNum, offset: u16) -> Result; + fn read_byte(&self, page: PageNum, offset: u16) -> Result; + + 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; -- cgit v1.2.3