20
20
static uint64_t page_walk (uint64_t vaddr_value );
21
21
static void page_fault_handler (pte4_t * pte , address_t vaddr );
22
22
23
+ int swap_in (uint64_t daddr , uint64_t ppn );
24
+ int swap_out (uint64_t daddr , uint64_t ppn );
25
+
23
26
// consider this function va2pa as functional
24
27
uint64_t va2pa (uint64_t vaddr )
25
28
{
@@ -151,9 +154,12 @@ static uint64_t page_walk(uint64_t vaddr_value)
151
154
static void page_fault_handler (pte4_t * pte , address_t vaddr )
152
155
{
153
156
// select one victim physical page to swap to disk
157
+ assert (pte -> present == 0 );
154
158
155
159
// this is the selected ppn for vaddr
156
160
int ppn = -1 ;
161
+ pte4_t * victim = NULL ;
162
+ uint64_t daddr = 0xffffffffffffffff ;
157
163
158
164
// 1. try to request one free physical page from DRAM
159
165
// kernel's responsibility
@@ -181,7 +187,86 @@ static void page_fault_handler(pte4_t *pte, address_t vaddr)
181
187
182
188
// 2. no free physical page: select one clean page (LRU) and overwrite
183
189
// in this case, there is no DRAM - DISK transaction
190
+ int lru_ppn = -1 ;
191
+ int lru_time = -1 ;
192
+ for (int i = 0 ; i < MAX_NUM_PHYSICAL_PAGE ; ++ i )
193
+ {
194
+ if (page_map [i ].dirty == 0 &&
195
+ lru_time < page_map [i ].time )
196
+ {
197
+ lru_time = page_map [i ].time ;
198
+ lru_ppn = i ;
199
+ }
200
+ }
201
+
202
+ if (-1 != lru_ppn && lru_ppn < MAX_NUM_PHYSICAL_PAGE )
203
+ {
204
+ ppn = lru_ppn ;
205
+
206
+ // reversed mapping
207
+ victim = page_map [ppn ].pte4 ;
208
+
209
+ victim -> pte_value = 0 ;
210
+ victim -> present = 0 ;
211
+ victim -> daddr = page_map [ppn ].daddr ;
212
+
213
+ // load page from disk to physical memory first
214
+ daddr = pte -> daddr ;
215
+ swap_in (pte -> daddr , ppn );
216
+
217
+ pte -> pte_value = 0 ;
218
+ pte -> present = 1 ;
219
+ pte -> ppn = ppn ;
220
+ pte -> dirty = 0 ;
221
+
222
+ page_map [ppn ].allocated = 1 ;
223
+ page_map [ppn ].time = 0 ;
224
+ page_map [ppn ].dirty = 0 ;
225
+ page_map [ppn ].pte4 = pte ;
226
+ page_map [ppn ].daddr = daddr ;
227
+
228
+ return ;
229
+ }
184
230
185
231
// 3. no free nor clean physical page: select one LRU victim
186
232
// write back (swap out) the DIRTY victim to disk
233
+ lru_ppn = -1 ;
234
+ lru_time = -1 ;
235
+ for (int i = 0 ; i < MAX_NUM_PHYSICAL_PAGE ; ++ i )
236
+ {
237
+ if (lru_time < page_map [i ].time )
238
+ {
239
+ lru_time = page_map [i ].time ;
240
+ lru_ppn = i ;
241
+ }
242
+ }
243
+
244
+ assert (0 <= lru_ppn && lru_ppn < MAX_NUM_PHYSICAL_PAGE );
245
+
246
+ ppn = lru_ppn ;
247
+
248
+ // reversed mapping
249
+ victim = page_map [ppn ].pte4 ;
250
+
251
+ // write back
252
+ swap_out (page_map [ppn ].daddr , ppn );
253
+
254
+ victim -> pte_value = 0 ;
255
+ victim -> present = 0 ;
256
+ victim -> daddr = page_map [ppn ].daddr ;
257
+
258
+ // load page from disk to physical memory first
259
+ daddr = pte -> daddr ;
260
+ swap_in (daddr , ppn );
261
+
262
+ pte -> pte_value = 0 ;
263
+ pte -> present = 1 ;
264
+ pte -> ppn = ppn ;
265
+ pte -> dirty = 0 ;
266
+
267
+ page_map [ppn ].allocated = 1 ;
268
+ page_map [ppn ].time = 0 ;
269
+ page_map [ppn ].dirty = 0 ;
270
+ page_map [ppn ].pte4 = pte ;
271
+ page_map [ppn ].daddr = daddr ;
187
272
}
0 commit comments