1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #include <string.h>
3 #include <linux/memblock.h>
4 #include "basic_api.h"
5 
6 #define EXPECTED_MEMBLOCK_REGIONS			128
7 
8 static int memblock_initialization_check(void)
9 {
10 	assert(memblock.memory.regions);
11 	assert(memblock.memory.cnt == 1);
12 	assert(memblock.memory.max == EXPECTED_MEMBLOCK_REGIONS);
13 	assert(strcmp(memblock.memory.name, "memory") == 0);
14 
15 	assert(memblock.reserved.regions);
16 	assert(memblock.reserved.cnt == 1);
17 	assert(memblock.memory.max == EXPECTED_MEMBLOCK_REGIONS);
18 	assert(strcmp(memblock.reserved.name, "reserved") == 0);
19 
20 	assert(!memblock.bottom_up);
21 	assert(memblock.current_limit == MEMBLOCK_ALLOC_ANYWHERE);
22 
23 	return 0;
24 }
25 
26 /*
27  * A simple test that adds a memory block of a specified base address
28  * and size to the collection of available memory regions (memblock.memory).
29  * Expect to create a new entry. The region counter and total memory get
30  * updated.
31  */
32 static int memblock_add_simple_check(void)
33 {
34 	struct memblock_region *rgn;
35 
36 	rgn = &memblock.memory.regions[0];
37 
38 	struct region r = {
39 		.base = SZ_1G,
40 		.size = SZ_4M
41 	};
42 
43 	reset_memblock_regions();
44 	memblock_add(r.base, r.size);
45 
46 	assert(rgn->base == r.base);
47 	assert(rgn->size == r.size);
48 
49 	assert(memblock.memory.cnt == 1);
50 	assert(memblock.memory.total_size == r.size);
51 
52 	return 0;
53 }
54 
55 /*
56  * A simple test that adds a memory block of a specified base address, size,
57  * NUMA node and memory flags to the collection of available memory regions.
58  * Expect to create a new entry. The region counter and total memory get
59  * updated.
60  */
61 static int memblock_add_node_simple_check(void)
62 {
63 	struct memblock_region *rgn;
64 
65 	rgn = &memblock.memory.regions[0];
66 
67 	struct region r = {
68 		.base = SZ_1M,
69 		.size = SZ_16M
70 	};
71 
72 	reset_memblock_regions();
73 	memblock_add_node(r.base, r.size, 1, MEMBLOCK_HOTPLUG);
74 
75 	assert(rgn->base == r.base);
76 	assert(rgn->size == r.size);
77 #ifdef CONFIG_NUMA
78 	assert(rgn->nid == 1);
79 #endif
80 	assert(rgn->flags == MEMBLOCK_HOTPLUG);
81 
82 	assert(memblock.memory.cnt == 1);
83 	assert(memblock.memory.total_size == r.size);
84 
85 	return 0;
86 }
87 
88 /*
89  * A test that tries to add two memory blocks that don't overlap with one
90  * another:
91  *
92  *  |        +--------+        +--------+  |
93  *  |        |   r1   |        |   r2   |  |
94  *  +--------+--------+--------+--------+--+
95  *
96  * Expect to add two correctly initialized entries to the collection of
97  * available memory regions (memblock.memory). The total size and
98  * region counter fields get updated.
99  */
100 static int memblock_add_disjoint_check(void)
101 {
102 	struct memblock_region *rgn1, *rgn2;
103 
104 	rgn1 = &memblock.memory.regions[0];
105 	rgn2 = &memblock.memory.regions[1];
106 
107 	struct region r1 = {
108 		.base = SZ_1G,
109 		.size = SZ_8K
110 	};
111 	struct region r2 = {
112 		.base = SZ_1G + SZ_16K,
113 		.size = SZ_8K
114 	};
115 
116 	reset_memblock_regions();
117 	memblock_add(r1.base, r1.size);
118 	memblock_add(r2.base, r2.size);
119 
120 	assert(rgn1->base == r1.base);
121 	assert(rgn1->size == r1.size);
122 
123 	assert(rgn2->base == r2.base);
124 	assert(rgn2->size == r2.size);
125 
126 	assert(memblock.memory.cnt == 2);
127 	assert(memblock.memory.total_size == r1.size + r2.size);
128 
129 	return 0;
130 }
131 
132 /*
133  * A test that tries to add two memory blocks r1 and r2, where r2 overlaps
134  * with the beginning of r1 (that is r1.base < r2.base + r2.size):
135  *
136  *  |    +----+----+------------+          |
137  *  |    |    |r2  |   r1       |          |
138  *  +----+----+----+------------+----------+
139  *       ^    ^
140  *       |    |
141  *       |    r1.base
142  *       |
143  *       r2.base
144  *
145  * Expect to merge the two entries into one region that starts at r2.base
146  * and has size of two regions minus their intersection. The total size of
147  * the available memory is updated, and the region counter stays the same.
148  */
149 static int memblock_add_overlap_top_check(void)
150 {
151 	struct memblock_region *rgn;
152 	phys_addr_t total_size;
153 
154 	rgn = &memblock.memory.regions[0];
155 
156 	struct region r1 = {
157 		.base = SZ_512M,
158 		.size = SZ_1G
159 	};
160 	struct region r2 = {
161 		.base = SZ_256M,
162 		.size = SZ_512M
163 	};
164 
165 	total_size = (r1.base - r2.base) + r1.size;
166 
167 	reset_memblock_regions();
168 	memblock_add(r1.base, r1.size);
169 	memblock_add(r2.base, r2.size);
170 
171 	assert(rgn->base == r2.base);
172 	assert(rgn->size == total_size);
173 
174 	assert(memblock.memory.cnt == 1);
175 	assert(memblock.memory.total_size == total_size);
176 
177 	return 0;
178 }
179 
180 /*
181  * A test that tries to add two memory blocks r1 and r2, where r2 overlaps
182  * with the end of r1 (that is r2.base < r1.base + r1.size):
183  *
184  *  |  +--+------+----------+              |
185  *  |  |  | r1   | r2       |              |
186  *  +--+--+------+----------+--------------+
187  *     ^  ^
188  *     |  |
189  *     |  r2.base
190  *     |
191  *     r1.base
192  *
193  * Expect to merge the two entries into one region that starts at r1.base
194  * and has size of two regions minus their intersection. The total size of
195  * the available memory is updated, and the region counter stays the same.
196  */
197 static int memblock_add_overlap_bottom_check(void)
198 {
199 	struct memblock_region *rgn;
200 	phys_addr_t total_size;
201 
202 	rgn = &memblock.memory.regions[0];
203 
204 	struct region r1 = {
205 		.base = SZ_128M,
206 		.size = SZ_512M
207 	};
208 	struct region r2 = {
209 		.base = SZ_256M,
210 		.size = SZ_1G
211 	};
212 
213 	total_size = (r2.base - r1.base) + r2.size;
214 
215 	reset_memblock_regions();
216 	memblock_add(r1.base, r1.size);
217 	memblock_add(r2.base, r2.size);
218 
219 	assert(rgn->base == r1.base);
220 	assert(rgn->size == total_size);
221 
222 	assert(memblock.memory.cnt == 1);
223 	assert(memblock.memory.total_size == total_size);
224 
225 	return 0;
226 }
227 
228 /*
229  * A test that tries to add two memory blocks r1 and r2, where r2 is
230  * within the range of r1 (that is r1.base < r2.base &&
231  * r2.base + r2.size < r1.base + r1.size):
232  *
233  *  |   +-------+--+-----------------------+
234  *  |   |       |r2|      r1               |
235  *  +---+-------+--+-----------------------+
236  *      ^
237  *      |
238  *      r1.base
239  *
240  * Expect to merge two entries into one region that stays the same.
241  * The counter and total size of available memory are not updated.
242  */
243 static int memblock_add_within_check(void)
244 {
245 	struct memblock_region *rgn;
246 
247 	rgn = &memblock.memory.regions[0];
248 
249 	struct region r1 = {
250 		.base = SZ_8M,
251 		.size = SZ_32M
252 	};
253 	struct region r2 = {
254 		.base = SZ_16M,
255 		.size = SZ_1M
256 	};
257 
258 	reset_memblock_regions();
259 	memblock_add(r1.base, r1.size);
260 	memblock_add(r2.base, r2.size);
261 
262 	assert(rgn->base == r1.base);
263 	assert(rgn->size == r1.size);
264 
265 	assert(memblock.memory.cnt == 1);
266 	assert(memblock.memory.total_size == r1.size);
267 
268 	return 0;
269 }
270 
271 /*
272  * A simple test that tries to add the same memory block twice. Expect
273  * the counter and total size of available memory to not be updated.
274  */
275 static int memblock_add_twice_check(void)
276 {
277 	struct region r = {
278 		.base = SZ_16K,
279 		.size = SZ_2M
280 	};
281 
282 	reset_memblock_regions();
283 
284 	memblock_add(r.base, r.size);
285 	memblock_add(r.base, r.size);
286 
287 	assert(memblock.memory.cnt == 1);
288 	assert(memblock.memory.total_size == r.size);
289 
290 	return 0;
291 }
292 
293 static int memblock_add_checks(void)
294 {
295 	memblock_add_simple_check();
296 	memblock_add_node_simple_check();
297 	memblock_add_disjoint_check();
298 	memblock_add_overlap_top_check();
299 	memblock_add_overlap_bottom_check();
300 	memblock_add_within_check();
301 	memblock_add_twice_check();
302 
303 	return 0;
304 }
305 
306 /*
307  * A simple test that marks a memory block of a specified base address
308  * and size as reserved and to the collection of reserved memory regions
309  * (memblock.reserved). Expect to create a new entry. The region counter
310  * and total memory size are updated.
311  */
312 static int memblock_reserve_simple_check(void)
313 {
314 	struct memblock_region *rgn;
315 
316 	rgn =  &memblock.reserved.regions[0];
317 
318 	struct region r = {
319 		.base = SZ_2G,
320 		.size = SZ_128M
321 	};
322 
323 	reset_memblock_regions();
324 	memblock_reserve(r.base, r.size);
325 
326 	assert(rgn->base == r.base);
327 	assert(rgn->size == r.size);
328 
329 	return 0;
330 }
331 
332 /*
333  * A test that tries to mark two memory blocks that don't overlap as reserved:
334  *
335  *  |        +--+      +----------------+  |
336  *  |        |r1|      |       r2       |  |
337  *  +--------+--+------+----------------+--+
338  *
339  * Expect to add two entries to the collection of reserved memory regions
340  * (memblock.reserved). The total size and region counter for
341  * memblock.reserved are updated.
342  */
343 static int memblock_reserve_disjoint_check(void)
344 {
345 	struct memblock_region *rgn1, *rgn2;
346 
347 	rgn1 = &memblock.reserved.regions[0];
348 	rgn2 = &memblock.reserved.regions[1];
349 
350 	struct region r1 = {
351 		.base = SZ_256M,
352 		.size = SZ_16M
353 	};
354 	struct region r2 = {
355 		.base = SZ_512M,
356 		.size = SZ_512M
357 	};
358 
359 	reset_memblock_regions();
360 	memblock_reserve(r1.base, r1.size);
361 	memblock_reserve(r2.base, r2.size);
362 
363 	assert(rgn1->base == r1.base);
364 	assert(rgn1->size == r1.size);
365 
366 	assert(rgn2->base == r2.base);
367 	assert(rgn2->size == r2.size);
368 
369 	assert(memblock.reserved.cnt == 2);
370 	assert(memblock.reserved.total_size == r1.size + r2.size);
371 
372 	return 0;
373 }
374 
375 /*
376  * A test that tries to mark two memory blocks r1 and r2 as reserved,
377  * where r2 overlaps with the beginning of r1 (that is
378  * r1.base < r2.base + r2.size):
379  *
380  *  |  +--------------+--+--------------+  |
381  *  |  |       r2     |  |     r1       |  |
382  *  +--+--------------+--+--------------+--+
383  *     ^              ^
384  *     |              |
385  *     |              r1.base
386  *     |
387  *     r2.base
388  *
389  * Expect to merge two entries into one region that starts at r2.base and
390  * has size of two regions minus their intersection. The total size of the
391  * reserved memory is updated, and the region counter is not updated.
392  */
393 static int memblock_reserve_overlap_top_check(void)
394 {
395 	struct memblock_region *rgn;
396 	phys_addr_t total_size;
397 
398 	rgn = &memblock.reserved.regions[0];
399 
400 	struct region r1 = {
401 		.base = SZ_1G,
402 		.size = SZ_1G
403 	};
404 	struct region r2 = {
405 		.base = SZ_128M,
406 		.size = SZ_1G
407 	};
408 
409 	total_size = (r1.base - r2.base) + r1.size;
410 
411 	reset_memblock_regions();
412 	memblock_reserve(r1.base, r1.size);
413 	memblock_reserve(r2.base, r2.size);
414 
415 	assert(rgn->base == r2.base);
416 	assert(rgn->size == total_size);
417 
418 	assert(memblock.reserved.cnt == 1);
419 	assert(memblock.reserved.total_size == total_size);
420 
421 	return 0;
422 }
423 
424 /*
425  * A test that tries to mark two memory blocks r1 and r2 as reserved,
426  * where r2 overlaps with the end of r1 (that is
427  * r2.base < r1.base + r1.size):
428  *
429  *  |  +--------------+--+--------------+  |
430  *  |  |       r1     |  |     r2       |  |
431  *  +--+--------------+--+--------------+--+
432  *     ^              ^
433  *     |              |
434  *     |              r2.base
435  *     |
436  *     r1.base
437  *
438  * Expect to merge two entries into one region that starts at r1.base and
439  * has size of two regions minus their intersection. The total size of the
440  * reserved memory is updated, and the region counter is not updated.
441  */
442 static int memblock_reserve_overlap_bottom_check(void)
443 {
444 	struct memblock_region *rgn;
445 	phys_addr_t total_size;
446 
447 	rgn = &memblock.reserved.regions[0];
448 
449 	struct region r1 = {
450 		.base = SZ_2K,
451 		.size = SZ_128K
452 	};
453 	struct region r2 = {
454 		.base = SZ_128K,
455 		.size = SZ_128K
456 	};
457 
458 	total_size = (r2.base - r1.base) + r2.size;
459 
460 	reset_memblock_regions();
461 	memblock_reserve(r1.base, r1.size);
462 	memblock_reserve(r2.base, r2.size);
463 
464 	assert(rgn->base == r1.base);
465 	assert(rgn->size == total_size);
466 
467 	assert(memblock.reserved.cnt == 1);
468 	assert(memblock.reserved.total_size == total_size);
469 
470 	return 0;
471 }
472 
473 /*
474  * A test that tries to mark two memory blocks r1 and r2 as reserved,
475  * where r2 is within the range of r1 (that is
476  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
477  *
478  *  | +-----+--+---------------------------|
479  *  | |     |r2|          r1               |
480  *  +-+-----+--+---------------------------+
481  *    ^     ^
482  *    |     |
483  *    |     r2.base
484  *    |
485  *    r1.base
486  *
487  * Expect to merge two entries into one region that stays the same. The
488  * counter and total size of available memory are not updated.
489  */
490 static int memblock_reserve_within_check(void)
491 {
492 	struct memblock_region *rgn;
493 
494 	rgn = &memblock.reserved.regions[0];
495 
496 	struct region r1 = {
497 		.base = SZ_1M,
498 		.size = SZ_8M
499 	};
500 	struct region r2 = {
501 		.base = SZ_2M,
502 		.size = SZ_64K
503 	};
504 
505 	reset_memblock_regions();
506 	memblock_reserve(r1.base, r1.size);
507 	memblock_reserve(r2.base, r2.size);
508 
509 	assert(rgn->base == r1.base);
510 	assert(rgn->size == r1.size);
511 
512 	assert(memblock.reserved.cnt == 1);
513 	assert(memblock.reserved.total_size == r1.size);
514 
515 	return 0;
516 }
517 
518 /*
519  * A simple test that tries to reserve the same memory block twice.
520  * Expect the region counter and total size of reserved memory to not
521  * be updated.
522  */
523 static int memblock_reserve_twice_check(void)
524 {
525 	struct region r = {
526 		.base = SZ_16K,
527 		.size = SZ_2M
528 	};
529 
530 	reset_memblock_regions();
531 
532 	memblock_reserve(r.base, r.size);
533 	memblock_reserve(r.base, r.size);
534 
535 	assert(memblock.reserved.cnt == 1);
536 	assert(memblock.reserved.total_size == r.size);
537 
538 	return 0;
539 }
540 
541 static int memblock_reserve_checks(void)
542 {
543 	memblock_reserve_simple_check();
544 	memblock_reserve_disjoint_check();
545 	memblock_reserve_overlap_top_check();
546 	memblock_reserve_overlap_bottom_check();
547 	memblock_reserve_within_check();
548 	memblock_reserve_twice_check();
549 
550 	return 0;
551 }
552 
553 /*
554  * A simple test that tries to remove a region r1 from the array of
555  * available memory regions. By "removing" a region we mean overwriting it
556  * with the next region r2 in memblock.memory:
557  *
558  *  |  ......          +----------------+  |
559  *  |  : r1 :          |       r2       |  |
560  *  +--+----+----------+----------------+--+
561  *                     ^
562  *                     |
563  *                     rgn.base
564  *
565  * Expect to add two memory blocks r1 and r2 and then remove r1 so that
566  * r2 is the first available region. The region counter and total size
567  * are updated.
568  */
569 static int memblock_remove_simple_check(void)
570 {
571 	struct memblock_region *rgn;
572 
573 	rgn = &memblock.memory.regions[0];
574 
575 	struct region r1 = {
576 		.base = SZ_2K,
577 		.size = SZ_4K
578 	};
579 	struct region r2 = {
580 		.base = SZ_128K,
581 		.size = SZ_4M
582 	};
583 
584 	reset_memblock_regions();
585 	memblock_add(r1.base, r1.size);
586 	memblock_add(r2.base, r2.size);
587 	memblock_remove(r1.base, r1.size);
588 
589 	assert(rgn->base == r2.base);
590 	assert(rgn->size == r2.size);
591 
592 	assert(memblock.memory.cnt == 1);
593 	assert(memblock.memory.total_size == r2.size);
594 
595 	return 0;
596 }
597 
598 /*
599  * A test that tries to remove a region r2 that was not registered as
600  * available memory (i.e. has no corresponding entry in memblock.memory):
601  *
602  *                     +----------------+
603  *                     |       r2       |
604  *                     +----------------+
605  *  |  +----+                              |
606  *  |  | r1 |                              |
607  *  +--+----+------------------------------+
608  *     ^
609  *     |
610  *     rgn.base
611  *
612  * Expect the array, regions counter and total size to not be modified.
613  */
614 static int memblock_remove_absent_check(void)
615 {
616 	struct memblock_region *rgn;
617 
618 	rgn = &memblock.memory.regions[0];
619 
620 	struct region r1 = {
621 		.base = SZ_512K,
622 		.size = SZ_4M
623 	};
624 	struct region r2 = {
625 		.base = SZ_64M,
626 		.size = SZ_1G
627 	};
628 
629 	reset_memblock_regions();
630 	memblock_add(r1.base, r1.size);
631 	memblock_remove(r2.base, r2.size);
632 
633 	assert(rgn->base == r1.base);
634 	assert(rgn->size == r1.size);
635 
636 	assert(memblock.memory.cnt == 1);
637 	assert(memblock.memory.total_size == r1.size);
638 
639 	return 0;
640 }
641 
642 /*
643  * A test that tries to remove a region r2 that overlaps with the
644  * beginning of the already existing entry r1
645  * (that is r1.base < r2.base + r2.size):
646  *
647  *           +-----------------+
648  *           |       r2        |
649  *           +-----------------+
650  *  |                 .........+--------+  |
651  *  |                 :     r1 |  rgn   |  |
652  *  +-----------------+--------+--------+--+
653  *                    ^        ^
654  *                    |        |
655  *                    |        rgn.base
656  *                    r1.base
657  *
658  * Expect that only the intersection of both regions is removed from the
659  * available memory pool. The regions counter and total size are updated.
660  */
661 static int memblock_remove_overlap_top_check(void)
662 {
663 	struct memblock_region *rgn;
664 	phys_addr_t r1_end, r2_end, total_size;
665 
666 	rgn = &memblock.memory.regions[0];
667 
668 	struct region r1 = {
669 		.base = SZ_32M,
670 		.size = SZ_32M
671 	};
672 	struct region r2 = {
673 		.base = SZ_16M,
674 		.size = SZ_32M
675 	};
676 
677 	r1_end = r1.base + r1.size;
678 	r2_end = r2.base + r2.size;
679 	total_size = r1_end - r2_end;
680 
681 	reset_memblock_regions();
682 	memblock_add(r1.base, r1.size);
683 	memblock_remove(r2.base, r2.size);
684 
685 	assert(rgn->base == r1.base + r2.base);
686 	assert(rgn->size == total_size);
687 
688 	assert(memblock.memory.cnt == 1);
689 	assert(memblock.memory.total_size == total_size);
690 
691 	return 0;
692 }
693 
694 /*
695  * A test that tries to remove a region r2 that overlaps with the end of
696  * the already existing region r1 (that is r2.base < r1.base + r1.size):
697  *
698  *        +--------------------------------+
699  *        |               r2               |
700  *        +--------------------------------+
701  *  | +---+.....                           |
702  *  | |rgn| r1 :                           |
703  *  +-+---+----+---------------------------+
704  *    ^
705  *    |
706  *    r1.base
707  *
708  * Expect that only the intersection of both regions is removed from the
709  * available memory pool. The regions counter and total size are updated.
710  */
711 static int memblock_remove_overlap_bottom_check(void)
712 {
713 	struct memblock_region *rgn;
714 	phys_addr_t total_size;
715 
716 	rgn = &memblock.memory.regions[0];
717 
718 	struct region r1 = {
719 		.base = SZ_2M,
720 		.size = SZ_64M
721 	};
722 	struct region r2 = {
723 		.base = SZ_32M,
724 		.size = SZ_256M
725 	};
726 
727 	total_size = r2.base - r1.base;
728 
729 	reset_memblock_regions();
730 	memblock_add(r1.base, r1.size);
731 	memblock_remove(r2.base, r2.size);
732 
733 	assert(rgn->base == r1.base);
734 	assert(rgn->size == total_size);
735 
736 	assert(memblock.memory.cnt == 1);
737 	assert(memblock.memory.total_size == total_size);
738 	return 0;
739 }
740 
741 /*
742  * A test that tries to remove a region r2 that is within the range of
743  * the already existing entry r1 (that is
744  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
745  *
746  *                  +----+
747  *                  | r2 |
748  *                  +----+
749  *  | +-------------+....+---------------+ |
750  *  | |     rgn1    | r1 |     rgn2      | |
751  *  +-+-------------+----+---------------+-+
752  *    ^
753  *    |
754  *    r1.base
755  *
756  * Expect that the region is split into two - one that ends at r2.base and
757  * another that starts at r2.base + r2.size, with appropriate sizes. The
758  * region counter and total size are updated.
759  */
760 static int memblock_remove_within_check(void)
761 {
762 	struct memblock_region *rgn1, *rgn2;
763 	phys_addr_t r1_size, r2_size, total_size;
764 
765 	rgn1 = &memblock.memory.regions[0];
766 	rgn2 = &memblock.memory.regions[1];
767 
768 	struct region r1 = {
769 		.base = SZ_1M,
770 		.size = SZ_32M
771 	};
772 	struct region r2 = {
773 		.base = SZ_16M,
774 		.size = SZ_1M
775 	};
776 
777 	r1_size = r2.base - r1.base;
778 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
779 	total_size = r1_size + r2_size;
780 
781 	reset_memblock_regions();
782 	memblock_add(r1.base, r1.size);
783 	memblock_remove(r2.base, r2.size);
784 
785 	assert(rgn1->base == r1.base);
786 	assert(rgn1->size == r1_size);
787 
788 	assert(rgn2->base == r2.base + r2.size);
789 	assert(rgn2->size == r2_size);
790 
791 	assert(memblock.memory.cnt == 2);
792 	assert(memblock.memory.total_size == total_size);
793 
794 	return 0;
795 }
796 
797 static int memblock_remove_checks(void)
798 {
799 	memblock_remove_simple_check();
800 	memblock_remove_absent_check();
801 	memblock_remove_overlap_top_check();
802 	memblock_remove_overlap_bottom_check();
803 	memblock_remove_within_check();
804 
805 	return 0;
806 }
807 
808 /*
809  * A simple test that tries to free a memory block r1 that was marked
810  * earlier as reserved. By "freeing" a region we mean overwriting it with
811  * the next entry r2 in memblock.reserved:
812  *
813  *  |              ......           +----+ |
814  *  |              : r1 :           | r2 | |
815  *  +--------------+----+-----------+----+-+
816  *                                  ^
817  *                                  |
818  *                                  rgn.base
819  *
820  * Expect to reserve two memory regions and then erase r1 region with the
821  * value of r2. The region counter and total size are updated.
822  */
823 static int memblock_free_simple_check(void)
824 {
825 	struct memblock_region *rgn;
826 
827 	rgn = &memblock.reserved.regions[0];
828 
829 	struct region r1 = {
830 		.base = SZ_4M,
831 		.size = SZ_1M
832 	};
833 	struct region r2 = {
834 		.base = SZ_8M,
835 		.size = SZ_1M
836 	};
837 
838 	reset_memblock_regions();
839 	memblock_reserve(r1.base, r1.size);
840 	memblock_reserve(r2.base, r2.size);
841 	memblock_free((void *)r1.base, r1.size);
842 
843 	assert(rgn->base == r2.base);
844 	assert(rgn->size == r2.size);
845 
846 	assert(memblock.reserved.cnt == 1);
847 	assert(memblock.reserved.total_size == r2.size);
848 
849 	return 0;
850 }
851 
852 /*
853  * A test that tries to free a region r2 that was not marked as reserved
854  * (i.e. has no corresponding entry in memblock.reserved):
855  *
856  *                     +----------------+
857  *                     |       r2       |
858  *                     +----------------+
859  *  |  +----+                              |
860  *  |  | r1 |                              |
861  *  +--+----+------------------------------+
862  *     ^
863  *     |
864  *     rgn.base
865  *
866  * The array, regions counter and total size are not modified.
867  */
868 static int memblock_free_absent_check(void)
869 {
870 	struct memblock_region *rgn;
871 
872 	rgn = &memblock.reserved.regions[0];
873 
874 	struct region r1 = {
875 		.base = SZ_2M,
876 		.size = SZ_8K
877 	};
878 	struct region r2 = {
879 		.base = SZ_16M,
880 		.size = SZ_128M
881 	};
882 
883 	reset_memblock_regions();
884 	memblock_reserve(r1.base, r1.size);
885 	memblock_free((void *)r2.base, r2.size);
886 
887 	assert(rgn->base == r1.base);
888 	assert(rgn->size == r1.size);
889 
890 	assert(memblock.reserved.cnt == 1);
891 	assert(memblock.reserved.total_size == r1.size);
892 
893 	return 0;
894 }
895 
896 /*
897  * A test that tries to free a region r2 that overlaps with the beginning
898  * of the already existing entry r1 (that is r1.base < r2.base + r2.size):
899  *
900  *     +----+
901  *     | r2 |
902  *     +----+
903  *  |    ...+--------------+               |
904  *  |    :  |    r1        |               |
905  *  +----+--+--------------+---------------+
906  *       ^  ^
907  *       |  |
908  *       |  rgn.base
909  *       |
910  *       r1.base
911  *
912  * Expect that only the intersection of both regions is freed. The
913  * regions counter and total size are updated.
914  */
915 static int memblock_free_overlap_top_check(void)
916 {
917 	struct memblock_region *rgn;
918 	phys_addr_t total_size;
919 
920 	rgn = &memblock.reserved.regions[0];
921 
922 	struct region r1 = {
923 		.base = SZ_8M,
924 		.size = SZ_32M
925 	};
926 	struct region r2 = {
927 		.base = SZ_1M,
928 		.size = SZ_8M
929 	};
930 
931 	total_size = (r1.size + r1.base) - (r2.base + r2.size);
932 
933 	reset_memblock_regions();
934 	memblock_reserve(r1.base, r1.size);
935 	memblock_free((void *)r2.base, r2.size);
936 
937 	assert(rgn->base == r2.base + r2.size);
938 	assert(rgn->size == total_size);
939 
940 	assert(memblock.reserved.cnt == 1);
941 	assert(memblock.reserved.total_size == total_size);
942 
943 	return 0;
944 }
945 
946 /*
947  * A test that tries to free a region r2 that overlaps with the end of
948  * the already existing entry r1 (that is r2.base < r1.base + r1.size):
949  *
950  *                   +----------------+
951  *                   |       r2       |
952  *                   +----------------+
953  *  |    +-----------+.....                |
954  *  |    |       r1  |    :                |
955  *  +----+-----------+----+----------------+
956  *
957  * Expect that only the intersection of both regions is freed. The
958  * regions counter and total size are updated.
959  */
960 static int memblock_free_overlap_bottom_check(void)
961 {
962 	struct memblock_region *rgn;
963 	phys_addr_t total_size;
964 
965 	rgn = &memblock.reserved.regions[0];
966 
967 	struct region r1 = {
968 		.base = SZ_8M,
969 		.size = SZ_32M
970 	};
971 	struct region r2 = {
972 		.base = SZ_32M,
973 		.size = SZ_32M
974 	};
975 
976 	total_size = r2.base - r1.base;
977 
978 	reset_memblock_regions();
979 	memblock_reserve(r1.base, r1.size);
980 	memblock_free((void *)r2.base, r2.size);
981 
982 	assert(rgn->base == r1.base);
983 	assert(rgn->size == total_size);
984 
985 	assert(memblock.reserved.cnt == 1);
986 	assert(memblock.reserved.total_size == total_size);
987 
988 	return 0;
989 }
990 
991 /*
992  * A test that tries to free a region r2 that is within the range of the
993  * already existing entry r1 (that is
994  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
995  *
996  *                    +----+
997  *                    | r2 |
998  *                    +----+
999  *  |    +------------+....+---------------+
1000  *  |    |    rgn1    | r1 |     rgn2      |
1001  *  +----+------------+----+---------------+
1002  *       ^
1003  *       |
1004  *       r1.base
1005  *
1006  * Expect that the region is split into two - one that ends at r2.base and
1007  * another that starts at r2.base + r2.size, with appropriate sizes. The
1008  * region counter and total size fields are updated.
1009  */
1010 static int memblock_free_within_check(void)
1011 {
1012 	struct memblock_region *rgn1, *rgn2;
1013 	phys_addr_t r1_size, r2_size, total_size;
1014 
1015 	rgn1 = &memblock.reserved.regions[0];
1016 	rgn2 = &memblock.reserved.regions[1];
1017 
1018 	struct region r1 = {
1019 		.base = SZ_1M,
1020 		.size = SZ_8M
1021 	};
1022 	struct region r2 = {
1023 		.base = SZ_4M,
1024 		.size = SZ_1M
1025 	};
1026 
1027 	r1_size = r2.base - r1.base;
1028 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
1029 	total_size = r1_size + r2_size;
1030 
1031 	reset_memblock_regions();
1032 	memblock_reserve(r1.base, r1.size);
1033 	memblock_free((void *)r2.base, r2.size);
1034 
1035 	assert(rgn1->base == r1.base);
1036 	assert(rgn1->size == r1_size);
1037 
1038 	assert(rgn2->base == r2.base + r2.size);
1039 	assert(rgn2->size == r2_size);
1040 
1041 	assert(memblock.reserved.cnt == 2);
1042 	assert(memblock.reserved.total_size == total_size);
1043 
1044 	return 0;
1045 }
1046 
1047 static int memblock_free_checks(void)
1048 {
1049 	memblock_free_simple_check();
1050 	memblock_free_absent_check();
1051 	memblock_free_overlap_top_check();
1052 	memblock_free_overlap_bottom_check();
1053 	memblock_free_within_check();
1054 
1055 	return 0;
1056 }
1057 
1058 int memblock_basic_checks(void)
1059 {
1060 	memblock_initialization_check();
1061 	memblock_add_checks();
1062 	memblock_reserve_checks();
1063 	memblock_remove_checks();
1064 	memblock_free_checks();
1065 
1066 	return 0;
1067 }
1068