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