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