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