actually no NOW the memory interface is "done"
This commit is contained in:
136
src/mem.rs
136
src/mem.rs
@@ -19,10 +19,11 @@ pub struct MemConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MemConfig {
|
impl MemConfig {
|
||||||
pub fn find_device_by_page(&self, page: PageNum) -> Option<Arc<dyn MemDeviceInterface>> {
|
#[allow(clippy::needless_borrow)]
|
||||||
|
pub fn find_device_by_page(&self, page: PageNum) -> Option<&DeviceEntry> {
|
||||||
for entry in self.devices.iter() {
|
for entry in self.devices.iter() {
|
||||||
if page_in_range(page, entry.base, entry.size) {
|
if page_in_range(page, entry.base, entry.size) {
|
||||||
return Some(entry.interface.clone());
|
return Some(&entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,11 +32,134 @@ 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, MemAccessFault> {
|
||||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||||
self.ram.read_dword(page, offset)
|
self.ram.read_dword(page - self.ram_start, offset)
|
||||||
} else {
|
} else {
|
||||||
self.find_device_by_page(page)
|
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||||
.ok_or(MemAccessFault)?
|
|
||||||
.read_dword(page, offset)
|
entry.interface.read_dword(page - entry.base, offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault> {
|
||||||
|
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)?;
|
||||||
|
|
||||||
|
entry.interface.read_word(page - entry.base, offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault> {
|
||||||
|
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)?;
|
||||||
|
|
||||||
|
entry.interface.read_hword(page - entry.base, offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault> {
|
||||||
|
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)?;
|
||||||
|
|
||||||
|
entry.interface.read_byte(page - entry.base, offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_dword(
|
||||||
|
&self,
|
||||||
|
page: PageNum,
|
||||||
|
offset: u16,
|
||||||
|
value: DWord,
|
||||||
|
) -> Result<(), MemAccessFault> {
|
||||||
|
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)?;
|
||||||
|
entry
|
||||||
|
.interface
|
||||||
|
.write_dword(page - entry.base, offset, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn write_word(
|
||||||
|
&self,
|
||||||
|
page: PageNum,
|
||||||
|
offset: u16,
|
||||||
|
value: Word,
|
||||||
|
) -> Result<(), MemAccessFault> {
|
||||||
|
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)?;
|
||||||
|
entry.interface.write_word(page - entry.base, offset, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn write_hword(
|
||||||
|
&self,
|
||||||
|
page: PageNum,
|
||||||
|
offset: u16,
|
||||||
|
value: HWord,
|
||||||
|
) -> Result<(), MemAccessFault> {
|
||||||
|
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)?;
|
||||||
|
entry
|
||||||
|
.interface
|
||||||
|
.write_hword(page - entry.base, offset, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn write_byte(
|
||||||
|
&self,
|
||||||
|
page: PageNum,
|
||||||
|
offset: u16,
|
||||||
|
value: Byte,
|
||||||
|
) -> Result<(), MemAccessFault> {
|
||||||
|
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)?;
|
||||||
|
entry.interface.write_byte(page - entry.base, offset, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_atomic_dword(
|
||||||
|
&self,
|
||||||
|
page: PageNum,
|
||||||
|
offset: u16,
|
||||||
|
) -> Result<&AtomicU64, MemAccessFault> {
|
||||||
|
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);
|
||||||
|
unsafe {
|
||||||
|
self.ram
|
||||||
|
.buf_transmuted::<AtomicU64>()
|
||||||
|
.get(index)
|
||||||
|
.ok_or(MemAccessFault)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||||
|
entry.interface.get_atomic_dword(page - entry.base, offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn get_atomic_word(
|
||||||
|
&self,
|
||||||
|
page: PageNum,
|
||||||
|
offset: u16,
|
||||||
|
) -> Result<&AtomicU32, MemAccessFault> {
|
||||||
|
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);
|
||||||
|
unsafe {
|
||||||
|
self.ram
|
||||||
|
.buf_transmuted::<AtomicU32>()
|
||||||
|
.get(index)
|
||||||
|
.ok_or(MemAccessFault)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||||
|
entry.interface.get_atomic_word(page - entry.base, offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user