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