annotate src/impl/vm_impl_private.cbc @ 210:b8597756f701

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