xref: /openbmc/qemu/tests/qtest/aspeed-smc-utils.c (revision 11d94251)
1*11d94251SJamin Lin /*
2*11d94251SJamin Lin  * QTest testcase for the M25P80 Flash (Using the Aspeed SPI
3*11d94251SJamin Lin  * Controller)
4*11d94251SJamin Lin  *
5*11d94251SJamin Lin  * Copyright (C) 2016 IBM Corp.
6*11d94251SJamin Lin  *
7*11d94251SJamin Lin  * Permission is hereby granted, free of charge, to any person obtaining a copy
8*11d94251SJamin Lin  * of this software and associated documentation files (the "Software"), to deal
9*11d94251SJamin Lin  * in the Software without restriction, including without limitation the rights
10*11d94251SJamin Lin  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11*11d94251SJamin Lin  * copies of the Software, and to permit persons to whom the Software is
12*11d94251SJamin Lin  * furnished to do so, subject to the following conditions:
13*11d94251SJamin Lin  *
14*11d94251SJamin Lin  * The above copyright notice and this permission notice shall be included in
15*11d94251SJamin Lin  * all copies or substantial portions of the Software.
16*11d94251SJamin Lin  *
17*11d94251SJamin Lin  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*11d94251SJamin Lin  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*11d94251SJamin Lin  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*11d94251SJamin Lin  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*11d94251SJamin Lin  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22*11d94251SJamin Lin  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23*11d94251SJamin Lin  * THE SOFTWARE.
24*11d94251SJamin Lin  */
25*11d94251SJamin Lin 
26*11d94251SJamin Lin #include "qemu/osdep.h"
27*11d94251SJamin Lin #include "qemu/bswap.h"
28*11d94251SJamin Lin #include "libqtest-single.h"
29*11d94251SJamin Lin #include "qemu/bitops.h"
30*11d94251SJamin Lin #include "aspeed-smc-utils.h"
31*11d94251SJamin Lin 
32*11d94251SJamin Lin /*
33*11d94251SJamin Lin  * Use an explicit bswap for the values read/wrote to the flash region
34*11d94251SJamin Lin  * as they are BE and the Aspeed CPU is LE.
35*11d94251SJamin Lin  */
make_be32(uint32_t data)36*11d94251SJamin Lin static inline uint32_t make_be32(uint32_t data)
37*11d94251SJamin Lin {
38*11d94251SJamin Lin     return bswap32(data);
39*11d94251SJamin Lin }
40*11d94251SJamin Lin 
spi_writel(const AspeedSMCTestData * data,uint64_t offset,uint32_t value)41*11d94251SJamin Lin static inline void spi_writel(const AspeedSMCTestData *data, uint64_t offset,
42*11d94251SJamin Lin                               uint32_t value)
43*11d94251SJamin Lin {
44*11d94251SJamin Lin     qtest_writel(data->s, data->spi_base + offset, value);
45*11d94251SJamin Lin }
46*11d94251SJamin Lin 
spi_readl(const AspeedSMCTestData * data,uint64_t offset)47*11d94251SJamin Lin static inline uint32_t spi_readl(const AspeedSMCTestData *data, uint64_t offset)
48*11d94251SJamin Lin {
49*11d94251SJamin Lin     return qtest_readl(data->s, data->spi_base + offset);
50*11d94251SJamin Lin }
51*11d94251SJamin Lin 
flash_writeb(const AspeedSMCTestData * data,uint64_t offset,uint8_t value)52*11d94251SJamin Lin static inline void flash_writeb(const AspeedSMCTestData *data, uint64_t offset,
53*11d94251SJamin Lin                                 uint8_t value)
54*11d94251SJamin Lin {
55*11d94251SJamin Lin     qtest_writeb(data->s, data->flash_base + offset, value);
56*11d94251SJamin Lin }
57*11d94251SJamin Lin 
flash_writel(const AspeedSMCTestData * data,uint64_t offset,uint32_t value)58*11d94251SJamin Lin static inline void flash_writel(const AspeedSMCTestData *data, uint64_t offset,
59*11d94251SJamin Lin                                 uint32_t value)
60*11d94251SJamin Lin {
61*11d94251SJamin Lin     qtest_writel(data->s, data->flash_base + offset, value);
62*11d94251SJamin Lin }
63*11d94251SJamin Lin 
flash_readb(const AspeedSMCTestData * data,uint64_t offset)64*11d94251SJamin Lin static inline uint8_t flash_readb(const AspeedSMCTestData *data,
65*11d94251SJamin Lin                                   uint64_t offset)
66*11d94251SJamin Lin {
67*11d94251SJamin Lin     return qtest_readb(data->s, data->flash_base + offset);
68*11d94251SJamin Lin }
69*11d94251SJamin Lin 
flash_readl(const AspeedSMCTestData * data,uint64_t offset)70*11d94251SJamin Lin static inline uint32_t flash_readl(const AspeedSMCTestData *data,
71*11d94251SJamin Lin                                    uint64_t offset)
72*11d94251SJamin Lin {
73*11d94251SJamin Lin     return qtest_readl(data->s, data->flash_base + offset);
74*11d94251SJamin Lin }
75*11d94251SJamin Lin 
spi_conf(const AspeedSMCTestData * data,uint32_t value)76*11d94251SJamin Lin static void spi_conf(const AspeedSMCTestData *data, uint32_t value)
77*11d94251SJamin Lin {
78*11d94251SJamin Lin     uint32_t conf = spi_readl(data, R_CONF);
79*11d94251SJamin Lin 
80*11d94251SJamin Lin     conf |= value;
81*11d94251SJamin Lin     spi_writel(data, R_CONF, conf);
82*11d94251SJamin Lin }
83*11d94251SJamin Lin 
spi_conf_remove(const AspeedSMCTestData * data,uint32_t value)84*11d94251SJamin Lin static void spi_conf_remove(const AspeedSMCTestData *data, uint32_t value)
85*11d94251SJamin Lin {
86*11d94251SJamin Lin     uint32_t conf = spi_readl(data, R_CONF);
87*11d94251SJamin Lin 
88*11d94251SJamin Lin     conf &= ~value;
89*11d94251SJamin Lin     spi_writel(data, R_CONF, conf);
90*11d94251SJamin Lin }
91*11d94251SJamin Lin 
spi_ce_ctrl(const AspeedSMCTestData * data,uint32_t value)92*11d94251SJamin Lin static void spi_ce_ctrl(const AspeedSMCTestData *data, uint32_t value)
93*11d94251SJamin Lin {
94*11d94251SJamin Lin     uint32_t conf = spi_readl(data, R_CE_CTRL);
95*11d94251SJamin Lin 
96*11d94251SJamin Lin     conf |= value;
97*11d94251SJamin Lin     spi_writel(data, R_CE_CTRL, conf);
98*11d94251SJamin Lin }
99*11d94251SJamin Lin 
spi_ctrl_setmode(const AspeedSMCTestData * data,uint8_t mode,uint8_t cmd)100*11d94251SJamin Lin static void spi_ctrl_setmode(const AspeedSMCTestData *data, uint8_t mode,
101*11d94251SJamin Lin                              uint8_t cmd)
102*11d94251SJamin Lin {
103*11d94251SJamin Lin     uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
104*11d94251SJamin Lin     uint32_t ctrl = spi_readl(data, ctrl_reg);
105*11d94251SJamin Lin     ctrl &= ~(CTRL_USERMODE | 0xff << 16);
106*11d94251SJamin Lin     ctrl |= mode | (cmd << 16);
107*11d94251SJamin Lin     spi_writel(data, ctrl_reg, ctrl);
108*11d94251SJamin Lin }
109*11d94251SJamin Lin 
spi_ctrl_start_user(const AspeedSMCTestData * data)110*11d94251SJamin Lin static void spi_ctrl_start_user(const AspeedSMCTestData *data)
111*11d94251SJamin Lin {
112*11d94251SJamin Lin     uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
113*11d94251SJamin Lin     uint32_t ctrl = spi_readl(data, ctrl_reg);
114*11d94251SJamin Lin 
115*11d94251SJamin Lin     ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
116*11d94251SJamin Lin     spi_writel(data, ctrl_reg, ctrl);
117*11d94251SJamin Lin 
118*11d94251SJamin Lin     ctrl &= ~CTRL_CE_STOP_ACTIVE;
119*11d94251SJamin Lin     spi_writel(data, ctrl_reg, ctrl);
120*11d94251SJamin Lin }
121*11d94251SJamin Lin 
spi_ctrl_stop_user(const AspeedSMCTestData * data)122*11d94251SJamin Lin static void spi_ctrl_stop_user(const AspeedSMCTestData *data)
123*11d94251SJamin Lin {
124*11d94251SJamin Lin     uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
125*11d94251SJamin Lin     uint32_t ctrl = spi_readl(data, ctrl_reg);
126*11d94251SJamin Lin 
127*11d94251SJamin Lin     ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
128*11d94251SJamin Lin     spi_writel(data, ctrl_reg, ctrl);
129*11d94251SJamin Lin }
130*11d94251SJamin Lin 
spi_ctrl_set_io_mode(const AspeedSMCTestData * data,uint32_t value)131*11d94251SJamin Lin static void spi_ctrl_set_io_mode(const AspeedSMCTestData *data, uint32_t value)
132*11d94251SJamin Lin {
133*11d94251SJamin Lin     uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
134*11d94251SJamin Lin     uint32_t ctrl = spi_readl(data, ctrl_reg);
135*11d94251SJamin Lin     uint32_t mode;
136*11d94251SJamin Lin 
137*11d94251SJamin Lin     mode = value & CTRL_IO_MODE_MASK;
138*11d94251SJamin Lin     ctrl &= ~CTRL_IO_MODE_MASK;
139*11d94251SJamin Lin     ctrl |= mode;
140*11d94251SJamin Lin     spi_writel(data, ctrl_reg, ctrl);
141*11d94251SJamin Lin }
142*11d94251SJamin Lin 
flash_reset(const AspeedSMCTestData * data)143*11d94251SJamin Lin static void flash_reset(const AspeedSMCTestData *data)
144*11d94251SJamin Lin {
145*11d94251SJamin Lin     spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs));
146*11d94251SJamin Lin 
147*11d94251SJamin Lin     spi_ctrl_start_user(data);
148*11d94251SJamin Lin     flash_writeb(data, 0, RESET_ENABLE);
149*11d94251SJamin Lin     flash_writeb(data, 0, RESET_MEMORY);
150*11d94251SJamin Lin     flash_writeb(data, 0, WREN);
151*11d94251SJamin Lin     flash_writeb(data, 0, BULK_ERASE);
152*11d94251SJamin Lin     flash_writeb(data, 0, WRDI);
153*11d94251SJamin Lin     spi_ctrl_stop_user(data);
154*11d94251SJamin Lin 
155*11d94251SJamin Lin     spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs));
156*11d94251SJamin Lin }
157*11d94251SJamin Lin 
read_page(const AspeedSMCTestData * data,uint32_t addr,uint32_t * page)158*11d94251SJamin Lin static void read_page(const AspeedSMCTestData *data, uint32_t addr,
159*11d94251SJamin Lin                       uint32_t *page)
160*11d94251SJamin Lin {
161*11d94251SJamin Lin     int i;
162*11d94251SJamin Lin 
163*11d94251SJamin Lin     spi_ctrl_start_user(data);
164*11d94251SJamin Lin 
165*11d94251SJamin Lin     flash_writeb(data, 0, EN_4BYTE_ADDR);
166*11d94251SJamin Lin     flash_writeb(data, 0, READ);
167*11d94251SJamin Lin     flash_writel(data, 0, make_be32(addr));
168*11d94251SJamin Lin 
169*11d94251SJamin Lin     /* Continuous read are supported */
170*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
171*11d94251SJamin Lin         page[i] = make_be32(flash_readl(data, 0));
172*11d94251SJamin Lin     }
173*11d94251SJamin Lin     spi_ctrl_stop_user(data);
174*11d94251SJamin Lin }
175*11d94251SJamin Lin 
read_page_mem(const AspeedSMCTestData * data,uint32_t addr,uint32_t * page)176*11d94251SJamin Lin static void read_page_mem(const AspeedSMCTestData *data, uint32_t addr,
177*11d94251SJamin Lin                           uint32_t *page)
178*11d94251SJamin Lin {
179*11d94251SJamin Lin     int i;
180*11d94251SJamin Lin 
181*11d94251SJamin Lin     /* move out USER mode to use direct reads from the AHB bus */
182*11d94251SJamin Lin     spi_ctrl_setmode(data, CTRL_READMODE, READ);
183*11d94251SJamin Lin 
184*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
185*11d94251SJamin Lin         page[i] = make_be32(flash_readl(data, addr + i * 4));
186*11d94251SJamin Lin     }
187*11d94251SJamin Lin }
188*11d94251SJamin Lin 
write_page_mem(const AspeedSMCTestData * data,uint32_t addr,uint32_t write_value)189*11d94251SJamin Lin static void write_page_mem(const AspeedSMCTestData *data, uint32_t addr,
190*11d94251SJamin Lin                            uint32_t write_value)
191*11d94251SJamin Lin {
192*11d94251SJamin Lin     spi_ctrl_setmode(data, CTRL_WRITEMODE, PP);
193*11d94251SJamin Lin 
194*11d94251SJamin Lin     for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
195*11d94251SJamin Lin         flash_writel(data, addr + i * 4, write_value);
196*11d94251SJamin Lin     }
197*11d94251SJamin Lin }
198*11d94251SJamin Lin 
assert_page_mem(const AspeedSMCTestData * data,uint32_t addr,uint32_t expected_value)199*11d94251SJamin Lin static void assert_page_mem(const AspeedSMCTestData *data, uint32_t addr,
200*11d94251SJamin Lin                             uint32_t expected_value)
201*11d94251SJamin Lin {
202*11d94251SJamin Lin     uint32_t page[FLASH_PAGE_SIZE / 4];
203*11d94251SJamin Lin     read_page_mem(data, addr, page);
204*11d94251SJamin Lin     for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
205*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, expected_value);
206*11d94251SJamin Lin     }
207*11d94251SJamin Lin }
208*11d94251SJamin Lin 
aspeed_smc_test_read_jedec(const void * data)209*11d94251SJamin Lin void aspeed_smc_test_read_jedec(const void *data)
210*11d94251SJamin Lin {
211*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
212*11d94251SJamin Lin     uint32_t jedec = 0x0;
213*11d94251SJamin Lin 
214*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
215*11d94251SJamin Lin 
216*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
217*11d94251SJamin Lin     flash_writeb(test_data, 0, JEDEC_READ);
218*11d94251SJamin Lin     jedec |= flash_readb(test_data, 0) << 16;
219*11d94251SJamin Lin     jedec |= flash_readb(test_data, 0) << 8;
220*11d94251SJamin Lin     jedec |= flash_readb(test_data, 0);
221*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
222*11d94251SJamin Lin 
223*11d94251SJamin Lin     flash_reset(test_data);
224*11d94251SJamin Lin 
225*11d94251SJamin Lin     g_assert_cmphex(jedec, ==, test_data->jedec_id);
226*11d94251SJamin Lin }
227*11d94251SJamin Lin 
aspeed_smc_test_erase_sector(const void * data)228*11d94251SJamin Lin void aspeed_smc_test_erase_sector(const void *data)
229*11d94251SJamin Lin {
230*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
231*11d94251SJamin Lin     uint32_t some_page_addr = test_data->page_addr;
232*11d94251SJamin Lin     uint32_t page[FLASH_PAGE_SIZE / 4];
233*11d94251SJamin Lin     int i;
234*11d94251SJamin Lin 
235*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
236*11d94251SJamin Lin 
237*11d94251SJamin Lin     /*
238*11d94251SJamin Lin      * Previous page should be full of 0xffs after backend is
239*11d94251SJamin Lin      * initialized
240*11d94251SJamin Lin      */
241*11d94251SJamin Lin     read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
242*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
243*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, 0xffffffff);
244*11d94251SJamin Lin     }
245*11d94251SJamin Lin 
246*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
247*11d94251SJamin Lin     flash_writeb(test_data, 0, EN_4BYTE_ADDR);
248*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
249*11d94251SJamin Lin     flash_writeb(test_data, 0, PP);
250*11d94251SJamin Lin     flash_writel(test_data, 0, make_be32(some_page_addr));
251*11d94251SJamin Lin 
252*11d94251SJamin Lin     /* Fill the page with its own addresses */
253*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
254*11d94251SJamin Lin         flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
255*11d94251SJamin Lin     }
256*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
257*11d94251SJamin Lin 
258*11d94251SJamin Lin     /* Check the page is correctly written */
259*11d94251SJamin Lin     read_page(test_data, some_page_addr, page);
260*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
261*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
262*11d94251SJamin Lin     }
263*11d94251SJamin Lin 
264*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
265*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
266*11d94251SJamin Lin     flash_writeb(test_data, 0, EN_4BYTE_ADDR);
267*11d94251SJamin Lin     flash_writeb(test_data, 0, ERASE_SECTOR);
268*11d94251SJamin Lin     flash_writel(test_data, 0, make_be32(some_page_addr));
269*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
270*11d94251SJamin Lin 
271*11d94251SJamin Lin     /* Check the page is erased */
272*11d94251SJamin Lin     read_page(test_data, some_page_addr, page);
273*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
274*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, 0xffffffff);
275*11d94251SJamin Lin     }
276*11d94251SJamin Lin 
277*11d94251SJamin Lin     flash_reset(test_data);
278*11d94251SJamin Lin }
279*11d94251SJamin Lin 
aspeed_smc_test_erase_all(const void * data)280*11d94251SJamin Lin void aspeed_smc_test_erase_all(const void *data)
281*11d94251SJamin Lin {
282*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
283*11d94251SJamin Lin     uint32_t some_page_addr = test_data->page_addr;
284*11d94251SJamin Lin     uint32_t page[FLASH_PAGE_SIZE / 4];
285*11d94251SJamin Lin     int i;
286*11d94251SJamin Lin 
287*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
288*11d94251SJamin Lin 
289*11d94251SJamin Lin     /*
290*11d94251SJamin Lin      * Previous page should be full of 0xffs after backend is
291*11d94251SJamin Lin      * initialized
292*11d94251SJamin Lin      */
293*11d94251SJamin Lin     read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
294*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
295*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, 0xffffffff);
296*11d94251SJamin Lin     }
297*11d94251SJamin Lin 
298*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
299*11d94251SJamin Lin     flash_writeb(test_data, 0, EN_4BYTE_ADDR);
300*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
301*11d94251SJamin Lin     flash_writeb(test_data, 0, PP);
302*11d94251SJamin Lin     flash_writel(test_data, 0, make_be32(some_page_addr));
303*11d94251SJamin Lin 
304*11d94251SJamin Lin     /* Fill the page with its own addresses */
305*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
306*11d94251SJamin Lin         flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
307*11d94251SJamin Lin     }
308*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
309*11d94251SJamin Lin 
310*11d94251SJamin Lin     /* Check the page is correctly written */
311*11d94251SJamin Lin     read_page(test_data, some_page_addr, page);
312*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
313*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
314*11d94251SJamin Lin     }
315*11d94251SJamin Lin 
316*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
317*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
318*11d94251SJamin Lin     flash_writeb(test_data, 0, BULK_ERASE);
319*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
320*11d94251SJamin Lin 
321*11d94251SJamin Lin     /* Check the page is erased */
322*11d94251SJamin Lin     read_page(test_data, some_page_addr, page);
323*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
324*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, 0xffffffff);
325*11d94251SJamin Lin     }
326*11d94251SJamin Lin 
327*11d94251SJamin Lin     flash_reset(test_data);
328*11d94251SJamin Lin }
329*11d94251SJamin Lin 
aspeed_smc_test_write_page(const void * data)330*11d94251SJamin Lin void aspeed_smc_test_write_page(const void *data)
331*11d94251SJamin Lin {
332*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
333*11d94251SJamin Lin     uint32_t my_page_addr = test_data->page_addr;
334*11d94251SJamin Lin     uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
335*11d94251SJamin Lin     uint32_t page[FLASH_PAGE_SIZE / 4];
336*11d94251SJamin Lin     int i;
337*11d94251SJamin Lin 
338*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
339*11d94251SJamin Lin 
340*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
341*11d94251SJamin Lin     flash_writeb(test_data, 0, EN_4BYTE_ADDR);
342*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
343*11d94251SJamin Lin     flash_writeb(test_data, 0, PP);
344*11d94251SJamin Lin     flash_writel(test_data, 0, make_be32(my_page_addr));
345*11d94251SJamin Lin 
346*11d94251SJamin Lin     /* Fill the page with its own addresses */
347*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
348*11d94251SJamin Lin         flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
349*11d94251SJamin Lin     }
350*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
351*11d94251SJamin Lin 
352*11d94251SJamin Lin     /* Check what was written */
353*11d94251SJamin Lin     read_page(test_data, my_page_addr, page);
354*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
355*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
356*11d94251SJamin Lin     }
357*11d94251SJamin Lin 
358*11d94251SJamin Lin     /* Check some other page. It should be full of 0xff */
359*11d94251SJamin Lin     read_page(test_data, some_page_addr, page);
360*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
361*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, 0xffffffff);
362*11d94251SJamin Lin     }
363*11d94251SJamin Lin 
364*11d94251SJamin Lin     flash_reset(test_data);
365*11d94251SJamin Lin }
366*11d94251SJamin Lin 
aspeed_smc_test_read_page_mem(const void * data)367*11d94251SJamin Lin void aspeed_smc_test_read_page_mem(const void *data)
368*11d94251SJamin Lin {
369*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
370*11d94251SJamin Lin     uint32_t my_page_addr = test_data->page_addr;
371*11d94251SJamin Lin     uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
372*11d94251SJamin Lin     uint32_t page[FLASH_PAGE_SIZE / 4];
373*11d94251SJamin Lin     int i;
374*11d94251SJamin Lin 
375*11d94251SJamin Lin     /*
376*11d94251SJamin Lin      * Enable 4BYTE mode for controller.
377*11d94251SJamin Lin      */
378*11d94251SJamin Lin     spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
379*11d94251SJamin Lin 
380*11d94251SJamin Lin     /* Enable 4BYTE mode for flash. */
381*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
382*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
383*11d94251SJamin Lin     flash_writeb(test_data, 0, EN_4BYTE_ADDR);
384*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
385*11d94251SJamin Lin     flash_writeb(test_data, 0, PP);
386*11d94251SJamin Lin     flash_writel(test_data, 0, make_be32(my_page_addr));
387*11d94251SJamin Lin 
388*11d94251SJamin Lin     /* Fill the page with its own addresses */
389*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
390*11d94251SJamin Lin         flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
391*11d94251SJamin Lin     }
392*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
393*11d94251SJamin Lin     spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
394*11d94251SJamin Lin 
395*11d94251SJamin Lin     /* Check what was written */
396*11d94251SJamin Lin     read_page_mem(test_data, my_page_addr, page);
397*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
398*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
399*11d94251SJamin Lin     }
400*11d94251SJamin Lin 
401*11d94251SJamin Lin     /* Check some other page. It should be full of 0xff */
402*11d94251SJamin Lin     read_page_mem(test_data, some_page_addr, page);
403*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
404*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, 0xffffffff);
405*11d94251SJamin Lin     }
406*11d94251SJamin Lin 
407*11d94251SJamin Lin     flash_reset(test_data);
408*11d94251SJamin Lin }
409*11d94251SJamin Lin 
aspeed_smc_test_write_page_mem(const void * data)410*11d94251SJamin Lin void aspeed_smc_test_write_page_mem(const void *data)
411*11d94251SJamin Lin {
412*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
413*11d94251SJamin Lin     uint32_t my_page_addr = test_data->page_addr;
414*11d94251SJamin Lin     uint32_t page[FLASH_PAGE_SIZE / 4];
415*11d94251SJamin Lin     int i;
416*11d94251SJamin Lin 
417*11d94251SJamin Lin     /*
418*11d94251SJamin Lin      * Enable 4BYTE mode for controller.
419*11d94251SJamin Lin      */
420*11d94251SJamin Lin     spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
421*11d94251SJamin Lin 
422*11d94251SJamin Lin     /* Enable 4BYTE mode for flash. */
423*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
424*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
425*11d94251SJamin Lin     flash_writeb(test_data, 0, EN_4BYTE_ADDR);
426*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
427*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
428*11d94251SJamin Lin 
429*11d94251SJamin Lin     /* move out USER mode to use direct writes to the AHB bus */
430*11d94251SJamin Lin     spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP);
431*11d94251SJamin Lin 
432*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
433*11d94251SJamin Lin         flash_writel(test_data, my_page_addr + i * 4,
434*11d94251SJamin Lin                make_be32(my_page_addr + i * 4));
435*11d94251SJamin Lin     }
436*11d94251SJamin Lin 
437*11d94251SJamin Lin     /* Check what was written */
438*11d94251SJamin Lin     read_page_mem(test_data, my_page_addr, page);
439*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
440*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
441*11d94251SJamin Lin     }
442*11d94251SJamin Lin 
443*11d94251SJamin Lin     flash_reset(test_data);
444*11d94251SJamin Lin }
445*11d94251SJamin Lin 
aspeed_smc_test_read_status_reg(const void * data)446*11d94251SJamin Lin void aspeed_smc_test_read_status_reg(const void *data)
447*11d94251SJamin Lin {
448*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
449*11d94251SJamin Lin     uint8_t r;
450*11d94251SJamin Lin 
451*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
452*11d94251SJamin Lin 
453*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
454*11d94251SJamin Lin     flash_writeb(test_data, 0, RDSR);
455*11d94251SJamin Lin     r = flash_readb(test_data, 0);
456*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
457*11d94251SJamin Lin 
458*11d94251SJamin Lin     g_assert_cmphex(r & SR_WEL, ==, 0);
459*11d94251SJamin Lin     g_assert(!qtest_qom_get_bool
460*11d94251SJamin Lin             (test_data->s, test_data->node, "write-enable"));
461*11d94251SJamin Lin 
462*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
463*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
464*11d94251SJamin Lin     flash_writeb(test_data, 0, RDSR);
465*11d94251SJamin Lin     r = flash_readb(test_data, 0);
466*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
467*11d94251SJamin Lin 
468*11d94251SJamin Lin     g_assert_cmphex(r & SR_WEL, ==, SR_WEL);
469*11d94251SJamin Lin     g_assert(qtest_qom_get_bool
470*11d94251SJamin Lin             (test_data->s, test_data->node, "write-enable"));
471*11d94251SJamin Lin 
472*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
473*11d94251SJamin Lin     flash_writeb(test_data, 0, WRDI);
474*11d94251SJamin Lin     flash_writeb(test_data, 0, RDSR);
475*11d94251SJamin Lin     r = flash_readb(test_data, 0);
476*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
477*11d94251SJamin Lin 
478*11d94251SJamin Lin     g_assert_cmphex(r & SR_WEL, ==, 0);
479*11d94251SJamin Lin     g_assert(!qtest_qom_get_bool
480*11d94251SJamin Lin             (test_data->s, test_data->node, "write-enable"));
481*11d94251SJamin Lin 
482*11d94251SJamin Lin     flash_reset(test_data);
483*11d94251SJamin Lin }
484*11d94251SJamin Lin 
aspeed_smc_test_status_reg_write_protection(const void * data)485*11d94251SJamin Lin void aspeed_smc_test_status_reg_write_protection(const void *data)
486*11d94251SJamin Lin {
487*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
488*11d94251SJamin Lin     uint8_t r;
489*11d94251SJamin Lin 
490*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
491*11d94251SJamin Lin 
492*11d94251SJamin Lin     /* default case: WP# is high and SRWD is low -> status register writable */
493*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
494*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
495*11d94251SJamin Lin     /* test ability to write SRWD */
496*11d94251SJamin Lin     flash_writeb(test_data, 0, WRSR);
497*11d94251SJamin Lin     flash_writeb(test_data, 0, SRWD);
498*11d94251SJamin Lin     flash_writeb(test_data, 0, RDSR);
499*11d94251SJamin Lin     r = flash_readb(test_data, 0);
500*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
501*11d94251SJamin Lin     g_assert_cmphex(r & SRWD, ==, SRWD);
502*11d94251SJamin Lin 
503*11d94251SJamin Lin     /* WP# high and SRWD high -> status register writable */
504*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
505*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
506*11d94251SJamin Lin     /* test ability to write SRWD */
507*11d94251SJamin Lin     flash_writeb(test_data, 0, WRSR);
508*11d94251SJamin Lin     flash_writeb(test_data, 0, 0);
509*11d94251SJamin Lin     flash_writeb(test_data, 0, RDSR);
510*11d94251SJamin Lin     r = flash_readb(test_data, 0);
511*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
512*11d94251SJamin Lin     g_assert_cmphex(r & SRWD, ==, 0);
513*11d94251SJamin Lin 
514*11d94251SJamin Lin     /* WP# low and SRWD low -> status register writable */
515*11d94251SJamin Lin     qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0);
516*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
517*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
518*11d94251SJamin Lin     /* test ability to write SRWD */
519*11d94251SJamin Lin     flash_writeb(test_data, 0, WRSR);
520*11d94251SJamin Lin     flash_writeb(test_data, 0, SRWD);
521*11d94251SJamin Lin     flash_writeb(test_data, 0, RDSR);
522*11d94251SJamin Lin     r = flash_readb(test_data, 0);
523*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
524*11d94251SJamin Lin     g_assert_cmphex(r & SRWD, ==, SRWD);
525*11d94251SJamin Lin 
526*11d94251SJamin Lin     /* WP# low and SRWD high -> status register NOT writable */
527*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
528*11d94251SJamin Lin     flash_writeb(test_data, 0 , WREN);
529*11d94251SJamin Lin     /* test ability to write SRWD */
530*11d94251SJamin Lin     flash_writeb(test_data, 0, WRSR);
531*11d94251SJamin Lin     flash_writeb(test_data, 0, 0);
532*11d94251SJamin Lin     flash_writeb(test_data, 0, RDSR);
533*11d94251SJamin Lin     r = flash_readb(test_data, 0);
534*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
535*11d94251SJamin Lin     /* write is not successful */
536*11d94251SJamin Lin     g_assert_cmphex(r & SRWD, ==, SRWD);
537*11d94251SJamin Lin 
538*11d94251SJamin Lin     qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1);
539*11d94251SJamin Lin     flash_reset(test_data);
540*11d94251SJamin Lin }
541*11d94251SJamin Lin 
aspeed_smc_test_write_block_protect(const void * data)542*11d94251SJamin Lin void aspeed_smc_test_write_block_protect(const void *data)
543*11d94251SJamin Lin {
544*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
545*11d94251SJamin Lin     uint32_t sector_size = 65536;
546*11d94251SJamin Lin     uint32_t n_sectors = 512;
547*11d94251SJamin Lin 
548*11d94251SJamin Lin     spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
549*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
550*11d94251SJamin Lin 
551*11d94251SJamin Lin     uint32_t bp_bits = 0b0;
552*11d94251SJamin Lin 
553*11d94251SJamin Lin     for (int i = 0; i < 16; i++) {
554*11d94251SJamin Lin         bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2);
555*11d94251SJamin Lin 
556*11d94251SJamin Lin         spi_ctrl_start_user(test_data);
557*11d94251SJamin Lin         flash_writeb(test_data, 0, WREN);
558*11d94251SJamin Lin         flash_writeb(test_data, 0, BULK_ERASE);
559*11d94251SJamin Lin         flash_writeb(test_data, 0, WREN);
560*11d94251SJamin Lin         flash_writeb(test_data, 0, WRSR);
561*11d94251SJamin Lin         flash_writeb(test_data, 0, bp_bits);
562*11d94251SJamin Lin         flash_writeb(test_data, 0, EN_4BYTE_ADDR);
563*11d94251SJamin Lin         flash_writeb(test_data, 0, WREN);
564*11d94251SJamin Lin         spi_ctrl_stop_user(test_data);
565*11d94251SJamin Lin 
566*11d94251SJamin Lin         uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
567*11d94251SJamin Lin         uint32_t protection_start = n_sectors - num_protected_sectors;
568*11d94251SJamin Lin         uint32_t protection_end = n_sectors;
569*11d94251SJamin Lin 
570*11d94251SJamin Lin         for (int sector = 0; sector < n_sectors; sector++) {
571*11d94251SJamin Lin             uint32_t addr = sector * sector_size;
572*11d94251SJamin Lin 
573*11d94251SJamin Lin             assert_page_mem(test_data, addr, 0xffffffff);
574*11d94251SJamin Lin             write_page_mem(test_data, addr, make_be32(0xabcdef12));
575*11d94251SJamin Lin 
576*11d94251SJamin Lin             uint32_t expected_value = protection_start <= sector
577*11d94251SJamin Lin                                       && sector < protection_end
578*11d94251SJamin Lin                                       ? 0xffffffff : 0xabcdef12;
579*11d94251SJamin Lin 
580*11d94251SJamin Lin             assert_page_mem(test_data, addr, expected_value);
581*11d94251SJamin Lin         }
582*11d94251SJamin Lin     }
583*11d94251SJamin Lin 
584*11d94251SJamin Lin     flash_reset(test_data);
585*11d94251SJamin Lin }
586*11d94251SJamin Lin 
aspeed_smc_test_write_block_protect_bottom_bit(const void * data)587*11d94251SJamin Lin void aspeed_smc_test_write_block_protect_bottom_bit(const void *data)
588*11d94251SJamin Lin {
589*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
590*11d94251SJamin Lin     uint32_t sector_size = 65536;
591*11d94251SJamin Lin     uint32_t n_sectors = 512;
592*11d94251SJamin Lin 
593*11d94251SJamin Lin     spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
594*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
595*11d94251SJamin Lin 
596*11d94251SJamin Lin     /* top bottom bit is enabled */
597*11d94251SJamin Lin     uint32_t bp_bits = 0b00100 << 3;
598*11d94251SJamin Lin 
599*11d94251SJamin Lin     for (int i = 0; i < 16; i++) {
600*11d94251SJamin Lin         bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2);
601*11d94251SJamin Lin 
602*11d94251SJamin Lin         spi_ctrl_start_user(test_data);
603*11d94251SJamin Lin         flash_writeb(test_data, 0, WREN);
604*11d94251SJamin Lin         flash_writeb(test_data, 0, BULK_ERASE);
605*11d94251SJamin Lin         flash_writeb(test_data, 0, WREN);
606*11d94251SJamin Lin         flash_writeb(test_data, 0, WRSR);
607*11d94251SJamin Lin         flash_writeb(test_data, 0, bp_bits);
608*11d94251SJamin Lin         flash_writeb(test_data, 0, EN_4BYTE_ADDR);
609*11d94251SJamin Lin         flash_writeb(test_data, 0, WREN);
610*11d94251SJamin Lin         spi_ctrl_stop_user(test_data);
611*11d94251SJamin Lin 
612*11d94251SJamin Lin         uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
613*11d94251SJamin Lin         uint32_t protection_start = 0;
614*11d94251SJamin Lin         uint32_t protection_end = num_protected_sectors;
615*11d94251SJamin Lin 
616*11d94251SJamin Lin         for (int sector = 0; sector < n_sectors; sector++) {
617*11d94251SJamin Lin             uint32_t addr = sector * sector_size;
618*11d94251SJamin Lin 
619*11d94251SJamin Lin             assert_page_mem(test_data, addr, 0xffffffff);
620*11d94251SJamin Lin             write_page_mem(test_data, addr, make_be32(0xabcdef12));
621*11d94251SJamin Lin 
622*11d94251SJamin Lin             uint32_t expected_value = protection_start <= sector
623*11d94251SJamin Lin                                       && sector < protection_end
624*11d94251SJamin Lin                                       ? 0xffffffff : 0xabcdef12;
625*11d94251SJamin Lin 
626*11d94251SJamin Lin             assert_page_mem(test_data, addr, expected_value);
627*11d94251SJamin Lin         }
628*11d94251SJamin Lin     }
629*11d94251SJamin Lin 
630*11d94251SJamin Lin     flash_reset(test_data);
631*11d94251SJamin Lin }
632*11d94251SJamin Lin 
aspeed_smc_test_write_page_qpi(const void * data)633*11d94251SJamin Lin void aspeed_smc_test_write_page_qpi(const void *data)
634*11d94251SJamin Lin {
635*11d94251SJamin Lin     const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
636*11d94251SJamin Lin     uint32_t my_page_addr = test_data->page_addr;
637*11d94251SJamin Lin     uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
638*11d94251SJamin Lin     uint32_t page[FLASH_PAGE_SIZE / 4];
639*11d94251SJamin Lin     uint32_t page_pattern[] = {
640*11d94251SJamin Lin         0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf
641*11d94251SJamin Lin     };
642*11d94251SJamin Lin     int i;
643*11d94251SJamin Lin 
644*11d94251SJamin Lin     spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
645*11d94251SJamin Lin 
646*11d94251SJamin Lin     spi_ctrl_start_user(test_data);
647*11d94251SJamin Lin     flash_writeb(test_data, 0, EN_4BYTE_ADDR);
648*11d94251SJamin Lin     flash_writeb(test_data, 0, WREN);
649*11d94251SJamin Lin     flash_writeb(test_data, 0, PP);
650*11d94251SJamin Lin     flash_writel(test_data, 0, make_be32(my_page_addr));
651*11d94251SJamin Lin 
652*11d94251SJamin Lin     /* Set QPI mode */
653*11d94251SJamin Lin     spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO);
654*11d94251SJamin Lin 
655*11d94251SJamin Lin     /* Fill the page pattern */
656*11d94251SJamin Lin     for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
657*11d94251SJamin Lin         flash_writel(test_data, 0, make_be32(page_pattern[i]));
658*11d94251SJamin Lin     }
659*11d94251SJamin Lin 
660*11d94251SJamin Lin     /* Fill the page with its own addresses */
661*11d94251SJamin Lin     for (; i < FLASH_PAGE_SIZE / 4; i++) {
662*11d94251SJamin Lin         flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
663*11d94251SJamin Lin     }
664*11d94251SJamin Lin 
665*11d94251SJamin Lin     /* Restore io mode */
666*11d94251SJamin Lin     spi_ctrl_set_io_mode(test_data, 0);
667*11d94251SJamin Lin     spi_ctrl_stop_user(test_data);
668*11d94251SJamin Lin 
669*11d94251SJamin Lin     /* Check what was written */
670*11d94251SJamin Lin     read_page(test_data, my_page_addr, page);
671*11d94251SJamin Lin     for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
672*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, page_pattern[i]);
673*11d94251SJamin Lin     }
674*11d94251SJamin Lin     for (; i < FLASH_PAGE_SIZE / 4; i++) {
675*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
676*11d94251SJamin Lin     }
677*11d94251SJamin Lin 
678*11d94251SJamin Lin     /* Check some other page. It should be full of 0xff */
679*11d94251SJamin Lin     read_page(test_data, some_page_addr, page);
680*11d94251SJamin Lin     for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
681*11d94251SJamin Lin         g_assert_cmphex(page[i], ==, 0xffffffff);
682*11d94251SJamin Lin     }
683*11d94251SJamin Lin 
684*11d94251SJamin Lin     flash_reset(test_data);
685*11d94251SJamin Lin }
686*11d94251SJamin Lin 
687