1 /*
2  * Copyright (c) 2020-2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/drivers/flash.h>
10 #include <zephyr/devicetree.h>
11 #include <zephyr/storage/flash_map.h>
12 #include <zephyr/drivers/gpio.h>
13 
14 #if defined(CONFIG_TEST_FORCE_STORAGE_PARTITION)
15 #define TEST_AREA	storage_partition
16 #elif defined(CONFIG_NORDIC_QSPI_NOR)
17 #define TEST_AREA_DEV_NODE	DT_INST(0, nordic_qspi_nor)
18 #elif defined(SOC_SERIES_STM32N6X)
19 #define TEST_AREA_DEV_NODE	DT_INST(0, st_stm32_xspi_nor)
20 #elif defined(CONFIG_FLASH_RENESAS_RA_OSPI_B)
21 #define TEST_AREA_DEV_NODE	DT_INST(0, renesas_ra_ospi_b_nor)
22 #elif defined(CONFIG_SPI_NOR)
23 #define TEST_AREA_DEV_NODE	DT_INST(0, jedec_spi_nor)
24 #elif defined(CONFIG_FLASH_MSPI_NOR)
25 #define TEST_AREA_DEV_NODE	DT_INST(0, jedec_mspi_nor)
26 #elif defined(CONFIG_FLASH_RENESAS_RA_QSPI)
27 #define TEST_AREA_DEV_NODE DT_INST(0, renesas_ra_qspi_nor)
28 #elif defined(CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI)
29 #define TEST_AREA_DEV_NODE DT_INST(0, renesas_rz_qspi_xspi)
30 #elif defined(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC)
31 #define TEST_AREA_DEV_NODE DT_INST(0, renesas_rz_qspi_spibsc)
32 #else
33 #define TEST_AREA	storage_partition
34 #endif
35 
36 /* TEST_AREA is only defined for configurations that realy on
37  * fixed-partition nodes.
38  */
39 #ifdef TEST_AREA
40 
41 #define TEST_AREA_OFFSET	FIXED_PARTITION_OFFSET(TEST_AREA)
42 #define TEST_AREA_SIZE		FIXED_PARTITION_SIZE(TEST_AREA)
43 #define TEST_AREA_MAX		(TEST_AREA_OFFSET + TEST_AREA_SIZE)
44 #define TEST_AREA_DEVICE	FIXED_PARTITION_DEVICE(TEST_AREA)
45 
46 #elif defined(TEST_AREA_DEV_NODE)
47 
48 #define TEST_AREA_DEVICE	DEVICE_DT_GET(TEST_AREA_DEV_NODE)
49 #if defined CONFIG_FLASH_RENESAS_RA_OSPI_B
50 #define TEST_AREA_OFFSET	0x40000
51 #else
52 #define TEST_AREA_OFFSET	0xff000
53 #endif
54 
55 #if DT_NODE_HAS_PROP(TEST_AREA_DEV_NODE, size_in_bytes)
56 #define TEST_AREA_MAX DT_PROP(TEST_AREA_DEV_NODE, size_in_bytes)
57 #elif DT_NODE_HAS_PROP(TEST_AREA_DEV_NODE, size)
58 #define TEST_AREA_MAX (DT_PROP(TEST_AREA_DEV_NODE, size) / 8)
59 #else
60 #define TEST_AREA_MAX DT_REG_SIZE(TEST_AREA_DEV_NODE)
61 #endif
62 
63 #else
64 #error "Unsupported configuration"
65 #endif
66 
67 #define EXPECTED_SIZE	512
68 
69 #if !defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) &&		\
70 	!defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE)
71 #error There is no flash device enabled or it is missing Kconfig options
72 #endif
73 
74 #if DT_NODE_HAS_PROP(DT_BUS(TEST_AREA_DEV_NODE), packet_data_limit)
75 #define CONTROLLER_PACKET_DATA_LIMIT  DT_PROP(DT_BUS(TEST_AREA_DEV_NODE), packet_data_limit)
76 #define BUFFER_SIZE_OVER_PACKET_LIMIT CONTROLLER_PACKET_DATA_LIMIT + 1
77 #endif
78 
79 static const struct device *const flash_dev = TEST_AREA_DEVICE;
80 static struct flash_pages_info page_info;
81 static uint8_t __aligned(4) expected[EXPECTED_SIZE];
82 static uint8_t erase_value;
83 static bool ebw_required;
84 
flash_driver_before(void * arg)85 static void flash_driver_before(void *arg)
86 {
87 	int rc;
88 
89 	ARG_UNUSED(arg);
90 
91 	TC_PRINT("Test will run on device %s\n", flash_dev->name);
92 	zassert_true(device_is_ready(flash_dev));
93 
94 	/* Check for erase is only needed when there is mix of devices */
95 	if (IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE)) {
96 		const struct flash_parameters *fparams = flash_get_parameters(flash_dev);
97 
98 		erase_value = fparams->erase_value;
99 		ebw_required = flash_params_get_erase_cap(fparams) & FLASH_ERASE_C_EXPLICIT;
100 		/* For tests purposes use page (in nrf_qspi_nor page = 64 kB) */
101 		flash_get_page_info_by_offs(flash_dev, TEST_AREA_OFFSET,
102 					    &page_info);
103 	} else {
104 		TC_PRINT("No devices with erase requirement present\n");
105 		erase_value = 0x55;
106 		page_info.start_offset = TEST_AREA_OFFSET;
107 		/* test_flash_copy uses 2 pages, so split the test area */
108 		page_info.size = (TEST_AREA_MAX - TEST_AREA_OFFSET) / 2;
109 	}
110 
111 
112 	/* Check if test region is not empty */
113 	uint8_t buf[EXPECTED_SIZE];
114 
115 	rc = flash_read(flash_dev, TEST_AREA_OFFSET,
116 			buf, EXPECTED_SIZE);
117 	zassert_equal(rc, 0, "Cannot read flash");
118 
119 	/* Fill test buffer with random data */
120 	for (int i = 0, val = 0; i < EXPECTED_SIZE; i++, val++) {
121 		/* Skip erase value */
122 		if (val == erase_value) {
123 			val++;
124 		}
125 		expected[i] = val;
126 	}
127 
128 	/* Check if tested region fits in flash */
129 	zassert_true((TEST_AREA_OFFSET + EXPECTED_SIZE) <= TEST_AREA_MAX,
130 		     "Test area exceeds flash size");
131 
132 	/* Check if test region is suitable for test_flash_copy */
133 	zassert_true((TEST_AREA_OFFSET + 2 * page_info.size) <= TEST_AREA_MAX,
134 		     "test_flash_copy needs 2 flash pages");
135 
136 	/* Check if flash is cleared */
137 	if (IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && ebw_required) {
138 		bool is_buf_clear = true;
139 
140 		for (off_t i = 0; i < EXPECTED_SIZE; i++) {
141 			if (buf[i] != erase_value) {
142 				is_buf_clear = false;
143 				break;
144 			}
145 		}
146 
147 		if (!is_buf_clear) {
148 			/* Erase a nb of pages aligned to the EXPECTED_SIZE */
149 			rc = flash_erase(flash_dev, page_info.start_offset,
150 					(page_info.size *
151 					((EXPECTED_SIZE + page_info.size - 1)
152 					/ page_info.size)));
153 
154 			zassert_equal(rc, 0, "Flash memory not properly erased");
155 		}
156 	}
157 }
158 
ZTEST(flash_driver,test_read_unaligned_address)159 ZTEST(flash_driver, test_read_unaligned_address)
160 {
161 	int rc;
162 	uint8_t buf[EXPECTED_SIZE];
163 	const uint8_t canary = erase_value;
164 	uint32_t start;
165 
166 	if (IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && ebw_required) {
167 		start = page_info.start_offset;
168 		/* Erase a nb of pages aligned to the EXPECTED_SIZE */
169 		rc = flash_erase(flash_dev, page_info.start_offset,
170 				(page_info.size *
171 				((EXPECTED_SIZE + page_info.size - 1)
172 				/ page_info.size)));
173 
174 		zassert_equal(rc, 0, "Flash memory not properly erased");
175 	} else {
176 		start = TEST_AREA_OFFSET;
177 	}
178 
179 	rc = flash_write(flash_dev,
180 			 start,
181 			 expected, EXPECTED_SIZE);
182 	zassert_equal(rc, 0, "Cannot write to flash");
183 
184 	/* read buffer length*/
185 	for (off_t len = 0; len < 25; len++) {
186 		/* address offset */
187 		for (off_t ad_o = 0; ad_o < 4; ad_o++) {
188 			/* buffer offset; leave space for buffer guard */
189 			for (off_t buf_o = 1; buf_o < 5; buf_o++) {
190 				/* buffer overflow protection */
191 				buf[buf_o - 1] = canary;
192 				buf[buf_o + len] = canary;
193 				memset(buf + buf_o, 0, len);
194 				rc = flash_read(flash_dev,
195 						start + ad_o,
196 						buf + buf_o, len);
197 				zassert_equal(rc, 0, "Cannot read flash");
198 				zassert_equal(memcmp(buf + buf_o,
199 						expected + ad_o,
200 						len),
201 					0, "Flash read failed at len=%d, "
202 					"ad_o=%d, buf_o=%d", (int)len, (int)ad_o, (int)buf_o);
203 				/* check buffer guards */
204 				zassert_equal(buf[buf_o - 1], canary,
205 					"Buffer underflow at len=%d, "
206 					"ad_o=%d, buf_o=%d", (int)len, (int)ad_o, (int)buf_o);
207 				zassert_equal(buf[buf_o + len], canary,
208 					"Buffer overflow at len=%d, "
209 					"ad_o=%d, buf_o=%d", (int)len, (int)ad_o, (int)buf_o);
210 			}
211 		}
212 	}
213 }
214 
ZTEST(flash_driver,test_flash_fill)215 ZTEST(flash_driver, test_flash_fill)
216 {
217 	uint8_t buf[EXPECTED_SIZE];
218 	int rc;
219 	off_t i;
220 
221 	if (IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && ebw_required) {
222 		/* Erase a nb of pages aligned to the EXPECTED_SIZE */
223 		rc = flash_erase(flash_dev, page_info.start_offset,
224 				(page_info.size *
225 				((EXPECTED_SIZE + page_info.size - 1)
226 				/ page_info.size)));
227 
228 		zassert_equal(rc, 0, "Flash memory not properly erased");
229 	} else {
230 		rc = flash_fill(flash_dev, 0x55, page_info.start_offset,
231 				(page_info.size *
232 				((EXPECTED_SIZE + page_info.size - 1)
233 				/ page_info.size)));
234 		zassert_equal(rc, 0, "Leveling memory with fill failed\n");
235 	}
236 
237 	/* Fill the device with 0xaa */
238 	rc = flash_fill(flash_dev, 0xaa, page_info.start_offset,
239 			(page_info.size *
240 			((EXPECTED_SIZE + page_info.size - 1)
241 			/ page_info.size)));
242 	zassert_equal(rc, 0, "Fill failed\n");
243 
244 	rc = flash_read(flash_dev, TEST_AREA_OFFSET,
245 			buf, EXPECTED_SIZE);
246 	zassert_equal(rc, 0, "Cannot read flash");
247 
248 	for (i = 0; i < EXPECTED_SIZE; i++) {
249 		if (buf[i] != 0xaa) {
250 			break;
251 		}
252 	}
253 	zassert_equal(i, EXPECTED_SIZE, "Expected device to be filled wth 0xaa");
254 }
255 
ZTEST(flash_driver,test_flash_flatten)256 ZTEST(flash_driver, test_flash_flatten)
257 {
258 	uint8_t buf[EXPECTED_SIZE];
259 	int rc;
260 	off_t i;
261 
262 	rc = flash_flatten(flash_dev, page_info.start_offset,
263 			   (page_info.size *
264 			   ((EXPECTED_SIZE + page_info.size - 1)
265 			   / page_info.size)));
266 
267 	zassert_equal(rc, 0, "Flash not leveled not properly erased");
268 
269 	/* Fill the device with 0xaa */
270 	rc = flash_fill(flash_dev, 0xaa, page_info.start_offset,
271 			(page_info.size *
272 			((EXPECTED_SIZE + page_info.size - 1)
273 			/ page_info.size)));
274 	zassert_equal(rc, 0, "Fill failed\n");
275 
276 	rc = flash_read(flash_dev, TEST_AREA_OFFSET,
277 			buf, EXPECTED_SIZE);
278 	zassert_equal(rc, 0, "Cannot read flash");
279 
280 	for (i = 0; i < EXPECTED_SIZE; i++) {
281 		if (buf[i] != 0xaa) {
282 			break;
283 		}
284 	}
285 	zassert_equal(i, EXPECTED_SIZE, "Expected device to be filled wth 0xaa");
286 }
287 
ZTEST(flash_driver,test_flash_erase)288 ZTEST(flash_driver, test_flash_erase)
289 {
290 	int rc;
291 	uint8_t read_buf[EXPECTED_SIZE];
292 	bool comparison_result;
293 	const struct flash_parameters *fparams = flash_get_parameters(flash_dev);
294 
295 	erase_value = fparams->erase_value;
296 
297 	/* Write test data */
298 	rc = flash_write(flash_dev, page_info.start_offset, expected, EXPECTED_SIZE);
299 	zassert_equal(rc, 0, "Cannot write to flash");
300 
301 	/* Confirm write operation */
302 	rc = flash_read(flash_dev, page_info.start_offset, read_buf, EXPECTED_SIZE);
303 	zassert_equal(rc, 0, "Cannot read flash");
304 
305 	comparison_result = true;
306 	for (int i = 0; i < EXPECTED_SIZE; i++) {
307 		if (read_buf[i] != expected[i]) {
308 			comparison_result = false;
309 			TC_PRINT("i=%d:\tread_buf[i]=%d\texpected[i]=%d\n", i, read_buf[i],
310 				 expected[i]);
311 		}
312 	}
313 	zassert_true(comparison_result, "Write operation failed");
314 	/* Cross check - confirm that expected data is pseudo-random */
315 	zassert_not_equal(read_buf[0], expected[1], "These values shall be different");
316 
317 	/* Erase a nb of pages aligned to the EXPECTED_SIZE */
318 	rc = flash_erase(
319 		flash_dev, page_info.start_offset,
320 		(page_info.size * ((EXPECTED_SIZE + page_info.size - 1) / page_info.size)));
321 	zassert_equal(rc, 0, "Flash memory not properly erased");
322 
323 	/* Confirm erase operation */
324 	rc = flash_read(flash_dev, page_info.start_offset, read_buf, EXPECTED_SIZE);
325 	zassert_equal(rc, 0, "Cannot read flash");
326 
327 	comparison_result = true;
328 	for (int i = 0; i < EXPECTED_SIZE; i++) {
329 		if (read_buf[i] != erase_value) {
330 			comparison_result = false;
331 			TC_PRINT("i=%d:\tread_buf[i]=%d\texpected=%d\n", i, read_buf[i],
332 				 erase_value);
333 		}
334 	}
335 	zassert_true(comparison_result, "Write operation failed");
336 	/* Cross check - confirm that expected data
337 	 * doesn't contain erase_value
338 	 */
339 	zassert_not_equal(expected[0], erase_value, "These values shall be different");
340 }
341 
ZTEST(flash_driver,test_flash_write_read_over_the_packet_limit)342 ZTEST(flash_driver, test_flash_write_read_over_the_packet_limit)
343 {
344 
345 #if !defined(CONTROLLER_PACKET_DATA_LIMIT)
346 	TC_PRINT("Given bus controller does not have 'packet_data_limit' property\n");
347 	ztest_test_skip();
348 #else
349 	int rc;
350 	const uint8_t pattern = 0xA1;
351 	static uint8_t large_data_buf[BUFFER_SIZE_OVER_PACKET_LIMIT];
352 
353 	/* Flatten area corresponding to the size of two packets */
354 	rc = flash_flatten(flash_dev, page_info.start_offset, 2 * CONTROLLER_PACKET_DATA_LIMIT);
355 	zassert_equal(rc, 0, "Flash flatten failed: %d", rc);
356 
357 	/* Fill flash area with buffer size over the configured packet limit */
358 	rc = flash_fill(flash_dev, pattern, page_info.start_offset, BUFFER_SIZE_OVER_PACKET_LIMIT);
359 	zassert_equal(rc, 0, "Flash fill failed");
360 
361 	/* Read flash area with buffer size over the MSPI packet limit */
362 	rc = flash_read(flash_dev, page_info.start_offset, large_data_buf,
363 			BUFFER_SIZE_OVER_PACKET_LIMIT);
364 	zassert_equal(rc, 0, "Flash read failed");
365 
366 	/* Compare read data to the pre-defined pattern */
367 	for (int i = 0; i < BUFFER_SIZE_OVER_PACKET_LIMIT; i++) {
368 		zassert_equal(large_data_buf[i], pattern,
369 			      "large_data_buf[%u]=%x read, does not match written pattern %x", i,
370 			      large_data_buf[i], pattern);
371 	}
372 #endif
373 }
374 
ZTEST(flash_driver,test_supply_gpios_control)375 ZTEST(flash_driver, test_supply_gpios_control)
376 {
377 	if (!DT_NODE_HAS_PROP(TEST_AREA_DEV_NODE, supply_gpios)) {
378 		ztest_test_skip();
379 	}
380 
381 #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), test_gpios)
382 	const struct gpio_dt_spec test_gpio =
383 		GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), test_gpios);
384 	zassert_true(gpio_is_ready_dt(&test_gpio), "Test GPIO is not ready\n");
385 	zassert_ok(gpio_pin_configure_dt(&test_gpio, GPIO_INPUT | GPIO_PULL_DOWN),
386 		   "Failed to configure test pin\n");
387 	zassert_equal(gpio_pin_get(test_gpio.port, test_gpio.pin), 1, "Supply GPIO is not set\n");
388 #endif
389 }
390 
391 struct test_cb_data_type {
392 	size_t page_counter; /* used to count how many pages was iterated */
393 	size_t exit_page;    /* terminate iteration when this page is reached */
394 };
395 
flash_callback(const struct flash_pages_info * info,void * data)396 static bool flash_callback(const struct flash_pages_info *info, void *data)
397 {
398 	struct test_cb_data_type *cb_data = (struct test_cb_data_type *)data;
399 
400 	cb_data->page_counter++;
401 
402 	if (cb_data->page_counter >= cb_data->exit_page) {
403 		return false;
404 	}
405 
406 	return true;
407 }
408 
ZTEST(flash_driver,test_get_size)409 ZTEST(flash_driver, test_get_size)
410 {
411 #if CONFIG_TEST_DRIVER_FLASH_SIZE != -1
412 	uint64_t size;
413 
414 	zassert_ok(flash_get_size(flash_dev, &size));
415 	zassert_equal(size, (uint64_t)CONFIG_TEST_DRIVER_FLASH_SIZE, "Expected %llu, got %llu\n",
416 		      (uint64_t)CONFIG_TEST_DRIVER_FLASH_SIZE, size);
417 #else
418 	/* The test is sipped only because there is no uniform way to get device size */
419 	ztest_test_skip();
420 #endif
421 }
422 
ZTEST(flash_driver,test_flash_page_layout)423 ZTEST(flash_driver, test_flash_page_layout)
424 {
425 	int rc;
426 	struct flash_pages_info page_info_off = {0};
427 	struct flash_pages_info page_info_idx = {0};
428 	size_t page_count;
429 	struct test_cb_data_type test_cb_data = {0};
430 
431 #if !defined(CONFIG_FLASH_PAGE_LAYOUT)
432 	ztest_test_skip();
433 #endif
434 
435 	/* Get page info with flash_get_page_info_by_offs() */
436 	rc = flash_get_page_info_by_offs(flash_dev, TEST_AREA_OFFSET, &page_info_off);
437 	zassert_true(rc == 0, "flash_get_page_info_by_offs returned %d", rc);
438 	TC_PRINT("start_offset=0x%lx\tsize=%d\tindex=%d\n", page_info_off.start_offset,
439 		 (int)page_info_off.size, page_info_off.index);
440 	zassert_true(page_info_off.start_offset >= 0, "start_offset is %d", rc);
441 	zassert_true(page_info_off.size > 0, "size is %d", rc);
442 	zassert_true(page_info_off.index >= 0, "index is %d", rc);
443 
444 	/* Get info for the same page with flash_get_page_info_by_idx() */
445 	rc = flash_get_page_info_by_idx(flash_dev, page_info_off.index, &page_info_idx);
446 	zassert_true(rc == 0, "flash_get_page_info_by_offs returned %d", rc);
447 	zassert_equal(page_info_off.start_offset, page_info_idx.start_offset);
448 	zassert_equal(page_info_off.size, page_info_idx.size);
449 	zassert_equal(page_info_off.index, page_info_idx.index);
450 
451 	page_count = flash_get_page_count(flash_dev);
452 	TC_PRINT("page_count=%zu\n", page_count);
453 	zassert_true(page_count > 0, "flash_get_page_count returned %d", rc);
454 	zassert_true(page_count >= page_info_off.index);
455 
456 	/* Test that callback is executed for every page */
457 	test_cb_data.exit_page = page_count + 1;
458 	flash_page_foreach(flash_dev, flash_callback, &test_cb_data);
459 	zassert_true(page_count == test_cb_data.page_counter,
460 		     "page_count = %zu not equal to pages counted with cb = %zu", page_count,
461 		     test_cb_data.page_counter);
462 
463 	/* Test that callback can cancell iteration */
464 	test_cb_data.page_counter = 0;
465 	test_cb_data.exit_page = page_count >> 1;
466 	flash_page_foreach(flash_dev, flash_callback, &test_cb_data);
467 	zassert_true(test_cb_data.exit_page == test_cb_data.page_counter,
468 		     "%zu pages were iterated while it shall stop on page %zu",
469 		     test_cb_data.page_counter, test_cb_data.exit_page);
470 }
471 
test_flash_copy_inner(const struct device * src_dev,off_t src_offset,const struct device * dst_dev,off_t dst_offset,off_t size,uint8_t * buf,size_t buf_size,int expected_result)472 static void test_flash_copy_inner(const struct device *src_dev, off_t src_offset,
473 				  const struct device *dst_dev, off_t dst_offset, off_t size,
474 				  uint8_t *buf, size_t buf_size, int expected_result)
475 {
476 	int actual_result;
477 
478 	if ((expected_result == 0) && (size != 0) && (src_offset != dst_offset)) {
479 		/* prepare for successful copy */
480 		zassert_ok(flash_flatten(flash_dev, page_info.start_offset, page_info.size));
481 		zassert_ok(flash_fill(flash_dev, 0xaa, page_info.start_offset, page_info.size));
482 		zassert_ok(flash_flatten(flash_dev, page_info.start_offset + page_info.size,
483 					 page_info.size));
484 	}
485 
486 	/* perform copy (if args are valid) */
487 	actual_result = flash_copy(src_dev, src_offset, dst_dev, dst_offset, size, buf, buf_size);
488 	zassert_equal(actual_result, expected_result,
489 		      "flash_copy(%p, %lx, %p, %lx, %zu, %p, %zu) failed: expected: %d actual: %d",
490 		      src_dev, src_offset, dst_dev, dst_offset, (size_t)size, buf, buf_size,
491 		      expected_result, actual_result);
492 
493 	if ((expected_result == 0) && (size != 0) && (src_offset != dst_offset)) {
494 		/* verify a successful copy */
495 		off_t copy_size = MIN(size, EXPECTED_SIZE);
496 
497 		zassert_ok(flash_read(flash_dev, TEST_AREA_OFFSET, expected, copy_size));
498 		for (int i = 0; i < copy_size; i++) {
499 			zassert_equal(buf[i], 0xaa, "incorrect data (%02x) at %d", buf[i], i);
500 		}
501 	}
502 }
503 
ZTEST(flash_driver,test_flash_copy)504 ZTEST(flash_driver, test_flash_copy)
505 {
506 	uint8_t buf[EXPECTED_SIZE];
507 	const off_t off_max = (sizeof(off_t) == sizeof(int32_t)) ? INT32_MAX : INT64_MAX;
508 
509 	/*
510 	 * Rather than explicitly testing 128+ permutations of input,
511 	 * merge redundant cases:
512 	 *  - src_dev or dst_dev are invalid
513 	 *  - src_offset or dst_offset are invalid
514 	 *  - src_offset + size or dst_offset + size overflow
515 	 *  - buf is NULL
516 	 *  - buf size is invalid
517 	 */
518 	test_flash_copy_inner(NULL, -1, NULL, -1, -1, NULL, 0, -EINVAL);
519 	test_flash_copy_inner(NULL, -1, NULL, -1, -1, NULL, sizeof(buf), -EINVAL);
520 	test_flash_copy_inner(NULL, -1, NULL, -1, -1, buf, sizeof(buf), -EINVAL);
521 	test_flash_copy_inner(NULL, -1, NULL, -1, page_info.size, buf, sizeof(buf), -EINVAL);
522 	test_flash_copy_inner(NULL, -1, NULL, -1, page_info.size, buf, sizeof(buf), -EINVAL);
523 	test_flash_copy_inner(NULL, page_info.start_offset, NULL,
524 			      page_info.start_offset + page_info.size, page_info.size, buf,
525 			      sizeof(buf), -ENODEV);
526 	test_flash_copy_inner(flash_dev, page_info.start_offset, flash_dev,
527 			      page_info.start_offset + page_info.size, page_info.size, buf,
528 			      sizeof(buf), 0);
529 
530 	/* zero-sized copy should succeed */
531 	test_flash_copy_inner(flash_dev, page_info.start_offset, flash_dev,
532 			      page_info.start_offset + page_info.size, 0, buf, sizeof(buf), 0);
533 
534 	/* copy with same offset should succeed */
535 	test_flash_copy_inner(flash_dev, page_info.start_offset, flash_dev, page_info.start_offset,
536 			      page_info.size, buf, sizeof(buf), 0);
537 
538 	/* copy with integer overflow should fail */
539 	test_flash_copy_inner(flash_dev, off_max, flash_dev, page_info.start_offset, 42, buf,
540 			      sizeof(buf), -EINVAL);
541 
542 	/* copy with overlapping ranges should fail */
543 	test_flash_copy_inner(flash_dev, page_info.start_offset, flash_dev,
544 			      page_info.start_offset + (page_info.size / 4),
545 			      page_info.size - (page_info.size / 4), buf, sizeof(buf), -EINVAL);
546 }
547 
548 ZTEST_SUITE(flash_driver, NULL, NULL, flash_driver_before, NULL, NULL);
549