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). It checks if a new entry was created and if region
310   * counter and total memory size were correctly 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  * and checks if two entries were correctly added to the collection of reserved
335  * memory regions (memblock.reserved) and if this change was reflected in
336  * memblock.reserved's total size and region counter.
337  */
338 static int memblock_reserve_disjoint_check(void)
339 {
340 	struct memblock_region *rgn1, *rgn2;
341 
342 	rgn1 = &memblock.reserved.regions[0];
343 	rgn2 = &memblock.reserved.regions[1];
344 
345 	struct region r1 = {
346 		.base = SZ_256M,
347 		.size = SZ_16M
348 	};
349 	struct region r2 = {
350 		.base = SZ_512M,
351 		.size = SZ_512M
352 	};
353 
354 	reset_memblock_regions();
355 	memblock_reserve(r1.base, r1.size);
356 	memblock_reserve(r2.base, r2.size);
357 
358 	assert(rgn1->base == r1.base);
359 	assert(rgn1->size == r1.size);
360 
361 	assert(rgn2->base == r2.base);
362 	assert(rgn2->size == r2.size);
363 
364 	assert(memblock.reserved.cnt == 2);
365 	assert(memblock.reserved.total_size == r1.size + r2.size);
366 
367 	return 0;
368 }
369 
370 /*
371  * A test that tries to mark two memory blocks as reserved, where the
372  * second one overlaps with the beginning of the first (that is
373  * r1.base < r2.base + r2.size).
374  * It checks if two entries are merged into one region that starts at r2.base
375  * and has size of two regions minus their intersection. The test also verifies
376  * that memblock can still see only one entry and has a correct total size of
377  * the reserved memory.
378  */
379 static int memblock_reserve_overlap_top_check(void)
380 {
381 	struct memblock_region *rgn;
382 	phys_addr_t total_size;
383 
384 	rgn = &memblock.reserved.regions[0];
385 
386 	struct region r1 = {
387 		.base = SZ_1G,
388 		.size = SZ_1G
389 	};
390 	struct region r2 = {
391 		.base = SZ_128M,
392 		.size = SZ_1G
393 	};
394 
395 	total_size = (r1.base - r2.base) + r1.size;
396 
397 	reset_memblock_regions();
398 	memblock_reserve(r1.base, r1.size);
399 	memblock_reserve(r2.base, r2.size);
400 
401 	assert(rgn->base == r2.base);
402 	assert(rgn->size == total_size);
403 
404 	assert(memblock.reserved.cnt == 1);
405 	assert(memblock.reserved.total_size == total_size);
406 
407 	return 0;
408 }
409 
410 /*
411  * A test that tries to mark two memory blocks as reserved, where the
412  * second one overlaps with the end of the first entry (that is
413  * r2.base < r1.base + r1.size).
414  * It checks if two entries are merged into one region that starts at r1.base
415  * and has size of two regions minus their intersection. It verifies that
416  * memblock can still see only one entry and has a correct total size of the
417  * reserved memory.
418  */
419 static int memblock_reserve_overlap_bottom_check(void)
420 {
421 	struct memblock_region *rgn;
422 	phys_addr_t total_size;
423 
424 	rgn = &memblock.reserved.regions[0];
425 
426 	struct region r1 = {
427 		.base = SZ_2K,
428 		.size = SZ_128K
429 	};
430 	struct region r2 = {
431 		.base = SZ_128K,
432 		.size = SZ_128K
433 	};
434 
435 	total_size = (r2.base - r1.base) + r2.size;
436 
437 	reset_memblock_regions();
438 	memblock_reserve(r1.base, r1.size);
439 	memblock_reserve(r2.base, r2.size);
440 
441 	assert(rgn->base == r1.base);
442 	assert(rgn->size == total_size);
443 
444 	assert(memblock.reserved.cnt == 1);
445 	assert(memblock.reserved.total_size == total_size);
446 
447 	return 0;
448 }
449 
450 /*
451  * A test that tries to mark two memory blocks as reserved, where the second
452  * one is within the range of the first entry (that is
453  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
454  * It checks if two entries are merged into one region that stays the
455  * same. The counter and total size of available memory are expected to not be
456  * updated.
457  */
458 static int memblock_reserve_within_check(void)
459 {
460 	struct memblock_region *rgn;
461 
462 	rgn = &memblock.reserved.regions[0];
463 
464 	struct region r1 = {
465 		.base = SZ_1M,
466 		.size = SZ_8M
467 	};
468 	struct region r2 = {
469 		.base = SZ_2M,
470 		.size = SZ_64K
471 	};
472 
473 	reset_memblock_regions();
474 	memblock_reserve(r1.base, r1.size);
475 	memblock_reserve(r2.base, r2.size);
476 
477 	assert(rgn->base == r1.base);
478 	assert(rgn->size == r1.size);
479 
480 	assert(memblock.reserved.cnt == 1);
481 	assert(memblock.reserved.total_size == r1.size);
482 
483 	return 0;
484 }
485 
486 /*
487  * A simple test that tries to reserve the same memory block twice.
488  * The region counter and total size of reserved memory are expected to not
489  * be updated.
490  */
491 static int memblock_reserve_twice_check(void)
492 {
493 	struct region r = {
494 		.base = SZ_16K,
495 		.size = SZ_2M
496 	};
497 
498 	reset_memblock_regions();
499 
500 	memblock_reserve(r.base, r.size);
501 	memblock_reserve(r.base, r.size);
502 
503 	assert(memblock.reserved.cnt == 1);
504 	assert(memblock.reserved.total_size == r.size);
505 
506 	return 0;
507 }
508 
509 static int memblock_reserve_checks(void)
510 {
511 	memblock_reserve_simple_check();
512 	memblock_reserve_disjoint_check();
513 	memblock_reserve_overlap_top_check();
514 	memblock_reserve_overlap_bottom_check();
515 	memblock_reserve_within_check();
516 	memblock_reserve_twice_check();
517 
518 	return 0;
519 }
520 
521  /*
522   * A simple test that tries to remove the first entry of the array of
523   * available memory regions. By "removing" a region we mean overwriting it
524   * with the next region in memblock.memory. To check this is the case, the
525   * test adds two memory blocks and verifies that the value of the latter
526   * was used to erase r1 region.  It also checks if the region counter and
527   * total size were updated to expected values.
528   */
529 static int memblock_remove_simple_check(void)
530 {
531 	struct memblock_region *rgn;
532 
533 	rgn = &memblock.memory.regions[0];
534 
535 	struct region r1 = {
536 		.base = SZ_2K,
537 		.size = SZ_4K
538 	};
539 	struct region r2 = {
540 		.base = SZ_128K,
541 		.size = SZ_4M
542 	};
543 
544 	reset_memblock_regions();
545 	memblock_add(r1.base, r1.size);
546 	memblock_add(r2.base, r2.size);
547 	memblock_remove(r1.base, r1.size);
548 
549 	assert(rgn->base == r2.base);
550 	assert(rgn->size == r2.size);
551 
552 	assert(memblock.memory.cnt == 1);
553 	assert(memblock.memory.total_size == r2.size);
554 
555 	return 0;
556 }
557 
558  /*
559   * A test that tries to remove a region that was not registered as available
560   * memory (i.e. has no corresponding entry in memblock.memory). It verifies
561   * that array, regions counter and total size were not modified.
562   */
563 static int memblock_remove_absent_check(void)
564 {
565 	struct memblock_region *rgn;
566 
567 	rgn = &memblock.memory.regions[0];
568 
569 	struct region r1 = {
570 		.base = SZ_512K,
571 		.size = SZ_4M
572 	};
573 	struct region r2 = {
574 		.base = SZ_64M,
575 		.size = SZ_1G
576 	};
577 
578 	reset_memblock_regions();
579 	memblock_add(r1.base, r1.size);
580 	memblock_remove(r2.base, r2.size);
581 
582 	assert(rgn->base == r1.base);
583 	assert(rgn->size == r1.size);
584 
585 	assert(memblock.memory.cnt == 1);
586 	assert(memblock.memory.total_size == r1.size);
587 
588 	return 0;
589 }
590 
591 /*
592  * A test that tries to remove a region which overlaps with the beginning of
593  * the already existing entry r1 (that is r1.base < r2.base + r2.size). It
594  * checks if only the intersection of both regions is removed from the available
595  * memory pool. The test also checks if the regions counter and total size are
596  * updated to expected values.
597  */
598 static int memblock_remove_overlap_top_check(void)
599 {
600 	struct memblock_region *rgn;
601 	phys_addr_t r1_end, r2_end, total_size;
602 
603 	rgn = &memblock.memory.regions[0];
604 
605 	struct region r1 = {
606 		.base = SZ_32M,
607 		.size = SZ_32M
608 	};
609 	struct region r2 = {
610 		.base = SZ_16M,
611 		.size = SZ_32M
612 	};
613 
614 	r1_end = r1.base + r1.size;
615 	r2_end = r2.base + r2.size;
616 	total_size = r1_end - r2_end;
617 
618 	reset_memblock_regions();
619 	memblock_add(r1.base, r1.size);
620 	memblock_remove(r2.base, r2.size);
621 
622 	assert(rgn->base == r1.base + r2.base);
623 	assert(rgn->size == total_size);
624 
625 	assert(memblock.memory.cnt == 1);
626 	assert(memblock.memory.total_size == total_size);
627 
628 	return 0;
629 }
630 
631 /*
632  * A test that tries to remove a region which overlaps with the end of the
633  * first entry (that is r2.base < r1.base + r1.size). It checks if only the
634  * intersection of both regions is removed from the available memory pool.
635  * The test also checks if the regions counter and total size are updated to
636  * expected values.
637  */
638 static int memblock_remove_overlap_bottom_check(void)
639 {
640 	struct memblock_region *rgn;
641 	phys_addr_t total_size;
642 
643 	rgn = &memblock.memory.regions[0];
644 
645 	struct region r1 = {
646 		.base = SZ_2M,
647 		.size = SZ_64M
648 	};
649 	struct region r2 = {
650 		.base = SZ_32M,
651 		.size = SZ_256M
652 	};
653 
654 	total_size = r2.base - r1.base;
655 
656 	reset_memblock_regions();
657 	memblock_add(r1.base, r1.size);
658 	memblock_remove(r2.base, r2.size);
659 
660 	assert(rgn->base == r1.base);
661 	assert(rgn->size == total_size);
662 
663 	assert(memblock.memory.cnt == 1);
664 	assert(memblock.memory.total_size == total_size);
665 	return 0;
666 }
667 
668 /*
669  * A test that tries to remove a region which is within the range of the
670  * already existing entry (that is
671  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
672  * It checks if the region is split into two - one that ends at r2.base and
673  * second that starts at r2.base + size, with appropriate sizes. The test
674  * also checks if the region counter and total size were updated to
675  * expected values.
676  */
677 static int memblock_remove_within_check(void)
678 {
679 	struct memblock_region *rgn1, *rgn2;
680 	phys_addr_t r1_size, r2_size, total_size;
681 
682 	rgn1 = &memblock.memory.regions[0];
683 	rgn2 = &memblock.memory.regions[1];
684 
685 	struct region r1 = {
686 		.base = SZ_1M,
687 		.size = SZ_32M
688 	};
689 	struct region r2 = {
690 		.base = SZ_16M,
691 		.size = SZ_1M
692 	};
693 
694 	r1_size = r2.base - r1.base;
695 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
696 	total_size = r1_size + r2_size;
697 
698 	reset_memblock_regions();
699 	memblock_add(r1.base, r1.size);
700 	memblock_remove(r2.base, r2.size);
701 
702 	assert(rgn1->base == r1.base);
703 	assert(rgn1->size == r1_size);
704 
705 	assert(rgn2->base == r2.base + r2.size);
706 	assert(rgn2->size == r2_size);
707 
708 	assert(memblock.memory.cnt == 2);
709 	assert(memblock.memory.total_size == total_size);
710 
711 	return 0;
712 }
713 
714 static int memblock_remove_checks(void)
715 {
716 	memblock_remove_simple_check();
717 	memblock_remove_absent_check();
718 	memblock_remove_overlap_top_check();
719 	memblock_remove_overlap_bottom_check();
720 	memblock_remove_within_check();
721 
722 	return 0;
723 }
724 
725 /*
726  * A simple test that tries to free a memory block that was marked earlier
727  * as reserved. By "freeing" a region we mean overwriting it with the next
728  * entry in memblock.reserved. To check this is the case, the test reserves
729  * two memory regions and verifies that the value of the latter was used to
730  * erase r1 region.
731  * The test also checks if the region counter and total size were updated.
732  */
733 static int memblock_free_simple_check(void)
734 {
735 	struct memblock_region *rgn;
736 
737 	rgn = &memblock.reserved.regions[0];
738 
739 	struct region r1 = {
740 		.base = SZ_4M,
741 		.size = SZ_1M
742 	};
743 	struct region r2 = {
744 		.base = SZ_8M,
745 		.size = SZ_1M
746 	};
747 
748 	reset_memblock_regions();
749 	memblock_reserve(r1.base, r1.size);
750 	memblock_reserve(r2.base, r2.size);
751 	memblock_free((void *)r1.base, r1.size);
752 
753 	assert(rgn->base == r2.base);
754 	assert(rgn->size == r2.size);
755 
756 	assert(memblock.reserved.cnt == 1);
757 	assert(memblock.reserved.total_size == r2.size);
758 
759 	return 0;
760 }
761 
762  /*
763   * A test that tries to free a region that was not marked as reserved
764   * (i.e. has no corresponding entry in memblock.reserved). It verifies
765   * that array, regions counter and total size were not modified.
766   */
767 static int memblock_free_absent_check(void)
768 {
769 	struct memblock_region *rgn;
770 
771 	rgn = &memblock.reserved.regions[0];
772 
773 	struct region r1 = {
774 		.base = SZ_2M,
775 		.size = SZ_8K
776 	};
777 	struct region r2 = {
778 		.base = SZ_16M,
779 		.size = SZ_128M
780 	};
781 
782 	reset_memblock_regions();
783 	memblock_reserve(r1.base, r1.size);
784 	memblock_free((void *)r2.base, r2.size);
785 
786 	assert(rgn->base == r1.base);
787 	assert(rgn->size == r1.size);
788 
789 	assert(memblock.reserved.cnt == 1);
790 	assert(memblock.reserved.total_size == r1.size);
791 
792 	return 0;
793 }
794 
795 /*
796  * A test that tries to free a region which overlaps with the beginning of
797  * the already existing entry r1 (that is r1.base < r2.base + r2.size). It
798  * checks if only the intersection of both regions is freed. The test also
799  * checks if the regions counter and total size are updated to expected
800  * values.
801  */
802 static int memblock_free_overlap_top_check(void)
803 {
804 	struct memblock_region *rgn;
805 	phys_addr_t total_size;
806 
807 	rgn = &memblock.reserved.regions[0];
808 
809 	struct region r1 = {
810 		.base = SZ_8M,
811 		.size = SZ_32M
812 	};
813 	struct region r2 = {
814 		.base = SZ_1M,
815 		.size = SZ_8M
816 	};
817 
818 	total_size = (r1.size + r1.base) - (r2.base + r2.size);
819 
820 	reset_memblock_regions();
821 	memblock_reserve(r1.base, r1.size);
822 	memblock_free((void *)r2.base, r2.size);
823 
824 	assert(rgn->base == r2.base + r2.size);
825 	assert(rgn->size == total_size);
826 
827 	assert(memblock.reserved.cnt == 1);
828 	assert(memblock.reserved.total_size == total_size);
829 
830 	return 0;
831 }
832 
833 /*
834  * A test that tries to free a region which overlaps with the end of the
835  * first entry (that is r2.base < r1.base + r1.size). It checks if only the
836  * intersection of both regions is freed. The test also checks if the
837  * regions counter and total size are updated to expected values.
838  */
839 static int memblock_free_overlap_bottom_check(void)
840 {
841 	struct memblock_region *rgn;
842 	phys_addr_t total_size;
843 
844 	rgn = &memblock.reserved.regions[0];
845 
846 	struct region r1 = {
847 		.base = SZ_8M,
848 		.size = SZ_32M
849 	};
850 	struct region r2 = {
851 		.base = SZ_32M,
852 		.size = SZ_32M
853 	};
854 
855 	total_size = r2.base - r1.base;
856 
857 	reset_memblock_regions();
858 	memblock_reserve(r1.base, r1.size);
859 	memblock_free((void *)r2.base, r2.size);
860 
861 	assert(rgn->base == r1.base);
862 	assert(rgn->size == total_size);
863 
864 	assert(memblock.reserved.cnt == 1);
865 	assert(memblock.reserved.total_size == total_size);
866 
867 	return 0;
868 }
869 
870 /*
871  * A test that tries to free a region which is within the range of the
872  * already existing entry (that is
873  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
874  * It checks if the region is split into two - one that ends at r2.base and
875  * second that starts at r2.base + size, with appropriate sizes. It is
876  * expected that the region counter and total size fields were updated t
877  * reflect that change.
878  */
879 static int memblock_free_within_check(void)
880 {
881 	struct memblock_region *rgn1, *rgn2;
882 	phys_addr_t r1_size, r2_size, total_size;
883 
884 	rgn1 = &memblock.reserved.regions[0];
885 	rgn2 = &memblock.reserved.regions[1];
886 
887 	struct region r1 = {
888 		.base = SZ_1M,
889 		.size = SZ_8M
890 	};
891 	struct region r2 = {
892 		.base = SZ_4M,
893 		.size = SZ_1M
894 	};
895 
896 	r1_size = r2.base - r1.base;
897 	r2_size = (r1.base + r1.size) - (r2.base + r2.size);
898 	total_size = r1_size + r2_size;
899 
900 	reset_memblock_regions();
901 	memblock_reserve(r1.base, r1.size);
902 	memblock_free((void *)r2.base, r2.size);
903 
904 	assert(rgn1->base == r1.base);
905 	assert(rgn1->size == r1_size);
906 
907 	assert(rgn2->base == r2.base + r2.size);
908 	assert(rgn2->size == r2_size);
909 
910 	assert(memblock.reserved.cnt == 2);
911 	assert(memblock.reserved.total_size == total_size);
912 
913 	return 0;
914 }
915 
916 static int memblock_free_checks(void)
917 {
918 	memblock_free_simple_check();
919 	memblock_free_absent_check();
920 	memblock_free_overlap_top_check();
921 	memblock_free_overlap_bottom_check();
922 	memblock_free_within_check();
923 
924 	return 0;
925 }
926 
927 int memblock_basic_checks(void)
928 {
929 	memblock_initialization_check();
930 	memblock_add_checks();
931 	memblock_reserve_checks();
932 	memblock_remove_checks();
933 	memblock_free_checks();
934 
935 	return 0;
936 }
937