1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #include "alloc_helpers_api.h"
5 * A simple test that tries to allocate a memory region above a specified,
11 * +----------+-----------+---------+
16 * Expect to allocate a cleared region at the minimal memory address.
18 static int alloc_from_simple_generic_check(void)
20 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
21 void *allocated_ptr
= NULL
;
22 phys_addr_t size
= SZ_16
;
28 min_addr
= memblock_end_of_DRAM() - SMP_CACHE_BYTES
;
30 allocated_ptr
= memblock_alloc_from(size
, SMP_CACHE_BYTES
, min_addr
);
32 ASSERT_NE(allocated_ptr
, NULL
);
33 ASSERT_MEM_EQ(allocated_ptr
, 0, size
);
35 ASSERT_EQ(rgn
->size
, size
);
36 ASSERT_EQ(rgn
->base
, min_addr
);
38 ASSERT_EQ(memblock
.reserved
.cnt
, 1);
39 ASSERT_EQ(memblock
.reserved
.total_size
, size
);
47 * A test that tries to allocate a memory region above a certain address.
48 * The minimal address here is not aligned:
53 * +------+------+---------+------------+
56 * min_addr Aligned address
59 * Expect to allocate a cleared region at the closest aligned memory address.
61 static int alloc_from_misaligned_generic_check(void)
63 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
64 void *allocated_ptr
= NULL
;
65 phys_addr_t size
= SZ_32
;
71 /* A misaligned address */
72 min_addr
= memblock_end_of_DRAM() - (SMP_CACHE_BYTES
* 2 - 1);
74 allocated_ptr
= memblock_alloc_from(size
, SMP_CACHE_BYTES
, min_addr
);
76 ASSERT_NE(allocated_ptr
, NULL
);
77 ASSERT_MEM_EQ(allocated_ptr
, 0, size
);
79 ASSERT_EQ(rgn
->size
, size
);
80 ASSERT_EQ(rgn
->base
, memblock_end_of_DRAM() - SMP_CACHE_BYTES
);
82 ASSERT_EQ(memblock
.reserved
.cnt
, 1);
83 ASSERT_EQ(memblock
.reserved
.total_size
, size
);
91 * A test that tries to allocate a memory region above an address that is too
92 * close to the end of the memory:
97 * +-----------+--------+---+------+
105 * Expect to prioritize granting memory over satisfying the minimal address
108 static int alloc_from_top_down_high_addr_check(void)
110 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
111 void *allocated_ptr
= NULL
;
112 phys_addr_t size
= SZ_32
;
113 phys_addr_t min_addr
;
118 /* The address is too close to the end of the memory */
119 min_addr
= memblock_end_of_DRAM() - SZ_16
;
121 allocated_ptr
= memblock_alloc_from(size
, SMP_CACHE_BYTES
, min_addr
);
123 ASSERT_NE(allocated_ptr
, NULL
);
124 ASSERT_EQ(rgn
->size
, size
);
125 ASSERT_EQ(rgn
->base
, memblock_end_of_DRAM() - SMP_CACHE_BYTES
);
127 ASSERT_EQ(memblock
.reserved
.cnt
, 1);
128 ASSERT_EQ(memblock
.reserved
.total_size
, size
);
136 * A test that tries to allocate a memory region when there is no space
137 * available above the minimal address above a certain address:
140 * | +---------+-------------|
142 * +--------+---------+-------------+
147 * Expect to prioritize granting memory over satisfying the minimal address
148 * requirement and to allocate next to the previously reserved region. The
149 * regions get merged into one.
151 static int alloc_from_top_down_no_space_above_check(void)
153 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
154 void *allocated_ptr
= NULL
;
155 phys_addr_t r1_size
= SZ_64
;
156 phys_addr_t r2_size
= SZ_2
;
157 phys_addr_t total_size
= r1_size
+ r2_size
;
158 phys_addr_t min_addr
;
163 min_addr
= memblock_end_of_DRAM() - SMP_CACHE_BYTES
* 2;
165 /* No space above this address */
166 memblock_reserve(min_addr
, r2_size
);
168 allocated_ptr
= memblock_alloc_from(r1_size
, SMP_CACHE_BYTES
, min_addr
);
170 ASSERT_NE(allocated_ptr
, NULL
);
171 ASSERT_EQ(rgn
->base
, min_addr
- r1_size
);
172 ASSERT_EQ(rgn
->size
, total_size
);
174 ASSERT_EQ(memblock
.reserved
.cnt
, 1);
175 ASSERT_EQ(memblock
.reserved
.total_size
, total_size
);
183 * A test that tries to allocate a memory region with a minimal address below
184 * the start address of the available memory. As the allocation is top-down,
185 * first reserve a region that will force allocation near the start.
186 * Expect successful allocation and merge of both regions.
188 static int alloc_from_top_down_min_addr_cap_check(void)
190 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
191 void *allocated_ptr
= NULL
;
192 phys_addr_t r1_size
= SZ_64
;
193 phys_addr_t min_addr
;
194 phys_addr_t start_addr
;
199 start_addr
= (phys_addr_t
)memblock_start_of_DRAM();
200 min_addr
= start_addr
- SMP_CACHE_BYTES
* 3;
202 memblock_reserve(start_addr
+ r1_size
, MEM_SIZE
- r1_size
);
204 allocated_ptr
= memblock_alloc_from(r1_size
, SMP_CACHE_BYTES
, min_addr
);
206 ASSERT_NE(allocated_ptr
, NULL
);
207 ASSERT_EQ(rgn
->base
, start_addr
);
208 ASSERT_EQ(rgn
->size
, MEM_SIZE
);
210 ASSERT_EQ(memblock
.reserved
.cnt
, 1);
211 ASSERT_EQ(memblock
.reserved
.total_size
, MEM_SIZE
);
219 * A test that tries to allocate a memory region above an address that is too
220 * close to the end of the memory:
225 * +-----------+--------------+-----+
228 * Aligned address min_addr
231 * Expect to prioritize granting memory over satisfying the minimal address
232 * requirement. Allocation happens at beginning of the available memory.
234 static int alloc_from_bottom_up_high_addr_check(void)
236 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
237 void *allocated_ptr
= NULL
;
238 phys_addr_t size
= SZ_32
;
239 phys_addr_t min_addr
;
244 /* The address is too close to the end of the memory */
245 min_addr
= memblock_end_of_DRAM() - SZ_8
;
247 allocated_ptr
= memblock_alloc_from(size
, SMP_CACHE_BYTES
, min_addr
);
249 ASSERT_NE(allocated_ptr
, NULL
);
250 ASSERT_EQ(rgn
->size
, size
);
251 ASSERT_EQ(rgn
->base
, memblock_start_of_DRAM());
253 ASSERT_EQ(memblock
.reserved
.cnt
, 1);
254 ASSERT_EQ(memblock
.reserved
.total_size
, size
);
262 * A test that tries to allocate a memory region when there is no space
263 * available above the minimal address above a certain address:
266 * |-----------+ +-------------------|
268 * +-----------+----+-------------------+
273 * Expect to prioritize granting memory over satisfying the minimal address
274 * requirement and to allocate at the beginning of the available memory.
276 static int alloc_from_bottom_up_no_space_above_check(void)
278 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
279 void *allocated_ptr
= NULL
;
280 phys_addr_t r1_size
= SZ_64
;
281 phys_addr_t min_addr
;
287 min_addr
= memblock_start_of_DRAM() + SZ_128
;
288 r2_size
= memblock_end_of_DRAM() - min_addr
;
290 /* No space above this address */
291 memblock_reserve(min_addr
- SMP_CACHE_BYTES
, r2_size
);
293 allocated_ptr
= memblock_alloc_from(r1_size
, SMP_CACHE_BYTES
, min_addr
);
295 ASSERT_NE(allocated_ptr
, NULL
);
296 ASSERT_EQ(rgn
->base
, memblock_start_of_DRAM());
297 ASSERT_EQ(rgn
->size
, r1_size
);
299 ASSERT_EQ(memblock
.reserved
.cnt
, 2);
300 ASSERT_EQ(memblock
.reserved
.total_size
, r1_size
+ r2_size
);
308 * A test that tries to allocate a memory region with a minimal address below
309 * the start address of the available memory. Expect to allocate a region
310 * at the beginning of the available memory.
312 static int alloc_from_bottom_up_min_addr_cap_check(void)
314 struct memblock_region
*rgn
= &memblock
.reserved
.regions
[0];
315 void *allocated_ptr
= NULL
;
316 phys_addr_t r1_size
= SZ_64
;
317 phys_addr_t min_addr
;
318 phys_addr_t start_addr
;
323 start_addr
= (phys_addr_t
)memblock_start_of_DRAM();
324 min_addr
= start_addr
- SMP_CACHE_BYTES
* 3;
326 allocated_ptr
= memblock_alloc_from(r1_size
, SMP_CACHE_BYTES
, min_addr
);
328 ASSERT_NE(allocated_ptr
, NULL
);
329 ASSERT_EQ(rgn
->base
, start_addr
);
330 ASSERT_EQ(rgn
->size
, r1_size
);
332 ASSERT_EQ(memblock
.reserved
.cnt
, 1);
333 ASSERT_EQ(memblock
.reserved
.total_size
, r1_size
);
340 /* Test case wrappers */
341 static int alloc_from_simple_check(void)
343 test_print("\tRunning %s...\n", __func__
);
344 run_top_down(alloc_from_simple_generic_check
);
345 run_bottom_up(alloc_from_simple_generic_check
);
350 static int alloc_from_misaligned_check(void)
352 test_print("\tRunning %s...\n", __func__
);
353 run_top_down(alloc_from_misaligned_generic_check
);
354 run_bottom_up(alloc_from_misaligned_generic_check
);
359 static int alloc_from_high_addr_check(void)
361 test_print("\tRunning %s...\n", __func__
);
362 memblock_set_bottom_up(false);
363 alloc_from_top_down_high_addr_check();
364 memblock_set_bottom_up(true);
365 alloc_from_bottom_up_high_addr_check();
370 static int alloc_from_no_space_above_check(void)
372 test_print("\tRunning %s...\n", __func__
);
373 memblock_set_bottom_up(false);
374 alloc_from_top_down_no_space_above_check();
375 memblock_set_bottom_up(true);
376 alloc_from_bottom_up_no_space_above_check();
381 static int alloc_from_min_addr_cap_check(void)
383 test_print("\tRunning %s...\n", __func__
);
384 memblock_set_bottom_up(false);
385 alloc_from_top_down_min_addr_cap_check();
386 memblock_set_bottom_up(true);
387 alloc_from_bottom_up_min_addr_cap_check();
392 int memblock_alloc_helpers_checks(void)
394 const char *func_testing
= "memblock_alloc_from";
397 prefix_push(func_testing
);
398 test_print("Running %s tests...\n", func_testing
);
400 reset_memblock_attributes();
401 dummy_physical_memory_init();
403 alloc_from_simple_check();
404 alloc_from_misaligned_check();
405 alloc_from_high_addr_check();
406 alloc_from_no_space_above_check();
407 alloc_from_min_addr_cap_check();
409 dummy_physical_memory_cleanup();