pub struct MemView {
pub mappings: Set<Mapping>,
pub memory: Map<Paddr, MemContents<u8>>,
}Fields§
§mappings: Set<Mapping>§memory: Map<Paddr, MemContents<u8>>Implementations§
Source§impl MemView
impl MemView
Sourcepub open spec fn addr_transl(self, va: usize) -> Option<usize>
pub open spec fn addr_transl(self, va: usize) -> Option<usize>
{
let mappings = self
.mappings
.filter(|m: Mapping| m.va_range.start <= va < m.va_range.end);
if 0 < mappings.len() {
let m = mappings.choose();
let off = va - m.va_range.start;
Some((m.pa_range.start + off) as usize)
} else {
None
}
}Sourcepub open spec fn read(self, va: usize) -> Option<MemContents<u8>>
pub open spec fn read(self, va: usize) -> Option<MemContents<u8>>
{
let pa = self.addr_transl(va);
if pa is Some { Some(self.memory[pa.unwrap()]) } else { None }
}Sourcepub open spec fn write(self, va: usize, x: u8) -> Option<Self>
pub open spec fn write(self, va: usize, x: u8) -> Option<Self>
{
let pa = self.addr_transl(va);
if pa is Some {
Some(MemView {
memory: self.memory.insert(pa.unwrap(), raw_ptr::MemContents::Init(x)),
..self
})
} else {
None
}
}Sourcepub open spec fn eq_at(self, va1: usize, va2: usize) -> bool
pub open spec fn eq_at(self, va1: usize, va2: usize) -> bool
{
let pa1 = self.addr_transl(va1);
let pa2 = self.addr_transl(va2);
if pa1 is Some && pa2 is Some {
self.memory[pa1.unwrap()] == self.memory[pa2.unwrap()]
} else {
false
}
}Sourcepub open spec fn borrow_at_spec(&self, vaddr: usize, len: usize) -> MemView
pub open spec fn borrow_at_spec(&self, vaddr: usize, len: usize) -> MemView
{
let range_end = vaddr + len;
let valid_pas = Set::new(|pa: usize| {
exists |va: usize| {
vaddr <= va < range_end && #[trigger] self.addr_transl(va) == Some(pa)
}
});
MemView {
mappings: self
.mappings
.filter(|m: Mapping| m.va_range.start < range_end && m.va_range.end > vaddr),
memory: self.memory.restrict(valid_pas),
}
}Sourcepub open spec fn mappings_are_disjoint(self) -> bool
pub open spec fn mappings_are_disjoint(self) -> bool
{
forall |m1: Mapping, m2: Mapping| {
self.mappings.contains(m1) && self.mappings.contains(m2) && m1 != m2
==> {
m1.va_range.end <= m2.va_range.start
|| m2.va_range.end <= m1.va_range.start
}
}
}Sourcepub open spec fn split_spec(self, vaddr: usize, len: usize) -> (MemView, MemView)
pub open spec fn split_spec(self, vaddr: usize, len: usize) -> (MemView, MemView)
{
let split_end = vaddr + len;
let left_mappings = self
.mappings
.filter(|m: Mapping| m.va_range.start < split_end && m.va_range.end > vaddr);
let right_mappings = self.mappings.filter(|m: Mapping| m.va_range.end > split_end);
let left_pas = Set::new(|pa: usize| {
exists |va: usize| vaddr <= va < split_end && self.addr_transl(va) == Some(pa)
});
let right_pas = Set::new(|pa: usize| {
exists |va: usize| va >= split_end && self.addr_transl(va) == Some(pa)
});
(
MemView {
mappings: left_mappings,
memory: self.memory.restrict(left_pas),
},
MemView {
mappings: right_mappings,
memory: self.memory.restrict(right_pas),
},
)
}Sourcepub proof fn lemma_disjoint_filter_at_one(&self, va: usize)
pub proof fn lemma_disjoint_filter_at_one(&self, va: usize)
requires
self.mappings_are_disjoint(),ensuresself.mappings.filter(|m: Mapping| m.va_range.start <= va < m.va_range.end).len() <= 1,Sourcepub proof fn borrow_at(tracked &self, vaddr: usize, len: usize) -> tracked r : &MemView
pub proof fn borrow_at(tracked &self, vaddr: usize, len: usize) -> tracked r : &MemView
ensures
r == self.borrow_at_spec(vaddr, len),Borrows a memory view for a sub-range.
Sourcepub proof fn split(tracked self, vaddr: usize, len: usize) -> tracked r : (Self, Self)
pub proof fn split(tracked self, vaddr: usize, len: usize) -> tracked r : (Self, Self)
ensures
r == self.split_spec(vaddr, len),Splits the memory view into two disjoint views.
Returns the split memory views where the first is
for [vaddr, vaddr + len) and the second is for the rest.
Sourcepub proof fn lemma_split_preserves_transl(
original: MemView,
vaddr: usize,
len: usize,
left: MemView,
right: MemView,
)
pub proof fn lemma_split_preserves_transl( original: MemView, vaddr: usize, len: usize, left: MemView, right: MemView, )
requires
original.split_spec(vaddr, len) == (left, right),ensuresright.memory.dom().subset_of(original.memory.dom()),forall |va: usize| {
vaddr <= va < vaddr + len
==> { #[trigger] original.addr_transl(va) == left.addr_transl(va) }
},forall |va: usize| {
va >= vaddr + len
==> { #[trigger] original.addr_transl(va) == right.addr_transl(va) }
},This proves that if split is performed and we have (lhs, rhs) = self.split(vaddr, len), then we have all translations preserved in lhs and rhs.
Sourcepub open spec fn join_spec(self, other: MemView) -> MemView
pub open spec fn join_spec(self, other: MemView) -> MemView
{
MemView {
mappings: self.mappings.union(other.mappings),
memory: self.memory.union_prefer_right(other.memory),
}
}Auto Trait Implementations§
impl Freeze for MemView
impl RefUnwindSafe for MemView
impl Send for MemView
impl Sync for MemView
impl Unpin for MemView
impl UnwindSafe for MemView
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more