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