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 the first entry of the array of
555   * available memory regions. By "removing" a region we mean overwriting it
556   * with the next region in memblock.memory. To check this is the case, the
557   * test adds two memory blocks and verifies that the value of the latter
558   * was used to erase r1 region.  It also checks if the region counter and
559   * total size were updated to expected values.
560   */
561 static int memblock_remove_simple_check(void)
562 {
563 	struct memblock_region *rgn;
564 
565 	rgn = &memblock.memory.regions[0];
566 
567 	struct region r1 = {
568 		.base = SZ_2K,
569 		.size = SZ_4K
570 	};
571 	struct region r2 = {
572 		.base = SZ_128K,
573 		.size = SZ_4M
574 	};
575 
576 	reset_memblock_regions();
577 	memblock_add(r1.base, r1.size);
578 	memblock_add(r2.base, r2.size);
579 	memblock_remove(r1.base, r1.size);
580 
581 	assert(rgn->base == r2.base);
582 	assert(rgn->size == r2.size);
583 
584 	assert(memblock.memory.cnt == 1);
585 	assert(memblock.memory.total_size == r2.size);
586 
587 	return 0;
588 }
589 
590  /*
591   * A test that tries to remove a region that was not registered as available
592   * memory (i.e. has no corresponding entry in memblock.memory). It verifies
593   * that array, regions counter and total size were not modified.
594   */
595 static int memblock_remove_absent_check(void)
596 {
597 	struct memblock_region *rgn;
598 
599 	rgn = &memblock.memory.regions[0];
600 
601 	struct region r1 = {
602 		.base = SZ_512K,
603 		.size = SZ_4M
604 	};
605 	struct region r2 = {
606 		.base = SZ_64M,
607 		.size = SZ_1G
608 	};
609 
610 	reset_memblock_regions();
611 	memblock_add(r1.base, r1.size);
612 	memblock_remove(r2.base, r2.size);
613 
614 	assert(rgn->base == r1.base);
615 	assert(rgn->size == r1.size);
616 
617 	assert(memblock.memory.cnt == 1);
618 	assert(memblock.memory.total_size == r1.size);
619 
620 	return 0;
621 }
622 
623 /*
624  * A test that tries to remove a region which overlaps with the beginning of
625  * the already existing entry r1 (that is r1.base < r2.base + r2.size). It
626  * checks if only the intersection of both regions is removed from the available
627  * memory pool. The test also checks if the regions counter and total size are
628  * updated to expected values.
629  */
630 static int memblock_remove_overlap_top_check(void)
631 {
632 	struct memblock_region *rgn;
633 	phys_addr_t r1_end, r2_end, total_size;
634 
635 	rgn = &memblock.memory.regions[0];
636 
637 	struct region r1 = {
638 		.base = SZ_32M,
639 		.size = SZ_32M
640 	};
641 	struct region r2 = {
642 		.base = SZ_16M,
643 		.size = SZ_32M
644 	};
645 
646 	r1_end = r1.base + r1.size;
647 	r2_end = r2.base + r2.size;
648 	total_size = r1_end - r2_end;
649 
650 	reset_memblock_regions();
651 	memblock_add(r1.base, r1.size);
652 	memblock_remove(r2.base, r2.size);
653 
654 	assert(rgn->base == r1.base + r2.base);
655 	assert(rgn->size == total_size);
656 
657 	assert(memblock.memory.cnt == 1);
658 	assert(memblock.memory.total_size == total_size);
659 
660 	return 0;
661 }
662 
663 /*
664  * A test that tries to remove a region which overlaps with the end of the
665  * first entry (that is r2.base < r1.base + r1.size). It checks if only the
666  * intersection of both regions is removed from the available memory pool.
667  * The test also checks if the regions counter and total size are updated to
668  * expected values.
669  */
670 static int memblock_remove_overlap_bottom_check(void)
671 {
672 	struct memblock_region *rgn;
673 	phys_addr_t total_size;
674 
675 	rgn = &memblock.memory.regions[0];
676 
677 	struct region r1 = {
678 		.base = SZ_2M,
679 		.size = SZ_64M
680 	};
681 	struct region r2 = {
682 		.base = SZ_32M,
683 		.size = SZ_256M
684 	};
685 
686 	total_size = r2.base - r1.base;
687 
688 	reset_memblock_regions();
689 	memblock_add(r1.base, r1.size);
690 	memblock_remove(r2.base, r2.size);
691 
692 	assert(rgn->base == r1.base);
693 	assert(rgn->size == total_size);
694 
695 	assert(memblock.memory.cnt == 1);
696 	assert(memblock.memory.total_size == total_size);
697 	return 0;
698 }
699 
700 /*
701  * A test that tries to remove a region which is within the range of the
702  * already existing entry (that is
703  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
704  * It checks if the region is split into two - one that ends at r2.base and
705  * second that starts at r2.base + size, with appropriate sizes. The test
706  * also checks if the region counter and total size were updated to
707  * expected values.
708  */
709 static int memblock_remove_within_check(void)
710 {
711 	struct memblock_region *rgn1, *rgn2;
712 	phys_addr_t r1_size, r2_size, total_size;
713 
714 	rgn1 = &memblock.memory.regions[0];
715 	rgn2 = &memblock.memory.regions[1];
716 
717 	struct region r1 = {
718 		.base = SZ_1M,
719 		.size = SZ_32M
720 	};
721 	struct region r2 = {
722 		.base = SZ_16M,
723 		.size = SZ_1M
724 	};
725 
726 	r1_size = r2.base - r1.base;
727 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
728 	total_size = r1_size + r2_size;
729 
730 	reset_memblock_regions();
731 	memblock_add(r1.base, r1.size);
732 	memblock_remove(r2.base, r2.size);
733 
734 	assert(rgn1->base == r1.base);
735 	assert(rgn1->size == r1_size);
736 
737 	assert(rgn2->base == r2.base + r2.size);
738 	assert(rgn2->size == r2_size);
739 
740 	assert(memblock.memory.cnt == 2);
741 	assert(memblock.memory.total_size == total_size);
742 
743 	return 0;
744 }
745 
746 static int memblock_remove_checks(void)
747 {
748 	memblock_remove_simple_check();
749 	memblock_remove_absent_check();
750 	memblock_remove_overlap_top_check();
751 	memblock_remove_overlap_bottom_check();
752 	memblock_remove_within_check();
753 
754 	return 0;
755 }
756 
757 /*
758  * A simple test that tries to free a memory block that was marked earlier
759  * as reserved. By "freeing" a region we mean overwriting it with the next
760  * entry in memblock.reserved. To check this is the case, the test reserves
761  * two memory regions and verifies that the value of the latter was used to
762  * erase r1 region.
763  * The test also checks if the region counter and total size were updated.
764  */
765 static int memblock_free_simple_check(void)
766 {
767 	struct memblock_region *rgn;
768 
769 	rgn = &memblock.reserved.regions[0];
770 
771 	struct region r1 = {
772 		.base = SZ_4M,
773 		.size = SZ_1M
774 	};
775 	struct region r2 = {
776 		.base = SZ_8M,
777 		.size = SZ_1M
778 	};
779 
780 	reset_memblock_regions();
781 	memblock_reserve(r1.base, r1.size);
782 	memblock_reserve(r2.base, r2.size);
783 	memblock_free((void *)r1.base, r1.size);
784 
785 	assert(rgn->base == r2.base);
786 	assert(rgn->size == r2.size);
787 
788 	assert(memblock.reserved.cnt == 1);
789 	assert(memblock.reserved.total_size == r2.size);
790 
791 	return 0;
792 }
793 
794  /*
795   * A test that tries to free a region that was not marked as reserved
796   * (i.e. has no corresponding entry in memblock.reserved). It verifies
797   * that array, regions counter and total size were not modified.
798   */
799 static int memblock_free_absent_check(void)
800 {
801 	struct memblock_region *rgn;
802 
803 	rgn = &memblock.reserved.regions[0];
804 
805 	struct region r1 = {
806 		.base = SZ_2M,
807 		.size = SZ_8K
808 	};
809 	struct region r2 = {
810 		.base = SZ_16M,
811 		.size = SZ_128M
812 	};
813 
814 	reset_memblock_regions();
815 	memblock_reserve(r1.base, r1.size);
816 	memblock_free((void *)r2.base, r2.size);
817 
818 	assert(rgn->base == r1.base);
819 	assert(rgn->size == r1.size);
820 
821 	assert(memblock.reserved.cnt == 1);
822 	assert(memblock.reserved.total_size == r1.size);
823 
824 	return 0;
825 }
826 
827 /*
828  * A test that tries to free a region which overlaps with the beginning of
829  * the already existing entry r1 (that is r1.base < r2.base + r2.size). It
830  * checks if only the intersection of both regions is freed. The test also
831  * checks if the regions counter and total size are updated to expected
832  * values.
833  */
834 static int memblock_free_overlap_top_check(void)
835 {
836 	struct memblock_region *rgn;
837 	phys_addr_t total_size;
838 
839 	rgn = &memblock.reserved.regions[0];
840 
841 	struct region r1 = {
842 		.base = SZ_8M,
843 		.size = SZ_32M
844 	};
845 	struct region r2 = {
846 		.base = SZ_1M,
847 		.size = SZ_8M
848 	};
849 
850 	total_size = (r1.size + r1.base) - (r2.base + r2.size);
851 
852 	reset_memblock_regions();
853 	memblock_reserve(r1.base, r1.size);
854 	memblock_free((void *)r2.base, r2.size);
855 
856 	assert(rgn->base == r2.base + r2.size);
857 	assert(rgn->size == total_size);
858 
859 	assert(memblock.reserved.cnt == 1);
860 	assert(memblock.reserved.total_size == total_size);
861 
862 	return 0;
863 }
864 
865 /*
866  * A test that tries to free a region which overlaps with the end of the
867  * first entry (that is r2.base < r1.base + r1.size). It checks if only the
868  * intersection of both regions is freed. The test also checks if the
869  * regions counter and total size are updated to expected values.
870  */
871 static int memblock_free_overlap_bottom_check(void)
872 {
873 	struct memblock_region *rgn;
874 	phys_addr_t total_size;
875 
876 	rgn = &memblock.reserved.regions[0];
877 
878 	struct region r1 = {
879 		.base = SZ_8M,
880 		.size = SZ_32M
881 	};
882 	struct region r2 = {
883 		.base = SZ_32M,
884 		.size = SZ_32M
885 	};
886 
887 	total_size = r2.base - r1.base;
888 
889 	reset_memblock_regions();
890 	memblock_reserve(r1.base, r1.size);
891 	memblock_free((void *)r2.base, r2.size);
892 
893 	assert(rgn->base == r1.base);
894 	assert(rgn->size == total_size);
895 
896 	assert(memblock.reserved.cnt == 1);
897 	assert(memblock.reserved.total_size == total_size);
898 
899 	return 0;
900 }
901 
902 /*
903  * A test that tries to free a region which is within the range of the
904  * already existing entry (that is
905  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
906  * It checks if the region is split into two - one that ends at r2.base and
907  * second that starts at r2.base + size, with appropriate sizes. It is
908  * expected that the region counter and total size fields were updated t
909  * reflect that change.
910  */
911 static int memblock_free_within_check(void)
912 {
913 	struct memblock_region *rgn1, *rgn2;
914 	phys_addr_t r1_size, r2_size, total_size;
915 
916 	rgn1 = &memblock.reserved.regions[0];
917 	rgn2 = &memblock.reserved.regions[1];
918 
919 	struct region r1 = {
920 		.base = SZ_1M,
921 		.size = SZ_8M
922 	};
923 	struct region r2 = {
924 		.base = SZ_4M,
925 		.size = SZ_1M
926 	};
927 
928 	r1_size = r2.base - r1.base;
929 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
930 	total_size = r1_size + r2_size;
931 
932 	reset_memblock_regions();
933 	memblock_reserve(r1.base, r1.size);
934 	memblock_free((void *)r2.base, r2.size);
935 
936 	assert(rgn1->base == r1.base);
937 	assert(rgn1->size == r1_size);
938 
939 	assert(rgn2->base == r2.base + r2.size);
940 	assert(rgn2->size == r2_size);
941 
942 	assert(memblock.reserved.cnt == 2);
943 	assert(memblock.reserved.total_size == total_size);
944 
945 	return 0;
946 }
947 
948 static int memblock_free_checks(void)
949 {
950 	memblock_free_simple_check();
951 	memblock_free_absent_check();
952 	memblock_free_overlap_top_check();
953 	memblock_free_overlap_bottom_check();
954 	memblock_free_within_check();
955 
956 	return 0;
957 }
958 
959 int memblock_basic_checks(void)
960 {
961 	memblock_initialization_check();
962 	memblock_add_checks();
963 	memblock_reserve_checks();
964 	memblock_remove_checks();
965 	memblock_free_checks();
966 
967 	return 0;
968 }
969