blob: 058d3c332bec31766c59656f4be541cf03bc0807 [file] [log] [blame]
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2018 Simon Goldschmidt
4 */
5
6#include <common.h>
7#include <lmb.h>
8#include <dm/test.h>
9#include <test/ut.h>
10
11static int check_lmb(struct unit_test_state *uts, struct lmb *lmb,
12 phys_addr_t ram_base, phys_size_t ram_size,
13 unsigned long num_reserved,
14 phys_addr_t base1, phys_size_t size1,
15 phys_addr_t base2, phys_size_t size2,
16 phys_addr_t base3, phys_size_t size3)
17{
18 ut_asserteq(lmb->memory.cnt, 1);
19 ut_asserteq(lmb->memory.region[0].base, ram_base);
20 ut_asserteq(lmb->memory.region[0].size, ram_size);
21
22 ut_asserteq(lmb->reserved.cnt, num_reserved);
23 if (num_reserved > 0) {
24 ut_asserteq(lmb->reserved.region[0].base, base1);
25 ut_asserteq(lmb->reserved.region[0].size, size1);
26 }
27 if (num_reserved > 1) {
28 ut_asserteq(lmb->reserved.region[1].base, base2);
29 ut_asserteq(lmb->reserved.region[1].size, size2);
30 }
31 if (num_reserved > 2) {
32 ut_asserteq(lmb->reserved.region[2].base, base3);
33 ut_asserteq(lmb->reserved.region[2].size, size3);
34 }
35 return 0;
36}
37
38#define ASSERT_LMB(lmb, ram_base, ram_size, num_reserved, base1, size1, \
39 base2, size2, base3, size3) \
40 ut_assert(!check_lmb(uts, lmb, ram_base, ram_size, \
41 num_reserved, base1, size1, base2, size2, base3, \
42 size3))
43
44/*
45 * Test helper function that reserves 64 KiB somewhere in the simulated RAM and
46 * then does some alloc + free tests.
47 */
48static int test_multi_alloc(struct unit_test_state *uts,
49 const phys_addr_t ram, const phys_size_t ram_size,
50 const phys_addr_t alloc_64k_addr)
51{
52 const phys_addr_t ram_end = ram + ram_size;
53 const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000;
54
55 struct lmb lmb;
56 long ret;
57 phys_addr_t a, a2, b, b2, c, d;
58
59 /* check for overflow */
60 ut_assert(ram_end == 0 || ram_end > ram);
61 ut_assert(alloc_64k_end > alloc_64k_addr);
62 /* check input addresses + size */
63 ut_assert(alloc_64k_addr >= ram + 8);
64 ut_assert(alloc_64k_end <= ram_end - 8);
65
66 lmb_init(&lmb);
67
68 ret = lmb_add(&lmb, ram, ram_size);
69 ut_asserteq(ret, 0);
70
71 /* reserve 64KiB somewhere */
72 ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
73 ut_asserteq(ret, 0);
74 ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
75 0, 0, 0, 0);
76
77 /* allocate somewhere, should be at the end of RAM */
78 a = lmb_alloc(&lmb, 4, 1);
79 ut_asserteq(a, ram_end - 4);
80 ASSERT_LMB(&lmb, ram, ram_size, 2, alloc_64k_addr, 0x10000,
81 ram_end - 4, 4, 0, 0);
82 /* alloc below end of reserved region -> below reserved region */
83 b = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
84 ut_asserteq(b, alloc_64k_addr - 4);
85 ASSERT_LMB(&lmb, ram, ram_size, 2,
86 alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0);
87
88 /* 2nd time */
89 c = lmb_alloc(&lmb, 4, 1);
90 ut_asserteq(c, ram_end - 8);
91 ASSERT_LMB(&lmb, ram, ram_size, 2,
92 alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0);
93 d = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
94 ut_asserteq(d, alloc_64k_addr - 8);
95 ASSERT_LMB(&lmb, ram, ram_size, 2,
96 alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
97
98 ret = lmb_free(&lmb, a, 4);
99 ut_asserteq(ret, 0);
100 ASSERT_LMB(&lmb, ram, ram_size, 2,
101 alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
102 /* allocate again to ensure we get the same address */
103 a2 = lmb_alloc(&lmb, 4, 1);
104 ut_asserteq(a, a2);
105 ASSERT_LMB(&lmb, ram, ram_size, 2,
106 alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
107 ret = lmb_free(&lmb, a2, 4);
108 ut_asserteq(ret, 0);
109 ASSERT_LMB(&lmb, ram, ram_size, 2,
110 alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
111
112 ret = lmb_free(&lmb, b, 4);
113 ut_asserteq(ret, 0);
114 ASSERT_LMB(&lmb, ram, ram_size, 3,
115 alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
116 ram_end - 8, 4);
117 /* allocate again to ensure we get the same address */
118 b2 = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
119 ut_asserteq(b, b2);
120 ASSERT_LMB(&lmb, ram, ram_size, 2,
121 alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
122 ret = lmb_free(&lmb, b2, 4);
123 ut_asserteq(ret, 0);
124 ASSERT_LMB(&lmb, ram, ram_size, 3,
125 alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
126 ram_end - 8, 4);
127
128 ret = lmb_free(&lmb, c, 4);
129 ut_asserteq(ret, 0);
130 ASSERT_LMB(&lmb, ram, ram_size, 2,
131 alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0);
132 ret = lmb_free(&lmb, d, 4);
133 ut_asserteq(ret, 0);
134 ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
135 0, 0, 0, 0);
136
137 return 0;
138}
139
140static int test_multi_alloc_512mb(struct unit_test_state *uts,
141 const phys_addr_t ram)
142{
143 return test_multi_alloc(uts, ram, 0x20000000, ram + 0x10000000);
144}
145
146/* Create a memory region with one reserved region and allocate */
147static int lib_test_lmb_simple(struct unit_test_state *uts)
148{
Simon Goldschmidt6402d9b2019-01-14 22:38:15 +0100149 int ret;
150
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100151 /* simulate 512 MiB RAM beginning at 1GiB */
Simon Goldschmidt6402d9b2019-01-14 22:38:15 +0100152 ret = test_multi_alloc_512mb(uts, 0x40000000);
153 if (ret)
154 return ret;
155
156 /* simulate 512 MiB RAM beginning at 1.5GiB */
157 return test_multi_alloc_512mb(uts, 0xE0000000);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100158}
159
160DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
161
162/* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */
163static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram)
164{
165 const phys_size_t ram_size = 0x20000000;
166 const phys_size_t big_block_size = 0x10000000;
167 const phys_addr_t ram_end = ram + ram_size;
168 const phys_addr_t alloc_64k_addr = ram + 0x10000000;
169 struct lmb lmb;
170 long ret;
171 phys_addr_t a, b;
172
173 /* check for overflow */
174 ut_assert(ram_end == 0 || ram_end > ram);
175
176 lmb_init(&lmb);
177
178 ret = lmb_add(&lmb, ram, ram_size);
179 ut_asserteq(ret, 0);
180
181 /* reserve 64KiB in the middle of RAM */
182 ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
183 ut_asserteq(ret, 0);
184 ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
185 0, 0, 0, 0);
186
187 /* allocate a big block, should be below reserved */
188 a = lmb_alloc(&lmb, big_block_size, 1);
189 ut_asserteq(a, ram);
190 ASSERT_LMB(&lmb, ram, ram_size, 1, a,
191 big_block_size + 0x10000, 0, 0, 0, 0);
192 /* allocate 2nd big block */
193 /* This should fail, printing an error */
194 b = lmb_alloc(&lmb, big_block_size, 1);
195 ut_asserteq(b, 0);
196 ASSERT_LMB(&lmb, ram, ram_size, 1, a,
197 big_block_size + 0x10000, 0, 0, 0, 0);
198
199 ret = lmb_free(&lmb, a, big_block_size);
200 ut_asserteq(ret, 0);
201 ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
202 0, 0, 0, 0);
203
204 /* allocate too big block */
205 /* This should fail, printing an error */
206 a = lmb_alloc(&lmb, ram_size, 1);
207 ut_asserteq(a, 0);
208 ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
209 0, 0, 0, 0);
210
211 return 0;
212}
213
214static int lib_test_lmb_big(struct unit_test_state *uts)
215{
Simon Goldschmidt6402d9b2019-01-14 22:38:15 +0100216 int ret;
217
218 /* simulate 512 MiB RAM beginning at 1GiB */
219 ret = test_bigblock(uts, 0x40000000);
220 if (ret)
221 return ret;
222
223 /* simulate 512 MiB RAM beginning at 1.5GiB */
224 return test_bigblock(uts, 0xE0000000);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100225}
226
227DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
228
229/* Simulate 512 MiB RAM, allocate a block without previous reservation */
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100230static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram,
231 const phys_addr_t alloc_size, const ulong align)
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100232{
233 const phys_size_t ram_size = 0x20000000;
234 const phys_addr_t ram_end = ram + ram_size;
235 struct lmb lmb;
236 long ret;
237 phys_addr_t a, b;
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100238 const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) &
239 ~(align - 1);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100240
241 /* check for overflow */
242 ut_assert(ram_end == 0 || ram_end > ram);
243
244 lmb_init(&lmb);
245
246 ret = lmb_add(&lmb, ram, ram_size);
247 ut_asserteq(ret, 0);
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100248 ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100249
250 /* allocate a block */
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100251 a = lmb_alloc(&lmb, alloc_size, align);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100252 ut_assert(a != 0);
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100253 ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
254 alloc_size, 0, 0, 0, 0);
255 /* allocate another block */
256 b = lmb_alloc(&lmb, alloc_size, align);
257 ut_assert(b != 0);
258 if (alloc_size == alloc_size_aligned) {
259 ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size -
260 (alloc_size_aligned * 2), alloc_size * 2, 0, 0, 0,
261 0);
262 } else {
263 ASSERT_LMB(&lmb, ram, ram_size, 2, ram + ram_size -
264 (alloc_size_aligned * 2), alloc_size, ram + ram_size
265 - alloc_size_aligned, alloc_size, 0, 0);
266 }
267 /* and free them */
268 ret = lmb_free(&lmb, b, alloc_size);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100269 ut_asserteq(ret, 0);
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100270 ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
271 alloc_size, 0, 0, 0, 0);
272 ret = lmb_free(&lmb, a, alloc_size);
273 ut_asserteq(ret, 0);
274 ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100275
276 /* allocate a block with base*/
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100277 b = lmb_alloc_base(&lmb, alloc_size, align, ram_end);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100278 ut_assert(a == b);
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100279 ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
280 alloc_size, 0, 0, 0, 0);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100281 /* and free it */
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100282 ret = lmb_free(&lmb, b, alloc_size);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100283 ut_asserteq(ret, 0);
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100284 ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100285
286 return 0;
287}
288
289static int lib_test_lmb_noreserved(struct unit_test_state *uts)
290{
Simon Goldschmidt6402d9b2019-01-14 22:38:15 +0100291 int ret;
292
293 /* simulate 512 MiB RAM beginning at 1GiB */
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100294 ret = test_noreserved(uts, 0x40000000, 4, 1);
Simon Goldschmidt6402d9b2019-01-14 22:38:15 +0100295 if (ret)
296 return ret;
297
298 /* simulate 512 MiB RAM beginning at 1.5GiB */
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100299 return test_noreserved(uts, 0xE0000000, 4, 1);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100300}
301
302DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
303
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100304static int lib_test_lmb_unaligned_size(struct unit_test_state *uts)
305{
306 int ret;
307
308 /* simulate 512 MiB RAM beginning at 1GiB */
309 ret = test_noreserved(uts, 0x40000000, 5, 8);
310 if (ret)
311 return ret;
312
313 /* simulate 512 MiB RAM beginning at 1.5GiB */
314 return test_noreserved(uts, 0xE0000000, 5, 8);
315}
316
317DM_TEST(lib_test_lmb_unaligned_size, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Goldschmidt9f3b6272019-01-14 22:38:14 +0100318/*
319 * Simulate a RAM that starts at 0 and allocate down to address 0, which must
320 * fail as '0' means failure for the lmb_alloc functions.
321 */
322static int lib_test_lmb_at_0(struct unit_test_state *uts)
323{
324 const phys_addr_t ram = 0;
325 const phys_size_t ram_size = 0x20000000;
326 struct lmb lmb;
327 long ret;
328 phys_addr_t a, b;
329
330 lmb_init(&lmb);
331
332 ret = lmb_add(&lmb, ram, ram_size);
333 ut_asserteq(ret, 0);
334
335 /* allocate nearly everything */
336 a = lmb_alloc(&lmb, ram_size - 4, 1);
337 ut_asserteq(a, ram + 4);
338 ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
339 0, 0, 0, 0);
340 /* allocate the rest */
341 /* This should fail as the allocated address would be 0 */
342 b = lmb_alloc(&lmb, 4, 1);
343 ut_asserteq(b, 0);
344 /* check that this was an error by checking lmb */
345 ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
346 0, 0, 0, 0);
347 /* check that this was an error by freeing b */
348 ret = lmb_free(&lmb, b, 4);
349 ut_asserteq(ret, -1);
350 ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
351 0, 0, 0, 0);
352
353 ret = lmb_free(&lmb, a, ram_size - 4);
354 ut_asserteq(ret, 0);
355 ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
356
357 return 0;
358}
359
360DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Goldschmidtcb57d132019-01-14 22:38:16 +0100361
362/* Check that calling lmb_reserve with overlapping regions fails. */
363static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts)
364{
365 const phys_addr_t ram = 0x40000000;
366 const phys_size_t ram_size = 0x20000000;
367 struct lmb lmb;
368 long ret;
369
370 lmb_init(&lmb);
371
372 ret = lmb_add(&lmb, ram, ram_size);
373 ut_asserteq(ret, 0);
374
375 ret = lmb_reserve(&lmb, 0x40010000, 0x10000);
376 ut_asserteq(ret, 0);
377 ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
378 0, 0, 0, 0);
379 /* allocate overlapping region should fail */
380 ret = lmb_reserve(&lmb, 0x40011000, 0x10000);
381 ut_asserteq(ret, -1);
382 ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
383 0, 0, 0, 0);
384 /* allocate 3nd region */
385 ret = lmb_reserve(&lmb, 0x40030000, 0x10000);
386 ut_asserteq(ret, 0);
387 ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000,
388 0x40030000, 0x10000, 0, 0);
389 /* allocate 2nd region */
390 ret = lmb_reserve(&lmb, 0x40020000, 0x10000);
391 ut_assert(ret >= 0);
392 ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000,
393 0, 0, 0, 0);
394
395 return 0;
396}
397
398DM_TEST(lib_test_lmb_overlapping_reserve,
399 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Goldschmidt7a6ee462019-01-14 22:38:18 +0100400
401/*
402 * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between.
403 * Expect addresses outside the memory range to fail.
404 */
405static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
406{
407 const phys_size_t ram_size = 0x20000000;
408 const phys_addr_t ram_end = ram + ram_size;
409 const phys_size_t alloc_addr_a = ram + 0x8000000;
410 const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
411 const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
412 struct lmb lmb;
413 long ret;
414 phys_addr_t a, b, c, d, e;
415
416 /* check for overflow */
417 ut_assert(ram_end == 0 || ram_end > ram);
418
419 lmb_init(&lmb);
420
421 ret = lmb_add(&lmb, ram, ram_size);
422 ut_asserteq(ret, 0);
423
424 /* reserve 3 blocks */
425 ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
426 ut_asserteq(ret, 0);
427 ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
428 ut_asserteq(ret, 0);
429 ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
430 ut_asserteq(ret, 0);
431 ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
432 alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
433
434 /* allocate blocks */
435 a = lmb_alloc_addr(&lmb, ram, alloc_addr_a - ram);
436 ut_asserteq(a, ram);
437 ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000,
438 alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
439 b = lmb_alloc_addr(&lmb, alloc_addr_a + 0x10000,
440 alloc_addr_b - alloc_addr_a - 0x10000);
441 ut_asserteq(b, alloc_addr_a + 0x10000);
442 ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000,
443 alloc_addr_c, 0x10000, 0, 0);
444 c = lmb_alloc_addr(&lmb, alloc_addr_b + 0x10000,
445 alloc_addr_c - alloc_addr_b - 0x10000);
446 ut_asserteq(c, alloc_addr_b + 0x10000);
447 ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
448 0, 0, 0, 0);
449 d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000,
450 ram_end - alloc_addr_c - 0x10000);
451 ut_asserteq(d, alloc_addr_c + 0x10000);
452 ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
453 0, 0, 0, 0);
454
455 /* allocating anything else should fail */
456 e = lmb_alloc(&lmb, 1, 1);
457 ut_asserteq(e, 0);
458 ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
459 0, 0, 0, 0);
460
461 ret = lmb_free(&lmb, d, ram_end - alloc_addr_c - 0x10000);
462 ut_asserteq(ret, 0);
463
464 /* allocate at 3 points in free range */
465
466 d = lmb_alloc_addr(&lmb, ram_end - 4, 4);
467 ut_asserteq(d, ram_end - 4);
468 ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
469 d, 4, 0, 0);
470 ret = lmb_free(&lmb, d, 4);
471 ut_asserteq(ret, 0);
472 ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
473 0, 0, 0, 0);
474
475 d = lmb_alloc_addr(&lmb, ram_end - 128, 4);
476 ut_asserteq(d, ram_end - 128);
477 ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
478 d, 4, 0, 0);
479 ret = lmb_free(&lmb, d, 4);
480 ut_asserteq(ret, 0);
481 ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
482 0, 0, 0, 0);
483
484 d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, 4);
485 ut_asserteq(d, alloc_addr_c + 0x10000);
486 ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004,
487 0, 0, 0, 0);
488 ret = lmb_free(&lmb, d, 4);
489 ut_asserteq(ret, 0);
490 ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
491 0, 0, 0, 0);
492
493 /* allocate at the bottom */
494 ret = lmb_free(&lmb, a, alloc_addr_a - ram);
495 ut_asserteq(ret, 0);
496 ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000,
497 0, 0, 0, 0);
498 d = lmb_alloc_addr(&lmb, ram, 4);
499 ut_asserteq(d, ram);
500 ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4,
501 ram + 0x8000000, 0x10010000, 0, 0);
502
503 /* check that allocating outside memory fails */
504 if (ram_end != 0) {
505 ret = lmb_alloc_addr(&lmb, ram_end, 1);
506 ut_asserteq(ret, 0);
507 }
508 if (ram != 0) {
509 ret = lmb_alloc_addr(&lmb, ram - 1, 1);
510 ut_asserteq(ret, 0);
511 }
512
513 return 0;
514}
515
516static int lib_test_lmb_alloc_addr(struct unit_test_state *uts)
517{
518 int ret;
519
520 /* simulate 512 MiB RAM beginning at 1GiB */
521 ret = test_alloc_addr(uts, 0x40000000);
522 if (ret)
523 return ret;
524
525 /* simulate 512 MiB RAM beginning at 1.5GiB */
526 return test_alloc_addr(uts, 0xE0000000);
527}
528
529DM_TEST(lib_test_lmb_alloc_addr, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
530
531/* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */
532static int test_get_unreserved_size(struct unit_test_state *uts,
533 const phys_addr_t ram)
534{
535 const phys_size_t ram_size = 0x20000000;
536 const phys_addr_t ram_end = ram + ram_size;
537 const phys_size_t alloc_addr_a = ram + 0x8000000;
538 const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
539 const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
540 struct lmb lmb;
541 long ret;
542 phys_size_t s;
543
544 /* check for overflow */
545 ut_assert(ram_end == 0 || ram_end > ram);
546
547 lmb_init(&lmb);
548
549 ret = lmb_add(&lmb, ram, ram_size);
550 ut_asserteq(ret, 0);
551
552 /* reserve 3 blocks */
553 ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
554 ut_asserteq(ret, 0);
555 ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
556 ut_asserteq(ret, 0);
557 ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
558 ut_asserteq(ret, 0);
559 ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
560 alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
561
562 /* check addresses in between blocks */
563 s = lmb_get_unreserved_size(&lmb, ram);
564 ut_asserteq(s, alloc_addr_a - ram);
565 s = lmb_get_unreserved_size(&lmb, ram + 0x10000);
566 ut_asserteq(s, alloc_addr_a - ram - 0x10000);
567 s = lmb_get_unreserved_size(&lmb, alloc_addr_a - 4);
568 ut_asserteq(s, 4);
569
570 s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x10000);
571 ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x10000);
572 s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x20000);
573 ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x20000);
574 s = lmb_get_unreserved_size(&lmb, alloc_addr_b - 4);
575 ut_asserteq(s, 4);
576
577 s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x10000);
578 ut_asserteq(s, ram_end - alloc_addr_c - 0x10000);
579 s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x20000);
580 ut_asserteq(s, ram_end - alloc_addr_c - 0x20000);
581 s = lmb_get_unreserved_size(&lmb, ram_end - 4);
582 ut_asserteq(s, 4);
583
584 return 0;
585}
586
587static int lib_test_lmb_get_unreserved_size(struct unit_test_state *uts)
588{
589 int ret;
590
591 /* simulate 512 MiB RAM beginning at 1GiB */
592 ret = test_get_unreserved_size(uts, 0x40000000);
593 if (ret)
594 return ret;
595
596 /* simulate 512 MiB RAM beginning at 1.5GiB */
597 return test_get_unreserved_size(uts, 0xE0000000);
598}
599
600DM_TEST(lib_test_lmb_get_unreserved_size,
601 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);