1a01ae0c2SSimon Goldschmidt // SPDX-License-Identifier: GPL-2.0+
2a01ae0c2SSimon Goldschmidt /*
3a01ae0c2SSimon Goldschmidt * (C) Copyright 2018 Simon Goldschmidt
4a01ae0c2SSimon Goldschmidt */
5a01ae0c2SSimon Goldschmidt
6a01ae0c2SSimon Goldschmidt #include <common.h>
7a01ae0c2SSimon Goldschmidt #include <lmb.h>
8a01ae0c2SSimon Goldschmidt #include <dm/test.h>
9a01ae0c2SSimon Goldschmidt #include <test/ut.h>
10a01ae0c2SSimon Goldschmidt
check_lmb(struct unit_test_state * uts,struct lmb * lmb,phys_addr_t ram_base,phys_size_t ram_size,unsigned long num_reserved,phys_addr_t base1,phys_size_t size1,phys_addr_t base2,phys_size_t size2,phys_addr_t base3,phys_size_t size3)11a01ae0c2SSimon Goldschmidt static int check_lmb(struct unit_test_state *uts, struct lmb *lmb,
12a01ae0c2SSimon Goldschmidt phys_addr_t ram_base, phys_size_t ram_size,
13a01ae0c2SSimon Goldschmidt unsigned long num_reserved,
14a01ae0c2SSimon Goldschmidt phys_addr_t base1, phys_size_t size1,
15a01ae0c2SSimon Goldschmidt phys_addr_t base2, phys_size_t size2,
16a01ae0c2SSimon Goldschmidt phys_addr_t base3, phys_size_t size3)
17a01ae0c2SSimon Goldschmidt {
18*dc57be51SSimon Goldschmidt if (ram_size) {
19a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->memory.cnt, 1);
20a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->memory.region[0].base, ram_base);
21a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->memory.region[0].size, ram_size);
22*dc57be51SSimon Goldschmidt }
23a01ae0c2SSimon Goldschmidt
24a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->reserved.cnt, num_reserved);
25a01ae0c2SSimon Goldschmidt if (num_reserved > 0) {
26a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->reserved.region[0].base, base1);
27a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->reserved.region[0].size, size1);
28a01ae0c2SSimon Goldschmidt }
29a01ae0c2SSimon Goldschmidt if (num_reserved > 1) {
30a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->reserved.region[1].base, base2);
31a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->reserved.region[1].size, size2);
32a01ae0c2SSimon Goldschmidt }
33a01ae0c2SSimon Goldschmidt if (num_reserved > 2) {
34a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->reserved.region[2].base, base3);
35a01ae0c2SSimon Goldschmidt ut_asserteq(lmb->reserved.region[2].size, size3);
36a01ae0c2SSimon Goldschmidt }
37a01ae0c2SSimon Goldschmidt return 0;
38a01ae0c2SSimon Goldschmidt }
39a01ae0c2SSimon Goldschmidt
40a01ae0c2SSimon Goldschmidt #define ASSERT_LMB(lmb, ram_base, ram_size, num_reserved, base1, size1, \
41a01ae0c2SSimon Goldschmidt base2, size2, base3, size3) \
42a01ae0c2SSimon Goldschmidt ut_assert(!check_lmb(uts, lmb, ram_base, ram_size, \
43a01ae0c2SSimon Goldschmidt num_reserved, base1, size1, base2, size2, base3, \
44a01ae0c2SSimon Goldschmidt size3))
45a01ae0c2SSimon Goldschmidt
46a01ae0c2SSimon Goldschmidt /*
47a01ae0c2SSimon Goldschmidt * Test helper function that reserves 64 KiB somewhere in the simulated RAM and
48a01ae0c2SSimon Goldschmidt * then does some alloc + free tests.
49a01ae0c2SSimon Goldschmidt */
test_multi_alloc(struct unit_test_state * uts,const phys_addr_t ram,const phys_size_t ram_size,const phys_addr_t ram0,const phys_size_t ram0_size,const phys_addr_t alloc_64k_addr)50*dc57be51SSimon Goldschmidt static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
51*dc57be51SSimon Goldschmidt const phys_size_t ram_size, const phys_addr_t ram0,
52*dc57be51SSimon Goldschmidt const phys_size_t ram0_size,
53a01ae0c2SSimon Goldschmidt const phys_addr_t alloc_64k_addr)
54a01ae0c2SSimon Goldschmidt {
55a01ae0c2SSimon Goldschmidt const phys_addr_t ram_end = ram + ram_size;
56a01ae0c2SSimon Goldschmidt const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000;
57a01ae0c2SSimon Goldschmidt
58a01ae0c2SSimon Goldschmidt struct lmb lmb;
59a01ae0c2SSimon Goldschmidt long ret;
60a01ae0c2SSimon Goldschmidt phys_addr_t a, a2, b, b2, c, d;
61a01ae0c2SSimon Goldschmidt
62a01ae0c2SSimon Goldschmidt /* check for overflow */
63a01ae0c2SSimon Goldschmidt ut_assert(ram_end == 0 || ram_end > ram);
64a01ae0c2SSimon Goldschmidt ut_assert(alloc_64k_end > alloc_64k_addr);
65a01ae0c2SSimon Goldschmidt /* check input addresses + size */
66a01ae0c2SSimon Goldschmidt ut_assert(alloc_64k_addr >= ram + 8);
67a01ae0c2SSimon Goldschmidt ut_assert(alloc_64k_end <= ram_end - 8);
68a01ae0c2SSimon Goldschmidt
69a01ae0c2SSimon Goldschmidt lmb_init(&lmb);
70a01ae0c2SSimon Goldschmidt
71*dc57be51SSimon Goldschmidt if (ram0_size) {
72*dc57be51SSimon Goldschmidt ret = lmb_add(&lmb, ram0, ram0_size);
73*dc57be51SSimon Goldschmidt ut_asserteq(ret, 0);
74*dc57be51SSimon Goldschmidt }
75*dc57be51SSimon Goldschmidt
76a01ae0c2SSimon Goldschmidt ret = lmb_add(&lmb, ram, ram_size);
77a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
78a01ae0c2SSimon Goldschmidt
79*dc57be51SSimon Goldschmidt if (ram0_size) {
80*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.cnt, 2);
81*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].base, ram0);
82*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].size, ram0_size);
83*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[1].base, ram);
84*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[1].size, ram_size);
85*dc57be51SSimon Goldschmidt } else {
86*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.cnt, 1);
87*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].base, ram);
88*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].size, ram_size);
89*dc57be51SSimon Goldschmidt }
90*dc57be51SSimon Goldschmidt
91a01ae0c2SSimon Goldschmidt /* reserve 64KiB somewhere */
92a01ae0c2SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
93a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
94*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 1, alloc_64k_addr, 0x10000,
95a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
96a01ae0c2SSimon Goldschmidt
97a01ae0c2SSimon Goldschmidt /* allocate somewhere, should be at the end of RAM */
98a01ae0c2SSimon Goldschmidt a = lmb_alloc(&lmb, 4, 1);
99a01ae0c2SSimon Goldschmidt ut_asserteq(a, ram_end - 4);
100*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr, 0x10000,
101a01ae0c2SSimon Goldschmidt ram_end - 4, 4, 0, 0);
102a01ae0c2SSimon Goldschmidt /* alloc below end of reserved region -> below reserved region */
103a01ae0c2SSimon Goldschmidt b = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
104a01ae0c2SSimon Goldschmidt ut_asserteq(b, alloc_64k_addr - 4);
105*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
106a01ae0c2SSimon Goldschmidt alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0);
107a01ae0c2SSimon Goldschmidt
108a01ae0c2SSimon Goldschmidt /* 2nd time */
109a01ae0c2SSimon Goldschmidt c = lmb_alloc(&lmb, 4, 1);
110a01ae0c2SSimon Goldschmidt ut_asserteq(c, ram_end - 8);
111*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
112a01ae0c2SSimon Goldschmidt alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0);
113a01ae0c2SSimon Goldschmidt d = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
114a01ae0c2SSimon Goldschmidt ut_asserteq(d, alloc_64k_addr - 8);
115*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
116a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
117a01ae0c2SSimon Goldschmidt
118a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, a, 4);
119a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
120*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
121a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
122a01ae0c2SSimon Goldschmidt /* allocate again to ensure we get the same address */
123a01ae0c2SSimon Goldschmidt a2 = lmb_alloc(&lmb, 4, 1);
124a01ae0c2SSimon Goldschmidt ut_asserteq(a, a2);
125*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
126a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
127a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, a2, 4);
128a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
129*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
130a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
131a01ae0c2SSimon Goldschmidt
132a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, b, 4);
133a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
134*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 3,
135a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
136a01ae0c2SSimon Goldschmidt ram_end - 8, 4);
137a01ae0c2SSimon Goldschmidt /* allocate again to ensure we get the same address */
138a01ae0c2SSimon Goldschmidt b2 = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
139a01ae0c2SSimon Goldschmidt ut_asserteq(b, b2);
140*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
141a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
142a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, b2, 4);
143a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
144*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 3,
145a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
146a01ae0c2SSimon Goldschmidt ram_end - 8, 4);
147a01ae0c2SSimon Goldschmidt
148a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, c, 4);
149a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
150*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 2,
151a01ae0c2SSimon Goldschmidt alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0);
152a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, d, 4);
153a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
154*dc57be51SSimon Goldschmidt ASSERT_LMB(&lmb, 0, 0, 1, alloc_64k_addr, 0x10000,
155a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
156a01ae0c2SSimon Goldschmidt
157*dc57be51SSimon Goldschmidt if (ram0_size) {
158*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.cnt, 2);
159*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].base, ram0);
160*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].size, ram0_size);
161*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[1].base, ram);
162*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[1].size, ram_size);
163*dc57be51SSimon Goldschmidt } else {
164*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.cnt, 1);
165*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].base, ram);
166*dc57be51SSimon Goldschmidt ut_asserteq(lmb.memory.region[0].size, ram_size);
167*dc57be51SSimon Goldschmidt }
168*dc57be51SSimon Goldschmidt
169a01ae0c2SSimon Goldschmidt return 0;
170a01ae0c2SSimon Goldschmidt }
171a01ae0c2SSimon Goldschmidt
test_multi_alloc_512mb(struct unit_test_state * uts,const phys_addr_t ram)172a01ae0c2SSimon Goldschmidt static int test_multi_alloc_512mb(struct unit_test_state *uts,
173a01ae0c2SSimon Goldschmidt const phys_addr_t ram)
174a01ae0c2SSimon Goldschmidt {
175*dc57be51SSimon Goldschmidt return test_multi_alloc(uts, ram, 0x20000000, 0, 0, ram + 0x10000000);
176*dc57be51SSimon Goldschmidt }
177*dc57be51SSimon Goldschmidt
test_multi_alloc_512mb_x2(struct unit_test_state * uts,const phys_addr_t ram,const phys_addr_t ram0)178*dc57be51SSimon Goldschmidt static int test_multi_alloc_512mb_x2(struct unit_test_state *uts,
179*dc57be51SSimon Goldschmidt const phys_addr_t ram,
180*dc57be51SSimon Goldschmidt const phys_addr_t ram0)
181*dc57be51SSimon Goldschmidt {
182*dc57be51SSimon Goldschmidt return test_multi_alloc(uts, ram, 0x20000000, ram0, 0x20000000,
183*dc57be51SSimon Goldschmidt ram + 0x10000000);
184a01ae0c2SSimon Goldschmidt }
185a01ae0c2SSimon Goldschmidt
186a01ae0c2SSimon Goldschmidt /* Create a memory region with one reserved region and allocate */
lib_test_lmb_simple(struct unit_test_state * uts)187a01ae0c2SSimon Goldschmidt static int lib_test_lmb_simple(struct unit_test_state *uts)
188a01ae0c2SSimon Goldschmidt {
189d67f33cfSSimon Goldschmidt int ret;
190d67f33cfSSimon Goldschmidt
191a01ae0c2SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1GiB */
192d67f33cfSSimon Goldschmidt ret = test_multi_alloc_512mb(uts, 0x40000000);
193d67f33cfSSimon Goldschmidt if (ret)
194d67f33cfSSimon Goldschmidt return ret;
195d67f33cfSSimon Goldschmidt
196d67f33cfSSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1.5GiB */
197d67f33cfSSimon Goldschmidt return test_multi_alloc_512mb(uts, 0xE0000000);
198a01ae0c2SSimon Goldschmidt }
199a01ae0c2SSimon Goldschmidt
200a01ae0c2SSimon Goldschmidt DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
201a01ae0c2SSimon Goldschmidt
202*dc57be51SSimon Goldschmidt /* Create two memory regions with one reserved region and allocate */
lib_test_lmb_simple_x2(struct unit_test_state * uts)203*dc57be51SSimon Goldschmidt static int lib_test_lmb_simple_x2(struct unit_test_state *uts)
204*dc57be51SSimon Goldschmidt {
205*dc57be51SSimon Goldschmidt int ret;
206*dc57be51SSimon Goldschmidt
207*dc57be51SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 2GiB and 1 GiB */
208*dc57be51SSimon Goldschmidt ret = test_multi_alloc_512mb_x2(uts, 0x80000000, 0x40000000);
209*dc57be51SSimon Goldschmidt if (ret)
210*dc57be51SSimon Goldschmidt return ret;
211*dc57be51SSimon Goldschmidt
212*dc57be51SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 3.5GiB and 1 GiB */
213*dc57be51SSimon Goldschmidt return test_multi_alloc_512mb_x2(uts, 0xE0000000, 0x40000000);
214*dc57be51SSimon Goldschmidt }
215*dc57be51SSimon Goldschmidt
216*dc57be51SSimon Goldschmidt DM_TEST(lib_test_lmb_simple_x2, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
217*dc57be51SSimon Goldschmidt
218a01ae0c2SSimon Goldschmidt /* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */
test_bigblock(struct unit_test_state * uts,const phys_addr_t ram)219a01ae0c2SSimon Goldschmidt static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram)
220a01ae0c2SSimon Goldschmidt {
221a01ae0c2SSimon Goldschmidt const phys_size_t ram_size = 0x20000000;
222a01ae0c2SSimon Goldschmidt const phys_size_t big_block_size = 0x10000000;
223a01ae0c2SSimon Goldschmidt const phys_addr_t ram_end = ram + ram_size;
224a01ae0c2SSimon Goldschmidt const phys_addr_t alloc_64k_addr = ram + 0x10000000;
225a01ae0c2SSimon Goldschmidt struct lmb lmb;
226a01ae0c2SSimon Goldschmidt long ret;
227a01ae0c2SSimon Goldschmidt phys_addr_t a, b;
228a01ae0c2SSimon Goldschmidt
229a01ae0c2SSimon Goldschmidt /* check for overflow */
230a01ae0c2SSimon Goldschmidt ut_assert(ram_end == 0 || ram_end > ram);
231a01ae0c2SSimon Goldschmidt
232a01ae0c2SSimon Goldschmidt lmb_init(&lmb);
233a01ae0c2SSimon Goldschmidt
234a01ae0c2SSimon Goldschmidt ret = lmb_add(&lmb, ram, ram_size);
235a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
236a01ae0c2SSimon Goldschmidt
237a01ae0c2SSimon Goldschmidt /* reserve 64KiB in the middle of RAM */
238a01ae0c2SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
239a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
240a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
241a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
242a01ae0c2SSimon Goldschmidt
243a01ae0c2SSimon Goldschmidt /* allocate a big block, should be below reserved */
244a01ae0c2SSimon Goldschmidt a = lmb_alloc(&lmb, big_block_size, 1);
245a01ae0c2SSimon Goldschmidt ut_asserteq(a, ram);
246a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, a,
247a01ae0c2SSimon Goldschmidt big_block_size + 0x10000, 0, 0, 0, 0);
248a01ae0c2SSimon Goldschmidt /* allocate 2nd big block */
249a01ae0c2SSimon Goldschmidt /* This should fail, printing an error */
250a01ae0c2SSimon Goldschmidt b = lmb_alloc(&lmb, big_block_size, 1);
251a01ae0c2SSimon Goldschmidt ut_asserteq(b, 0);
252a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, a,
253a01ae0c2SSimon Goldschmidt big_block_size + 0x10000, 0, 0, 0, 0);
254a01ae0c2SSimon Goldschmidt
255a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, a, big_block_size);
256a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
257a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
258a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
259a01ae0c2SSimon Goldschmidt
260a01ae0c2SSimon Goldschmidt /* allocate too big block */
261a01ae0c2SSimon Goldschmidt /* This should fail, printing an error */
262a01ae0c2SSimon Goldschmidt a = lmb_alloc(&lmb, ram_size, 1);
263a01ae0c2SSimon Goldschmidt ut_asserteq(a, 0);
264a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
265a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
266a01ae0c2SSimon Goldschmidt
267a01ae0c2SSimon Goldschmidt return 0;
268a01ae0c2SSimon Goldschmidt }
269a01ae0c2SSimon Goldschmidt
lib_test_lmb_big(struct unit_test_state * uts)270a01ae0c2SSimon Goldschmidt static int lib_test_lmb_big(struct unit_test_state *uts)
271a01ae0c2SSimon Goldschmidt {
272d67f33cfSSimon Goldschmidt int ret;
273d67f33cfSSimon Goldschmidt
274d67f33cfSSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1GiB */
275d67f33cfSSimon Goldschmidt ret = test_bigblock(uts, 0x40000000);
276d67f33cfSSimon Goldschmidt if (ret)
277d67f33cfSSimon Goldschmidt return ret;
278d67f33cfSSimon Goldschmidt
279d67f33cfSSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1.5GiB */
280d67f33cfSSimon Goldschmidt return test_bigblock(uts, 0xE0000000);
281a01ae0c2SSimon Goldschmidt }
282a01ae0c2SSimon Goldschmidt
283a01ae0c2SSimon Goldschmidt DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
284a01ae0c2SSimon Goldschmidt
285a01ae0c2SSimon Goldschmidt /* Simulate 512 MiB RAM, allocate a block without previous reservation */
test_noreserved(struct unit_test_state * uts,const phys_addr_t ram,const phys_addr_t alloc_size,const ulong align)2860f7c51a6SSimon Goldschmidt static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram,
2870f7c51a6SSimon Goldschmidt const phys_addr_t alloc_size, const ulong align)
288a01ae0c2SSimon Goldschmidt {
289a01ae0c2SSimon Goldschmidt const phys_size_t ram_size = 0x20000000;
290a01ae0c2SSimon Goldschmidt const phys_addr_t ram_end = ram + ram_size;
291a01ae0c2SSimon Goldschmidt struct lmb lmb;
292a01ae0c2SSimon Goldschmidt long ret;
293a01ae0c2SSimon Goldschmidt phys_addr_t a, b;
2940f7c51a6SSimon Goldschmidt const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) &
2950f7c51a6SSimon Goldschmidt ~(align - 1);
296a01ae0c2SSimon Goldschmidt
297a01ae0c2SSimon Goldschmidt /* check for overflow */
298a01ae0c2SSimon Goldschmidt ut_assert(ram_end == 0 || ram_end > ram);
299a01ae0c2SSimon Goldschmidt
300a01ae0c2SSimon Goldschmidt lmb_init(&lmb);
301a01ae0c2SSimon Goldschmidt
302a01ae0c2SSimon Goldschmidt ret = lmb_add(&lmb, ram, ram_size);
303a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
3040f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
305a01ae0c2SSimon Goldschmidt
306a01ae0c2SSimon Goldschmidt /* allocate a block */
3070f7c51a6SSimon Goldschmidt a = lmb_alloc(&lmb, alloc_size, align);
308a01ae0c2SSimon Goldschmidt ut_assert(a != 0);
3090f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
3100f7c51a6SSimon Goldschmidt alloc_size, 0, 0, 0, 0);
3110f7c51a6SSimon Goldschmidt /* allocate another block */
3120f7c51a6SSimon Goldschmidt b = lmb_alloc(&lmb, alloc_size, align);
3130f7c51a6SSimon Goldschmidt ut_assert(b != 0);
3140f7c51a6SSimon Goldschmidt if (alloc_size == alloc_size_aligned) {
3150f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size -
3160f7c51a6SSimon Goldschmidt (alloc_size_aligned * 2), alloc_size * 2, 0, 0, 0,
3170f7c51a6SSimon Goldschmidt 0);
3180f7c51a6SSimon Goldschmidt } else {
3190f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 2, ram + ram_size -
3200f7c51a6SSimon Goldschmidt (alloc_size_aligned * 2), alloc_size, ram + ram_size
3210f7c51a6SSimon Goldschmidt - alloc_size_aligned, alloc_size, 0, 0);
3220f7c51a6SSimon Goldschmidt }
3230f7c51a6SSimon Goldschmidt /* and free them */
3240f7c51a6SSimon Goldschmidt ret = lmb_free(&lmb, b, alloc_size);
325a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
3260f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
3270f7c51a6SSimon Goldschmidt alloc_size, 0, 0, 0, 0);
3280f7c51a6SSimon Goldschmidt ret = lmb_free(&lmb, a, alloc_size);
3290f7c51a6SSimon Goldschmidt ut_asserteq(ret, 0);
3300f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
331a01ae0c2SSimon Goldschmidt
332a01ae0c2SSimon Goldschmidt /* allocate a block with base*/
3330f7c51a6SSimon Goldschmidt b = lmb_alloc_base(&lmb, alloc_size, align, ram_end);
334a01ae0c2SSimon Goldschmidt ut_assert(a == b);
3350f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
3360f7c51a6SSimon Goldschmidt alloc_size, 0, 0, 0, 0);
337a01ae0c2SSimon Goldschmidt /* and free it */
3380f7c51a6SSimon Goldschmidt ret = lmb_free(&lmb, b, alloc_size);
339a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
3400f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
341a01ae0c2SSimon Goldschmidt
342a01ae0c2SSimon Goldschmidt return 0;
343a01ae0c2SSimon Goldschmidt }
344a01ae0c2SSimon Goldschmidt
lib_test_lmb_noreserved(struct unit_test_state * uts)345a01ae0c2SSimon Goldschmidt static int lib_test_lmb_noreserved(struct unit_test_state *uts)
346a01ae0c2SSimon Goldschmidt {
347d67f33cfSSimon Goldschmidt int ret;
348d67f33cfSSimon Goldschmidt
349d67f33cfSSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1GiB */
3500f7c51a6SSimon Goldschmidt ret = test_noreserved(uts, 0x40000000, 4, 1);
351d67f33cfSSimon Goldschmidt if (ret)
352d67f33cfSSimon Goldschmidt return ret;
353d67f33cfSSimon Goldschmidt
354d67f33cfSSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1.5GiB */
3550f7c51a6SSimon Goldschmidt return test_noreserved(uts, 0xE0000000, 4, 1);
356a01ae0c2SSimon Goldschmidt }
357a01ae0c2SSimon Goldschmidt
358a01ae0c2SSimon Goldschmidt DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
359a01ae0c2SSimon Goldschmidt
lib_test_lmb_unaligned_size(struct unit_test_state * uts)3600f7c51a6SSimon Goldschmidt static int lib_test_lmb_unaligned_size(struct unit_test_state *uts)
3610f7c51a6SSimon Goldschmidt {
3620f7c51a6SSimon Goldschmidt int ret;
3630f7c51a6SSimon Goldschmidt
3640f7c51a6SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1GiB */
3650f7c51a6SSimon Goldschmidt ret = test_noreserved(uts, 0x40000000, 5, 8);
3660f7c51a6SSimon Goldschmidt if (ret)
3670f7c51a6SSimon Goldschmidt return ret;
3680f7c51a6SSimon Goldschmidt
3690f7c51a6SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1.5GiB */
3700f7c51a6SSimon Goldschmidt return test_noreserved(uts, 0xE0000000, 5, 8);
3710f7c51a6SSimon Goldschmidt }
3720f7c51a6SSimon Goldschmidt
3730f7c51a6SSimon Goldschmidt DM_TEST(lib_test_lmb_unaligned_size, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
374a01ae0c2SSimon Goldschmidt /*
375a01ae0c2SSimon Goldschmidt * Simulate a RAM that starts at 0 and allocate down to address 0, which must
376a01ae0c2SSimon Goldschmidt * fail as '0' means failure for the lmb_alloc functions.
377a01ae0c2SSimon Goldschmidt */
lib_test_lmb_at_0(struct unit_test_state * uts)378a01ae0c2SSimon Goldschmidt static int lib_test_lmb_at_0(struct unit_test_state *uts)
379a01ae0c2SSimon Goldschmidt {
380a01ae0c2SSimon Goldschmidt const phys_addr_t ram = 0;
381a01ae0c2SSimon Goldschmidt const phys_size_t ram_size = 0x20000000;
382a01ae0c2SSimon Goldschmidt struct lmb lmb;
383a01ae0c2SSimon Goldschmidt long ret;
384a01ae0c2SSimon Goldschmidt phys_addr_t a, b;
385a01ae0c2SSimon Goldschmidt
386a01ae0c2SSimon Goldschmidt lmb_init(&lmb);
387a01ae0c2SSimon Goldschmidt
388a01ae0c2SSimon Goldschmidt ret = lmb_add(&lmb, ram, ram_size);
389a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
390a01ae0c2SSimon Goldschmidt
391a01ae0c2SSimon Goldschmidt /* allocate nearly everything */
392a01ae0c2SSimon Goldschmidt a = lmb_alloc(&lmb, ram_size - 4, 1);
393a01ae0c2SSimon Goldschmidt ut_asserteq(a, ram + 4);
394a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
395a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
396a01ae0c2SSimon Goldschmidt /* allocate the rest */
397a01ae0c2SSimon Goldschmidt /* This should fail as the allocated address would be 0 */
398a01ae0c2SSimon Goldschmidt b = lmb_alloc(&lmb, 4, 1);
399a01ae0c2SSimon Goldschmidt ut_asserteq(b, 0);
400a01ae0c2SSimon Goldschmidt /* check that this was an error by checking lmb */
401a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
402a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
403a01ae0c2SSimon Goldschmidt /* check that this was an error by freeing b */
404a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, b, 4);
405a01ae0c2SSimon Goldschmidt ut_asserteq(ret, -1);
406a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
407a01ae0c2SSimon Goldschmidt 0, 0, 0, 0);
408a01ae0c2SSimon Goldschmidt
409a01ae0c2SSimon Goldschmidt ret = lmb_free(&lmb, a, ram_size - 4);
410a01ae0c2SSimon Goldschmidt ut_asserteq(ret, 0);
411a01ae0c2SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
412a01ae0c2SSimon Goldschmidt
413a01ae0c2SSimon Goldschmidt return 0;
414a01ae0c2SSimon Goldschmidt }
415a01ae0c2SSimon Goldschmidt
416a01ae0c2SSimon Goldschmidt DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
4170f7c51a6SSimon Goldschmidt
4180f7c51a6SSimon Goldschmidt /* Check that calling lmb_reserve with overlapping regions fails. */
lib_test_lmb_overlapping_reserve(struct unit_test_state * uts)4190f7c51a6SSimon Goldschmidt static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts)
4200f7c51a6SSimon Goldschmidt {
4210f7c51a6SSimon Goldschmidt const phys_addr_t ram = 0x40000000;
4220f7c51a6SSimon Goldschmidt const phys_size_t ram_size = 0x20000000;
4230f7c51a6SSimon Goldschmidt struct lmb lmb;
4240f7c51a6SSimon Goldschmidt long ret;
4250f7c51a6SSimon Goldschmidt
4260f7c51a6SSimon Goldschmidt lmb_init(&lmb);
4270f7c51a6SSimon Goldschmidt
4280f7c51a6SSimon Goldschmidt ret = lmb_add(&lmb, ram, ram_size);
4290f7c51a6SSimon Goldschmidt ut_asserteq(ret, 0);
4300f7c51a6SSimon Goldschmidt
4310f7c51a6SSimon Goldschmidt ret = lmb_reserve(&lmb, 0x40010000, 0x10000);
4320f7c51a6SSimon Goldschmidt ut_asserteq(ret, 0);
4330f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
4340f7c51a6SSimon Goldschmidt 0, 0, 0, 0);
4350f7c51a6SSimon Goldschmidt /* allocate overlapping region should fail */
4360f7c51a6SSimon Goldschmidt ret = lmb_reserve(&lmb, 0x40011000, 0x10000);
4370f7c51a6SSimon Goldschmidt ut_asserteq(ret, -1);
4380f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
4390f7c51a6SSimon Goldschmidt 0, 0, 0, 0);
4400f7c51a6SSimon Goldschmidt /* allocate 3nd region */
4410f7c51a6SSimon Goldschmidt ret = lmb_reserve(&lmb, 0x40030000, 0x10000);
4420f7c51a6SSimon Goldschmidt ut_asserteq(ret, 0);
4430f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000,
4440f7c51a6SSimon Goldschmidt 0x40030000, 0x10000, 0, 0);
4450f7c51a6SSimon Goldschmidt /* allocate 2nd region */
4460f7c51a6SSimon Goldschmidt ret = lmb_reserve(&lmb, 0x40020000, 0x10000);
4470f7c51a6SSimon Goldschmidt ut_assert(ret >= 0);
4480f7c51a6SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000,
4490f7c51a6SSimon Goldschmidt 0, 0, 0, 0);
4500f7c51a6SSimon Goldschmidt
4510f7c51a6SSimon Goldschmidt return 0;
4520f7c51a6SSimon Goldschmidt }
4530f7c51a6SSimon Goldschmidt
4540f7c51a6SSimon Goldschmidt DM_TEST(lib_test_lmb_overlapping_reserve,
4550f7c51a6SSimon Goldschmidt DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
4564cc8af80SSimon Goldschmidt
4574cc8af80SSimon Goldschmidt /*
4584cc8af80SSimon Goldschmidt * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between.
4594cc8af80SSimon Goldschmidt * Expect addresses outside the memory range to fail.
4604cc8af80SSimon Goldschmidt */
test_alloc_addr(struct unit_test_state * uts,const phys_addr_t ram)4614cc8af80SSimon Goldschmidt static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
4624cc8af80SSimon Goldschmidt {
4634cc8af80SSimon Goldschmidt const phys_size_t ram_size = 0x20000000;
4644cc8af80SSimon Goldschmidt const phys_addr_t ram_end = ram + ram_size;
4654cc8af80SSimon Goldschmidt const phys_size_t alloc_addr_a = ram + 0x8000000;
4664cc8af80SSimon Goldschmidt const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
4674cc8af80SSimon Goldschmidt const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
4684cc8af80SSimon Goldschmidt struct lmb lmb;
4694cc8af80SSimon Goldschmidt long ret;
4704cc8af80SSimon Goldschmidt phys_addr_t a, b, c, d, e;
4714cc8af80SSimon Goldschmidt
4724cc8af80SSimon Goldschmidt /* check for overflow */
4734cc8af80SSimon Goldschmidt ut_assert(ram_end == 0 || ram_end > ram);
4744cc8af80SSimon Goldschmidt
4754cc8af80SSimon Goldschmidt lmb_init(&lmb);
4764cc8af80SSimon Goldschmidt
4774cc8af80SSimon Goldschmidt ret = lmb_add(&lmb, ram, ram_size);
4784cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
4794cc8af80SSimon Goldschmidt
4804cc8af80SSimon Goldschmidt /* reserve 3 blocks */
4814cc8af80SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
4824cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
4834cc8af80SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
4844cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
4854cc8af80SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
4864cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
4874cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
4884cc8af80SSimon Goldschmidt alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
4894cc8af80SSimon Goldschmidt
4904cc8af80SSimon Goldschmidt /* allocate blocks */
4914cc8af80SSimon Goldschmidt a = lmb_alloc_addr(&lmb, ram, alloc_addr_a - ram);
4924cc8af80SSimon Goldschmidt ut_asserteq(a, ram);
4934cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000,
4944cc8af80SSimon Goldschmidt alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
4954cc8af80SSimon Goldschmidt b = lmb_alloc_addr(&lmb, alloc_addr_a + 0x10000,
4964cc8af80SSimon Goldschmidt alloc_addr_b - alloc_addr_a - 0x10000);
4974cc8af80SSimon Goldschmidt ut_asserteq(b, alloc_addr_a + 0x10000);
4984cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000,
4994cc8af80SSimon Goldschmidt alloc_addr_c, 0x10000, 0, 0);
5004cc8af80SSimon Goldschmidt c = lmb_alloc_addr(&lmb, alloc_addr_b + 0x10000,
5014cc8af80SSimon Goldschmidt alloc_addr_c - alloc_addr_b - 0x10000);
5024cc8af80SSimon Goldschmidt ut_asserteq(c, alloc_addr_b + 0x10000);
5034cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
5044cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5054cc8af80SSimon Goldschmidt d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000,
5064cc8af80SSimon Goldschmidt ram_end - alloc_addr_c - 0x10000);
5074cc8af80SSimon Goldschmidt ut_asserteq(d, alloc_addr_c + 0x10000);
5084cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
5094cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5104cc8af80SSimon Goldschmidt
5114cc8af80SSimon Goldschmidt /* allocating anything else should fail */
5124cc8af80SSimon Goldschmidt e = lmb_alloc(&lmb, 1, 1);
5134cc8af80SSimon Goldschmidt ut_asserteq(e, 0);
5144cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
5154cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5164cc8af80SSimon Goldschmidt
5174cc8af80SSimon Goldschmidt ret = lmb_free(&lmb, d, ram_end - alloc_addr_c - 0x10000);
5184cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
5194cc8af80SSimon Goldschmidt
5204cc8af80SSimon Goldschmidt /* allocate at 3 points in free range */
5214cc8af80SSimon Goldschmidt
5224cc8af80SSimon Goldschmidt d = lmb_alloc_addr(&lmb, ram_end - 4, 4);
5234cc8af80SSimon Goldschmidt ut_asserteq(d, ram_end - 4);
5244cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
5254cc8af80SSimon Goldschmidt d, 4, 0, 0);
5264cc8af80SSimon Goldschmidt ret = lmb_free(&lmb, d, 4);
5274cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
5284cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
5294cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5304cc8af80SSimon Goldschmidt
5314cc8af80SSimon Goldschmidt d = lmb_alloc_addr(&lmb, ram_end - 128, 4);
5324cc8af80SSimon Goldschmidt ut_asserteq(d, ram_end - 128);
5334cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
5344cc8af80SSimon Goldschmidt d, 4, 0, 0);
5354cc8af80SSimon Goldschmidt ret = lmb_free(&lmb, d, 4);
5364cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
5374cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
5384cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5394cc8af80SSimon Goldschmidt
5404cc8af80SSimon Goldschmidt d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, 4);
5414cc8af80SSimon Goldschmidt ut_asserteq(d, alloc_addr_c + 0x10000);
5424cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004,
5434cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5444cc8af80SSimon Goldschmidt ret = lmb_free(&lmb, d, 4);
5454cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
5464cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
5474cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5484cc8af80SSimon Goldschmidt
5494cc8af80SSimon Goldschmidt /* allocate at the bottom */
5504cc8af80SSimon Goldschmidt ret = lmb_free(&lmb, a, alloc_addr_a - ram);
5514cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
5524cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000,
5534cc8af80SSimon Goldschmidt 0, 0, 0, 0);
5544cc8af80SSimon Goldschmidt d = lmb_alloc_addr(&lmb, ram, 4);
5554cc8af80SSimon Goldschmidt ut_asserteq(d, ram);
5564cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4,
5574cc8af80SSimon Goldschmidt ram + 0x8000000, 0x10010000, 0, 0);
5584cc8af80SSimon Goldschmidt
5594cc8af80SSimon Goldschmidt /* check that allocating outside memory fails */
5604cc8af80SSimon Goldschmidt if (ram_end != 0) {
5614cc8af80SSimon Goldschmidt ret = lmb_alloc_addr(&lmb, ram_end, 1);
5624cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
5634cc8af80SSimon Goldschmidt }
5644cc8af80SSimon Goldschmidt if (ram != 0) {
5654cc8af80SSimon Goldschmidt ret = lmb_alloc_addr(&lmb, ram - 1, 1);
5664cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
5674cc8af80SSimon Goldschmidt }
5684cc8af80SSimon Goldschmidt
5694cc8af80SSimon Goldschmidt return 0;
5704cc8af80SSimon Goldschmidt }
5714cc8af80SSimon Goldschmidt
lib_test_lmb_alloc_addr(struct unit_test_state * uts)5724cc8af80SSimon Goldschmidt static int lib_test_lmb_alloc_addr(struct unit_test_state *uts)
5734cc8af80SSimon Goldschmidt {
5744cc8af80SSimon Goldschmidt int ret;
5754cc8af80SSimon Goldschmidt
5764cc8af80SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1GiB */
5774cc8af80SSimon Goldschmidt ret = test_alloc_addr(uts, 0x40000000);
5784cc8af80SSimon Goldschmidt if (ret)
5794cc8af80SSimon Goldschmidt return ret;
5804cc8af80SSimon Goldschmidt
5814cc8af80SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1.5GiB */
5824cc8af80SSimon Goldschmidt return test_alloc_addr(uts, 0xE0000000);
5834cc8af80SSimon Goldschmidt }
5844cc8af80SSimon Goldschmidt
5854cc8af80SSimon Goldschmidt DM_TEST(lib_test_lmb_alloc_addr, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
5864cc8af80SSimon Goldschmidt
5874cc8af80SSimon Goldschmidt /* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */
test_get_unreserved_size(struct unit_test_state * uts,const phys_addr_t ram)5884cc8af80SSimon Goldschmidt static int test_get_unreserved_size(struct unit_test_state *uts,
5894cc8af80SSimon Goldschmidt const phys_addr_t ram)
5904cc8af80SSimon Goldschmidt {
5914cc8af80SSimon Goldschmidt const phys_size_t ram_size = 0x20000000;
5924cc8af80SSimon Goldschmidt const phys_addr_t ram_end = ram + ram_size;
5934cc8af80SSimon Goldschmidt const phys_size_t alloc_addr_a = ram + 0x8000000;
5944cc8af80SSimon Goldschmidt const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
5954cc8af80SSimon Goldschmidt const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
5964cc8af80SSimon Goldschmidt struct lmb lmb;
5974cc8af80SSimon Goldschmidt long ret;
5984cc8af80SSimon Goldschmidt phys_size_t s;
5994cc8af80SSimon Goldschmidt
6004cc8af80SSimon Goldschmidt /* check for overflow */
6014cc8af80SSimon Goldschmidt ut_assert(ram_end == 0 || ram_end > ram);
6024cc8af80SSimon Goldschmidt
6034cc8af80SSimon Goldschmidt lmb_init(&lmb);
6044cc8af80SSimon Goldschmidt
6054cc8af80SSimon Goldschmidt ret = lmb_add(&lmb, ram, ram_size);
6064cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
6074cc8af80SSimon Goldschmidt
6084cc8af80SSimon Goldschmidt /* reserve 3 blocks */
6094cc8af80SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
6104cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
6114cc8af80SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
6124cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
6134cc8af80SSimon Goldschmidt ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
6144cc8af80SSimon Goldschmidt ut_asserteq(ret, 0);
6154cc8af80SSimon Goldschmidt ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
6164cc8af80SSimon Goldschmidt alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
6174cc8af80SSimon Goldschmidt
6184cc8af80SSimon Goldschmidt /* check addresses in between blocks */
61965304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, ram);
6204cc8af80SSimon Goldschmidt ut_asserteq(s, alloc_addr_a - ram);
62165304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, ram + 0x10000);
6224cc8af80SSimon Goldschmidt ut_asserteq(s, alloc_addr_a - ram - 0x10000);
62365304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, alloc_addr_a - 4);
6244cc8af80SSimon Goldschmidt ut_asserteq(s, 4);
6254cc8af80SSimon Goldschmidt
62665304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, alloc_addr_a + 0x10000);
6274cc8af80SSimon Goldschmidt ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x10000);
62865304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, alloc_addr_a + 0x20000);
6294cc8af80SSimon Goldschmidt ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x20000);
63065304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, alloc_addr_b - 4);
6314cc8af80SSimon Goldschmidt ut_asserteq(s, 4);
6324cc8af80SSimon Goldschmidt
63365304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, alloc_addr_c + 0x10000);
6344cc8af80SSimon Goldschmidt ut_asserteq(s, ram_end - alloc_addr_c - 0x10000);
63565304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, alloc_addr_c + 0x20000);
6364cc8af80SSimon Goldschmidt ut_asserteq(s, ram_end - alloc_addr_c - 0x20000);
63765304aadSSimon Goldschmidt s = lmb_get_free_size(&lmb, ram_end - 4);
6384cc8af80SSimon Goldschmidt ut_asserteq(s, 4);
6394cc8af80SSimon Goldschmidt
6404cc8af80SSimon Goldschmidt return 0;
6414cc8af80SSimon Goldschmidt }
6424cc8af80SSimon Goldschmidt
lib_test_lmb_get_free_size(struct unit_test_state * uts)64365304aadSSimon Goldschmidt static int lib_test_lmb_get_free_size(struct unit_test_state *uts)
6444cc8af80SSimon Goldschmidt {
6454cc8af80SSimon Goldschmidt int ret;
6464cc8af80SSimon Goldschmidt
6474cc8af80SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1GiB */
6484cc8af80SSimon Goldschmidt ret = test_get_unreserved_size(uts, 0x40000000);
6494cc8af80SSimon Goldschmidt if (ret)
6504cc8af80SSimon Goldschmidt return ret;
6514cc8af80SSimon Goldschmidt
6524cc8af80SSimon Goldschmidt /* simulate 512 MiB RAM beginning at 1.5GiB */
6534cc8af80SSimon Goldschmidt return test_get_unreserved_size(uts, 0xE0000000);
6544cc8af80SSimon Goldschmidt }
6554cc8af80SSimon Goldschmidt
65665304aadSSimon Goldschmidt DM_TEST(lib_test_lmb_get_free_size,
6574cc8af80SSimon Goldschmidt DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
658