-
Notifications
You must be signed in to change notification settings - Fork 0
/
mmu_manager.c
110 lines (82 loc) · 2.72 KB
/
mmu_manager.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "hardware.h"
#include "hw_config.h"
static FILE *swap_file;
int victime_rr = 1;
struct vm_mapping_s vm_mapping[VM_PAGES];
struct pm_mapping_s pm_mapping[PM_PAGES];
static char init_swap(char* path)
{
swap_file = fopen(path, "w+");
assert(swap_file != NULL);
fseek(swap_file, VM_SIZE, SEEK_SET);
fwrite("", 1, 1, swap_file);
return 0;
}
static char store_to_swap(int vpage, int ppage)
{
fseek(swap_file, vpage*PAGE_SIZE, SEEK_SET);
fwrite((char*)((int)physical_memory + (ppage << 12)), PAGE_SIZE, 1, swap_file);
return 0;
}
static char fetch_from_swap(int vpage, int ppage)
{
fseek(swap_file, vpage*PAGE_SIZE, SEEK_SET);
fread((char*)((int)physical_memory + (ppage << 12)), PAGE_SIZE, 1, swap_file);
return 0;
}
static void mmuhandler()
{
int fault = _in(MMU_FAULT_ADDR);
struct tlb_entry_s tlb_entry;
assert(fault >= (int)virtual_memory && fault <= (int)virtual_memory + VM_SIZE - 1);
tlb_entry.tlbe_cfu = 0;
tlb_entry.tlbe_x_access = 1;
tlb_entry.tlbe_w_access = 1;
tlb_entry.tlbe_r_access = 1;
tlb_entry.tlbe_used = 1;
if(vm_mapping[vpage_of_vaddr(fault)].mapped)
{
tlb_entry.tlbe_physical_page = vm_mapping[vpage_of_vaddr(fault)].ppage;
tlb_entry.tlbe_virtual_page = vpage_of_vaddr(fault);
_out(TLB_ADD_ENTRY, *((int*)&tlb_entry));
return;
}
if(pm_mapping[victime_rr].mapped)
{
store_to_swap(pm_mapping[victime_rr].vpage, victime_rr);
pm_mapping[victime_rr].mapped = 0;
vm_mapping[pm_mapping[victime_rr].vpage].mapped = 0;
tlb_entry.tlbe_physical_page = victime_rr;
_out(TLB_DEL_ENTRY, *((int*)&tlb_entry));
}
fetch_from_swap(vpage_of_vaddr(fault), victime_rr);
pm_mapping[victime_rr].mapped = 1;
pm_mapping[victime_rr].vpage = vpage_of_vaddr(fault);
vm_mapping[vpage_of_vaddr(fault)].mapped = 1;
vm_mapping[vpage_of_vaddr(fault)].ppage = victime_rr;
tlb_entry.tlbe_physical_page = victime_rr;
tlb_entry.tlbe_virtual_page = vpage_of_vaddr(fault);
_out(TLB_ADD_ENTRY, *((int*)&tlb_entry));
victime_rr = (victime_rr % 255) + 1;
return;
}
int main(int argc, char **argv)
{
/* init hardware */
if(init_hardware("hardware.ini") == 0)
{
fprintf(stderr, "Error in hardware initialization\n");
exit(EXIT_FAILURE);
}
init_swap("swapfile");
memset(vm_mapping, 0, sizeof(struct vm_mapping_s) * VM_PAGES);
memset(pm_mapping, 0, sizeof(struct pm_mapping_s) * PM_PAGES);
IRQVECTOR[MMU_IRQ] = mmuhandler;
_mask(0x1001);
user_process();
return 0;
}