t_uvm_physseg.c revision 1.1 1 1.1 cherry /* $NetBSD: t_uvm_physseg.c,v 1.1 2016/12/19 12:21:29 cherry Exp $ */
2 1.1 cherry
3 1.1 cherry /*-
4 1.1 cherry * Copyright (c) 2015, 2016 The NetBSD Foundation, Inc.
5 1.1 cherry * All rights reserved.
6 1.1 cherry *
7 1.1 cherry * This code is derived from software contributed to The NetBSD Foundation
8 1.1 cherry * by Santhosh N. Raju <santhosh.raju (at) gmail.com> and
9 1.1 cherry * by Cherry G. Mathew
10 1.1 cherry *
11 1.1 cherry * Redistribution and use in source and binary forms, with or without
12 1.1 cherry * modification, are permitted provided that the following conditions
13 1.1 cherry * are met:
14 1.1 cherry * 1. Redistributions of source code must retain the above copyright
15 1.1 cherry * notice, this list of conditions and the following disclaimer.
16 1.1 cherry * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 cherry * notice, this list of conditions and the following disclaimer in the
18 1.1 cherry * documentation and/or other materials provided with the distribution.
19 1.1 cherry *
20 1.1 cherry * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 1.1 cherry * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 1.1 cherry * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 1.1 cherry * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 1.1 cherry * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.1 cherry * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.1 cherry * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 1.1 cherry * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 1.1 cherry * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.1 cherry * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 1.1 cherry * POSSIBILITY OF SUCH DAMAGE.
31 1.1 cherry */
32 1.1 cherry
33 1.1 cherry #include <sys/cdefs.h>
34 1.1 cherry __RCSID("$NetBSD: t_uvm_physseg.c,v 1.1 2016/12/19 12:21:29 cherry Exp $");
35 1.1 cherry
36 1.1 cherry /* Testing API - assumes userland */
37 1.1 cherry /* Provide Kernel API equivalents */
38 1.1 cherry #include <assert.h>
39 1.1 cherry #include <errno.h>
40 1.1 cherry #include <stdbool.h>
41 1.1 cherry #include <string.h> /* memset(3) et. al */
42 1.1 cherry #include <stdio.h> /* printf(3) */
43 1.1 cherry #include <stdlib.h> /* malloc(3) */
44 1.1 cherry #include <stdarg.h>
45 1.1 cherry #include <stddef.h>
46 1.1 cherry
47 1.1 cherry #define PRIxPADDR "lx"
48 1.1 cherry #define PRIxPSIZE "lx"
49 1.1 cherry #define PRIuPSIZE "lu"
50 1.1 cherry #define PRIxVADDR "lx"
51 1.1 cherry #define PRIxVSIZE "lx"
52 1.1 cherry #define PRIuVSIZE "lu"
53 1.1 cherry
54 1.1 cherry #define UVM_HOTPLUG /* Enable hotplug with rbtree. */
55 1.1 cherry #define PMAP_STEAL_MEMORY
56 1.1 cherry #define DEBUG /* Enable debug functionality. */
57 1.1 cherry
58 1.1 cherry typedef unsigned long vaddr_t;
59 1.1 cherry typedef unsigned long paddr_t;
60 1.1 cherry typedef unsigned long psize_t;
61 1.1 cherry typedef unsigned long vsize_t;
62 1.1 cherry
63 1.1 cherry #include <uvm/uvm_page.h>
64 1.1 cherry
65 1.1 cherry /*
66 1.1 cherry * If this line is commented out tests related to uvm_physseg_get_pmseg()
67 1.1 cherry * wont run.
68 1.1 cherry *
69 1.1 cherry * Have a look at machine/uvm_physseg.h for more details.
70 1.1 cherry */
71 1.1 cherry #define __HAVE_PMAP_PHYSSEG
72 1.1 cherry
73 1.1 cherry #include <uvm/uvm_physseg.h>
74 1.1 cherry
75 1.1 cherry /*
76 1.1 cherry * This is a dummy struct used for testing purposes
77 1.1 cherry *
78 1.1 cherry * In reality this struct would exist in the MD part of the code residing in
79 1.1 cherry * machines/vmparam.h
80 1.1 cherry */
81 1.1 cherry
82 1.1 cherry #ifdef __HAVE_PMAP_PHYSSEG
83 1.1 cherry struct pmap_physseg {
84 1.1 cherry bool dummy_variable; /* Dummy variable use for testing */
85 1.1 cherry };
86 1.1 cherry #endif
87 1.1 cherry
88 1.1 cherry #ifndef DIAGNOSTIC
89 1.1 cherry #define KASSERTMSG(e, msg, ...) /* NOTHING */
90 1.1 cherry #define KASSERT(e) /* NOTHING */
91 1.1 cherry #else
92 1.1 cherry #define KASSERT(a) assert(a)
93 1.1 cherry #define KASSERTMSG(exp, ...) printf(__VA_ARGS__); assert((exp))
94 1.1 cherry #endif
95 1.1 cherry
96 1.1 cherry #define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
97 1.1 cherry
98 1.1 cherry #define VM_NFREELIST 4
99 1.1 cherry #define VM_FREELIST_DEFAULT 0
100 1.1 cherry #define VM_FREELIST_FIRST16 3
101 1.1 cherry #define VM_FREELIST_FIRST1G 2
102 1.1 cherry #define VM_FREELIST_FIRST4G 1
103 1.1 cherry
104 1.1 cherry /*
105 1.1 cherry * Used in tests when Array implementation is tested
106 1.1 cherry */
107 1.1 cherry #if !defined(VM_PHYSSEG_MAX)
108 1.1 cherry #define VM_PHYSSEG_MAX 1
109 1.1 cherry #endif
110 1.1 cherry
111 1.1 cherry #define PAGE_SHIFT 12
112 1.1 cherry #define PAGE_SIZE (1 << PAGE_SHIFT)
113 1.1 cherry #define PAGE_MASK (PAGE_SIZE - 1)
114 1.1 cherry #define atop(x) (((paddr_t)(x)) >> PAGE_SHIFT)
115 1.1 cherry #define ptoa(x) (((paddr_t)(x)) << PAGE_SHIFT)
116 1.1 cherry
117 1.1 cherry #define mutex_enter(l)
118 1.1 cherry #define mutex_exit(l)
119 1.1 cherry
120 1.1 cherry psize_t physmem;
121 1.1 cherry
122 1.1 cherry struct uvmexp uvmexp; /* decl */
123 1.1 cherry
124 1.1 cherry /*
125 1.1 cherry * uvm structure borrowed from uvm.h
126 1.1 cherry *
127 1.1 cherry * Remember this is a dummy structure used within the ATF Tests and
128 1.1 cherry * uses only necessary fields from the original uvm struct.
129 1.1 cherry * See uvm/uvm.h for the full struct.
130 1.1 cherry */
131 1.1 cherry
132 1.1 cherry struct uvm {
133 1.1 cherry /* vm_page related parameters */
134 1.1 cherry
135 1.1 cherry bool page_init_done; /* TRUE if uvm_page_init() finished */
136 1.1 cherry } uvm;
137 1.1 cherry
138 1.1 cherry #include <sys/kmem.h>
139 1.1 cherry
140 1.1 cherry void *
141 1.1 cherry kmem_alloc(size_t size, km_flag_t flags)
142 1.1 cherry {
143 1.1 cherry return malloc(size);
144 1.1 cherry }
145 1.1 cherry
146 1.1 cherry void *
147 1.1 cherry kmem_zalloc(size_t size, km_flag_t flags)
148 1.1 cherry {
149 1.1 cherry void *ptr;
150 1.1 cherry ptr = malloc(size);
151 1.1 cherry
152 1.1 cherry memset(ptr, 0, size);
153 1.1 cherry
154 1.1 cherry return ptr;
155 1.1 cherry }
156 1.1 cherry
157 1.1 cherry void
158 1.1 cherry kmem_free(void *mem, size_t size)
159 1.1 cherry {
160 1.1 cherry free(mem);
161 1.1 cherry }
162 1.1 cherry
163 1.1 cherry static void
164 1.1 cherry panic(const char *fmt, ...)
165 1.1 cherry {
166 1.1 cherry va_list ap;
167 1.1 cherry
168 1.1 cherry va_start(ap, fmt);
169 1.1 cherry vprintf(fmt, ap);
170 1.1 cherry printf("\n");
171 1.1 cherry va_end(ap);
172 1.1 cherry KASSERT(false);
173 1.1 cherry
174 1.1 cherry /*NOTREACHED*/
175 1.1 cherry }
176 1.1 cherry
177 1.1 cherry static void
178 1.1 cherry uvm_pagefree(struct vm_page *pg)
179 1.1 cherry {
180 1.1 cherry return;
181 1.1 cherry }
182 1.1 cherry
183 1.1 cherry #if defined(UVM_HOTPLUG)
184 1.1 cherry static void
185 1.1 cherry uvmpdpol_reinit(void)
186 1.1 cherry {
187 1.1 cherry return;
188 1.1 cherry }
189 1.1 cherry #endif /* UVM_HOTPLUG */
190 1.1 cherry
191 1.1 cherry /* end - Provide Kernel API equivalents */
192 1.1 cherry
193 1.1 cherry
194 1.1 cherry #include "uvm/uvm_physseg.c"
195 1.1 cherry
196 1.1 cherry #include <atf-c.h>
197 1.1 cherry
198 1.1 cherry #define SIXTYFOUR_KILO (64 * 1024)
199 1.1 cherry #define ONETWENTYEIGHT_KILO (128 * 1024)
200 1.1 cherry #define TWOFIFTYSIX_KILO (256 * 1024)
201 1.1 cherry #define FIVEONETWO_KILO (512 * 1024)
202 1.1 cherry #define ONE_MEGABYTE (1024 * 1024)
203 1.1 cherry #define TWO_MEGABYTE (2 * 1024 * 1024)
204 1.1 cherry
205 1.1 cherry /* Sample Page Frame Numbers */
206 1.1 cherry #define VALID_START_PFN_1 atop(0)
207 1.1 cherry #define VALID_END_PFN_1 atop(ONE_MEGABYTE)
208 1.1 cherry #define VALID_AVAIL_START_PFN_1 atop(0)
209 1.1 cherry #define VALID_AVAIL_END_PFN_1 atop(ONE_MEGABYTE)
210 1.1 cherry
211 1.1 cherry #define VALID_START_PFN_2 atop(ONE_MEGABYTE + 1)
212 1.1 cherry #define VALID_END_PFN_2 atop(ONE_MEGABYTE * 2)
213 1.1 cherry #define VALID_AVAIL_START_PFN_2 atop(ONE_MEGABYTE + 1)
214 1.1 cherry #define VALID_AVAIL_END_PFN_2 atop(ONE_MEGABYTE * 2)
215 1.1 cherry
216 1.1 cherry #define VALID_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1)
217 1.1 cherry #define VALID_END_PFN_3 atop(ONE_MEGABYTE * 3)
218 1.1 cherry #define VALID_AVAIL_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1)
219 1.1 cherry #define VALID_AVAIL_END_PFN_3 atop(ONE_MEGABYTE * 3)
220 1.1 cherry
221 1.1 cherry #define VALID_START_PFN_4 atop((ONE_MEGABYTE * 3) + 1)
222 1.1 cherry #define VALID_END_PFN_4 atop(ONE_MEGABYTE * 4)
223 1.1 cherry #define VALID_AVAIL_START_PFN_4 atop((ONE_MEGABYTE * 3) + 1)
224 1.1 cherry #define VALID_AVAIL_END_PFN_4 atop(ONE_MEGABYTE * 4)
225 1.1 cherry
226 1.1 cherry /*
227 1.1 cherry * Total number of pages (of 4K size each) should be 256 for 1MB of memory.
228 1.1 cherry */
229 1.1 cherry #define PAGE_COUNT_1M 256
230 1.1 cherry
231 1.1 cherry /*
232 1.1 cherry * A debug fucntion to print the content of upm.
233 1.1 cherry */
234 1.1 cherry static inline void
235 1.1 cherry uvm_physseg_dump_seg(uvm_physseg_t upm)
236 1.1 cherry {
237 1.1 cherry #if defined(DEBUG)
238 1.1 cherry printf("%s: seg->start == %ld\n", __func__,
239 1.1 cherry uvm_physseg_get_start(upm));
240 1.1 cherry printf("%s: seg->end == %ld\n", __func__,
241 1.1 cherry uvm_physseg_get_end(upm));
242 1.1 cherry printf("%s: seg->avail_start == %ld\n", __func__,
243 1.1 cherry uvm_physseg_get_avail_start(upm));
244 1.1 cherry printf("%s: seg->avail_end == %ld\n", __func__,
245 1.1 cherry uvm_physseg_get_avail_end(upm));
246 1.1 cherry
247 1.1 cherry printf("====\n\n");
248 1.1 cherry #else
249 1.1 cherry return;
250 1.1 cherry #endif /* DEBUG */
251 1.1 cherry }
252 1.1 cherry
253 1.1 cherry /*
254 1.1 cherry * Private accessor that gets the value of uvm_physseg_graph.nentries
255 1.1 cherry */
256 1.1 cherry static int
257 1.1 cherry uvm_physseg_get_entries(void)
258 1.1 cherry {
259 1.1 cherry #if defined(UVM_HOTPLUG)
260 1.1 cherry return uvm_physseg_graph.nentries;
261 1.1 cherry #else
262 1.1 cherry return vm_nphysmem;
263 1.1 cherry #endif /* UVM_HOTPLUG */
264 1.1 cherry }
265 1.1 cherry
266 1.1 cherry #if !defined(UVM_HOTPLUG)
267 1.1 cherry static void *
268 1.1 cherry uvm_physseg_alloc(size_t sz)
269 1.1 cherry {
270 1.1 cherry return &vm_physmem[vm_nphysseg++];
271 1.1 cherry }
272 1.1 cherry #endif
273 1.1 cherry
274 1.1 cherry /*
275 1.1 cherry * Test Fixture SetUp().
276 1.1 cherry */
277 1.1 cherry static void
278 1.1 cherry setup(void)
279 1.1 cherry {
280 1.1 cherry /* Prerequisites for running certain calls in uvm_physseg */
281 1.1 cherry uvmexp.pagesize = PAGE_SIZE;
282 1.1 cherry uvmexp.npages = 0;
283 1.1 cherry uvm.page_init_done = false;
284 1.1 cherry uvm_physseg_init();
285 1.1 cherry }
286 1.1 cherry
287 1.1 cherry
288 1.1 cherry /* <---- Tests for Internal functions ----> */
289 1.1 cherry #if defined(UVM_HOTPLUG)
290 1.1 cherry ATF_TC(uvm_physseg_alloc_atboot_mismatch);
291 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_atboot_mismatch, tc)
292 1.1 cherry {
293 1.1 cherry atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_alloc() sanity"
294 1.1 cherry "size mismatch alloc() test.");
295 1.1 cherry }
296 1.1 cherry
297 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_atboot_mismatch, tc)
298 1.1 cherry {
299 1.1 cherry uvm.page_init_done = false;
300 1.1 cherry
301 1.1 cherry atf_tc_expect_signal(SIGABRT, "size mismatch alloc()");
302 1.1 cherry
303 1.1 cherry uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1);
304 1.1 cherry }
305 1.1 cherry
306 1.1 cherry ATF_TC(uvm_physseg_alloc_atboot_overrun);
307 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_atboot_overrun, tc)
308 1.1 cherry {
309 1.1 cherry atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_alloc() sanity"
310 1.1 cherry "array overrun alloc() test.");
311 1.1 cherry }
312 1.1 cherry
313 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_atboot_overrun, tc)
314 1.1 cherry {
315 1.1 cherry uvm.page_init_done = false;
316 1.1 cherry
317 1.1 cherry atf_tc_expect_signal(SIGABRT, "array overrun alloc()");
318 1.1 cherry
319 1.1 cherry uvm_physseg_alloc((VM_PHYSSEG_MAX + 1) * sizeof(struct uvm_physseg));
320 1.1 cherry
321 1.1 cherry }
322 1.1 cherry
323 1.1 cherry ATF_TC(uvm_physseg_alloc_sanity);
324 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_sanity, tc)
325 1.1 cherry {
326 1.1 cherry atf_tc_set_md_var(tc, "descr", "further uvm_physseg_alloc() sanity checks");
327 1.1 cherry }
328 1.1 cherry
329 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_sanity, tc)
330 1.1 cherry {
331 1.1 cherry
332 1.1 cherry /* At boot time */
333 1.1 cherry uvm.page_init_done = false;
334 1.1 cherry
335 1.1 cherry /* Correct alloc */
336 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(VM_PHYSSEG_MAX * sizeof(struct uvm_physseg)));
337 1.1 cherry
338 1.1 cherry /* Retry static alloc()s as dynamic - we expect them to pass */
339 1.1 cherry uvm.page_init_done = true;
340 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1));
341 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg)));
342 1.1 cherry }
343 1.1 cherry
344 1.1 cherry ATF_TC(uvm_physseg_free_atboot_mismatch);
345 1.1 cherry ATF_TC_HEAD(uvm_physseg_free_atboot_mismatch, tc)
346 1.1 cherry {
347 1.1 cherry atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_free() sanity"
348 1.1 cherry "size mismatch free() test.");
349 1.1 cherry }
350 1.1 cherry
351 1.1 cherry ATF_TC_BODY(uvm_physseg_free_atboot_mismatch, tc)
352 1.1 cherry {
353 1.1 cherry uvm.page_init_done = false;
354 1.1 cherry
355 1.1 cherry atf_tc_expect_signal(SIGABRT, "size mismatch free()");
356 1.1 cherry
357 1.1 cherry uvm_physseg_free(&uvm_physseg[0], sizeof(struct uvm_physseg) - 1);
358 1.1 cherry }
359 1.1 cherry
360 1.1 cherry ATF_TC(uvm_physseg_free_sanity);
361 1.1 cherry ATF_TC_HEAD(uvm_physseg_free_sanity, tc)
362 1.1 cherry {
363 1.1 cherry atf_tc_set_md_var(tc, "descr", "further uvm_physseg_free() sanity checks");
364 1.1 cherry }
365 1.1 cherry
366 1.1 cherry ATF_TC_BODY(uvm_physseg_free_sanity, tc)
367 1.1 cherry {
368 1.1 cherry
369 1.1 cherry /* At boot time */
370 1.1 cherry uvm.page_init_done = false;
371 1.1 cherry
372 1.1 cherry struct uvm_physseg *seg;
373 1.1 cherry
374 1.1 cherry #if VM_PHYSSEG_MAX > 1
375 1.1 cherry /*
376 1.1 cherry * Note: free()ing the entire array is considered to be an
377 1.1 cherry * error. Thus VM_PHYSSEG_MAX - 1.
378 1.1 cherry */
379 1.1 cherry
380 1.1 cherry seg = uvm_physseg_alloc((VM_PHYSSEG_MAX - 1) * sizeof(*seg));
381 1.1 cherry uvm_physseg_free(seg, (VM_PHYSSEG_MAX - 1) * sizeof(struct uvm_physseg));
382 1.1 cherry #endif
383 1.1 cherry
384 1.1 cherry /* Retry static alloc()s as dynamic - we expect them to pass */
385 1.1 cherry uvm.page_init_done = true;
386 1.1 cherry
387 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1);
388 1.1 cherry uvm_physseg_free(seg, sizeof(struct uvm_physseg) - 1);
389 1.1 cherry
390 1.1 cherry seg = uvm_physseg_alloc(2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg));
391 1.1 cherry
392 1.1 cherry uvm_physseg_free(seg, 2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg));
393 1.1 cherry }
394 1.1 cherry
395 1.1 cherry #if VM_PHYSSEG_MAX > 1
396 1.1 cherry ATF_TC(uvm_physseg_atboot_free_leak);
397 1.1 cherry ATF_TC_HEAD(uvm_physseg_atboot_free_leak, tc)
398 1.1 cherry {
399 1.1 cherry atf_tc_set_md_var(tc, "descr",
400 1.1 cherry "does free() leak at boot ?\n"
401 1.1 cherry "This test needs VM_PHYSSEG_MAX > 1)");
402 1.1 cherry }
403 1.1 cherry
404 1.1 cherry ATF_TC_BODY(uvm_physseg_atboot_free_leak, tc)
405 1.1 cherry {
406 1.1 cherry
407 1.1 cherry /* At boot time */
408 1.1 cherry uvm.page_init_done = false;
409 1.1 cherry
410 1.1 cherry /* alloc to array size */
411 1.1 cherry struct uvm_physseg *seg;
412 1.1 cherry seg = uvm_physseg_alloc(VM_PHYSSEG_MAX * sizeof(*seg));
413 1.1 cherry
414 1.1 cherry uvm_physseg_free(seg, sizeof(*seg));
415 1.1 cherry
416 1.1 cherry atf_tc_expect_signal(SIGABRT, "array overrun on alloc() after leak");
417 1.1 cherry
418 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(sizeof(struct uvm_physseg)));
419 1.1 cherry }
420 1.1 cherry #endif /* VM_PHYSSEG_MAX */
421 1.1 cherry #endif /* UVM_HOTPLUG */
422 1.1 cherry
423 1.1 cherry /*
424 1.1 cherry * Note: This function replicates verbatim what happens in
425 1.1 cherry * uvm_page.c:uvm_page_init().
426 1.1 cherry *
427 1.1 cherry * Please track any changes that happen there.
428 1.1 cherry */
429 1.1 cherry static void
430 1.1 cherry uvm_page_init_fake(struct vm_page *pagearray, psize_t pagecount)
431 1.1 cherry {
432 1.1 cherry uvm_physseg_t bank;
433 1.1 cherry size_t n;
434 1.1 cherry
435 1.1 cherry for (bank = uvm_physseg_get_first(),
436 1.1 cherry uvm_physseg_seg_chomp_slab(bank, pagearray, pagecount);
437 1.1 cherry uvm_physseg_valid(bank);
438 1.1 cherry bank = uvm_physseg_get_next(bank)) {
439 1.1 cherry
440 1.1 cherry n = uvm_physseg_get_end(bank) - uvm_physseg_get_start(bank);
441 1.1 cherry uvm_physseg_seg_alloc_from_slab(bank, n);
442 1.1 cherry uvm_physseg_init_seg(bank, pagearray);
443 1.1 cherry
444 1.1 cherry /* set up page array pointers */
445 1.1 cherry pagearray += n;
446 1.1 cherry pagecount -= n;
447 1.1 cherry }
448 1.1 cherry
449 1.1 cherry uvm.page_init_done = true;
450 1.1 cherry }
451 1.1 cherry
452 1.1 cherry ATF_TC(uvm_physseg_plug);
453 1.1 cherry ATF_TC_HEAD(uvm_physseg_plug, tc)
454 1.1 cherry {
455 1.1 cherry atf_tc_set_md_var(tc, "descr",
456 1.1 cherry "Test plug functionality.");
457 1.1 cherry }
458 1.1 cherry /* Note: We only do the second boot time plug if VM_PHYSSEG_MAX > 1 */
459 1.1 cherry ATF_TC_BODY(uvm_physseg_plug, tc)
460 1.1 cherry {
461 1.1 cherry int nentries = 0; /* Count of entries via plug done so far */
462 1.1 cherry uvm_physseg_t upm1;
463 1.1 cherry #if VM_PHYSSEG_MAX > 2
464 1.1 cherry uvm_physseg_t upm2;
465 1.1 cherry #endif
466 1.1 cherry
467 1.1 cherry #if VM_PHYSSEG_MAX > 1
468 1.1 cherry uvm_physseg_t upm3;
469 1.1 cherry #endif
470 1.1 cherry uvm_physseg_t upm4;
471 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1);
472 1.1 cherry psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2);
473 1.1 cherry psize_t npages3 = (VALID_END_PFN_3 - VALID_START_PFN_3);
474 1.1 cherry psize_t npages4 = (VALID_END_PFN_4 - VALID_START_PFN_4);
475 1.1 cherry struct vm_page *pgs, *slab = malloc(sizeof(struct vm_page) * (npages1
476 1.1 cherry #if VM_PHYSSEG_MAX > 2
477 1.1 cherry + npages2
478 1.1 cherry #endif
479 1.1 cherry + npages3));
480 1.1 cherry
481 1.1 cherry /* Fake early boot */
482 1.1 cherry
483 1.1 cherry setup();
484 1.1 cherry
485 1.1 cherry /* Vanilla plug x 2 */
486 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_1, npages1, &upm1), true);
487 1.1 cherry ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries());
488 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
489 1.1 cherry
490 1.1 cherry #if VM_PHYSSEG_MAX > 2
491 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_2, npages2, &upm2), true);
492 1.1 cherry ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries());
493 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
494 1.1 cherry #endif
495 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */
496 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2 + npages3);
497 1.1 cherry
498 1.1 cherry ATF_CHECK_EQ(npages1
499 1.1 cherry #if VM_PHYSSEG_MAX > 2
500 1.1 cherry + npages2
501 1.1 cherry #endif
502 1.1 cherry , uvmexp.npages);
503 1.1 cherry #if VM_PHYSSEG_MAX > 1
504 1.1 cherry /* Scavenge plug - goes into the same slab */
505 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_3, npages3, &upm3), true);
506 1.1 cherry ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries());
507 1.1 cherry ATF_REQUIRE_EQ(npages1
508 1.1 cherry #if VM_PHYSSEG_MAX > 2
509 1.1 cherry + npages2
510 1.1 cherry #endif
511 1.1 cherry + npages3, uvmexp.npages);
512 1.1 cherry
513 1.1 cherry /* Scavenge plug should fit right in the slab */
514 1.1 cherry pgs = uvm_physseg_get_pg(upm3, 0);
515 1.1 cherry ATF_REQUIRE(pgs > slab && pgs < (slab + npages1 + npages2 + npages3));
516 1.1 cherry #endif
517 1.1 cherry /* Hot plug - goes into a brand new slab */
518 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_4, npages4, &upm4), true);
519 1.1 cherry /* The hot plug slab should have nothing to do with the original slab */
520 1.1 cherry pgs = uvm_physseg_get_pg(upm4, 0);
521 1.1 cherry ATF_REQUIRE(pgs < slab || pgs > (slab + npages1
522 1.1 cherry #if VM_PHYSSEG_MAX > 2
523 1.1 cherry + npages2
524 1.1 cherry #endif
525 1.1 cherry + npages3));
526 1.1 cherry
527 1.1 cherry }
528 1.1 cherry ATF_TC(uvm_physseg_unplug);
529 1.1 cherry ATF_TC_HEAD(uvm_physseg_unplug, tc)
530 1.1 cherry {
531 1.1 cherry atf_tc_set_md_var(tc, "descr",
532 1.1 cherry "Test unplug functionality.");
533 1.1 cherry }
534 1.1 cherry ATF_TC_BODY(uvm_physseg_unplug, tc)
535 1.1 cherry {
536 1.1 cherry paddr_t pa = 0;
537 1.1 cherry
538 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1);
539 1.1 cherry psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2);
540 1.1 cherry psize_t npages3 = (VALID_END_PFN_3 - VALID_START_PFN_3);
541 1.1 cherry
542 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2 + npages3));
543 1.1 cherry
544 1.1 cherry uvm_physseg_t upm;
545 1.1 cherry
546 1.1 cherry /* Boot time */
547 1.1 cherry setup();
548 1.1 cherry
549 1.1 cherry /* We start with zero segments */
550 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(atop(0), atop(ONE_MEGABYTE), NULL));
551 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
552 1.1 cherry /* Do we have an arbitrary offset in there ? */
553 1.1 cherry uvm_physseg_find(atop(TWOFIFTYSIX_KILO), &pa);
554 1.1 cherry ATF_REQUIRE_EQ(pa, atop(TWOFIFTYSIX_KILO));
555 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); /* Boot time sanity */
556 1.1 cherry
557 1.1 cherry #if VM_PHYSSEG_MAX == 1
558 1.1 cherry /*
559 1.1 cherry * This is the curious case at boot time, of having one
560 1.1 cherry * extent(9) static entry per segment, which means that a
561 1.1 cherry * fragmenting unplug will fail.
562 1.1 cherry */
563 1.1 cherry atf_tc_expect_signal(SIGABRT, "fragmenting unplug for single segment");
564 1.1 cherry
565 1.1 cherry /*
566 1.1 cherry * In order to test the fragmenting cases, please set
567 1.1 cherry * VM_PHYSSEG_MAX > 1
568 1.1 cherry */
569 1.1 cherry #endif
570 1.1 cherry /* Now let's unplug from the middle */
571 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(TWOFIFTYSIX_KILO), atop(FIVEONETWO_KILO)));
572 1.1 cherry /* verify that a gap exists at TWOFIFTYSIX_KILO */
573 1.1 cherry pa = 0; /* reset */
574 1.1 cherry uvm_physseg_find(atop(TWOFIFTYSIX_KILO), &pa);
575 1.1 cherry ATF_REQUIRE_EQ(pa, 0);
576 1.1 cherry
577 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */
578 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2 + npages3);
579 1.1 cherry /* Account for the unplug */
580 1.1 cherry ATF_CHECK_EQ(atop(FIVEONETWO_KILO), uvmexp.npages);
581 1.1 cherry
582 1.1 cherry /* Original entry should fragment into two */
583 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
584 1.1 cherry
585 1.1 cherry upm = uvm_physseg_find(atop(TWOFIFTYSIX_KILO + FIVEONETWO_KILO), NULL);
586 1.1 cherry
587 1.1 cherry ATF_REQUIRE(uvm_physseg_valid(upm));
588 1.1 cherry
589 1.1 cherry /* Now unplug the tail fragment - should swallow the complete entry */
590 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(TWOFIFTYSIX_KILO + FIVEONETWO_KILO), atop(TWOFIFTYSIX_KILO)));
591 1.1 cherry
592 1.1 cherry /* The "swallow" above should have invalidated the handle */
593 1.1 cherry ATF_REQUIRE_EQ(false, uvm_physseg_valid(upm));
594 1.1 cherry
595 1.1 cherry /* Only the first one is left now */
596 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
597 1.1 cherry
598 1.1 cherry /* Unplug from the back */
599 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(ONETWENTYEIGHT_KILO), atop(ONETWENTYEIGHT_KILO)));
600 1.1 cherry /* Shouldn't change the number of segments */
601 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
602 1.1 cherry
603 1.1 cherry /* Unplug from the front */
604 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(0, atop(SIXTYFOUR_KILO)));
605 1.1 cherry /* Shouldn't change the number of segments */
606 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
607 1.1 cherry
608 1.1 cherry /* Unplugging the final fragment should fail */
609 1.1 cherry atf_tc_expect_signal(SIGABRT, "Unplugging the last segment");
610 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(SIXTYFOUR_KILO), atop(SIXTYFOUR_KILO)));
611 1.1 cherry }
612 1.1 cherry
613 1.1 cherry
614 1.1 cherry /* <---- end Tests for Internal functions ----> */
615 1.1 cherry
616 1.1 cherry /* Tests for functions exported via uvm_physseg.h */
617 1.1 cherry ATF_TC(uvm_physseg_init);
618 1.1 cherry ATF_TC_HEAD(uvm_physseg_init, tc)
619 1.1 cherry {
620 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_init() call\
621 1.1 cherry initializes the vm_physmem struct which holds the rb_tree.");
622 1.1 cherry }
623 1.1 cherry ATF_TC_BODY(uvm_physseg_init, tc)
624 1.1 cherry {
625 1.1 cherry uvm_physseg_init();
626 1.1 cherry
627 1.1 cherry ATF_REQUIRE_EQ(0, uvm_physseg_get_entries());
628 1.1 cherry }
629 1.1 cherry
630 1.1 cherry ATF_TC(uvm_page_physload_preload);
631 1.1 cherry ATF_TC_HEAD(uvm_page_physload_preload, tc)
632 1.1 cherry {
633 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \
634 1.1 cherry call works without a panic() in a preload scenario.");
635 1.1 cherry }
636 1.1 cherry ATF_TC_BODY(uvm_page_physload_preload, tc)
637 1.1 cherry {
638 1.1 cherry uvm_physseg_t upm;
639 1.1 cherry
640 1.1 cherry setup();
641 1.1 cherry
642 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
643 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
644 1.1 cherry
645 1.1 cherry /* Should return a valid handle */
646 1.1 cherry ATF_REQUIRE(uvm_physseg_valid(upm));
647 1.1 cherry
648 1.1 cherry /* No pages should be allocated yet */
649 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
650 1.1 cherry
651 1.1 cherry /* After the first call one segment should exist */
652 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries());
653 1.1 cherry
654 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */
655 1.1 cherry #if VM_PHYSSEG_MAX > 1
656 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
657 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
658 1.1 cherry
659 1.1 cherry /* Should return a valid handle */
660 1.1 cherry ATF_REQUIRE(uvm_physseg_valid(upm));
661 1.1 cherry
662 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
663 1.1 cherry
664 1.1 cherry /* After the second call two segments should exist */
665 1.1 cherry ATF_CHECK_EQ(2, uvm_physseg_get_entries());
666 1.1 cherry #endif
667 1.1 cherry }
668 1.1 cherry
669 1.1 cherry ATF_TC(uvm_page_physload_postboot);
670 1.1 cherry ATF_TC_HEAD(uvm_page_physload_postboot, tc)
671 1.1 cherry {
672 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \
673 1.1 cherry panic()s in a post boot scenario.");
674 1.1 cherry }
675 1.1 cherry ATF_TC_BODY(uvm_page_physload_postboot, tc)
676 1.1 cherry {
677 1.1 cherry uvm_physseg_t upm;
678 1.1 cherry
679 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1);
680 1.1 cherry psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2);
681 1.1 cherry
682 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2));
683 1.1 cherry
684 1.1 cherry setup();
685 1.1 cherry
686 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
687 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
688 1.1 cherry
689 1.1 cherry /* Should return a valid handle */
690 1.1 cherry ATF_REQUIRE(uvm_physseg_valid(upm));
691 1.1 cherry
692 1.1 cherry /* No pages should be allocated yet */
693 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
694 1.1 cherry
695 1.1 cherry /* After the first call one segment should exist */
696 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries());
697 1.1 cherry
698 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */
699 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2);
700 1.1 cherry
701 1.1 cherry atf_tc_expect_signal(SIGABRT,
702 1.1 cherry "uvm_page_physload() called post boot");
703 1.1 cherry
704 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
705 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
706 1.1 cherry
707 1.1 cherry /* Should return a valid handle */
708 1.1 cherry ATF_REQUIRE(uvm_physseg_valid(upm));
709 1.1 cherry
710 1.1 cherry ATF_REQUIRE_EQ(npages1 + npages2, uvmexp.npages);
711 1.1 cherry
712 1.1 cherry /* After the second call two segments should exist */
713 1.1 cherry ATF_CHECK_EQ(2, uvm_physseg_get_entries());
714 1.1 cherry }
715 1.1 cherry
716 1.1 cherry ATF_TC(uvm_physseg_handle_immutable);
717 1.1 cherry ATF_TC_HEAD(uvm_physseg_handle_immutable, tc)
718 1.1 cherry {
719 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_physseg_t handle is \
720 1.1 cherry immutable.");
721 1.1 cherry }
722 1.1 cherry ATF_TC_BODY(uvm_physseg_handle_immutable, tc)
723 1.1 cherry {
724 1.1 cherry uvm_physseg_t upm;
725 1.1 cherry
726 1.1 cherry /* We insert the segments in out of order */
727 1.1 cherry
728 1.1 cherry setup();
729 1.1 cherry
730 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
731 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
732 1.1 cherry
733 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
734 1.1 cherry
735 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
736 1.1 cherry
737 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, uvm_physseg_get_prev(upm));
738 1.1 cherry
739 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */
740 1.1 cherry #if VM_PHYSSEG_MAX > 1
741 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
742 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
743 1.1 cherry
744 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
745 1.1 cherry
746 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
747 1.1 cherry
748 1.1 cherry /* Fetch Previous, we inserted a lower value */
749 1.1 cherry upm = uvm_physseg_get_prev(upm);
750 1.1 cherry
751 1.1 cherry #if !defined(UVM_HOTPLUG)
752 1.1 cherry /*
753 1.1 cherry * This test is going to fail for the Array Implementation but is
754 1.1 cherry * expected to pass in the RB Tree implementation.
755 1.1 cherry */
756 1.1 cherry /* Failure can be expected iff there are more than one handles */
757 1.1 cherry atf_tc_expect_fail("Mutable handle in static array impl.");
758 1.1 cherry #endif
759 1.1 cherry ATF_CHECK(UVM_PHYSSEG_TYPE_INVALID_EMPTY != upm);
760 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm));
761 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm));
762 1.1 cherry #endif
763 1.1 cherry }
764 1.1 cherry
765 1.1 cherry ATF_TC(uvm_physseg_seg_chomp_slab);
766 1.1 cherry ATF_TC_HEAD(uvm_physseg_seg_chomp_slab, tc)
767 1.1 cherry {
768 1.1 cherry atf_tc_set_md_var(tc, "descr", "The slab import code.()");
769 1.1 cherry
770 1.1 cherry }
771 1.1 cherry ATF_TC_BODY(uvm_physseg_seg_chomp_slab, tc)
772 1.1 cherry {
773 1.1 cherry int err;
774 1.1 cherry size_t i;
775 1.1 cherry struct uvm_physseg *seg;
776 1.1 cherry struct vm_page *slab, *pgs;
777 1.1 cherry const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */
778 1.1 cherry
779 1.1 cherry setup();
780 1.1 cherry
781 1.1 cherry /* This is boot time */
782 1.1 cherry slab = malloc(sizeof(struct vm_page) * npages * 2);
783 1.1 cherry
784 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg));
785 1.1 cherry
786 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2);
787 1.1 cherry
788 1.1 cherry /* Should be able to allocate two 128 * sizeof(*slab) */
789 1.1 cherry ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs));
790 1.1 cherry err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO);
791 1.1 cherry
792 1.1 cherry #if VM_PHYSSEG_MAX == 1
793 1.1 cherry /*
794 1.1 cherry * free() needs an extra region descriptor, but we only have
795 1.1 cherry * one! The classic alloc() at free() problem
796 1.1 cherry */
797 1.1 cherry
798 1.1 cherry ATF_REQUIRE_EQ(ENOMEM, err);
799 1.1 cherry #else
800 1.1 cherry /* Try alloc/free at static time */
801 1.1 cherry for (i = 0; i < npages; i++) {
802 1.1 cherry ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs));
803 1.1 cherry err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO);
804 1.1 cherry ATF_REQUIRE_EQ(0, err);
805 1.1 cherry }
806 1.1 cherry #endif
807 1.1 cherry
808 1.1 cherry /* Now setup post boot */
809 1.1 cherry uvm.page_init_done = true;
810 1.1 cherry
811 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2);
812 1.1 cherry
813 1.1 cherry /* Try alloc/free after uvm_page.c:uvm_page_init() as well */
814 1.1 cherry for (i = 0; i < npages; i++) {
815 1.1 cherry ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs));
816 1.1 cherry err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO);
817 1.1 cherry ATF_REQUIRE_EQ(0, err);
818 1.1 cherry }
819 1.1 cherry
820 1.1 cherry }
821 1.1 cherry
822 1.1 cherry ATF_TC(uvm_physseg_alloc_from_slab);
823 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_from_slab, tc)
824 1.1 cherry {
825 1.1 cherry atf_tc_set_md_var(tc, "descr", "The slab alloc code.()");
826 1.1 cherry
827 1.1 cherry }
828 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_from_slab, tc)
829 1.1 cherry {
830 1.1 cherry struct uvm_physseg *seg;
831 1.1 cherry struct vm_page *slab, *pgs;
832 1.1 cherry const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */
833 1.1 cherry
834 1.1 cherry setup();
835 1.1 cherry
836 1.1 cherry /* This is boot time */
837 1.1 cherry slab = malloc(sizeof(struct vm_page) * npages * 2);
838 1.1 cherry
839 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg));
840 1.1 cherry
841 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2);
842 1.1 cherry
843 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages);
844 1.1 cherry
845 1.1 cherry ATF_REQUIRE(pgs != NULL);
846 1.1 cherry
847 1.1 cherry /* Now setup post boot */
848 1.1 cherry uvm.page_init_done = true;
849 1.1 cherry
850 1.1 cherry #if VM_PHYSSEG_MAX > 1
851 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages);
852 1.1 cherry ATF_REQUIRE(pgs != NULL);
853 1.1 cherry #endif
854 1.1 cherry atf_tc_expect_fail("alloc beyond extent");
855 1.1 cherry
856 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages);
857 1.1 cherry ATF_REQUIRE(pgs != NULL);
858 1.1 cherry }
859 1.1 cherry
860 1.1 cherry ATF_TC(uvm_physseg_init_seg);
861 1.1 cherry ATF_TC_HEAD(uvm_physseg_init_seg, tc)
862 1.1 cherry {
863 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if uvm_physseg_init_seg adds pages to"
864 1.1 cherry "uvmexp.npages");
865 1.1 cherry }
866 1.1 cherry ATF_TC_BODY(uvm_physseg_init_seg, tc)
867 1.1 cherry {
868 1.1 cherry struct uvm_physseg *seg;
869 1.1 cherry struct vm_page *slab, *pgs;
870 1.1 cherry const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */
871 1.1 cherry
872 1.1 cherry setup();
873 1.1 cherry
874 1.1 cherry /* This is boot time */
875 1.1 cherry slab = malloc(sizeof(struct vm_page) * npages * 2);
876 1.1 cherry
877 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg));
878 1.1 cherry
879 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2);
880 1.1 cherry
881 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages);
882 1.1 cherry
883 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
884 1.1 cherry
885 1.1 cherry seg->start = 0;
886 1.1 cherry seg->end = npages;
887 1.1 cherry
888 1.1 cherry seg->avail_start = 0;
889 1.1 cherry seg->avail_end = npages;
890 1.1 cherry
891 1.1 cherry uvm_physseg_init_seg(PHYSSEG_NODE_TO_HANDLE(seg), pgs);
892 1.1 cherry
893 1.1 cherry ATF_REQUIRE_EQ(npages, uvmexp.npages);
894 1.1 cherry }
895 1.1 cherry
896 1.1 cherry #if 0
897 1.1 cherry ATF_TC(uvm_physseg_init_seg);
898 1.1 cherry ATF_TC_HEAD(uvm_physseg_init_seg, tc)
899 1.1 cherry {
900 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \
901 1.1 cherry call works without a panic() after Segment is inited.");
902 1.1 cherry }
903 1.1 cherry ATF_TC_BODY(uvm_physseg_init_seg, tc)
904 1.1 cherry {
905 1.1 cherry uvm_physseg_t upm;
906 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1);
907 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
908 1.1 cherry
909 1.1 cherry setup();
910 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
911 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
912 1.1 cherry
913 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
914 1.1 cherry
915 1.1 cherry ATF_CHECK_EQ(0, uvmexp.npages);
916 1.1 cherry
917 1.1 cherry /*
918 1.1 cherry * Boot time physplug needs explicit external init,
919 1.1 cherry * Duplicate what uvm_page.c:uvm_page_init() does.
920 1.1 cherry * Note: not everything uvm_page_init() does gets done here.
921 1.1 cherry * Read the source.
922 1.1 cherry */
923 1.1 cherry /* suck in backing slab, initialise extent. */
924 1.1 cherry uvm_physseg_seg_chomp_slab(upm, pgs, npages);
925 1.1 cherry
926 1.1 cherry /*
927 1.1 cherry * Actual pgs[] allocation, from extent.
928 1.1 cherry */
929 1.1 cherry uvm_physseg_alloc_from_slab(upm, npages);
930 1.1 cherry
931 1.1 cherry /* Now we initialize the segment */
932 1.1 cherry uvm_physseg_init_seg(upm, pgs);
933 1.1 cherry
934 1.1 cherry /* Done with boot simulation */
935 1.1 cherry extent_init();
936 1.1 cherry uvm.page_init_done = true;
937 1.1 cherry
938 1.1 cherry /* We have total memory of 1MB */
939 1.1 cherry ATF_CHECK_EQ(PAGE_COUNT_1M, uvmexp.npages);
940 1.1 cherry
941 1.1 cherry upm =uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
942 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
943 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
944 1.1 cherry
945 1.1 cherry /* We added another 1MB so PAGE_COUNT_1M + PAGE_COUNT_1M */
946 1.1 cherry ATF_CHECK_EQ(PAGE_COUNT_1M + PAGE_COUNT_1M, uvmexp.npages);
947 1.1 cherry
948 1.1 cherry }
949 1.1 cherry #endif
950 1.1 cherry
951 1.1 cherry ATF_TC(uvm_physseg_get_start);
952 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_start, tc)
953 1.1 cherry {
954 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the start PFN is returned \
955 1.1 cherry correctly from a segment created via uvm_page_physload().");
956 1.1 cherry }
957 1.1 cherry ATF_TC_BODY(uvm_physseg_get_start, tc)
958 1.1 cherry {
959 1.1 cherry uvm_physseg_t upm;
960 1.1 cherry
961 1.1 cherry /* Fake early boot */
962 1.1 cherry setup();
963 1.1 cherry
964 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
965 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
966 1.1 cherry
967 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
968 1.1 cherry
969 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
970 1.1 cherry
971 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm));
972 1.1 cherry
973 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
974 1.1 cherry #if VM_PHYSSEG_MAX > 1
975 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
976 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
977 1.1 cherry
978 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
979 1.1 cherry
980 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
981 1.1 cherry
982 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
983 1.1 cherry #endif
984 1.1 cherry }
985 1.1 cherry
986 1.1 cherry ATF_TC(uvm_physseg_get_start_invalid);
987 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_start_invalid, tc)
988 1.1 cherry {
989 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \
990 1.1 cherry correctly when uvm_physseg_get_start() is called with invalid \
991 1.1 cherry parameter values.");
992 1.1 cherry }
993 1.1 cherry ATF_TC_BODY(uvm_physseg_get_start_invalid, tc)
994 1.1 cherry {
995 1.1 cherry /* Check for pgs == NULL */
996 1.1 cherry setup();
997 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
998 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
999 1.1 cherry
1000 1.1 cherry /* Force other check conditions */
1001 1.1 cherry uvm.page_init_done = true;
1002 1.1 cherry
1003 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1004 1.1 cherry
1005 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1006 1.1 cherry
1007 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done);
1008 1.1 cherry
1009 1.1 cherry /* Invalid uvm_physseg_t */
1010 1.1 cherry ATF_CHECK_EQ((paddr_t) -1,
1011 1.1 cherry uvm_physseg_get_start(UVM_PHYSSEG_TYPE_INVALID));
1012 1.1 cherry }
1013 1.1 cherry
1014 1.1 cherry ATF_TC(uvm_physseg_get_end);
1015 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_end, tc)
1016 1.1 cherry {
1017 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the end PFN is returned \
1018 1.1 cherry correctly from a segment created via uvm_page_physload().");
1019 1.1 cherry }
1020 1.1 cherry ATF_TC_BODY(uvm_physseg_get_end, tc)
1021 1.1 cherry {
1022 1.1 cherry uvm_physseg_t upm;
1023 1.1 cherry
1024 1.1 cherry setup();
1025 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1026 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1027 1.1 cherry
1028 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1029 1.1 cherry
1030 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1031 1.1 cherry
1032 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm));
1033 1.1 cherry
1034 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1035 1.1 cherry #if VM_PHYSSEG_MAX > 1
1036 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1037 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1038 1.1 cherry
1039 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1040 1.1 cherry
1041 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1042 1.1 cherry
1043 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
1044 1.1 cherry #endif
1045 1.1 cherry }
1046 1.1 cherry
1047 1.1 cherry ATF_TC(uvm_physseg_get_end_invalid);
1048 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_end_invalid, tc)
1049 1.1 cherry {
1050 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \
1051 1.1 cherry correctly when uvm_physseg_get_end() is called with invalid \
1052 1.1 cherry parameter values.");
1053 1.1 cherry }
1054 1.1 cherry ATF_TC_BODY(uvm_physseg_get_end_invalid, tc)
1055 1.1 cherry {
1056 1.1 cherry /* Check for pgs == NULL */
1057 1.1 cherry setup();
1058 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1059 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1060 1.1 cherry
1061 1.1 cherry /* Force other check conditions */
1062 1.1 cherry uvm.page_init_done = true;
1063 1.1 cherry
1064 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1065 1.1 cherry
1066 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1067 1.1 cherry
1068 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done);
1069 1.1 cherry
1070 1.1 cherry /* Invalid uvm_physseg_t */
1071 1.1 cherry ATF_CHECK_EQ((paddr_t) -1,
1072 1.1 cherry uvm_physseg_get_end(UVM_PHYSSEG_TYPE_INVALID));
1073 1.1 cherry }
1074 1.1 cherry
1075 1.1 cherry ATF_TC(uvm_physseg_get_avail_start);
1076 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_start, tc)
1077 1.1 cherry {
1078 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the avail_start PFN is \
1079 1.1 cherry returned correctly from a segment created via uvm_page_physload().");
1080 1.1 cherry }
1081 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_start, tc)
1082 1.1 cherry {
1083 1.1 cherry uvm_physseg_t upm;
1084 1.1 cherry
1085 1.1 cherry setup();
1086 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1087 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1088 1.1 cherry
1089 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1090 1.1 cherry
1091 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1092 1.1 cherry
1093 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm));
1094 1.1 cherry
1095 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1096 1.1 cherry #if VM_PHYSSEG_MAX > 1
1097 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1098 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1099 1.1 cherry
1100 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1101 1.1 cherry
1102 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1103 1.1 cherry
1104 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm));
1105 1.1 cherry #endif
1106 1.1 cherry }
1107 1.1 cherry
1108 1.1 cherry ATF_TC(uvm_physseg_get_avail_start_invalid);
1109 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_start_invalid, tc)
1110 1.1 cherry {
1111 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \
1112 1.1 cherry correctly when uvm_physseg_get_avail_start() is called with invalid\
1113 1.1 cherry parameter values.");
1114 1.1 cherry }
1115 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_start_invalid, tc)
1116 1.1 cherry {
1117 1.1 cherry /* Check for pgs == NULL */
1118 1.1 cherry setup();
1119 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1120 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1121 1.1 cherry
1122 1.1 cherry /* Force other check conditions */
1123 1.1 cherry uvm.page_init_done = true;
1124 1.1 cherry
1125 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1126 1.1 cherry
1127 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1128 1.1 cherry
1129 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done);
1130 1.1 cherry
1131 1.1 cherry /* Invalid uvm_physseg_t */
1132 1.1 cherry ATF_CHECK_EQ((paddr_t) -1,
1133 1.1 cherry uvm_physseg_get_avail_start(UVM_PHYSSEG_TYPE_INVALID));
1134 1.1 cherry }
1135 1.1 cherry
1136 1.1 cherry ATF_TC(uvm_physseg_get_avail_end);
1137 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_end, tc)
1138 1.1 cherry {
1139 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the avail_end PFN is \
1140 1.1 cherry returned correctly from a segment created via uvm_page_physload().");
1141 1.1 cherry }
1142 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_end, tc)
1143 1.1 cherry {
1144 1.1 cherry uvm_physseg_t upm;
1145 1.1 cherry
1146 1.1 cherry setup();
1147 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1148 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1149 1.1 cherry
1150 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1151 1.1 cherry
1152 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1153 1.1 cherry
1154 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm));
1155 1.1 cherry
1156 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1157 1.1 cherry #if VM_PHYSSEG_MAX > 1
1158 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1159 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1160 1.1 cherry
1161 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1162 1.1 cherry
1163 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1164 1.1 cherry
1165 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm));
1166 1.1 cherry #endif
1167 1.1 cherry }
1168 1.1 cherry
1169 1.1 cherry ATF_TC(uvm_physseg_get_avail_end_invalid);
1170 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_end_invalid, tc)
1171 1.1 cherry {
1172 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \
1173 1.1 cherry correctly when uvm_physseg_get_avail_end() is called with invalid\
1174 1.1 cherry parameter values.");
1175 1.1 cherry }
1176 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_end_invalid, tc)
1177 1.1 cherry {
1178 1.1 cherry /* Check for pgs == NULL */
1179 1.1 cherry setup();
1180 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1181 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1182 1.1 cherry
1183 1.1 cherry /* Force other check conditions */
1184 1.1 cherry uvm.page_init_done = true;
1185 1.1 cherry
1186 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1187 1.1 cherry
1188 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1189 1.1 cherry
1190 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done);
1191 1.1 cherry
1192 1.1 cherry /* Invalid uvm_physseg_t */
1193 1.1 cherry ATF_CHECK_EQ((paddr_t) -1,
1194 1.1 cherry uvm_physseg_get_avail_end(UVM_PHYSSEG_TYPE_INVALID));
1195 1.1 cherry }
1196 1.1 cherry
1197 1.1 cherry ATF_TC(uvm_physseg_get_next);
1198 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_next, tc)
1199 1.1 cherry {
1200 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for next \
1201 1.1 cherry segment using the uvm_physseg_get_next() call.");
1202 1.1 cherry }
1203 1.1 cherry ATF_TC_BODY(uvm_physseg_get_next, tc)
1204 1.1 cherry {
1205 1.1 cherry uvm_physseg_t upm;
1206 1.1 cherry #if VM_PHYSSEG_MAX > 1
1207 1.1 cherry uvm_physseg_t upm_next;
1208 1.1 cherry #endif
1209 1.1 cherry
1210 1.1 cherry /* We insert the segments in ascending order */
1211 1.1 cherry
1212 1.1 cherry setup();
1213 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1214 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1215 1.1 cherry
1216 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1217 1.1 cherry
1218 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1219 1.1 cherry
1220 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_OVERFLOW,
1221 1.1 cherry uvm_physseg_get_next(upm));
1222 1.1 cherry
1223 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1224 1.1 cherry #if VM_PHYSSEG_MAX > 1
1225 1.1 cherry upm_next = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1226 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1227 1.1 cherry
1228 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1229 1.1 cherry
1230 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1231 1.1 cherry
1232 1.1 cherry upm = uvm_physseg_get_next(upm); /* Fetch Next */
1233 1.1 cherry
1234 1.1 cherry ATF_CHECK_EQ(upm_next, upm);
1235 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
1236 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
1237 1.1 cherry #endif
1238 1.1 cherry
1239 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */
1240 1.1 cherry #if VM_PHYSSEG_MAX > 2
1241 1.1 cherry upm_next = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3,
1242 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT);
1243 1.1 cherry
1244 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1245 1.1 cherry
1246 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries());
1247 1.1 cherry
1248 1.1 cherry upm = uvm_physseg_get_next(upm); /* Fetch Next */
1249 1.1 cherry
1250 1.1 cherry ATF_CHECK_EQ(upm_next, upm);
1251 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_3, uvm_physseg_get_start(upm));
1252 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_3, uvm_physseg_get_end(upm));
1253 1.1 cherry #endif
1254 1.1 cherry }
1255 1.1 cherry
1256 1.1 cherry ATF_TC(uvm_physseg_get_next_invalid);
1257 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_next_invalid, tc)
1258 1.1 cherry {
1259 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \
1260 1.1 cherry correctly when uvm_physseg_get_next() is called with invalid \
1261 1.1 cherry parameter values.");
1262 1.1 cherry }
1263 1.1 cherry ATF_TC_BODY(uvm_physseg_get_next_invalid, tc)
1264 1.1 cherry {
1265 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID;
1266 1.1 cherry
1267 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, uvm_physseg_get_next(upm));
1268 1.1 cherry }
1269 1.1 cherry
1270 1.1 cherry ATF_TC(uvm_physseg_get_prev);
1271 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_prev, tc)
1272 1.1 cherry {
1273 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for previous \
1274 1.1 cherry segment using the uvm_physseg_get_prev() call.");
1275 1.1 cherry }
1276 1.1 cherry ATF_TC_BODY(uvm_physseg_get_prev, tc)
1277 1.1 cherry {
1278 1.1 cherry #if VM_PHYSSEG_MAX > 1
1279 1.1 cherry uvm_physseg_t upm;
1280 1.1 cherry #endif
1281 1.1 cherry uvm_physseg_t upm_prev;
1282 1.1 cherry
1283 1.1 cherry
1284 1.1 cherry setup();
1285 1.1 cherry upm_prev = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1286 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1287 1.1 cherry
1288 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1289 1.1 cherry
1290 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1291 1.1 cherry
1292 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY,
1293 1.1 cherry uvm_physseg_get_prev(upm_prev));
1294 1.1 cherry
1295 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1296 1.1 cherry #if VM_PHYSSEG_MAX > 1
1297 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1298 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1299 1.1 cherry
1300 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1301 1.1 cherry
1302 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1303 1.1 cherry
1304 1.1 cherry /* Fetch Previous, we inserted a lower value */
1305 1.1 cherry upm = uvm_physseg_get_prev(upm);
1306 1.1 cherry
1307 1.1 cherry ATF_CHECK_EQ(upm_prev, upm);
1308 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm));
1309 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm));
1310 1.1 cherry #endif
1311 1.1 cherry
1312 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */
1313 1.1 cherry #if VM_PHYSSEG_MAX > 2
1314 1.1 cherry uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3,
1315 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT);
1316 1.1 cherry
1317 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1318 1.1 cherry
1319 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries());
1320 1.1 cherry
1321 1.1 cherry /*
1322 1.1 cherry * This will return a UVM_PHYSSEG_TYPE_INVALID_EMPTY we are at the
1323 1.1 cherry * lowest
1324 1.1 cherry */
1325 1.1 cherry upm = uvm_physseg_get_prev(upm);
1326 1.1 cherry
1327 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, upm);
1328 1.1 cherry #endif
1329 1.1 cherry }
1330 1.1 cherry
1331 1.1 cherry ATF_TC(uvm_physseg_get_prev_invalid);
1332 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_prev_invalid, tc)
1333 1.1 cherry {
1334 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \
1335 1.1 cherry correctly when uvm_physseg_get_prev() is called with invalid \
1336 1.1 cherry parameter values.");
1337 1.1 cherry }
1338 1.1 cherry ATF_TC_BODY(uvm_physseg_get_prev_invalid, tc)
1339 1.1 cherry {
1340 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID;
1341 1.1 cherry
1342 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, uvm_physseg_get_prev(upm));
1343 1.1 cherry }
1344 1.1 cherry
1345 1.1 cherry ATF_TC(uvm_physseg_get_first);
1346 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_first, tc)
1347 1.1 cherry {
1348 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for first \
1349 1.1 cherry segment (lowest node) using the uvm_physseg_get_first() call.");
1350 1.1 cherry }
1351 1.1 cherry ATF_TC_BODY(uvm_physseg_get_first, tc)
1352 1.1 cherry {
1353 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID_EMPTY;
1354 1.1 cherry uvm_physseg_t upm_first;
1355 1.1 cherry
1356 1.1 cherry /* Fake early boot */
1357 1.1 cherry setup();
1358 1.1 cherry
1359 1.1 cherry /* No nodes exist */
1360 1.1 cherry ATF_CHECK_EQ(upm, uvm_physseg_get_first());
1361 1.1 cherry
1362 1.1 cherry upm_first = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1363 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1364 1.1 cherry
1365 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1366 1.1 cherry
1367 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1368 1.1 cherry
1369 1.1 cherry /* Pointer to first should be the least valued node */
1370 1.1 cherry upm = uvm_physseg_get_first();
1371 1.1 cherry ATF_CHECK_EQ(upm_first, upm);
1372 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
1373 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
1374 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm));
1375 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm));
1376 1.1 cherry
1377 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1378 1.1 cherry #if VM_PHYSSEG_MAX > 1
1379 1.1 cherry /* Insert a node of lesser value */
1380 1.1 cherry upm_first = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1381 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1382 1.1 cherry
1383 1.1 cherry ATF_CHECK_EQ(0, uvmexp.npages);
1384 1.1 cherry
1385 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1386 1.1 cherry
1387 1.1 cherry /* Pointer to first should be the least valued node */
1388 1.1 cherry upm = uvm_physseg_get_first();
1389 1.1 cherry ATF_CHECK_EQ(upm_first, upm);
1390 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm));
1391 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm));
1392 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm));
1393 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm));
1394 1.1 cherry #endif
1395 1.1 cherry
1396 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */
1397 1.1 cherry #if VM_PHYSSEG_MAX > 2
1398 1.1 cherry /* Insert a node of higher value */
1399 1.1 cherry upm_first =uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3,
1400 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT);
1401 1.1 cherry
1402 1.1 cherry ATF_CHECK_EQ(0, uvmexp.npages);
1403 1.1 cherry
1404 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries());
1405 1.1 cherry
1406 1.1 cherry /* Pointer to first should be the least valued node */
1407 1.1 cherry upm = uvm_physseg_get_first();
1408 1.1 cherry ATF_CHECK(upm_first != upm);
1409 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm));
1410 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm));
1411 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm));
1412 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm));
1413 1.1 cherry #endif
1414 1.1 cherry }
1415 1.1 cherry
1416 1.1 cherry ATF_TC(uvm_physseg_get_last);
1417 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_last, tc)
1418 1.1 cherry {
1419 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for last \
1420 1.1 cherry segment using the uvm_physseg_get_last() call.");
1421 1.1 cherry }
1422 1.1 cherry ATF_TC_BODY(uvm_physseg_get_last, tc)
1423 1.1 cherry {
1424 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID_EMPTY;
1425 1.1 cherry uvm_physseg_t upm_last;
1426 1.1 cherry
1427 1.1 cherry setup();
1428 1.1 cherry
1429 1.1 cherry /* No nodes exist */
1430 1.1 cherry ATF_CHECK_EQ(upm, uvm_physseg_get_last());
1431 1.1 cherry
1432 1.1 cherry upm_last = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1433 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1434 1.1 cherry
1435 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1436 1.1 cherry
1437 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1438 1.1 cherry
1439 1.1 cherry /* Pointer to last should be the most valued node */
1440 1.1 cherry upm = uvm_physseg_get_last();
1441 1.1 cherry ATF_CHECK_EQ(upm_last, upm);
1442 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm));
1443 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm));
1444 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm));
1445 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm));
1446 1.1 cherry
1447 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1448 1.1 cherry #if VM_PHYSSEG_MAX > 1
1449 1.1 cherry /* Insert node of greater value */
1450 1.1 cherry upm_last = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1451 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1452 1.1 cherry
1453 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1454 1.1 cherry
1455 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1456 1.1 cherry
1457 1.1 cherry /* Pointer to last should be the most valued node */
1458 1.1 cherry upm = uvm_physseg_get_last();
1459 1.1 cherry ATF_CHECK_EQ(upm_last, upm);
1460 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
1461 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
1462 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm));
1463 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm));
1464 1.1 cherry #endif
1465 1.1 cherry
1466 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */
1467 1.1 cherry #if VM_PHYSSEG_MAX > 2
1468 1.1 cherry /* Insert node of greater value */
1469 1.1 cherry upm_last = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3,
1470 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT);
1471 1.1 cherry
1472 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1473 1.1 cherry
1474 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries());
1475 1.1 cherry
1476 1.1 cherry /* Pointer to last should be the most valued node */
1477 1.1 cherry upm = uvm_physseg_get_last();
1478 1.1 cherry ATF_CHECK_EQ(upm_last, upm);
1479 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_3, uvm_physseg_get_start(upm));
1480 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_3, uvm_physseg_get_end(upm));
1481 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_3, uvm_physseg_get_avail_start(upm));
1482 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3, uvm_physseg_get_avail_end(upm));
1483 1.1 cherry #endif
1484 1.1 cherry }
1485 1.1 cherry
1486 1.1 cherry ATF_TC(uvm_physseg_valid);
1487 1.1 cherry ATF_TC_HEAD(uvm_physseg_valid, tc)
1488 1.1 cherry {
1489 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer value for current \
1490 1.1 cherry segment is valid using the uvm_physseg_valid() call.");
1491 1.1 cherry }
1492 1.1 cherry ATF_TC_BODY(uvm_physseg_valid, tc)
1493 1.1 cherry {
1494 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1);
1495 1.1 cherry
1496 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
1497 1.1 cherry
1498 1.1 cherry uvm_physseg_t upm;
1499 1.1 cherry
1500 1.1 cherry setup();
1501 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1502 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1503 1.1 cherry
1504 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1505 1.1 cherry
1506 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1507 1.1 cherry
1508 1.1 cherry uvm_physseg_init_seg(upm, pgs);
1509 1.1 cherry
1510 1.1 cherry ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages);
1511 1.1 cherry
1512 1.1 cherry ATF_CHECK_EQ(true, uvm_physseg_valid(upm));
1513 1.1 cherry }
1514 1.1 cherry
1515 1.1 cherry ATF_TC(uvm_physseg_valid_invalid);
1516 1.1 cherry ATF_TC_HEAD(uvm_physseg_valid_invalid, tc)
1517 1.1 cherry {
1518 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer value for current \
1519 1.1 cherry segment is invalid using the uvm_physseg_valid() call.");
1520 1.1 cherry }
1521 1.1 cherry ATF_TC_BODY(uvm_physseg_valid_invalid, tc)
1522 1.1 cherry {
1523 1.1 cherry uvm_physseg_t upm;
1524 1.1 cherry
1525 1.1 cherry setup();
1526 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1527 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1528 1.1 cherry
1529 1.1 cherry /* Force other check conditions */
1530 1.1 cherry uvm.page_init_done = true;
1531 1.1 cherry
1532 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done);
1533 1.1 cherry
1534 1.1 cherry /* Invalid uvm_physseg_t */
1535 1.1 cherry ATF_CHECK_EQ(false, uvm_physseg_valid(UVM_PHYSSEG_TYPE_INVALID));
1536 1.1 cherry
1537 1.1 cherry /*
1538 1.1 cherry * Without any pages initialized for segment, it is considered
1539 1.1 cherry * invalid
1540 1.1 cherry */
1541 1.1 cherry ATF_CHECK_EQ(false, uvm_physseg_valid(upm));
1542 1.1 cherry }
1543 1.1 cherry
1544 1.1 cherry ATF_TC(uvm_physseg_get_highest);
1545 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_highest, tc)
1546 1.1 cherry {
1547 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned PFN matches \
1548 1.1 cherry the highest PFN in use by the system.");
1549 1.1 cherry }
1550 1.1 cherry ATF_TC_BODY(uvm_physseg_get_highest, tc)
1551 1.1 cherry {
1552 1.1 cherry setup();
1553 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1554 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1555 1.1 cherry
1556 1.1 cherry /* Only one segment so highest is the current */
1557 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1 - 1, uvm_physseg_get_highest_frame());
1558 1.1 cherry
1559 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1560 1.1 cherry #if VM_PHYSSEG_MAX > 1
1561 1.1 cherry uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3,
1562 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT);
1563 1.1 cherry
1564 1.1 cherry /* PFN_3 > PFN_1 */
1565 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3 - 1, uvm_physseg_get_highest_frame());
1566 1.1 cherry #endif
1567 1.1 cherry
1568 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */
1569 1.1 cherry #if VM_PHYSSEG_MAX > 2
1570 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1571 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1572 1.1 cherry
1573 1.1 cherry /* PFN_3 > PFN_2 */
1574 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3 - 1, uvm_physseg_get_highest_frame());
1575 1.1 cherry #endif
1576 1.1 cherry }
1577 1.1 cherry
1578 1.1 cherry ATF_TC(uvm_physseg_get_free_list);
1579 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_free_list, tc)
1580 1.1 cherry {
1581 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned Free List type \
1582 1.1 cherry of a segment matches the one returned from \
1583 1.1 cherry uvm_physseg_get_free_list() call.");
1584 1.1 cherry }
1585 1.1 cherry ATF_TC_BODY(uvm_physseg_get_free_list, tc)
1586 1.1 cherry {
1587 1.1 cherry uvm_physseg_t upm;
1588 1.1 cherry
1589 1.1 cherry /* Fake early boot */
1590 1.1 cherry setup();
1591 1.1 cherry
1592 1.1 cherry /* Insertions are made in ascending order */
1593 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1594 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1595 1.1 cherry
1596 1.1 cherry ATF_CHECK_EQ(VM_FREELIST_DEFAULT, uvm_physseg_get_free_list(upm));
1597 1.1 cherry
1598 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1599 1.1 cherry #if VM_PHYSSEG_MAX > 1
1600 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1601 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_FIRST16);
1602 1.1 cherry
1603 1.1 cherry ATF_CHECK_EQ(VM_FREELIST_FIRST16, uvm_physseg_get_free_list(upm));
1604 1.1 cherry #endif
1605 1.1 cherry
1606 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */
1607 1.1 cherry #if VM_PHYSSEG_MAX > 2
1608 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3,
1609 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_FIRST1G);
1610 1.1 cherry
1611 1.1 cherry ATF_CHECK_EQ(VM_FREELIST_FIRST1G, uvm_physseg_get_free_list(upm));
1612 1.1 cherry #endif
1613 1.1 cherry }
1614 1.1 cherry
1615 1.1 cherry ATF_TC(uvm_physseg_get_start_hint);
1616 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_start_hint, tc)
1617 1.1 cherry {
1618 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned start_hint value \
1619 1.1 cherry of a segment matches the one returned from \
1620 1.1 cherry uvm_physseg_get_start_hint() call.");
1621 1.1 cherry }
1622 1.1 cherry ATF_TC_BODY(uvm_physseg_get_start_hint, tc)
1623 1.1 cherry {
1624 1.1 cherry uvm_physseg_t upm;
1625 1.1 cherry
1626 1.1 cherry setup();
1627 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1628 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1629 1.1 cherry
1630 1.1 cherry /* Will be Zero since no specific value is set during init */
1631 1.1 cherry ATF_CHECK_EQ(0, uvm_physseg_get_start_hint(upm));
1632 1.1 cherry }
1633 1.1 cherry
1634 1.1 cherry ATF_TC(uvm_physseg_set_start_hint);
1635 1.1 cherry ATF_TC_HEAD(uvm_physseg_set_start_hint, tc)
1636 1.1 cherry {
1637 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned start_hint value \
1638 1.1 cherry of a segment matches the one set by the \
1639 1.1 cherry uvm_physseg_set_start_hint() call.");
1640 1.1 cherry }
1641 1.1 cherry ATF_TC_BODY(uvm_physseg_set_start_hint, tc)
1642 1.1 cherry {
1643 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1);
1644 1.1 cherry
1645 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
1646 1.1 cherry
1647 1.1 cherry uvm_physseg_t upm;
1648 1.1 cherry
1649 1.1 cherry setup();
1650 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1651 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1652 1.1 cherry
1653 1.1 cherry uvm_physseg_init_seg(upm, pgs);
1654 1.1 cherry
1655 1.1 cherry ATF_CHECK_EQ(true, uvm_physseg_set_start_hint(upm, atop(128)));
1656 1.1 cherry
1657 1.1 cherry /* Will be atop(128) since no specific value is set above */
1658 1.1 cherry ATF_CHECK_EQ(atop(128), uvm_physseg_get_start_hint(upm));
1659 1.1 cherry }
1660 1.1 cherry
1661 1.1 cherry ATF_TC(uvm_physseg_set_start_hint_invalid);
1662 1.1 cherry ATF_TC_HEAD(uvm_physseg_set_start_hint_invalid, tc)
1663 1.1 cherry {
1664 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned value is false \
1665 1.1 cherry when an invalid segment matches the one trying to set by the \
1666 1.1 cherry uvm_physseg_set_start_hint() call.");
1667 1.1 cherry }
1668 1.1 cherry ATF_TC_BODY(uvm_physseg_set_start_hint_invalid, tc)
1669 1.1 cherry {
1670 1.1 cherry uvm_physseg_t upm;
1671 1.1 cherry
1672 1.1 cherry setup();
1673 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1674 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1675 1.1 cherry
1676 1.1 cherry /* Force other check conditions */
1677 1.1 cherry uvm.page_init_done = true;
1678 1.1 cherry
1679 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done);
1680 1.1 cherry
1681 1.1 cherry ATF_CHECK_EQ(false, uvm_physseg_set_start_hint(upm, atop(128)));
1682 1.1 cherry
1683 1.1 cherry /*
1684 1.1 cherry * Will be Zero since no specific value is set after the init
1685 1.1 cherry * due to failure
1686 1.1 cherry */
1687 1.1 cherry atf_tc_expect_signal(SIGABRT, "invalid uvm_physseg_t handle");
1688 1.1 cherry
1689 1.1 cherry ATF_CHECK_EQ(0, uvm_physseg_get_start_hint(upm));
1690 1.1 cherry }
1691 1.1 cherry
1692 1.1 cherry ATF_TC(uvm_physseg_get_pg);
1693 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_pg, tc)
1694 1.1 cherry {
1695 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned vm_page struct \
1696 1.1 cherry is correct when fetched by uvm_physseg_get_pg() call.");
1697 1.1 cherry }
1698 1.1 cherry ATF_TC_BODY(uvm_physseg_get_pg, tc)
1699 1.1 cherry {
1700 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1);
1701 1.1 cherry
1702 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
1703 1.1 cherry
1704 1.1 cherry struct vm_page *extracted_pg = NULL;
1705 1.1 cherry
1706 1.1 cherry uvm_physseg_t upm;
1707 1.1 cherry
1708 1.1 cherry setup();
1709 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1710 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1711 1.1 cherry
1712 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1713 1.1 cherry
1714 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1715 1.1 cherry
1716 1.1 cherry /* Now we initialize the segment */
1717 1.1 cherry uvm_physseg_init_seg(upm, pgs);
1718 1.1 cherry
1719 1.1 cherry ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages);
1720 1.1 cherry
1721 1.1 cherry ATF_REQUIRE_EQ(NULL, extracted_pg);
1722 1.1 cherry
1723 1.1 cherry /* Try fetching the 5th Page in the Segment */
1724 1.1 cherry extracted_pg = uvm_physseg_get_pg(upm, 5);
1725 1.1 cherry
1726 1.1 cherry /* Values of phys_addr is n * PAGE_SIZE where n is the page number */
1727 1.1 cherry ATF_CHECK_EQ(5 * PAGE_SIZE, extracted_pg->phys_addr);
1728 1.1 cherry
1729 1.1 cherry /* Try fetching the 113th Page in the Segment */
1730 1.1 cherry extracted_pg = uvm_physseg_get_pg(upm, 113);
1731 1.1 cherry
1732 1.1 cherry ATF_CHECK_EQ(113 * PAGE_SIZE, extracted_pg->phys_addr);
1733 1.1 cherry }
1734 1.1 cherry
1735 1.1 cherry #ifdef __HAVE_PMAP_PHYSSEG
1736 1.1 cherry ATF_TC(uvm_physseg_get_pmseg);
1737 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_pmseg, tc)
1738 1.1 cherry {
1739 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned pmap_physseg \
1740 1.1 cherry struct is correct when fetched by uvm_physseg_get_pmseg() call.");
1741 1.1 cherry }
1742 1.1 cherry ATF_TC_BODY(uvm_physseg_get_pmseg, tc)
1743 1.1 cherry {
1744 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1);
1745 1.1 cherry
1746 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
1747 1.1 cherry
1748 1.1 cherry struct pmap_physseg pmseg = { true };
1749 1.1 cherry
1750 1.1 cherry struct pmap_physseg *extracted_pmseg = NULL;
1751 1.1 cherry
1752 1.1 cherry uvm_physseg_t upm;
1753 1.1 cherry
1754 1.1 cherry setup();
1755 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1756 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1757 1.1 cherry
1758 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1759 1.1 cherry
1760 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1761 1.1 cherry
1762 1.1 cherry /* Now we initialize the segment */
1763 1.1 cherry uvm_physseg_init_seg(upm, pgs);
1764 1.1 cherry
1765 1.1 cherry ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages);
1766 1.1 cherry
1767 1.1 cherry ATF_REQUIRE_EQ(NULL, extracted_pmseg);
1768 1.1 cherry
1769 1.1 cherry ATF_REQUIRE_EQ(true, pmseg.dummy_variable);
1770 1.1 cherry
1771 1.1 cherry /* Extract the current pmseg */
1772 1.1 cherry extracted_pmseg = uvm_physseg_get_pmseg(upm);
1773 1.1 cherry
1774 1.1 cherry /*
1775 1.1 cherry * We can only check if it is not NULL
1776 1.1 cherry * We do not know the value it contains
1777 1.1 cherry */
1778 1.1 cherry ATF_CHECK(NULL != extracted_pmseg);
1779 1.1 cherry
1780 1.1 cherry extracted_pmseg->dummy_variable = pmseg.dummy_variable;
1781 1.1 cherry
1782 1.1 cherry /* Invert value to ensure test integrity */
1783 1.1 cherry pmseg.dummy_variable = false;
1784 1.1 cherry
1785 1.1 cherry ATF_REQUIRE_EQ(false, pmseg.dummy_variable);
1786 1.1 cherry
1787 1.1 cherry extracted_pmseg = uvm_physseg_get_pmseg(upm);
1788 1.1 cherry
1789 1.1 cherry ATF_CHECK(NULL != extracted_pmseg);
1790 1.1 cherry
1791 1.1 cherry ATF_CHECK_EQ(true, extracted_pmseg->dummy_variable);
1792 1.1 cherry }
1793 1.1 cherry #endif
1794 1.1 cherry
1795 1.1 cherry ATF_TC(vm_physseg_find);
1796 1.1 cherry ATF_TC_HEAD(vm_physseg_find, tc)
1797 1.1 cherry {
1798 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned segment number \
1799 1.1 cherry is correct when an PFN is passed into uvm_physseg_find() call. \
1800 1.1 cherry In addition to this the offset of the PFN from the start of \
1801 1.1 cherry segment is also set if the parameter is passed in as not NULL.");
1802 1.1 cherry }
1803 1.1 cherry ATF_TC_BODY(vm_physseg_find, tc)
1804 1.1 cherry {
1805 1.1 cherry psize_t offset = (psize_t) -1;
1806 1.1 cherry
1807 1.1 cherry uvm_physseg_t upm_first, result;
1808 1.1 cherry #if VM_PHYSSEG_MAX > 1
1809 1.1 cherry uvm_physseg_t upm_second;
1810 1.1 cherry #endif
1811 1.1 cherry
1812 1.1 cherry setup();
1813 1.1 cherry
1814 1.1 cherry upm_first = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1815 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1816 1.1 cherry
1817 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1818 1.1 cherry
1819 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1820 1.1 cherry
1821 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1822 1.1 cherry #if VM_PHYSSEG_MAX > 1
1823 1.1 cherry upm_second = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1824 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1825 1.1 cherry
1826 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
1827 1.1 cherry
1828 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1829 1.1 cherry #endif
1830 1.1 cherry
1831 1.1 cherry /* Under ONE_MEGABYTE is segment upm_first */
1832 1.1 cherry result = uvm_physseg_find(atop(ONE_MEGABYTE - 1024), NULL);
1833 1.1 cherry ATF_CHECK_EQ(upm_first, result);
1834 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_start(upm_first),
1835 1.1 cherry uvm_physseg_get_start(result));
1836 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_end(upm_first),
1837 1.1 cherry uvm_physseg_get_end(result));
1838 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_first),
1839 1.1 cherry uvm_physseg_get_avail_start(result));
1840 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_first),
1841 1.1 cherry uvm_physseg_get_avail_end(result));
1842 1.1 cherry
1843 1.1 cherry ATF_REQUIRE_EQ((psize_t) -1, offset);
1844 1.1 cherry
1845 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */
1846 1.1 cherry #if VM_PHYSSEG_MAX > 1
1847 1.1 cherry /* Over ONE_MEGABYTE is segment upm_second */
1848 1.1 cherry result = uvm_physseg_find(atop(ONE_MEGABYTE + 8192), &offset);
1849 1.1 cherry ATF_CHECK_EQ(upm_second, result);
1850 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_start(upm_second),
1851 1.1 cherry uvm_physseg_get_start(result));
1852 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_end(upm_second),
1853 1.1 cherry uvm_physseg_get_end(result));
1854 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_second),
1855 1.1 cherry uvm_physseg_get_avail_start(result));
1856 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_second),
1857 1.1 cherry uvm_physseg_get_avail_end(result));
1858 1.1 cherry
1859 1.1 cherry /* Offset is calculated based on PAGE_SIZE */
1860 1.1 cherry /* atop(ONE_MEGABYTE + (2 * PAGE_SIZE)) - VALID_START_PFN1 = 2 */
1861 1.1 cherry ATF_CHECK_EQ(2, offset);
1862 1.1 cherry #else
1863 1.1 cherry /* Under ONE_MEGABYTE is segment upm_first */
1864 1.1 cherry result = uvm_physseg_find(atop(ONE_MEGABYTE - 12288), &offset);
1865 1.1 cherry ATF_CHECK_EQ(upm_first, result);
1866 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_start(upm_first),
1867 1.1 cherry uvm_physseg_get_start(result));
1868 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_end(upm_first),
1869 1.1 cherry uvm_physseg_get_end(result));
1870 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_first),
1871 1.1 cherry uvm_physseg_get_avail_start(result));
1872 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_first),
1873 1.1 cherry uvm_physseg_get_avail_end(result));
1874 1.1 cherry
1875 1.1 cherry /* Offset is calculated based on PAGE_SIZE */
1876 1.1 cherry /* atop(ONE_MEGABYTE - (3 * PAGE_SIZE)) - VALID_START_PFN1 = 253 */
1877 1.1 cherry ATF_CHECK_EQ(253, offset);
1878 1.1 cherry #endif
1879 1.1 cherry }
1880 1.1 cherry
1881 1.1 cherry ATF_TC(vm_physseg_find_invalid);
1882 1.1 cherry ATF_TC_HEAD(vm_physseg_find_invalid, tc)
1883 1.1 cherry {
1884 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned segment number \
1885 1.1 cherry is (paddr_t) -1 when a non existant PFN is passed into \
1886 1.1 cherry uvm_physseg_find() call.");
1887 1.1 cherry }
1888 1.1 cherry ATF_TC_BODY(vm_physseg_find_invalid, tc)
1889 1.1 cherry {
1890 1.1 cherry psize_t offset = (psize_t) -1;
1891 1.1 cherry
1892 1.1 cherry setup();
1893 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
1894 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
1895 1.1 cherry
1896 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1897 1.1 cherry
1898 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1899 1.1 cherry
1900 1.1 cherry /* No segments over 3 MB exists at the moment */
1901 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID,
1902 1.1 cherry uvm_physseg_find(atop(ONE_MEGABYTE * 3), NULL));
1903 1.1 cherry
1904 1.1 cherry ATF_REQUIRE_EQ((psize_t) -1, offset);
1905 1.1 cherry
1906 1.1 cherry /* No segments over 3 MB exists at the moment */
1907 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID,
1908 1.1 cherry uvm_physseg_find(atop(ONE_MEGABYTE * 3), &offset));
1909 1.1 cherry
1910 1.1 cherry ATF_CHECK_EQ((psize_t) -1, offset);
1911 1.1 cherry }
1912 1.1 cherry
1913 1.1 cherry ATF_TC(uvm_page_physunload_start);
1914 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_start, tc)
1915 1.1 cherry {
1916 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\
1917 1.1 cherry call works without a panic(). Unloads from Start of the segment.");
1918 1.1 cherry }
1919 1.1 cherry ATF_TC_BODY(uvm_page_physunload_start, tc)
1920 1.1 cherry {
1921 1.1 cherry /*
1922 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called?
1923 1.1 cherry */
1924 1.1 cherry psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2);
1925 1.1 cherry
1926 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
1927 1.1 cherry
1928 1.1 cherry paddr_t p = 0;
1929 1.1 cherry
1930 1.1 cherry uvm_physseg_t upm;
1931 1.1 cherry
1932 1.1 cherry setup();
1933 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1934 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
1935 1.1 cherry
1936 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1937 1.1 cherry
1938 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1939 1.1 cherry
1940 1.1 cherry uvm_physseg_init_seg(upm, pgs);
1941 1.1 cherry
1942 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p));
1943 1.1 cherry
1944 1.1 cherry /*
1945 1.1 cherry * When called for first time, uvm_page_physload() removes the first PFN
1946 1.1 cherry *
1947 1.1 cherry * New avail start will be VALID_AVAIL_START_PFN_2 + 1
1948 1.1 cherry */
1949 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, atop(p));
1950 1.1 cherry
1951 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1,
1952 1.1 cherry uvm_physseg_get_avail_start(upm));
1953 1.1 cherry
1954 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2 + 1, uvm_physseg_get_start(upm));
1955 1.1 cherry
1956 1.1 cherry /* Rest of the stuff should remain the same */
1957 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
1958 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm));
1959 1.1 cherry }
1960 1.1 cherry
1961 1.1 cherry ATF_TC(uvm_page_physunload_end);
1962 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_end, tc)
1963 1.1 cherry {
1964 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\
1965 1.1 cherry call works without a panic(). Unloads from End of the segment.");
1966 1.1 cherry }
1967 1.1 cherry ATF_TC_BODY(uvm_page_physunload_end, tc)
1968 1.1 cherry {
1969 1.1 cherry /*
1970 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called?
1971 1.1 cherry */
1972 1.1 cherry paddr_t p = 0;
1973 1.1 cherry
1974 1.1 cherry uvm_physseg_t upm;
1975 1.1 cherry
1976 1.1 cherry setup();
1977 1.1 cherry /* Note: start != avail_start to remove from end. */
1978 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
1979 1.1 cherry VALID_AVAIL_START_PFN_2 + 1, VALID_AVAIL_END_PFN_2,
1980 1.1 cherry VM_FREELIST_DEFAULT);
1981 1.1 cherry
1982 1.1 cherry p = 0;
1983 1.1 cherry
1984 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
1985 1.1 cherry
1986 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
1987 1.1 cherry
1988 1.1 cherry ATF_REQUIRE(
1989 1.1 cherry uvm_physseg_get_avail_start(upm) != uvm_physseg_get_start(upm));
1990 1.1 cherry
1991 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p));
1992 1.1 cherry
1993 1.1 cherry /*
1994 1.1 cherry * Remember if X is the upper limit the actual valid pointer is X - 1
1995 1.1 cherry *
1996 1.1 cherry * For example if 256 is the upper limit for 1MB memory, last valid
1997 1.1 cherry * pointer is 256 - 1 = 255
1998 1.1 cherry */
1999 1.1 cherry
2000 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2 - 1, atop(p));
2001 1.1 cherry
2002 1.1 cherry /*
2003 1.1 cherry * When called for second time, uvm_page_physload() removes the last PFN
2004 1.1 cherry *
2005 1.1 cherry * New avail end will be VALID_AVAIL_END_PFN_2 - 1
2006 1.1 cherry * New end will be VALID_AVAIL_PFN_2 - 1
2007 1.1 cherry */
2008 1.1 cherry
2009 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2 - 1, uvm_physseg_get_avail_end(upm));
2010 1.1 cherry
2011 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2 - 1, uvm_physseg_get_end(upm));
2012 1.1 cherry
2013 1.1 cherry /* Rest of the stuff should remain the same */
2014 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1,
2015 1.1 cherry uvm_physseg_get_avail_start(upm));
2016 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
2017 1.1 cherry }
2018 1.1 cherry
2019 1.1 cherry ATF_TC(uvm_page_physunload_none);
2020 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_none, tc)
2021 1.1 cherry {
2022 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\
2023 1.1 cherry call works without a panic(). Does not unload from start or end \
2024 1.1 cherry because of non-aligned start / avail_start and end / avail_end \
2025 1.1 cherry respectively.");
2026 1.1 cherry }
2027 1.1 cherry ATF_TC_BODY(uvm_page_physunload_none, tc)
2028 1.1 cherry {
2029 1.1 cherry psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2);
2030 1.1 cherry
2031 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
2032 1.1 cherry
2033 1.1 cherry paddr_t p = 0;
2034 1.1 cherry
2035 1.1 cherry uvm_physseg_t upm;
2036 1.1 cherry
2037 1.1 cherry setup();
2038 1.1 cherry /*
2039 1.1 cherry * Note: start != avail_start and end != avail_end.
2040 1.1 cherry *
2041 1.1 cherry * This prevents any unload from occuring.
2042 1.1 cherry */
2043 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
2044 1.1 cherry VALID_AVAIL_START_PFN_2 + 1, VALID_AVAIL_END_PFN_2 - 1,
2045 1.1 cherry VM_FREELIST_DEFAULT);
2046 1.1 cherry
2047 1.1 cherry p = 0;
2048 1.1 cherry
2049 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
2050 1.1 cherry
2051 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
2052 1.1 cherry
2053 1.1 cherry ATF_REQUIRE(
2054 1.1 cherry uvm_physseg_get_avail_start(upm) != uvm_physseg_get_start(upm));
2055 1.1 cherry
2056 1.1 cherry uvm_physseg_init_seg(upm, pgs);
2057 1.1 cherry
2058 1.1 cherry ATF_CHECK_EQ(false, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p));
2059 1.1 cherry
2060 1.1 cherry /* uvm_page_physload() will no longer unload memory */
2061 1.1 cherry ATF_CHECK_EQ(0, p);
2062 1.1 cherry
2063 1.1 cherry /* Rest of the stuff should remain the same */
2064 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1,
2065 1.1 cherry uvm_physseg_get_avail_start(upm));
2066 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2 - 1,
2067 1.1 cherry uvm_physseg_get_avail_end(upm));
2068 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
2069 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
2070 1.1 cherry }
2071 1.1 cherry
2072 1.1 cherry ATF_TC(uvm_page_physunload_delete_start);
2073 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_delete_start, tc)
2074 1.1 cherry {
2075 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \
2076 1.1 cherry works when the segment gets small enough to be deleted scenario. \
2077 1.1 cherry NOTE: This one works deletes from start.");
2078 1.1 cherry }
2079 1.1 cherry ATF_TC_BODY(uvm_page_physunload_delete_start, tc)
2080 1.1 cherry {
2081 1.1 cherry /*
2082 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called?
2083 1.1 cherry */
2084 1.1 cherry paddr_t p = 0;
2085 1.1 cherry
2086 1.1 cherry uvm_physseg_t upm;
2087 1.1 cherry
2088 1.1 cherry setup();
2089 1.1 cherry
2090 1.1 cherry /*
2091 1.1 cherry * Setup the Nuke from Starting point
2092 1.1 cherry */
2093 1.1 cherry
2094 1.1 cherry upm = uvm_page_physload(VALID_END_PFN_1 - 1, VALID_END_PFN_1,
2095 1.1 cherry VALID_AVAIL_END_PFN_1 - 1, VALID_AVAIL_END_PFN_1,
2096 1.1 cherry VM_FREELIST_DEFAULT);
2097 1.1 cherry
2098 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
2099 1.1 cherry
2100 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
2101 1.1 cherry
2102 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */
2103 1.1 cherry #if VM_PHYSSEG_MAX > 1
2104 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
2105 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
2106 1.1 cherry
2107 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
2108 1.1 cherry #endif
2109 1.1 cherry
2110 1.1 cherry #if VM_PHYSSEG_MAX == 1
2111 1.1 cherry atf_tc_expect_signal(SIGABRT,
2112 1.1 cherry "cannot uvm_page_physunload() the last segment");
2113 1.1 cherry #endif
2114 1.1 cherry
2115 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p));
2116 1.1 cherry
2117 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1 - 1, atop(p));
2118 1.1 cherry
2119 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries());
2120 1.1 cherry
2121 1.1 cherry /* The only node now is the one we inserted second. */
2122 1.1 cherry upm = uvm_physseg_get_first();
2123 1.1 cherry
2124 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
2125 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
2126 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm));
2127 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm));
2128 1.1 cherry }
2129 1.1 cherry
2130 1.1 cherry ATF_TC(uvm_page_physunload_delete_end);
2131 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_delete_end, tc)
2132 1.1 cherry {
2133 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \
2134 1.1 cherry works when the segment gets small enough to be deleted scenario. \
2135 1.1 cherry NOTE: This one works deletes from end.");
2136 1.1 cherry }
2137 1.1 cherry ATF_TC_BODY(uvm_page_physunload_delete_end, tc)
2138 1.1 cherry {
2139 1.1 cherry /*
2140 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called?
2141 1.1 cherry */
2142 1.1 cherry
2143 1.1 cherry paddr_t p = 0;
2144 1.1 cherry
2145 1.1 cherry uvm_physseg_t upm;
2146 1.1 cherry
2147 1.1 cherry setup();
2148 1.1 cherry
2149 1.1 cherry /*
2150 1.1 cherry * Setup the Nuke from Ending point
2151 1.1 cherry */
2152 1.1 cherry
2153 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_START_PFN_1 + 2,
2154 1.1 cherry VALID_AVAIL_START_PFN_1 + 1, VALID_AVAIL_START_PFN_1 + 2,
2155 1.1 cherry VM_FREELIST_DEFAULT);
2156 1.1 cherry
2157 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
2158 1.1 cherry
2159 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
2160 1.1 cherry
2161 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */
2162 1.1 cherry #if VM_PHYSSEG_MAX > 1
2163 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
2164 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
2165 1.1 cherry
2166 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
2167 1.1 cherry #endif
2168 1.1 cherry
2169 1.1 cherry #if VM_PHYSSEG_MAX == 1
2170 1.1 cherry atf_tc_expect_signal(SIGABRT,
2171 1.1 cherry "cannot uvm_page_physunload() the last segment");
2172 1.1 cherry #endif
2173 1.1 cherry
2174 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p));
2175 1.1 cherry
2176 1.1 cherry p = 0;
2177 1.1 cherry
2178 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p));
2179 1.1 cherry
2180 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1 + 2, atop(p));
2181 1.1 cherry
2182 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries());
2183 1.1 cherry
2184 1.1 cherry /* The only node now is the one we inserted second. */
2185 1.1 cherry upm = uvm_physseg_get_first();
2186 1.1 cherry
2187 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm));
2188 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm));
2189 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm));
2190 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm));
2191 1.1 cherry }
2192 1.1 cherry
2193 1.1 cherry ATF_TC(uvm_page_physunload_invalid);
2194 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_invalid, tc)
2195 1.1 cherry {
2196 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \
2197 1.1 cherry fails when then Free list does not match.");
2198 1.1 cherry }
2199 1.1 cherry ATF_TC_BODY(uvm_page_physunload_invalid, tc)
2200 1.1 cherry {
2201 1.1 cherry psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2);
2202 1.1 cherry
2203 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages);
2204 1.1 cherry
2205 1.1 cherry paddr_t p = 0;
2206 1.1 cherry
2207 1.1 cherry uvm_physseg_t upm;
2208 1.1 cherry
2209 1.1 cherry setup();
2210 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
2211 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
2212 1.1 cherry
2213 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
2214 1.1 cherry
2215 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
2216 1.1 cherry
2217 1.1 cherry uvm_physseg_init_seg(upm, pgs);
2218 1.1 cherry
2219 1.1 cherry ATF_CHECK_EQ(false, uvm_page_physunload(upm, VM_FREELIST_FIRST4G, &p));
2220 1.1 cherry }
2221 1.1 cherry
2222 1.1 cherry ATF_TC(uvm_page_physunload_force);
2223 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_force, tc)
2224 1.1 cherry {
2225 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic \
2226 1.1 cherry uvm_page_physunload_force() including delete works without.");
2227 1.1 cherry }
2228 1.1 cherry ATF_TC_BODY(uvm_page_physunload_force, tc)
2229 1.1 cherry {
2230 1.1 cherry /*
2231 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called?
2232 1.1 cherry */
2233 1.1 cherry paddr_t p = 0;
2234 1.1 cherry
2235 1.1 cherry uvm_physseg_t upm;
2236 1.1 cherry
2237 1.1 cherry setup();
2238 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1,
2239 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT);
2240 1.1 cherry
2241 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
2242 1.1 cherry
2243 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
2244 1.1 cherry
2245 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */
2246 1.1 cherry #if VM_PHYSSEG_MAX > 1
2247 1.1 cherry /*
2248 1.1 cherry * We have couple of physloads done this is bacause of the fact that if
2249 1.1 cherry * we physunload all the PFs from a given range and we have only one
2250 1.1 cherry * segment in total a panic() is called
2251 1.1 cherry */
2252 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2,
2253 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT);
2254 1.1 cherry
2255 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries());
2256 1.1 cherry #endif
2257 1.1 cherry
2258 1.1 cherry #if VM_PHYSSEG_MAX == 1
2259 1.1 cherry atf_tc_expect_signal(SIGABRT,
2260 1.1 cherry "cannot uvm_page_physunload() the last segment");
2261 1.1 cherry #endif
2262 1.1 cherry
2263 1.1 cherry ATF_REQUIRE_EQ(VALID_AVAIL_START_PFN_1,
2264 1.1 cherry uvm_physseg_get_avail_start(upm));
2265 1.1 cherry
2266 1.1 cherry for(paddr_t i = VALID_AVAIL_START_PFN_1;
2267 1.1 cherry i < VALID_AVAIL_END_PFN_1; i++) {
2268 1.1 cherry ATF_CHECK_EQ(true,
2269 1.1 cherry uvm_page_physunload_force(upm, VM_FREELIST_DEFAULT, &p));
2270 1.1 cherry ATF_CHECK_EQ(i, atop(p));
2271 1.1 cherry
2272 1.1 cherry if(i + 1 < VALID_AVAIL_END_PFN_1)
2273 1.1 cherry ATF_CHECK_EQ(i + 1, uvm_physseg_get_avail_start(upm));
2274 1.1 cherry }
2275 1.1 cherry
2276 1.1 cherry /*
2277 1.1 cherry * Now we try to retrieve the segment, which has been removed
2278 1.1 cherry * from the system through force unloading all the pages inside it.
2279 1.1 cherry */
2280 1.1 cherry upm = uvm_physseg_find(VALID_AVAIL_END_PFN_1 - 1, NULL);
2281 1.1 cherry
2282 1.1 cherry /* It should no longer exist */
2283 1.1 cherry ATF_CHECK_EQ(NULL, upm);
2284 1.1 cherry
2285 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries());
2286 1.1 cherry }
2287 1.1 cherry
2288 1.1 cherry ATF_TC(uvm_page_physunload_force_invalid);
2289 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_force_invalid, tc)
2290 1.1 cherry {
2291 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the invalid conditions for \
2292 1.1 cherry uvm_page_physunload_force_invalid().");
2293 1.1 cherry }
2294 1.1 cherry ATF_TC_BODY(uvm_page_physunload_force_invalid, tc)
2295 1.1 cherry {
2296 1.1 cherry paddr_t p = 0;
2297 1.1 cherry
2298 1.1 cherry uvm_physseg_t upm;
2299 1.1 cherry
2300 1.1 cherry setup();
2301 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_START_PFN_2+ 1,
2302 1.1 cherry VALID_START_PFN_2, VALID_START_PFN_2, VM_FREELIST_DEFAULT);
2303 1.1 cherry
2304 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries());
2305 1.1 cherry
2306 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages);
2307 1.1 cherry
2308 1.1 cherry ATF_CHECK_EQ(false,
2309 1.1 cherry uvm_page_physunload_force(upm, VM_FREELIST_DEFAULT, &p));
2310 1.1 cherry
2311 1.1 cherry ATF_CHECK_EQ(0, p);
2312 1.1 cherry }
2313 1.1 cherry
2314 1.1 cherry ATF_TP_ADD_TCS(tp)
2315 1.1 cherry {
2316 1.1 cherry #if defined(UVM_HOTPLUG)
2317 1.1 cherry /* Internal */
2318 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_atboot_mismatch);
2319 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_atboot_overrun);
2320 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_sanity);
2321 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_free_atboot_mismatch);
2322 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_free_sanity);
2323 1.1 cherry #if VM_PHYSSEG_MAX > 1
2324 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_atboot_free_leak);
2325 1.1 cherry #endif
2326 1.1 cherry #endif /* UVM_HOTPLUG */
2327 1.1 cherry
2328 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_plug);
2329 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_unplug);
2330 1.1 cherry
2331 1.1 cherry /* Exported */
2332 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_init);
2333 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physload_preload);
2334 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physload_postboot);
2335 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_handle_immutable);
2336 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_seg_chomp_slab);
2337 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_from_slab);
2338 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_init_seg);
2339 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_start);
2340 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_start_invalid);
2341 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_end);
2342 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_end_invalid);
2343 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_start);
2344 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_start_invalid);
2345 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_end);
2346 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_end_invalid);
2347 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_next);
2348 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_next_invalid);
2349 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_prev);
2350 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_prev_invalid);
2351 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_first);
2352 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_last);
2353 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_valid);
2354 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_valid_invalid);
2355 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_highest);
2356 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_free_list);
2357 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_start_hint);
2358 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_set_start_hint);
2359 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_set_start_hint_invalid);
2360 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_pg);
2361 1.1 cherry
2362 1.1 cherry #ifdef __HAVE_PMAP_PHYSSEG
2363 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_pmseg);
2364 1.1 cherry #endif
2365 1.1 cherry ATF_TP_ADD_TC(tp, vm_physseg_find);
2366 1.1 cherry ATF_TP_ADD_TC(tp, vm_physseg_find_invalid);
2367 1.1 cherry
2368 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_start);
2369 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_end);
2370 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_none);
2371 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_delete_start);
2372 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_delete_end);
2373 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_invalid);
2374 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_force);
2375 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_force_invalid);
2376 1.1 cherry
2377 1.1 cherry return atf_no_error();
2378 1.1 cherry }
2379