xref: /linux/tools/testing/memblock/tests/basic_api.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1f3252a22SKarolina Drobnik // SPDX-License-Identifier: GPL-2.0-or-later
255122e01SMike Rapoport (IBM) #include "basic_api.h"
3f3252a22SKarolina Drobnik #include <string.h>
4f3252a22SKarolina Drobnik #include <linux/memblock.h>
5f3252a22SKarolina Drobnik 
6f3252a22SKarolina Drobnik #define EXPECTED_MEMBLOCK_REGIONS			128
776586c00SRebecca Mckeever #define FUNC_ADD					"memblock_add"
876586c00SRebecca Mckeever #define FUNC_RESERVE					"memblock_reserve"
976586c00SRebecca Mckeever #define FUNC_REMOVE					"memblock_remove"
1076586c00SRebecca Mckeever #define FUNC_FREE					"memblock_free"
11dcd45ad2SRebecca Mckeever #define FUNC_TRIM					"memblock_trim_memory"
12f3252a22SKarolina Drobnik 
memblock_initialization_check(void)13f3252a22SKarolina Drobnik static int memblock_initialization_check(void)
14f3252a22SKarolina Drobnik {
1576586c00SRebecca Mckeever 	PREFIX_PUSH();
16f3252a22SKarolina Drobnik 
1776586c00SRebecca Mckeever 	ASSERT_NE(memblock.memory.regions, NULL);
18721f4a65SWei Yang 	ASSERT_EQ(memblock.memory.cnt, 0);
1976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.max, EXPECTED_MEMBLOCK_REGIONS);
2076586c00SRebecca Mckeever 	ASSERT_EQ(strcmp(memblock.memory.name, "memory"), 0);
21f3252a22SKarolina Drobnik 
2276586c00SRebecca Mckeever 	ASSERT_NE(memblock.reserved.regions, NULL);
23721f4a65SWei Yang 	ASSERT_EQ(memblock.reserved.cnt, 0);
2476586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.max, EXPECTED_MEMBLOCK_REGIONS);
2576586c00SRebecca Mckeever 	ASSERT_EQ(strcmp(memblock.reserved.name, "reserved"), 0);
2676586c00SRebecca Mckeever 
2776586c00SRebecca Mckeever 	ASSERT_EQ(memblock.bottom_up, false);
2876586c00SRebecca Mckeever 	ASSERT_EQ(memblock.current_limit, MEMBLOCK_ALLOC_ANYWHERE);
2976586c00SRebecca Mckeever 
3076586c00SRebecca Mckeever 	test_pass_pop();
31f3252a22SKarolina Drobnik 
32f3252a22SKarolina Drobnik 	return 0;
33f3252a22SKarolina Drobnik }
34f3252a22SKarolina Drobnik 
351f1180d4SKarolina Drobnik /*
361f1180d4SKarolina Drobnik  * A simple test that adds a memory block of a specified base address
371f1180d4SKarolina Drobnik  * and size to the collection of available memory regions (memblock.memory).
3823b5c796SRebecca Mckeever  * Expect to create a new entry. The region counter and total memory get
3923b5c796SRebecca Mckeever  * updated.
401f1180d4SKarolina Drobnik  */
memblock_add_simple_check(void)411f1180d4SKarolina Drobnik static int memblock_add_simple_check(void)
421f1180d4SKarolina Drobnik {
431f1180d4SKarolina Drobnik 	struct memblock_region *rgn;
441f1180d4SKarolina Drobnik 
451f1180d4SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
461f1180d4SKarolina Drobnik 
471f1180d4SKarolina Drobnik 	struct region r = {
481f1180d4SKarolina Drobnik 		.base = SZ_1G,
491f1180d4SKarolina Drobnik 		.size = SZ_4M
501f1180d4SKarolina Drobnik 	};
511f1180d4SKarolina Drobnik 
5276586c00SRebecca Mckeever 	PREFIX_PUSH();
5376586c00SRebecca Mckeever 
542c3dacbaSKarolina Drobnik 	reset_memblock_regions();
551f1180d4SKarolina Drobnik 	memblock_add(r.base, r.size);
561f1180d4SKarolina Drobnik 
5776586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r.base);
5876586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r.size);
591f1180d4SKarolina Drobnik 
6076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
6176586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, r.size);
6276586c00SRebecca Mckeever 
6376586c00SRebecca Mckeever 	test_pass_pop();
641f1180d4SKarolina Drobnik 
651f1180d4SKarolina Drobnik 	return 0;
661f1180d4SKarolina Drobnik }
671f1180d4SKarolina Drobnik 
681f1180d4SKarolina Drobnik /*
6923b5c796SRebecca Mckeever  * A simple test that adds a memory block of a specified base address, size,
70e393c093SKarolina Drobnik  * NUMA node and memory flags to the collection of available memory regions.
7123b5c796SRebecca Mckeever  * Expect to create a new entry. The region counter and total memory get
7223b5c796SRebecca Mckeever  * updated.
73e393c093SKarolina Drobnik  */
memblock_add_node_simple_check(void)74e393c093SKarolina Drobnik static int memblock_add_node_simple_check(void)
75e393c093SKarolina Drobnik {
76e393c093SKarolina Drobnik 	struct memblock_region *rgn;
77e393c093SKarolina Drobnik 
78e393c093SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
79e393c093SKarolina Drobnik 
80e393c093SKarolina Drobnik 	struct region r = {
81e393c093SKarolina Drobnik 		.base = SZ_1M,
82e393c093SKarolina Drobnik 		.size = SZ_16M
83e393c093SKarolina Drobnik 	};
84e393c093SKarolina Drobnik 
8576586c00SRebecca Mckeever 	PREFIX_PUSH();
8676586c00SRebecca Mckeever 
872c3dacbaSKarolina Drobnik 	reset_memblock_regions();
88e393c093SKarolina Drobnik 	memblock_add_node(r.base, r.size, 1, MEMBLOCK_HOTPLUG);
89e393c093SKarolina Drobnik 
9076586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r.base);
9176586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r.size);
92e393c093SKarolina Drobnik #ifdef CONFIG_NUMA
9376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->nid, 1);
94e393c093SKarolina Drobnik #endif
9576586c00SRebecca Mckeever 	ASSERT_EQ(rgn->flags, MEMBLOCK_HOTPLUG);
96e393c093SKarolina Drobnik 
9776586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
9876586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, r.size);
9976586c00SRebecca Mckeever 
10076586c00SRebecca Mckeever 	test_pass_pop();
101e393c093SKarolina Drobnik 
102e393c093SKarolina Drobnik 	return 0;
103e393c093SKarolina Drobnik }
104e393c093SKarolina Drobnik 
105e393c093SKarolina Drobnik /*
1061f1180d4SKarolina Drobnik  * A test that tries to add two memory blocks that don't overlap with one
10723b5c796SRebecca Mckeever  * another:
10823b5c796SRebecca Mckeever  *
10923b5c796SRebecca Mckeever  *  |        +--------+        +--------+  |
11023b5c796SRebecca Mckeever  *  |        |   r1   |        |   r2   |  |
11123b5c796SRebecca Mckeever  *  +--------+--------+--------+--------+--+
11223b5c796SRebecca Mckeever  *
11323b5c796SRebecca Mckeever  * Expect to add two correctly initialized entries to the collection of
11423b5c796SRebecca Mckeever  * available memory regions (memblock.memory). The total size and
11523b5c796SRebecca Mckeever  * region counter fields get updated.
1161f1180d4SKarolina Drobnik  */
memblock_add_disjoint_check(void)1171f1180d4SKarolina Drobnik static int memblock_add_disjoint_check(void)
1181f1180d4SKarolina Drobnik {
1191f1180d4SKarolina Drobnik 	struct memblock_region *rgn1, *rgn2;
1201f1180d4SKarolina Drobnik 
1211f1180d4SKarolina Drobnik 	rgn1 = &memblock.memory.regions[0];
1221f1180d4SKarolina Drobnik 	rgn2 = &memblock.memory.regions[1];
1231f1180d4SKarolina Drobnik 
1241f1180d4SKarolina Drobnik 	struct region r1 = {
1251f1180d4SKarolina Drobnik 		.base = SZ_1G,
1261f1180d4SKarolina Drobnik 		.size = SZ_8K
1271f1180d4SKarolina Drobnik 	};
1281f1180d4SKarolina Drobnik 	struct region r2 = {
1291f1180d4SKarolina Drobnik 		.base = SZ_1G + SZ_16K,
1301f1180d4SKarolina Drobnik 		.size = SZ_8K
1311f1180d4SKarolina Drobnik 	};
1321f1180d4SKarolina Drobnik 
13376586c00SRebecca Mckeever 	PREFIX_PUSH();
13476586c00SRebecca Mckeever 
1352c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1361f1180d4SKarolina Drobnik 	memblock_add(r1.base, r1.size);
1371f1180d4SKarolina Drobnik 	memblock_add(r2.base, r2.size);
1381f1180d4SKarolina Drobnik 
13976586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
14076586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1.size);
1411f1180d4SKarolina Drobnik 
14276586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->base, r2.base);
14376586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->size, r2.size);
1441f1180d4SKarolina Drobnik 
14576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 2);
14676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, r1.size + r2.size);
14776586c00SRebecca Mckeever 
14876586c00SRebecca Mckeever 	test_pass_pop();
1491f1180d4SKarolina Drobnik 
1501f1180d4SKarolina Drobnik 	return 0;
1511f1180d4SKarolina Drobnik }
1521f1180d4SKarolina Drobnik 
1531f1180d4SKarolina Drobnik /*
15423b5c796SRebecca Mckeever  * A test that tries to add two memory blocks r1 and r2, where r2 overlaps
15523b5c796SRebecca Mckeever  * with the beginning of r1 (that is r1.base < r2.base + r2.size):
15623b5c796SRebecca Mckeever  *
15723b5c796SRebecca Mckeever  *  |    +----+----+------------+          |
15823b5c796SRebecca Mckeever  *  |    |    |r2  |   r1       |          |
15923b5c796SRebecca Mckeever  *  +----+----+----+------------+----------+
16023b5c796SRebecca Mckeever  *       ^    ^
16123b5c796SRebecca Mckeever  *       |    |
16223b5c796SRebecca Mckeever  *       |    r1.base
16323b5c796SRebecca Mckeever  *       |
16423b5c796SRebecca Mckeever  *       r2.base
16523b5c796SRebecca Mckeever  *
16623b5c796SRebecca Mckeever  * Expect to merge the two entries into one region that starts at r2.base
16723b5c796SRebecca Mckeever  * and has size of two regions minus their intersection. The total size of
16823b5c796SRebecca Mckeever  * the available memory is updated, and the region counter stays the same.
1691f1180d4SKarolina Drobnik  */
memblock_add_overlap_top_check(void)1701f1180d4SKarolina Drobnik static int memblock_add_overlap_top_check(void)
1711f1180d4SKarolina Drobnik {
1721f1180d4SKarolina Drobnik 	struct memblock_region *rgn;
1731f1180d4SKarolina Drobnik 	phys_addr_t total_size;
1741f1180d4SKarolina Drobnik 
1751f1180d4SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
1761f1180d4SKarolina Drobnik 
1771f1180d4SKarolina Drobnik 	struct region r1 = {
1781f1180d4SKarolina Drobnik 		.base = SZ_512M,
1791f1180d4SKarolina Drobnik 		.size = SZ_1G
1801f1180d4SKarolina Drobnik 	};
1811f1180d4SKarolina Drobnik 	struct region r2 = {
1821f1180d4SKarolina Drobnik 		.base = SZ_256M,
1831f1180d4SKarolina Drobnik 		.size = SZ_512M
1841f1180d4SKarolina Drobnik 	};
1851f1180d4SKarolina Drobnik 
18676586c00SRebecca Mckeever 	PREFIX_PUSH();
18776586c00SRebecca Mckeever 
1881f1180d4SKarolina Drobnik 	total_size = (r1.base - r2.base) + r1.size;
1891f1180d4SKarolina Drobnik 
1902c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1911f1180d4SKarolina Drobnik 	memblock_add(r1.base, r1.size);
1921f1180d4SKarolina Drobnik 	memblock_add(r2.base, r2.size);
1931f1180d4SKarolina Drobnik 
19476586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r2.base);
19576586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
1961f1180d4SKarolina Drobnik 
19776586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
19876586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
19976586c00SRebecca Mckeever 
20076586c00SRebecca Mckeever 	test_pass_pop();
2011f1180d4SKarolina Drobnik 
2021f1180d4SKarolina Drobnik 	return 0;
2031f1180d4SKarolina Drobnik }
2041f1180d4SKarolina Drobnik 
2051f1180d4SKarolina Drobnik /*
20623b5c796SRebecca Mckeever  * A test that tries to add two memory blocks r1 and r2, where r2 overlaps
20723b5c796SRebecca Mckeever  * with the end of r1 (that is r2.base < r1.base + r1.size):
20823b5c796SRebecca Mckeever  *
20923b5c796SRebecca Mckeever  *  |  +--+------+----------+              |
21023b5c796SRebecca Mckeever  *  |  |  | r1   | r2       |              |
21123b5c796SRebecca Mckeever  *  +--+--+------+----------+--------------+
21223b5c796SRebecca Mckeever  *     ^  ^
21323b5c796SRebecca Mckeever  *     |  |
21423b5c796SRebecca Mckeever  *     |  r2.base
21523b5c796SRebecca Mckeever  *     |
21623b5c796SRebecca Mckeever  *     r1.base
21723b5c796SRebecca Mckeever  *
21823b5c796SRebecca Mckeever  * Expect to merge the two entries into one region that starts at r1.base
21923b5c796SRebecca Mckeever  * and has size of two regions minus their intersection. The total size of
22023b5c796SRebecca Mckeever  * the available memory is updated, and the region counter stays the same.
2211f1180d4SKarolina Drobnik  */
memblock_add_overlap_bottom_check(void)2221f1180d4SKarolina Drobnik static int memblock_add_overlap_bottom_check(void)
2231f1180d4SKarolina Drobnik {
2241f1180d4SKarolina Drobnik 	struct memblock_region *rgn;
2251f1180d4SKarolina Drobnik 	phys_addr_t total_size;
2261f1180d4SKarolina Drobnik 
2271f1180d4SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
2281f1180d4SKarolina Drobnik 
2291f1180d4SKarolina Drobnik 	struct region r1 = {
2301f1180d4SKarolina Drobnik 		.base = SZ_128M,
2311f1180d4SKarolina Drobnik 		.size = SZ_512M
2321f1180d4SKarolina Drobnik 	};
2331f1180d4SKarolina Drobnik 	struct region r2 = {
2341f1180d4SKarolina Drobnik 		.base = SZ_256M,
2351f1180d4SKarolina Drobnik 		.size = SZ_1G
2361f1180d4SKarolina Drobnik 	};
2371f1180d4SKarolina Drobnik 
23876586c00SRebecca Mckeever 	PREFIX_PUSH();
23976586c00SRebecca Mckeever 
2401f1180d4SKarolina Drobnik 	total_size = (r2.base - r1.base) + r2.size;
2411f1180d4SKarolina Drobnik 
2422c3dacbaSKarolina Drobnik 	reset_memblock_regions();
2431f1180d4SKarolina Drobnik 	memblock_add(r1.base, r1.size);
2441f1180d4SKarolina Drobnik 	memblock_add(r2.base, r2.size);
2451f1180d4SKarolina Drobnik 
24676586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
24776586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
2481f1180d4SKarolina Drobnik 
24976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
25076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
25176586c00SRebecca Mckeever 
25276586c00SRebecca Mckeever 	test_pass_pop();
2531f1180d4SKarolina Drobnik 
2541f1180d4SKarolina Drobnik 	return 0;
2551f1180d4SKarolina Drobnik }
2561f1180d4SKarolina Drobnik 
2571f1180d4SKarolina Drobnik /*
25823b5c796SRebecca Mckeever  * A test that tries to add two memory blocks r1 and r2, where r2 is
25923b5c796SRebecca Mckeever  * within the range of r1 (that is r1.base < r2.base &&
26023b5c796SRebecca Mckeever  * r2.base + r2.size < r1.base + r1.size):
26123b5c796SRebecca Mckeever  *
26223b5c796SRebecca Mckeever  *  |   +-------+--+-----------------------+
26323b5c796SRebecca Mckeever  *  |   |       |r2|      r1               |
26423b5c796SRebecca Mckeever  *  +---+-------+--+-----------------------+
26523b5c796SRebecca Mckeever  *      ^
26623b5c796SRebecca Mckeever  *      |
26723b5c796SRebecca Mckeever  *      r1.base
26823b5c796SRebecca Mckeever  *
26923b5c796SRebecca Mckeever  * Expect to merge two entries into one region that stays the same.
27023b5c796SRebecca Mckeever  * The counter and total size of available memory are not updated.
2711f1180d4SKarolina Drobnik  */
memblock_add_within_check(void)2721f1180d4SKarolina Drobnik static int memblock_add_within_check(void)
2731f1180d4SKarolina Drobnik {
2741f1180d4SKarolina Drobnik 	struct memblock_region *rgn;
2751f1180d4SKarolina Drobnik 
2761f1180d4SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
2771f1180d4SKarolina Drobnik 
2781f1180d4SKarolina Drobnik 	struct region r1 = {
2791f1180d4SKarolina Drobnik 		.base = SZ_8M,
2801f1180d4SKarolina Drobnik 		.size = SZ_32M
2811f1180d4SKarolina Drobnik 	};
2821f1180d4SKarolina Drobnik 	struct region r2 = {
2831f1180d4SKarolina Drobnik 		.base = SZ_16M,
2841f1180d4SKarolina Drobnik 		.size = SZ_1M
2851f1180d4SKarolina Drobnik 	};
2861f1180d4SKarolina Drobnik 
28776586c00SRebecca Mckeever 	PREFIX_PUSH();
28876586c00SRebecca Mckeever 
2892c3dacbaSKarolina Drobnik 	reset_memblock_regions();
2901f1180d4SKarolina Drobnik 	memblock_add(r1.base, r1.size);
2911f1180d4SKarolina Drobnik 	memblock_add(r2.base, r2.size);
2921f1180d4SKarolina Drobnik 
29376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
29476586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r1.size);
2951f1180d4SKarolina Drobnik 
29676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
29776586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, r1.size);
29876586c00SRebecca Mckeever 
29976586c00SRebecca Mckeever 	test_pass_pop();
3001f1180d4SKarolina Drobnik 
3011f1180d4SKarolina Drobnik 	return 0;
3021f1180d4SKarolina Drobnik }
3031f1180d4SKarolina Drobnik 
3041f1180d4SKarolina Drobnik /*
30523b5c796SRebecca Mckeever  * A simple test that tries to add the same memory block twice. Expect
30623b5c796SRebecca Mckeever  * the counter and total size of available memory to not be updated.
3071f1180d4SKarolina Drobnik  */
memblock_add_twice_check(void)3081f1180d4SKarolina Drobnik static int memblock_add_twice_check(void)
3091f1180d4SKarolina Drobnik {
3101f1180d4SKarolina Drobnik 	struct region r = {
3111f1180d4SKarolina Drobnik 		.base = SZ_16K,
3121f1180d4SKarolina Drobnik 		.size = SZ_2M
3131f1180d4SKarolina Drobnik 	};
3141f1180d4SKarolina Drobnik 
31576586c00SRebecca Mckeever 	PREFIX_PUSH();
31676586c00SRebecca Mckeever 
3172c3dacbaSKarolina Drobnik 	reset_memblock_regions();
3181f1180d4SKarolina Drobnik 
3191f1180d4SKarolina Drobnik 	memblock_add(r.base, r.size);
3201f1180d4SKarolina Drobnik 	memblock_add(r.base, r.size);
3211f1180d4SKarolina Drobnik 
32276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
32376586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, r.size);
32476586c00SRebecca Mckeever 
32576586c00SRebecca Mckeever 	test_pass_pop();
3261f1180d4SKarolina Drobnik 
3271f1180d4SKarolina Drobnik 	return 0;
3281f1180d4SKarolina Drobnik }
3291f1180d4SKarolina Drobnik 
33021a233f6SRebecca Mckeever /*
33121a233f6SRebecca Mckeever  * A test that tries to add two memory blocks that don't overlap with one
33221a233f6SRebecca Mckeever  * another and then add a third memory block in the space between the first two:
33321a233f6SRebecca Mckeever  *
33421a233f6SRebecca Mckeever  *  |        +--------+--------+--------+  |
33521a233f6SRebecca Mckeever  *  |        |   r1   |   r3   |   r2   |  |
33621a233f6SRebecca Mckeever  *  +--------+--------+--------+--------+--+
33721a233f6SRebecca Mckeever  *
33821a233f6SRebecca Mckeever  * Expect to merge the three entries into one region that starts at r1.base
33921a233f6SRebecca Mckeever  * and has size of r1.size + r2.size + r3.size. The region counter and total
34021a233f6SRebecca Mckeever  * size of the available memory are updated.
34121a233f6SRebecca Mckeever  */
memblock_add_between_check(void)34221a233f6SRebecca Mckeever static int memblock_add_between_check(void)
34321a233f6SRebecca Mckeever {
34421a233f6SRebecca Mckeever 	struct memblock_region *rgn;
34521a233f6SRebecca Mckeever 	phys_addr_t total_size;
34621a233f6SRebecca Mckeever 
34721a233f6SRebecca Mckeever 	rgn = &memblock.memory.regions[0];
34821a233f6SRebecca Mckeever 
34921a233f6SRebecca Mckeever 	struct region r1 = {
35021a233f6SRebecca Mckeever 		.base = SZ_1G,
35121a233f6SRebecca Mckeever 		.size = SZ_8K
35221a233f6SRebecca Mckeever 	};
35321a233f6SRebecca Mckeever 	struct region r2 = {
35421a233f6SRebecca Mckeever 		.base = SZ_1G + SZ_16K,
35521a233f6SRebecca Mckeever 		.size = SZ_8K
35621a233f6SRebecca Mckeever 	};
35721a233f6SRebecca Mckeever 	struct region r3 = {
35821a233f6SRebecca Mckeever 		.base = SZ_1G + SZ_8K,
35921a233f6SRebecca Mckeever 		.size = SZ_8K
36021a233f6SRebecca Mckeever 	};
36121a233f6SRebecca Mckeever 
36221a233f6SRebecca Mckeever 	PREFIX_PUSH();
36321a233f6SRebecca Mckeever 
36421a233f6SRebecca Mckeever 	total_size = r1.size + r2.size + r3.size;
36521a233f6SRebecca Mckeever 
36621a233f6SRebecca Mckeever 	reset_memblock_regions();
36721a233f6SRebecca Mckeever 	memblock_add(r1.base, r1.size);
36821a233f6SRebecca Mckeever 	memblock_add(r2.base, r2.size);
36921a233f6SRebecca Mckeever 	memblock_add(r3.base, r3.size);
37021a233f6SRebecca Mckeever 
37121a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
37221a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
37321a233f6SRebecca Mckeever 
37421a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
37521a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
37621a233f6SRebecca Mckeever 
37721a233f6SRebecca Mckeever 	test_pass_pop();
37821a233f6SRebecca Mckeever 
37921a233f6SRebecca Mckeever 	return 0;
38021a233f6SRebecca Mckeever }
38121a233f6SRebecca Mckeever 
38221a233f6SRebecca Mckeever /*
38321a233f6SRebecca Mckeever  * A simple test that tries to add a memory block r when r extends past
38421a233f6SRebecca Mckeever  * PHYS_ADDR_MAX:
38521a233f6SRebecca Mckeever  *
38621a233f6SRebecca Mckeever  *                               +--------+
38721a233f6SRebecca Mckeever  *                               |    r   |
38821a233f6SRebecca Mckeever  *                               +--------+
38921a233f6SRebecca Mckeever  *  |                            +----+
39021a233f6SRebecca Mckeever  *  |                            | rgn|
39121a233f6SRebecca Mckeever  *  +----------------------------+----+
39221a233f6SRebecca Mckeever  *
39321a233f6SRebecca Mckeever  * Expect to add a memory block of size PHYS_ADDR_MAX - r.base. Expect the
39421a233f6SRebecca Mckeever  * total size of available memory and the counter to be updated.
39521a233f6SRebecca Mckeever  */
memblock_add_near_max_check(void)39621a233f6SRebecca Mckeever static int memblock_add_near_max_check(void)
39721a233f6SRebecca Mckeever {
39821a233f6SRebecca Mckeever 	struct memblock_region *rgn;
39921a233f6SRebecca Mckeever 	phys_addr_t total_size;
40021a233f6SRebecca Mckeever 
40121a233f6SRebecca Mckeever 	rgn = &memblock.memory.regions[0];
40221a233f6SRebecca Mckeever 
40321a233f6SRebecca Mckeever 	struct region r = {
40421a233f6SRebecca Mckeever 		.base = PHYS_ADDR_MAX - SZ_1M,
40521a233f6SRebecca Mckeever 		.size = SZ_2M
40621a233f6SRebecca Mckeever 	};
40721a233f6SRebecca Mckeever 
40821a233f6SRebecca Mckeever 	PREFIX_PUSH();
40921a233f6SRebecca Mckeever 
41021a233f6SRebecca Mckeever 	total_size = PHYS_ADDR_MAX - r.base;
41121a233f6SRebecca Mckeever 
41221a233f6SRebecca Mckeever 	reset_memblock_regions();
41321a233f6SRebecca Mckeever 	memblock_add(r.base, r.size);
41421a233f6SRebecca Mckeever 
41521a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, r.base);
41621a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
41721a233f6SRebecca Mckeever 
41821a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
41921a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
42021a233f6SRebecca Mckeever 
42121a233f6SRebecca Mckeever 	test_pass_pop();
42221a233f6SRebecca Mckeever 
42321a233f6SRebecca Mckeever 	return 0;
42421a233f6SRebecca Mckeever }
42521a233f6SRebecca Mckeever 
426085bdaa6SShaoqin Huang /*
427085bdaa6SShaoqin Huang  * A test that trying to add the 129th memory block.
428085bdaa6SShaoqin Huang  * Expect to trigger memblock_double_array() to double the
429085bdaa6SShaoqin Huang  * memblock.memory.max, find a new valid memory as
430085bdaa6SShaoqin Huang  * memory.regions.
431085bdaa6SShaoqin Huang  */
memblock_add_many_check(void)432085bdaa6SShaoqin Huang static int memblock_add_many_check(void)
433085bdaa6SShaoqin Huang {
434085bdaa6SShaoqin Huang 	int i;
435085bdaa6SShaoqin Huang 	void *orig_region;
436085bdaa6SShaoqin Huang 	struct region r = {
437085bdaa6SShaoqin Huang 		.base = SZ_16K,
438085bdaa6SShaoqin Huang 		.size = SZ_16K,
439085bdaa6SShaoqin Huang 	};
440085bdaa6SShaoqin Huang 	phys_addr_t new_memory_regions_size;
441085bdaa6SShaoqin Huang 	phys_addr_t base, size = SZ_64;
442085bdaa6SShaoqin Huang 	phys_addr_t gap_size = SZ_64;
443085bdaa6SShaoqin Huang 
444085bdaa6SShaoqin Huang 	PREFIX_PUSH();
445085bdaa6SShaoqin Huang 
446085bdaa6SShaoqin Huang 	reset_memblock_regions();
447085bdaa6SShaoqin Huang 	memblock_allow_resize();
448085bdaa6SShaoqin Huang 
449085bdaa6SShaoqin Huang 	dummy_physical_memory_init();
450085bdaa6SShaoqin Huang 	/*
451085bdaa6SShaoqin Huang 	 * We allocated enough memory by using dummy_physical_memory_init(), and
452085bdaa6SShaoqin Huang 	 * split it into small block. First we split a large enough memory block
453085bdaa6SShaoqin Huang 	 * as the memory region which will be choosed by memblock_double_array().
454085bdaa6SShaoqin Huang 	 */
455085bdaa6SShaoqin Huang 	base = PAGE_ALIGN(dummy_physical_memory_base());
456085bdaa6SShaoqin Huang 	new_memory_regions_size = PAGE_ALIGN(INIT_MEMBLOCK_REGIONS * 2 *
457085bdaa6SShaoqin Huang 					     sizeof(struct memblock_region));
458085bdaa6SShaoqin Huang 	memblock_add(base, new_memory_regions_size);
459085bdaa6SShaoqin Huang 
460085bdaa6SShaoqin Huang 	/* This is the base of small memory block. */
461085bdaa6SShaoqin Huang 	base += new_memory_regions_size + gap_size;
462085bdaa6SShaoqin Huang 
463085bdaa6SShaoqin Huang 	orig_region = memblock.memory.regions;
464085bdaa6SShaoqin Huang 
465085bdaa6SShaoqin Huang 	for (i = 0; i < INIT_MEMBLOCK_REGIONS; i++) {
466085bdaa6SShaoqin Huang 		/*
467085bdaa6SShaoqin Huang 		 * Add these small block to fulfill the memblock. We keep a
468085bdaa6SShaoqin Huang 		 * gap between the nearby memory to avoid being merged.
469085bdaa6SShaoqin Huang 		 */
470085bdaa6SShaoqin Huang 		memblock_add(base, size);
471085bdaa6SShaoqin Huang 		base += size + gap_size;
472085bdaa6SShaoqin Huang 
473085bdaa6SShaoqin Huang 		ASSERT_EQ(memblock.memory.cnt, i + 2);
474085bdaa6SShaoqin Huang 		ASSERT_EQ(memblock.memory.total_size, new_memory_regions_size +
475085bdaa6SShaoqin Huang 						      (i + 1) * size);
476085bdaa6SShaoqin Huang 	}
477085bdaa6SShaoqin Huang 
478085bdaa6SShaoqin Huang 	/*
479085bdaa6SShaoqin Huang 	 * At there, memblock_double_array() has been succeed, check if it
480085bdaa6SShaoqin Huang 	 * update the memory.max.
481085bdaa6SShaoqin Huang 	 */
482085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2);
483085bdaa6SShaoqin Huang 
484085bdaa6SShaoqin Huang 	/* memblock_double_array() will reserve the memory it used. Check it. */
485085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.reserved.cnt, 1);
486085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.reserved.total_size, new_memory_regions_size);
487085bdaa6SShaoqin Huang 
488085bdaa6SShaoqin Huang 	/*
489085bdaa6SShaoqin Huang 	 * Now memblock_double_array() works fine. Let's check after the
490085bdaa6SShaoqin Huang 	 * double_array(), the memblock_add() still works as normal.
491085bdaa6SShaoqin Huang 	 */
492085bdaa6SShaoqin Huang 	memblock_add(r.base, r.size);
493085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.memory.regions[0].base, r.base);
494085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.memory.regions[0].size, r.size);
495085bdaa6SShaoqin Huang 
496085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.memory.cnt, INIT_MEMBLOCK_REGIONS + 2);
497085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.memory.total_size, INIT_MEMBLOCK_REGIONS * size +
498085bdaa6SShaoqin Huang 					      new_memory_regions_size +
499085bdaa6SShaoqin Huang 					      r.size);
500085bdaa6SShaoqin Huang 	ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2);
501085bdaa6SShaoqin Huang 
502085bdaa6SShaoqin Huang 	dummy_physical_memory_cleanup();
503085bdaa6SShaoqin Huang 
504085bdaa6SShaoqin Huang 	/*
505085bdaa6SShaoqin Huang 	 * The current memory.regions is occupying a range of memory that
506085bdaa6SShaoqin Huang 	 * allocated from dummy_physical_memory_init(). After free the memory,
507085bdaa6SShaoqin Huang 	 * we must not use it. So restore the origin memory region to make sure
508085bdaa6SShaoqin Huang 	 * the tests can run as normal and not affected by the double array.
509085bdaa6SShaoqin Huang 	 */
510085bdaa6SShaoqin Huang 	memblock.memory.regions = orig_region;
511085bdaa6SShaoqin Huang 	memblock.memory.cnt = INIT_MEMBLOCK_REGIONS;
512085bdaa6SShaoqin Huang 
513085bdaa6SShaoqin Huang 	test_pass_pop();
514085bdaa6SShaoqin Huang 
515085bdaa6SShaoqin Huang 	return 0;
516085bdaa6SShaoqin Huang }
517085bdaa6SShaoqin Huang 
memblock_add_checks(void)5181f1180d4SKarolina Drobnik static int memblock_add_checks(void)
5191f1180d4SKarolina Drobnik {
52076586c00SRebecca Mckeever 	prefix_reset();
52176586c00SRebecca Mckeever 	prefix_push(FUNC_ADD);
52276586c00SRebecca Mckeever 	test_print("Running %s tests...\n", FUNC_ADD);
52376586c00SRebecca Mckeever 
5241f1180d4SKarolina Drobnik 	memblock_add_simple_check();
525e393c093SKarolina Drobnik 	memblock_add_node_simple_check();
5261f1180d4SKarolina Drobnik 	memblock_add_disjoint_check();
5271f1180d4SKarolina Drobnik 	memblock_add_overlap_top_check();
5281f1180d4SKarolina Drobnik 	memblock_add_overlap_bottom_check();
5291f1180d4SKarolina Drobnik 	memblock_add_within_check();
5301f1180d4SKarolina Drobnik 	memblock_add_twice_check();
53121a233f6SRebecca Mckeever 	memblock_add_between_check();
53221a233f6SRebecca Mckeever 	memblock_add_near_max_check();
533085bdaa6SShaoqin Huang 	memblock_add_many_check();
5341f1180d4SKarolina Drobnik 
53576586c00SRebecca Mckeever 	prefix_pop();
53676586c00SRebecca Mckeever 
5371f1180d4SKarolina Drobnik 	return 0;
5381f1180d4SKarolina Drobnik }
5391f1180d4SKarolina Drobnik 
54083787a80SKarolina Drobnik /*
54183787a80SKarolina Drobnik  * A simple test that marks a memory block of a specified base address
54283787a80SKarolina Drobnik  * and size as reserved and to the collection of reserved memory regions
543e4f76c8dSRebecca Mckeever  * (memblock.reserved). Expect to create a new entry. The region counter
544e4f76c8dSRebecca Mckeever  * and total memory size are updated.
54583787a80SKarolina Drobnik  */
memblock_reserve_simple_check(void)54683787a80SKarolina Drobnik static int memblock_reserve_simple_check(void)
54783787a80SKarolina Drobnik {
54883787a80SKarolina Drobnik 	struct memblock_region *rgn;
54983787a80SKarolina Drobnik 
55083787a80SKarolina Drobnik 	rgn =  &memblock.reserved.regions[0];
55183787a80SKarolina Drobnik 
55283787a80SKarolina Drobnik 	struct region r = {
55383787a80SKarolina Drobnik 		.base = SZ_2G,
55483787a80SKarolina Drobnik 		.size = SZ_128M
55583787a80SKarolina Drobnik 	};
55683787a80SKarolina Drobnik 
55776586c00SRebecca Mckeever 	PREFIX_PUSH();
55876586c00SRebecca Mckeever 
5592c3dacbaSKarolina Drobnik 	reset_memblock_regions();
56083787a80SKarolina Drobnik 	memblock_reserve(r.base, r.size);
56183787a80SKarolina Drobnik 
56276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r.base);
56376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r.size);
56476586c00SRebecca Mckeever 
56576586c00SRebecca Mckeever 	test_pass_pop();
56683787a80SKarolina Drobnik 
56783787a80SKarolina Drobnik 	return 0;
56883787a80SKarolina Drobnik }
56983787a80SKarolina Drobnik 
57083787a80SKarolina Drobnik /*
571e4f76c8dSRebecca Mckeever  * A test that tries to mark two memory blocks that don't overlap as reserved:
572e4f76c8dSRebecca Mckeever  *
573e4f76c8dSRebecca Mckeever  *  |        +--+      +----------------+  |
574e4f76c8dSRebecca Mckeever  *  |        |r1|      |       r2       |  |
575e4f76c8dSRebecca Mckeever  *  +--------+--+------+----------------+--+
576e4f76c8dSRebecca Mckeever  *
577e4f76c8dSRebecca Mckeever  * Expect to add two entries to the collection of reserved memory regions
578e4f76c8dSRebecca Mckeever  * (memblock.reserved). The total size and region counter for
579e4f76c8dSRebecca Mckeever  * memblock.reserved are updated.
58083787a80SKarolina Drobnik  */
memblock_reserve_disjoint_check(void)58183787a80SKarolina Drobnik static int memblock_reserve_disjoint_check(void)
58283787a80SKarolina Drobnik {
58383787a80SKarolina Drobnik 	struct memblock_region *rgn1, *rgn2;
58483787a80SKarolina Drobnik 
58583787a80SKarolina Drobnik 	rgn1 = &memblock.reserved.regions[0];
58683787a80SKarolina Drobnik 	rgn2 = &memblock.reserved.regions[1];
58783787a80SKarolina Drobnik 
58883787a80SKarolina Drobnik 	struct region r1 = {
58983787a80SKarolina Drobnik 		.base = SZ_256M,
59083787a80SKarolina Drobnik 		.size = SZ_16M
59183787a80SKarolina Drobnik 	};
59283787a80SKarolina Drobnik 	struct region r2 = {
59383787a80SKarolina Drobnik 		.base = SZ_512M,
59483787a80SKarolina Drobnik 		.size = SZ_512M
59583787a80SKarolina Drobnik 	};
59683787a80SKarolina Drobnik 
59776586c00SRebecca Mckeever 	PREFIX_PUSH();
59876586c00SRebecca Mckeever 
5992c3dacbaSKarolina Drobnik 	reset_memblock_regions();
60083787a80SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
60183787a80SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
60283787a80SKarolina Drobnik 
60376586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
60476586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1.size);
60583787a80SKarolina Drobnik 
60676586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->base, r2.base);
60776586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->size, r2.size);
60883787a80SKarolina Drobnik 
60976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 2);
61076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, r1.size + r2.size);
61176586c00SRebecca Mckeever 
61276586c00SRebecca Mckeever 	test_pass_pop();
61383787a80SKarolina Drobnik 
61483787a80SKarolina Drobnik 	return 0;
61583787a80SKarolina Drobnik }
61683787a80SKarolina Drobnik 
61783787a80SKarolina Drobnik /*
618e4f76c8dSRebecca Mckeever  * A test that tries to mark two memory blocks r1 and r2 as reserved,
619e4f76c8dSRebecca Mckeever  * where r2 overlaps with the beginning of r1 (that is
620e4f76c8dSRebecca Mckeever  * r1.base < r2.base + r2.size):
621e4f76c8dSRebecca Mckeever  *
622e4f76c8dSRebecca Mckeever  *  |  +--------------+--+--------------+  |
623e4f76c8dSRebecca Mckeever  *  |  |       r2     |  |     r1       |  |
624e4f76c8dSRebecca Mckeever  *  +--+--------------+--+--------------+--+
625e4f76c8dSRebecca Mckeever  *     ^              ^
626e4f76c8dSRebecca Mckeever  *     |              |
627e4f76c8dSRebecca Mckeever  *     |              r1.base
628e4f76c8dSRebecca Mckeever  *     |
629e4f76c8dSRebecca Mckeever  *     r2.base
630e4f76c8dSRebecca Mckeever  *
631e4f76c8dSRebecca Mckeever  * Expect to merge two entries into one region that starts at r2.base and
632e4f76c8dSRebecca Mckeever  * has size of two regions minus their intersection. The total size of the
633e4f76c8dSRebecca Mckeever  * reserved memory is updated, and the region counter is not updated.
63483787a80SKarolina Drobnik  */
memblock_reserve_overlap_top_check(void)63583787a80SKarolina Drobnik static int memblock_reserve_overlap_top_check(void)
63683787a80SKarolina Drobnik {
63783787a80SKarolina Drobnik 	struct memblock_region *rgn;
63883787a80SKarolina Drobnik 	phys_addr_t total_size;
63983787a80SKarolina Drobnik 
64083787a80SKarolina Drobnik 	rgn = &memblock.reserved.regions[0];
64183787a80SKarolina Drobnik 
64283787a80SKarolina Drobnik 	struct region r1 = {
64383787a80SKarolina Drobnik 		.base = SZ_1G,
64483787a80SKarolina Drobnik 		.size = SZ_1G
64583787a80SKarolina Drobnik 	};
64683787a80SKarolina Drobnik 	struct region r2 = {
64783787a80SKarolina Drobnik 		.base = SZ_128M,
64883787a80SKarolina Drobnik 		.size = SZ_1G
64983787a80SKarolina Drobnik 	};
65083787a80SKarolina Drobnik 
65176586c00SRebecca Mckeever 	PREFIX_PUSH();
65276586c00SRebecca Mckeever 
65383787a80SKarolina Drobnik 	total_size = (r1.base - r2.base) + r1.size;
65483787a80SKarolina Drobnik 
6552c3dacbaSKarolina Drobnik 	reset_memblock_regions();
65683787a80SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
65783787a80SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
65883787a80SKarolina Drobnik 
65976586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r2.base);
66076586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
66183787a80SKarolina Drobnik 
66276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
66376586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
66476586c00SRebecca Mckeever 
66576586c00SRebecca Mckeever 	test_pass_pop();
66683787a80SKarolina Drobnik 
66783787a80SKarolina Drobnik 	return 0;
66883787a80SKarolina Drobnik }
66983787a80SKarolina Drobnik 
67083787a80SKarolina Drobnik /*
671e4f76c8dSRebecca Mckeever  * A test that tries to mark two memory blocks r1 and r2 as reserved,
672e4f76c8dSRebecca Mckeever  * where r2 overlaps with the end of r1 (that is
673e4f76c8dSRebecca Mckeever  * r2.base < r1.base + r1.size):
674e4f76c8dSRebecca Mckeever  *
675e4f76c8dSRebecca Mckeever  *  |  +--------------+--+--------------+  |
676e4f76c8dSRebecca Mckeever  *  |  |       r1     |  |     r2       |  |
677e4f76c8dSRebecca Mckeever  *  +--+--------------+--+--------------+--+
678e4f76c8dSRebecca Mckeever  *     ^              ^
679e4f76c8dSRebecca Mckeever  *     |              |
680e4f76c8dSRebecca Mckeever  *     |              r2.base
681e4f76c8dSRebecca Mckeever  *     |
682e4f76c8dSRebecca Mckeever  *     r1.base
683e4f76c8dSRebecca Mckeever  *
684e4f76c8dSRebecca Mckeever  * Expect to merge two entries into one region that starts at r1.base and
685e4f76c8dSRebecca Mckeever  * has size of two regions minus their intersection. The total size of the
686e4f76c8dSRebecca Mckeever  * reserved memory is updated, and the region counter is not updated.
68783787a80SKarolina Drobnik  */
memblock_reserve_overlap_bottom_check(void)68883787a80SKarolina Drobnik static int memblock_reserve_overlap_bottom_check(void)
68983787a80SKarolina Drobnik {
69083787a80SKarolina Drobnik 	struct memblock_region *rgn;
69183787a80SKarolina Drobnik 	phys_addr_t total_size;
69283787a80SKarolina Drobnik 
69383787a80SKarolina Drobnik 	rgn = &memblock.reserved.regions[0];
69483787a80SKarolina Drobnik 
69583787a80SKarolina Drobnik 	struct region r1 = {
69683787a80SKarolina Drobnik 		.base = SZ_2K,
69783787a80SKarolina Drobnik 		.size = SZ_128K
69883787a80SKarolina Drobnik 	};
69983787a80SKarolina Drobnik 	struct region r2 = {
70083787a80SKarolina Drobnik 		.base = SZ_128K,
70183787a80SKarolina Drobnik 		.size = SZ_128K
70283787a80SKarolina Drobnik 	};
70383787a80SKarolina Drobnik 
70476586c00SRebecca Mckeever 	PREFIX_PUSH();
70576586c00SRebecca Mckeever 
70683787a80SKarolina Drobnik 	total_size = (r2.base - r1.base) + r2.size;
70783787a80SKarolina Drobnik 
7082c3dacbaSKarolina Drobnik 	reset_memblock_regions();
70983787a80SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
71083787a80SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
71183787a80SKarolina Drobnik 
71276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
71376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
71483787a80SKarolina Drobnik 
71576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
71676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
71776586c00SRebecca Mckeever 
71876586c00SRebecca Mckeever 	test_pass_pop();
71983787a80SKarolina Drobnik 
72083787a80SKarolina Drobnik 	return 0;
72183787a80SKarolina Drobnik }
72283787a80SKarolina Drobnik 
72383787a80SKarolina Drobnik /*
724e4f76c8dSRebecca Mckeever  * A test that tries to mark two memory blocks r1 and r2 as reserved,
725e4f76c8dSRebecca Mckeever  * where r2 is within the range of r1 (that is
726e4f76c8dSRebecca Mckeever  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
727e4f76c8dSRebecca Mckeever  *
728e4f76c8dSRebecca Mckeever  *  | +-----+--+---------------------------|
729e4f76c8dSRebecca Mckeever  *  | |     |r2|          r1               |
730e4f76c8dSRebecca Mckeever  *  +-+-----+--+---------------------------+
731e4f76c8dSRebecca Mckeever  *    ^     ^
732e4f76c8dSRebecca Mckeever  *    |     |
733e4f76c8dSRebecca Mckeever  *    |     r2.base
734e4f76c8dSRebecca Mckeever  *    |
735e4f76c8dSRebecca Mckeever  *    r1.base
736e4f76c8dSRebecca Mckeever  *
737e4f76c8dSRebecca Mckeever  * Expect to merge two entries into one region that stays the same. The
738e4f76c8dSRebecca Mckeever  * counter and total size of available memory are not updated.
73983787a80SKarolina Drobnik  */
memblock_reserve_within_check(void)74083787a80SKarolina Drobnik static int memblock_reserve_within_check(void)
74183787a80SKarolina Drobnik {
74283787a80SKarolina Drobnik 	struct memblock_region *rgn;
74383787a80SKarolina Drobnik 
74483787a80SKarolina Drobnik 	rgn = &memblock.reserved.regions[0];
74583787a80SKarolina Drobnik 
74683787a80SKarolina Drobnik 	struct region r1 = {
74783787a80SKarolina Drobnik 		.base = SZ_1M,
74883787a80SKarolina Drobnik 		.size = SZ_8M
74983787a80SKarolina Drobnik 	};
75083787a80SKarolina Drobnik 	struct region r2 = {
75183787a80SKarolina Drobnik 		.base = SZ_2M,
75283787a80SKarolina Drobnik 		.size = SZ_64K
75383787a80SKarolina Drobnik 	};
75483787a80SKarolina Drobnik 
75576586c00SRebecca Mckeever 	PREFIX_PUSH();
75676586c00SRebecca Mckeever 
7572c3dacbaSKarolina Drobnik 	reset_memblock_regions();
75883787a80SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
75983787a80SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
76083787a80SKarolina Drobnik 
76176586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
76276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r1.size);
76383787a80SKarolina Drobnik 
76476586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
76576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, r1.size);
76676586c00SRebecca Mckeever 
76776586c00SRebecca Mckeever 	test_pass_pop();
76883787a80SKarolina Drobnik 
76983787a80SKarolina Drobnik 	return 0;
77083787a80SKarolina Drobnik }
77183787a80SKarolina Drobnik 
77283787a80SKarolina Drobnik /*
77383787a80SKarolina Drobnik  * A simple test that tries to reserve the same memory block twice.
774e4f76c8dSRebecca Mckeever  * Expect the region counter and total size of reserved memory to not
77583787a80SKarolina Drobnik  * be updated.
77683787a80SKarolina Drobnik  */
memblock_reserve_twice_check(void)77783787a80SKarolina Drobnik static int memblock_reserve_twice_check(void)
77883787a80SKarolina Drobnik {
77983787a80SKarolina Drobnik 	struct region r = {
78083787a80SKarolina Drobnik 		.base = SZ_16K,
78183787a80SKarolina Drobnik 		.size = SZ_2M
78283787a80SKarolina Drobnik 	};
78383787a80SKarolina Drobnik 
78476586c00SRebecca Mckeever 	PREFIX_PUSH();
78576586c00SRebecca Mckeever 
7862c3dacbaSKarolina Drobnik 	reset_memblock_regions();
78783787a80SKarolina Drobnik 
78883787a80SKarolina Drobnik 	memblock_reserve(r.base, r.size);
78983787a80SKarolina Drobnik 	memblock_reserve(r.base, r.size);
79083787a80SKarolina Drobnik 
79176586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
79276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, r.size);
79376586c00SRebecca Mckeever 
79476586c00SRebecca Mckeever 	test_pass_pop();
79583787a80SKarolina Drobnik 
79683787a80SKarolina Drobnik 	return 0;
79783787a80SKarolina Drobnik }
79883787a80SKarolina Drobnik 
79921a233f6SRebecca Mckeever /*
80021a233f6SRebecca Mckeever  * A test that tries to mark two memory blocks that don't overlap as reserved
80121a233f6SRebecca Mckeever  * and then reserve a third memory block in the space between the first two:
80221a233f6SRebecca Mckeever  *
80321a233f6SRebecca Mckeever  *  |        +--------+--------+--------+  |
80421a233f6SRebecca Mckeever  *  |        |   r1   |   r3   |   r2   |  |
80521a233f6SRebecca Mckeever  *  +--------+--------+--------+--------+--+
80621a233f6SRebecca Mckeever  *
80721a233f6SRebecca Mckeever  * Expect to merge the three entries into one reserved region that starts at
80821a233f6SRebecca Mckeever  * r1.base and has size of r1.size + r2.size + r3.size. The region counter and
80921a233f6SRebecca Mckeever  * total for memblock.reserved are updated.
81021a233f6SRebecca Mckeever  */
memblock_reserve_between_check(void)81121a233f6SRebecca Mckeever static int memblock_reserve_between_check(void)
81221a233f6SRebecca Mckeever {
81321a233f6SRebecca Mckeever 	struct memblock_region *rgn;
81421a233f6SRebecca Mckeever 	phys_addr_t total_size;
81521a233f6SRebecca Mckeever 
81621a233f6SRebecca Mckeever 	rgn = &memblock.reserved.regions[0];
81721a233f6SRebecca Mckeever 
81821a233f6SRebecca Mckeever 	struct region r1 = {
81921a233f6SRebecca Mckeever 		.base = SZ_1G,
82021a233f6SRebecca Mckeever 		.size = SZ_8K
82121a233f6SRebecca Mckeever 	};
82221a233f6SRebecca Mckeever 	struct region r2 = {
82321a233f6SRebecca Mckeever 		.base = SZ_1G + SZ_16K,
82421a233f6SRebecca Mckeever 		.size = SZ_8K
82521a233f6SRebecca Mckeever 	};
82621a233f6SRebecca Mckeever 	struct region r3 = {
82721a233f6SRebecca Mckeever 		.base = SZ_1G + SZ_8K,
82821a233f6SRebecca Mckeever 		.size = SZ_8K
82921a233f6SRebecca Mckeever 	};
83021a233f6SRebecca Mckeever 
83121a233f6SRebecca Mckeever 	PREFIX_PUSH();
83221a233f6SRebecca Mckeever 
83321a233f6SRebecca Mckeever 	total_size = r1.size + r2.size + r3.size;
83421a233f6SRebecca Mckeever 
83521a233f6SRebecca Mckeever 	reset_memblock_regions();
83621a233f6SRebecca Mckeever 	memblock_reserve(r1.base, r1.size);
83721a233f6SRebecca Mckeever 	memblock_reserve(r2.base, r2.size);
83821a233f6SRebecca Mckeever 	memblock_reserve(r3.base, r3.size);
83921a233f6SRebecca Mckeever 
84021a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
84121a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
84221a233f6SRebecca Mckeever 
84321a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
84421a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
84521a233f6SRebecca Mckeever 
84621a233f6SRebecca Mckeever 	test_pass_pop();
84721a233f6SRebecca Mckeever 
84821a233f6SRebecca Mckeever 	return 0;
84921a233f6SRebecca Mckeever }
85021a233f6SRebecca Mckeever 
85121a233f6SRebecca Mckeever /*
85221a233f6SRebecca Mckeever  * A simple test that tries to reserve a memory block r when r extends past
85321a233f6SRebecca Mckeever  * PHYS_ADDR_MAX:
85421a233f6SRebecca Mckeever  *
85521a233f6SRebecca Mckeever  *                               +--------+
85621a233f6SRebecca Mckeever  *                               |    r   |
85721a233f6SRebecca Mckeever  *                               +--------+
85821a233f6SRebecca Mckeever  *  |                            +----+
85921a233f6SRebecca Mckeever  *  |                            | rgn|
86021a233f6SRebecca Mckeever  *  +----------------------------+----+
86121a233f6SRebecca Mckeever  *
86221a233f6SRebecca Mckeever  * Expect to reserve a memory block of size PHYS_ADDR_MAX - r.base. Expect the
86321a233f6SRebecca Mckeever  * total size of reserved memory and the counter to be updated.
86421a233f6SRebecca Mckeever  */
memblock_reserve_near_max_check(void)86521a233f6SRebecca Mckeever static int memblock_reserve_near_max_check(void)
86621a233f6SRebecca Mckeever {
86721a233f6SRebecca Mckeever 	struct memblock_region *rgn;
86821a233f6SRebecca Mckeever 	phys_addr_t total_size;
86921a233f6SRebecca Mckeever 
87021a233f6SRebecca Mckeever 	rgn = &memblock.reserved.regions[0];
87121a233f6SRebecca Mckeever 
87221a233f6SRebecca Mckeever 	struct region r = {
87321a233f6SRebecca Mckeever 		.base = PHYS_ADDR_MAX - SZ_1M,
87421a233f6SRebecca Mckeever 		.size = SZ_2M
87521a233f6SRebecca Mckeever 	};
87621a233f6SRebecca Mckeever 
87721a233f6SRebecca Mckeever 	PREFIX_PUSH();
87821a233f6SRebecca Mckeever 
87921a233f6SRebecca Mckeever 	total_size = PHYS_ADDR_MAX - r.base;
88021a233f6SRebecca Mckeever 
88121a233f6SRebecca Mckeever 	reset_memblock_regions();
88221a233f6SRebecca Mckeever 	memblock_reserve(r.base, r.size);
88321a233f6SRebecca Mckeever 
88421a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, r.base);
88521a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
88621a233f6SRebecca Mckeever 
88721a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
88821a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
88921a233f6SRebecca Mckeever 
89021a233f6SRebecca Mckeever 	test_pass_pop();
89121a233f6SRebecca Mckeever 
89221a233f6SRebecca Mckeever 	return 0;
89321a233f6SRebecca Mckeever }
89421a233f6SRebecca Mckeever 
8955b27dd79SShaoqin Huang /*
8965b27dd79SShaoqin Huang  * A test that trying to reserve the 129th memory block.
8975b27dd79SShaoqin Huang  * Expect to trigger memblock_double_array() to double the
8985b27dd79SShaoqin Huang  * memblock.memory.max, find a new valid memory as
8995b27dd79SShaoqin Huang  * reserved.regions.
9005b27dd79SShaoqin Huang  */
memblock_reserve_many_check(void)9015b27dd79SShaoqin Huang static int memblock_reserve_many_check(void)
9025b27dd79SShaoqin Huang {
9035b27dd79SShaoqin Huang 	int i;
9045b27dd79SShaoqin Huang 	void *orig_region;
9055b27dd79SShaoqin Huang 	struct region r = {
9065b27dd79SShaoqin Huang 		.base = SZ_16K,
9075b27dd79SShaoqin Huang 		.size = SZ_16K,
9085b27dd79SShaoqin Huang 	};
9095b27dd79SShaoqin Huang 	phys_addr_t memory_base = SZ_128K;
9105b27dd79SShaoqin Huang 	phys_addr_t new_reserved_regions_size;
9115b27dd79SShaoqin Huang 
9125b27dd79SShaoqin Huang 	PREFIX_PUSH();
9135b27dd79SShaoqin Huang 
9145b27dd79SShaoqin Huang 	reset_memblock_regions();
9155b27dd79SShaoqin Huang 	memblock_allow_resize();
9165b27dd79SShaoqin Huang 
9175b27dd79SShaoqin Huang 	/* Add a valid memory region used by double_array(). */
9185b27dd79SShaoqin Huang 	dummy_physical_memory_init();
9195b27dd79SShaoqin Huang 	memblock_add(dummy_physical_memory_base(), MEM_SIZE);
9205b27dd79SShaoqin Huang 
9215b27dd79SShaoqin Huang 	for (i = 0; i < INIT_MEMBLOCK_REGIONS; i++) {
9225b27dd79SShaoqin Huang 		/* Reserve some fakes memory region to fulfill the memblock. */
9235b27dd79SShaoqin Huang 		memblock_reserve(memory_base, MEM_SIZE);
9245b27dd79SShaoqin Huang 
9255b27dd79SShaoqin Huang 		ASSERT_EQ(memblock.reserved.cnt, i + 1);
9265b27dd79SShaoqin Huang 		ASSERT_EQ(memblock.reserved.total_size, (i + 1) * MEM_SIZE);
9275b27dd79SShaoqin Huang 
9285b27dd79SShaoqin Huang 		/* Keep the gap so these memory region will not be merged. */
9295b27dd79SShaoqin Huang 		memory_base += MEM_SIZE * 2;
9305b27dd79SShaoqin Huang 	}
9315b27dd79SShaoqin Huang 
9325b27dd79SShaoqin Huang 	orig_region = memblock.reserved.regions;
9335b27dd79SShaoqin Huang 
9345b27dd79SShaoqin Huang 	/* This reserve the 129 memory_region, and makes it double array. */
9355b27dd79SShaoqin Huang 	memblock_reserve(memory_base, MEM_SIZE);
9365b27dd79SShaoqin Huang 
9375b27dd79SShaoqin Huang 	/*
9385b27dd79SShaoqin Huang 	 * This is the memory region size used by the doubled reserved.regions,
9395b27dd79SShaoqin Huang 	 * and it has been reserved due to it has been used. The size is used to
9405b27dd79SShaoqin Huang 	 * calculate the total_size that the memblock.reserved have now.
9415b27dd79SShaoqin Huang 	 */
9425b27dd79SShaoqin Huang 	new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) *
9435b27dd79SShaoqin Huang 					sizeof(struct memblock_region));
9445b27dd79SShaoqin Huang 	/*
9455b27dd79SShaoqin Huang 	 * The double_array() will find a free memory region as the new
9465b27dd79SShaoqin Huang 	 * reserved.regions, and the used memory region will be reserved, so
9475b27dd79SShaoqin Huang 	 * there will be one more region exist in the reserved memblock. And the
9485b27dd79SShaoqin Huang 	 * one more reserved region's size is new_reserved_regions_size.
9495b27dd79SShaoqin Huang 	 */
9505b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2);
9515b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
9525b27dd79SShaoqin Huang 						new_reserved_regions_size);
9535b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
9545b27dd79SShaoqin Huang 
9555b27dd79SShaoqin Huang 	/*
9565b27dd79SShaoqin Huang 	 * Now memblock_double_array() works fine. Let's check after the
9575b27dd79SShaoqin Huang 	 * double_array(), the memblock_reserve() still works as normal.
9585b27dd79SShaoqin Huang 	 */
9595b27dd79SShaoqin Huang 	memblock_reserve(r.base, r.size);
9605b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.regions[0].base, r.base);
9615b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.regions[0].size, r.size);
9625b27dd79SShaoqin Huang 
9635b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3);
9645b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
9655b27dd79SShaoqin Huang 						new_reserved_regions_size +
9665b27dd79SShaoqin Huang 						r.size);
9675b27dd79SShaoqin Huang 	ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
9685b27dd79SShaoqin Huang 
9695b27dd79SShaoqin Huang 	dummy_physical_memory_cleanup();
9705b27dd79SShaoqin Huang 
9715b27dd79SShaoqin Huang 	/*
9725b27dd79SShaoqin Huang 	 * The current reserved.regions is occupying a range of memory that
9735b27dd79SShaoqin Huang 	 * allocated from dummy_physical_memory_init(). After free the memory,
9745b27dd79SShaoqin Huang 	 * we must not use it. So restore the origin memory region to make sure
9755b27dd79SShaoqin Huang 	 * the tests can run as normal and not affected by the double array.
9765b27dd79SShaoqin Huang 	 */
9775b27dd79SShaoqin Huang 	memblock.reserved.regions = orig_region;
9785b27dd79SShaoqin Huang 	memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;
9795b27dd79SShaoqin Huang 
9805b27dd79SShaoqin Huang 	test_pass_pop();
9815b27dd79SShaoqin Huang 
9825b27dd79SShaoqin Huang 	return 0;
9835b27dd79SShaoqin Huang }
9845b27dd79SShaoqin Huang 
9853d316519SWei Yang 
9863d316519SWei Yang /*
9873d316519SWei Yang  * A test that trying to reserve the 129th memory block at all locations.
9883d316519SWei Yang  * Expect to trigger memblock_double_array() to double the
9893d316519SWei Yang  * memblock.memory.max, find a new valid memory as reserved.regions.
9903d316519SWei Yang  *
9913d316519SWei Yang  *  0               1               2                 128
9923d316519SWei Yang  *  +-------+       +-------+       +-------+         +-------+
9933d316519SWei Yang  *  |  32K  |       |  32K  |       |  32K  |   ...   |  32K  |
9943d316519SWei Yang  *  +-------+-------+-------+-------+-------+         +-------+
9953d316519SWei Yang  *          |<-32K->|       |<-32K->|
9963d316519SWei Yang  *
9973d316519SWei Yang  */
9983d316519SWei Yang /* Keep the gap so these memory region will not be merged. */
9993d316519SWei Yang #define MEMORY_BASE(idx) (SZ_128K + (MEM_SIZE * 2) * (idx))
memblock_reserve_all_locations_check(void)10003d316519SWei Yang static int memblock_reserve_all_locations_check(void)
10013d316519SWei Yang {
10023d316519SWei Yang 	int i, skip;
10033d316519SWei Yang 	void *orig_region;
10043d316519SWei Yang 	struct region r = {
10053d316519SWei Yang 		.base = SZ_16K,
10063d316519SWei Yang 		.size = SZ_16K,
10073d316519SWei Yang 	};
10083d316519SWei Yang 	phys_addr_t new_reserved_regions_size;
10093d316519SWei Yang 
10103d316519SWei Yang 	PREFIX_PUSH();
10113d316519SWei Yang 
10123d316519SWei Yang 	/* Reserve the 129th memory block for all possible positions*/
10133d316519SWei Yang 	for (skip = 0; skip < INIT_MEMBLOCK_REGIONS + 1; skip++) {
10143d316519SWei Yang 		reset_memblock_regions();
10153d316519SWei Yang 		memblock_allow_resize();
10163d316519SWei Yang 
10173d316519SWei Yang 		/* Add a valid memory region used by double_array(). */
10183d316519SWei Yang 		dummy_physical_memory_init();
10193d316519SWei Yang 		memblock_add(dummy_physical_memory_base(), MEM_SIZE);
10203d316519SWei Yang 
10213d316519SWei Yang 		for (i = 0; i < INIT_MEMBLOCK_REGIONS + 1; i++) {
10223d316519SWei Yang 			if (i == skip)
10233d316519SWei Yang 				continue;
10243d316519SWei Yang 
10253d316519SWei Yang 			/* Reserve some fakes memory region to fulfill the memblock. */
10263d316519SWei Yang 			memblock_reserve(MEMORY_BASE(i), MEM_SIZE);
10273d316519SWei Yang 
10283d316519SWei Yang 			if (i < skip) {
10293d316519SWei Yang 				ASSERT_EQ(memblock.reserved.cnt, i + 1);
10303d316519SWei Yang 				ASSERT_EQ(memblock.reserved.total_size, (i + 1) * MEM_SIZE);
10313d316519SWei Yang 			} else {
10323d316519SWei Yang 				ASSERT_EQ(memblock.reserved.cnt, i);
10333d316519SWei Yang 				ASSERT_EQ(memblock.reserved.total_size, i * MEM_SIZE);
10343d316519SWei Yang 			}
10353d316519SWei Yang 		}
10363d316519SWei Yang 
10373d316519SWei Yang 		orig_region = memblock.reserved.regions;
10383d316519SWei Yang 
10393d316519SWei Yang 		/* This reserve the 129 memory_region, and makes it double array. */
10403d316519SWei Yang 		memblock_reserve(MEMORY_BASE(skip), MEM_SIZE);
10413d316519SWei Yang 
10423d316519SWei Yang 		/*
10433d316519SWei Yang 		 * This is the memory region size used by the doubled reserved.regions,
10443d316519SWei Yang 		 * and it has been reserved due to it has been used. The size is used to
10453d316519SWei Yang 		 * calculate the total_size that the memblock.reserved have now.
10463d316519SWei Yang 		 */
10473d316519SWei Yang 		new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) *
10483d316519SWei Yang 						sizeof(struct memblock_region));
10493d316519SWei Yang 		/*
10503d316519SWei Yang 		 * The double_array() will find a free memory region as the new
10513d316519SWei Yang 		 * reserved.regions, and the used memory region will be reserved, so
10523d316519SWei Yang 		 * there will be one more region exist in the reserved memblock. And the
10533d316519SWei Yang 		 * one more reserved region's size is new_reserved_regions_size.
10543d316519SWei Yang 		 */
10553d316519SWei Yang 		ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2);
10563d316519SWei Yang 		ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
10573d316519SWei Yang 							new_reserved_regions_size);
10583d316519SWei Yang 		ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
10593d316519SWei Yang 
10603d316519SWei Yang 		/*
10613d316519SWei Yang 		 * Now memblock_double_array() works fine. Let's check after the
10623d316519SWei Yang 		 * double_array(), the memblock_reserve() still works as normal.
10633d316519SWei Yang 		 */
10643d316519SWei Yang 		memblock_reserve(r.base, r.size);
10653d316519SWei Yang 		ASSERT_EQ(memblock.reserved.regions[0].base, r.base);
10663d316519SWei Yang 		ASSERT_EQ(memblock.reserved.regions[0].size, r.size);
10673d316519SWei Yang 
10683d316519SWei Yang 		ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3);
10693d316519SWei Yang 		ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
10703d316519SWei Yang 							new_reserved_regions_size +
10713d316519SWei Yang 							r.size);
10723d316519SWei Yang 		ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
10733d316519SWei Yang 
10743d316519SWei Yang 		dummy_physical_memory_cleanup();
10753d316519SWei Yang 
10763d316519SWei Yang 		/*
10773d316519SWei Yang 		 * The current reserved.regions is occupying a range of memory that
10783d316519SWei Yang 		 * allocated from dummy_physical_memory_init(). After free the memory,
10793d316519SWei Yang 		 * we must not use it. So restore the origin memory region to make sure
10803d316519SWei Yang 		 * the tests can run as normal and not affected by the double array.
10813d316519SWei Yang 		 */
10823d316519SWei Yang 		memblock.reserved.regions = orig_region;
10833d316519SWei Yang 		memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;
10843d316519SWei Yang 	}
10853d316519SWei Yang 
10863d316519SWei Yang 	test_pass_pop();
10873d316519SWei Yang 
10883d316519SWei Yang 	return 0;
10893d316519SWei Yang }
10903d316519SWei Yang 
1091f6df89c3SWei Yang /*
1092f6df89c3SWei Yang  * A test that trying to reserve the 129th memory block at all locations.
1093f6df89c3SWei Yang  * Expect to trigger memblock_double_array() to double the
1094f6df89c3SWei Yang  * memblock.memory.max, find a new valid memory as reserved.regions. And make
1095f6df89c3SWei Yang  * sure it doesn't conflict with the range we want to reserve.
1096f6df89c3SWei Yang  *
1097f6df89c3SWei Yang  * For example, we have 128 regions in reserved and now want to reserve
1098f6df89c3SWei Yang  * the skipped one. Since reserved is full, memblock_double_array() would find
1099f6df89c3SWei Yang  * an available range in memory for the new array. We intended to put two
1100f6df89c3SWei Yang  * ranges in memory with one is the exact range of the skipped one. Before
1101f6df89c3SWei Yang  * commit 48c3b583bbdd ("mm/memblock: fix overlapping allocation when doubling
1102f6df89c3SWei Yang  * reserved array"), the new array would sits in the skipped range which is a
1103f6df89c3SWei Yang  * conflict. The expected new array should be allocated from memory.regions[0].
1104f6df89c3SWei Yang  *
1105f6df89c3SWei Yang  *           0                               1
1106f6df89c3SWei Yang  * memory    +-------+                       +-------+
1107f6df89c3SWei Yang  *           |  32K  |                       |  32K  |
1108f6df89c3SWei Yang  *           +-------+ ------+-------+-------+-------+
1109f6df89c3SWei Yang  *                   |<-32K->|<-32K->|<-32K->|
1110f6df89c3SWei Yang  *
1111f6df89c3SWei Yang  *                           0               skipped           127
1112f6df89c3SWei Yang  * reserved                  +-------+       .........         +-------+
1113f6df89c3SWei Yang  *                           |  32K  |       .  32K  .   ...   |  32K  |
1114f6df89c3SWei Yang  *                           +-------+-------+-------+         +-------+
1115f6df89c3SWei Yang  *                                   |<-32K->|
1116f6df89c3SWei Yang  *                                           ^
1117f6df89c3SWei Yang  *                                           |
1118f6df89c3SWei Yang  *                                           |
1119f6df89c3SWei Yang  *                                           skipped one
1120f6df89c3SWei Yang  */
1121f6df89c3SWei Yang /* Keep the gap so these memory region will not be merged. */
1122f6df89c3SWei Yang #define MEMORY_BASE_OFFSET(idx, offset) ((offset) + (MEM_SIZE * 2) * (idx))
memblock_reserve_many_may_conflict_check(void)1123f6df89c3SWei Yang static int memblock_reserve_many_may_conflict_check(void)
1124f6df89c3SWei Yang {
1125f6df89c3SWei Yang 	int i, skip;
1126f6df89c3SWei Yang 	void *orig_region;
1127f6df89c3SWei Yang 	struct region r = {
1128f6df89c3SWei Yang 		.base = SZ_16K,
1129f6df89c3SWei Yang 		.size = SZ_16K,
1130f6df89c3SWei Yang 	};
1131f6df89c3SWei Yang 	phys_addr_t new_reserved_regions_size;
1132f6df89c3SWei Yang 
1133f6df89c3SWei Yang 	/*
1134f6df89c3SWei Yang 	 *  0        1          129
1135f6df89c3SWei Yang 	 *  +---+    +---+      +---+
1136f6df89c3SWei Yang 	 *  |32K|    |32K|  ..  |32K|
1137f6df89c3SWei Yang 	 *  +---+    +---+      +---+
1138f6df89c3SWei Yang 	 *
1139f6df89c3SWei Yang 	 * Pre-allocate the range for 129 memory block + one range for double
1140f6df89c3SWei Yang 	 * memblock.reserved.regions at idx 0.
1141f6df89c3SWei Yang 	 */
1142f6df89c3SWei Yang 	dummy_physical_memory_init();
1143f6df89c3SWei Yang 	phys_addr_t memory_base = dummy_physical_memory_base();
1144f6df89c3SWei Yang 	phys_addr_t offset = PAGE_ALIGN(memory_base);
1145f6df89c3SWei Yang 
1146f6df89c3SWei Yang 	PREFIX_PUSH();
1147f6df89c3SWei Yang 
1148f6df89c3SWei Yang 	/* Reserve the 129th memory block for all possible positions*/
1149f6df89c3SWei Yang 	for (skip = 1; skip <= INIT_MEMBLOCK_REGIONS + 1; skip++) {
1150f6df89c3SWei Yang 		reset_memblock_regions();
1151f6df89c3SWei Yang 		memblock_allow_resize();
1152f6df89c3SWei Yang 
1153f6df89c3SWei Yang 		reset_memblock_attributes();
1154f6df89c3SWei Yang 		/* Add a valid memory region used by double_array(). */
1155f6df89c3SWei Yang 		memblock_add(MEMORY_BASE_OFFSET(0, offset), MEM_SIZE);
1156f6df89c3SWei Yang 		/*
1157f6df89c3SWei Yang 		 * Add a memory region which will be reserved as 129th memory
1158f6df89c3SWei Yang 		 * region. This is not expected to be used by double_array().
1159f6df89c3SWei Yang 		 */
1160f6df89c3SWei Yang 		memblock_add(MEMORY_BASE_OFFSET(skip, offset), MEM_SIZE);
1161f6df89c3SWei Yang 
1162f6df89c3SWei Yang 		for (i = 1; i <= INIT_MEMBLOCK_REGIONS + 1; i++) {
1163f6df89c3SWei Yang 			if (i == skip)
1164f6df89c3SWei Yang 				continue;
1165f6df89c3SWei Yang 
1166f6df89c3SWei Yang 			/* Reserve some fakes memory region to fulfill the memblock. */
1167f6df89c3SWei Yang 			memblock_reserve(MEMORY_BASE_OFFSET(i, offset), MEM_SIZE);
1168f6df89c3SWei Yang 
1169f6df89c3SWei Yang 			if (i < skip) {
1170f6df89c3SWei Yang 				ASSERT_EQ(memblock.reserved.cnt, i);
1171f6df89c3SWei Yang 				ASSERT_EQ(memblock.reserved.total_size, i * MEM_SIZE);
1172f6df89c3SWei Yang 			} else {
1173f6df89c3SWei Yang 				ASSERT_EQ(memblock.reserved.cnt, i - 1);
1174f6df89c3SWei Yang 				ASSERT_EQ(memblock.reserved.total_size, (i - 1) * MEM_SIZE);
1175f6df89c3SWei Yang 			}
1176f6df89c3SWei Yang 		}
1177f6df89c3SWei Yang 
1178f6df89c3SWei Yang 		orig_region = memblock.reserved.regions;
1179f6df89c3SWei Yang 
1180f6df89c3SWei Yang 		/* This reserve the 129 memory_region, and makes it double array. */
1181f6df89c3SWei Yang 		memblock_reserve(MEMORY_BASE_OFFSET(skip, offset), MEM_SIZE);
1182f6df89c3SWei Yang 
1183f6df89c3SWei Yang 		/*
1184f6df89c3SWei Yang 		 * This is the memory region size used by the doubled reserved.regions,
1185f6df89c3SWei Yang 		 * and it has been reserved due to it has been used. The size is used to
1186f6df89c3SWei Yang 		 * calculate the total_size that the memblock.reserved have now.
1187f6df89c3SWei Yang 		 */
1188f6df89c3SWei Yang 		new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) *
1189f6df89c3SWei Yang 						sizeof(struct memblock_region));
1190f6df89c3SWei Yang 		/*
1191f6df89c3SWei Yang 		 * The double_array() will find a free memory region as the new
1192f6df89c3SWei Yang 		 * reserved.regions, and the used memory region will be reserved, so
1193f6df89c3SWei Yang 		 * there will be one more region exist in the reserved memblock. And the
1194f6df89c3SWei Yang 		 * one more reserved region's size is new_reserved_regions_size.
1195f6df89c3SWei Yang 		 */
1196f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2);
1197f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
1198f6df89c3SWei Yang 							new_reserved_regions_size);
1199f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
1200f6df89c3SWei Yang 
1201f6df89c3SWei Yang 		/*
1202f6df89c3SWei Yang 		 * The first reserved region is allocated for double array
1203f6df89c3SWei Yang 		 * with the size of new_reserved_regions_size and the base to be
1204f6df89c3SWei Yang 		 * MEMORY_BASE_OFFSET(0, offset) + SZ_32K - new_reserved_regions_size
1205f6df89c3SWei Yang 		 */
1206f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.regions[0].base + memblock.reserved.regions[0].size,
1207f6df89c3SWei Yang 			  MEMORY_BASE_OFFSET(0, offset) + SZ_32K);
1208f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.regions[0].size, new_reserved_regions_size);
1209f6df89c3SWei Yang 
1210f6df89c3SWei Yang 		/*
1211f6df89c3SWei Yang 		 * Now memblock_double_array() works fine. Let's check after the
1212f6df89c3SWei Yang 		 * double_array(), the memblock_reserve() still works as normal.
1213f6df89c3SWei Yang 		 */
1214f6df89c3SWei Yang 		memblock_reserve(r.base, r.size);
1215f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.regions[0].base, r.base);
1216f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.regions[0].size, r.size);
1217f6df89c3SWei Yang 
1218f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3);
1219f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
1220f6df89c3SWei Yang 							new_reserved_regions_size +
1221f6df89c3SWei Yang 							r.size);
1222f6df89c3SWei Yang 		ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
1223f6df89c3SWei Yang 
1224f6df89c3SWei Yang 		/*
1225f6df89c3SWei Yang 		 * The current reserved.regions is occupying a range of memory that
1226f6df89c3SWei Yang 		 * allocated from dummy_physical_memory_init(). After free the memory,
1227f6df89c3SWei Yang 		 * we must not use it. So restore the origin memory region to make sure
1228f6df89c3SWei Yang 		 * the tests can run as normal and not affected by the double array.
1229f6df89c3SWei Yang 		 */
1230f6df89c3SWei Yang 		memblock.reserved.regions = orig_region;
1231f6df89c3SWei Yang 		memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;
1232f6df89c3SWei Yang 	}
1233f6df89c3SWei Yang 
1234f6df89c3SWei Yang 	dummy_physical_memory_cleanup();
1235f6df89c3SWei Yang 
1236f6df89c3SWei Yang 	test_pass_pop();
1237f6df89c3SWei Yang 
1238f6df89c3SWei Yang 	return 0;
1239f6df89c3SWei Yang }
1240f6df89c3SWei Yang 
memblock_reserve_checks(void)124183787a80SKarolina Drobnik static int memblock_reserve_checks(void)
124283787a80SKarolina Drobnik {
124376586c00SRebecca Mckeever 	prefix_reset();
124476586c00SRebecca Mckeever 	prefix_push(FUNC_RESERVE);
124576586c00SRebecca Mckeever 	test_print("Running %s tests...\n", FUNC_RESERVE);
124676586c00SRebecca Mckeever 
124783787a80SKarolina Drobnik 	memblock_reserve_simple_check();
124883787a80SKarolina Drobnik 	memblock_reserve_disjoint_check();
124983787a80SKarolina Drobnik 	memblock_reserve_overlap_top_check();
125083787a80SKarolina Drobnik 	memblock_reserve_overlap_bottom_check();
125183787a80SKarolina Drobnik 	memblock_reserve_within_check();
125283787a80SKarolina Drobnik 	memblock_reserve_twice_check();
125321a233f6SRebecca Mckeever 	memblock_reserve_between_check();
125421a233f6SRebecca Mckeever 	memblock_reserve_near_max_check();
12555b27dd79SShaoqin Huang 	memblock_reserve_many_check();
12563d316519SWei Yang 	memblock_reserve_all_locations_check();
1257f6df89c3SWei Yang 	memblock_reserve_many_may_conflict_check();
125883787a80SKarolina Drobnik 
125976586c00SRebecca Mckeever 	prefix_pop();
126076586c00SRebecca Mckeever 
126183787a80SKarolina Drobnik 	return 0;
126283787a80SKarolina Drobnik }
126383787a80SKarolina Drobnik 
1264b4d96893SKarolina Drobnik /*
126560bba7b1SRebecca Mckeever  * A simple test that tries to remove a region r1 from the array of
1266b4d96893SKarolina Drobnik  * available memory regions. By "removing" a region we mean overwriting it
126760bba7b1SRebecca Mckeever  * with the next region r2 in memblock.memory:
126860bba7b1SRebecca Mckeever  *
126960bba7b1SRebecca Mckeever  *  |  ......          +----------------+  |
127060bba7b1SRebecca Mckeever  *  |  : r1 :          |       r2       |  |
127160bba7b1SRebecca Mckeever  *  +--+----+----------+----------------+--+
127260bba7b1SRebecca Mckeever  *                     ^
127360bba7b1SRebecca Mckeever  *                     |
127460bba7b1SRebecca Mckeever  *                     rgn.base
127560bba7b1SRebecca Mckeever  *
127660bba7b1SRebecca Mckeever  * Expect to add two memory blocks r1 and r2 and then remove r1 so that
127760bba7b1SRebecca Mckeever  * r2 is the first available region. The region counter and total size
127860bba7b1SRebecca Mckeever  * are updated.
1279b4d96893SKarolina Drobnik  */
memblock_remove_simple_check(void)1280b4d96893SKarolina Drobnik static int memblock_remove_simple_check(void)
1281b4d96893SKarolina Drobnik {
1282b4d96893SKarolina Drobnik 	struct memblock_region *rgn;
1283b4d96893SKarolina Drobnik 
1284b4d96893SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
1285b4d96893SKarolina Drobnik 
1286b4d96893SKarolina Drobnik 	struct region r1 = {
1287b4d96893SKarolina Drobnik 		.base = SZ_2K,
1288b4d96893SKarolina Drobnik 		.size = SZ_4K
1289b4d96893SKarolina Drobnik 	};
1290b4d96893SKarolina Drobnik 	struct region r2 = {
1291b4d96893SKarolina Drobnik 		.base = SZ_128K,
1292b4d96893SKarolina Drobnik 		.size = SZ_4M
1293b4d96893SKarolina Drobnik 	};
1294b4d96893SKarolina Drobnik 
129576586c00SRebecca Mckeever 	PREFIX_PUSH();
129676586c00SRebecca Mckeever 
12972c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1298b4d96893SKarolina Drobnik 	memblock_add(r1.base, r1.size);
1299b4d96893SKarolina Drobnik 	memblock_add(r2.base, r2.size);
1300b4d96893SKarolina Drobnik 	memblock_remove(r1.base, r1.size);
1301b4d96893SKarolina Drobnik 
130276586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r2.base);
130376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r2.size);
1304b4d96893SKarolina Drobnik 
130576586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
130676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, r2.size);
130776586c00SRebecca Mckeever 
130876586c00SRebecca Mckeever 	test_pass_pop();
1309b4d96893SKarolina Drobnik 
1310b4d96893SKarolina Drobnik 	return 0;
1311b4d96893SKarolina Drobnik }
1312b4d96893SKarolina Drobnik 
1313b4d96893SKarolina Drobnik /*
131460bba7b1SRebecca Mckeever  * A test that tries to remove a region r2 that was not registered as
131560bba7b1SRebecca Mckeever  * available memory (i.e. has no corresponding entry in memblock.memory):
131660bba7b1SRebecca Mckeever  *
131760bba7b1SRebecca Mckeever  *                     +----------------+
131860bba7b1SRebecca Mckeever  *                     |       r2       |
131960bba7b1SRebecca Mckeever  *                     +----------------+
132060bba7b1SRebecca Mckeever  *  |  +----+                              |
132160bba7b1SRebecca Mckeever  *  |  | r1 |                              |
132260bba7b1SRebecca Mckeever  *  +--+----+------------------------------+
132360bba7b1SRebecca Mckeever  *     ^
132460bba7b1SRebecca Mckeever  *     |
132560bba7b1SRebecca Mckeever  *     rgn.base
132660bba7b1SRebecca Mckeever  *
132760bba7b1SRebecca Mckeever  * Expect the array, regions counter and total size to not be modified.
1328b4d96893SKarolina Drobnik  */
memblock_remove_absent_check(void)1329b4d96893SKarolina Drobnik static int memblock_remove_absent_check(void)
1330b4d96893SKarolina Drobnik {
1331b4d96893SKarolina Drobnik 	struct memblock_region *rgn;
1332b4d96893SKarolina Drobnik 
1333b4d96893SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
1334b4d96893SKarolina Drobnik 
1335b4d96893SKarolina Drobnik 	struct region r1 = {
1336b4d96893SKarolina Drobnik 		.base = SZ_512K,
1337b4d96893SKarolina Drobnik 		.size = SZ_4M
1338b4d96893SKarolina Drobnik 	};
1339b4d96893SKarolina Drobnik 	struct region r2 = {
1340b4d96893SKarolina Drobnik 		.base = SZ_64M,
1341b4d96893SKarolina Drobnik 		.size = SZ_1G
1342b4d96893SKarolina Drobnik 	};
1343b4d96893SKarolina Drobnik 
134476586c00SRebecca Mckeever 	PREFIX_PUSH();
134576586c00SRebecca Mckeever 
13462c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1347b4d96893SKarolina Drobnik 	memblock_add(r1.base, r1.size);
1348b4d96893SKarolina Drobnik 	memblock_remove(r2.base, r2.size);
1349b4d96893SKarolina Drobnik 
135076586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
135176586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r1.size);
1352b4d96893SKarolina Drobnik 
135376586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
135476586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, r1.size);
135576586c00SRebecca Mckeever 
135676586c00SRebecca Mckeever 	test_pass_pop();
1357b4d96893SKarolina Drobnik 
1358b4d96893SKarolina Drobnik 	return 0;
1359b4d96893SKarolina Drobnik }
1360b4d96893SKarolina Drobnik 
1361b4d96893SKarolina Drobnik /*
136260bba7b1SRebecca Mckeever  * A test that tries to remove a region r2 that overlaps with the
136360bba7b1SRebecca Mckeever  * beginning of the already existing entry r1
136460bba7b1SRebecca Mckeever  * (that is r1.base < r2.base + r2.size):
136560bba7b1SRebecca Mckeever  *
136660bba7b1SRebecca Mckeever  *           +-----------------+
136760bba7b1SRebecca Mckeever  *           |       r2        |
136860bba7b1SRebecca Mckeever  *           +-----------------+
136960bba7b1SRebecca Mckeever  *  |                 .........+--------+  |
137060bba7b1SRebecca Mckeever  *  |                 :     r1 |  rgn   |  |
137160bba7b1SRebecca Mckeever  *  +-----------------+--------+--------+--+
137260bba7b1SRebecca Mckeever  *                    ^        ^
137360bba7b1SRebecca Mckeever  *                    |        |
137460bba7b1SRebecca Mckeever  *                    |        rgn.base
137560bba7b1SRebecca Mckeever  *                    r1.base
137660bba7b1SRebecca Mckeever  *
137760bba7b1SRebecca Mckeever  * Expect that only the intersection of both regions is removed from the
137860bba7b1SRebecca Mckeever  * available memory pool. The regions counter and total size are updated.
1379b4d96893SKarolina Drobnik  */
memblock_remove_overlap_top_check(void)1380b4d96893SKarolina Drobnik static int memblock_remove_overlap_top_check(void)
1381b4d96893SKarolina Drobnik {
1382b4d96893SKarolina Drobnik 	struct memblock_region *rgn;
1383b4d96893SKarolina Drobnik 	phys_addr_t r1_end, r2_end, total_size;
1384b4d96893SKarolina Drobnik 
1385b4d96893SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
1386b4d96893SKarolina Drobnik 
1387b4d96893SKarolina Drobnik 	struct region r1 = {
1388b4d96893SKarolina Drobnik 		.base = SZ_32M,
1389b4d96893SKarolina Drobnik 		.size = SZ_32M
1390b4d96893SKarolina Drobnik 	};
1391b4d96893SKarolina Drobnik 	struct region r2 = {
1392b4d96893SKarolina Drobnik 		.base = SZ_16M,
1393b4d96893SKarolina Drobnik 		.size = SZ_32M
1394b4d96893SKarolina Drobnik 	};
1395b4d96893SKarolina Drobnik 
139676586c00SRebecca Mckeever 	PREFIX_PUSH();
139776586c00SRebecca Mckeever 
1398b4d96893SKarolina Drobnik 	r1_end = r1.base + r1.size;
1399b4d96893SKarolina Drobnik 	r2_end = r2.base + r2.size;
1400b4d96893SKarolina Drobnik 	total_size = r1_end - r2_end;
1401b4d96893SKarolina Drobnik 
14022c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1403b4d96893SKarolina Drobnik 	memblock_add(r1.base, r1.size);
1404b4d96893SKarolina Drobnik 	memblock_remove(r2.base, r2.size);
1405b4d96893SKarolina Drobnik 
140676586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base + r2.base);
140776586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
1408b4d96893SKarolina Drobnik 
140976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
141076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
141176586c00SRebecca Mckeever 
141276586c00SRebecca Mckeever 	test_pass_pop();
1413b4d96893SKarolina Drobnik 
1414b4d96893SKarolina Drobnik 	return 0;
1415b4d96893SKarolina Drobnik }
1416b4d96893SKarolina Drobnik 
1417b4d96893SKarolina Drobnik /*
141860bba7b1SRebecca Mckeever  * A test that tries to remove a region r2 that overlaps with the end of
141960bba7b1SRebecca Mckeever  * the already existing region r1 (that is r2.base < r1.base + r1.size):
142060bba7b1SRebecca Mckeever  *
142160bba7b1SRebecca Mckeever  *        +--------------------------------+
142260bba7b1SRebecca Mckeever  *        |               r2               |
142360bba7b1SRebecca Mckeever  *        +--------------------------------+
142460bba7b1SRebecca Mckeever  *  | +---+.....                           |
142560bba7b1SRebecca Mckeever  *  | |rgn| r1 :                           |
142660bba7b1SRebecca Mckeever  *  +-+---+----+---------------------------+
142760bba7b1SRebecca Mckeever  *    ^
142860bba7b1SRebecca Mckeever  *    |
142960bba7b1SRebecca Mckeever  *    r1.base
143060bba7b1SRebecca Mckeever  *
143160bba7b1SRebecca Mckeever  * Expect that only the intersection of both regions is removed from the
143260bba7b1SRebecca Mckeever  * available memory pool. The regions counter and total size are updated.
1433b4d96893SKarolina Drobnik  */
memblock_remove_overlap_bottom_check(void)1434b4d96893SKarolina Drobnik static int memblock_remove_overlap_bottom_check(void)
1435b4d96893SKarolina Drobnik {
1436b4d96893SKarolina Drobnik 	struct memblock_region *rgn;
1437b4d96893SKarolina Drobnik 	phys_addr_t total_size;
1438b4d96893SKarolina Drobnik 
1439b4d96893SKarolina Drobnik 	rgn = &memblock.memory.regions[0];
1440b4d96893SKarolina Drobnik 
1441b4d96893SKarolina Drobnik 	struct region r1 = {
1442b4d96893SKarolina Drobnik 		.base = SZ_2M,
1443b4d96893SKarolina Drobnik 		.size = SZ_64M
1444b4d96893SKarolina Drobnik 	};
1445b4d96893SKarolina Drobnik 	struct region r2 = {
1446b4d96893SKarolina Drobnik 		.base = SZ_32M,
1447b4d96893SKarolina Drobnik 		.size = SZ_256M
1448b4d96893SKarolina Drobnik 	};
1449b4d96893SKarolina Drobnik 
145076586c00SRebecca Mckeever 	PREFIX_PUSH();
145176586c00SRebecca Mckeever 
1452b4d96893SKarolina Drobnik 	total_size = r2.base - r1.base;
1453b4d96893SKarolina Drobnik 
14542c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1455b4d96893SKarolina Drobnik 	memblock_add(r1.base, r1.size);
1456b4d96893SKarolina Drobnik 	memblock_remove(r2.base, r2.size);
1457b4d96893SKarolina Drobnik 
145876586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
145976586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
1460b4d96893SKarolina Drobnik 
146176586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
146276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
146376586c00SRebecca Mckeever 
146476586c00SRebecca Mckeever 	test_pass_pop();
146576586c00SRebecca Mckeever 
1466b4d96893SKarolina Drobnik 	return 0;
1467b4d96893SKarolina Drobnik }
1468b4d96893SKarolina Drobnik 
1469b4d96893SKarolina Drobnik /*
147060bba7b1SRebecca Mckeever  * A test that tries to remove a region r2 that is within the range of
147160bba7b1SRebecca Mckeever  * the already existing entry r1 (that is
147260bba7b1SRebecca Mckeever  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
147360bba7b1SRebecca Mckeever  *
147460bba7b1SRebecca Mckeever  *                  +----+
147560bba7b1SRebecca Mckeever  *                  | r2 |
147660bba7b1SRebecca Mckeever  *                  +----+
147760bba7b1SRebecca Mckeever  *  | +-------------+....+---------------+ |
147860bba7b1SRebecca Mckeever  *  | |     rgn1    | r1 |     rgn2      | |
147960bba7b1SRebecca Mckeever  *  +-+-------------+----+---------------+-+
148060bba7b1SRebecca Mckeever  *    ^
148160bba7b1SRebecca Mckeever  *    |
148260bba7b1SRebecca Mckeever  *    r1.base
148360bba7b1SRebecca Mckeever  *
148460bba7b1SRebecca Mckeever  * Expect that the region is split into two - one that ends at r2.base and
148560bba7b1SRebecca Mckeever  * another that starts at r2.base + r2.size, with appropriate sizes. The
148660bba7b1SRebecca Mckeever  * region counter and total size are updated.
1487b4d96893SKarolina Drobnik  */
memblock_remove_within_check(void)1488b4d96893SKarolina Drobnik static int memblock_remove_within_check(void)
1489b4d96893SKarolina Drobnik {
1490b4d96893SKarolina Drobnik 	struct memblock_region *rgn1, *rgn2;
1491b4d96893SKarolina Drobnik 	phys_addr_t r1_size, r2_size, total_size;
1492b4d96893SKarolina Drobnik 
1493b4d96893SKarolina Drobnik 	rgn1 = &memblock.memory.regions[0];
1494b4d96893SKarolina Drobnik 	rgn2 = &memblock.memory.regions[1];
1495b4d96893SKarolina Drobnik 
1496b4d96893SKarolina Drobnik 	struct region r1 = {
1497b4d96893SKarolina Drobnik 		.base = SZ_1M,
1498b4d96893SKarolina Drobnik 		.size = SZ_32M
1499b4d96893SKarolina Drobnik 	};
1500b4d96893SKarolina Drobnik 	struct region r2 = {
1501b4d96893SKarolina Drobnik 		.base = SZ_16M,
1502b4d96893SKarolina Drobnik 		.size = SZ_1M
1503b4d96893SKarolina Drobnik 	};
1504b4d96893SKarolina Drobnik 
150576586c00SRebecca Mckeever 	PREFIX_PUSH();
150676586c00SRebecca Mckeever 
1507b4d96893SKarolina Drobnik 	r1_size = r2.base - r1.base;
1508b4d96893SKarolina Drobnik 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
1509b4d96893SKarolina Drobnik 	total_size = r1_size + r2_size;
1510b4d96893SKarolina Drobnik 
15112c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1512b4d96893SKarolina Drobnik 	memblock_add(r1.base, r1.size);
1513b4d96893SKarolina Drobnik 	memblock_remove(r2.base, r2.size);
1514b4d96893SKarolina Drobnik 
151576586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
151676586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1_size);
1517b4d96893SKarolina Drobnik 
151876586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->base, r2.base + r2.size);
151976586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->size, r2_size);
1520b4d96893SKarolina Drobnik 
152176586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 2);
152276586c00SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
152376586c00SRebecca Mckeever 
152476586c00SRebecca Mckeever 	test_pass_pop();
1525b4d96893SKarolina Drobnik 
1526b4d96893SKarolina Drobnik 	return 0;
1527b4d96893SKarolina Drobnik }
1528b4d96893SKarolina Drobnik 
152921a233f6SRebecca Mckeever /*
153021a233f6SRebecca Mckeever  * A simple test that tries to remove a region r1 from the array of
153121a233f6SRebecca Mckeever  * available memory regions when r1 is the only available region.
153221a233f6SRebecca Mckeever  * Expect to add a memory block r1 and then remove r1 so that a dummy
153321a233f6SRebecca Mckeever  * region is added. The region counter stays the same, and the total size
153421a233f6SRebecca Mckeever  * is updated.
153521a233f6SRebecca Mckeever  */
memblock_remove_only_region_check(void)153621a233f6SRebecca Mckeever static int memblock_remove_only_region_check(void)
153721a233f6SRebecca Mckeever {
153821a233f6SRebecca Mckeever 	struct memblock_region *rgn;
153921a233f6SRebecca Mckeever 
154021a233f6SRebecca Mckeever 	rgn = &memblock.memory.regions[0];
154121a233f6SRebecca Mckeever 
154221a233f6SRebecca Mckeever 	struct region r1 = {
154321a233f6SRebecca Mckeever 		.base = SZ_2K,
154421a233f6SRebecca Mckeever 		.size = SZ_4K
154521a233f6SRebecca Mckeever 	};
154621a233f6SRebecca Mckeever 
154721a233f6SRebecca Mckeever 	PREFIX_PUSH();
154821a233f6SRebecca Mckeever 
154921a233f6SRebecca Mckeever 	reset_memblock_regions();
155021a233f6SRebecca Mckeever 	memblock_add(r1.base, r1.size);
155121a233f6SRebecca Mckeever 	memblock_remove(r1.base, r1.size);
155221a233f6SRebecca Mckeever 
155321a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, 0);
155421a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, 0);
155521a233f6SRebecca Mckeever 
1556721f4a65SWei Yang 	ASSERT_EQ(memblock.memory.cnt, 0);
155721a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, 0);
155821a233f6SRebecca Mckeever 
155921a233f6SRebecca Mckeever 	test_pass_pop();
156021a233f6SRebecca Mckeever 
156121a233f6SRebecca Mckeever 	return 0;
156221a233f6SRebecca Mckeever }
156321a233f6SRebecca Mckeever 
156421a233f6SRebecca Mckeever /*
156521a233f6SRebecca Mckeever  * A simple test that tries remove a region r2 from the array of available
156621a233f6SRebecca Mckeever  * memory regions when r2 extends past PHYS_ADDR_MAX:
156721a233f6SRebecca Mckeever  *
156821a233f6SRebecca Mckeever  *                               +--------+
156921a233f6SRebecca Mckeever  *                               |   r2   |
157021a233f6SRebecca Mckeever  *                               +--------+
157121a233f6SRebecca Mckeever  *  |                        +---+....+
157221a233f6SRebecca Mckeever  *  |                        |rgn|    |
157321a233f6SRebecca Mckeever  *  +------------------------+---+----+
157421a233f6SRebecca Mckeever  *
157521a233f6SRebecca Mckeever  * Expect that only the portion between PHYS_ADDR_MAX and r2.base is removed.
157621a233f6SRebecca Mckeever  * Expect the total size of available memory to be updated and the counter to
157721a233f6SRebecca Mckeever  * not be updated.
157821a233f6SRebecca Mckeever  */
memblock_remove_near_max_check(void)157921a233f6SRebecca Mckeever static int memblock_remove_near_max_check(void)
158021a233f6SRebecca Mckeever {
158121a233f6SRebecca Mckeever 	struct memblock_region *rgn;
158221a233f6SRebecca Mckeever 	phys_addr_t total_size;
158321a233f6SRebecca Mckeever 
158421a233f6SRebecca Mckeever 	rgn = &memblock.memory.regions[0];
158521a233f6SRebecca Mckeever 
158621a233f6SRebecca Mckeever 	struct region r1 = {
158721a233f6SRebecca Mckeever 		.base = PHYS_ADDR_MAX - SZ_2M,
158821a233f6SRebecca Mckeever 		.size = SZ_2M
158921a233f6SRebecca Mckeever 	};
159021a233f6SRebecca Mckeever 
159121a233f6SRebecca Mckeever 	struct region r2 = {
159221a233f6SRebecca Mckeever 		.base = PHYS_ADDR_MAX - SZ_1M,
159321a233f6SRebecca Mckeever 		.size = SZ_2M
159421a233f6SRebecca Mckeever 	};
159521a233f6SRebecca Mckeever 
159621a233f6SRebecca Mckeever 	PREFIX_PUSH();
159721a233f6SRebecca Mckeever 
159821a233f6SRebecca Mckeever 	total_size = r1.size - (PHYS_ADDR_MAX - r2.base);
159921a233f6SRebecca Mckeever 
160021a233f6SRebecca Mckeever 	reset_memblock_regions();
160121a233f6SRebecca Mckeever 	memblock_add(r1.base, r1.size);
160221a233f6SRebecca Mckeever 	memblock_remove(r2.base, r2.size);
160321a233f6SRebecca Mckeever 
160421a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
160521a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
160621a233f6SRebecca Mckeever 
160721a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
160821a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
160921a233f6SRebecca Mckeever 
161021a233f6SRebecca Mckeever 	test_pass_pop();
161121a233f6SRebecca Mckeever 
161221a233f6SRebecca Mckeever 	return 0;
161321a233f6SRebecca Mckeever }
161421a233f6SRebecca Mckeever 
161521a233f6SRebecca Mckeever /*
161621a233f6SRebecca Mckeever  * A test that tries to remove a region r3 that overlaps with two existing
161721a233f6SRebecca Mckeever  * regions r1 and r2:
161821a233f6SRebecca Mckeever  *
161921a233f6SRebecca Mckeever  *            +----------------+
162021a233f6SRebecca Mckeever  *            |       r3       |
162121a233f6SRebecca Mckeever  *            +----------------+
162221a233f6SRebecca Mckeever  *  |    +----+.....   ........+--------+
162321a233f6SRebecca Mckeever  *  |    |    |r1  :   :       |r2      |     |
162421a233f6SRebecca Mckeever  *  +----+----+----+---+-------+--------+-----+
162521a233f6SRebecca Mckeever  *
162621a233f6SRebecca Mckeever  * Expect that only the intersections of r1 with r3 and r2 with r3 are removed
162721a233f6SRebecca Mckeever  * from the available memory pool. Expect the total size of available memory to
162821a233f6SRebecca Mckeever  * be updated and the counter to not be updated.
162921a233f6SRebecca Mckeever  */
memblock_remove_overlap_two_check(void)163021a233f6SRebecca Mckeever static int memblock_remove_overlap_two_check(void)
163121a233f6SRebecca Mckeever {
163221a233f6SRebecca Mckeever 	struct memblock_region *rgn1, *rgn2;
163321a233f6SRebecca Mckeever 	phys_addr_t new_r1_size, new_r2_size, r2_end, r3_end, total_size;
163421a233f6SRebecca Mckeever 
163521a233f6SRebecca Mckeever 	rgn1 = &memblock.memory.regions[0];
163621a233f6SRebecca Mckeever 	rgn2 = &memblock.memory.regions[1];
163721a233f6SRebecca Mckeever 
163821a233f6SRebecca Mckeever 	struct region r1 = {
163921a233f6SRebecca Mckeever 		.base = SZ_16M,
164021a233f6SRebecca Mckeever 		.size = SZ_32M
164121a233f6SRebecca Mckeever 	};
164221a233f6SRebecca Mckeever 	struct region r2 = {
164321a233f6SRebecca Mckeever 		.base = SZ_64M,
164421a233f6SRebecca Mckeever 		.size = SZ_64M
164521a233f6SRebecca Mckeever 	};
164621a233f6SRebecca Mckeever 	struct region r3 = {
164721a233f6SRebecca Mckeever 		.base = SZ_32M,
164821a233f6SRebecca Mckeever 		.size = SZ_64M
164921a233f6SRebecca Mckeever 	};
165021a233f6SRebecca Mckeever 
165121a233f6SRebecca Mckeever 	PREFIX_PUSH();
165221a233f6SRebecca Mckeever 
165321a233f6SRebecca Mckeever 	r2_end = r2.base + r2.size;
165421a233f6SRebecca Mckeever 	r3_end = r3.base + r3.size;
165521a233f6SRebecca Mckeever 	new_r1_size = r3.base - r1.base;
165621a233f6SRebecca Mckeever 	new_r2_size = r2_end - r3_end;
165721a233f6SRebecca Mckeever 	total_size = new_r1_size + new_r2_size;
165821a233f6SRebecca Mckeever 
165921a233f6SRebecca Mckeever 	reset_memblock_regions();
166021a233f6SRebecca Mckeever 	memblock_add(r1.base, r1.size);
166121a233f6SRebecca Mckeever 	memblock_add(r2.base, r2.size);
166221a233f6SRebecca Mckeever 	memblock_remove(r3.base, r3.size);
166321a233f6SRebecca Mckeever 
166421a233f6SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
166521a233f6SRebecca Mckeever 	ASSERT_EQ(rgn1->size, new_r1_size);
166621a233f6SRebecca Mckeever 
166721a233f6SRebecca Mckeever 	ASSERT_EQ(rgn2->base, r3_end);
166821a233f6SRebecca Mckeever 	ASSERT_EQ(rgn2->size, new_r2_size);
166921a233f6SRebecca Mckeever 
167021a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 2);
167121a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.memory.total_size, total_size);
167221a233f6SRebecca Mckeever 
167321a233f6SRebecca Mckeever 	test_pass_pop();
167421a233f6SRebecca Mckeever 
167521a233f6SRebecca Mckeever 	return 0;
167621a233f6SRebecca Mckeever }
167721a233f6SRebecca Mckeever 
memblock_remove_checks(void)1678b4d96893SKarolina Drobnik static int memblock_remove_checks(void)
1679b4d96893SKarolina Drobnik {
168076586c00SRebecca Mckeever 	prefix_reset();
168176586c00SRebecca Mckeever 	prefix_push(FUNC_REMOVE);
168276586c00SRebecca Mckeever 	test_print("Running %s tests...\n", FUNC_REMOVE);
168376586c00SRebecca Mckeever 
1684b4d96893SKarolina Drobnik 	memblock_remove_simple_check();
1685b4d96893SKarolina Drobnik 	memblock_remove_absent_check();
1686b4d96893SKarolina Drobnik 	memblock_remove_overlap_top_check();
1687b4d96893SKarolina Drobnik 	memblock_remove_overlap_bottom_check();
1688b4d96893SKarolina Drobnik 	memblock_remove_within_check();
168921a233f6SRebecca Mckeever 	memblock_remove_only_region_check();
169021a233f6SRebecca Mckeever 	memblock_remove_near_max_check();
169121a233f6SRebecca Mckeever 	memblock_remove_overlap_two_check();
1692b4d96893SKarolina Drobnik 
169376586c00SRebecca Mckeever 	prefix_pop();
169476586c00SRebecca Mckeever 
1695b4d96893SKarolina Drobnik 	return 0;
1696b4d96893SKarolina Drobnik }
1697b4d96893SKarolina Drobnik 
1698dd45dc07SKarolina Drobnik /*
1699a5550c05SRebecca Mckeever  * A simple test that tries to free a memory block r1 that was marked
1700a5550c05SRebecca Mckeever  * earlier as reserved. By "freeing" a region we mean overwriting it with
1701a5550c05SRebecca Mckeever  * the next entry r2 in memblock.reserved:
1702a5550c05SRebecca Mckeever  *
1703a5550c05SRebecca Mckeever  *  |              ......           +----+ |
1704a5550c05SRebecca Mckeever  *  |              : r1 :           | r2 | |
1705a5550c05SRebecca Mckeever  *  +--------------+----+-----------+----+-+
1706a5550c05SRebecca Mckeever  *                                  ^
1707a5550c05SRebecca Mckeever  *                                  |
1708a5550c05SRebecca Mckeever  *                                  rgn.base
1709a5550c05SRebecca Mckeever  *
1710a5550c05SRebecca Mckeever  * Expect to reserve two memory regions and then erase r1 region with the
1711a5550c05SRebecca Mckeever  * value of r2. The region counter and total size are updated.
1712dd45dc07SKarolina Drobnik  */
memblock_free_simple_check(void)1713dd45dc07SKarolina Drobnik static int memblock_free_simple_check(void)
1714dd45dc07SKarolina Drobnik {
1715dd45dc07SKarolina Drobnik 	struct memblock_region *rgn;
1716dd45dc07SKarolina Drobnik 
1717dd45dc07SKarolina Drobnik 	rgn = &memblock.reserved.regions[0];
1718dd45dc07SKarolina Drobnik 
1719dd45dc07SKarolina Drobnik 	struct region r1 = {
1720dd45dc07SKarolina Drobnik 		.base = SZ_4M,
1721dd45dc07SKarolina Drobnik 		.size = SZ_1M
1722dd45dc07SKarolina Drobnik 	};
1723dd45dc07SKarolina Drobnik 	struct region r2 = {
1724dd45dc07SKarolina Drobnik 		.base = SZ_8M,
1725dd45dc07SKarolina Drobnik 		.size = SZ_1M
1726dd45dc07SKarolina Drobnik 	};
1727dd45dc07SKarolina Drobnik 
172876586c00SRebecca Mckeever 	PREFIX_PUSH();
172976586c00SRebecca Mckeever 
17302c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1731dd45dc07SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
1732dd45dc07SKarolina Drobnik 	memblock_reserve(r2.base, r2.size);
1733dd45dc07SKarolina Drobnik 	memblock_free((void *)r1.base, r1.size);
1734dd45dc07SKarolina Drobnik 
173576586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r2.base);
173676586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r2.size);
1737dd45dc07SKarolina Drobnik 
173876586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
173976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, r2.size);
174076586c00SRebecca Mckeever 
174176586c00SRebecca Mckeever 	test_pass_pop();
1742dd45dc07SKarolina Drobnik 
1743dd45dc07SKarolina Drobnik 	return 0;
1744dd45dc07SKarolina Drobnik }
1745dd45dc07SKarolina Drobnik 
1746dd45dc07SKarolina Drobnik /*
1747a5550c05SRebecca Mckeever  * A test that tries to free a region r2 that was not marked as reserved
1748a5550c05SRebecca Mckeever  * (i.e. has no corresponding entry in memblock.reserved):
1749a5550c05SRebecca Mckeever  *
1750a5550c05SRebecca Mckeever  *                     +----------------+
1751a5550c05SRebecca Mckeever  *                     |       r2       |
1752a5550c05SRebecca Mckeever  *                     +----------------+
1753a5550c05SRebecca Mckeever  *  |  +----+                              |
1754a5550c05SRebecca Mckeever  *  |  | r1 |                              |
1755a5550c05SRebecca Mckeever  *  +--+----+------------------------------+
1756a5550c05SRebecca Mckeever  *     ^
1757a5550c05SRebecca Mckeever  *     |
1758a5550c05SRebecca Mckeever  *     rgn.base
1759a5550c05SRebecca Mckeever  *
1760a5550c05SRebecca Mckeever  * The array, regions counter and total size are not modified.
1761dd45dc07SKarolina Drobnik  */
memblock_free_absent_check(void)1762dd45dc07SKarolina Drobnik static int memblock_free_absent_check(void)
1763dd45dc07SKarolina Drobnik {
1764dd45dc07SKarolina Drobnik 	struct memblock_region *rgn;
1765dd45dc07SKarolina Drobnik 
1766dd45dc07SKarolina Drobnik 	rgn = &memblock.reserved.regions[0];
1767dd45dc07SKarolina Drobnik 
1768dd45dc07SKarolina Drobnik 	struct region r1 = {
1769dd45dc07SKarolina Drobnik 		.base = SZ_2M,
1770dd45dc07SKarolina Drobnik 		.size = SZ_8K
1771dd45dc07SKarolina Drobnik 	};
1772dd45dc07SKarolina Drobnik 	struct region r2 = {
1773dd45dc07SKarolina Drobnik 		.base = SZ_16M,
1774dd45dc07SKarolina Drobnik 		.size = SZ_128M
1775dd45dc07SKarolina Drobnik 	};
1776dd45dc07SKarolina Drobnik 
177776586c00SRebecca Mckeever 	PREFIX_PUSH();
177876586c00SRebecca Mckeever 
17792c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1780dd45dc07SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
1781dd45dc07SKarolina Drobnik 	memblock_free((void *)r2.base, r2.size);
1782dd45dc07SKarolina Drobnik 
178376586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
178476586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, r1.size);
1785dd45dc07SKarolina Drobnik 
178676586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
178776586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, r1.size);
178876586c00SRebecca Mckeever 
178976586c00SRebecca Mckeever 	test_pass_pop();
1790dd45dc07SKarolina Drobnik 
1791dd45dc07SKarolina Drobnik 	return 0;
1792dd45dc07SKarolina Drobnik }
1793dd45dc07SKarolina Drobnik 
1794dd45dc07SKarolina Drobnik /*
1795a5550c05SRebecca Mckeever  * A test that tries to free a region r2 that overlaps with the beginning
1796a5550c05SRebecca Mckeever  * of the already existing entry r1 (that is r1.base < r2.base + r2.size):
1797a5550c05SRebecca Mckeever  *
1798a5550c05SRebecca Mckeever  *     +----+
1799a5550c05SRebecca Mckeever  *     | r2 |
1800a5550c05SRebecca Mckeever  *     +----+
1801a5550c05SRebecca Mckeever  *  |    ...+--------------+               |
1802a5550c05SRebecca Mckeever  *  |    :  |    r1        |               |
1803a5550c05SRebecca Mckeever  *  +----+--+--------------+---------------+
1804a5550c05SRebecca Mckeever  *       ^  ^
1805a5550c05SRebecca Mckeever  *       |  |
1806a5550c05SRebecca Mckeever  *       |  rgn.base
1807a5550c05SRebecca Mckeever  *       |
1808a5550c05SRebecca Mckeever  *       r1.base
1809a5550c05SRebecca Mckeever  *
1810a5550c05SRebecca Mckeever  * Expect that only the intersection of both regions is freed. The
1811a5550c05SRebecca Mckeever  * regions counter and total size are updated.
1812dd45dc07SKarolina Drobnik  */
memblock_free_overlap_top_check(void)1813dd45dc07SKarolina Drobnik static int memblock_free_overlap_top_check(void)
1814dd45dc07SKarolina Drobnik {
1815dd45dc07SKarolina Drobnik 	struct memblock_region *rgn;
1816dd45dc07SKarolina Drobnik 	phys_addr_t total_size;
1817dd45dc07SKarolina Drobnik 
1818dd45dc07SKarolina Drobnik 	rgn = &memblock.reserved.regions[0];
1819dd45dc07SKarolina Drobnik 
1820dd45dc07SKarolina Drobnik 	struct region r1 = {
1821dd45dc07SKarolina Drobnik 		.base = SZ_8M,
1822dd45dc07SKarolina Drobnik 		.size = SZ_32M
1823dd45dc07SKarolina Drobnik 	};
1824dd45dc07SKarolina Drobnik 	struct region r2 = {
1825dd45dc07SKarolina Drobnik 		.base = SZ_1M,
1826dd45dc07SKarolina Drobnik 		.size = SZ_8M
1827dd45dc07SKarolina Drobnik 	};
1828dd45dc07SKarolina Drobnik 
182976586c00SRebecca Mckeever 	PREFIX_PUSH();
183076586c00SRebecca Mckeever 
1831dd45dc07SKarolina Drobnik 	total_size = (r1.size + r1.base) - (r2.base + r2.size);
1832dd45dc07SKarolina Drobnik 
18332c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1834dd45dc07SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
1835dd45dc07SKarolina Drobnik 	memblock_free((void *)r2.base, r2.size);
1836dd45dc07SKarolina Drobnik 
183776586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r2.base + r2.size);
183876586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
1839dd45dc07SKarolina Drobnik 
184076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
184176586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
184276586c00SRebecca Mckeever 
184376586c00SRebecca Mckeever 	test_pass_pop();
1844dd45dc07SKarolina Drobnik 
1845dd45dc07SKarolina Drobnik 	return 0;
1846dd45dc07SKarolina Drobnik }
1847dd45dc07SKarolina Drobnik 
1848dd45dc07SKarolina Drobnik /*
1849a5550c05SRebecca Mckeever  * A test that tries to free a region r2 that overlaps with the end of
1850a5550c05SRebecca Mckeever  * the already existing entry r1 (that is r2.base < r1.base + r1.size):
1851a5550c05SRebecca Mckeever  *
1852a5550c05SRebecca Mckeever  *                   +----------------+
1853a5550c05SRebecca Mckeever  *                   |       r2       |
1854a5550c05SRebecca Mckeever  *                   +----------------+
1855a5550c05SRebecca Mckeever  *  |    +-----------+.....                |
1856a5550c05SRebecca Mckeever  *  |    |       r1  |    :                |
1857a5550c05SRebecca Mckeever  *  +----+-----------+----+----------------+
1858a5550c05SRebecca Mckeever  *
1859a5550c05SRebecca Mckeever  * Expect that only the intersection of both regions is freed. The
1860a5550c05SRebecca Mckeever  * regions counter and total size are updated.
1861dd45dc07SKarolina Drobnik  */
memblock_free_overlap_bottom_check(void)1862dd45dc07SKarolina Drobnik static int memblock_free_overlap_bottom_check(void)
1863dd45dc07SKarolina Drobnik {
1864dd45dc07SKarolina Drobnik 	struct memblock_region *rgn;
1865dd45dc07SKarolina Drobnik 	phys_addr_t total_size;
1866dd45dc07SKarolina Drobnik 
1867dd45dc07SKarolina Drobnik 	rgn = &memblock.reserved.regions[0];
1868dd45dc07SKarolina Drobnik 
1869dd45dc07SKarolina Drobnik 	struct region r1 = {
1870dd45dc07SKarolina Drobnik 		.base = SZ_8M,
1871dd45dc07SKarolina Drobnik 		.size = SZ_32M
1872dd45dc07SKarolina Drobnik 	};
1873dd45dc07SKarolina Drobnik 	struct region r2 = {
1874dd45dc07SKarolina Drobnik 		.base = SZ_32M,
1875dd45dc07SKarolina Drobnik 		.size = SZ_32M
1876dd45dc07SKarolina Drobnik 	};
1877dd45dc07SKarolina Drobnik 
187876586c00SRebecca Mckeever 	PREFIX_PUSH();
187976586c00SRebecca Mckeever 
1880dd45dc07SKarolina Drobnik 	total_size = r2.base - r1.base;
1881dd45dc07SKarolina Drobnik 
18822c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1883dd45dc07SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
1884dd45dc07SKarolina Drobnik 	memblock_free((void *)r2.base, r2.size);
1885dd45dc07SKarolina Drobnik 
188676586c00SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
188776586c00SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
1888dd45dc07SKarolina Drobnik 
188976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
189076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
189176586c00SRebecca Mckeever 
189276586c00SRebecca Mckeever 	test_pass_pop();
1893dd45dc07SKarolina Drobnik 
1894dd45dc07SKarolina Drobnik 	return 0;
1895dd45dc07SKarolina Drobnik }
1896dd45dc07SKarolina Drobnik 
1897dd45dc07SKarolina Drobnik /*
1898a5550c05SRebecca Mckeever  * A test that tries to free a region r2 that is within the range of the
1899a5550c05SRebecca Mckeever  * already existing entry r1 (that is
1900a5550c05SRebecca Mckeever  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
1901a5550c05SRebecca Mckeever  *
1902a5550c05SRebecca Mckeever  *                    +----+
1903a5550c05SRebecca Mckeever  *                    | r2 |
1904a5550c05SRebecca Mckeever  *                    +----+
1905a5550c05SRebecca Mckeever  *  |    +------------+....+---------------+
1906a5550c05SRebecca Mckeever  *  |    |    rgn1    | r1 |     rgn2      |
1907a5550c05SRebecca Mckeever  *  +----+------------+----+---------------+
1908a5550c05SRebecca Mckeever  *       ^
1909a5550c05SRebecca Mckeever  *       |
1910a5550c05SRebecca Mckeever  *       r1.base
1911a5550c05SRebecca Mckeever  *
1912a5550c05SRebecca Mckeever  * Expect that the region is split into two - one that ends at r2.base and
1913a5550c05SRebecca Mckeever  * another that starts at r2.base + r2.size, with appropriate sizes. The
1914a5550c05SRebecca Mckeever  * region counter and total size fields are updated.
1915dd45dc07SKarolina Drobnik  */
memblock_free_within_check(void)1916dd45dc07SKarolina Drobnik static int memblock_free_within_check(void)
1917dd45dc07SKarolina Drobnik {
1918dd45dc07SKarolina Drobnik 	struct memblock_region *rgn1, *rgn2;
1919dd45dc07SKarolina Drobnik 	phys_addr_t r1_size, r2_size, total_size;
1920dd45dc07SKarolina Drobnik 
1921dd45dc07SKarolina Drobnik 	rgn1 = &memblock.reserved.regions[0];
1922dd45dc07SKarolina Drobnik 	rgn2 = &memblock.reserved.regions[1];
1923dd45dc07SKarolina Drobnik 
1924dd45dc07SKarolina Drobnik 	struct region r1 = {
1925dd45dc07SKarolina Drobnik 		.base = SZ_1M,
1926dd45dc07SKarolina Drobnik 		.size = SZ_8M
1927dd45dc07SKarolina Drobnik 	};
1928dd45dc07SKarolina Drobnik 	struct region r2 = {
1929dd45dc07SKarolina Drobnik 		.base = SZ_4M,
1930dd45dc07SKarolina Drobnik 		.size = SZ_1M
1931dd45dc07SKarolina Drobnik 	};
1932dd45dc07SKarolina Drobnik 
193376586c00SRebecca Mckeever 	PREFIX_PUSH();
193476586c00SRebecca Mckeever 
1935dd45dc07SKarolina Drobnik 	r1_size = r2.base - r1.base;
1936dd45dc07SKarolina Drobnik 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
1937dd45dc07SKarolina Drobnik 	total_size = r1_size + r2_size;
1938dd45dc07SKarolina Drobnik 
19392c3dacbaSKarolina Drobnik 	reset_memblock_regions();
1940dd45dc07SKarolina Drobnik 	memblock_reserve(r1.base, r1.size);
1941dd45dc07SKarolina Drobnik 	memblock_free((void *)r2.base, r2.size);
1942dd45dc07SKarolina Drobnik 
194376586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
194476586c00SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1_size);
1945dd45dc07SKarolina Drobnik 
194676586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->base, r2.base + r2.size);
194776586c00SRebecca Mckeever 	ASSERT_EQ(rgn2->size, r2_size);
1948dd45dc07SKarolina Drobnik 
194976586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 2);
195076586c00SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
195176586c00SRebecca Mckeever 
195276586c00SRebecca Mckeever 	test_pass_pop();
1953dd45dc07SKarolina Drobnik 
1954dd45dc07SKarolina Drobnik 	return 0;
1955dd45dc07SKarolina Drobnik }
1956dd45dc07SKarolina Drobnik 
195721a233f6SRebecca Mckeever /*
195821a233f6SRebecca Mckeever  * A simple test that tries to free a memory block r1 that was marked
195921a233f6SRebecca Mckeever  * earlier as reserved when r1 is the only available region.
196021a233f6SRebecca Mckeever  * Expect to reserve a memory block r1 and then free r1 so that r1 is
196121a233f6SRebecca Mckeever  * overwritten with a dummy region. The region counter stays the same,
196221a233f6SRebecca Mckeever  * and the total size is updated.
196321a233f6SRebecca Mckeever  */
memblock_free_only_region_check(void)196421a233f6SRebecca Mckeever static int memblock_free_only_region_check(void)
196521a233f6SRebecca Mckeever {
196621a233f6SRebecca Mckeever 	struct memblock_region *rgn;
196721a233f6SRebecca Mckeever 
196821a233f6SRebecca Mckeever 	rgn = &memblock.reserved.regions[0];
196921a233f6SRebecca Mckeever 
197021a233f6SRebecca Mckeever 	struct region r1 = {
197121a233f6SRebecca Mckeever 		.base = SZ_2K,
197221a233f6SRebecca Mckeever 		.size = SZ_4K
197321a233f6SRebecca Mckeever 	};
197421a233f6SRebecca Mckeever 
197521a233f6SRebecca Mckeever 	PREFIX_PUSH();
197621a233f6SRebecca Mckeever 
197721a233f6SRebecca Mckeever 	reset_memblock_regions();
197821a233f6SRebecca Mckeever 	memblock_reserve(r1.base, r1.size);
197921a233f6SRebecca Mckeever 	memblock_free((void *)r1.base, r1.size);
198021a233f6SRebecca Mckeever 
198121a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, 0);
198221a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, 0);
198321a233f6SRebecca Mckeever 
1984721f4a65SWei Yang 	ASSERT_EQ(memblock.reserved.cnt, 0);
198521a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, 0);
198621a233f6SRebecca Mckeever 
198721a233f6SRebecca Mckeever 	test_pass_pop();
198821a233f6SRebecca Mckeever 
198921a233f6SRebecca Mckeever 	return 0;
199021a233f6SRebecca Mckeever }
199121a233f6SRebecca Mckeever 
199221a233f6SRebecca Mckeever /*
199321a233f6SRebecca Mckeever  * A simple test that tries free a region r2 when r2 extends past PHYS_ADDR_MAX:
199421a233f6SRebecca Mckeever  *
199521a233f6SRebecca Mckeever  *                               +--------+
199621a233f6SRebecca Mckeever  *                               |   r2   |
199721a233f6SRebecca Mckeever  *                               +--------+
199821a233f6SRebecca Mckeever  *  |                        +---+....+
199921a233f6SRebecca Mckeever  *  |                        |rgn|    |
200021a233f6SRebecca Mckeever  *  +------------------------+---+----+
200121a233f6SRebecca Mckeever  *
200221a233f6SRebecca Mckeever  * Expect that only the portion between PHYS_ADDR_MAX and r2.base is freed.
200321a233f6SRebecca Mckeever  * Expect the total size of reserved memory to be updated and the counter to
200421a233f6SRebecca Mckeever  * not be updated.
200521a233f6SRebecca Mckeever  */
memblock_free_near_max_check(void)200621a233f6SRebecca Mckeever static int memblock_free_near_max_check(void)
200721a233f6SRebecca Mckeever {
200821a233f6SRebecca Mckeever 	struct memblock_region *rgn;
200921a233f6SRebecca Mckeever 	phys_addr_t total_size;
201021a233f6SRebecca Mckeever 
201121a233f6SRebecca Mckeever 	rgn = &memblock.reserved.regions[0];
201221a233f6SRebecca Mckeever 
201321a233f6SRebecca Mckeever 	struct region r1 = {
201421a233f6SRebecca Mckeever 		.base = PHYS_ADDR_MAX - SZ_2M,
201521a233f6SRebecca Mckeever 		.size = SZ_2M
201621a233f6SRebecca Mckeever 	};
201721a233f6SRebecca Mckeever 
201821a233f6SRebecca Mckeever 	struct region r2 = {
201921a233f6SRebecca Mckeever 		.base = PHYS_ADDR_MAX - SZ_1M,
202021a233f6SRebecca Mckeever 		.size = SZ_2M
202121a233f6SRebecca Mckeever 	};
202221a233f6SRebecca Mckeever 
202321a233f6SRebecca Mckeever 	PREFIX_PUSH();
202421a233f6SRebecca Mckeever 
202521a233f6SRebecca Mckeever 	total_size = r1.size - (PHYS_ADDR_MAX - r2.base);
202621a233f6SRebecca Mckeever 
202721a233f6SRebecca Mckeever 	reset_memblock_regions();
202821a233f6SRebecca Mckeever 	memblock_reserve(r1.base, r1.size);
202921a233f6SRebecca Mckeever 	memblock_free((void *)r2.base, r2.size);
203021a233f6SRebecca Mckeever 
203121a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
203221a233f6SRebecca Mckeever 	ASSERT_EQ(rgn->size, total_size);
203321a233f6SRebecca Mckeever 
203421a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 1);
203521a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
203621a233f6SRebecca Mckeever 
203721a233f6SRebecca Mckeever 	test_pass_pop();
203821a233f6SRebecca Mckeever 
203921a233f6SRebecca Mckeever 	return 0;
204021a233f6SRebecca Mckeever }
204121a233f6SRebecca Mckeever 
204221a233f6SRebecca Mckeever /*
204321a233f6SRebecca Mckeever  * A test that tries to free a reserved region r3 that overlaps with two
204421a233f6SRebecca Mckeever  * existing reserved regions r1 and r2:
204521a233f6SRebecca Mckeever  *
204621a233f6SRebecca Mckeever  *            +----------------+
204721a233f6SRebecca Mckeever  *            |       r3       |
204821a233f6SRebecca Mckeever  *            +----------------+
204921a233f6SRebecca Mckeever  *  |    +----+.....   ........+--------+
205021a233f6SRebecca Mckeever  *  |    |    |r1  :   :       |r2      |     |
205121a233f6SRebecca Mckeever  *  +----+----+----+---+-------+--------+-----+
205221a233f6SRebecca Mckeever  *
205321a233f6SRebecca Mckeever  * Expect that only the intersections of r1 with r3 and r2 with r3 are freed
205421a233f6SRebecca Mckeever  * from the collection of reserved memory. Expect the total size of reserved
205521a233f6SRebecca Mckeever  * memory to be updated and the counter to not be updated.
205621a233f6SRebecca Mckeever  */
memblock_free_overlap_two_check(void)205721a233f6SRebecca Mckeever static int memblock_free_overlap_two_check(void)
205821a233f6SRebecca Mckeever {
205921a233f6SRebecca Mckeever 	struct memblock_region *rgn1, *rgn2;
206021a233f6SRebecca Mckeever 	phys_addr_t new_r1_size, new_r2_size, r2_end, r3_end, total_size;
206121a233f6SRebecca Mckeever 
206221a233f6SRebecca Mckeever 	rgn1 = &memblock.reserved.regions[0];
206321a233f6SRebecca Mckeever 	rgn2 = &memblock.reserved.regions[1];
206421a233f6SRebecca Mckeever 
206521a233f6SRebecca Mckeever 	struct region r1 = {
206621a233f6SRebecca Mckeever 		.base = SZ_16M,
206721a233f6SRebecca Mckeever 		.size = SZ_32M
206821a233f6SRebecca Mckeever 	};
206921a233f6SRebecca Mckeever 	struct region r2 = {
207021a233f6SRebecca Mckeever 		.base = SZ_64M,
207121a233f6SRebecca Mckeever 		.size = SZ_64M
207221a233f6SRebecca Mckeever 	};
207321a233f6SRebecca Mckeever 	struct region r3 = {
207421a233f6SRebecca Mckeever 		.base = SZ_32M,
207521a233f6SRebecca Mckeever 		.size = SZ_64M
207621a233f6SRebecca Mckeever 	};
207721a233f6SRebecca Mckeever 
207821a233f6SRebecca Mckeever 	PREFIX_PUSH();
207921a233f6SRebecca Mckeever 
208021a233f6SRebecca Mckeever 	r2_end = r2.base + r2.size;
208121a233f6SRebecca Mckeever 	r3_end = r3.base + r3.size;
208221a233f6SRebecca Mckeever 	new_r1_size = r3.base - r1.base;
208321a233f6SRebecca Mckeever 	new_r2_size = r2_end - r3_end;
208421a233f6SRebecca Mckeever 	total_size = new_r1_size + new_r2_size;
208521a233f6SRebecca Mckeever 
208621a233f6SRebecca Mckeever 	reset_memblock_regions();
208721a233f6SRebecca Mckeever 	memblock_reserve(r1.base, r1.size);
208821a233f6SRebecca Mckeever 	memblock_reserve(r2.base, r2.size);
208921a233f6SRebecca Mckeever 	memblock_free((void *)r3.base, r3.size);
209021a233f6SRebecca Mckeever 
209121a233f6SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
209221a233f6SRebecca Mckeever 	ASSERT_EQ(rgn1->size, new_r1_size);
209321a233f6SRebecca Mckeever 
209421a233f6SRebecca Mckeever 	ASSERT_EQ(rgn2->base, r3_end);
209521a233f6SRebecca Mckeever 	ASSERT_EQ(rgn2->size, new_r2_size);
209621a233f6SRebecca Mckeever 
209721a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.cnt, 2);
209821a233f6SRebecca Mckeever 	ASSERT_EQ(memblock.reserved.total_size, total_size);
209921a233f6SRebecca Mckeever 
210021a233f6SRebecca Mckeever 	test_pass_pop();
210121a233f6SRebecca Mckeever 
210221a233f6SRebecca Mckeever 	return 0;
210321a233f6SRebecca Mckeever }
210421a233f6SRebecca Mckeever 
memblock_free_checks(void)2105dd45dc07SKarolina Drobnik static int memblock_free_checks(void)
2106dd45dc07SKarolina Drobnik {
210776586c00SRebecca Mckeever 	prefix_reset();
210876586c00SRebecca Mckeever 	prefix_push(FUNC_FREE);
210976586c00SRebecca Mckeever 	test_print("Running %s tests...\n", FUNC_FREE);
211076586c00SRebecca Mckeever 
2111dd45dc07SKarolina Drobnik 	memblock_free_simple_check();
2112dd45dc07SKarolina Drobnik 	memblock_free_absent_check();
2113dd45dc07SKarolina Drobnik 	memblock_free_overlap_top_check();
2114dd45dc07SKarolina Drobnik 	memblock_free_overlap_bottom_check();
2115dd45dc07SKarolina Drobnik 	memblock_free_within_check();
211621a233f6SRebecca Mckeever 	memblock_free_only_region_check();
211721a233f6SRebecca Mckeever 	memblock_free_near_max_check();
211821a233f6SRebecca Mckeever 	memblock_free_overlap_two_check();
2119dd45dc07SKarolina Drobnik 
212076586c00SRebecca Mckeever 	prefix_pop();
212176586c00SRebecca Mckeever 
2122dd45dc07SKarolina Drobnik 	return 0;
2123dd45dc07SKarolina Drobnik }
2124dd45dc07SKarolina Drobnik 
memblock_set_bottom_up_check(void)2125a541c6d4SRebecca Mckeever static int memblock_set_bottom_up_check(void)
2126a541c6d4SRebecca Mckeever {
2127a541c6d4SRebecca Mckeever 	prefix_push("memblock_set_bottom_up");
2128a541c6d4SRebecca Mckeever 
2129a541c6d4SRebecca Mckeever 	memblock_set_bottom_up(false);
2130a541c6d4SRebecca Mckeever 	ASSERT_EQ(memblock.bottom_up, false);
2131a541c6d4SRebecca Mckeever 	memblock_set_bottom_up(true);
2132a541c6d4SRebecca Mckeever 	ASSERT_EQ(memblock.bottom_up, true);
2133a541c6d4SRebecca Mckeever 
2134a541c6d4SRebecca Mckeever 	reset_memblock_attributes();
2135a541c6d4SRebecca Mckeever 	test_pass_pop();
2136a541c6d4SRebecca Mckeever 
2137a541c6d4SRebecca Mckeever 	return 0;
2138a541c6d4SRebecca Mckeever }
2139a541c6d4SRebecca Mckeever 
memblock_bottom_up_check(void)2140a541c6d4SRebecca Mckeever static int memblock_bottom_up_check(void)
2141a541c6d4SRebecca Mckeever {
2142a541c6d4SRebecca Mckeever 	prefix_push("memblock_bottom_up");
2143a541c6d4SRebecca Mckeever 
2144a541c6d4SRebecca Mckeever 	memblock_set_bottom_up(false);
2145a541c6d4SRebecca Mckeever 	ASSERT_EQ(memblock_bottom_up(), memblock.bottom_up);
2146a541c6d4SRebecca Mckeever 	ASSERT_EQ(memblock_bottom_up(), false);
2147a541c6d4SRebecca Mckeever 	memblock_set_bottom_up(true);
2148a541c6d4SRebecca Mckeever 	ASSERT_EQ(memblock_bottom_up(), memblock.bottom_up);
2149a541c6d4SRebecca Mckeever 	ASSERT_EQ(memblock_bottom_up(), true);
2150a541c6d4SRebecca Mckeever 
2151a541c6d4SRebecca Mckeever 	reset_memblock_attributes();
2152a541c6d4SRebecca Mckeever 	test_pass_pop();
2153a541c6d4SRebecca Mckeever 
2154a541c6d4SRebecca Mckeever 	return 0;
2155a541c6d4SRebecca Mckeever }
2156a541c6d4SRebecca Mckeever 
memblock_bottom_up_checks(void)2157a541c6d4SRebecca Mckeever static int memblock_bottom_up_checks(void)
2158a541c6d4SRebecca Mckeever {
2159a541c6d4SRebecca Mckeever 	test_print("Running memblock_*bottom_up tests...\n");
2160a541c6d4SRebecca Mckeever 
2161a541c6d4SRebecca Mckeever 	prefix_reset();
2162a541c6d4SRebecca Mckeever 	memblock_set_bottom_up_check();
2163a541c6d4SRebecca Mckeever 	prefix_reset();
2164a541c6d4SRebecca Mckeever 	memblock_bottom_up_check();
2165a541c6d4SRebecca Mckeever 
2166a541c6d4SRebecca Mckeever 	return 0;
2167a541c6d4SRebecca Mckeever }
2168a541c6d4SRebecca Mckeever 
2169dcd45ad2SRebecca Mckeever /*
2170dcd45ad2SRebecca Mckeever  * A test that tries to trim memory when both ends of the memory region are
2171dcd45ad2SRebecca Mckeever  * aligned. Expect that the memory will not be trimmed. Expect the counter to
2172dcd45ad2SRebecca Mckeever  * not be updated.
2173dcd45ad2SRebecca Mckeever  */
memblock_trim_memory_aligned_check(void)2174dcd45ad2SRebecca Mckeever static int memblock_trim_memory_aligned_check(void)
2175dcd45ad2SRebecca Mckeever {
2176dcd45ad2SRebecca Mckeever 	struct memblock_region *rgn;
2177dcd45ad2SRebecca Mckeever 	const phys_addr_t alignment = SMP_CACHE_BYTES;
2178dcd45ad2SRebecca Mckeever 
2179dcd45ad2SRebecca Mckeever 	rgn = &memblock.memory.regions[0];
2180dcd45ad2SRebecca Mckeever 
2181dcd45ad2SRebecca Mckeever 	struct region r = {
2182dcd45ad2SRebecca Mckeever 		.base = alignment,
2183dcd45ad2SRebecca Mckeever 		.size = alignment * 4
2184dcd45ad2SRebecca Mckeever 	};
2185dcd45ad2SRebecca Mckeever 
2186dcd45ad2SRebecca Mckeever 	PREFIX_PUSH();
2187dcd45ad2SRebecca Mckeever 
2188dcd45ad2SRebecca Mckeever 	reset_memblock_regions();
2189dcd45ad2SRebecca Mckeever 	memblock_add(r.base, r.size);
2190dcd45ad2SRebecca Mckeever 	memblock_trim_memory(alignment);
2191dcd45ad2SRebecca Mckeever 
2192dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn->base, r.base);
2193dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn->size, r.size);
2194dcd45ad2SRebecca Mckeever 
2195dcd45ad2SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
2196dcd45ad2SRebecca Mckeever 
2197dcd45ad2SRebecca Mckeever 	test_pass_pop();
2198dcd45ad2SRebecca Mckeever 
2199dcd45ad2SRebecca Mckeever 	return 0;
2200dcd45ad2SRebecca Mckeever }
2201dcd45ad2SRebecca Mckeever 
2202dcd45ad2SRebecca Mckeever /*
2203dcd45ad2SRebecca Mckeever  * A test that tries to trim memory when there are two available regions, r1 and
2204dcd45ad2SRebecca Mckeever  * r2. Region r1 is aligned on both ends and region r2 is unaligned on one end
2205dcd45ad2SRebecca Mckeever  * and smaller than the alignment:
2206dcd45ad2SRebecca Mckeever  *
2207dcd45ad2SRebecca Mckeever  *                                     alignment
2208dcd45ad2SRebecca Mckeever  *                                     |--------|
2209dcd45ad2SRebecca Mckeever  * |        +-----------------+        +------+   |
2210dcd45ad2SRebecca Mckeever  * |        |        r1       |        |  r2  |   |
2211dcd45ad2SRebecca Mckeever  * +--------+-----------------+--------+------+---+
2212dcd45ad2SRebecca Mckeever  *          ^        ^        ^        ^      ^
2213dcd45ad2SRebecca Mckeever  *          |________|________|________|      |
2214dcd45ad2SRebecca Mckeever  *                            |               Unaligned address
2215dcd45ad2SRebecca Mckeever  *                Aligned addresses
2216dcd45ad2SRebecca Mckeever  *
2217dcd45ad2SRebecca Mckeever  * Expect that r1 will not be trimmed and r2 will be removed. Expect the
2218dcd45ad2SRebecca Mckeever  * counter to be updated.
2219dcd45ad2SRebecca Mckeever  */
memblock_trim_memory_too_small_check(void)2220dcd45ad2SRebecca Mckeever static int memblock_trim_memory_too_small_check(void)
2221dcd45ad2SRebecca Mckeever {
2222dcd45ad2SRebecca Mckeever 	struct memblock_region *rgn;
2223dcd45ad2SRebecca Mckeever 	const phys_addr_t alignment = SMP_CACHE_BYTES;
2224dcd45ad2SRebecca Mckeever 
2225dcd45ad2SRebecca Mckeever 	rgn = &memblock.memory.regions[0];
2226dcd45ad2SRebecca Mckeever 
2227dcd45ad2SRebecca Mckeever 	struct region r1 = {
2228dcd45ad2SRebecca Mckeever 		.base = alignment,
2229dcd45ad2SRebecca Mckeever 		.size = alignment * 2
2230dcd45ad2SRebecca Mckeever 	};
2231dcd45ad2SRebecca Mckeever 	struct region r2 = {
2232dcd45ad2SRebecca Mckeever 		.base = alignment * 4,
2233dcd45ad2SRebecca Mckeever 		.size = alignment - SZ_2
2234dcd45ad2SRebecca Mckeever 	};
2235dcd45ad2SRebecca Mckeever 
2236dcd45ad2SRebecca Mckeever 	PREFIX_PUSH();
2237dcd45ad2SRebecca Mckeever 
2238dcd45ad2SRebecca Mckeever 	reset_memblock_regions();
2239dcd45ad2SRebecca Mckeever 	memblock_add(r1.base, r1.size);
2240dcd45ad2SRebecca Mckeever 	memblock_add(r2.base, r2.size);
2241dcd45ad2SRebecca Mckeever 	memblock_trim_memory(alignment);
2242dcd45ad2SRebecca Mckeever 
2243dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn->base, r1.base);
2244dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn->size, r1.size);
2245dcd45ad2SRebecca Mckeever 
2246dcd45ad2SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 1);
2247dcd45ad2SRebecca Mckeever 
2248dcd45ad2SRebecca Mckeever 	test_pass_pop();
2249dcd45ad2SRebecca Mckeever 
2250dcd45ad2SRebecca Mckeever 	return 0;
2251dcd45ad2SRebecca Mckeever }
2252dcd45ad2SRebecca Mckeever 
2253dcd45ad2SRebecca Mckeever /*
2254dcd45ad2SRebecca Mckeever  * A test that tries to trim memory when there are two available regions, r1 and
2255dcd45ad2SRebecca Mckeever  * r2. Region r1 is aligned on both ends and region r2 is unaligned at the base
2256dcd45ad2SRebecca Mckeever  * and aligned at the end:
2257dcd45ad2SRebecca Mckeever  *
2258dcd45ad2SRebecca Mckeever  *                               Unaligned address
2259dcd45ad2SRebecca Mckeever  *                                       |
2260dcd45ad2SRebecca Mckeever  *                                       v
2261dcd45ad2SRebecca Mckeever  * |        +-----------------+          +---------------+   |
2262dcd45ad2SRebecca Mckeever  * |        |        r1       |          |      r2       |   |
2263dcd45ad2SRebecca Mckeever  * +--------+-----------------+----------+---------------+---+
2264dcd45ad2SRebecca Mckeever  *          ^        ^        ^        ^        ^        ^
2265dcd45ad2SRebecca Mckeever  *          |________|________|________|________|________|
2266dcd45ad2SRebecca Mckeever  *                            |
2267dcd45ad2SRebecca Mckeever  *                    Aligned addresses
2268dcd45ad2SRebecca Mckeever  *
2269dcd45ad2SRebecca Mckeever  * Expect that r1 will not be trimmed and r2 will be trimmed at the base.
2270dcd45ad2SRebecca Mckeever  * Expect the counter to not be updated.
2271dcd45ad2SRebecca Mckeever  */
memblock_trim_memory_unaligned_base_check(void)2272dcd45ad2SRebecca Mckeever static int memblock_trim_memory_unaligned_base_check(void)
2273dcd45ad2SRebecca Mckeever {
2274dcd45ad2SRebecca Mckeever 	struct memblock_region *rgn1, *rgn2;
2275dcd45ad2SRebecca Mckeever 	const phys_addr_t alignment = SMP_CACHE_BYTES;
2276dcd45ad2SRebecca Mckeever 	phys_addr_t offset = SZ_2;
2277dcd45ad2SRebecca Mckeever 	phys_addr_t new_r2_base, new_r2_size;
2278dcd45ad2SRebecca Mckeever 
2279dcd45ad2SRebecca Mckeever 	rgn1 = &memblock.memory.regions[0];
2280dcd45ad2SRebecca Mckeever 	rgn2 = &memblock.memory.regions[1];
2281dcd45ad2SRebecca Mckeever 
2282dcd45ad2SRebecca Mckeever 	struct region r1 = {
2283dcd45ad2SRebecca Mckeever 		.base = alignment,
2284dcd45ad2SRebecca Mckeever 		.size = alignment * 2
2285dcd45ad2SRebecca Mckeever 	};
2286dcd45ad2SRebecca Mckeever 	struct region r2 = {
2287dcd45ad2SRebecca Mckeever 		.base = alignment * 4 + offset,
2288dcd45ad2SRebecca Mckeever 		.size = alignment * 2 - offset
2289dcd45ad2SRebecca Mckeever 	};
2290dcd45ad2SRebecca Mckeever 
2291dcd45ad2SRebecca Mckeever 	PREFIX_PUSH();
2292dcd45ad2SRebecca Mckeever 
2293dcd45ad2SRebecca Mckeever 	new_r2_base = r2.base + (alignment - offset);
2294dcd45ad2SRebecca Mckeever 	new_r2_size = r2.size - (alignment - offset);
2295dcd45ad2SRebecca Mckeever 
2296dcd45ad2SRebecca Mckeever 	reset_memblock_regions();
2297dcd45ad2SRebecca Mckeever 	memblock_add(r1.base, r1.size);
2298dcd45ad2SRebecca Mckeever 	memblock_add(r2.base, r2.size);
2299dcd45ad2SRebecca Mckeever 	memblock_trim_memory(alignment);
2300dcd45ad2SRebecca Mckeever 
2301dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
2302dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1.size);
2303dcd45ad2SRebecca Mckeever 
2304dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn2->base, new_r2_base);
2305dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn2->size, new_r2_size);
2306dcd45ad2SRebecca Mckeever 
2307dcd45ad2SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 2);
2308dcd45ad2SRebecca Mckeever 
2309dcd45ad2SRebecca Mckeever 	test_pass_pop();
2310dcd45ad2SRebecca Mckeever 
2311dcd45ad2SRebecca Mckeever 	return 0;
2312dcd45ad2SRebecca Mckeever }
2313dcd45ad2SRebecca Mckeever 
2314dcd45ad2SRebecca Mckeever /*
2315dcd45ad2SRebecca Mckeever  * A test that tries to trim memory when there are two available regions, r1 and
2316dcd45ad2SRebecca Mckeever  * r2. Region r1 is aligned on both ends and region r2 is aligned at the base
2317dcd45ad2SRebecca Mckeever  * and unaligned at the end:
2318dcd45ad2SRebecca Mckeever  *
2319dcd45ad2SRebecca Mckeever  *                                             Unaligned address
2320dcd45ad2SRebecca Mckeever  *                                                     |
2321dcd45ad2SRebecca Mckeever  *                                                     v
2322dcd45ad2SRebecca Mckeever  * |        +-----------------+        +---------------+   |
2323dcd45ad2SRebecca Mckeever  * |        |        r1       |        |      r2       |   |
2324dcd45ad2SRebecca Mckeever  * +--------+-----------------+--------+---------------+---+
2325dcd45ad2SRebecca Mckeever  *          ^        ^        ^        ^        ^        ^
2326dcd45ad2SRebecca Mckeever  *          |________|________|________|________|________|
2327dcd45ad2SRebecca Mckeever  *                            |
2328dcd45ad2SRebecca Mckeever  *                    Aligned addresses
2329dcd45ad2SRebecca Mckeever  *
2330dcd45ad2SRebecca Mckeever  * Expect that r1 will not be trimmed and r2 will be trimmed at the end.
2331dcd45ad2SRebecca Mckeever  * Expect the counter to not be updated.
2332dcd45ad2SRebecca Mckeever  */
memblock_trim_memory_unaligned_end_check(void)2333dcd45ad2SRebecca Mckeever static int memblock_trim_memory_unaligned_end_check(void)
2334dcd45ad2SRebecca Mckeever {
2335dcd45ad2SRebecca Mckeever 	struct memblock_region *rgn1, *rgn2;
2336dcd45ad2SRebecca Mckeever 	const phys_addr_t alignment = SMP_CACHE_BYTES;
2337dcd45ad2SRebecca Mckeever 	phys_addr_t offset = SZ_2;
2338dcd45ad2SRebecca Mckeever 	phys_addr_t new_r2_size;
2339dcd45ad2SRebecca Mckeever 
2340dcd45ad2SRebecca Mckeever 	rgn1 = &memblock.memory.regions[0];
2341dcd45ad2SRebecca Mckeever 	rgn2 = &memblock.memory.regions[1];
2342dcd45ad2SRebecca Mckeever 
2343dcd45ad2SRebecca Mckeever 	struct region r1 = {
2344dcd45ad2SRebecca Mckeever 		.base = alignment,
2345dcd45ad2SRebecca Mckeever 		.size = alignment * 2
2346dcd45ad2SRebecca Mckeever 	};
2347dcd45ad2SRebecca Mckeever 	struct region r2 = {
2348dcd45ad2SRebecca Mckeever 		.base = alignment * 4,
2349dcd45ad2SRebecca Mckeever 		.size = alignment * 2 - offset
2350dcd45ad2SRebecca Mckeever 	};
2351dcd45ad2SRebecca Mckeever 
2352dcd45ad2SRebecca Mckeever 	PREFIX_PUSH();
2353dcd45ad2SRebecca Mckeever 
2354dcd45ad2SRebecca Mckeever 	new_r2_size = r2.size - (alignment - offset);
2355dcd45ad2SRebecca Mckeever 
2356dcd45ad2SRebecca Mckeever 	reset_memblock_regions();
2357dcd45ad2SRebecca Mckeever 	memblock_add(r1.base, r1.size);
2358dcd45ad2SRebecca Mckeever 	memblock_add(r2.base, r2.size);
2359dcd45ad2SRebecca Mckeever 	memblock_trim_memory(alignment);
2360dcd45ad2SRebecca Mckeever 
2361dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn1->base, r1.base);
2362dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn1->size, r1.size);
2363dcd45ad2SRebecca Mckeever 
2364dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn2->base, r2.base);
2365dcd45ad2SRebecca Mckeever 	ASSERT_EQ(rgn2->size, new_r2_size);
2366dcd45ad2SRebecca Mckeever 
2367dcd45ad2SRebecca Mckeever 	ASSERT_EQ(memblock.memory.cnt, 2);
2368dcd45ad2SRebecca Mckeever 
2369dcd45ad2SRebecca Mckeever 	test_pass_pop();
2370dcd45ad2SRebecca Mckeever 
2371dcd45ad2SRebecca Mckeever 	return 0;
2372dcd45ad2SRebecca Mckeever }
2373dcd45ad2SRebecca Mckeever 
memblock_trim_memory_checks(void)2374dcd45ad2SRebecca Mckeever static int memblock_trim_memory_checks(void)
2375dcd45ad2SRebecca Mckeever {
2376dcd45ad2SRebecca Mckeever 	prefix_reset();
2377dcd45ad2SRebecca Mckeever 	prefix_push(FUNC_TRIM);
2378dcd45ad2SRebecca Mckeever 	test_print("Running %s tests...\n", FUNC_TRIM);
2379dcd45ad2SRebecca Mckeever 
2380dcd45ad2SRebecca Mckeever 	memblock_trim_memory_aligned_check();
2381dcd45ad2SRebecca Mckeever 	memblock_trim_memory_too_small_check();
2382dcd45ad2SRebecca Mckeever 	memblock_trim_memory_unaligned_base_check();
2383dcd45ad2SRebecca Mckeever 	memblock_trim_memory_unaligned_end_check();
2384dcd45ad2SRebecca Mckeever 
2385dcd45ad2SRebecca Mckeever 	prefix_pop();
2386dcd45ad2SRebecca Mckeever 
2387dcd45ad2SRebecca Mckeever 	return 0;
2388dcd45ad2SRebecca Mckeever }
2389dcd45ad2SRebecca Mckeever 
memblock_overlaps_region_check(void)2390*1a879671SWei Yang static int memblock_overlaps_region_check(void)
2391*1a879671SWei Yang {
2392*1a879671SWei Yang 	struct region r = {
2393*1a879671SWei Yang 		.base = SZ_1G,
2394*1a879671SWei Yang 		.size = SZ_4M
2395*1a879671SWei Yang 	};
2396*1a879671SWei Yang 
2397*1a879671SWei Yang 	PREFIX_PUSH();
2398*1a879671SWei Yang 
2399*1a879671SWei Yang 	reset_memblock_regions();
2400*1a879671SWei Yang 	memblock_add(r.base, r.size);
2401*1a879671SWei Yang 
2402*1a879671SWei Yang 	/* Far Away */
2403*1a879671SWei Yang 	ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_1M, SZ_1M));
2404*1a879671SWei Yang 	ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_2G, SZ_1M));
2405*1a879671SWei Yang 
2406*1a879671SWei Yang 	/* Neighbor */
2407*1a879671SWei Yang 	ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_1G - SZ_1M, SZ_1M));
2408*1a879671SWei Yang 	ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_1G + SZ_4M, SZ_1M));
2409*1a879671SWei Yang 
2410*1a879671SWei Yang 	/* Partial Overlap */
2411*1a879671SWei Yang 	ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G - SZ_1M, SZ_2M));
2412*1a879671SWei Yang 	ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G + SZ_2M, SZ_2M));
2413*1a879671SWei Yang 
2414*1a879671SWei Yang 	/* Totally Overlap */
2415*1a879671SWei Yang 	ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G, SZ_4M));
2416*1a879671SWei Yang 	ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G - SZ_2M, SZ_8M));
2417*1a879671SWei Yang 	ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G + SZ_1M, SZ_1M));
2418*1a879671SWei Yang 
2419*1a879671SWei Yang 	test_pass_pop();
2420*1a879671SWei Yang 
2421*1a879671SWei Yang 	return 0;
2422*1a879671SWei Yang }
2423*1a879671SWei Yang 
memblock_overlaps_region_checks(void)2424*1a879671SWei Yang static int memblock_overlaps_region_checks(void)
2425*1a879671SWei Yang {
2426*1a879671SWei Yang 	prefix_reset();
2427*1a879671SWei Yang 	prefix_push("memblock_overlaps_region");
2428*1a879671SWei Yang 	test_print("Running memblock_overlaps_region tests...\n");
2429*1a879671SWei Yang 
2430*1a879671SWei Yang 	memblock_overlaps_region_check();
2431*1a879671SWei Yang 
2432*1a879671SWei Yang 	prefix_pop();
2433*1a879671SWei Yang 
2434*1a879671SWei Yang 	return 0;
2435*1a879671SWei Yang }
2436*1a879671SWei Yang 
memblock_basic_checks(void)2437f3252a22SKarolina Drobnik int memblock_basic_checks(void)
2438f3252a22SKarolina Drobnik {
2439f3252a22SKarolina Drobnik 	memblock_initialization_check();
24401f1180d4SKarolina Drobnik 	memblock_add_checks();
244183787a80SKarolina Drobnik 	memblock_reserve_checks();
2442b4d96893SKarolina Drobnik 	memblock_remove_checks();
2443dd45dc07SKarolina Drobnik 	memblock_free_checks();
2444a541c6d4SRebecca Mckeever 	memblock_bottom_up_checks();
2445dcd45ad2SRebecca Mckeever 	memblock_trim_memory_checks();
2446*1a879671SWei Yang 	memblock_overlaps_region_checks();
244783787a80SKarolina Drobnik 
2448f3252a22SKarolina Drobnik 	return 0;
2449f3252a22SKarolina Drobnik }
2450