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