use crate::cglue::*;
use crate::dataview::Pod;
use crate::error::Result;
use crate::types::{umem, Address, PhysicalAddress};
use super::mem_data::*;
use super::PhysicalMemoryMapping;
use std::prelude::v1::*;
use crate::mem::memory_view::*;
pub mod cache;
pub use cache::*;
#[cfg_attr(feature = "plugins", cglue_trait)]
#[int_result]
#[cglue_forward]
pub trait PhysicalMemory: Send {
fn phys_read_raw_iter<'a>(
&mut self,
data: CIterator<PhysicalReadData<'a>>,
out_fail: &mut ReadFailCallback<'_, 'a>,
) -> Result<()>;
fn phys_write_raw_iter<'a>(
&mut self,
data: CIterator<PhysicalWriteData<'a>>,
out_fail: &mut WriteFailCallback<'_, 'a>,
) -> Result<()>;
fn metadata(&self) -> PhysicalMemoryMetadata;
#[inline]
fn set_mem_map(&mut self, _mem_map: &[PhysicalMemoryMapping]) {}
#[skip_func]
fn phys_read_into<T: Pod + ?Sized>(&mut self, addr: PhysicalAddress, out: &mut T) -> Result<()>
where
Self: Sized,
{
let mut iter = Some(MemData(addr, out.as_bytes_mut().into())).into_iter();
self.phys_read_raw_iter(
(&mut iter).into(),
&mut (&mut |MemData(_, mut d): ReadData| {
d.iter_mut().for_each(|b| *b = 0);
true
})
.into(),
)
}
#[skip_func]
fn phys_write<T: Pod + ?Sized>(&mut self, addr: PhysicalAddress, data: &T) -> Result<()>
where
Self: Sized,
{
let mut iter = Some(MemData(addr, data.as_bytes().into())).into_iter();
self.phys_write_raw_iter((&mut iter).into(), &mut (&mut |_| true).into())
}
#[vtbl_only('static, wrap_with_obj(MemoryView))]
fn into_phys_view(self) -> PhysicalMemoryView<Self>
where
Self: Sized,
{
PhysicalMemoryView { mem: self }
}
#[vtbl_only('_, wrap_with_obj(MemoryView))]
fn phys_view(&mut self) -> PhysicalMemoryView<Fwd<&mut Self>>
where
Self: Sized,
{
self.forward_mut().into_phys_view()
}
}
#[repr(C)]
#[derive(Clone)]
#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
pub struct PhysicalMemoryView<T> {
mem: T,
}
impl<T: PhysicalMemory> MemoryView for PhysicalMemoryView<T> {
fn read_raw_iter<'a>(
&mut self,
data: CIterator<ReadData<'a>>,
out_fail: &mut ReadFailCallback<'_, 'a>,
) -> Result<()> {
let mut iter = data.map(|MemData(addr, data)| MemData(addr.into(), data));
self.mem.phys_read_raw_iter((&mut iter).into(), out_fail)
}
fn write_raw_iter<'a>(
&mut self,
data: CIterator<WriteData<'a>>,
out_fail: &mut WriteFailCallback<'_, 'a>,
) -> Result<()> {
let mut iter = data.map(|MemData(addr, data)| MemData(addr.into(), data));
self.mem.phys_write_raw_iter((&mut iter).into(), out_fail)
}
fn metadata(&self) -> MemoryViewMetadata {
let PhysicalMemoryMetadata {
max_address,
real_size,
readonly,
..
} = self.mem.metadata();
MemoryViewMetadata {
max_address,
real_size,
readonly,
#[cfg(target_pointer_width = "64")]
arch_bits: 64,
#[cfg(target_pointer_width = "32")]
arch_bits: 32,
#[cfg(target_endian = "little")]
little_endian: true,
#[cfg(target_endian = "big")]
little_endian: false,
}
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
pub struct PhysicalMemoryMetadata {
pub max_address: Address,
pub real_size: umem,
pub readonly: bool,
pub ideal_batch_size: u32,
}