1 /*
2  * Copyright (c) 2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 
10 #include <zephyr/sys/heap_listener.h>
11 #include <zephyr/sys/mem_blocks.h>
12 #include <zephyr/sys/util.h>
13 
14 #define BLK_SZ     64
15 #define NUM_BLOCKS 8
16 
17 SYS_MEM_BLOCKS_DEFINE(mem_block_01, BLK_SZ, NUM_BLOCKS, 4);
18 
19 static uint8_t mem_block_02_buf[BLK_SZ * NUM_BLOCKS];
20 SYS_MEM_BLOCKS_DEFINE_STATIC_WITH_EXT_BUF(mem_block_02,
21 					  BLK_SZ, NUM_BLOCKS,
22 					  mem_block_02_buf);
23 
24 static sys_multi_mem_blocks_t alloc_group;
25 
26 static ZTEST_DMEM volatile int expected_reason = -1;
27 
k_sys_fatal_error_handler(unsigned int reason,const z_arch_esf_t * pEsf)28 void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
29 {
30 	printk("Caught system error -- reason %d\n", reason);
31 
32 	if (expected_reason == -1) {
33 		printk("Was not expecting a crash\n");
34 		ztest_test_fail();
35 	}
36 
37 	if (reason != expected_reason) {
38 		printk("Wrong crash type got %d expected %d\n", reason,
39 		       expected_reason);
40 		ztest_test_fail();
41 	}
42 
43 	expected_reason = -1;
44 	ztest_test_pass();
45 }
46 
choice_fn(struct sys_multi_mem_blocks * group,void * cfg)47 sys_mem_blocks_t *choice_fn(struct sys_multi_mem_blocks *group, void *cfg)
48 {
49 	/* mem_block_"01" or mem_block_"02" */
50 	uintptr_t num = POINTER_TO_UINT(cfg) - 1;
51 
52 	if (num >= group->num_allocators) {
53 		return NULL;
54 	} else {
55 		return group->allocators[num];
56 	}
57 }
58 
check_buffer_bound(sys_mem_blocks_t * mem_block,void * ptr)59 static bool check_buffer_bound(sys_mem_blocks_t *mem_block, void *ptr)
60 {
61 	uint8_t *start, *end, *ptr_u8;
62 
63 	start = mem_block->buffer;
64 	end = start + (BIT(mem_block->info.blk_sz_shift) *
65 		       mem_block->info.num_blocks);
66 
67 	ptr_u8 = (uint8_t *)ptr;
68 
69 	if ((ptr_u8 >= start) && (ptr_u8 < end)) {
70 		return true;
71 	} else {
72 		return false;
73 	}
74 }
75 
76 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
77 #define HEAP_LISTENER_LOG_SIZE 64
78 
79 static uintptr_t listener_heap_id[HEAP_LISTENER_LOG_SIZE];
80 static void *listener_mem[HEAP_LISTENER_LOG_SIZE];
81 static size_t listener_size[HEAP_LISTENER_LOG_SIZE];
82 static uint8_t listener_idx;
83 
mem_block_alloc_free_cb(uintptr_t heap_id,void * mem,size_t bytes)84 static void mem_block_alloc_free_cb(uintptr_t heap_id, void *mem, size_t bytes)
85 {
86 	listener_heap_id[listener_idx] = heap_id;
87 	listener_mem[listener_idx] = mem;
88 	listener_size[listener_idx] = bytes;
89 
90 #ifdef CONFIG_DEBUG
91 	TC_PRINT("[%u] Heap 0x%" PRIxPTR ", alloc %p, size %u\n",
92 		 listener_idx, heap_id, mem, (uint32_t)bytes);
93 #endif
94 
95 	listener_idx++;
96 }
97 
98 HEAP_LISTENER_ALLOC_DEFINE(mem_block_01_alloc,
99 			   HEAP_ID_FROM_POINTER(&mem_block_01),
100 			   mem_block_alloc_free_cb);
101 
102 HEAP_LISTENER_FREE_DEFINE(mem_block_01_free,
103 			  HEAP_ID_FROM_POINTER(&mem_block_01),
104 			  mem_block_alloc_free_cb);
105 
106 HEAP_LISTENER_ALLOC_DEFINE(mem_block_02_alloc,
107 			   HEAP_ID_FROM_POINTER(&mem_block_02),
108 			   mem_block_alloc_free_cb);
109 
110 HEAP_LISTENER_FREE_DEFINE(mem_block_02_free,
111 			  HEAP_ID_FROM_POINTER(&mem_block_02),
112 			  mem_block_alloc_free_cb);
113 #endif /* CONFIG_SYS_MEM_BLOCKS_LISTENER */
114 
alloc_free(sys_mem_blocks_t * mem_block,int num_blocks,int num_iters)115 static void alloc_free(sys_mem_blocks_t *mem_block,
116 		       int num_blocks, int num_iters)
117 {
118 	int i, j, ret;
119 	void *blocks[NUM_BLOCKS][1];
120 	int val;
121 
122 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
123 	if (mem_block == &mem_block_01) {
124 		heap_listener_register(&mem_block_01_alloc);
125 		heap_listener_register(&mem_block_01_free);
126 	} else if (mem_block == &mem_block_02) {
127 		heap_listener_register(&mem_block_02_alloc);
128 		heap_listener_register(&mem_block_02_free);
129 	}
130 #endif
131 
132 	for (j = 0; j < num_iters; j++) {
133 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
134 		listener_idx = 0;
135 #endif
136 
137 		for (i = 0; i < num_blocks; i++) {
138 			ret = sys_mem_blocks_alloc(mem_block, 1, blocks[i]);
139 			zassert_equal(ret, 0,
140 				      "sys_mem_blocks_alloc failed (%d)", ret);
141 
142 			zassert_true(check_buffer_bound(mem_block, blocks[i][0]),
143 				     "allocated memory is out of bound");
144 
145 			ret = sys_bitarray_test_bit(mem_block->bitmap,
146 						    i, &val);
147 			zassert_equal(ret, 0, "API failure");
148 			zassert_equal(val, 1,
149 				      "sys_mem_blockss_alloc bitmap failed");
150 
151 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
152 			zassert_equal(listener_heap_id[i],
153 				      HEAP_ID_FROM_POINTER(mem_block),
154 				      "Heap ID mismatched: 0x%lx != %p",
155 				      listener_heap_id[i], mem_block);
156 			zassert_equal(listener_mem[i], blocks[i][0],
157 				      "Heap allocated pointer mismatched: %p != %p",
158 				      listener_mem[i], blocks[i][0]);
159 			zassert_equal(listener_size[i],
160 				      BIT(mem_block->info.blk_sz_shift),
161 				      "Heap allocated sized: %u != %u",
162 				      listener_size[i],
163 				      BIT(mem_block->info.blk_sz_shift));
164 #endif
165 		}
166 
167 		if (num_blocks >= NUM_BLOCKS) {
168 			ret = sys_mem_blocks_alloc(mem_block, 1, blocks[i]);
169 			zassert_equal(ret, -ENOMEM,
170 				"sys_mem_blocks_alloc should fail with -ENOMEM but not");
171 		}
172 
173 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
174 		listener_idx = 0;
175 #endif
176 
177 		for (i = 0; i < num_blocks; i++) {
178 			ret = sys_mem_blocks_free(mem_block, 1, blocks[i]);
179 			zassert_equal(ret, 0,
180 				      "sys_mem_blocks_free failed (%d)", ret);
181 
182 			ret = sys_bitarray_test_bit(mem_block->bitmap,
183 						    i, &val);
184 			zassert_equal(ret, 0, "API failure");
185 			zassert_equal(val, 0,
186 				      "sys_mem_blocks_free bitmap failed");
187 
188 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
189 			zassert_equal(listener_heap_id[i],
190 				      HEAP_ID_FROM_POINTER(mem_block),
191 				      "Heap ID mismatched: 0x%lx != %p",
192 				      listener_heap_id[i], mem_block);
193 			zassert_equal(listener_mem[i], blocks[i][0],
194 				      "Heap allocated pointer mismatched: %p != %p",
195 				      listener_mem[i], blocks[i][0]);
196 			zassert_equal(listener_size[i],
197 				      BIT(mem_block->info.blk_sz_shift),
198 				      "Heap allocated sized: %u != %u",
199 				      listener_size[i],
200 				      BIT(mem_block->info.blk_sz_shift));
201 #endif
202 		}
203 	}
204 
205 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
206 	if (mem_block == &mem_block_01) {
207 		heap_listener_unregister(&mem_block_01_alloc);
208 		heap_listener_unregister(&mem_block_01_free);
209 	} else if (mem_block == &mem_block_02) {
210 		heap_listener_unregister(&mem_block_02_alloc);
211 		heap_listener_unregister(&mem_block_02_free);
212 	}
213 #endif
214 }
215 
ZTEST(lib_mem_block,test_mem_block_alloc_free)216 ZTEST(lib_mem_block, test_mem_block_alloc_free)
217 {
218 	alloc_free(&mem_block_01, 1, 1);
219 }
220 
ZTEST(lib_mem_block,test_mem_block_alloc_free_alt_buf)221 ZTEST(lib_mem_block, test_mem_block_alloc_free_alt_buf)
222 {
223 	alloc_free(&mem_block_02, 1, 1);
224 }
225 
ZTEST(lib_mem_block,test_mem_block_multi_alloc_free)226 ZTEST(lib_mem_block, test_mem_block_multi_alloc_free)
227 {
228 	alloc_free(&mem_block_01, NUM_BLOCKS, 10);
229 }
230 
ZTEST(lib_mem_block,test_mem_block_multi_alloc_free_alt_buf)231 ZTEST(lib_mem_block, test_mem_block_multi_alloc_free_alt_buf)
232 {
233 	alloc_free(&mem_block_02, NUM_BLOCKS, 10);
234 }
235 
ZTEST(lib_mem_block,test_mem_block_get)236 ZTEST(lib_mem_block, test_mem_block_get)
237 {
238 	int i, ret, val;
239 
240 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
241 	listener_idx = 0;
242 	heap_listener_register(&mem_block_01_alloc);
243 	heap_listener_register(&mem_block_01_free);
244 #endif
245 
246 	/* get a 2 entiries memory block starting from 0 */
247 	ret = sys_mem_blocks_get(&mem_block_01, mem_block_01.buffer, 2);
248 	zassert_equal(ret, 0,
249 		      "sys_mem_blocks_get failed (%d)", ret);
250 
251 	/* blocks 0 and 1 should be taken */
252 	for (i = 0; i < NUM_BLOCKS; i++) {
253 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
254 					    i, &val);
255 		zassert_equal(ret, 0, "API failure");
256 		switch (i) {
257 		case 0:
258 		case 1:
259 			zassert_equal(val, 1,
260 			      "sys_mem_blocks_get bitmap failed, bit %i should be set", i);
261 			break;
262 		default:
263 			zassert_equal(val, 0,
264 			     "sys_mem_blocks_get bitmap failed, bit %i should be cleared", i);
265 			break;
266 
267 		}
268 	}
269 
270 	/* get a 2 entiries memory block starting from 1 - should fail  */
271 	ret = sys_mem_blocks_get(&mem_block_01, mem_block_01.buffer + BLK_SZ, 2);
272 	zassert_equal(ret, -ENOMEM,
273 		      "sys_mem_blocks_get failed (%d), memory block taken twice", ret);
274 
275 	/* blocks 0 and 1 should be taken */
276 	for (i = 0; i < NUM_BLOCKS; i++) {
277 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
278 					    i, &val);
279 		zassert_equal(ret, 0, "API failure");
280 		switch (i) {
281 		case 0:
282 		case 1:
283 			zassert_equal(val, 1,
284 			     "sys_mem_blocks_get bitmap failed, bit %i should be set", i);
285 			break;
286 		default:
287 			zassert_equal(val, 0,
288 			     "sys_mem_blocks_get bitmap failed, bit %i should be cleared", i);
289 			break;
290 
291 		}
292 	}
293 
294 	/* get a 2 slots block starting from the last one - should fail */
295 	ret = sys_mem_blocks_get(&mem_block_01, mem_block_01.buffer + (BLK_SZ * (NUM_BLOCKS-1)), 2);
296 	zassert_equal(ret, -ENOMEM,
297 		      "sys_mem_blocks_get failed - out of bounds (%d)", ret);
298 
299 	/* blocks 0 and 1 should be taken */
300 	for (i = 0; i < NUM_BLOCKS; i++) {
301 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
302 					    i, &val);
303 		zassert_equal(ret, 0, "API failure");
304 		switch (i) {
305 		case 0:
306 		case 1:
307 			zassert_equal(val, 1,
308 			     "sys_mem_blocks_get bitmap failed, bit %i should be set", i);
309 			break;
310 		default:
311 			zassert_equal(val, 0,
312 			     "sys_mem_blocks_get bitmap failed, bit %i should be cleared", i);
313 			break;
314 
315 		}
316 	}
317 
318 	/* get a 1 slots block starting from 3 */
319 	ret = sys_mem_blocks_get(&mem_block_01, mem_block_01.buffer + (BLK_SZ * 3), 1);
320 	zassert_equal(ret, 0,
321 		      "sys_mem_blocks_get failed (%d)", ret);
322 
323 	/* blocks 0,1,3 should be taken */
324 	for (i = 0; i < NUM_BLOCKS; i++) {
325 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
326 					    i, &val);
327 		zassert_equal(ret, 0, "API failure");
328 		switch (i) {
329 		case 0:
330 		case 1:
331 		case 3:
332 			zassert_equal(val, 1,
333 			     "sys_mem_blocks_get bitmap failed, bit %i should be set", i);
334 			break;
335 		default:
336 			zassert_equal(val, 0,
337 			     "sys_mem_blocks_get bitmap failed, bit %i should be cleared", i);
338 			break;
339 		}
340 	}
341 
342 	/* get a 1 slots block starting from 2 */
343 	ret = sys_mem_blocks_get(&mem_block_01, mem_block_01.buffer + (BLK_SZ * 2), 1);
344 	zassert_equal(ret, 0,
345 		      "sys_mem_blocks_get failed (%d)", ret);
346 
347 	/* blocks 0,1,2, 3 should be taken */
348 	for (i = 0; i < NUM_BLOCKS; i++) {
349 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
350 					    i, &val);
351 		zassert_equal(ret, 0, "API failure");
352 		switch (i) {
353 		case 0:
354 		case 1:
355 		case 2:
356 		case 3:
357 			zassert_equal(val, 1,
358 			     "sys_mem_blocks_get bitmap failed, bit %i should be set", i);
359 			break;
360 		default:
361 			zassert_equal(val, 0,
362 			     "sys_mem_blocks_get bitmap failed, bit %i should be cleared", i);
363 			break;
364 		}
365 	}
366 
367 	/* cleanup - free all blocks */
368 	ret = sys_mem_blocks_free_contiguous(&mem_block_01, mem_block_01.buffer, 4);
369 	zassert_equal(ret, 0,
370 		      "sys_mem_blocks_get failed (%d)", ret);
371 
372 	/* all blocks should be cleared */
373 	for (i = 0; i < NUM_BLOCKS; i++) {
374 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
375 					    i, &val);
376 		zassert_equal(ret, 0, "API failure");
377 		zassert_equal(val, 0,
378 		     "sys_mem_blocks_get bitmap failed, bit %i should be cleared", i);
379 	}
380 
381 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
382 	heap_listener_unregister(&mem_block_01_alloc);
383 	heap_listener_unregister(&mem_block_01_free);
384 
385 	/* verify alloc/free log */
386 	zassert_equal(listener_mem[0], mem_block_01.buffer,
387 			"sys_mem_blocks_get bitmap failed, %p != %p",
388 			listener_mem[0], mem_block_01.buffer);
389 	zassert_equal(listener_size[0], BLK_SZ*2,
390 			"sys_mem_blocks_get bitmap failed, %u != %u",
391 			listener_size[0], BLK_SZ*2);
392 
393 	zassert_equal(listener_mem[1], mem_block_01.buffer + BLK_SZ*3,
394 			"sys_mem_blocks_get bitmap failed, %p != %p",
395 			listener_mem[1], mem_block_01.buffer + BLK_SZ*2);
396 	zassert_equal(listener_size[1], BLK_SZ,
397 			"sys_mem_blocks_get bitmap failed, %u != %u",
398 			listener_size[1], BLK_SZ);
399 
400 	zassert_equal(listener_mem[2], mem_block_01.buffer + BLK_SZ*2,
401 			"sys_mem_blocks_get bitmap failed, %p != %p",
402 			listener_mem[2], mem_block_01.buffer + BLK_SZ);
403 	zassert_equal(listener_size[2], BLK_SZ,
404 			"sys_mem_blocks_get bitmap failed, %u != %u",
405 			listener_size[2], BLK_SZ);
406 
407 	zassert_equal(listener_mem[3], mem_block_01.buffer,
408 			"sys_mem_blocks_get bitmap failed, %p != %p",
409 			listener_mem[3], mem_block_01.buffer);
410 	zassert_equal(listener_size[3], BLK_SZ*4,
411 			"sys_mem_blocks_get bitmap failed, %u != %u",
412 			listener_size[3], BLK_SZ*4);
413 
414 #endif
415 }
416 
ZTEST(lib_mem_block,test_mem_block_alloc_free_contiguous)417 ZTEST(lib_mem_block, test_mem_block_alloc_free_contiguous)
418 {
419 	int i, ret, val;
420 	void *block;
421 
422 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
423 	listener_idx = 0;
424 	heap_listener_register(&mem_block_01_alloc);
425 	heap_listener_register(&mem_block_01_free);
426 #endif
427 
428 	/* allocate all available blocks */
429 	ret = sys_mem_blocks_alloc_contiguous(&mem_block_01, NUM_BLOCKS, &block);
430 	zassert_equal(ret, 0,
431 		      "sys_mem_blocks_alloc_contiguous failed (%d)", ret);
432 
433 	/* all blocks should be taken */
434 	for (i = 0; i < NUM_BLOCKS; i++) {
435 		ret = sys_bitarray_test_bit(mem_block_01.bitmap, i, &val);
436 		zassert_equal(val, 1,
437 		     "sys_mem_blocks_alloc_contiguous failed, bit %i should be set", i);
438 	}
439 
440 	/* free first 3 memory blocks, use a pointer provided by previous case */
441 	ret = sys_mem_blocks_free_contiguous(&mem_block_01, block, 3);
442 	zassert_equal(ret, 0,
443 		      "sys_mem_blocks_free_contiguous failed (%d)", ret);
444 
445 	/* all blocks extept 0,1,2 should be taken */
446 	for (i = 0; i < NUM_BLOCKS; i++) {
447 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
448 					    i, &val);
449 		switch (i) {
450 		case 0:
451 		case 1:
452 		case 2:
453 			zassert_equal(val, 0,
454 			     "sys_mem_blocks_alloc_contiguous failed, bit %i should be cleared", i);
455 			break;
456 		default:
457 			zassert_equal(val, 1,
458 			     "sys_mem_blocks_alloc_contiguous failed, bit %i should be set", i);
459 			break;
460 		}
461 	}
462 
463 	/* free a memory block, starting from 4, size 4 */
464 	ret = sys_mem_blocks_free_contiguous(&mem_block_01, mem_block_01.buffer+BLK_SZ*4, 4);
465 	zassert_equal(ret, 0,
466 		      "sys_mem_blocks_free_contiguous failed (%d)", ret);
467 
468 	/* all blocks extept 0,1,2,4,5,6,7 should be taken */
469 	for (i = 0; i < NUM_BLOCKS; i++) {
470 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
471 					    i, &val);
472 		switch (i) {
473 		case 0:
474 		case 1:
475 		case 2:
476 		case 4:
477 		case 5:
478 		case 6:
479 		case 7:
480 			zassert_equal(val, 0,
481 			     "sys_mem_blocks_alloc_contiguous failed, bit %i should be cleared", i);
482 			break;
483 		default:
484 			zassert_equal(val, 1,
485 			     "sys_mem_blocks_alloc_contiguous failed, bit %i should be set", i);
486 			break;
487 		}
488 	}
489 
490 	/* at this point, regardless of the memory size, there are 2 free continuous blocks
491 	 * sizes: 3 and 4 slots.
492 	 * try to allocate 5 blocks, should fail
493 	 */
494 	ret = sys_mem_blocks_alloc_contiguous(&mem_block_01, 5, &block);
495 	zassert_equal(ret, -ENOMEM,
496 		      "sys_mem_blocks_free_contiguous failed (%d)", ret);
497 
498 
499 	/* allocate 3 blocks */
500 	ret = sys_mem_blocks_alloc_contiguous(&mem_block_01, 3, &block);
501 	zassert_equal(ret, 0,
502 		      "sys_mem_blocks_free_contiguous failed (%d)", ret);
503 	/* all blocks extept 4,5,6,7 should be taken */
504 	for (i = 0; i < NUM_BLOCKS; i++) {
505 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
506 					    i, &val);
507 		switch (i) {
508 		case 4:
509 		case 5:
510 		case 6:
511 		case 7:
512 			zassert_equal(val, 0,
513 			     "sys_mem_blocks_alloc_contiguous failed, bit %i should be cleared", i);
514 			break;
515 		default:
516 			zassert_equal(val, 1,
517 			     "sys_mem_blocks_alloc_contiguous failed, bit %i should be set", i);
518 			break;
519 		}
520 	}
521 
522 	/* allocate 4 blocks */
523 	ret = sys_mem_blocks_alloc_contiguous(&mem_block_01, 4, &block);
524 	zassert_equal(ret, 0,
525 		      "sys_mem_blocks_free_contiguous failed (%d)", ret);
526 	/* all blocks  should be taken */
527 	for (i = 0; i < NUM_BLOCKS; i++) {
528 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
529 					    i, &val);
530 		zassert_equal(val, 1,
531 		     "sys_mem_blocks_alloc_contiguous failed, bit %i should be set", i);
532 	}
533 
534 	/* cleanup - free all blocks */
535 	ret = sys_mem_blocks_free_contiguous(&mem_block_01, mem_block_01.buffer, NUM_BLOCKS);
536 	zassert_equal(ret, 0,
537 		      "sys_mem_blocks_alloc_contiguous failed (%d)", ret);
538 
539 	/* all blocks should be cleared */
540 	for (i = 0; i < NUM_BLOCKS; i++) {
541 		ret = sys_bitarray_test_bit(mem_block_01.bitmap,
542 					    i, &val);
543 		zassert_equal(val, 0,
544 		     "sys_mem_blocks_alloc_contiguous failed, bit %i should be cleared", i);
545 	}
546 
547 #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
548 	heap_listener_unregister(&mem_block_01_alloc);
549 	heap_listener_unregister(&mem_block_01_free);
550 
551 	/* verify alloc/free log */
552 	zassert_equal(listener_mem[0], mem_block_01.buffer,
553 			"sys_mem_blocks_alloc_contiguous failed, %p != %p",
554 			listener_mem[0], mem_block_01.buffer);
555 	zassert_equal(listener_size[0], BLK_SZ*NUM_BLOCKS,
556 			"sys_mem_blocks_alloc_contiguous failed, %u != %u",
557 			listener_size[0], BLK_SZ*NUM_BLOCKS);
558 
559 	zassert_equal(listener_mem[1], mem_block_01.buffer,
560 			"sys_mem_blocks_alloc_contiguous failed, %p != %p",
561 			listener_mem[1], mem_block_01.buffer);
562 	zassert_equal(listener_size[1], BLK_SZ*3,
563 			"sys_mem_blocks_alloc_contiguous failed, %u != %u",
564 			listener_size[1], BLK_SZ*3);
565 
566 	zassert_equal(listener_mem[2], mem_block_01.buffer+BLK_SZ*4,
567 			"sys_mem_blocks_alloc_contiguous failed, %p != %p",
568 			listener_mem[2], mem_block_01.buffer+BLK_SZ*4);
569 	zassert_equal(listener_size[2], BLK_SZ*4,
570 			"sys_mem_blocks_alloc_contiguous failed, %u != %u",
571 			listener_size[2], BLK_SZ*4);
572 
573 	zassert_equal(listener_mem[3], mem_block_01.buffer,
574 			"sys_mem_blocks_alloc_contiguous failed, %p != %p",
575 			listener_mem[3], mem_block_01.buffer);
576 	zassert_equal(listener_size[3], BLK_SZ*3,
577 			"sys_mem_blocks_alloc_contiguous failed, %u != %u",
578 			listener_size[3], BLK_SZ*3);
579 
580 	zassert_equal(listener_mem[4], mem_block_01.buffer+BLK_SZ*4,
581 			"sys_mem_blocks_alloc_contiguous failed, %p != %p",
582 			listener_mem[4], mem_block_01.buffer+BLK_SZ*4);
583 	zassert_equal(listener_size[4], BLK_SZ*4,
584 			"sys_mem_blocks_alloc_contiguous failed, %u != %u",
585 			listener_size[4], BLK_SZ*4);
586 
587 	zassert_equal(listener_mem[5], mem_block_01.buffer,
588 			"sys_mem_blocks_alloc_contiguous failed, %p != %p",
589 			listener_mem[5], mem_block_01.buffer);
590 	zassert_equal(listener_size[5], BLK_SZ*NUM_BLOCKS,
591 			"sys_mem_blocks_alloc_contiguous failed, %u != %u",
592 			listener_size[5], BLK_SZ*NUM_BLOCKS);
593 #endif
594 }
595 
ZTEST(lib_mem_block,test_multi_mem_block_alloc_free)596 ZTEST(lib_mem_block, test_multi_mem_block_alloc_free)
597 {
598 	int ret;
599 	void *blocks[2][1] = {0};
600 	size_t blk_size;
601 
602 	ret = sys_multi_mem_blocks_alloc(&alloc_group, UINT_TO_POINTER(16),
603 					 1, blocks[0], &blk_size);
604 	zassert_equal(ret, -EINVAL,
605 		      "sys_multi_mem_blocks_alloc should fail with -EINVAL but not");
606 
607 	ret = sys_multi_mem_blocks_alloc(&alloc_group, UINT_TO_POINTER(1),
608 					 1, blocks[0], &blk_size);
609 	zassert_equal(ret, 0,
610 		      "sys_multi_mem_blocks_alloc failed (%d)", ret);
611 	zassert_true(check_buffer_bound(&mem_block_01, blocks[0][0]),
612 		     "allocated memory is out of bound");
613 	zassert_equal(blk_size, BLK_SZ,
614 		      "returned block size is not %d", BLK_SZ);
615 
616 	ret = sys_multi_mem_blocks_alloc(&alloc_group, UINT_TO_POINTER(2),
617 					 1, blocks[1], &blk_size);
618 	zassert_equal(ret, 0,
619 		      "sys_multi_mem_blocks_alloc failed (%d)", ret);
620 	zassert_true(check_buffer_bound(&mem_block_02, blocks[1][0]),
621 		     "allocated memory is out of bound");
622 	zassert_equal(blk_size, BLK_SZ,
623 		      "returned block size is not %d", BLK_SZ);
624 
625 	ret = sys_multi_mem_blocks_free(&alloc_group, 1, blocks[0]);
626 	zassert_equal(ret, 0,
627 		      "sys_multi_mem_blocks_free failed (%d)", ret);
628 
629 	ret = sys_multi_mem_blocks_free(&alloc_group, 1, blocks[1]);
630 	zassert_equal(ret, 0,
631 		      "sys_multi_mem_blocks_free failed (%d)", ret);
632 }
633 
ZTEST(lib_mem_block,test_mem_block_invalid_params_panic_1)634 ZTEST(lib_mem_block, test_mem_block_invalid_params_panic_1)
635 {
636 	void *blocks[2] = {0};
637 
638 	expected_reason = K_ERR_KERNEL_PANIC;
639 	sys_mem_blocks_alloc(NULL, 1, blocks);
640 
641 	/* test should raise an exception and should not reach this line */
642 	ztest_test_fail();
643 }
644 
ZTEST(lib_mem_block,test_mem_block_invalid_params_panic_2)645 ZTEST(lib_mem_block, test_mem_block_invalid_params_panic_2)
646 {
647 	expected_reason = K_ERR_KERNEL_PANIC;
648 	sys_mem_blocks_alloc(&mem_block_01, 1, NULL);
649 
650 	/* test should raise an exception and should not reach this line */
651 	ztest_test_fail();
652 }
653 
ZTEST(lib_mem_block,test_mem_block_invalid_params_panic_3)654 ZTEST(lib_mem_block, test_mem_block_invalid_params_panic_3)
655 {
656 	void *blocks[2] = {0};
657 
658 	expected_reason = K_ERR_KERNEL_PANIC;
659 	sys_mem_blocks_free(NULL, 1, blocks);
660 
661 	/* test should raise an exception and should not reach this line */
662 	ztest_test_fail();
663 }
664 
ZTEST(lib_mem_block,test_mem_block_invalid_params_panic_4)665 ZTEST(lib_mem_block, test_mem_block_invalid_params_panic_4)
666 {
667 	expected_reason = K_ERR_KERNEL_PANIC;
668 	sys_mem_blocks_free(&mem_block_01, 1, NULL);
669 
670 	/* test should raise an exception and should not reach this line */
671 	ztest_test_fail();
672 }
673 
ZTEST(lib_mem_block,test_mem_block_invalid_params)674 ZTEST(lib_mem_block, test_mem_block_invalid_params)
675 {
676 	int ret;
677 	void *blocks[2] = {0};
678 
679 	ret = sys_mem_blocks_alloc(&mem_block_01, 0, blocks);
680 	zassert_equal(ret, 0,
681 		      "sys_mem_blocks_alloc failed (%d)", ret);
682 
683 	ret = sys_mem_blocks_alloc(&mem_block_01, NUM_BLOCKS + 1, blocks);
684 	zassert_equal(ret, -ENOMEM,
685 		      "sys_mem_blocks_alloc should fail with -ENOMEM but not");
686 
687 	ret = sys_mem_blocks_alloc(&mem_block_01, 1, blocks);
688 	zassert_equal(ret, 0,
689 		      "sys_mem_blocks_alloc failed (%d)", ret);
690 
691 	ret = sys_mem_blocks_free(&mem_block_01, 0, blocks);
692 	zassert_equal(ret, 0,
693 		      "sys_mem_blocks_free failed (%d)", ret);
694 
695 	ret = sys_mem_blocks_free(&mem_block_01, NUM_BLOCKS + 1, blocks);
696 	zassert_equal(ret, -EINVAL,
697 		      "sys_mem_blocks_free should fail with -EINVAL but not");
698 
699 	ret = sys_mem_blocks_free(&mem_block_01, 1, blocks);
700 	zassert_equal(ret, 0,
701 		      "sys_mem_blocks_free failed (%d)", ret);
702 
703 	ret = sys_mem_blocks_free(&mem_block_01, 1, blocks);
704 	zassert_equal(ret, -EFAULT,
705 		      "sys_mem_blocks_free should fail with -EFAULT but not");
706 
707 	/* Fake a pointer */
708 	blocks[0] = mem_block_01.buffer +
709 			(BIT(mem_block_01.info.blk_sz_shift) *
710 			 mem_block_01.info.num_blocks);
711 	ret = sys_mem_blocks_free(&mem_block_01, 1, blocks);
712 	zassert_equal(ret, -EFAULT,
713 		      "sys_mem_blocks_free should fail with -EFAULT but not");
714 }
715 
ZTEST(lib_mem_block,test_multi_mem_block_invalid_params_panic_1)716 ZTEST(lib_mem_block, test_multi_mem_block_invalid_params_panic_1)
717 {
718 	void *blocks[2] = {0};
719 
720 	expected_reason = K_ERR_KERNEL_PANIC;
721 	sys_multi_mem_blocks_alloc(NULL, UINT_TO_POINTER(16),
722 						 1, blocks, NULL);
723 
724 	/* test should raise an exception and should not reach this line */
725 	ztest_test_fail();
726 }
727 
728 
ZTEST(lib_mem_block,test_multi_mem_block_invalid_params_panic_2)729 ZTEST(lib_mem_block, test_multi_mem_block_invalid_params_panic_2)
730 {
731 	expected_reason = K_ERR_KERNEL_PANIC;
732 
733 	sys_multi_mem_blocks_alloc(&alloc_group, UINT_TO_POINTER(16),
734 						 1, NULL, NULL);
735 
736 	/* test should raise an exception and should not reach this line */
737 	ztest_test_fail();
738 }
739 
ZTEST(lib_mem_block,test_multi_mem_block_invalid_params_panic_3)740 ZTEST(lib_mem_block, test_multi_mem_block_invalid_params_panic_3)
741 {
742 	void *blocks[2] = {0};
743 
744 	expected_reason = K_ERR_KERNEL_PANIC;
745 	sys_multi_mem_blocks_free(NULL, 1, blocks);
746 
747 	/* test should raise an exception and should not reach this line */
748 	ztest_test_fail();
749 }
750 
751 
ZTEST(lib_mem_block,test_multi_mem_block_invalid_params_panic_4)752 ZTEST(lib_mem_block, test_multi_mem_block_invalid_params_panic_4)
753 {
754 	expected_reason = K_ERR_KERNEL_PANIC;
755 
756 	sys_multi_mem_blocks_free(&alloc_group, 1, NULL);
757 
758 	/* test should raise an exception and should not reach this line */
759 	ztest_test_fail();
760 }
761 
ZTEST(lib_mem_block,test_multi_mem_block_invalid_params)762 ZTEST(lib_mem_block, test_multi_mem_block_invalid_params)
763 {
764 	int ret;
765 	void *blocks[2] = {0};
766 
767 	ret = sys_multi_mem_blocks_alloc(&alloc_group, UINT_TO_POINTER(16),
768 					 0, blocks, NULL);
769 	zassert_equal(ret, 0,
770 		      "sys_multi_mem_blocks_alloc failed (%d)", ret);
771 
772 	ret = sys_multi_mem_blocks_alloc(&alloc_group, UINT_TO_POINTER(1),
773 					 NUM_BLOCKS + 1, blocks, NULL);
774 	zassert_equal(ret, -ENOMEM,
775 		      "sys_multi_mem_blocks_alloc should fail with -ENOMEM but not");
776 
777 	ret = sys_multi_mem_blocks_alloc(&alloc_group, UINT_TO_POINTER(1),
778 					 1, blocks, NULL);
779 	zassert_equal(ret, 0,
780 		      "sys_multi_mem_blocks_alloc failed (%d)", ret);
781 
782 	ret = sys_multi_mem_blocks_free(&alloc_group, 0, blocks);
783 	zassert_equal(ret, 0,
784 		      "sys_multi_mem_blocks_free failed (%d)", ret);
785 
786 	ret = sys_multi_mem_blocks_free(&alloc_group, NUM_BLOCKS + 1, blocks);
787 	zassert_equal(ret, -EINVAL,
788 		      "sys_multi_mem_blocks_free should fail with -EINVAL but not");
789 
790 	ret = sys_multi_mem_blocks_free(&alloc_group, 1, blocks);
791 	zassert_equal(ret, 0,
792 		      "sys_multi_mem_blocks_free failed (%d)", ret);
793 
794 	ret = sys_multi_mem_blocks_free(&alloc_group, 1, blocks);
795 	zassert_equal(ret, -EFAULT,
796 		      "sys_multi_mem_blocks_free should fail with -EFAULT but not");
797 
798 	/* Fake a pointer */
799 	blocks[0] = mem_block_01.buffer +
800 			(BIT(mem_block_01.info.blk_sz_shift) *
801 			 mem_block_01.info.num_blocks);
802 	ret = sys_multi_mem_blocks_free(&alloc_group, 1, blocks);
803 	zassert_equal(ret, -EINVAL,
804 		      "sys_multi_mem_blocks_free should fail with -EINVAL but not");
805 }
806 
lib_mem_block_setup(void)807 static void *lib_mem_block_setup(void)
808 {
809 	sys_multi_mem_blocks_init(&alloc_group, choice_fn);
810 	sys_multi_mem_blocks_add_allocator(&alloc_group, &mem_block_01);
811 	sys_multi_mem_blocks_add_allocator(&alloc_group, &mem_block_02);
812 	return NULL;
813 }
814 
815 ZTEST_SUITE(lib_mem_block, NULL, lib_mem_block_setup, NULL, NULL, NULL);
816