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 
13 #if defined(CONFIG_NORDIC_QSPI_NOR)
14 #define TEST_AREA_DEV_NODE DT_INST(0, nordic_qspi_nor)
15 #elif defined(CONFIG_SPI_NOR)
16 #define TEST_AREA_DEV_NODE DT_INST(0, jedec_spi_nor)
17 #else
18 #define TEST_AREA storage_partition
19 #endif
20 
21 /* TEST_AREA is only defined for configurations that rely on
22  * fixed-partition nodes.
23  */
24 #if defined(TEST_AREA)
25 #define TEST_AREA_OFFSET FIXED_PARTITION_OFFSET(TEST_AREA)
26 #define TEST_AREA_SIZE   FIXED_PARTITION_SIZE(TEST_AREA)
27 #define TEST_AREA_DEVICE FIXED_PARTITION_DEVICE(TEST_AREA)
28 
29 #if defined(CONFIG_SOC_NRF54L05) || \
30 	defined(CONFIG_SOC_NRF54L09) || \
31 	defined(CONFIG_SOC_NRF54L10) || \
32 	defined(CONFIG_SOC_NRF54L15)
33 #define TEST_FLASH_START (DT_REG_ADDR(DT_MEM_FROM_FIXED_PARTITION(DT_NODELABEL(TEST_AREA))))
34 #define TEST_FLASH_SIZE  (DT_REG_SIZE(DT_MEM_FROM_FIXED_PARTITION(DT_NODELABEL(TEST_AREA))))
35 #elif defined(CONFIG_SOC_NRF54H20)
36 #define TEST_FLASH_START (DT_REG_ADDR(DT_PARENT(DT_PARENT(DT_NODELABEL(TEST_AREA)))))
37 #define TEST_FLASH_SIZE  (DT_REG_SIZE(DT_PARENT(DT_PARENT(DT_NODELABEL(TEST_AREA)))))
38 #else
39 #error "Missing definition of TEST_FLASH_START and TEST_FLASH_SIZE for this target"
40 #endif
41 
42 #else
43 #error "Unsupported configuraiton"
44 #endif
45 
46 #define EXPECTED_SIZE 512
47 
48 #if !defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && !defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE)
49 #error There is no flash device enabled or it is missing Kconfig options
50 #endif
51 
52 static const struct device *const flash_dev = TEST_AREA_DEVICE;
53 static struct flash_pages_info page_info;
54 static uint8_t __aligned(4) expected[EXPECTED_SIZE];
55 
flash_driver_setup(void)56 static void *flash_driver_setup(void)
57 {
58 	int rc;
59 
60 	zassert_true(device_is_ready(flash_dev));
61 
62 	TC_PRINT("Test will run on device %s\n", flash_dev->name);
63 	TC_PRINT("TEST_AREA_OFFSET = 0x%lx\n", (unsigned long)TEST_AREA_OFFSET);
64 	TC_PRINT("TEST_AREA_SIZE   = 0x%lx\n", (unsigned long)TEST_AREA_SIZE);
65 	TC_PRINT("TEST_FLASH_START = 0x%lx\n", (unsigned long)TEST_FLASH_START);
66 	TC_PRINT("TEST_FLASH_SIZE  = 0x%lx\n", (unsigned long)TEST_FLASH_SIZE);
67 
68 	rc = flash_get_page_info_by_offs(flash_dev, TEST_AREA_OFFSET, &page_info);
69 	zassert_true(rc == 0, "flash_get_page_info_by_offs returned %d", rc);
70 	TC_PRINT("Test Page Info:\n");
71 	TC_PRINT("start_offset = 0x%lx\n", (unsigned long)page_info.start_offset);
72 	TC_PRINT("size         = 0x%lx\n", (unsigned long)page_info.size);
73 	TC_PRINT("index        = %d\n", page_info.index);
74 	TC_PRINT("===================================================================\n");
75 
76 	return NULL;
77 }
78 
ZTEST(flash_driver_negative,test_negative_flash_erase)79 ZTEST(flash_driver_negative, test_negative_flash_erase)
80 {
81 	int rc;
82 
83 #if !defined(TEST_AREA)
84 	/* Flash memory boundaries are correctly calculated
85 	 * only for storage_partition.
86 	 */
87 	ztest_test_skip();
88 #endif
89 
90 	/*  Acceptable values of erase size and offset are subject to
91 	 *  hardware-specific multiples of page size and offset.
92 	 */
93 
94 	/* Check error returned when erasing memory at wrong address (too low) */
95 	rc = flash_erase(flash_dev, (TEST_FLASH_START - page_info.size), page_info.size);
96 	zassert_true(rc < 0, "Invalid use of flash_erase returned %d", rc);
97 
98 	/* Check error returned when erasing memory at wrong address (too high) */
99 	rc = flash_erase(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), page_info.size);
100 	zassert_true(rc < 0, "Invalid use of flash_erase returned %d", rc);
101 
102 	/* Check error returned when erasing unaligned memory or too large chunk of memory */
103 	rc = flash_erase(flash_dev, (TEST_AREA_OFFSET + 1), (TEST_FLASH_SIZE + 1));
104 	zassert_true(rc < 0, "Invalid use of flash_erase returned %d", rc);
105 
106 	/* Erasing 0 bytes shall succeed */
107 	rc = flash_erase(flash_dev, TEST_AREA_OFFSET, 0);
108 	zassert_true(rc == 0, "flash_erase 0 bytes returned %d", rc);
109 }
110 
ZTEST(flash_driver_negative,test_negative_flash_fill)111 ZTEST(flash_driver_negative, test_negative_flash_fill)
112 {
113 	int rc;
114 	uint8_t fill_val = 0xA; /* Dummy value */
115 
116 #if !defined(TEST_AREA)
117 	/* Flash memory boundaries are correctly calculated
118 	 * only for storage_partition.
119 	 */
120 	ztest_test_skip();
121 #endif
122 
123 	/*  Erase page offset and size are constrains of paged, explicit erase devices,
124 	 *  but can be relaxed with devices without such requirement.
125 	 */
126 
127 	/* Check error returned when filling memory at wrong address (too low) */
128 	rc = flash_fill(flash_dev, fill_val, (TEST_FLASH_START - page_info.size), page_info.size);
129 	zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc);
130 
131 	/* Check error returned when filling memory at wrong address (too high) */
132 	rc = flash_fill(flash_dev, fill_val, (TEST_FLASH_START + TEST_FLASH_SIZE), page_info.size);
133 	zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc);
134 
135 	/* Check error returned when filling unaligned memory */
136 	rc = flash_fill(flash_dev, fill_val, (TEST_AREA_OFFSET + 1), page_info.size);
137 	zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc);
138 	rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, (page_info.size + 1));
139 	zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc);
140 
141 	/* Filling 0 bytes shall succeed */
142 	rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, 0);
143 	zassert_true(rc == 0, "flash_fill 0 bytes returned %d", rc);
144 }
145 
ZTEST(flash_driver_negative,test_negative_flash_flatten)146 ZTEST(flash_driver_negative, test_negative_flash_flatten)
147 {
148 	int rc;
149 
150 #if !defined(TEST_AREA)
151 	/* Flash memory boundaries are correctly calculated
152 	 * only for storage_partition.
153 	 */
154 	ztest_test_skip();
155 #endif
156 
157 	/*  Erase page offset and size are constrains of paged, explicit erase devices,
158 	 *  but can be relaxed with devices without such requirement.
159 	 */
160 
161 	/* Check error returned when flatten memory at wrong address (too low) */
162 	rc = flash_flatten(flash_dev, (TEST_FLASH_START - page_info.size), page_info.size);
163 	zassert_true(rc < 0, "Invalid use of flash_flatten returned %d", rc);
164 
165 	/* Check error returned when flatten memory at wrong address (too high) */
166 	rc = flash_flatten(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), page_info.size);
167 	zassert_true(rc < 0, "Invalid use of flash_flatten returned %d", rc);
168 
169 	/* Check error returned when flatten unaligned memory */
170 	rc = flash_flatten(flash_dev, (TEST_AREA_OFFSET + 1), page_info.size);
171 	zassert_true(rc < 0, "Invalid use of flash_flatten returned %d", rc);
172 	rc = flash_flatten(flash_dev, TEST_AREA_OFFSET, (page_info.size + 1));
173 	zassert_true(rc < 0, "Invalid use of flash_flatten returned %d", rc);
174 
175 	/* Flatten 0 bytes shall succeed */
176 	rc = flash_flatten(flash_dev, TEST_AREA_OFFSET, 0);
177 	zassert_true(rc == 0, "flash_flatten 0 bytes returned %d", rc);
178 }
179 
ZTEST(flash_driver_negative,test_negative_flash_read)180 ZTEST(flash_driver_negative, test_negative_flash_read)
181 {
182 	int rc;
183 	uint8_t read_buf[EXPECTED_SIZE];
184 
185 #if !defined(TEST_AREA)
186 	/* Flash memory boundaries are correctly calculated
187 	 * only for storage_partition.
188 	 */
189 	ztest_test_skip();
190 #endif
191 
192 	/*  All flash drivers support reads without alignment restrictions on
193 	 *  the read offset, the read size, or the destination address.
194 	 */
195 
196 	/* Check error returned when reading from a wrong address (too low) */
197 	rc = flash_read(flash_dev, (TEST_FLASH_START - page_info.size), read_buf, EXPECTED_SIZE);
198 	zassert_true(rc < 0, "Invalid use of flash_read returned %d", rc);
199 
200 	/* Check error returned when reading from a wrong address (too high) */
201 	rc = flash_read(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), read_buf, EXPECTED_SIZE);
202 	zassert_true(rc < 0, "Invalid use of flash_read returned %d", rc);
203 
204 	/* Check error returned when reading too many data */
205 	rc = flash_read(flash_dev, TEST_AREA_OFFSET, read_buf, (TEST_FLASH_SIZE + page_info.size));
206 	zassert_true(rc < 0, "Invalid use of flash_read returned %d", rc);
207 
208 	/* Reading 0 bytes shall succeed */
209 	rc = flash_read(flash_dev, TEST_AREA_OFFSET, read_buf, 0);
210 	zassert_true(rc == 0, "flash_read 0 bytes returned %d", rc);
211 }
212 
ZTEST(flash_driver_negative,test_negative_flash_write)213 ZTEST(flash_driver_negative, test_negative_flash_write)
214 {
215 	int rc;
216 
217 #if !defined(TEST_AREA)
218 	/* Flash memory boundaries are correctly calculated
219 	 * only for storage_partition.
220 	 */
221 	ztest_test_skip();
222 #endif
223 
224 	/*  Write size and offset must be multiples of the minimum write block size
225 	 *  supported by the driver.
226 	 */
227 
228 	/* Check error returned when writing to a wrong address (too low) */
229 	rc = flash_write(flash_dev, (TEST_FLASH_START - page_info.size), expected, page_info.size);
230 	zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc);
231 
232 	/* Check error returned when writing to a wrong address (too high) */
233 	rc = flash_write(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), expected, page_info.size);
234 	zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc);
235 
236 	/* Check error returned when writing at unaligned memory or too large chunk of memory */
237 	rc = flash_write(flash_dev, (TEST_AREA_OFFSET + 1), expected, (TEST_FLASH_SIZE + 1));
238 	zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc);
239 
240 	/* Writing 0 bytes shall succeed */
241 	rc = flash_write(flash_dev, TEST_AREA_OFFSET, expected, 0);
242 	zassert_true(rc == 0, "flash_write 0 bytes returned %d", rc);
243 }
244 
245 ZTEST_SUITE(flash_driver_negative, NULL, flash_driver_setup, NULL, NULL, NULL);
246