2020static uint64_t page_walk (uint64_t vaddr_value );
2121static void page_fault_handler (pte4_t * pte , address_t vaddr );
2222
23+ int swap_in (uint64_t daddr , uint64_t ppn );
24+ int swap_out (uint64_t daddr , uint64_t ppn );
25+
2326// consider this function va2pa as functional
2427uint64_t va2pa (uint64_t vaddr )
2528{
@@ -151,9 +154,12 @@ static uint64_t page_walk(uint64_t vaddr_value)
151154static void page_fault_handler (pte4_t * pte , address_t vaddr )
152155{
153156 // select one victim physical page to swap to disk
157+ assert (pte -> present == 0 );
154158
155159 // this is the selected ppn for vaddr
156160 int ppn = -1 ;
161+ pte4_t * victim = NULL ;
162+ uint64_t daddr = 0xffffffffffffffff ;
157163
158164 // 1. try to request one free physical page from DRAM
159165 // kernel's responsibility
@@ -181,7 +187,86 @@ static void page_fault_handler(pte4_t *pte, address_t vaddr)
181187
182188 // 2. no free physical page: select one clean page (LRU) and overwrite
183189 // 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+ }
184230
185231 // 3. no free nor clean physical page: select one LRU victim
186232 // 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 ;
187272}
0 commit comments