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(&mut self, data: PhysicalReadMemOps) -> Result<()>;
fn phys_write_raw_iter(&mut self, data: PhysicalWriteMemOps) -> 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,
{
MemOps::with(
std::iter::once((addr, CSliceMut::from(out.as_bytes_mut()))),
None,
Some(
&mut (&mut |CTup2(_, mut d): ReadData| {
d.iter_mut().for_each(|b| *b = 0);
true
})
.into(),
),
|data| self.phys_read_raw_iter(data),
)
}
#[skip_func]
fn phys_write<T: Pod + ?Sized>(&mut self, addr: PhysicalAddress, data: &T) -> Result<()>
where
Self: Sized,
{
MemOps::with(
std::iter::once((addr, CSliceRef::from(data.as_bytes()))),
None,
None,
|data| self.phys_write_raw_iter(data),
)
}
#[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(&mut self, MemOps { inp, out, out_fail }: ReadRawMemOps) -> Result<()> {
let inp = &mut inp.map(|CTup3(addr, meta_addr, data)| CTup3(addr.into(), meta_addr, data));
let inp = inp.into();
let data = MemOps { inp, out, out_fail };
self.mem.phys_read_raw_iter(data)
}
fn write_raw_iter(&mut self, MemOps { inp, out, out_fail }: WriteRawMemOps) -> Result<()> {
let inp = &mut inp.map(|CTup3(addr, meta_addr, data)| CTup3(addr.into(), meta_addr, data));
let inp = inp.into();
let data = MemOps { inp, out, out_fail };
self.mem.phys_write_raw_iter(data)
}
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,
}