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 that was marked earlier
810  * as reserved. By "freeing" a region we mean overwriting it with the next
811  * entry in memblock.reserved. To check this is the case, the test reserves
812  * two memory regions and verifies that the value of the latter was used to
813  * erase r1 region.
814  * The test also checks if the region counter and total size were updated.
815  */
816 static int memblock_free_simple_check(void)
817 {
818 	struct memblock_region *rgn;
819 
820 	rgn = &memblock.reserved.regions[0];
821 
822 	struct region r1 = {
823 		.base = SZ_4M,
824 		.size = SZ_1M
825 	};
826 	struct region r2 = {
827 		.base = SZ_8M,
828 		.size = SZ_1M
829 	};
830 
831 	reset_memblock_regions();
832 	memblock_reserve(r1.base, r1.size);
833 	memblock_reserve(r2.base, r2.size);
834 	memblock_free((void *)r1.base, r1.size);
835 
836 	assert(rgn->base == r2.base);
837 	assert(rgn->size == r2.size);
838 
839 	assert(memblock.reserved.cnt == 1);
840 	assert(memblock.reserved.total_size == r2.size);
841 
842 	return 0;
843 }
844 
845  /*
846   * A test that tries to free a region that was not marked as reserved
847   * (i.e. has no corresponding entry in memblock.reserved). It verifies
848   * that array, regions counter and total size were not modified.
849   */
850 static int memblock_free_absent_check(void)
851 {
852 	struct memblock_region *rgn;
853 
854 	rgn = &memblock.reserved.regions[0];
855 
856 	struct region r1 = {
857 		.base = SZ_2M,
858 		.size = SZ_8K
859 	};
860 	struct region r2 = {
861 		.base = SZ_16M,
862 		.size = SZ_128M
863 	};
864 
865 	reset_memblock_regions();
866 	memblock_reserve(r1.base, r1.size);
867 	memblock_free((void *)r2.base, r2.size);
868 
869 	assert(rgn->base == r1.base);
870 	assert(rgn->size == r1.size);
871 
872 	assert(memblock.reserved.cnt == 1);
873 	assert(memblock.reserved.total_size == r1.size);
874 
875 	return 0;
876 }
877 
878 /*
879  * A test that tries to free a region which overlaps with the beginning of
880  * the already existing entry r1 (that is r1.base < r2.base + r2.size). It
881  * checks if only the intersection of both regions is freed. The test also
882  * checks if the regions counter and total size are updated to expected
883  * values.
884  */
885 static int memblock_free_overlap_top_check(void)
886 {
887 	struct memblock_region *rgn;
888 	phys_addr_t total_size;
889 
890 	rgn = &memblock.reserved.regions[0];
891 
892 	struct region r1 = {
893 		.base = SZ_8M,
894 		.size = SZ_32M
895 	};
896 	struct region r2 = {
897 		.base = SZ_1M,
898 		.size = SZ_8M
899 	};
900 
901 	total_size = (r1.size + r1.base) - (r2.base + r2.size);
902 
903 	reset_memblock_regions();
904 	memblock_reserve(r1.base, r1.size);
905 	memblock_free((void *)r2.base, r2.size);
906 
907 	assert(rgn->base == r2.base + r2.size);
908 	assert(rgn->size == total_size);
909 
910 	assert(memblock.reserved.cnt == 1);
911 	assert(memblock.reserved.total_size == total_size);
912 
913 	return 0;
914 }
915 
916 /*
917  * A test that tries to free a region which overlaps with the end of the
918  * first entry (that is r2.base < r1.base + r1.size). It checks if only the
919  * intersection of both regions is freed. The test also checks if the
920  * regions counter and total size are updated to expected values.
921  */
922 static int memblock_free_overlap_bottom_check(void)
923 {
924 	struct memblock_region *rgn;
925 	phys_addr_t total_size;
926 
927 	rgn = &memblock.reserved.regions[0];
928 
929 	struct region r1 = {
930 		.base = SZ_8M,
931 		.size = SZ_32M
932 	};
933 	struct region r2 = {
934 		.base = SZ_32M,
935 		.size = SZ_32M
936 	};
937 
938 	total_size = r2.base - r1.base;
939 
940 	reset_memblock_regions();
941 	memblock_reserve(r1.base, r1.size);
942 	memblock_free((void *)r2.base, r2.size);
943 
944 	assert(rgn->base == r1.base);
945 	assert(rgn->size == total_size);
946 
947 	assert(memblock.reserved.cnt == 1);
948 	assert(memblock.reserved.total_size == total_size);
949 
950 	return 0;
951 }
952 
953 /*
954  * A test that tries to free a region which is within the range of the
955  * already existing entry (that is
956  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
957  * It checks if the region is split into two - one that ends at r2.base and
958  * second that starts at r2.base + size, with appropriate sizes. It is
959  * expected that the region counter and total size fields were updated t
960  * reflect that change.
961  */
962 static int memblock_free_within_check(void)
963 {
964 	struct memblock_region *rgn1, *rgn2;
965 	phys_addr_t r1_size, r2_size, total_size;
966 
967 	rgn1 = &memblock.reserved.regions[0];
968 	rgn2 = &memblock.reserved.regions[1];
969 
970 	struct region r1 = {
971 		.base = SZ_1M,
972 		.size = SZ_8M
973 	};
974 	struct region r2 = {
975 		.base = SZ_4M,
976 		.size = SZ_1M
977 	};
978 
979 	r1_size = r2.base - r1.base;
980 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
981 	total_size = r1_size + r2_size;
982 
983 	reset_memblock_regions();
984 	memblock_reserve(r1.base, r1.size);
985 	memblock_free((void *)r2.base, r2.size);
986 
987 	assert(rgn1->base == r1.base);
988 	assert(rgn1->size == r1_size);
989 
990 	assert(rgn2->base == r2.base + r2.size);
991 	assert(rgn2->size == r2_size);
992 
993 	assert(memblock.reserved.cnt == 2);
994 	assert(memblock.reserved.total_size == total_size);
995 
996 	return 0;
997 }
998 
999 static int memblock_free_checks(void)
1000 {
1001 	memblock_free_simple_check();
1002 	memblock_free_absent_check();
1003 	memblock_free_overlap_top_check();
1004 	memblock_free_overlap_bottom_check();
1005 	memblock_free_within_check();
1006 
1007 	return 0;
1008 }
1009 
1010 int memblock_basic_checks(void)
1011 {
1012 	memblock_initialization_check();
1013 	memblock_add_checks();
1014 	memblock_reserve_checks();
1015 	memblock_remove_checks();
1016 	memblock_free_checks();
1017 
1018 	return 0;
1019 }
1020