2 * QTest testcase for the M25P80 Flash (Using the Aspeed SPI
5 * Copyright (C) 2016 IBM Corp.
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 #include "qemu/osdep.h"
27 #include "qemu/bswap.h"
28 #include "libqtest-single.h"
29 #include "qemu/bitops.h"
32 * ASPEED SPI Controller registers
35 #define CONF_ENABLE_W0 (1 << 16)
36 #define R_CE_CTRL 0x04
37 #define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */
39 #define CTRL_CE_STOP_ACTIVE (1 << 2)
40 #define CTRL_READMODE 0x0
41 #define CTRL_FREADMODE 0x1
42 #define CTRL_WRITEMODE 0x2
43 #define CTRL_USERMODE 0x3
46 #define ASPEED_FMC_BASE 0x1E620000
47 #define ASPEED_FLASH_BASE 0x20000000
68 #define FLASH_JEDEC 0x20ba19 /* n25q256a */
69 #define FLASH_SIZE (32 * 1024 * 1024)
71 #define FLASH_PAGE_SIZE 256
74 * Use an explicit bswap for the values read/wrote to the flash region
75 * as they are BE and the Aspeed CPU is LE.
77 static inline uint32_t make_be32(uint32_t data
)
82 static void spi_conf(uint32_t value
)
84 uint32_t conf
= readl(ASPEED_FMC_BASE
+ R_CONF
);
87 writel(ASPEED_FMC_BASE
+ R_CONF
, conf
);
90 static void spi_conf_remove(uint32_t value
)
92 uint32_t conf
= readl(ASPEED_FMC_BASE
+ R_CONF
);
95 writel(ASPEED_FMC_BASE
+ R_CONF
, conf
);
98 static void spi_ce_ctrl(uint32_t value
)
100 uint32_t conf
= readl(ASPEED_FMC_BASE
+ R_CE_CTRL
);
103 writel(ASPEED_FMC_BASE
+ R_CE_CTRL
, conf
);
106 static void spi_ctrl_setmode(uint8_t mode
, uint8_t cmd
)
108 uint32_t ctrl
= readl(ASPEED_FMC_BASE
+ R_CTRL0
);
109 ctrl
&= ~(CTRL_USERMODE
| 0xff << 16);
110 ctrl
|= mode
| (cmd
<< 16);
111 writel(ASPEED_FMC_BASE
+ R_CTRL0
, ctrl
);
114 static void spi_ctrl_start_user(void)
116 uint32_t ctrl
= readl(ASPEED_FMC_BASE
+ R_CTRL0
);
118 ctrl
|= CTRL_USERMODE
| CTRL_CE_STOP_ACTIVE
;
119 writel(ASPEED_FMC_BASE
+ R_CTRL0
, ctrl
);
121 ctrl
&= ~CTRL_CE_STOP_ACTIVE
;
122 writel(ASPEED_FMC_BASE
+ R_CTRL0
, ctrl
);
125 static void spi_ctrl_stop_user(void)
127 uint32_t ctrl
= readl(ASPEED_FMC_BASE
+ R_CTRL0
);
129 ctrl
|= CTRL_USERMODE
| CTRL_CE_STOP_ACTIVE
;
130 writel(ASPEED_FMC_BASE
+ R_CTRL0
, ctrl
);
133 static void flash_reset(void)
135 spi_conf(CONF_ENABLE_W0
);
137 spi_ctrl_start_user();
138 writeb(ASPEED_FLASH_BASE
, RESET_ENABLE
);
139 writeb(ASPEED_FLASH_BASE
, RESET_MEMORY
);
140 writeb(ASPEED_FLASH_BASE
, WREN
);
141 writeb(ASPEED_FLASH_BASE
, BULK_ERASE
);
142 writeb(ASPEED_FLASH_BASE
, WRDI
);
143 spi_ctrl_stop_user();
145 spi_conf_remove(CONF_ENABLE_W0
);
148 static void test_read_jedec(void)
150 uint32_t jedec
= 0x0;
152 spi_conf(CONF_ENABLE_W0
);
154 spi_ctrl_start_user();
155 writeb(ASPEED_FLASH_BASE
, JEDEC_READ
);
156 jedec
|= readb(ASPEED_FLASH_BASE
) << 16;
157 jedec
|= readb(ASPEED_FLASH_BASE
) << 8;
158 jedec
|= readb(ASPEED_FLASH_BASE
);
159 spi_ctrl_stop_user();
163 g_assert_cmphex(jedec
, ==, FLASH_JEDEC
);
166 static void read_page(uint32_t addr
, uint32_t *page
)
170 spi_ctrl_start_user();
172 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
173 writeb(ASPEED_FLASH_BASE
, READ
);
174 writel(ASPEED_FLASH_BASE
, make_be32(addr
));
176 /* Continuous read are supported */
177 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
178 page
[i
] = make_be32(readl(ASPEED_FLASH_BASE
));
180 spi_ctrl_stop_user();
183 static void read_page_mem(uint32_t addr
, uint32_t *page
)
187 /* move out USER mode to use direct reads from the AHB bus */
188 spi_ctrl_setmode(CTRL_READMODE
, READ
);
190 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
191 page
[i
] = make_be32(readl(ASPEED_FLASH_BASE
+ addr
+ i
* 4));
195 static void write_page_mem(uint32_t addr
, uint32_t write_value
)
197 spi_ctrl_setmode(CTRL_WRITEMODE
, PP
);
199 for (int i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
200 writel(ASPEED_FLASH_BASE
+ addr
+ i
* 4, write_value
);
204 static void assert_page_mem(uint32_t addr
, uint32_t expected_value
)
206 uint32_t page
[FLASH_PAGE_SIZE
/ 4];
207 read_page_mem(addr
, page
);
208 for (int i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
209 g_assert_cmphex(page
[i
], ==, expected_value
);
213 static void test_erase_sector(void)
215 uint32_t some_page_addr
= 0x600 * FLASH_PAGE_SIZE
;
216 uint32_t page
[FLASH_PAGE_SIZE
/ 4];
219 spi_conf(CONF_ENABLE_W0
);
222 * Previous page should be full of 0xffs after backend is
225 read_page(some_page_addr
- FLASH_PAGE_SIZE
, page
);
226 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
227 g_assert_cmphex(page
[i
], ==, 0xffffffff);
230 spi_ctrl_start_user();
231 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
232 writeb(ASPEED_FLASH_BASE
, WREN
);
233 writeb(ASPEED_FLASH_BASE
, PP
);
234 writel(ASPEED_FLASH_BASE
, make_be32(some_page_addr
));
236 /* Fill the page with its own addresses */
237 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
238 writel(ASPEED_FLASH_BASE
, make_be32(some_page_addr
+ i
* 4));
240 spi_ctrl_stop_user();
242 /* Check the page is correctly written */
243 read_page(some_page_addr
, page
);
244 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
245 g_assert_cmphex(page
[i
], ==, some_page_addr
+ i
* 4);
248 spi_ctrl_start_user();
249 writeb(ASPEED_FLASH_BASE
, WREN
);
250 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
251 writeb(ASPEED_FLASH_BASE
, ERASE_SECTOR
);
252 writel(ASPEED_FLASH_BASE
, make_be32(some_page_addr
));
253 spi_ctrl_stop_user();
255 /* Check the page is erased */
256 read_page(some_page_addr
, page
);
257 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
258 g_assert_cmphex(page
[i
], ==, 0xffffffff);
264 static void test_erase_all(void)
266 uint32_t some_page_addr
= 0x15000 * FLASH_PAGE_SIZE
;
267 uint32_t page
[FLASH_PAGE_SIZE
/ 4];
270 spi_conf(CONF_ENABLE_W0
);
273 * Previous page should be full of 0xffs after backend is
276 read_page(some_page_addr
- FLASH_PAGE_SIZE
, page
);
277 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
278 g_assert_cmphex(page
[i
], ==, 0xffffffff);
281 spi_ctrl_start_user();
282 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
283 writeb(ASPEED_FLASH_BASE
, WREN
);
284 writeb(ASPEED_FLASH_BASE
, PP
);
285 writel(ASPEED_FLASH_BASE
, make_be32(some_page_addr
));
287 /* Fill the page with its own addresses */
288 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
289 writel(ASPEED_FLASH_BASE
, make_be32(some_page_addr
+ i
* 4));
291 spi_ctrl_stop_user();
293 /* Check the page is correctly written */
294 read_page(some_page_addr
, page
);
295 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
296 g_assert_cmphex(page
[i
], ==, some_page_addr
+ i
* 4);
299 spi_ctrl_start_user();
300 writeb(ASPEED_FLASH_BASE
, WREN
);
301 writeb(ASPEED_FLASH_BASE
, BULK_ERASE
);
302 spi_ctrl_stop_user();
304 /* Check the page is erased */
305 read_page(some_page_addr
, page
);
306 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
307 g_assert_cmphex(page
[i
], ==, 0xffffffff);
313 static void test_write_page(void)
315 uint32_t my_page_addr
= 0x14000 * FLASH_PAGE_SIZE
; /* beyond 16MB */
316 uint32_t some_page_addr
= 0x15000 * FLASH_PAGE_SIZE
;
317 uint32_t page
[FLASH_PAGE_SIZE
/ 4];
320 spi_conf(CONF_ENABLE_W0
);
322 spi_ctrl_start_user();
323 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
324 writeb(ASPEED_FLASH_BASE
, WREN
);
325 writeb(ASPEED_FLASH_BASE
, PP
);
326 writel(ASPEED_FLASH_BASE
, make_be32(my_page_addr
));
328 /* Fill the page with its own addresses */
329 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
330 writel(ASPEED_FLASH_BASE
, make_be32(my_page_addr
+ i
* 4));
332 spi_ctrl_stop_user();
334 /* Check what was written */
335 read_page(my_page_addr
, page
);
336 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
337 g_assert_cmphex(page
[i
], ==, my_page_addr
+ i
* 4);
340 /* Check some other page. It should be full of 0xff */
341 read_page(some_page_addr
, page
);
342 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
343 g_assert_cmphex(page
[i
], ==, 0xffffffff);
349 static void test_read_page_mem(void)
351 uint32_t my_page_addr
= 0x14000 * FLASH_PAGE_SIZE
; /* beyond 16MB */
352 uint32_t some_page_addr
= 0x15000 * FLASH_PAGE_SIZE
;
353 uint32_t page
[FLASH_PAGE_SIZE
/ 4];
356 /* Enable 4BYTE mode for controller. This is should be strapped by
359 spi_ce_ctrl(1 << CRTL_EXTENDED0
);
361 /* Enable 4BYTE mode for flash. */
362 spi_conf(CONF_ENABLE_W0
);
363 spi_ctrl_start_user();
364 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
365 writeb(ASPEED_FLASH_BASE
, WREN
);
366 writeb(ASPEED_FLASH_BASE
, PP
);
367 writel(ASPEED_FLASH_BASE
, make_be32(my_page_addr
));
369 /* Fill the page with its own addresses */
370 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
371 writel(ASPEED_FLASH_BASE
, make_be32(my_page_addr
+ i
* 4));
373 spi_ctrl_stop_user();
374 spi_conf_remove(CONF_ENABLE_W0
);
376 /* Check what was written */
377 read_page_mem(my_page_addr
, page
);
378 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
379 g_assert_cmphex(page
[i
], ==, my_page_addr
+ i
* 4);
382 /* Check some other page. It should be full of 0xff */
383 read_page_mem(some_page_addr
, page
);
384 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
385 g_assert_cmphex(page
[i
], ==, 0xffffffff);
391 static void test_write_page_mem(void)
393 uint32_t my_page_addr
= 0x15000 * FLASH_PAGE_SIZE
;
394 uint32_t page
[FLASH_PAGE_SIZE
/ 4];
397 /* Enable 4BYTE mode for controller. This is should be strapped by
400 spi_ce_ctrl(1 << CRTL_EXTENDED0
);
402 /* Enable 4BYTE mode for flash. */
403 spi_conf(CONF_ENABLE_W0
);
404 spi_ctrl_start_user();
405 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
406 writeb(ASPEED_FLASH_BASE
, WREN
);
407 spi_ctrl_stop_user();
409 /* move out USER mode to use direct writes to the AHB bus */
410 spi_ctrl_setmode(CTRL_WRITEMODE
, PP
);
412 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
413 writel(ASPEED_FLASH_BASE
+ my_page_addr
+ i
* 4,
414 make_be32(my_page_addr
+ i
* 4));
417 /* Check what was written */
418 read_page_mem(my_page_addr
, page
);
419 for (i
= 0; i
< FLASH_PAGE_SIZE
/ 4; i
++) {
420 g_assert_cmphex(page
[i
], ==, my_page_addr
+ i
* 4);
426 static void test_read_status_reg(void)
430 spi_conf(CONF_ENABLE_W0
);
432 spi_ctrl_start_user();
433 writeb(ASPEED_FLASH_BASE
, RDSR
);
434 r
= readb(ASPEED_FLASH_BASE
);
435 spi_ctrl_stop_user();
437 g_assert_cmphex(r
& SR_WEL
, ==, 0);
438 g_assert(!qtest_qom_get_bool
439 (global_qtest
, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
441 spi_ctrl_start_user();
442 writeb(ASPEED_FLASH_BASE
, WREN
);
443 writeb(ASPEED_FLASH_BASE
, RDSR
);
444 r
= readb(ASPEED_FLASH_BASE
);
445 spi_ctrl_stop_user();
447 g_assert_cmphex(r
& SR_WEL
, ==, SR_WEL
);
448 g_assert(qtest_qom_get_bool
449 (global_qtest
, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
451 spi_ctrl_start_user();
452 writeb(ASPEED_FLASH_BASE
, WRDI
);
453 writeb(ASPEED_FLASH_BASE
, RDSR
);
454 r
= readb(ASPEED_FLASH_BASE
);
455 spi_ctrl_stop_user();
457 g_assert_cmphex(r
& SR_WEL
, ==, 0);
458 g_assert(!qtest_qom_get_bool
459 (global_qtest
, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
464 static void test_status_reg_write_protection(void)
468 spi_conf(CONF_ENABLE_W0
);
470 /* default case: WP# is high and SRWD is low -> status register writable */
471 spi_ctrl_start_user();
472 writeb(ASPEED_FLASH_BASE
, WREN
);
473 /* test ability to write SRWD */
474 writeb(ASPEED_FLASH_BASE
, WRSR
);
475 writeb(ASPEED_FLASH_BASE
, SRWD
);
476 writeb(ASPEED_FLASH_BASE
, RDSR
);
477 r
= readb(ASPEED_FLASH_BASE
);
478 spi_ctrl_stop_user();
479 g_assert_cmphex(r
& SRWD
, ==, SRWD
);
481 /* WP# high and SRWD high -> status register writable */
482 spi_ctrl_start_user();
483 writeb(ASPEED_FLASH_BASE
, WREN
);
484 /* test ability to write SRWD */
485 writeb(ASPEED_FLASH_BASE
, WRSR
);
486 writeb(ASPEED_FLASH_BASE
, 0);
487 writeb(ASPEED_FLASH_BASE
, RDSR
);
488 r
= readb(ASPEED_FLASH_BASE
);
489 spi_ctrl_stop_user();
490 g_assert_cmphex(r
& SRWD
, ==, 0);
492 /* WP# low and SRWD low -> status register writable */
493 qtest_set_irq_in(global_qtest
,
494 "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 0);
495 spi_ctrl_start_user();
496 writeb(ASPEED_FLASH_BASE
, WREN
);
497 /* test ability to write SRWD */
498 writeb(ASPEED_FLASH_BASE
, WRSR
);
499 writeb(ASPEED_FLASH_BASE
, SRWD
);
500 writeb(ASPEED_FLASH_BASE
, RDSR
);
501 r
= readb(ASPEED_FLASH_BASE
);
502 spi_ctrl_stop_user();
503 g_assert_cmphex(r
& SRWD
, ==, SRWD
);
505 /* WP# low and SRWD high -> status register NOT writable */
506 spi_ctrl_start_user();
507 writeb(ASPEED_FLASH_BASE
, WREN
);
508 /* test ability to write SRWD */
509 writeb(ASPEED_FLASH_BASE
, WRSR
);
510 writeb(ASPEED_FLASH_BASE
, 0);
511 writeb(ASPEED_FLASH_BASE
, RDSR
);
512 r
= readb(ASPEED_FLASH_BASE
);
513 spi_ctrl_stop_user();
514 /* write is not successful */
515 g_assert_cmphex(r
& SRWD
, ==, SRWD
);
517 qtest_set_irq_in(global_qtest
,
518 "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 1);
522 static void test_write_block_protect(void)
524 uint32_t sector_size
= 65536;
525 uint32_t n_sectors
= 512;
527 spi_ce_ctrl(1 << CRTL_EXTENDED0
);
528 spi_conf(CONF_ENABLE_W0
);
530 uint32_t bp_bits
= 0b0;
532 for (int i
= 0; i
< 16; i
++) {
533 bp_bits
= ((i
& 0b1000) << 3) | ((i
& 0b0111) << 2);
535 spi_ctrl_start_user();
536 writeb(ASPEED_FLASH_BASE
, WREN
);
537 writeb(ASPEED_FLASH_BASE
, BULK_ERASE
);
538 writeb(ASPEED_FLASH_BASE
, WREN
);
539 writeb(ASPEED_FLASH_BASE
, WRSR
);
540 writeb(ASPEED_FLASH_BASE
, bp_bits
);
541 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
542 writeb(ASPEED_FLASH_BASE
, WREN
);
543 spi_ctrl_stop_user();
545 uint32_t num_protected_sectors
= i
? MIN(1 << (i
- 1), n_sectors
) : 0;
546 uint32_t protection_start
= n_sectors
- num_protected_sectors
;
547 uint32_t protection_end
= n_sectors
;
549 for (int sector
= 0; sector
< n_sectors
; sector
++) {
550 uint32_t addr
= sector
* sector_size
;
552 assert_page_mem(addr
, 0xffffffff);
553 write_page_mem(addr
, make_be32(0xabcdef12));
555 uint32_t expected_value
= protection_start
<= sector
556 && sector
< protection_end
557 ? 0xffffffff : 0xabcdef12;
559 assert_page_mem(addr
, expected_value
);
566 static void test_write_block_protect_bottom_bit(void)
568 uint32_t sector_size
= 65536;
569 uint32_t n_sectors
= 512;
571 spi_ce_ctrl(1 << CRTL_EXTENDED0
);
572 spi_conf(CONF_ENABLE_W0
);
574 /* top bottom bit is enabled */
575 uint32_t bp_bits
= 0b00100 << 3;
577 for (int i
= 0; i
< 16; i
++) {
578 bp_bits
= (((i
& 0b1000) | 0b0100) << 3) | ((i
& 0b0111) << 2);
580 spi_ctrl_start_user();
581 writeb(ASPEED_FLASH_BASE
, WREN
);
582 writeb(ASPEED_FLASH_BASE
, BULK_ERASE
);
583 writeb(ASPEED_FLASH_BASE
, WREN
);
584 writeb(ASPEED_FLASH_BASE
, WRSR
);
585 writeb(ASPEED_FLASH_BASE
, bp_bits
);
586 writeb(ASPEED_FLASH_BASE
, EN_4BYTE_ADDR
);
587 writeb(ASPEED_FLASH_BASE
, WREN
);
588 spi_ctrl_stop_user();
590 uint32_t num_protected_sectors
= i
? MIN(1 << (i
- 1), n_sectors
) : 0;
591 uint32_t protection_start
= 0;
592 uint32_t protection_end
= num_protected_sectors
;
594 for (int sector
= 0; sector
< n_sectors
; sector
++) {
595 uint32_t addr
= sector
* sector_size
;
597 assert_page_mem(addr
, 0xffffffff);
598 write_page_mem(addr
, make_be32(0xabcdef12));
600 uint32_t expected_value
= protection_start
<= sector
601 && sector
< protection_end
602 ? 0xffffffff : 0xabcdef12;
604 assert_page_mem(addr
, expected_value
);
611 static char tmp_path
[] = "/tmp/qtest.m25p80.XXXXXX";
613 int main(int argc
, char **argv
)
618 g_test_init(&argc
, &argv
, NULL
);
620 fd
= mkstemp(tmp_path
);
622 ret
= ftruncate(fd
, FLASH_SIZE
);
626 global_qtest
= qtest_initf("-m 256 -machine palmetto-bmc "
627 "-drive file=%s,format=raw,if=mtd",
630 qtest_add_func("/ast2400/smc/read_jedec", test_read_jedec
);
631 qtest_add_func("/ast2400/smc/erase_sector", test_erase_sector
);
632 qtest_add_func("/ast2400/smc/erase_all", test_erase_all
);
633 qtest_add_func("/ast2400/smc/write_page", test_write_page
);
634 qtest_add_func("/ast2400/smc/read_page_mem", test_read_page_mem
);
635 qtest_add_func("/ast2400/smc/write_page_mem", test_write_page_mem
);
636 qtest_add_func("/ast2400/smc/read_status_reg", test_read_status_reg
);
637 qtest_add_func("/ast2400/smc/status_reg_write_protection",
638 test_status_reg_write_protection
);
639 qtest_add_func("/ast2400/smc/write_block_protect",
640 test_write_block_protect
);
641 qtest_add_func("/ast2400/smc/write_block_protect_bottom_bit",
642 test_write_block_protect_bottom_bit
);
647 qtest_quit(global_qtest
);