annotate src/impl/vm_impl_private.cbc @ 214:90b65036d9a2

paging_init
author tobaru
date Fri, 24 Jan 2020 18:33:52 +0900
parents 7a4d299a35be
children 37900976db8e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
193
1301727600cc success build
anatofuz
parents:
diff changeset
1 #include "../../context.h"
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
2 #include "mmu.h"
213
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
3 #include "defs.h"
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
4 #include "memlayout.h"
193
1301727600cc success build
anatofuz
parents:
diff changeset
5 #interface "vm_impl.h"
1301727600cc success build
anatofuz
parents:
diff changeset
6
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
7 /*
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
8 vm_impl* createvm_impl2();
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
9 */
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
10
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
11 __code loaduvm_ptesize_checkvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
12 char* addr = vm_impl->addr;
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
13
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
14 if ((uint) addr %PTE_SZ != 0) {
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
15 // goto panic
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
16 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
17
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
18 goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
193
1301727600cc success build
anatofuz
parents:
diff changeset
19 }
1301727600cc success build
anatofuz
parents:
diff changeset
20
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
21 __code loaduvm_loopvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
22 uint i = vm_impl->i;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
23 uint sz = vm_impl->sz;
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
24
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
25 if (i < sz) {
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
26 goto loaduvm_check_pgdir(vm_impl, next(ret, ...));
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
27 }
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
28
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
29 goto loaduvm_exit(vm_impl, next(ret, ...));
193
1301727600cc success build
anatofuz
parents:
diff changeset
30 }
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
31
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
32
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
33 static pte_t* walkpgdir (pde_t *pgdir, const void *va, int alloc)
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
34 {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
35 pde_t *pde;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
36 pte_t *pgtab;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
37
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
38 // pgdir points to the page directory, get the page direcotry entry (pde)
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
39 pde = &pgdir[PDE_IDX(va)];
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
40
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
41 if (*pde & PE_TYPES) {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
42 pgtab = (pte_t*) p2v(PT_ADDR(*pde));
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
43
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
44 } else {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
45 if (!alloc || (pgtab = (pte_t*) kpt_alloc()) == 0) {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
46 return 0;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
47 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
48
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
49 // Make sure all those PTE_P bits are zero.
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
50 memset(pgtab, 0, PT_SZ);
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
51
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
52 // The permissions here are overly generous, but they can
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
53 // be further restricted by the permissions in the page table
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
54 // entries, if necessary.
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
55 *pde = v2p(pgtab) | UPDE_TYPE;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
56 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
57
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
58 return &pgtab[PTE_IDX(va)];
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
59 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
60
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
61
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
62 __code loaduvm_check_pgdir(struct vm_impl* vm_impl, __code next(int ret, ...)) {
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
63 pte_t* pte = vm_impl->pte;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
64 pde_t* pgdir = vm_impl->pgdir;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
65 uint i = vm_impl->i;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
66 char* addr = vm_impl->addr;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
67 uint pa = vm_impl->pa;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
68
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
69 if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
70 // goto panic
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
71 }
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
72 pa = PTE_ADDR(*pte);
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
73
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
74 vm_impl->pte = pte;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
75 vm_impl->pgdir = pgdir;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
76 vm_impl->addr = addr;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
77 vm_impl->pa = pa;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
78
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
79 goto loaduvm_check_PTE_SZ(vm_impl, next(ret, ...));
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
80 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
81
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
82 __code loaduvm_check_PTE_SZ(struct vm_impl* vm_impl, __code next(int ret, ...)) {
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
83 uint sz = vm_impl->sz;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
84 uint i = vm_impl->i;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
85 uint n = vm_impl->n;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
86 struct inode* ip = vm_impl->ip;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
87 uint pa = vm_impl->pa;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
88 uint offset = vm_impl->offset;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
89
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
90 if (sz - i < PTE_SZ) {
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
91 n = sz - i;
199
8a55878f6a25 loaduvm
tobaru
parents: 198
diff changeset
92 } else {
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
93 n = PTE_SZ;
199
8a55878f6a25 loaduvm
tobaru
parents: 198
diff changeset
94 }
8a55878f6a25 loaduvm
tobaru
parents: 198
diff changeset
95
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
96 if (readi(ip, p2v(pa), offset + i, n) != n) {
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
97 ret = -1;
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
98 goto next(ret, ...);
199
8a55878f6a25 loaduvm
tobaru
parents: 198
diff changeset
99 }
8a55878f6a25 loaduvm
tobaru
parents: 198
diff changeset
100
200
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
101 vm_impl->n = n;
a0620ca23f19 be functional loaduvm
tobaru
parents: 199
diff changeset
102
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
103 goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
104 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
105
210
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
106 __code loaduvm_exit(struct vm_impl* vm_impl, __code next(int ret, ...)) {
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
107 ret = 0;
b8597756f701 fix loaduvm loop
tobaru
parents: 209
diff changeset
108 goto next(ret, ...);
198
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 197
diff changeset
109 }
202
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 200
diff changeset
110
203
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
111 struct run {
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
112 struct run *next;
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
113 };
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
114
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
115 struct {
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
116 struct spinlock lock;
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
117 struct run* freelist;
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
118 } kpt_mem;
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
119
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
120
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
121 static int mappages (pde_t *pgdir, void *va, uint size, uint pa, int ap)
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
122 {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
123 char *a, *last;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
124 pte_t *pte;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
125
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
126 a = (char*) align_dn(va, PTE_SZ);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
127 last = (char*) align_dn((uint)va + size - 1, PTE_SZ);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
128
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
129 for (;;) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
130 if ((pte = walkpgdir(pgdir, a, 1)) == 0) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
131 return -1;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
132 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
133
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
134 if (*pte & PE_TYPES) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
135 panic("remap");
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
136 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
137
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
138 *pte = pa | ((ap & 0x3) << 4) | PE_CACHE | PE_BUF | PTE_TYPE;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
139
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
140 if (a == last) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
141 break;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
142 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
143
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
144 a += PTE_SZ;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
145 pa += PTE_SZ;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
146 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
147
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
148 return 0;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
149 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
150
202
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 200
diff changeset
151 __code kpt_alloc_check_impl(struct vm_impl* vm_impl, __code next(...)) {
203
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
152 struct run* r;
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
153 if ((r = kpt_mem.freelist) != NULL ) {
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
154 kpt_mem.freelist = r->next;
6e03cee9733e can use r
tobaru
parents: 202
diff changeset
155 }
204
f4effd36aefc kpt_alloc
tobaru
parents: 203
diff changeset
156 release(&kpt_mem.lock);
202
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 200
diff changeset
157
204
f4effd36aefc kpt_alloc
tobaru
parents: 203
diff changeset
158 if ((r == NULL) && ((r = kmalloc (PT_ORDER)) == NULL)) {
f4effd36aefc kpt_alloc
tobaru
parents: 203
diff changeset
159 // panic("oom: kpt_alloc");
f4effd36aefc kpt_alloc
tobaru
parents: 203
diff changeset
160 // goto panic
f4effd36aefc kpt_alloc
tobaru
parents: 203
diff changeset
161 }
f4effd36aefc kpt_alloc
tobaru
parents: 203
diff changeset
162
f4effd36aefc kpt_alloc
tobaru
parents: 203
diff changeset
163 memset(r, 0, PT_SZ);
202
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 200
diff changeset
164 goto next((char*)r);
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 200
diff changeset
165 }
205
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
166
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
167 __code allocuvm_check_newszvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, __code next(int ret, ...)){
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
168 if (newsz >= UADDR_SZ) {
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
169 goto next(0, ...);
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
170 }
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
171
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
172 if (newsz < oldsz) {
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
173 ret = newsz;
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
174 goto next(ret, ...);
205
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
175 }
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
176
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
177 char* mem;
205
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
178 uint a = align_up(oldsz, PTE_SZ);
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
179
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
180 goto allocuvm_loopvm_impl(vm_impl, pgdir, oldsz, newsz, mem, a, next(ret, ...));
205
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
181 }
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
182
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
183 __code allocuvm_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, char* mem, uint a, __code next(int ret, ...)){
205
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
184
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
185 if (a < newsz) {
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
186 mem = alloc_page();
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
187
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
188 if (mem == 0) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
189 cprintf("allocuvm out of memory\n");
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
190 deallocuvm(pgdir, newsz, oldsz);
207
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
191 goto next(0, ...);
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
192 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
193
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
194 memset(mem, 0, PTE_SZ);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
195 mappages(pgdir, (char*) a, PTE_SZ, v2p(mem), AP_KU);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
196
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
197 goto allocuvm_loopvm_impl(vm_impl, pgdir, oldsz, newsz, a + PTE_SZ, next(ret, ...));
205
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
198 }
206
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
199 ret = newsz;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 205
diff changeset
200 goto next(ret, ...);
205
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 204
diff changeset
201 }
207
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
202
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
203 __code clearpteu_check_ptevm_impl(struct vm_impl* vm_impl, pde_t* pgdir, char* uva, __code next(int ret, ...)) {
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
204 pte_t *pte;
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
205
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
206 pte = walkpgdir(pgdir, uva, 0);
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
207 if (pte == 0) {
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
208 // panic("clearpteu");
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
209 // goto panic;
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
210 }
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
211
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
212 // in ARM, we change the AP field (ap & 0x3) << 4)
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
213 *pte = (*pte & ~(0x03 << 4)) | AP_KO << 4;
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
214
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
215 goto next(ret, ...);
0f1700bd5cff cleapteu
tobaru
parents: 206
diff changeset
216 }
208
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
217
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
218 __code copyuvm_check_nullvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, __code next(int ret, ...)) {
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
219 pde_t *d;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
220 pte_t *pte;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
221 uint pa, i, ap;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
222 char *mem;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
223
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
224 // allocate a new first level page directory
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
225 d = kpt_alloc();
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
226 if (d == NULL ) {
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
227 ret = NULL;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
228 goto next(ret, ...);
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
229 }
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
230 i = 0;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
231
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
232 goto copyuvm_loopvm_impl(vm_impl, pgdir, sz, *d, *pte, pa, i, ap, *mem, next(ret, ...));
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
233 }
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
234
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
235 __code copyuvm_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
236
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
237 if (i < sz) {
209
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
238 goto copyuvm_loop_check_walkpgdir(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
208
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
239
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
240 }
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
241 ret = d;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
242 goto next(ret, ...);
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
243 }
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
244
209
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
245 __code copyuvm_loop_check_walkpgdir(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
246 if ((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
247 // panic("copyuvm: pte should exist");
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
248 // goto panic();
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
249 }
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
250 goto copyuvm_loop_check_pte(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
251 }
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
252
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
253 __code copyuvm_loop_check_pte(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
254
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
255 if (!(*pte & PE_TYPES)) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
256 // panic("copyuvm: page not present");
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
257 // goto panic();
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
258 }
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
259
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
260 goto copyuvm_loop_check_mem(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
261 }
208
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
262
209
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
263 __code copyuvm_loop_check_mem(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
264 pa = PTE_ADDR (*pte);
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
265 ap = PTE_AP (*pte);
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
266
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
267 if ((mem = alloc_page()) == 0) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
268 goto copyuvm_loop_bad(vm_impl, d, next(...));
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
269 }
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
270 goto copyuvm_loop_check_mappages(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
271
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
272 }
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
273
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
274 __code copyuvm_loop_check_mappages(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
275
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
276 memmove(mem, (char*) p2v(pa), PTE_SZ);
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
277
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
278 if (mappages(d, (void*) i, PTE_SZ, v2p(mem), ap) < 0) {
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
279 goto copyuvm_loop_bad(vm_impl, d, next(...));
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
280 }
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
281 goto copyuvm_loopvm_impl(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 208
diff changeset
282
208
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
283 }
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
284
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
285 __code copyuvm_loop_bad(struct vm_impl* vm_impl, pde_t* d, __code next(int ret, ...)) {
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
286 freevm(d);
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
287 ret = 0;
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
288 goto next(ret, ...);
f940ff602312 copyuvm_loop
tobaru
parents: 207
diff changeset
289 }
211
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
290
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
291
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
292 __code uva2ka_check_pe_types(struct vm_impl* vm, pde_t* pgdir, char* uva, __code next(int ret, ...)) {
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
293 pte_t* pte;
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
294
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
295 pte = walkpgdir(pgdir, uva, 0);
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
296
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
297 // make sure it exists
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
298 if ((*pte & PE_TYPES) == 0) {
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
299 ret = 0;
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
300 goto next(ret, ...);
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
301 }
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
302 goto uva2ka_check_pte_ap(vm, pgdir, uva, pte, next(...));
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
303 }
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
304
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
305 __code uva2ka_check_pte_ap(struct vm_impl* vm, pde_t* pgdir, char* uva, pte_t* pte, __code next(int ret, ...)) {
212
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 211
diff changeset
306 // make sure it is a user page
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 211
diff changeset
307 if (PTE_AP(*pte) != AP_KU) {
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 211
diff changeset
308 ret = 0;
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 211
diff changeset
309 goto next(ret, ...);
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 211
diff changeset
310 }
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 211
diff changeset
311 ret = (char*) p2v(PTE_ADDR(*pte));
211
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
312 goto next(ret, ...);
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
313 }
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 210
diff changeset
314
213
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
315 // flush all TLB
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
316 static void flush_tlb (void)
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
317 {
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
318 uint val = 0;
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
319 asm("MCR p15, 0, %[r], c8, c7, 0" : :[r]"r" (val):);
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
320
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
321 // invalid entire data and instruction cache
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
322 asm ("MCR p15,0,%[r],c7,c10,0": :[r]"r" (val):);
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
323 asm ("MCR p15,0,%[r],c7,c11,0": :[r]"r" (val):);
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
324 }
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
325
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
326 __code paging_intvmvm_impl(struct vm_impl* vm_impl, uint phy_low, uint phy_hi, __code next(...)) {
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
327 mappages (P2V(&_kernel_pgtbl), P2V(phy_low), phy_hi - phy_low, phy_low, AP_KU);
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
328 flush_tlb ();
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
329
214
90b65036d9a2 paging_init
tobaru
parents: 213
diff changeset
330 goto next(...);
213
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
331 }
7a4d299a35be paging_init
tobaru
parents: 212
diff changeset
332
214
90b65036d9a2 paging_init
tobaru
parents: 213
diff changeset
333 __code copyout_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, __code next(...)) {
90b65036d9a2 paging_init
tobaru
parents: 213
diff changeset
334
90b65036d9a2 paging_init
tobaru
parents: 213
diff changeset
335 goto next(...);
90b65036d9a2 paging_init
tobaru
parents: 213
diff changeset
336 }
90b65036d9a2 paging_init
tobaru
parents: 213
diff changeset
337
90b65036d9a2 paging_init
tobaru
parents: 213
diff changeset
338