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