@samitouri / QOSamiQemu / commits / 828872aa98

tests/qtest/ast2700-smc-test: Add Data FIFO mode test

Add two qtest cases exercising the new AST2700 Data FIFO-based flash access path (R_DATA_FIFO at spi_base + 0x200). Write_page_datafifo sends the page-program command and data through the FIFO port, then verifies the result via the regular read path. Read_page_datafifo writes a page the regular way, then reads it back through the FIFO port, so both directions are checked independently. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260717084559.3477061-10-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com>

Jamin Lin committed Jul 17, 2026 at 08:46 UTC 828872aa980ce747e835a4182f9958b9e6e7554c
3 files changed +110
tests/qtest/aspeed-smc-utils.c
+102
@@ -57,6 +57,28 @@ static inline uint32_t flash_readl(const AspeedSMCTestData *data,
57 return qtest_readl(data->s, data->flash_base + offset);
58 }
59
60 +/*
61 + * Data FIFO port, in spi_base's register bank (not flash_base). Accesses
62 + * through the FIFO require the complete user-mode transaction (opcode,
63 + * address, and data). Assumes CS0, whose FIFO slot is at R_DATA_FIFO.
64 + */
65 +static inline void datafifo_writeb(const AspeedSMCTestData *data,
66 + uint8_t value)
67 +{
68 + qtest_writeb(data->s, data->spi_base + R_DATA_FIFO, value);
69 +}
70 +
71 +static inline void datafifo_writel(const AspeedSMCTestData *data,
72 + uint32_t value)
73 +{
74 + spi_writel(data, R_DATA_FIFO, value);
75 +}
76 +
77 +static inline uint32_t datafifo_readl(const AspeedSMCTestData *data)
78 +{
79 + return spi_readl(data, R_DATA_FIFO);
80 +}
81 +
82 static void spi_conf(const AspeedSMCTestData *data, uint32_t value)
83 {
84 uint32_t conf = spi_readl(data, R_CONF);
@@ -826,3 +848,83 @@ void aspeed_smc_test_write_page_qor(const void *data)
848 {
849 test_write_page(data, read_page_qor);
850 }
851 +
852 +void aspeed_smc_test_write_page_datafifo(const void *data)
853 +{
854 + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
855 + uint32_t my_page_addr = test_data->page_addr;
856 + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
857 + uint32_t page[FLASH_PAGE_SIZE / 4];
858 + int i;
859 +
860 + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
861 +
862 + /*
863 + * Send the complete user-mode transaction (opcode, address, data)
864 + * through the Data FIFO port.
865 + */
866 + spi_ctrl_start_user(test_data);
867 + datafifo_writeb(test_data, EN_4BYTE_ADDR);
868 + datafifo_writeb(test_data, WREN);
869 + datafifo_writeb(test_data, PP);
870 + datafifo_writel(test_data, make_be32(my_page_addr));
871 +
872 + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
873 + datafifo_writel(test_data, make_be32(my_page_addr + i * 4));
874 + }
875 + spi_ctrl_stop_user(test_data);
876 +
877 + /* Check what was written, using the regular read path */
878 + read_page(test_data, my_page_addr, page);
879 + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
880 + g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
881 + }
882 +
883 + /* Check some other page. It should be full of 0xff */
884 + read_page(test_data, some_page_addr, page);
885 + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
886 + g_assert_cmphex(page[i], ==, 0xffffffff);
887 + }
888 +
889 + flash_reset(test_data);
890 +}
891 +
892 +void aspeed_smc_test_read_page_datafifo(const void *data)
893 +{
894 + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
895 + uint32_t my_page_addr = test_data->page_addr;
896 + uint32_t page[FLASH_PAGE_SIZE / 4];
897 + int i;
898 +
899 + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
900 +
901 + /* Write the page the regular way */
902 + spi_ctrl_start_user(test_data);
903 + flash_writeb(test_data, 0, EN_4BYTE_ADDR);
904 + flash_writeb(test_data, 0, WREN);
905 + flash_writeb(test_data, 0, PP);
906 + flash_writel(test_data, 0, make_be32(my_page_addr));
907 + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
908 + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
909 + }
910 + spi_ctrl_stop_user(test_data);
911 +
912 + /*
913 + * Read it back through the data FIFO port, again sending the whole
914 + * transaction (opcode, address, data) through it.
915 + */
916 + spi_ctrl_start_user(test_data);
917 + datafifo_writeb(test_data, EN_4BYTE_ADDR);
918 + datafifo_writeb(test_data, READ);
919 + datafifo_writel(test_data, make_be32(my_page_addr));
920 + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
921 + page[i] = make_be32(datafifo_readl(test_data));
922 + }
923 + spi_ctrl_stop_user(test_data);
924 +
925 + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
926 + g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
927 + }
928 +
929 + flash_reset(test_data);
930 +}
tests/qtest/aspeed-smc-utils.h
+4
@@ -33,6 +33,8 @@
33 #define CTRL_DUMMY_LOW_SHIFT 6
34 #define CTRL_DUMMY_HIGH_SHIFT 14
35 #define SR_WEL BIT(1)
36 +/* Data fifo */
37 +#define R_DATA_FIFO 0x200
38
39 /*
40 * Flash commands
@@ -87,5 +89,7 @@ void aspeed_smc_test_read_page_mem_dor(const void *data);
89 void aspeed_smc_test_write_page_dor(const void *data);
90 void aspeed_smc_test_read_page_mem_qor(const void *data);
91 void aspeed_smc_test_write_page_qor(const void *data);
92 +void aspeed_smc_test_write_page_datafifo(const void *data);
93 +void aspeed_smc_test_read_page_datafifo(const void *data);
94
95 #endif /* TESTS_ASPEED_SMC_UTILS_H */
tests/qtest/ast2700-smc-test.c
+4
@@ -64,6 +64,10 @@ static void test_ast2700_evb(AspeedSMCTestData *data)
64 data, aspeed_smc_test_read_page_mem_qor);
65 qtest_add_data_func("/ast2700/smc/write_page_qor",
66 data, aspeed_smc_test_write_page_qor);
67 + qtest_add_data_func("/ast2700/smc/write_page_datafifo",
68 + data, aspeed_smc_test_write_page_datafifo);
69 + qtest_add_data_func("/ast2700/smc/read_page_datafifo",
70 + data, aspeed_smc_test_read_page_datafifo);
71 }
72
73 int main(int argc, char **argv)