5 int sequence_length
= 16;
6 int sequence
[] = { 0, 1, 1, 2, 3,
8 55, 89, 144, 233, 377, 610};
11 mark_page(int* pg
, int i
) {
12 memset(pg
, 0, PGSIZE
);
14 // now dump a non-random sequence into the page
17 for (j
= 0; j
< sequence_length
; j
++)
18 pg
[j
] = i
+ sequence
[j
];
22 test_page(int* pg
, int i
) {
24 for (j
= 0; j
< sequence_length
; j
++)
25 if (pg
[j
] != i
+ sequence
[j
])
32 print_marked_page(int* pg
) {
34 for (j
= 0; j
< (sequence_length
-1); j
++)
35 cprintf("%d, ", pg
[j
]);
41 print_expected_mark(int i
) {
43 for (j
= 0; j
< (sequence_length
-1); j
++)
44 cprintf("%d, ", sequence
[j
]+i
);
46 cprintf("%d", sequence
[j
]+i
);
49 int n
, va
, r
, initva
, maxpa
, maxva
, maxnum
, failures
;
53 alloc_range(int initaddr
, int maxpa
, int startn
) {
55 maxnum
= maxpa
/ PGSIZE
;
57 maxva
= initva
+ maxpa
;
59 cprintf ("[%08x] trying to alloc pages in range [%08x, %08x]\n", env
->env_id
, initva
, maxva
);
61 // how many pages can I alloc?
62 // - limit to 256 M worth of pages
63 for (va
= initva
; va
< maxva
; va
+= PGSIZE
, n
++) {
65 if ((r
= sys_mem_alloc(0, va
, PTE_P
| PTE_U
| PTE_W
| PTE_AVAIL
)) < 0) {
66 //cprintf("\nsys_mem_alloc failed: %e", r);
71 //*page_id = n; // mark this page...
72 //memset((int*)va, n, PGSIZE / sizeof(int));
73 mark_page((int*)va
, n
);
75 if ( (((va
- initva
) / PGSIZE
) % 128) == 0) cprintf(".");
79 cprintf("[%08x] able to allocate [%d] pages of requested [%d] pages\n", env
->env_id
, n
, maxnum
);
86 test_range(int startva
, int endva
, int startn
) {
88 cprintf("[%08x] testing pages in [%08x, %08x] to see if they look okay\n", env
->env_id
, startva
, endva
);
91 for (va
= startva
, c
= 0; va
< endva
; va
+= PGSIZE
, n
++, c
++) {
94 if (test_page((int*)va
, n
)) {
95 cprintf("\n[%08x] unexpected value at [%08x]:\n {", env
->env_id
, va
);
96 print_marked_page((int*)va
);
97 cprintf("} should be\n {");
98 print_expected_mark(n
);
103 Pte pte
= vpt
[VPN(va
)];
104 int perm
= (PTE_U
| PTE_P
| PTE_W
| PTE_AVAIL
);
106 if ((pte
& perm
) != perm
) {
107 cprintf("\n[%08x] unexpected PTE permissions [04x] for address [%08x]\n {", env
->env_id
, pte
& perm
, va
);
111 // cprintf("\n value at [%08x]: {", va);
112 //print_marked_page((int*)va);
113 //cprintf("} should be {");
114 //print_expected_mark(n);
118 if ( (((va
- startva
) / PGSIZE
) % 128) == 0) cprintf(".");
119 //if ((va % PDMAP) == 0) cprintf(".");
123 cprintf("[%08x] tested %d pages: %d failed assertions.\n", env
->env_id
, c
, failures
);
129 unmap_range(int startva
, int endva
) {
130 cprintf("[%08x] unmapping range [%08x, %08x].\n", env
->env_id
, startva
, endva
);
132 for (z
=0, xva
= startva
; xva
< endva
; xva
+= PGSIZE
, z
++) {
133 sys_mem_unmap(0, xva
);
135 cprintf("[%08x] unmapped %d pages.\n", env
->env_id
, z
);
139 duplicate_range(int startva
, int dupeva
, int nbytes
) {
140 cprintf("[%08x] duplicating range [%08x, %08x] at [%08x, %08x]\n",
141 env
->env_id
, startva
, startva
+nbytes
, dupeva
, dupeva
+nbytes
);
143 for (xva
= 0, k
= 0; xva
< nbytes
; xva
+= PGSIZE
, k
+=PGSIZE
) {
144 if ((r
= sys_mem_map(0, startva
+xva
, 0, dupeva
+xva
, PTE_P
| PTE_U
| PTE_W
| PTE_USER
)) < 0) {
145 cprintf ("[%08x] duplicate_range FAILURE: %e\n", env
->env_id
, r
);
153 // This tries to stress test the pmap code...
154 // Not the most intelligent testing strategy,
155 // just hammer at it and see if it breaks.
157 umain(int argc
, char **argv
)
159 int max
, max2
, k
, j
, i
, dupesize
, dupen
;
161 for (i
= 0; i
< 2; i
++) { // might as well do this multiple times to stress the system...
162 cprintf("PMAPTEST[%08x] starting ROUND %d.\n", env
->env_id
, i
);
164 // Try to allocate as many pages as possible...
165 k
= alloc_range(UTEXT
+PDMAP
, (256 * 1024 * 1024), 0); // alloc as many as possible
166 max
= maxva
; // save maximum memory size
167 test_range(UTEXT
+PDMAP
, max
, 0); // test if all are unique pages
169 // If we've corrupted kernel memory, a yield might expose a problem.
170 cprintf("PMAPTEST[%08x] yielding...\n", env
->env_id
);
172 cprintf("PMAPTEST[%08x] back.\n", env
->env_id
);
174 // Free a couple of pages for use by page tables and other envs...
175 unmap_range(max
-16 * PGSIZE
, max
); // free some pages so we have wiggle room, if extra
176 max
-= 16 * PGSIZE
; // pages are needed for page tables...
178 // Unmap last 1024 pages and then try to reallocate them in the same place
179 unmap_range(max
- PDMAP
, max
); // unmap last 1024 pages
180 j
= alloc_range(max
- PDMAP
, PDMAP
, 0); // try to realloc them (<1024 if other envs alloc'd)
181 max2
= maxva
; // max2 <= max && max2 >= (max - PDMAP)
182 test_range(max
- PDMAP
, max2
, 0); // test if new pages are unique
184 // Create duplicate mappings of the last 1024
185 dupesize
= duplicate_range(max2
-PDMAP
, max
+PDMAP
, j
*PGSIZE
); // create duplicate mappings
186 test_range(max2
-PDMAP
, max2
-PDMAP
+dupesize
, 0); // test lower mapping
187 test_range(max
+PDMAP
, max
+ PDMAP
+ dupesize
, 0); // test upper mapping
188 dupen
= *((int*)(max
+PDMAP
));
190 // Remove one of the duplicate mappings and then unmap and realloc the last 1024 pages
191 unmap_range(max2
-PDMAP
, max2
-PDMAP
+dupesize
); // unmap lower mapping
192 j
= alloc_range(max2
-PDMAP
, PDMAP
, 0); // try to alloc something, should be below 1024 (really? other envs?)
193 unmap_range(max2
-2*PDMAP
, max2
- PDMAP
); // free 1024 pages
194 j
= alloc_range(max2
-2*PDMAP
, PDMAP
, 0); // alloc new pages for free'd 1024
195 //max2 = maxva; // max2 <= old_max2 - PDMAP
198 test_range(UTEXT
+PDMAP
, max2
-2*PDMAP
, 0); // test entire lower range of pages
199 test_range(max2
-2*PDMAP
, maxva
, 0); // test entire lower range of pages
200 test_range(max
+PDMAP
, max
+ PDMAP
+ dupesize
, dupen
); // test upper range
203 unmap_range(UTEXT
+PDMAP
, maxva
);
204 unmap_range(max
+PDMAP
, max
+PDMAP
+dupesize
);
206 //unmap_range(UTEXT+PDMAP, max);