1142eac65SKarolina Drobnik // SPDX-License-Identifier: GPL-2.0-or-later
2142eac65SKarolina Drobnik #include "alloc_api.h"
3142eac65SKarolina Drobnik 
4deee033eSRebecca Mckeever static int alloc_test_flags = TEST_F_NONE;
5deee033eSRebecca Mckeever 
get_memblock_alloc_name(int flags)6deee033eSRebecca Mckeever static inline const char * const get_memblock_alloc_name(int flags)
7deee033eSRebecca Mckeever {
8deee033eSRebecca Mckeever 	if (flags & TEST_F_RAW)
9deee033eSRebecca Mckeever 		return "memblock_alloc_raw";
10deee033eSRebecca Mckeever 	return "memblock_alloc";
11deee033eSRebecca Mckeever }
12deee033eSRebecca Mckeever 
run_memblock_alloc(phys_addr_t size,phys_addr_t align)13deee033eSRebecca Mckeever static inline void *run_memblock_alloc(phys_addr_t size, phys_addr_t align)
14deee033eSRebecca Mckeever {
15deee033eSRebecca Mckeever 	if (alloc_test_flags & TEST_F_RAW)
16deee033eSRebecca Mckeever 		return memblock_alloc_raw(size, align);
17deee033eSRebecca Mckeever 	return memblock_alloc(size, align);
18deee033eSRebecca Mckeever }
19deee033eSRebecca Mckeever 
20142eac65SKarolina Drobnik /*
21142eac65SKarolina Drobnik  * A simple test that tries to allocate a small memory region.
22142eac65SKarolina Drobnik  * Expect to allocate an aligned region near the end of the available memory.
23142eac65SKarolina Drobnik  */
alloc_top_down_simple_check(void)24142eac65SKarolina Drobnik static int alloc_top_down_simple_check(void)
25142eac65SKarolina Drobnik {
26142eac65SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
27142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
28142eac65SKarolina Drobnik 	phys_addr_t size = SZ_2;
29142eac65SKarolina Drobnik 	phys_addr_t expected_start;
30142eac65SKarolina Drobnik 
31*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
32142eac65SKarolina Drobnik 	setup_memblock();
33142eac65SKarolina Drobnik 
34142eac65SKarolina Drobnik 	expected_start = memblock_end_of_DRAM() - SMP_CACHE_BYTES;
35142eac65SKarolina Drobnik 
36deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(size, SMP_CACHE_BYTES);
37142eac65SKarolina Drobnik 
3876586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
39deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, size, alloc_test_flags);
40ac76d803SRebecca Mckeever 
4176586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, size);
4276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, expected_start);
43142eac65SKarolina Drobnik 
4476586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
4576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, size);
4676586c00SRebecca Mckeever 
4776586c00SRebecca Mckeever 	test_pass_pop();
48142eac65SKarolina Drobnik 
49142eac65SKarolina Drobnik 	return 0;
50142eac65SKarolina Drobnik }
51142eac65SKarolina Drobnik 
52142eac65SKarolina Drobnik /*
53142eac65SKarolina Drobnik  * A test that tries to allocate memory next to a reserved region that starts at
54142eac65SKarolina Drobnik  * the misaligned address. Expect to create two separate entries, with the new
55142eac65SKarolina Drobnik  * entry aligned to the provided alignment:
56142eac65SKarolina Drobnik  *
57142eac65SKarolina Drobnik  *              +
58142eac65SKarolina Drobnik  * |            +--------+         +--------|
59142eac65SKarolina Drobnik  * |            |  rgn2  |         |  rgn1  |
60142eac65SKarolina Drobnik  * +------------+--------+---------+--------+
61142eac65SKarolina Drobnik  *              ^
62142eac65SKarolina Drobnik  *              |
63142eac65SKarolina Drobnik  *              Aligned address boundary
64142eac65SKarolina Drobnik  *
65142eac65SKarolina Drobnik  * The allocation direction is top-down and region arrays are sorted from lower
66142eac65SKarolina Drobnik  * to higher addresses, so the new region will be the first entry in
67142eac65SKarolina Drobnik  * memory.reserved array. The previously reserved region does not get modified.
68142eac65SKarolina Drobnik  * Region counter and total size get updated.
69142eac65SKarolina Drobnik  */
alloc_top_down_disjoint_check(void)70142eac65SKarolina Drobnik static int alloc_top_down_disjoint_check(void)
71142eac65SKarolina Drobnik {
72142eac65SKarolina Drobnik 	/* After allocation, this will point to the "old" region */
73142eac65SKarolina Drobnik 	struct memblock_region *rgn1 = &memblock.reserved.regions[1];
74142eac65SKarolina Drobnik 	struct memblock_region *rgn2 = &memblock.reserved.regions[0];
75142eac65SKarolina Drobnik 	struct region r1;
76142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
77142eac65SKarolina Drobnik 	phys_addr_t r2_size = SZ_16;
78142eac65SKarolina Drobnik 	/* Use custom alignment */
79142eac65SKarolina Drobnik 	phys_addr_t alignment = SMP_CACHE_BYTES * 2;
80142eac65SKarolina Drobnik 	phys_addr_t total_size;
81142eac65SKarolina Drobnik 	phys_addr_t expected_start;
82142eac65SKarolina Drobnik 
83*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
84142eac65SKarolina Drobnik 	setup_memblock();
85142eac65SKarolina Drobnik 
86142eac65SKarolina Drobnik 	r1.base = memblock_end_of_DRAM() - SZ_2;
87142eac65SKarolina Drobnik 	r1.size = SZ_2;
88142eac65SKarolina Drobnik 
89142eac65SKarolina Drobnik 	total_size = r1.size + r2_size;
90142eac65SKarolina Drobnik 	expected_start = memblock_end_of_DRAM() - alignment;
91142eac65SKarolina Drobnik 
92142eac65SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
93142eac65SKarolina Drobnik 
94deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r2_size, alignment);
95142eac65SKarolina Drobnik 
9676586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
97deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
98ac76d803SRebecca Mckeever 
9976586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1.size);
10076586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
101142eac65SKarolina Drobnik 
10276586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->size, r2_size);
10376586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->base, expected_start);
104142eac65SKarolina Drobnik 
10576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 2);
10676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
10776586c00SRebecca Mckeever 
10876586c00SRebecca Mckeever 	test_pass_pop();
109142eac65SKarolina Drobnik 
110142eac65SKarolina Drobnik 	return 0;
111142eac65SKarolina Drobnik }
112142eac65SKarolina Drobnik 
113142eac65SKarolina Drobnik /*
114142eac65SKarolina Drobnik  * A test that tries to allocate memory when there is enough space at the end
115142eac65SKarolina Drobnik  * of the previously reserved block (i.e. first fit):
116142eac65SKarolina Drobnik  *
117142eac65SKarolina Drobnik  *  |              +--------+--------------|
118142eac65SKarolina Drobnik  *  |              |   r1   |      r2      |
119142eac65SKarolina Drobnik  *  +--------------+--------+--------------+
120142eac65SKarolina Drobnik  *
121142eac65SKarolina Drobnik  * Expect a merge of both regions. Only the region size gets updated.
122142eac65SKarolina Drobnik  */
alloc_top_down_before_check(void)123142eac65SKarolina Drobnik static int alloc_top_down_before_check(void)
124142eac65SKarolina Drobnik {
125142eac65SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
126142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
127142eac65SKarolina Drobnik 	/*
128142eac65SKarolina Drobnik 	 * The first region ends at the aligned address to test region merging
129142eac65SKarolina Drobnik 	 */
130142eac65SKarolina Drobnik 	phys_addr_t r1_size = SMP_CACHE_BYTES;
131142eac65SKarolina Drobnik 	phys_addr_t r2_size = SZ_512;
132142eac65SKarolina Drobnik 	phys_addr_t total_size = r1_size + r2_size;
133142eac65SKarolina Drobnik 
134*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
135142eac65SKarolina Drobnik 	setup_memblock();
136142eac65SKarolina Drobnik 
137142eac65SKarolina Drobnik 	memblock_reserve(memblock_end_of_DRAM() - total_size, r1_size);
138142eac65SKarolina Drobnik 
139deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES);
140142eac65SKarolina Drobnik 
14176586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
142deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
143ac76d803SRebecca Mckeever 
14476586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
14576586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - total_size);
146142eac65SKarolina Drobnik 
14776586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
14876586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
14976586c00SRebecca Mckeever 
15076586c00SRebecca Mckeever 	test_pass_pop();
151142eac65SKarolina Drobnik 
152142eac65SKarolina Drobnik 	return 0;
153142eac65SKarolina Drobnik }
154142eac65SKarolina Drobnik 
155142eac65SKarolina Drobnik /*
156142eac65SKarolina Drobnik  * A test that tries to allocate memory when there is not enough space at the
157142eac65SKarolina Drobnik  * end of the previously reserved block (i.e. second fit):
158142eac65SKarolina Drobnik  *
159142eac65SKarolina Drobnik  *  |            +-----------+------+     |
160142eac65SKarolina Drobnik  *  |            |     r2    |  r1  |     |
161142eac65SKarolina Drobnik  *  +------------+-----------+------+-----+
162142eac65SKarolina Drobnik  *
163142eac65SKarolina Drobnik  * Expect a merge of both regions. Both the base address and size of the region
164142eac65SKarolina Drobnik  * get updated.
165142eac65SKarolina Drobnik  */
alloc_top_down_after_check(void)166142eac65SKarolina Drobnik static int alloc_top_down_after_check(void)
167142eac65SKarolina Drobnik {
168142eac65SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
169142eac65SKarolina Drobnik 	struct region r1;
170142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
171142eac65SKarolina Drobnik 	phys_addr_t r2_size = SZ_512;
172142eac65SKarolina Drobnik 	phys_addr_t total_size;
173142eac65SKarolina Drobnik 
174*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
175142eac65SKarolina Drobnik 	setup_memblock();
176142eac65SKarolina Drobnik 
177142eac65SKarolina Drobnik 	/*
178142eac65SKarolina Drobnik 	 * The first region starts at the aligned address to test region merging
179142eac65SKarolina Drobnik 	 */
180142eac65SKarolina Drobnik 	r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES;
181142eac65SKarolina Drobnik 	r1.size = SZ_8;
182142eac65SKarolina Drobnik 
183142eac65SKarolina Drobnik 	total_size = r1.size + r2_size;
184142eac65SKarolina Drobnik 
185142eac65SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
186142eac65SKarolina Drobnik 
187deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES);
188142eac65SKarolina Drobnik 
18976586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
190deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
191ac76d803SRebecca Mckeever 
19276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
19376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base - r2_size);
194142eac65SKarolina Drobnik 
19576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
19676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
19776586c00SRebecca Mckeever 
19876586c00SRebecca Mckeever 	test_pass_pop();
199142eac65SKarolina Drobnik 
200142eac65SKarolina Drobnik 	return 0;
201142eac65SKarolina Drobnik }
202142eac65SKarolina Drobnik 
203142eac65SKarolina Drobnik /*
204142eac65SKarolina Drobnik  * A test that tries to allocate memory when there are two reserved regions with
205142eac65SKarolina Drobnik  * a gap too small to fit the new region:
206142eac65SKarolina Drobnik  *
207142eac65SKarolina Drobnik  *  |       +--------+----------+   +------|
208142eac65SKarolina Drobnik  *  |       |   r3   |    r2    |   |  r1  |
209142eac65SKarolina Drobnik  *  +-------+--------+----------+---+------+
210142eac65SKarolina Drobnik  *
211142eac65SKarolina Drobnik  * Expect to allocate a region before the one that starts at the lower address,
212142eac65SKarolina Drobnik  * and merge them into one. The region counter and total size fields get
213142eac65SKarolina Drobnik  * updated.
214142eac65SKarolina Drobnik  */
alloc_top_down_second_fit_check(void)215142eac65SKarolina Drobnik static int alloc_top_down_second_fit_check(void)
216142eac65SKarolina Drobnik {
217142eac65SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
218142eac65SKarolina Drobnik 	struct region r1, r2;
219142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
220142eac65SKarolina Drobnik 	phys_addr_t r3_size = SZ_1K;
221142eac65SKarolina Drobnik 	phys_addr_t total_size;
222142eac65SKarolina Drobnik 
223*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
224142eac65SKarolina Drobnik 	setup_memblock();
225142eac65SKarolina Drobnik 
226142eac65SKarolina Drobnik 	r1.base = memblock_end_of_DRAM() - SZ_512;
227142eac65SKarolina Drobnik 	r1.size = SZ_512;
228142eac65SKarolina Drobnik 
229142eac65SKarolina Drobnik 	r2.base = r1.base - SZ_512;
230142eac65SKarolina Drobnik 	r2.size = SZ_256;
231142eac65SKarolina Drobnik 
232142eac65SKarolina Drobnik 	total_size = r1.size + r2.size + r3_size;
233142eac65SKarolina Drobnik 
234142eac65SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
235142eac65SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
236142eac65SKarolina Drobnik 
237deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES);
238142eac65SKarolina Drobnik 
23976586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
240deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r3_size, alloc_test_flags);
241ac76d803SRebecca Mckeever 
24276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r2.size + r3_size);
24376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r2.base - r3_size);
244142eac65SKarolina Drobnik 
24576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 2);
24676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
24776586c00SRebecca Mckeever 
24876586c00SRebecca Mckeever 	test_pass_pop();
249142eac65SKarolina Drobnik 
250142eac65SKarolina Drobnik 	return 0;
251142eac65SKarolina Drobnik }
252142eac65SKarolina Drobnik 
253142eac65SKarolina Drobnik /*
254142eac65SKarolina Drobnik  * A test that tries to allocate memory when there are two reserved regions with
255142eac65SKarolina Drobnik  * a gap big enough to accommodate the new region:
256142eac65SKarolina Drobnik  *
257142eac65SKarolina Drobnik  *  |     +--------+--------+--------+     |
258142eac65SKarolina Drobnik  *  |     |   r2   |   r3   |   r1   |     |
259142eac65SKarolina Drobnik  *  +-----+--------+--------+--------+-----+
260142eac65SKarolina Drobnik  *
261142eac65SKarolina Drobnik  * Expect to merge all of them, creating one big entry in memblock.reserved
262142eac65SKarolina Drobnik  * array. The region counter and total size fields get updated.
263142eac65SKarolina Drobnik  */
alloc_in_between_generic_check(void)264142eac65SKarolina Drobnik static int alloc_in_between_generic_check(void)
265142eac65SKarolina Drobnik {
266142eac65SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
267142eac65SKarolina Drobnik 	struct region r1, r2;
268142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
269142eac65SKarolina Drobnik 	phys_addr_t gap_size = SMP_CACHE_BYTES;
270142eac65SKarolina Drobnik 	phys_addr_t r3_size = SZ_64;
271142eac65SKarolina Drobnik 	/*
272142eac65SKarolina Drobnik 	 * Calculate regions size so there's just enough space for the new entry
273142eac65SKarolina Drobnik 	 */
274142eac65SKarolina Drobnik 	phys_addr_t rgn_size = (MEM_SIZE - (2 * gap_size + r3_size)) / 2;
275142eac65SKarolina Drobnik 	phys_addr_t total_size;
276142eac65SKarolina Drobnik 
277*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
278142eac65SKarolina Drobnik 	setup_memblock();
279142eac65SKarolina Drobnik 
280142eac65SKarolina Drobnik 	r1.size = rgn_size;
281142eac65SKarolina Drobnik 	r1.base = memblock_end_of_DRAM() - (gap_size + rgn_size);
282142eac65SKarolina Drobnik 
283142eac65SKarolina Drobnik 	r2.size = rgn_size;
284142eac65SKarolina Drobnik 	r2.base = memblock_start_of_DRAM() + gap_size;
285142eac65SKarolina Drobnik 
286142eac65SKarolina Drobnik 	total_size = r1.size + r2.size + r3_size;
287142eac65SKarolina Drobnik 
288142eac65SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
289142eac65SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
290142eac65SKarolina Drobnik 
291deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES);
292142eac65SKarolina Drobnik 
29376586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
294deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r3_size, alloc_test_flags);
295ac76d803SRebecca Mckeever 
29676586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
29776586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base - r2.size - r3_size);
298142eac65SKarolina Drobnik 
29976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
30076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
30176586c00SRebecca Mckeever 
30276586c00SRebecca Mckeever 	test_pass_pop();
303142eac65SKarolina Drobnik 
304142eac65SKarolina Drobnik 	return 0;
305142eac65SKarolina Drobnik }
306142eac65SKarolina Drobnik 
307142eac65SKarolina Drobnik /*
308142eac65SKarolina Drobnik  * A test that tries to allocate memory when the memory is filled with reserved
309142eac65SKarolina Drobnik  * regions with memory gaps too small to fit the new region:
310142eac65SKarolina Drobnik  *
311142eac65SKarolina Drobnik  * +-------+
312142eac65SKarolina Drobnik  * |  new  |
313142eac65SKarolina Drobnik  * +--+----+
314142eac65SKarolina Drobnik  *    |    +-----+    +-----+    +-----+    |
315142eac65SKarolina Drobnik  *    |    | res |    | res |    | res |    |
316142eac65SKarolina Drobnik  *    +----+-----+----+-----+----+-----+----+
317142eac65SKarolina Drobnik  *
318142eac65SKarolina Drobnik  * Expect no allocation to happen.
319142eac65SKarolina Drobnik  */
alloc_small_gaps_generic_check(void)320142eac65SKarolina Drobnik static int alloc_small_gaps_generic_check(void)
321142eac65SKarolina Drobnik {
322142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
323142eac65SKarolina Drobnik 	phys_addr_t region_size = SZ_1K;
324142eac65SKarolina Drobnik 	phys_addr_t gap_size = SZ_256;
325142eac65SKarolina Drobnik 	phys_addr_t region_end;
326142eac65SKarolina Drobnik 
327*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
328142eac65SKarolina Drobnik 	setup_memblock();
329142eac65SKarolina Drobnik 
330142eac65SKarolina Drobnik 	region_end = memblock_start_of_DRAM();
331142eac65SKarolina Drobnik 
332142eac65SKarolina Drobnik 	while (region_end < memblock_end_of_DRAM()) {
333142eac65SKarolina Drobnik 		memblock_reserve(region_end + gap_size, region_size);
334142eac65SKarolina Drobnik 		region_end += gap_size + region_size;
335142eac65SKarolina Drobnik 	}
336142eac65SKarolina Drobnik 
337deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(region_size, SMP_CACHE_BYTES);
338142eac65SKarolina Drobnik 
33976586c00SRebecca Mckeever 	ASSERT_EQ(allocated_ptr, NULL);
34076586c00SRebecca Mckeever 
34176586c00SRebecca Mckeever 	test_pass_pop();
342142eac65SKarolina Drobnik 
343142eac65SKarolina Drobnik 	return 0;
344142eac65SKarolina Drobnik }
345142eac65SKarolina Drobnik 
346142eac65SKarolina Drobnik /*
347142eac65SKarolina Drobnik  * A test that tries to allocate memory when all memory is reserved.
348142eac65SKarolina Drobnik  * Expect no allocation to happen.
349142eac65SKarolina Drobnik  */
alloc_all_reserved_generic_check(void)350142eac65SKarolina Drobnik static int alloc_all_reserved_generic_check(void)
351142eac65SKarolina Drobnik {
352142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
353142eac65SKarolina Drobnik 
35476586c00SRebecca Mckeever 	PREFIX_PUSH();
355142eac65SKarolina Drobnik 	setup_memblock();
356142eac65SKarolina Drobnik 
357142eac65SKarolina Drobnik 	/* Simulate full memory */
358142eac65SKarolina Drobnik 	memblock_reserve(memblock_start_of_DRAM(), MEM_SIZE);
359142eac65SKarolina Drobnik 
360deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(SZ_256, SMP_CACHE_BYTES);
361142eac65SKarolina Drobnik 
36276586c00SRebecca Mckeever 	ASSERT_EQ(allocated_ptr, NULL);
36376586c00SRebecca Mckeever 
36476586c00SRebecca Mckeever 	test_pass_pop();
365142eac65SKarolina Drobnik 
366142eac65SKarolina Drobnik 	return 0;
367142eac65SKarolina Drobnik }
368142eac65SKarolina Drobnik 
369142eac65SKarolina Drobnik /*
370142eac65SKarolina Drobnik  * A test that tries to allocate memory when the memory is almost full,
371142eac65SKarolina Drobnik  * with not enough space left for the new region:
372142eac65SKarolina Drobnik  *
373142eac65SKarolina Drobnik  *                                +-------+
374142eac65SKarolina Drobnik  *                                |  new  |
375142eac65SKarolina Drobnik  *                                +-------+
376142eac65SKarolina Drobnik  *  |-----------------------------+   |
377142eac65SKarolina Drobnik  *  |          reserved           |   |
378142eac65SKarolina Drobnik  *  +-----------------------------+---+
379142eac65SKarolina Drobnik  *
380142eac65SKarolina Drobnik  * Expect no allocation to happen.
381142eac65SKarolina Drobnik  */
alloc_no_space_generic_check(void)382142eac65SKarolina Drobnik static int alloc_no_space_generic_check(void)
383142eac65SKarolina Drobnik {
384142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
385142eac65SKarolina Drobnik 	phys_addr_t available_size = SZ_256;
386142eac65SKarolina Drobnik 	phys_addr_t reserved_size = MEM_SIZE - available_size;
387142eac65SKarolina Drobnik 
388*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
389*42c3ba86SRebecca Mckeever 	setup_memblock();
390*42c3ba86SRebecca Mckeever 
391142eac65SKarolina Drobnik 	/* Simulate almost-full memory */
392142eac65SKarolina Drobnik 	memblock_reserve(memblock_start_of_DRAM(), reserved_size);
393142eac65SKarolina Drobnik 
394deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(SZ_1K, SMP_CACHE_BYTES);
395142eac65SKarolina Drobnik 
39676586c00SRebecca Mckeever 	ASSERT_EQ(allocated_ptr, NULL);
39776586c00SRebecca Mckeever 
39876586c00SRebecca Mckeever 	test_pass_pop();
399142eac65SKarolina Drobnik 
400142eac65SKarolina Drobnik 	return 0;
401142eac65SKarolina Drobnik }
402142eac65SKarolina Drobnik 
403142eac65SKarolina Drobnik /*
404142eac65SKarolina Drobnik  * A test that tries to allocate memory when the memory is almost full,
405142eac65SKarolina Drobnik  * but there is just enough space left:
406142eac65SKarolina Drobnik  *
407142eac65SKarolina Drobnik  *  |---------------------------+---------|
408142eac65SKarolina Drobnik  *  |          reserved         |   new   |
409142eac65SKarolina Drobnik  *  +---------------------------+---------+
410142eac65SKarolina Drobnik  *
411142eac65SKarolina Drobnik  * Expect to allocate memory and merge all the regions. The total size field
412142eac65SKarolina Drobnik  * gets updated.
413142eac65SKarolina Drobnik  */
alloc_limited_space_generic_check(void)414142eac65SKarolina Drobnik static int alloc_limited_space_generic_check(void)
415142eac65SKarolina Drobnik {
416142eac65SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
417142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
418142eac65SKarolina Drobnik 	phys_addr_t available_size = SZ_256;
419142eac65SKarolina Drobnik 	phys_addr_t reserved_size = MEM_SIZE - available_size;
420142eac65SKarolina Drobnik 
421*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
422142eac65SKarolina Drobnik 	setup_memblock();
423142eac65SKarolina Drobnik 
424142eac65SKarolina Drobnik 	/* Simulate almost-full memory */
425142eac65SKarolina Drobnik 	memblock_reserve(memblock_start_of_DRAM(), reserved_size);
426142eac65SKarolina Drobnik 
427deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(available_size, SMP_CACHE_BYTES);
428142eac65SKarolina Drobnik 
42976586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
430deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, available_size, alloc_test_flags);
431ac76d803SRebecca Mckeever 
43276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, MEM_SIZE);
43376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
434142eac65SKarolina Drobnik 
43576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
43676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, MEM_SIZE);
43776586c00SRebecca Mckeever 
43876586c00SRebecca Mckeever 	test_pass_pop();
439142eac65SKarolina Drobnik 
440142eac65SKarolina Drobnik 	return 0;
441142eac65SKarolina Drobnik }
442142eac65SKarolina Drobnik 
443142eac65SKarolina Drobnik /*
444142eac65SKarolina Drobnik  * A test that tries to allocate memory when there is no available memory
445142eac65SKarolina Drobnik  * registered (i.e. memblock.memory has only a dummy entry).
446142eac65SKarolina Drobnik  * Expect no allocation to happen.
447142eac65SKarolina Drobnik  */
alloc_no_memory_generic_check(void)448142eac65SKarolina Drobnik static int alloc_no_memory_generic_check(void)
449142eac65SKarolina Drobnik {
450142eac65SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
451142eac65SKarolina Drobnik 	void *allocated_ptr = NULL;
452142eac65SKarolina Drobnik 
45376586c00SRebecca Mckeever 	PREFIX_PUSH();
45476586c00SRebecca Mckeever 
455142eac65SKarolina Drobnik 	reset_memblock_regions();
456142eac65SKarolina Drobnik 
457deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(SZ_1K, SMP_CACHE_BYTES);
458142eac65SKarolina Drobnik 
45976586c00SRebecca Mckeever 	ASSERT_EQ(allocated_ptr, NULL);
46076586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, 0);
46176586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, 0);
46276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, 0);
46376586c00SRebecca Mckeever 
46476586c00SRebecca Mckeever 	test_pass_pop();
465142eac65SKarolina Drobnik 
466142eac65SKarolina Drobnik 	return 0;
467142eac65SKarolina Drobnik }
468142eac65SKarolina Drobnik 
4690237ee23SKarolina Drobnik /*
47021a233f6SRebecca Mckeever  * A test that tries to allocate a region that is larger than the total size of
47121a233f6SRebecca Mckeever  * available memory (memblock.memory):
47221a233f6SRebecca Mckeever  *
47321a233f6SRebecca Mckeever  *  +-----------------------------------+
47421a233f6SRebecca Mckeever  *  |                 new               |
47521a233f6SRebecca Mckeever  *  +-----------------------------------+
47621a233f6SRebecca Mckeever  *  |                                 |
47721a233f6SRebecca Mckeever  *  |                                 |
47821a233f6SRebecca Mckeever  *  +---------------------------------+
47921a233f6SRebecca Mckeever  *
48021a233f6SRebecca Mckeever  * Expect no allocation to happen.
48121a233f6SRebecca Mckeever  */
alloc_too_large_generic_check(void)48221a233f6SRebecca Mckeever static int alloc_too_large_generic_check(void)
48321a233f6SRebecca Mckeever {
48421a233f6SRebecca Mckeever 	struct memblock_region *rgn = &memblock.reserved.regions[0];
48521a233f6SRebecca Mckeever 	void *allocated_ptr = NULL;
48621a233f6SRebecca Mckeever 
48721a233f6SRebecca Mckeever 	PREFIX_PUSH();
48821a233f6SRebecca Mckeever 	setup_memblock();
48921a233f6SRebecca Mckeever 
490deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(MEM_SIZE + SZ_2, SMP_CACHE_BYTES);
49121a233f6SRebecca Mckeever 
49221a233f6SRebecca Mckeever 	ASSERT_EQ(allocated_ptr, NULL);
49321a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, 0);
49421a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, 0);
49521a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, 0);
49621a233f6SRebecca Mckeever 
49721a233f6SRebecca Mckeever 	test_pass_pop();
49821a233f6SRebecca Mckeever 
49921a233f6SRebecca Mckeever 	return 0;
50021a233f6SRebecca Mckeever }
50121a233f6SRebecca Mckeever 
50221a233f6SRebecca Mckeever /*
5030237ee23SKarolina Drobnik  * A simple test that tries to allocate a small memory region.
5040237ee23SKarolina Drobnik  * Expect to allocate an aligned region at the beginning of the available
5050237ee23SKarolina Drobnik  * memory.
5060237ee23SKarolina Drobnik  */
alloc_bottom_up_simple_check(void)5070237ee23SKarolina Drobnik static int alloc_bottom_up_simple_check(void)
5080237ee23SKarolina Drobnik {
5090237ee23SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
5100237ee23SKarolina Drobnik 	void *allocated_ptr = NULL;
5110237ee23SKarolina Drobnik 
51276586c00SRebecca Mckeever 	PREFIX_PUSH();
5130237ee23SKarolina Drobnik 	setup_memblock();
5140237ee23SKarolina Drobnik 
515deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(SZ_2, SMP_CACHE_BYTES);
5160237ee23SKarolina Drobnik 
51776586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
518deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, SZ_2, alloc_test_flags);
519ac76d803SRebecca Mckeever 
52076586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, SZ_2);
52176586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
5220237ee23SKarolina Drobnik 
52376586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
52476586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, SZ_2);
52576586c00SRebecca Mckeever 
52676586c00SRebecca Mckeever 	test_pass_pop();
5270237ee23SKarolina Drobnik 
5280237ee23SKarolina Drobnik 	return 0;
5290237ee23SKarolina Drobnik }
5300237ee23SKarolina Drobnik 
5310237ee23SKarolina Drobnik /*
5320237ee23SKarolina Drobnik  * A test that tries to allocate memory next to a reserved region that starts at
5330237ee23SKarolina Drobnik  * the misaligned address. Expect to create two separate entries, with the new
5340237ee23SKarolina Drobnik  * entry aligned to the provided alignment:
5350237ee23SKarolina Drobnik  *
5360237ee23SKarolina Drobnik  *                      +
5370237ee23SKarolina Drobnik  *  |    +----------+   +----------+     |
5380237ee23SKarolina Drobnik  *  |    |   rgn1   |   |   rgn2   |     |
5390237ee23SKarolina Drobnik  *  +----+----------+---+----------+-----+
5400237ee23SKarolina Drobnik  *                      ^
5410237ee23SKarolina Drobnik  *                      |
5420237ee23SKarolina Drobnik  *                      Aligned address boundary
5430237ee23SKarolina Drobnik  *
5440237ee23SKarolina Drobnik  * The allocation direction is bottom-up, so the new region will be the second
5450237ee23SKarolina Drobnik  * entry in memory.reserved array. The previously reserved region does not get
5460237ee23SKarolina Drobnik  * modified. Region counter and total size get updated.
5470237ee23SKarolina Drobnik  */
alloc_bottom_up_disjoint_check(void)5480237ee23SKarolina Drobnik static int alloc_bottom_up_disjoint_check(void)
5490237ee23SKarolina Drobnik {
5500237ee23SKarolina Drobnik 	struct memblock_region *rgn1 = &memblock.reserved.regions[0];
5510237ee23SKarolina Drobnik 	struct memblock_region *rgn2 = &memblock.reserved.regions[1];
5520237ee23SKarolina Drobnik 	struct region r1;
5530237ee23SKarolina Drobnik 	void *allocated_ptr = NULL;
5540237ee23SKarolina Drobnik 	phys_addr_t r2_size = SZ_16;
5550237ee23SKarolina Drobnik 	/* Use custom alignment */
5560237ee23SKarolina Drobnik 	phys_addr_t alignment = SMP_CACHE_BYTES * 2;
5570237ee23SKarolina Drobnik 	phys_addr_t total_size;
5580237ee23SKarolina Drobnik 	phys_addr_t expected_start;
5590237ee23SKarolina Drobnik 
560*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
5610237ee23SKarolina Drobnik 	setup_memblock();
5620237ee23SKarolina Drobnik 
5630237ee23SKarolina Drobnik 	r1.base = memblock_start_of_DRAM() + SZ_2;
5640237ee23SKarolina Drobnik 	r1.size = SZ_2;
5650237ee23SKarolina Drobnik 
5660237ee23SKarolina Drobnik 	total_size = r1.size + r2_size;
5670237ee23SKarolina Drobnik 	expected_start = memblock_start_of_DRAM() + alignment;
5680237ee23SKarolina Drobnik 
5690237ee23SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
5700237ee23SKarolina Drobnik 
571deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r2_size, alignment);
5720237ee23SKarolina Drobnik 
57376586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
574deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
5750237ee23SKarolina Drobnik 
57676586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1.size);
57776586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
5780237ee23SKarolina Drobnik 
57976586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->size, r2_size);
58076586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->base, expected_start);
5810237ee23SKarolina Drobnik 
58276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 2);
58376586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
58476586c00SRebecca Mckeever 
58576586c00SRebecca Mckeever 	test_pass_pop();
5860237ee23SKarolina Drobnik 
5870237ee23SKarolina Drobnik 	return 0;
5880237ee23SKarolina Drobnik }
5890237ee23SKarolina Drobnik 
5900237ee23SKarolina Drobnik /*
5910237ee23SKarolina Drobnik  * A test that tries to allocate memory when there is enough space at
5920237ee23SKarolina Drobnik  * the beginning of the previously reserved block (i.e. first fit):
5930237ee23SKarolina Drobnik  *
5940237ee23SKarolina Drobnik  *  |------------------+--------+         |
5950237ee23SKarolina Drobnik  *  |        r1        |   r2   |         |
5960237ee23SKarolina Drobnik  *  +------------------+--------+---------+
5970237ee23SKarolina Drobnik  *
5980237ee23SKarolina Drobnik  * Expect a merge of both regions. Only the region size gets updated.
5990237ee23SKarolina Drobnik  */
alloc_bottom_up_before_check(void)6000237ee23SKarolina Drobnik static int alloc_bottom_up_before_check(void)
6010237ee23SKarolina Drobnik {
6020237ee23SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
6030237ee23SKarolina Drobnik 	void *allocated_ptr = NULL;
6040237ee23SKarolina Drobnik 	phys_addr_t r1_size = SZ_512;
6050237ee23SKarolina Drobnik 	phys_addr_t r2_size = SZ_128;
6060237ee23SKarolina Drobnik 	phys_addr_t total_size = r1_size + r2_size;
6070237ee23SKarolina Drobnik 
608*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
6090237ee23SKarolina Drobnik 	setup_memblock();
6100237ee23SKarolina Drobnik 
6110237ee23SKarolina Drobnik 	memblock_reserve(memblock_start_of_DRAM() + r1_size, r2_size);
6120237ee23SKarolina Drobnik 
613deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r1_size, SMP_CACHE_BYTES);
6140237ee23SKarolina Drobnik 
61576586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
616deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r1_size, alloc_test_flags);
617ac76d803SRebecca Mckeever 
61876586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
61976586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
6200237ee23SKarolina Drobnik 
62176586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
62276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
62376586c00SRebecca Mckeever 
62476586c00SRebecca Mckeever 	test_pass_pop();
6250237ee23SKarolina Drobnik 
6260237ee23SKarolina Drobnik 	return 0;
6270237ee23SKarolina Drobnik }
6280237ee23SKarolina Drobnik 
6290237ee23SKarolina Drobnik /*
6300237ee23SKarolina Drobnik  * A test that tries to allocate memory when there is not enough space at
6310237ee23SKarolina Drobnik  * the beginning of the previously reserved block (i.e. second fit):
6320237ee23SKarolina Drobnik  *
6330237ee23SKarolina Drobnik  *  |    +--------+--------------+         |
6340237ee23SKarolina Drobnik  *  |    |   r1   |      r2      |         |
6350237ee23SKarolina Drobnik  *  +----+--------+--------------+---------+
6360237ee23SKarolina Drobnik  *
6370237ee23SKarolina Drobnik  * Expect a merge of both regions. Only the region size gets updated.
6380237ee23SKarolina Drobnik  */
alloc_bottom_up_after_check(void)6390237ee23SKarolina Drobnik static int alloc_bottom_up_after_check(void)
6400237ee23SKarolina Drobnik {
6410237ee23SKarolina Drobnik 	struct memblock_region *rgn = &memblock.reserved.regions[0];
6420237ee23SKarolina Drobnik 	struct region r1;
6430237ee23SKarolina Drobnik 	void *allocated_ptr = NULL;
6440237ee23SKarolina Drobnik 	phys_addr_t r2_size = SZ_512;
6450237ee23SKarolina Drobnik 	phys_addr_t total_size;
6460237ee23SKarolina Drobnik 
647*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
6480237ee23SKarolina Drobnik 	setup_memblock();
6490237ee23SKarolina Drobnik 
6500237ee23SKarolina Drobnik 	/*
6510237ee23SKarolina Drobnik 	 * The first region starts at the aligned address to test region merging
6520237ee23SKarolina Drobnik 	 */
6530237ee23SKarolina Drobnik 	r1.base = memblock_start_of_DRAM() + SMP_CACHE_BYTES;
6540237ee23SKarolina Drobnik 	r1.size = SZ_64;
6550237ee23SKarolina Drobnik 
6560237ee23SKarolina Drobnik 	total_size = r1.size + r2_size;
6570237ee23SKarolina Drobnik 
6580237ee23SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
6590237ee23SKarolina Drobnik 
660deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES);
6610237ee23SKarolina Drobnik 
66276586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
663deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
664ac76d803SRebecca Mckeever 
66576586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
66676586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
6670237ee23SKarolina Drobnik 
66876586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
66976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
67076586c00SRebecca Mckeever 
67176586c00SRebecca Mckeever 	test_pass_pop();
6720237ee23SKarolina Drobnik 
6730237ee23SKarolina Drobnik 	return 0;
6740237ee23SKarolina Drobnik }
6750237ee23SKarolina Drobnik 
6760237ee23SKarolina Drobnik /*
6770237ee23SKarolina Drobnik  * A test that tries to allocate memory when there are two reserved regions, the
6780237ee23SKarolina Drobnik  * first one starting at the beginning of the available memory, with a gap too
6790237ee23SKarolina Drobnik  * small to fit the new region:
6800237ee23SKarolina Drobnik  *
6810237ee23SKarolina Drobnik  *  |------------+     +--------+--------+  |
6820237ee23SKarolina Drobnik  *  |     r1     |     |   r2   |   r3   |  |
6830237ee23SKarolina Drobnik  *  +------------+-----+--------+--------+--+
6840237ee23SKarolina Drobnik  *
6850237ee23SKarolina Drobnik  * Expect to allocate after the second region, which starts at the higher
6860237ee23SKarolina Drobnik  * address, and merge them into one. The region counter and total size fields
6870237ee23SKarolina Drobnik  * get updated.
6880237ee23SKarolina Drobnik  */
alloc_bottom_up_second_fit_check(void)6890237ee23SKarolina Drobnik static int alloc_bottom_up_second_fit_check(void)
6900237ee23SKarolina Drobnik {
6910237ee23SKarolina Drobnik 	struct memblock_region *rgn  = &memblock.reserved.regions[1];
6920237ee23SKarolina Drobnik 	struct region r1, r2;
6930237ee23SKarolina Drobnik 	void *allocated_ptr = NULL;
6940237ee23SKarolina Drobnik 	phys_addr_t r3_size = SZ_1K;
6950237ee23SKarolina Drobnik 	phys_addr_t total_size;
6960237ee23SKarolina Drobnik 
697*42c3ba86SRebecca Mckeever 	PREFIX_PUSH();
6980237ee23SKarolina Drobnik 	setup_memblock();
6990237ee23SKarolina Drobnik 
7000237ee23SKarolina Drobnik 	r1.base = memblock_start_of_DRAM();
7010237ee23SKarolina Drobnik 	r1.size = SZ_512;
7020237ee23SKarolina Drobnik 
7030237ee23SKarolina Drobnik 	r2.base = r1.base + r1.size + SZ_512;
7040237ee23SKarolina Drobnik 	r2.size = SZ_256;
7050237ee23SKarolina Drobnik 
7060237ee23SKarolina Drobnik 	total_size = r1.size + r2.size + r3_size;
7070237ee23SKarolina Drobnik 
7080237ee23SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
7090237ee23SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
7100237ee23SKarolina Drobnik 
711deee033eSRebecca Mckeever 	allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES);
7120237ee23SKarolina Drobnik 
71376586c00SRebecca Mckeever 	ASSERT_NE(allocated_ptr, NULL);
714deee033eSRebecca Mckeever 	assert_mem_content(allocated_ptr, r3_size, alloc_test_flags);
715ac76d803SRebecca Mckeever 
71676586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r2.size + r3_size);
71776586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r2.base);
7180237ee23SKarolina Drobnik 
71976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 2);
72076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
72176586c00SRebecca Mckeever 
72276586c00SRebecca Mckeever 	test_pass_pop();
7230237ee23SKarolina Drobnik 
7240237ee23SKarolina Drobnik 	return 0;
7250237ee23SKarolina Drobnik }
7260237ee23SKarolina Drobnik 
7270237ee23SKarolina Drobnik /* Test case wrappers */
alloc_simple_check(void)7280237ee23SKarolina Drobnik static int alloc_simple_check(void)
7290237ee23SKarolina Drobnik {
73076586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
7310237ee23SKarolina Drobnik 	memblock_set_bottom_up(false);
7320237ee23SKarolina Drobnik 	alloc_top_down_simple_check();
7330237ee23SKarolina Drobnik 	memblock_set_bottom_up(true);
7340237ee23SKarolina Drobnik 	alloc_bottom_up_simple_check();
7350237ee23SKarolina Drobnik 
7360237ee23SKarolina Drobnik 	return 0;
7370237ee23SKarolina Drobnik }
7380237ee23SKarolina Drobnik 
alloc_disjoint_check(void)7390237ee23SKarolina Drobnik static int alloc_disjoint_check(void)
7400237ee23SKarolina Drobnik {
74176586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
7420237ee23SKarolina Drobnik 	memblock_set_bottom_up(false);
7430237ee23SKarolina Drobnik 	alloc_top_down_disjoint_check();
7440237ee23SKarolina Drobnik 	memblock_set_bottom_up(true);
7450237ee23SKarolina Drobnik 	alloc_bottom_up_disjoint_check();
7460237ee23SKarolina Drobnik 
7470237ee23SKarolina Drobnik 	return 0;
7480237ee23SKarolina Drobnik }
7490237ee23SKarolina Drobnik 
alloc_before_check(void)7500237ee23SKarolina Drobnik static int alloc_before_check(void)
7510237ee23SKarolina Drobnik {
75276586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
7530237ee23SKarolina Drobnik 	memblock_set_bottom_up(false);
7540237ee23SKarolina Drobnik 	alloc_top_down_before_check();
7550237ee23SKarolina Drobnik 	memblock_set_bottom_up(true);
7560237ee23SKarolina Drobnik 	alloc_bottom_up_before_check();
7570237ee23SKarolina Drobnik 
7580237ee23SKarolina Drobnik 	return 0;
7590237ee23SKarolina Drobnik }
7600237ee23SKarolina Drobnik 
alloc_after_check(void)7610237ee23SKarolina Drobnik static int alloc_after_check(void)
7620237ee23SKarolina Drobnik {
76376586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
7640237ee23SKarolina Drobnik 	memblock_set_bottom_up(false);
7650237ee23SKarolina Drobnik 	alloc_top_down_after_check();
7660237ee23SKarolina Drobnik 	memblock_set_bottom_up(true);
7670237ee23SKarolina Drobnik 	alloc_bottom_up_after_check();
7680237ee23SKarolina Drobnik 
7690237ee23SKarolina Drobnik 	return 0;
7700237ee23SKarolina Drobnik }
7710237ee23SKarolina Drobnik 
alloc_in_between_check(void)7720237ee23SKarolina Drobnik static int alloc_in_between_check(void)
7730237ee23SKarolina Drobnik {
77476586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
775fb2e97feSRebecca Mckeever 	run_top_down(alloc_in_between_generic_check);
776fb2e97feSRebecca Mckeever 	run_bottom_up(alloc_in_between_generic_check);
7770237ee23SKarolina Drobnik 
7780237ee23SKarolina Drobnik 	return 0;
7790237ee23SKarolina Drobnik }
7800237ee23SKarolina Drobnik 
alloc_second_fit_check(void)7810237ee23SKarolina Drobnik static int alloc_second_fit_check(void)
7820237ee23SKarolina Drobnik {
78376586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
7840237ee23SKarolina Drobnik 	memblock_set_bottom_up(false);
7850237ee23SKarolina Drobnik 	alloc_top_down_second_fit_check();
7860237ee23SKarolina Drobnik 	memblock_set_bottom_up(true);
7870237ee23SKarolina Drobnik 	alloc_bottom_up_second_fit_check();
7880237ee23SKarolina Drobnik 
7890237ee23SKarolina Drobnik 	return 0;
7900237ee23SKarolina Drobnik }
7910237ee23SKarolina Drobnik 
alloc_small_gaps_check(void)7920237ee23SKarolina Drobnik static int alloc_small_gaps_check(void)
7930237ee23SKarolina Drobnik {
79476586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
795fb2e97feSRebecca Mckeever 	run_top_down(alloc_small_gaps_generic_check);
796fb2e97feSRebecca Mckeever 	run_bottom_up(alloc_small_gaps_generic_check);
7970237ee23SKarolina Drobnik 
7980237ee23SKarolina Drobnik 	return 0;
7990237ee23SKarolina Drobnik }
8000237ee23SKarolina Drobnik 
alloc_all_reserved_check(void)8010237ee23SKarolina Drobnik static int alloc_all_reserved_check(void)
8020237ee23SKarolina Drobnik {
80376586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
804fb2e97feSRebecca Mckeever 	run_top_down(alloc_all_reserved_generic_check);
805fb2e97feSRebecca Mckeever 	run_bottom_up(alloc_all_reserved_generic_check);
8060237ee23SKarolina Drobnik 
8070237ee23SKarolina Drobnik 	return 0;
8080237ee23SKarolina Drobnik }
8090237ee23SKarolina Drobnik 
alloc_no_space_check(void)8100237ee23SKarolina Drobnik static int alloc_no_space_check(void)
8110237ee23SKarolina Drobnik {
81276586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
813fb2e97feSRebecca Mckeever 	run_top_down(alloc_no_space_generic_check);
814fb2e97feSRebecca Mckeever 	run_bottom_up(alloc_no_space_generic_check);
8150237ee23SKarolina Drobnik 
8160237ee23SKarolina Drobnik 	return 0;
8170237ee23SKarolina Drobnik }
8180237ee23SKarolina Drobnik 
alloc_limited_space_check(void)8190237ee23SKarolina Drobnik static int alloc_limited_space_check(void)
8200237ee23SKarolina Drobnik {
82176586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
822fb2e97feSRebecca Mckeever 	run_top_down(alloc_limited_space_generic_check);
823fb2e97feSRebecca Mckeever 	run_bottom_up(alloc_limited_space_generic_check);
8240237ee23SKarolina Drobnik 
8250237ee23SKarolina Drobnik 	return 0;
8260237ee23SKarolina Drobnik }
8270237ee23SKarolina Drobnik 
alloc_no_memory_check(void)8280237ee23SKarolina Drobnik static int alloc_no_memory_check(void)
8290237ee23SKarolina Drobnik {
83076586c00SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
831fb2e97feSRebecca Mckeever 	run_top_down(alloc_no_memory_generic_check);
832fb2e97feSRebecca Mckeever 	run_bottom_up(alloc_no_memory_generic_check);
8330237ee23SKarolina Drobnik 
8340237ee23SKarolina Drobnik 	return 0;
8350237ee23SKarolina Drobnik }
8360237ee23SKarolina Drobnik 
alloc_too_large_check(void)83721a233f6SRebecca Mckeever static int alloc_too_large_check(void)
83821a233f6SRebecca Mckeever {
83921a233f6SRebecca Mckeever 	test_print("\tRunning %s...\n", __func__);
84021a233f6SRebecca Mckeever 	run_top_down(alloc_too_large_generic_check);
84121a233f6SRebecca Mckeever 	run_bottom_up(alloc_too_large_generic_check);
84221a233f6SRebecca Mckeever 
84321a233f6SRebecca Mckeever 	return 0;
84421a233f6SRebecca Mckeever }
84521a233f6SRebecca Mckeever 
memblock_alloc_checks_internal(int flags)846deee033eSRebecca Mckeever static int memblock_alloc_checks_internal(int flags)
847142eac65SKarolina Drobnik {
848deee033eSRebecca Mckeever 	const char *func = get_memblock_alloc_name(flags);
84976586c00SRebecca Mckeever 
850deee033eSRebecca Mckeever 	alloc_test_flags = flags;
85176586c00SRebecca Mckeever 	prefix_reset();
852deee033eSRebecca Mckeever 	prefix_push(func);
853deee033eSRebecca Mckeever 	test_print("Running %s tests...\n", func);
85476586c00SRebecca Mckeever 
855142eac65SKarolina Drobnik 	reset_memblock_attributes();
856142eac65SKarolina Drobnik 	dummy_physical_memory_init();
857142eac65SKarolina Drobnik 
8580237ee23SKarolina Drobnik 	alloc_simple_check();
8590237ee23SKarolina Drobnik 	alloc_disjoint_check();
8600237ee23SKarolina Drobnik 	alloc_before_check();
8610237ee23SKarolina Drobnik 	alloc_after_check();
8620237ee23SKarolina Drobnik 	alloc_second_fit_check();
8630237ee23SKarolina Drobnik 	alloc_small_gaps_check();
8640237ee23SKarolina Drobnik 	alloc_in_between_check();
8650237ee23SKarolina Drobnik 	alloc_all_reserved_check();
8660237ee23SKarolina Drobnik 	alloc_no_space_check();
8670237ee23SKarolina Drobnik 	alloc_limited_space_check();
8680237ee23SKarolina Drobnik 	alloc_no_memory_check();
86921a233f6SRebecca Mckeever 	alloc_too_large_check();
870142eac65SKarolina Drobnik 
871142eac65SKarolina Drobnik 	dummy_physical_memory_cleanup();
872142eac65SKarolina Drobnik 
87376586c00SRebecca Mckeever 	prefix_pop();
87476586c00SRebecca Mckeever 
875142eac65SKarolina Drobnik 	return 0;
876142eac65SKarolina Drobnik }
877deee033eSRebecca Mckeever 
memblock_alloc_checks(void)878deee033eSRebecca Mckeever int memblock_alloc_checks(void)
879deee033eSRebecca Mckeever {
880deee033eSRebecca Mckeever 	memblock_alloc_checks_internal(TEST_F_NONE);
881deee033eSRebecca Mckeever 	memblock_alloc_checks_internal(TEST_F_RAW);
882deee033eSRebecca Mckeever 
883deee033eSRebecca Mckeever 	return 0;
884deee033eSRebecca Mckeever }
885