ostd/mm/frame/meta/
mapping.rs1use vstd::prelude::*;
2use vstd_extra::extern_const::*;
3
4use crate::mm::frame::meta::MetaSlot;
5use crate::mm::Paddr;
6use crate::mm::Vaddr;
7use crate::specs::arch::kspace::FRAME_METADATA_RANGE;
8use crate::specs::arch::mm::{MAX_NR_PAGES, MAX_PADDR, PAGE_SIZE};
9
10use core::mem::size_of;
11use core::ops::Range;
12
13verus! {
14
15extern_const!(
16pub META_SLOT_SIZE [META_SLOT_SIZE_SPEC, CONST_META_SLOT_SIZE]: usize = 64
18);
19
20pub open spec fn max_meta_slots() -> int {
21 (FRAME_METADATA_RANGE().end - FRAME_METADATA_RANGE().start) / META_SLOT_SIZE() as int
22}
23
24pub open spec fn meta_addr(i: usize) -> (res: usize)
25 recommends
26 0 <= i < max_meta_slots() as usize,
27{
28 (FRAME_METADATA_RANGE().start + i * META_SLOT_SIZE()) as usize
29}
30
31#[allow(non_snake_case)]
32pub broadcast proof fn lemma_FRAME_METADATA_RANGE_is_page_aligned()
33 ensures
34 #[trigger] FRAME_METADATA_RANGE().start % PAGE_SIZE() == 0,
35 FRAME_METADATA_RANGE().end % PAGE_SIZE() == 0,
36{
37}
38
39#[allow(non_snake_case)]
40pub broadcast proof fn lemma_FRAME_METADATA_RANGE_is_large_enough()
41 ensures
42 #[trigger] FRAME_METADATA_RANGE().end >= FRAME_METADATA_RANGE().start + MAX_NR_PAGES()
43 * META_SLOT_SIZE(),
44{
45}
46
47} verus! {
49
50#[verifier::inline]
51pub open spec fn frame_to_meta_spec(paddr: Paddr) -> (res: Vaddr)
52 recommends
53 paddr % PAGE_SIZE() == 0,
54 paddr < MAX_PADDR(),
55{
56 (FRAME_METADATA_RANGE().start + (paddr / PAGE_SIZE()) * META_SLOT_SIZE()) as usize
57}
58
59#[verifier::inline]
60pub open spec fn meta_to_frame_spec(vaddr: Vaddr) -> Paddr
61 recommends
62 vaddr % size_of::<super::MetaSlot>() == 0,
63 FRAME_METADATA_RANGE().start <= vaddr < FRAME_METADATA_RANGE().end,
64{
65 ((vaddr - FRAME_METADATA_RANGE().start) / META_SLOT_SIZE() as int * PAGE_SIZE()) as usize
66}
67
68#[verifier::inline]
69pub open spec fn frame_to_index_spec(paddr: Paddr) -> usize {
70 paddr / PAGE_SIZE()
71}
72
73#[verifier::inline]
74pub open spec fn index_to_frame_spec(index: usize) -> Paddr {
75 (index * PAGE_SIZE()) as usize
76}
77
78#[verifier::when_used_as_spec(frame_to_index_spec)]
79pub fn frame_to_index(paddr: Paddr) -> (res: usize)
80 requires
81 paddr % PAGE_SIZE() == 0,
82 ensures
83 res == frame_to_index_spec(paddr),
84{
85 paddr / PAGE_SIZE()
86}
87
88#[verifier::when_used_as_spec(index_to_frame_spec)]
89pub fn index_to_frame(index: usize) -> (res: Paddr)
90 requires
91 index < max_meta_slots(),
92 ensures
93 res == index_to_frame_spec(index),
94{
95 index * PAGE_SIZE()
96}
97
98} verus! {
100
101#[inline(always)]
102#[verifier::when_used_as_spec(frame_to_meta_spec)]
103pub fn frame_to_meta(paddr: Paddr) -> (res: Vaddr)
104 requires
105 paddr % PAGE_SIZE() == 0,
106 paddr < MAX_PADDR(),
107 ensures
108 res == frame_to_meta_spec(paddr),
109 res % META_SLOT_SIZE() == 0,
110{
111 let base = FRAME_METADATA_RANGE().start;
112 let offset = paddr / PAGE_SIZE();
113 base + offset * META_SLOT_SIZE()
114}
115
116#[inline(always)]
117#[verifier::when_used_as_spec(meta_to_frame_spec)]
118pub fn meta_to_frame(vaddr: Vaddr) -> (res: Paddr)
119 requires
120 FRAME_METADATA_RANGE().start <= vaddr && vaddr < FRAME_METADATA_RANGE().end,
121 vaddr % META_SLOT_SIZE() == 0,
122 ensures
123 res == meta_to_frame_spec(vaddr),
124 res % PAGE_SIZE() == 0,
125{
126 let base = FRAME_METADATA_RANGE().start;
127 let offset = (vaddr - base) / META_SLOT_SIZE();
128 offset * PAGE_SIZE()
129}
130
131pub broadcast proof fn lemma_paddr_to_meta_biinjective(paddr: Paddr)
132 requires
133 paddr % PAGE_SIZE() == 0,
134 paddr < MAX_PADDR(),
135 ensures
136 #[trigger] meta_to_frame(frame_to_meta(paddr)) == paddr,
137{
138}
139
140pub broadcast proof fn lemma_meta_to_paddr_biinjective(vaddr: Vaddr)
141 requires
142 FRAME_METADATA_RANGE().start <= vaddr && vaddr < FRAME_METADATA_RANGE().end,
143 vaddr % META_SLOT_SIZE() == 0,
144 ensures
145 #[trigger] frame_to_meta(meta_to_frame(vaddr)) == vaddr,
146{
147}
148
149pub broadcast proof fn lemma_meta_to_frame_soundness(meta: Vaddr)
150 requires
151 meta % META_SLOT_SIZE() == 0,
152 FRAME_METADATA_RANGE().start <= meta && meta < FRAME_METADATA_RANGE().start + MAX_NR_PAGES()
153 * META_SLOT_SIZE(),
154 ensures
155 #[trigger] meta_to_frame(meta) % PAGE_SIZE() == 0,
156 meta_to_frame(meta) < MAX_PADDR(),
157{
158}
159
160pub broadcast proof fn lemma_frame_to_meta_soundness(page: Paddr)
161 requires
162 page % PAGE_SIZE() == 0,
163 page < MAX_PADDR(),
164 ensures
165 #[trigger] frame_to_meta(page) % META_SLOT_SIZE() == 0,
166 FRAME_METADATA_RANGE().start <= frame_to_meta(page) && frame_to_meta(page)
167 < FRAME_METADATA_RANGE().start + MAX_NR_PAGES() * META_SLOT_SIZE(),
168{
169}
170
171pub broadcast proof fn lemma_meta_to_frame_alignment(meta: Vaddr)
172 requires
173 meta % META_SLOT_SIZE() == 0,
174 FRAME_METADATA_RANGE().start <= meta && meta < FRAME_METADATA_RANGE().start + MAX_NR_PAGES()
175 * META_SLOT_SIZE(),
176 ensures
177 #[trigger] meta_to_frame(meta) % PAGE_SIZE() == 0,
178 meta_to_frame(meta) < MAX_PADDR(),
179{
180}
181
182pub broadcast group group_page_meta {
183 crate::mm::frame::meta::lemma_meta_slot_size,
184 lemma_FRAME_METADATA_RANGE_is_page_aligned,
185 lemma_FRAME_METADATA_RANGE_is_large_enough,
186 lemma_paddr_to_meta_biinjective,
187 lemma_meta_to_paddr_biinjective,
188 lemma_meta_to_frame_soundness,
189 lemma_frame_to_meta_soundness,
190 lemma_meta_to_frame_alignment,
191}
192
193}